feat: ship as a real iOS-installable PWA, restructure bottom nav, fix safe-area
CI / test (push) Has been cancelled
CI / test (push) Has been cancelled
- Add manifest.webmanifest with standalone display + warm-craft theme colors, apple-touch-icon, and 192/512/512-maskable icons (frame-with-sunset glyph). - Add PWA meta tags + viewport-fit=cover so add-to-home-screen produces a true standalone app on iOS instead of a Safari bookmark. - Drop the Shared bottom-nav tab; the in-page sub-tabs already cover that. Three nav tabs total (Home / Library / Settings); pending-share badge moves to the Library tab. Predicate-based isActive() now correctly disambiguates /library vs /library?tab=shared. - Safe-area handling: bottom nav, bottom sheet, upload overlay, and #app respect env(safe-area-inset-*); sticky Library tabs anchor below the iPhone status bar. Introduces --bottom-nav-height token consumed by Settings, Library, and the toast. - LibraryView reactively follows route.query.tab so deep-linking /library?tab=shared lands on the right sub-tab. - Theme-color meta syncs client-side via useTheme.applyTheme so the user's chosen theme follows them into Android Chrome's chrome bar. Test suite expanded to 278 tests / 100% line coverage (99.84% statements, 99.78% branches). Remaining gaps are unreachable defensive code. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -1 +1 @@
|
||||
import{C as e,H as t,M as n,P as r,R as i,_ as a,d as o,f as s,k as c,p as l,r as u,s as d,t as f,u as p,v as m,w as h,z as g}from"./_plugin-vue_export-helper-DVo1OUMD.js";import{c as _,d as v,f as y}from"./index-DCUs53vX.js";var b=u(`devices`,()=>{let e=t([]),n=t(!1),r=t(null);async function i(){n.value=!0,r.value=null;try{let t=await fetch(`/api/devices`);if(!t.ok)throw Error(`Failed to load devices`);e.value=await t.json()}catch(e){r.value=e instanceof Error?e.message:`Unknown error`}finally{n.value=!1}}async function a(t,n){let r=await fetch(`/api/devices/${t}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify(n)});if(!r.ok)throw Error(`Failed to update device`);let i=await r.json(),a=e.value.findIndex(e=>e.id===t);return a!==-1&&(e.value[a]=i),i}async function o(t,n){let r=await fetch(`/api/devices/${t}/lock`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({imageId:n})});if(!r.ok)throw Error(`Failed to lock image`);let i=await r.json(),a=e.value.findIndex(e=>e.id===t);return a!==-1&&(e.value[a]=i),i}async function s(t){let n=await fetch(`/api/devices/${t}/lock`,{method:`DELETE`});if(!n.ok)throw Error(`Failed to unlock`);let r=await n.json(),i=e.value.findIndex(e=>e.id===t);return i!==-1&&(e.value[i]=r),r}return{devices:e,loading:n,error:r,fetchDevices:i,updateDevice:a,lockImage:o,unlockImage:s}}),x=u(`upload`,()=>{let e=t(null),n=t(null),r=t(null),i=t(null),a=t(null),o=t(null),s=t([]),c=t(null),l=t([]),u=t(null);function d(t,r){_(),e.value=t,n.value=URL.createObjectURL(t),c.value=r??null,l.value=r?[r]:[]}async function f(t,r){_();let i=await(await fetch(t.originalUrl)).blob();e.value=new File([i],t.originalFilename,{type:i.type}),n.value=URL.createObjectURL(i),u.value=t.id,a.value=t.cropParams??null,o.value=t.cropOrientation??null,s.value=t.stickerState?[...t.stickerState]:[],l.value=t.approvedDeviceIds,c.value=r??null}function p(e,t,n){i.value&&URL.revokeObjectURL(i.value),r.value=e,i.value=URL.createObjectURL(e),a.value=t,o.value=n}function m(e){s.value=[...s.value,e]}function h(e,t){s.value=s.value.map(n=>n.id===e?{...n,...t}:n)}function g(e){s.value=s.value.filter(t=>t.id!==e)}function _(){n.value&&URL.revokeObjectURL(n.value),i.value&&URL.revokeObjectURL(i.value),e.value=null,n.value=null,r.value=null,i.value=null,a.value=null,o.value=null,s.value=[],c.value=null,l.value=[],u.value=null}return{originalFile:e,originalUrl:n,croppedBlob:r,croppedUrl:i,cropParams:a,cropOrientation:o,stickers:s,contextDeviceId:c,selectedDeviceIds:l,editingImageId:u,init:d,initEdit:f,setCrop:p,addSticker:m,updateSticker:h,removeSticker:g,cleanup:_}}),S={key:0,class:`btn__spinner`,"aria-hidden":`true`},C=f(m({__name:`BaseButton`,props:{variant:{default:`primary`},tag:{default:`button`},type:{default:`button`},disabled:{type:Boolean,default:!1},loading:{type:Boolean,default:!1}},setup(t){return(i,a)=>(c(),o(r(t.tag),e({type:t.tag===`button`?t.type:void 0,disabled:t.disabled||t.loading,class:[`btn`,`btn--${t.variant}`,{"btn--loading":t.loading}]},i.$attrs),{default:g(()=>[t.loading?(c(),l(`span`,S)):s(``,!0),n(i.$slots,`default`,{},void 0,!0)]),_:3},16,[`type`,`disabled`,`class`]))}}),[[`__scopeId`,`data-v-7d3f1e61`]]),w=[`aria-label`],T=f(m({__name:`BaseBottomSheet`,props:{modelValue:{type:Boolean},label:{}},emits:[`update:modelValue`],setup(e,{emit:r}){let u=e,f=r,m=t(null),b=null;function x(){f(`update:modelValue`,!1)}return i(()=>u.modelValue,async e=>{e?(b=document.activeElement,await h(),m.value?.focus()):(b?.focus(),b=null)}),(t,r)=>(c(),o(d,{to:`body`},[a(_,{name:`sheet`},{default:g(()=>[e.modelValue?(c(),l(`div`,{key:0,class:`sheet-overlay`,role:`dialog`,"aria-label":e.label,"aria-modal":`true`,onClick:y(x,[`self`]),onKeydown:v(x,[`esc`])},[p(`div`,{ref_key:`sheetRef`,ref:m,class:`sheet`,tabindex:`-1`},[r[0]||=p(`div`,{class:`sheet__handle`,"aria-hidden":`true`},null,-1),n(t.$slots,`default`,{},void 0,!0)],512)],40,w)):s(``,!0)]),_:3})]))}}),[[`__scopeId`,`data-v-81ce2dd1`]]);export{b as i,C as n,x as r,T as t};
|
||||
import{C as e,H as t,M as n,P as r,R as i,_ as a,d as o,f as s,k as c,p as l,r as u,s as d,t as f,u as p,v as m,w as h,z as g}from"./_plugin-vue_export-helper-DVo1OUMD.js";import{c as _,d as v,f as y}from"./index-D13oAsTG.js";var b=u(`devices`,()=>{let e=t([]),n=t(!1),r=t(null);async function i(){n.value=!0,r.value=null;try{let t=await fetch(`/api/devices`);if(!t.ok)throw Error(`Failed to load devices`);e.value=await t.json()}catch(e){r.value=e instanceof Error?e.message:`Unknown error`}finally{n.value=!1}}async function a(t,n){let r=await fetch(`/api/devices/${t}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify(n)});if(!r.ok)throw Error(`Failed to update device`);let i=await r.json(),a=e.value.findIndex(e=>e.id===t);return a!==-1&&(e.value[a]=i),i}async function o(t,n){let r=await fetch(`/api/devices/${t}/lock`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({imageId:n})});if(!r.ok)throw Error(`Failed to lock image`);let i=await r.json(),a=e.value.findIndex(e=>e.id===t);return a!==-1&&(e.value[a]=i),i}async function s(t){let n=await fetch(`/api/devices/${t}/lock`,{method:`DELETE`});if(!n.ok)throw Error(`Failed to unlock`);let r=await n.json(),i=e.value.findIndex(e=>e.id===t);return i!==-1&&(e.value[i]=r),r}return{devices:e,loading:n,error:r,fetchDevices:i,updateDevice:a,lockImage:o,unlockImage:s}}),x=u(`upload`,()=>{let e=t(null),n=t(null),r=t(null),i=t(null),a=t(null),o=t(null),s=t([]),c=t(null),l=t([]),u=t(null);function d(t,r){_(),e.value=t,n.value=URL.createObjectURL(t),c.value=r??null,l.value=r?[r]:[]}async function f(t,r){_();let i=await(await fetch(t.originalUrl)).blob();e.value=new File([i],t.originalFilename,{type:i.type}),n.value=URL.createObjectURL(i),u.value=t.id,a.value=t.cropParams??null,o.value=t.cropOrientation??null,s.value=t.stickerState?[...t.stickerState]:[],l.value=t.approvedDeviceIds,c.value=r??null}function p(e,t,n){i.value&&URL.revokeObjectURL(i.value),r.value=e,i.value=URL.createObjectURL(e),a.value=t,o.value=n}function m(e){s.value=[...s.value,e]}function h(e,t){s.value=s.value.map(n=>n.id===e?{...n,...t}:n)}function g(e){s.value=s.value.filter(t=>t.id!==e)}function _(){n.value&&URL.revokeObjectURL(n.value),i.value&&URL.revokeObjectURL(i.value),e.value=null,n.value=null,r.value=null,i.value=null,a.value=null,o.value=null,s.value=[],c.value=null,l.value=[],u.value=null}return{originalFile:e,originalUrl:n,croppedBlob:r,croppedUrl:i,cropParams:a,cropOrientation:o,stickers:s,contextDeviceId:c,selectedDeviceIds:l,editingImageId:u,init:d,initEdit:f,setCrop:p,addSticker:m,updateSticker:h,removeSticker:g,cleanup:_}}),S={key:0,class:`btn__spinner`,"aria-hidden":`true`},C=f(m({__name:`BaseButton`,props:{variant:{default:`primary`},tag:{default:`button`},type:{default:`button`},disabled:{type:Boolean,default:!1},loading:{type:Boolean,default:!1}},setup(t){return(i,a)=>(c(),o(r(t.tag),e({type:t.tag===`button`?t.type:void 0,disabled:t.disabled||t.loading,class:[`btn`,`btn--${t.variant}`,{"btn--loading":t.loading}]},i.$attrs),{default:g(()=>[t.loading?(c(),l(`span`,S)):s(``,!0),n(i.$slots,`default`,{},void 0,!0)]),_:3},16,[`type`,`disabled`,`class`]))}}),[[`__scopeId`,`data-v-7d3f1e61`]]),w=[`aria-label`],T=f(m({__name:`BaseBottomSheet`,props:{modelValue:{type:Boolean},label:{}},emits:[`update:modelValue`],setup(e,{emit:r}){let u=e,f=r,m=t(null),b=null;function x(){f(`update:modelValue`,!1)}return i(()=>u.modelValue,async e=>{e?(b=document.activeElement,await h(),m.value?.focus()):(b?.focus(),b=null)}),(t,r)=>(c(),o(d,{to:`body`},[a(_,{name:`sheet`},{default:g(()=>[e.modelValue?(c(),l(`div`,{key:0,class:`sheet-overlay`,role:`dialog`,"aria-label":e.label,"aria-modal":`true`,onClick:y(x,[`self`]),onKeydown:v(x,[`esc`])},[p(`div`,{ref_key:`sheetRef`,ref:m,class:`sheet`,tabindex:`-1`},[r[0]||=p(`div`,{class:`sheet__handle`,"aria-hidden":`true`},null,-1),n(t.$slots,`default`,{},void 0,!0)],512)],40,w)):s(``,!0)]),_:3})]))}}),[[`__scopeId`,`data-v-9ba072ca`]]);export{b as i,C as n,x as r,T as t};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
.btn[data-v-7d3f1e61]{justify-content:center;align-items:center;gap:var(--space-2);min-height:var(--touch-min);padding:0 var(--space-5);border-radius:var(--radius-full);font-family:var(--font-family);font-size:var(--text-base);cursor:pointer;transition:opacity var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out);white-space:nowrap;border:none;font-weight:600;line-height:1;text-decoration:none;display:inline-flex}.btn[data-v-7d3f1e61]:disabled{opacity:.4;cursor:not-allowed}.btn[data-v-7d3f1e61]:not(:disabled):active{transform:scale(.96)}.btn--primary[data-v-7d3f1e61]{background:var(--color-primary);color:var(--color-primary-fg)}.btn--secondary[data-v-7d3f1e61]{background:var(--color-secondary);color:var(--color-secondary-fg);border:1px solid var(--color-border)}.btn--ghost[data-v-7d3f1e61]{color:var(--color-text);border:1px solid var(--color-border);background:0 0}.btn--destructive[data-v-7d3f1e61]{background:var(--color-destructive);color:var(--color-destructive-fg)}.btn--icon-pill[data-v-7d3f1e61]{width:var(--touch-min);border-radius:var(--radius-full);background:var(--color-surface-2);color:var(--color-text);padding:0}.btn__spinner[data-v-7d3f1e61]{border:2px solid;border-top-color:#0000;border-radius:50%;width:16px;height:16px;animation:.7s linear infinite spin-7d3f1e61}@keyframes spin-7d3f1e61{to{transform:rotate(360deg)}}.sheet-overlay[data-v-81ce2dd1]{z-index:100;background:#0006;align-items:flex-end;display:flex;position:fixed;inset:0}.sheet[data-v-81ce2dd1]{background:var(--color-surface);border-radius:var(--radius-lg) var(--radius-lg) 0 0;width:100%;padding:var(--space-3) var(--space-4) var(--space-6);outline:none;max-height:90dvh;overflow-y:auto}.sheet__handle[data-v-81ce2dd1]{border-radius:var(--radius-full);background:var(--color-border);width:36px;height:4px;margin:0 auto var(--space-4)}.sheet-enter-active .sheet-overlay[data-v-81ce2dd1]{transition:background var(--duration-base) var(--ease-out)}.sheet-enter-active .sheet[data-v-81ce2dd1]{transition:transform .25s var(--ease-out)}.sheet-leave-active .sheet[data-v-81ce2dd1]{transition:transform .2s ease-in}.sheet-leave-active[data-v-81ce2dd1]{transition:background .2s ease-in}.sheet-enter-from[data-v-81ce2dd1]{background:0 0}.sheet-enter-from .sheet[data-v-81ce2dd1]{transform:translateY(100%)}.sheet-leave-to[data-v-81ce2dd1]{background:0 0}.sheet-leave-to .sheet[data-v-81ce2dd1]{transform:translateY(100%)}
|
||||
.btn[data-v-7d3f1e61]{justify-content:center;align-items:center;gap:var(--space-2);min-height:var(--touch-min);padding:0 var(--space-5);border-radius:var(--radius-full);font-family:var(--font-family);font-size:var(--text-base);cursor:pointer;transition:opacity var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out);white-space:nowrap;border:none;font-weight:600;line-height:1;text-decoration:none;display:inline-flex}.btn[data-v-7d3f1e61]:disabled{opacity:.4;cursor:not-allowed}.btn[data-v-7d3f1e61]:not(:disabled):active{transform:scale(.96)}.btn--primary[data-v-7d3f1e61]{background:var(--color-primary);color:var(--color-primary-fg)}.btn--secondary[data-v-7d3f1e61]{background:var(--color-secondary);color:var(--color-secondary-fg);border:1px solid var(--color-border)}.btn--ghost[data-v-7d3f1e61]{color:var(--color-text);border:1px solid var(--color-border);background:0 0}.btn--destructive[data-v-7d3f1e61]{background:var(--color-destructive);color:var(--color-destructive-fg)}.btn--icon-pill[data-v-7d3f1e61]{width:var(--touch-min);border-radius:var(--radius-full);background:var(--color-surface-2);color:var(--color-text);padding:0}.btn__spinner[data-v-7d3f1e61]{border:2px solid;border-top-color:#0000;border-radius:50%;width:16px;height:16px;animation:.7s linear infinite spin-7d3f1e61}@keyframes spin-7d3f1e61{to{transform:rotate(360deg)}}.sheet-overlay[data-v-9ba072ca]{z-index:100;background:#0006;align-items:flex-end;display:flex;position:fixed;inset:0}.sheet[data-v-9ba072ca]{background:var(--color-surface);border-radius:var(--radius-lg) var(--radius-lg) 0 0;width:100%;padding:var(--space-3) var(--space-4) calc(var(--space-6) + env(safe-area-inset-bottom));outline:none;max-height:90dvh;overflow-y:auto}.sheet__handle[data-v-9ba072ca]{border-radius:var(--radius-full);background:var(--color-border);width:36px;height:4px;margin:0 auto var(--space-4)}.sheet-enter-active .sheet-overlay[data-v-9ba072ca]{transition:background var(--duration-base) var(--ease-out)}.sheet-enter-active .sheet[data-v-9ba072ca]{transition:transform .25s var(--ease-out)}.sheet-leave-active .sheet[data-v-9ba072ca]{transition:transform .2s ease-in}.sheet-leave-active[data-v-9ba072ca]{transition:background .2s ease-in}.sheet-enter-from[data-v-9ba072ca]{background:0 0}.sheet-enter-from .sheet[data-v-9ba072ca]{transform:translateY(100%)}.sheet-leave-to[data-v-9ba072ca]{background:0 0}.sheet-leave-to .sheet[data-v-9ba072ca]{transform:translateY(100%)}
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as e,d as t,g as n,j as r,k as i,l as a,o,p as s,pt as c,t as l,u,v as d,z as f}from"./_plugin-vue_export-helper-DVo1OUMD.js";import{n as p,t as m}from"./BaseBottomSheet-CzdI27OS.js";var h={class:`device-picker__list`},g=[`checked`,`onChange`],_={class:`device-picker__name`},v={class:`device-picker__orientation`},y=l(d({__name:`DevicePicker`,props:{modelValue:{type:Boolean},devices:{},selected:{},uploading:{type:Boolean}},emits:[`update:modelValue`,`update:selected`,`confirm`],setup(l,{emit:d}){let y=l,b=d;function x(e){y.selected.includes(e)?b(`update:selected`,y.selected.filter(t=>t!==e)):b(`update:selected`,[...y.selected,e])}let S=a(()=>{let e=y.selected.length;return e===0?`Add to frame`:`Add to ${e} frame${e>1?`s`:``}`});return(a,d)=>(i(),t(m,{"model-value":l.modelValue,label:`Choose frames`,"onUpdate:modelValue":d[1]||=e=>a.$emit(`update:modelValue`,e)},{default:f(()=>[d[2]||=u(`h2`,{class:`device-picker__title`},`Add to frames`,-1),d[3]||=u(`p`,{class:`device-picker__sub`},`Choose which frames will show this photo.`,-1),u(`div`,h,[(i(!0),s(o,null,r(l.devices,e=>(i(),s(`label`,{key:e.id,class:`device-picker__row`},[u(`input`,{type:`checkbox`,class:`device-picker__check`,checked:l.selected.includes(e.id),onChange:t=>x(e.id)},null,40,g),u(`span`,_,c(e.name),1),u(`span`,v,c(e.orientation),1)]))),128))]),e(p,{variant:`primary`,class:`device-picker__confirm`,disabled:l.selected.length===0||l.uploading,onClick:d[0]||=e=>a.$emit(`confirm`)},{default:f(()=>[n(c(l.uploading?`Uploading…`:S.value),1)]),_:1},8,[`disabled`])]),_:1},8,[`model-value`]))}}),[[`__scopeId`,`data-v-a6466fa5`]]);export{y as t};
|
||||
import{_ as e,d as t,g as n,j as r,k as i,l as a,o,p as s,pt as c,t as l,u,v as d,z as f}from"./_plugin-vue_export-helper-DVo1OUMD.js";import{n as p,t as m}from"./BaseBottomSheet-CO3Iefke.js";var h={class:`device-picker__list`},g=[`checked`,`onChange`],_={class:`device-picker__name`},v={class:`device-picker__orientation`},y=l(d({__name:`DevicePicker`,props:{modelValue:{type:Boolean},devices:{},selected:{},uploading:{type:Boolean}},emits:[`update:modelValue`,`update:selected`,`confirm`],setup(l,{emit:d}){let y=l,b=d;function x(e){y.selected.includes(e)?b(`update:selected`,y.selected.filter(t=>t!==e)):b(`update:selected`,[...y.selected,e])}let S=a(()=>{let e=y.selected.length;return e===0?`Add to frame`:`Add to ${e} frame${e>1?`s`:``}`});return(a,d)=>(i(),t(m,{"model-value":l.modelValue,label:`Choose frames`,"onUpdate:modelValue":d[1]||=e=>a.$emit(`update:modelValue`,e)},{default:f(()=>[d[2]||=u(`h2`,{class:`device-picker__title`},`Add to frames`,-1),d[3]||=u(`p`,{class:`device-picker__sub`},`Choose which frames will show this photo.`,-1),u(`div`,h,[(i(!0),s(o,null,r(l.devices,e=>(i(),s(`label`,{key:e.id,class:`device-picker__row`},[u(`input`,{type:`checkbox`,class:`device-picker__check`,checked:l.selected.includes(e.id),onChange:t=>x(e.id)},null,40,g),u(`span`,_,c(e.name),1),u(`span`,v,c(e.orientation),1)]))),128))]),e(p,{variant:`primary`,class:`device-picker__confirm`,disabled:l.selected.length===0||l.uploading,onClick:d[0]||=e=>a.$emit(`confirm`)},{default:f(()=>[n(c(l.uploading?`Uploading…`:S.value),1)]),_:1},8,[`disabled`])]),_:1},8,[`model-value`]))}}),[[`__scopeId`,`data-v-a6466fa5`]]);export{y as t};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
.settings[data-v-76ec3881]{padding:var(--space-4) var(--space-4) calc(var(--bottom-nav-height) + var(--space-6));max-width:480px;margin:0 auto}.settings__title[data-v-76ec3881]{font-size:var(--text-xl);margin-bottom:var(--space-6);font-weight:700}.settings__section[data-v-76ec3881]{margin-bottom:var(--space-6)}.settings__section-title[data-v-76ec3881]{font-size:var(--text-sm);color:var(--color-text-muted);text-transform:uppercase;letter-spacing:.06em;margin-bottom:var(--space-3);font-weight:700}.settings__row[data-v-76ec3881]{padding:var(--space-3) 0;border-bottom:1px solid var(--color-border);font-size:var(--text-base);justify-content:space-between;align-items:center;display:flex}.settings__row-label[data-v-76ec3881]{color:var(--color-text-muted)}.settings__row-value[data-v-76ec3881]{font-weight:600}.settings__logout[data-v-76ec3881]{min-height:var(--touch-min);padding:var(--space-3) 0;color:var(--color-destructive);font-weight:600;font-size:var(--text-base);align-items:center;text-decoration:none;display:flex}.theme-grid[data-v-76ec3881]{gap:var(--space-3);grid-template-columns:repeat(3,1fr);display:grid}.theme-swatch[data-v-76ec3881]{align-items:center;gap:var(--space-2);padding:var(--space-3);background:var(--swatch-bg);border-radius:var(--radius-md);cursor:pointer;transition:border-color var(--duration-fast);min-height:var(--touch-min);border:2px solid #0000;flex-direction:column;display:flex;position:relative}.theme-swatch--active[data-v-76ec3881]{border-color:var(--swatch-primary)}.theme-swatch__preview[data-v-76ec3881]{border-radius:var(--radius-sm);background:var(--swatch-bg);border:1px solid color-mix(in srgb, var(--swatch-text) 15%, transparent);flex-direction:column;justify-content:center;gap:4px;width:100%;height:36px;padding:0 6px;display:flex}.theme-swatch__bar[data-v-76ec3881]{background:var(--swatch-primary);border-radius:3px;width:60%;height:6px;display:block}.theme-swatch__dot[data-v-76ec3881]{background:var(--swatch-text);opacity:.4;border-radius:2px;width:80%;height:4px;display:block}.theme-swatch__label[data-v-76ec3881]{font-size:var(--text-xs);color:var(--color-text);text-align:center;font-weight:600;line-height:1.2}.theme-swatch__check[data-v-76ec3881]{top:var(--space-1);right:var(--space-2);font-size:var(--text-sm);color:var(--swatch-primary);font-weight:700;position:absolute}
|
||||
@@ -1 +0,0 @@
|
||||
.settings[data-v-1446e085]{padding:var(--space-4) var(--space-4) calc(64px + var(--space-6));max-width:480px;margin:0 auto}.settings__title[data-v-1446e085]{font-size:var(--text-xl);margin-bottom:var(--space-6);font-weight:700}.settings__section[data-v-1446e085]{margin-bottom:var(--space-6)}.settings__section-title[data-v-1446e085]{font-size:var(--text-sm);color:var(--color-text-muted);text-transform:uppercase;letter-spacing:.06em;margin-bottom:var(--space-3);font-weight:700}.settings__row[data-v-1446e085]{padding:var(--space-3) 0;border-bottom:1px solid var(--color-border);font-size:var(--text-base);justify-content:space-between;align-items:center;display:flex}.settings__row-label[data-v-1446e085]{color:var(--color-text-muted)}.settings__row-value[data-v-1446e085]{font-weight:600}.settings__logout[data-v-1446e085]{min-height:var(--touch-min);padding:var(--space-3) 0;color:var(--color-destructive);font-weight:600;font-size:var(--text-base);align-items:center;text-decoration:none;display:flex}.theme-grid[data-v-1446e085]{gap:var(--space-3);grid-template-columns:repeat(3,1fr);display:grid}.theme-swatch[data-v-1446e085]{align-items:center;gap:var(--space-2);padding:var(--space-3);background:var(--swatch-bg);border-radius:var(--radius-md);cursor:pointer;transition:border-color var(--duration-fast);min-height:var(--touch-min);border:2px solid #0000;flex-direction:column;display:flex;position:relative}.theme-swatch--active[data-v-1446e085]{border-color:var(--swatch-primary)}.theme-swatch__preview[data-v-1446e085]{border-radius:var(--radius-sm);background:var(--swatch-bg);border:1px solid color-mix(in srgb, var(--swatch-text) 15%, transparent);flex-direction:column;justify-content:center;gap:4px;width:100%;height:36px;padding:0 6px;display:flex}.theme-swatch__bar[data-v-1446e085]{background:var(--swatch-primary);border-radius:3px;width:60%;height:6px;display:block}.theme-swatch__dot[data-v-1446e085]{background:var(--swatch-text);opacity:.4;border-radius:2px;width:80%;height:4px;display:block}.theme-swatch__label[data-v-1446e085]{font-size:var(--text-xs);color:var(--color-text);text-align:center;font-weight:600;line-height:1.2}.theme-swatch__check[data-v-1446e085]{top:var(--space-1);right:var(--space-2);font-size:var(--text-sm);color:var(--swatch-primary);font-weight:700;position:absolute}
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{K as e,dt as t,f as n,ft as r,j as i,k as a,l as o,o as s,p as c,pt as l,t as u,u as d,v as f}from"./_plugin-vue_export-helper-DVo1OUMD.js";import{n as p,r as m,t as h}from"./index-DCUs53vX.js";var g={class:`settings`},_={class:`settings__section`},v={class:`theme-grid`,role:`radiogroup`,"aria-label":`Choose theme`},y=[`aria-checked`,`aria-label`,`onClick`],b={class:`theme-swatch__label`},x={key:0,class:`theme-swatch__check`,"aria-hidden":`true`},S={class:`settings__section`},C={class:`settings__row`},w={class:`settings__row-value`},T=u(f({__name:`SettingsView`,setup(u){let f=m(),{saveTheme:T}=p(),E=o(()=>f.user?.theme??`warm-craft`);function D(e){T(e)}return(o,u)=>(a(),c(`main`,g,[u[5]||=d(`h1`,{class:`settings__title`},`Settings`,-1),d(`section`,_,[u[1]||=d(`h2`,{class:`settings__section-title`},`Theme`,-1),d(`div`,v,[(a(!0),c(s,null,i(e(h),e=>(a(),c(`button`,{key:e.id,type:`button`,role:`radio`,"aria-checked":E.value===e.id,"aria-label":e.label,class:t([`theme-swatch`,{"theme-swatch--active":E.value===e.id}]),style:r({"--swatch-bg":e.bg,"--swatch-primary":e.primary,"--swatch-text":e.text}),onClick:t=>D(e.id)},[u[0]||=d(`span`,{class:`theme-swatch__preview`,"aria-hidden":`true`},[d(`span`,{class:`theme-swatch__bar`}),d(`span`,{class:`theme-swatch__dot`})],-1),d(`span`,b,l(e.label),1),E.value===e.id?(a(),c(`span`,x,`✓`)):n(``,!0)],14,y))),128))])]),d(`section`,S,[u[3]||=d(`h2`,{class:`settings__section-title`},`Account`,-1),d(`div`,C,[u[2]||=d(`span`,{class:`settings__row-label`},`Signed in as`,-1),d(`span`,w,l(e(f).user?.email),1)]),u[4]||=d(`a`,{href:`/logout`,class:`settings__logout`},`Sign out`,-1)])]))}}),[[`__scopeId`,`data-v-1446e085`]]);export{T as default};
|
||||
import{K as e,dt as t,f as n,ft as r,j as i,k as a,l as o,o as s,p as c,pt as l,t as u,u as d,v as f}from"./_plugin-vue_export-helper-DVo1OUMD.js";import{n as p,r as m,t as h}from"./index-D13oAsTG.js";var g={class:`settings`},_={class:`settings__section`},v={class:`theme-grid`,role:`radiogroup`,"aria-label":`Choose theme`},y=[`aria-checked`,`aria-label`,`onClick`],b={class:`theme-swatch__label`},x={key:0,class:`theme-swatch__check`,"aria-hidden":`true`},S={class:`settings__section`},C={class:`settings__row`},w={class:`settings__row-value`},T=u(f({__name:`SettingsView`,setup(u){let f=m(),{saveTheme:T}=p(),E=o(()=>f.user?.theme??`warm-craft`);function D(e){T(e)}return(o,u)=>(a(),c(`main`,g,[u[5]||=d(`h1`,{class:`settings__title`},`Settings`,-1),d(`section`,_,[u[1]||=d(`h2`,{class:`settings__section-title`},`Theme`,-1),d(`div`,v,[(a(!0),c(s,null,i(e(h),e=>(a(),c(`button`,{key:e.id,type:`button`,role:`radio`,"aria-checked":E.value===e.id,"aria-label":e.label,class:t([`theme-swatch`,{"theme-swatch--active":E.value===e.id}]),style:r({"--swatch-bg":e.bg,"--swatch-primary":e.primary,"--swatch-text":e.text}),onClick:t=>D(e.id)},[u[0]||=d(`span`,{class:`theme-swatch__preview`,"aria-hidden":`true`},[d(`span`,{class:`theme-swatch__bar`}),d(`span`,{class:`theme-swatch__dot`})],-1),d(`span`,b,l(e.label),1),E.value===e.id?(a(),c(`span`,x,`✓`)):n(``,!0)],14,y))),128))])]),d(`section`,S,[u[3]||=d(`h2`,{class:`settings__section-title`},`Account`,-1),d(`div`,C,[u[2]||=d(`span`,{class:`settings__row-label`},`Signed in as`,-1),d(`span`,w,l(e(f).user?.email),1)]),u[4]||=d(`a`,{href:`/logout`,class:`settings__logout`},`Sign out`,-1)])]))}}),[[`__scopeId`,`data-v-76ec3881`]]);export{T as default};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
+13
-4
@@ -2,12 +2,21 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
||||
<title>pictureFrame</title>
|
||||
|
||||
<link rel="icon" type="image/svg+xml" href="/build/favicon.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>frontend</title>
|
||||
<script type="module" crossorigin src="/build/assets/index-DCUs53vX.js"></script>
|
||||
<link rel="manifest" href="/build/manifest.webmanifest" />
|
||||
<link rel="apple-touch-icon" href="/build/icons/apple-touch-icon.png" />
|
||||
|
||||
<meta name="theme-color" content="#fdf6ee" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
||||
<meta name="apple-mobile-web-app-title" content="pictureFrame" />
|
||||
<script type="module" crossorigin src="/build/assets/index-D13oAsTG.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/build/assets/_plugin-vue_export-helper-DVo1OUMD.js">
|
||||
<link rel="stylesheet" crossorigin href="/build/assets/index-DlN2hqev.css">
|
||||
<link rel="stylesheet" crossorigin href="/build/assets/index-BlLBHR1q.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "pictureFrame",
|
||||
"short_name": "pictureFrame",
|
||||
"description": "Manage photos for your e-ink picture frames.",
|
||||
"id": "/",
|
||||
"start_url": "/",
|
||||
"scope": "/",
|
||||
"display": "standalone",
|
||||
"orientation": "portrait",
|
||||
"background_color": "#fdf6ee",
|
||||
"theme_color": "#fdf6ee",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/build/icons/icon-192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"purpose": "any"
|
||||
},
|
||||
{
|
||||
"src": "/build/icons/icon-512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "any"
|
||||
},
|
||||
{
|
||||
"src": "/build/icons/icon-512-maskable.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user