experiments in a post-browser web
10
fork

Configure Feed

Select the types of activity you want to include in your feed.

docs: add AGENT-TASKS.md with open tasks (webview UA fix, notes-with-URLs)

+67 -3
+64
AGENT-TASKS.md
··· 1 + # Open Tasks for Next Agent 2 + 3 + ## Task 1: iOS Webview — Set User-Agent to Fix Site Rejection 4 + 5 + **Status:** Research complete, implementation needed 6 + 7 + **Problem:** Inline webviews in the Tauri iOS app are rejected by YouTube, Reddit, and other sites. Wikipedia works fine. 8 + 9 + **Root cause:** WKWebView's default User-Agent string is missing `Version/X.X` and `Safari/604.1` tokens that Safari includes. Sites server-side detect this absence and reject the webview. 10 + 11 + **Solution:** Set `customUserAgent` on the inline WKWebView to match Safari's UA: 12 + 13 + ``` 14 + Mozilla/5.0 (iPhone; CPU iPhone OS 18_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.2 Mobile/15E148 Safari/604.1 15 + ``` 16 + 17 + This is exactly what Firefox iOS, Brave iOS, Chrome iOS, and DuckDuckGo all do (all iOS browsers use WKWebView under the hood). 18 + 19 + **Implementation options (ranked):** 20 + 1. **Tauri config:** `tauri.conf.json` supports `userAgent` per window — but may only apply to main window, not child webviews 21 + 2. **Tauri iOS Swift plugin:** Create a plugin with `load(webview:)` hook to set `customUserAgent` on inline WKWebView instances 22 + 3. **Wry's Rust API:** `WebViewBuilder::with_user_agent()` if creating webviews from Rust 23 + 24 + **Additional settings needed on inline WKWebView:** 25 + - `allowsInlineMediaPlayback = true` (for video on YouTube/Reddit) 26 + - Don't register `WKScriptMessageHandler` on the content webview (or inject JS to clean up `window.webkit.messageHandlers`) 27 + 28 + **Full research:** See research output at `/private/tmp/claude-501/-Users-dietrich-misc-mpeek-tmp-release-7140/tasks/aacd54a.output` 29 + 30 + --- 31 + 32 + ## Task 2: Notes with URLs — Open as Web Pages (Mobile App) 33 + 34 + **Status:** Wrong target implemented, needs redo for mobile 35 + 36 + **Problem:** Note-type items containing URLs should be openable as web pages, using the same webview mechanism that URL-type items use. 37 + 38 + **What was done (WRONG TARGET):** Commit `mrwsnryu` (14a36011) modified `extensions/tags/home.js`, `extensions/tags/home.html`, `extensions/tags/home.css`, and `extensions/groups/background.js`. These are **Electron desktop** extensions, NOT the Tauri mobile app. 39 + 40 + **What needs to happen:** The mobile app frontend is in `backend/tauri-mobile/src/App.tsx` (125KB React app). The feature needs to be implemented THERE, not in the extensions/ directory. 41 + 42 + **Implementation approach:** 43 + 1. Read `App.tsx` to find how URL-type items currently trigger web page viewing 44 + 2. Add URL detection for text/note items (extract first URL from content) 45 + 3. Wire up the same web page viewing path for notes that contain URLs 46 + 4. Show visual indicator (link icon, "Open Page" button) on note cards with URLs 47 + 48 + **The `extractUrl()` logic from the desktop implementation is reusable** (priority: full URL → bare domain → embedded URL, validated with `URL` constructor). 49 + 50 + --- 51 + 52 + ## Build Notes Discovered 53 + 54 + ### Stale Rust Cache (CRITICAL) 55 + - Changing `Cargo.toml` features (e.g., removing `custom-protocol`) does NOT invalidate the Tauri dependency's build cache 56 + - `build-ios.sh --force` only recompiles the app crate, not dependencies 57 + - **Must run `npm run clean:rust:full`** (from `backend/tauri-mobile/`) to clear dependency caches when changing features 58 + - Symptom: blank white page in simulator (loads bundled assets instead of devUrl) 59 + - Verify fix: check that `/target/aarch64-apple-ios-sim/debug/build/tauri-*/out/checked_features` does NOT contain `custom-protocol` for dev builds 60 + 61 + ### Dev Session Race Condition 62 + - `dev-ios-sim.sh` launches the app BEFORE starting vite → WKWebView gets connection refused → blank page 63 + - Workaround: run `npm run sim:launch` to relaunch after vite is up 64 + - Should be fixed: start vite first, wait for ready, then launch app
+1 -1
backend/tauri-mobile/BUILD_NUMBER
··· 1 - 1037 1 + 1039
+1 -1
backend/tauri-mobile/src-tauri/gen/apple/assets/assets/index-DbCPW-hJ.js backend/tauri-mobile/src-tauri/gen/apple/assets/assets/index-BsaIPLIs.js
··· 12 12 ${F}${mt} `,il=r+ge+j;Y(il),requestAnimationFrame(()=>{if(ct.current){const yl=W+ge.length;ct.current.selectionStart=yl,ct.current.selectionEnd=yl}})}};return z.useEffect(()=>{const U=r=>ce(r.clientY),J=r=>{r.touches.length===1&&ce(r.touches[0].clientY)},W=()=>b();return document.addEventListener("mousemove",U),document.addEventListener("mouseup",W),document.addEventListener("touchmove",J,{passive:!0}),document.addEventListener("touchend",W),()=>{document.removeEventListener("mousemove",U),document.removeEventListener("mouseup",W),document.removeEventListener("touchmove",J),document.removeEventListener("touchend",W)}},[Ut]),z.useEffect(()=>{if(!k)return;const U=setTimeout(()=>{if(ct.current){ct.current.focus();const J=ct.current.value.length;ct.current.selectionStart=J,ct.current.selectionEnd=J}},50);return()=>clearTimeout(U)},[]),s.jsxs(s.Fragment,{children:[s.jsxs("div",{className:"undo-redo-buttons",children:[s.jsx("button",{type:"button",onClick:le,disabled:Qt.current<=0,title:"Undo",children:s.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("polyline",{points:"1 4 1 10 7 10"}),s.jsx("path",{d:"M3.51 15a9 9 0 1 0 2.13-9.36L1 10"})]})}),s.jsx("button",{type:"button",onClick:yt,disabled:Qt.current>=St.current.length-1,title:"Redo",children:s.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("polyline",{points:"23 4 23 10 17 10"}),s.jsx("path",{d:"M20.49 15a9 9 0 1 1-2.13-9.36L23 10"})]})})]}),s.jsxs("div",{className:"resizable-input-wrapper",ref:V,style:$!=null?{height:`${je}px`,minHeight:`${Ut}px`}:{minHeight:`${Ut}px`},children:[s.jsx("textarea",{ref:ct,className:"resizable-input-textarea",value:E,onChange:U=>{const J=U.target.value.replace(/^(\s*(?:[-*+]|\d+\.))\s{2,}/gm,"$1 ");Y(J),gt&&gt(J)},onFocus:()=>{requestAnimationFrame(()=>window.scrollTo(0,0))},onKeyDown:M,placeholder:B,autoCapitalize:H,autoCorrect:T,autoComplete:"off",spellCheck:T==="on"}),rt&&s.jsx(Kc,{show:E.length>0,onClear:()=>Y(""),className:"textarea-clear"}),s.jsx("div",{className:"drag-handle",onMouseDown:U=>{U.preventDefault(),Kt(U.clientY)},onTouchStart:U=>{Kt(U.touches[0].clientY)},children:s.jsx("div",{className:"drag-handle-bar"})})]})]})},pm=()=>{const[E,Y]=z.useState(0),B=z.useRef(0);return z.useEffect(()=>{const v=window.visualViewport;if(!v)return;const q=()=>{const k=Math.max(0,window.innerHeight-v.height);k===0?(B.current=0,Y(0)):(B.current=Math.max(B.current,k),Y(B.current))};return v.addEventListener("resize",q),v.addEventListener("scroll",q),()=>{v.removeEventListener("resize",q),v.removeEventListener("scroll",q)}},[]),E};function Sm(){z.useEffect(()=>{const c=Math.floor(Math.random()*360);document.documentElement.style.setProperty("--dev-bg-light",`hsl(${c}, 80%, 85%)`),document.documentElement.style.setProperty("--dev-bg-dark",`hsl(${c}, 15%, 12%)`)},[]);const[E,Y]=z.useState("all"),[B,v]=z.useState([]),[q,k]=z.useState([]),[rt,gt]=z.useState([]),[H,T]=z.useState([]),[$,Q]=z.useState([]),[V,ct]=z.useState(null),[wt,Ht]=z.useState(""),[ee,St]=z.useState(new Set),[Qt,At]=z.useState([]),[Xt,le]=z.useState(""),[yt,lt]=z.useState(null),[It,Te]=z.useState(""),[ve,ie]=z.useState(new Set),[Ut,je]=z.useState(""),[Kt,ce]=z.useState(null),[b,M]=z.useState(new Set),[U,J]=z.useState(""),[W,r]=z.useState(null),[j,O]=z.useState(new Set),[R,Z]=z.useState(""),[F,nt]=z.useState(""),[zt,mt]=z.useState(new Set),[ae,ge]=z.useState(!1),[il,yl]=z.useState(""),pl=300,[Sl,hn]=z.useState(null),[ou,mn]=z.useState(!1),[ru,Da]=z.useState(!1),[vn,du]=z.useState(!1),[Ma,ye]=z.useState(null),[bl,Oa]=z.useState(new Set),[qe,xl]=z.useState(""),gi=z.useRef(null),$l=z.useRef(null),gn=z.useRef(null),[yn,Tl]=z.useState(null),[Lt,Ye]=z.useState(()=>localStorage.getItem("searchText")||""),[Bt,hu]=z.useState(()=>{const c=localStorage.getItem("selectedFilterTags");return c?new Set(JSON.parse(c)):new Set}),[Ua,Jc]=z.useState(()=>localStorage.getItem("sortOrder")||"newest"),[El,pn]=z.useState(()=>{const c=localStorage.getItem("filterTagsHeight");return c?parseInt(c,10):116}),Ra=z.useRef(null),Ge=z.useRef(!1),jl=z.useRef(!1),Il=z.useRef(0),yi=z.useRef(0),[Sn,bn]=z.useState(null),_l=z.useRef(null),qt=(c,h="success")=>{_l.current&&clearTimeout(_l.current),bn({message:c,type:h}),_l.current=setTimeout(()=>bn(null),3e3)},[xn,Al]=z.useState(null),[Pt,Me]=z.useState(null),[Tn,mu]=z.useState(!1),[pi,tl]=z.useState(!1),[Nt,se]=z.useState(""),[el,En]=z.useState(""),[kc,Si]=z.useState(""),[wa,Pl]=z.useState(""),[vu,zl]=z.useState(!1),[cl,Ha]=z.useState(!1),[_e,Ct]=z.useState(!1),[La,tt]=z.useState(null),[sl,Nl]=z.useState(null),[jn,bi]=z.useState(null),[Dt,_n]=z.useState(null),[Cl,Dl]=z.useState(""),[Qe,pe]=z.useState(!1),[ta,xi]=z.useState("archive"),[ea,gu]=z.useState("archive"),Xe=pm(),Ml=z.useRef(null),Jt=z.useRef(null),[la,Ol]=z.useState("idle"),An=80,aa=300,yu=c=>{Ge.current=!0,jl.current=!0,Il.current=c,yi.current=Ra.current?.offsetHeight??El,document.body.style.userSelect="none",document.body.style.cursor="ns-resize"};z.useEffect(()=>{const c=D=>{if(!Ge.current)return;const pt=D-Il.current,at=Math.max(71,yi.current+pt);pn(at)},h=D=>c(D.clientY),N=D=>{D.touches.length===1&&c(D.touches[0].clientY)},C=()=>{Ge.current&&(Ge.current=!1,jl.current=!1,document.body.style.userSelect="",document.body.style.cursor="",localStorage.setItem("filterTagsHeight",String(Math.round(El))))};return document.addEventListener("mousemove",h),document.addEventListener("mouseup",C),document.addEventListener("touchmove",N,{passive:!0}),document.addEventListener("touchend",C),()=>{document.removeEventListener("mousemove",h),document.removeEventListener("mouseup",C),document.removeEventListener("touchmove",N),document.removeEventListener("touchend",C)}},[El]),z.useEffect(()=>{localStorage.setItem("searchText",Lt)},[Lt]),z.useEffect(()=>{localStorage.setItem("selectedFilterTags",JSON.stringify(Array.from(Bt)))},[Bt]),z.useEffect(()=>{localStorage.setItem("sortOrder",Ua)},[Ua]),z.useEffect(()=>{},[]),z.useEffect(()=>{const c=async()=>{try{const D=await X("is_dark_mode");mu(D)}catch{const pt=window.matchMedia("(prefers-color-scheme: dark)");mu(pt.matches)}};c();const h=window.matchMedia("(prefers-color-scheme: dark)"),N=()=>c();h.addEventListener("change",N);const C=()=>{document.visibilityState==="visible"&&c()};return document.addEventListener("visibilitychange",C),()=>{h.removeEventListener("change",N),document.removeEventListener("visibilitychange",C)}},[]),z.useEffect(()=>{document.body.classList.toggle("dark",Tn)},[Tn]),z.useEffect(()=>{const c=()=>{Ze(),Ve(),Oe(),fe(),oe()},h=async()=>{try{await X("auto_sync_if_needed")}catch(C){console.log("Auto-sync check:",C)}};c(),Ti(),na(),Wc(),_i(),zn(),Nn(),ji(),h();const N=()=>{document.visibilityState==="visible"&&(c(),h())};return document.addEventListener("visibilitychange",N),()=>{document.removeEventListener("visibilitychange",N)}},[]),z.useEffect(()=>{let c;return(async()=>{c=await ym("webview:navigated",async N=>{const{itemId:C}=N.payload;try{await X("record_visit",{itemId:C,source:"webview",windowType:"embedded"})}catch(D){console.error("Failed to record webview visit:",D)}})})(),()=>{c&&c()}},[]),z.useEffect(()=>{const c=()=>{document.visibilityState==="visible"&&ae&&!F.trim()&&zt.size===0&&ge(!1)};return document.addEventListener("visibilitychange",c),()=>{document.removeEventListener("visibilitychange",c)}},[ae,F,zt]);const Ti=async()=>{try{const c=await X("get_webhook_url");c&&(se(c),En(c))}catch(c){console.error("Failed to load webhook URL:",c)}},na=async()=>{try{const c=await X("get_webhook_api_key");c&&(Si(c),Pl(c))}catch(c){console.error("Failed to load webhook API key:",c)}},Wc=async()=>{try{const c=await X("get_auto_sync");zl(c)}catch(c){console.error("Failed to load auto-sync setting:",c)}},Ei=async c=>{try{await X("set_auto_sync",{enabled:c}),zl(c)}catch(h){console.error("Failed to set auto-sync:",h)}},ji=async()=>{try{const c=await X("get_archive_tag");xi(c),gu(c)}catch(c){console.error("Failed to load archive tag:",c)}},pu=async()=>{try{await X("set_archive_tag",{tag:ea}),xi(ea)}catch(c){console.error("Failed to save archive tag:",c)}},_i=async()=>{try{const c=await X("get_last_sync");Nl(c)}catch(c){console.error("Failed to load last sync:",c)}},zn=async()=>{try{const c=await X("get_sync_status");bi(c),c.last_sync_time&&Nl(c.last_sync_time)}catch(c){console.error("Failed to load sync status:",c)}},Nn=async()=>{try{const c=await X("get_profile_info");_n(c),Dl("")}catch(c){console.error("Failed to load profile info:",c)}},ll=async c=>{console.log(`[Profile] setProfile called with: ${c}`);try{console.log("[Profile] Invoking set_profile command...");const h=await X("set_profile",{profileId:c});console.log("[Profile] set_profile returned:",h),_n(h),Dl(""),pe(!0)}catch(h){console.error("[Profile] Failed to set profile:",h),tt(`Failed: ${h}`),setTimeout(()=>tt(null),3e3)}},Cn=async()=>{try{await X("quit_app")}catch(c){console.error("Failed to quit:",c)}},Su=async()=>{try{await X("set_webhook_url",{url:el}),await X("set_webhook_api_key",{key:wa}),se(el),Si(wa),tt("Settings saved"),setTimeout(()=>tt(null),2e3)}catch(c){console.error("Failed to save webhook settings:",c),tt("Failed to save settings"),setTimeout(()=>tt(null),3e3)}},Ul=async()=>{if(!Nt){qt("Please configure server URL first","error");return}Ct(!0),qt("Syncing...");try{const c=await X("sync_all"),h=`Synced: ${c.pulled} pulled, ${c.pushed} pushed${c.conflicts>0?`, ${c.conflicts} conflicts`:""}`;qt(h),tt(h),await _i(),await zn(),Ze(),Ve(),Oe(),fe(),oe(),setTimeout(()=>tt(null),4e3)}catch(c){console.error("Failed to sync:",c);const h=`Sync failed: ${c}`;qt(h,"error"),tt(h),setTimeout(()=>tt(null),5e3)}finally{Ct(!1)}},ua=async()=>{if(!Nt){tt("Please save a server URL first"),setTimeout(()=>tt(null),3e3);return}Ct(!0),tt(null);try{const c=await X("pull_from_server"),h=`Pulled ${c.pulled} items${c.conflicts>0?`, ${c.conflicts} conflicts`:""}`;tt(h),await zn(),Ze(),Ve(),Oe(),fe(),oe(),setTimeout(()=>tt(null),4e3)}catch(c){console.error("Failed to pull:",c),tt(`Pull failed: ${c}`),setTimeout(()=>tt(null),5e3)}finally{Ct(!1)}},Ai=async()=>{if(!Nt){tt("Please save a server URL first"),setTimeout(()=>tt(null),3e3);return}Ct(!0),tt(null);try{const c=await X("push_to_server");tt(`Pushed ${c.pushed} items`),await zn(),setTimeout(()=>tt(null),4e3)}catch(c){console.error("Failed to push:",c),tt(`Push failed: ${c}`),setTimeout(()=>tt(null),5e3)}finally{Ct(!1)}},Ze=async()=>{try{const c=await X("get_saved_urls");v(c)}catch(c){console.error("Failed to load saved URLs:",c)}},Ve=async()=>{try{const c=await X("get_saved_texts");k(c)}catch(c){console.error("Failed to load saved texts:",c)}},Oe=async()=>{try{const c=await X("get_saved_tagsets");gt(c)}catch(c){console.error("Failed to load saved tagsets:",c)}},fe=async()=>{try{const c=await X("get_saved_images");T(c)}catch(c){console.error("Failed to load saved images:",c)}},oe=async()=>{try{const c=await X("get_tags_by_frecency");Q(c)}catch(c){console.error("Failed to load tags:",c)}},Ba=()=>Pt?wt!==Pt.url||JSON.stringify(Array.from(ee).sort())!==JSON.stringify(Pt.tags):!1,fl=()=>Pt?It!==Pt.content||JSON.stringify(Array.from(ve).sort())!==JSON.stringify(Pt.tags):!1,bu=()=>Pt?JSON.stringify(Array.from(b).sort())!==JSON.stringify(Pt.tags):!1,Dn=()=>Pt?JSON.stringify(Array.from(j).sort())!==JSON.stringify(Pt.tags):!1,zi=async c=>{$l.current?.focus(),ct(c.id),Ht(c.url),St(new Set(c.tags)),le(""),Me({url:c.url,tags:[...c.tags].sort()});try{const h=await X("get_tags_by_frecency_for_url",{url:c.url});At(h)}catch(h){console.error("Failed to load domain-boosted tags:",h),At($)}},Rl=()=>{ct(null),Ht(""),St(new Set),At([]),le(""),Me(null)},qa=()=>{Ba()?Al({type:"page"}):Rl()},Ni=async c=>{console.log("[Frontend] deleteUrl called for id:",c);try{await X("delete_url",{id:c}),console.log("[Frontend] delete_url invoke succeeded"),await Ze(),Rl()}catch(h){console.error("[Frontend] Failed to delete URL:",h)}},Se=c=>{const h=new Set(ee);h.has(c)?h.delete(c):h.add(c),St(h)},wl=()=>{const c=new Set(ee),h=Xt.split(",");let N=!1;for(const C of h){const D=C.trim().toLowerCase();D&&!c.has(D)&&(c.add(D),N=!0)}N&&St(c),le("")},Mn=async()=>{if(!V)return;const c=new Set(ee);if(Xt.trim()){for(const h of Xt.split(",").map(N=>N.trim().toLowerCase()).filter(N=>N.length>0))c.add(h);le("")}try{await X("update_url",{id:V,url:wt,tags:Array.from(c)}),await Ze(),await oe(),Rl(),qt("Page saved")}catch(h){console.error("[Frontend] Failed to update URL:",h),qt("Failed to save page","error")}},Ya=c=>{console.log("[toggleAddInputTag] toggling tag:",c);const h=new Set(zt);h.has(c)?h.delete(c):h.add(c),console.log("[toggleAddInputTag] new tags:",Array.from(h)),mt(h)},xu=()=>{nt(""),mt(new Set),ge(!1),yl("")},Tu=()=>{const c=new Set(zt),h=il.split(",");for(const N of h){const C=N.trim().toLowerCase();C&&c.add(C)}mt(c),yl("")},Eu=()=>{gi.current?.click()},Ga=c=>{const h=c.target.files?.[0];if(!h)return;const N=new FileReader;N.onload=C=>{const D=C.target?.result;ye(D),Oa(new Set),xl("")},N.readAsDataURL(h),c.target.value=""},Qa=c=>{const h=new Set(bl);h.has(c)?h.delete(c):h.add(c),Oa(h)},ju=()=>{const c=new Set(bl),h=qe.split(",");for(const N of h){const C=N.trim().toLowerCase();C&&c.add(C)}Oa(c),xl("")},_u=()=>{ye(null),Oa(new Set),xl("")},Fc=async()=>{if(!Ma)return;const c=new Set(bl);if(qe.trim()){const h=qe.split(",");for(const N of h){const C=N.trim().toLowerCase();C&&c.add(C)}}try{const h=Ma.split(",")[1],N=Ma.split(";")[0].split(":")[1];await X("save_captured_image",{imageData:h,mimeType:N,tags:Array.from(c)}),_u(),await fe(),await oe()}catch(h){console.error("Failed to save captured image:",h)}},$c=async()=>{const c=F.trim(),h=new Set(zt);if(console.log("[saveAddInput] addInputTags:",Array.from(zt)),il.trim()){const D=il.split(",");for(const pt of D){const at=pt.trim().toLowerCase();at&&h.add(at)}}const N=Array.from(h);if(console.log("[saveAddInput] final tags to save:",N),c.startsWith("http://")||c.startsWith("https://"))try{await X("save_url",{url:c,tags:N}),xu(),await Ze(),await oe(),qt("Page saved")}catch(D){console.error("Failed to save URL:",D),qt("Failed to save page","error")}else if(c)try{console.log("[saveAddInput] Saving text with tags:",{content:c,tags:N}),await X("save_text",{content:c,tags:N}),xu(),await Ve(),await oe(),qt("Note saved")}catch(D){console.error("Failed to save text:",D),qt("Failed to save note","error")}else if(N.length>0)try{await X("save_tagset",{tags:N}),xu(),await Oe(),await oe(),qt("Tags saved")}catch(D){console.error("Failed to save tagset:",D),qt("Failed to save tags","error")}},Au=()=>{const c=F.trim();return c.startsWith("http://")||c.startsWith("https://")?"url":c?"text":zt.size>0?"tagset":null},Ic=c=>{$l.current?.focus(),lt(c.id),Te(c.content);const h=c.tags.length>0?c.tags:Ui(c.content);ie(new Set(h)),je(""),Me({content:c.content,tags:[...h].sort()})},On=()=>{lt(null),Te(""),ie(new Set),je(""),Me(null)},Ci=()=>{fl()?Al({type:"text"}):On()},Pc=c=>{const h=new Set(ve);h.has(c)?h.delete(c):h.add(c),ie(h)},ts=()=>{const c=Ut.trim().toLowerCase();c&&(ie(new Set(ve).add(c)),je(""))},ol=z.useRef(null),es=z.useCallback(c=>{!yt||!Pt||(ol.current&&clearTimeout(ol.current),c.trim()!==Pt.content&&(ol.current=setTimeout(async()=>{try{await X("update_text",{id:yt,content:c.trim(),tags:Array.from(ve)}),Me(h=>h?{...h,content:c.trim()}:null),await Ve()}catch(h){console.error("Auto-save failed:",h)}},500)))},[yt,Pt,ve]);z.useEffect(()=>()=>{ol.current&&clearTimeout(ol.current)},[yt]);const ls=async()=>{if(!yt)return;ol.current&&clearTimeout(ol.current);const c=new Set(ve);if(Ut.trim())for(const h of Ut.split(",").map(N=>N.trim().toLowerCase()).filter(N=>N.length>0))c.add(h);try{await X("update_text",{id:yt,content:It.trim(),tags:Array.from(c)}),await Ve(),await oe(),On(),qt("Note saved")}catch(h){console.error("Failed to update text:",h),qt("Failed to save note","error")}},as=async c=>{try{await X("delete_url",{id:c}),await Ve(),On()}catch(h){console.error("Failed to delete text:",h)}},ns=c=>{$l.current?.focus(),ce(c.id),M(new Set(c.tags)),J(""),Me({tags:[...c.tags].sort()})},ia=()=>{ce(null),M(new Set),J(""),Me(null)},Di=()=>{bu()?Al({type:"tagset"}):ia()},us=c=>{const h=new Set(b);h.has(c)?h.delete(c):h.add(c),M(h)},is=()=>{const c=new Set(b),h=U.split(",");for(const N of h){const C=N.trim().toLowerCase();C&&c.add(C)}M(c),J("")},Mi=async()=>{if(!Kt)return;const c=new Set(b);if(U.trim())for(const h of U.split(",").map(N=>N.trim().toLowerCase()).filter(N=>N.length>0))c.add(h);if(c.size===0){qt("At least one tag is required","error");return}try{await X("update_tagset",{id:Kt,tags:Array.from(c)}),await Oe(),await oe(),ia(),qt("Tags saved")}catch(h){console.error("Failed to update tagset:",h),qt("Failed to save tags","error")}},cs=async c=>{try{await X("delete_url",{id:c}),await Oe(),ia()}catch(h){console.error("Failed to delete tagset:",h)}},ss=c=>{$l.current?.focus(),r(c.id),O(new Set(c.tags)),Z(""),Me({tags:[...c.tags].sort()})},Un=()=>{r(null),O(new Set),Z(""),Me(null)},Oi=()=>{Dn()?Al({type:"image"}):Un()},fs=c=>{const h=new Set(j);h.has(c)?h.delete(c):h.add(c),O(h)},os=()=>{const c=new Set(j),h=R.split(",");for(const N of h){const C=N.trim().toLowerCase();C&&c.add(C)}O(c),Z("")},rs=async()=>{if(!W)return;const c=new Set(j);if(R.trim()){const h=R.split(",");for(const N of h){const C=N.trim().toLowerCase();C&&c.add(C)}}try{await X("update_image_tags",{id:W,tags:Array.from(c)}),await fe(),await oe(),Un(),qt("Image saved")}catch(h){console.error("Failed to update image:",h),qt("Failed to save image","error")}},Ui=c=>{const h=c.match(/#(\w+)/g);return h?h.map(N=>N.slice(1).toLowerCase()):[]},Rn=c=>{Y(E===c?"all":c)},wn=()=>{gn.current?.scrollTo({top:0,behavior:"smooth"})},Xa=c=>{if(V||yt||Kt||W||ae||_e||jl.current||document.body.dataset.resizing)return;const N=gn.current;N&&N.scrollTop<=0&&(Ml.current=c.touches[0].clientY,Jt.current=null,Ol("idle"))},Ri=c=>{if(Ml.current===null)return;if(jl.current||document.body.dataset.resizing){Ml.current=null,Jt.current=null,Ol("idle");return}c.touches[0].clientY-Ml.current>An?(c.preventDefault(),Jt.current===null?(Jt.current=Date.now(),Ol("pulling")):Date.now()-Jt.current>=aa&&Ol("ready")):(Jt.current=null,Ol("idle"))},wi=c=>{if(Ml.current===null)return;const h=c.changedTouches[0].clientY-Ml.current,N=la==="ready";Ml.current=null,Jt.current=null,Ol("idle"),h>An&&N&&Ul()};z.useEffect(()=>{const c=gn.current;if(c)return c.addEventListener("touchmove",Ri,{passive:!1}),()=>{c.removeEventListener("touchmove",Ri)}},[V,yt,Kt,W,ae,_e]);const Hi=()=>{Y("all"),Ye(""),hu(new Set),wn()},Li=c=>{const h=new Set(Bt);h.has(c)?h.delete(c):h.add(c),hu(h)},zu=()=>{if(!Lt.trim())return $;const c=Lt.toLowerCase();return $.filter(h=>h.name.toLowerCase().includes(c))},Bi=()=>{const c=[],h=D=>E==="all"||E===D;h("page")&&B.forEach(D=>{c.push({id:D.id,type:"page",url:D.url,tags:D.tags,saved_at:D.saved_at,metadata:D.metadata})}),h("text")&&q.forEach(D=>{c.push({id:D.id,type:"text",content:D.content,tags:D.tags,saved_at:D.saved_at,metadata:D.metadata})}),h("tagset")&&rt.forEach(D=>{c.push({id:D.id,type:"tagset",tags:D.tags,saved_at:D.saved_at,metadata:D.metadata})}),h("image")&&H.forEach(D=>{c.push({id:D.id,type:"image",tags:D.tags,saved_at:D.saved_at,metadata:D.metadata,thumbnail:D.thumbnail,mime_type:D.mime_type,width:D.width,height:D.height})});const N=Lt.toLowerCase();return c.filter(D=>{const pt=!Lt.trim()||D.tags.some(ca=>ca.toLowerCase().includes(N))||D.url?.toLowerCase().includes(N)||D.content?.toLowerCase().includes(N)||D.metadata?.title?.toLowerCase().includes(N),at=Bt.size===0||Array.from(Bt).every(ca=>D.tags.includes(ca)),ne=ta&&D.tags.includes(ta),Fa=ta&&Bt.has(ta);return ne&&!Fa?!1:pt&&at}).sort((D,pt)=>{const at=new Date(pt.saved_at).getTime()-new Date(D.saved_at).getTime();return Ua==="oldest"?-at:at})},rl=V||yt||Kt||W;z.useEffect(()=>(rl||ae?document.body.classList.add("editor-open"):document.body.classList.remove("editor-open"),()=>{document.body.classList.remove("editor-open")}),[rl,ae]);const ds=()=>{if(!rl)return null;if(V)return B.find(h=>h.id===V)?s.jsxs(hi,{onDismiss:qa,keyboardHeight:Xe,className:"text-editor-overlay",children:[s.jsxs("div",{className:"input-with-clear editor-url-wrapper",children:[s.jsx("input",{type:"url",className:"editor-url-input",value:wt,onChange:h=>Ht(h.target.value),onFocus:()=>{requestAnimationFrame(()=>window.scrollTo(0,0))},placeholder:"URL",autoCapitalize:"none",autoCorrect:"off"}),s.jsx(Kc,{show:wt.length>0,onClear:()=>Ht("")})]}),s.jsx(mi,{selectedTags:ee,availableTags:Qt,tagInput:Xt,onTagInputChange:le,onToggleTag:Se,onAddTag:wl}),s.jsx(vi,{onSave:Mn,onCancel:qa,onDelete:()=>dl(V,"page")})]}):null;if(yt)return s.jsxs(hi,{onDismiss:Ci,keyboardHeight:Xe,className:"text-editor-overlay",children:[s.jsx(wh,{value:It,onChange:Te,placeholder:"Note text...",keyboardHeight:Xe,autoFocus:!0,showClearButton:!1,onAutoSave:es}),s.jsx(mi,{selectedTags:ve,availableTags:$,tagInput:Ut,onTagInputChange:je,onToggleTag:Pc,onAddTag:ts}),s.jsx(vi,{onSave:ls,onCancel:Ci,onDelete:()=>dl(yt,"text"),saveLabel:"Done"})]});if(Kt)return s.jsxs(hi,{onDismiss:Di,keyboardHeight:Xe,className:"text-editor-overlay",children:[s.jsx(mi,{selectedTags:b,availableTags:$,tagInput:U,onTagInputChange:J,onToggleTag:us,onAddTag:is}),s.jsx(vi,{onSave:Mi,onCancel:Di,onDelete:()=>dl(Kt,"tagset")})]});if(W){const c=H.find(C=>C.id===W);if(!c)return null;const N=c.metadata?.title;return s.jsxs(hi,{onDismiss:Oi,keyboardHeight:Xe,className:"text-editor-overlay",children:[s.jsxs("div",{className:"editor-image-preview",children:[c.thumbnail?s.jsx("img",{src:`data:image/jpeg;base64,${c.thumbnail}`,alt:N||"Preview",className:"edit-modal-image"}):s.jsx("div",{className:"image-placeholder",children:s.jsxs("svg",{width:"48",height:"48",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",ry:"2"}),s.jsx("circle",{cx:"8.5",cy:"8.5",r:"1.5"}),s.jsx("polyline",{points:"21 15 16 10 5 21"})]})}),N&&s.jsx("div",{className:"edit-image-title",children:N})]}),s.jsx(mi,{selectedTags:j,availableTags:$,tagInput:R,onTagInputChange:Z,onToggleTag:fs,onAddTag:os}),s.jsx(vi,{onSave:rs,onCancel:Oi,onDelete:()=>dl(W,"image")})]})}return null},hs=c=>{switch(c.type){case"page":return Yi({id:c.id,url:c.url,tags:c.tags,saved_at:c.saved_at,metadata:c.metadata});case"text":return Gi({id:c.id,content:c.content,tags:c.tags,saved_at:c.saved_at,metadata:c.metadata});case"tagset":return Za({id:c.id,tags:c.tags,saved_at:c.saved_at,metadata:c.metadata});case"image":return gs({id:c.id,tags:c.tags,saved_at:c.saved_at,metadata:c.metadata,thumbnail:c.thumbnail,mime_type:c.mime_type||"image/jpeg",width:c.width,height:c.height});default:return null}},qi=c=>s.jsxs("div",{className:`webview-inline ${ou?"webview-expanded":""}`,children:[vn?s.jsxs("div",{className:"webview-error",children:[s.jsx("p",{children:"This site can't be displayed inline."}),s.jsx("button",{onClick:h=>{h.stopPropagation(),Vc(c)},children:"Open in Safari"})]}):s.jsx("iframe",{src:c,className:"webview-iframe",onLoad:()=>Da(!0),onError:()=>du(!0),sandbox:"allow-scripts allow-same-origin allow-forms allow-popups"}),!ru&&!vn&&s.jsx("div",{className:"webview-loading",children:"Loading..."})]}),Yi=c=>{const h=c.metadata?.title,N=Sl?.itemId===c.id;return s.jsxs("div",{id:`card-${c.id}`,className:`saved-item-card ${N?"card-webview-expanded":""}`,onClick:()=>!N&&zi(c),children:[s.jsxs("div",{className:"card-header",children:[N&&s.jsx("button",{className:`card-action-btn webview-back-btn ${ou?"visible":""}`,onClick:C=>{C.stopPropagation(),Hn()},title:"Back",children:s.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",children:s.jsx("path",{d:"M15 18l-6-6 6-6"})})}),s.jsx("div",{className:"card-type-icon",children:s.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("circle",{cx:"12",cy:"12",r:"10"}),s.jsx("line",{x1:"2",y1:"12",x2:"22",y2:"12"}),s.jsx("path",{d:"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"})]})}),s.jsx("span",{className:"card-title",children:h||c.url}),s.jsxs("div",{className:"card-actions",children:[s.jsx("button",{className:"card-action-btn",onClick:C=>N?(C.stopPropagation(),Vc(c.url)):Du(c.url,c.id,C),title:"Open in Safari",children:s.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"}),s.jsx("polyline",{points:"15 3 21 3 21 9"}),s.jsx("line",{x1:"10",y1:"14",x2:"21",y2:"3"})]})}),s.jsx("button",{className:"card-action-btn",onClick:C=>N?(C.stopPropagation(),Hn()):Mu(c.url,c.id,C),title:N?"Close webview":"Open in app",children:s.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",ry:"2"}),s.jsx("line",{x1:"3",y1:"9",x2:"21",y2:"9"})]})}),s.jsx("button",{className:"card-delete-btn",onClick:C=>{C.stopPropagation(),dl(c.id,"page")},children:s.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("polyline",{points:"3 6 5 6 21 6"}),s.jsx("path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"})]})})]})]}),N&&qi(Sl.url),s.jsxs("div",{className:"card-footer",children:[(c.tags.includes("todo")||c.tags.includes("done"))&&s.jsx("button",{className:`todo-checkbox ${c.tags.includes("done")?"checked":""}`,onClick:C=>Ja(C,c.id,"page",c.tags),children:c.tags.includes("done")?s.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",ry:"2"}),s.jsx("polyline",{points:"9 11 12 14 22 4"})]}):s.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:s.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",ry:"2"})})}),s.jsxs("div",{className:"card-tags",children:[c.tags.map(C=>s.jsx("span",{className:"card-tag",children:C},C)),s.jsx("span",{className:"card-date",children:new Date(c.saved_at).toLocaleDateString()})]})]})]},c.id)},Gi=c=>{const h=c.tags.length>0?c.tags:Ui(c.content),C=c.content.replace(/#\w+/g,"").trim().split(` 13 13 `)[0].slice(0,100)||c.content.slice(0,100),D=c.content.match(/https?:\/\/[^\s<>"{}|\\^`[\]]+/),pt=Sl?.itemId===c.id;return s.jsxs("div",{id:`card-${c.id}`,className:`saved-item-card ${pt?"card-webview-expanded":""}`,onClick:()=>!pt&&Ic(c),children:[s.jsxs("div",{className:"card-header",children:[pt&&s.jsx("button",{className:`card-action-btn webview-back-btn ${ou?"visible":""}`,onClick:at=>{at.stopPropagation(),Hn()},title:"Back",children:s.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",children:s.jsx("path",{d:"M15 18l-6-6 6-6"})})}),s.jsx("div",{className:"card-type-icon",children:s.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("path",{d:"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"}),s.jsx("polyline",{points:"14 2 14 8 20 8"}),s.jsx("line",{x1:"16",y1:"13",x2:"8",y2:"13"}),s.jsx("line",{x1:"16",y1:"17",x2:"8",y2:"17"})]})}),s.jsx("div",{className:"card-title",children:C}),s.jsxs("div",{className:"card-actions",children:[D&&s.jsx("button",{className:"card-action-btn",onClick:at=>pt?(at.stopPropagation(),Vc(D[0])):Du(D[0],c.id,at),title:"Open in Safari",children:s.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"}),s.jsx("polyline",{points:"15 3 21 3 21 9"}),s.jsx("line",{x1:"10",y1:"14",x2:"21",y2:"3"})]})}),D&&s.jsx("button",{className:"card-action-btn",onClick:at=>pt?(at.stopPropagation(),Hn()):Mu(D[0],c.id,at),title:pt?"Close webview":"Open in app",children:s.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",ry:"2"}),s.jsx("line",{x1:"3",y1:"9",x2:"21",y2:"9"})]})}),s.jsx("button",{className:"card-delete-btn",onClick:at=>{at.stopPropagation(),dl(c.id,"text")},children:s.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("polyline",{points:"3 6 5 6 21 6"}),s.jsx("path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"})]})})]})]}),pt&&qi(Sl.url),s.jsxs("div",{className:"card-footer",children:[(h.includes("todo")||h.includes("done"))&&s.jsx("button",{className:`todo-checkbox ${h.includes("done")?"checked":""}`,onClick:at=>Ja(at,c.id,"text",h),children:h.includes("done")?s.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",ry:"2"}),s.jsx("polyline",{points:"9 11 12 14 22 4"})]}):s.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:s.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",ry:"2"})})}),s.jsxs("div",{className:"card-tags",children:[h.map(at=>s.jsx("span",{className:"card-tag",children:at},at)),s.jsx("span",{className:"card-date",children:new Date(c.saved_at).toLocaleDateString()})]})]})]},c.id)},Za=c=>s.jsxs("div",{className:"saved-item-card",onClick:()=>ns(c),children:[s.jsxs("div",{className:"card-header",children:[s.jsx("div",{className:"card-type-icon",children:s.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("path",{d:"M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z"}),s.jsx("line",{x1:"7",y1:"7",x2:"7.01",y2:"7"})]})}),s.jsx("div",{className:"card-title",children:c.tags.join(", ")}),s.jsx("button",{className:"card-delete-btn",onClick:h=>{h.stopPropagation(),dl(c.id,"tagset")},children:s.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("polyline",{points:"3 6 5 6 21 6"}),s.jsx("path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"})]})})]}),s.jsx("div",{className:"card-footer",children:s.jsx("div",{className:"card-tags",children:s.jsx("span",{className:"card-date",children:new Date(c.saved_at).toLocaleDateString()})})})]},c.id),Va=async c=>{try{await X("delete_url",{id:c}),await fe(),Un()}catch(h){console.error("Failed to delete image:",h)}},dl=(c,h)=>{Tl({id:c,type:h})},Ka=()=>{Tl(null)},Qi=async()=>{if(!yn)return;const{id:c,type:h}=yn;Tl(null);const N={page:"Page",text:"Note",tagset:"Tags",image:"Image"};try{switch(h){case"page":await Ni(c);break;case"text":await as(c);break;case"tagset":await cs(c);break;case"image":await Va(c);break}qt(`${N[h]} deleted`)}catch(C){console.error("Failed to delete:",C),qt("Failed to delete","error")}},Nu=()=>{Al(null)},Cu=async()=>{if(!xn)return;const{type:c}=xn;switch(Al(null),c){case"page":Rl();break;case"text":if(yt&&Pt?.content!==void 0)try{await X("update_text",{id:yt,content:Pt.content,tags:Pt.tags||[]}),await Ve()}catch(h){console.error("Failed to restore original content:",h)}On();break;case"tagset":ia();break;case"image":Un();break}},Ja=async(c,h,N,C)=>{c.stopPropagation();const D=C.includes("todo"),pt=C.includes("done");let at;if(D)at=C.filter(ne=>ne!=="todo").concat("done");else if(pt)at=C.filter(ne=>ne!=="done").concat("todo");else return;try{switch(await X("update_url_tags",{id:h,tags:at}),N){case"page":await Ze();break;case"text":await Ve();break;case"tagset":await Oe();break;case"image":await fe();break}await oe()}catch(ne){console.error("Failed to toggle todo/done:",ne)}},Du=async(c,h,N)=>{N.stopPropagation();try{await X("record_visit",{itemId:h,source:"browser",windowType:"external"}),await Vc(c)}catch(C){console.error("Failed to open in browser:",C)}},ka=z.useRef(null),Mu=async(c,h,N)=>{N.stopPropagation(),Da(!1),du(!1),mn(!1),hn({url:c,itemId:h}),requestAnimationFrame(()=>{requestAnimationFrame(()=>{const C=document.getElementById(`card-${h}`),D=ka.current;if(C&&D){const pt=C.getBoundingClientRect(),at=D.getBoundingClientRect(),ne=document.createElement("div");ne.style.cssText="position:fixed;top:0;height:env(safe-area-inset-top,0px);visibility:hidden;",document.body.appendChild(ne);const Fa=ne.offsetHeight;document.body.removeChild(ne);const ca=pt.top-at.top-Fa;D.style.setProperty("--slide-offset",`${Math.max(0,ca)}px`)}document.documentElement.style.setProperty("--webview-ease","var(--webview-ease-in)"),mn(!0)})});try{await X("record_visit",{itemId:h,source:"webview",windowType:"embedded"})}catch(C){console.error("[App] Failed to record webview visit:",C)}},Hn=()=>{document.documentElement.style.setProperty("--webview-ease","var(--webview-ease-out)"),mn(!1),ka.current&&ka.current.style.setProperty("--slide-offset","0px"),setTimeout(()=>{hn(null),Da(!1),du(!1)},pl)},ms=()=>xn?s.jsx("div",{className:"confirm-modal-overlay",onClick:Nu,children:s.jsxs("div",{className:"confirm-modal",onClick:c=>c.stopPropagation(),children:[s.jsx("p",{children:"Discard unsaved changes?"}),s.jsxs("div",{className:"confirm-modal-buttons",children:[s.jsx("button",{className:"cancel-btn",onClick:Nu,children:"Cancel"}),s.jsx("button",{className:"delete-btn",onClick:Cu,children:"Discard"})]})]})}):null,vs=()=>{if(!yn)return null;const c={page:"page",text:"note",tagset:"tag set",image:"image"};return s.jsx("div",{className:"confirm-modal-overlay",onClick:Ka,children:s.jsxs("div",{className:"confirm-modal",onClick:h=>h.stopPropagation(),children:[s.jsxs("p",{children:["Delete this ",c[yn.type],"?"]}),s.jsxs("div",{className:"confirm-modal-buttons",children:[s.jsx("button",{className:"cancel-btn",onClick:Ka,children:"Cancel"}),s.jsx("button",{className:"delete-btn",onClick:Qi,children:"Delete"})]})]})})},gs=c=>{const h=c.metadata,N=h?.title,C=h?.sourceUrl;return s.jsxs("div",{className:"saved-item-card image-card",onClick:()=>ss(c),children:[s.jsxs("div",{className:"card-header",children:[s.jsx("div",{className:"card-thumbnail",children:c.thumbnail?s.jsx("img",{src:`data:image/jpeg;base64,${c.thumbnail}`,alt:N||"Preview"}):s.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",ry:"2"}),s.jsx("circle",{cx:"8.5",cy:"8.5",r:"1.5"}),s.jsx("polyline",{points:"21 15 16 10 5 21"})]})}),s.jsx("div",{className:"card-title",children:N||C||"Image"}),s.jsx("button",{className:"card-delete-btn",onClick:D=>{D.stopPropagation(),dl(c.id,"image")},children:s.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("polyline",{points:"3 6 5 6 21 6"}),s.jsx("path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"})]})})]}),s.jsxs("div",{className:"card-footer",children:[(c.tags.includes("todo")||c.tags.includes("done"))&&s.jsx("button",{className:`todo-checkbox ${c.tags.includes("done")?"checked":""}`,onClick:D=>Ja(D,c.id,"image",c.tags),children:c.tags.includes("done")?s.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",ry:"2"}),s.jsx("polyline",{points:"9 11 12 14 22 4"})]}):s.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:s.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",ry:"2"})})}),s.jsxs("div",{className:"card-tags",children:[c.tags.map(D=>s.jsx("span",{className:"card-tag",children:D},D)),s.jsx("span",{className:"card-date",children:new Date(c.saved_at).toLocaleDateString()})]})]})]},c.id)},ys=()=>{tl(!1),Ze(),oe()};if(pi)return s.jsxs("div",{className:"app",children:[s.jsxs("header",{children:[s.jsx("button",{className:"header-btn back-btn",onClick:ys,children:"Back"}),s.jsx("h1",{children:"Settings"}),s.jsx("div",{className:"header-spacer"})]}),s.jsxs("main",{className:"settings-view",children:[s.jsxs("div",{className:"settings-section",children:[s.jsx("h2",{children:"Server Sync"}),s.jsx("p",{className:"settings-description",children:"Sync your saved items with the server. Pull to get items from other devices, push to send local items, or sync all to do both."}),s.jsx("p",{className:"settings-description",style:{fontSize:"0.85rem",opacity:.8},children:"Items sync to your account's current profile on the server."}),s.jsx("div",{className:"webhook-input",children:s.jsx("input",{type:"url",value:el,onChange:c=>En(c.target.value),placeholder:"https://your-server.example.com",autoCapitalize:"none",autoCorrect:"off"})}),s.jsxs("div",{className:"webhook-input api-key-field",children:[s.jsx("input",{type:cl?"text":"password",value:wa,onChange:c=>Pl(c.target.value),placeholder:"API key",autoCapitalize:"none",autoCorrect:"off"}),s.jsx("button",{type:"button",className:"toggle-visibility-btn",onClick:()=>Ha(!cl),children:cl?s.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("path",{d:"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"}),s.jsx("line",{x1:"1",y1:"1",x2:"23",y2:"23"})]}):s.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("path",{d:"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"}),s.jsx("circle",{cx:"12",cy:"12",r:"3"})]})})]}),s.jsx("button",{onClick:Su,disabled:el===Nt&&wa===kc,className:"save-settings-btn",children:"Save Settings"}),s.jsxs("label",{className:"auto-sync-toggle",children:[s.jsx("input",{type:"checkbox",checked:vu,onChange:c=>Ei(c.target.checked)}),s.jsx("span",{children:"Auto-sync when items are added or modified"})]}),sl&&s.jsxs("p",{className:"last-sync-info",children:["Last synced: ",new Date(sl).toLocaleString()]}),jn&&jn.pending_count>0&&s.jsxs("p",{className:"sync-pending-info",children:[jn.pending_count," item",jn.pending_count===1?"":"s"," pending sync"]}),s.jsx("button",{className:"sync-btn primary",onClick:Ul,disabled:!Nt||_e,children:_e?"Syncing...":"Sync All"}),s.jsxs("div",{className:"sync-btn-row",children:[s.jsx("button",{className:"sync-btn secondary",onClick:ua,disabled:!Nt||_e,children:"Pull"}),s.jsx("button",{className:"sync-btn secondary",onClick:Ai,disabled:!Nt||_e,children:"Push"})]}),La&&s.jsx("div",{className:`sync-message ${La.includes("failed")||La.includes("Failed")?"error":"success"}`,children:La})]}),s.jsxs("div",{className:"settings-section",children:[s.jsx("h2",{children:"Profiles"}),Dt&&s.jsxs(s.Fragment,{children:[s.jsxs("p",{className:"settings-description",children:[Dt.isProductionBuild?"App Store/TestFlight build":"Development build",". Each profile has separate local data and sync destination."]}),(()=>{const c=Dt.profiles.find(C=>C.id===Dt.currentProfileId),h=Dt.profiles[0],N=c?.id===h?.id;return s.jsxs(s.Fragment,{children:[!N&&c&&s.jsxs("div",{className:"profile-warning-banner",children:['Using "',c.name,'" profile - data is isolated from default']}),s.jsx("div",{className:"profile-list",children:Dt.profiles.map(C=>{const D=C.id===Dt.currentProfileId,pt=!D&&Dt.profiles.length>1;return s.jsxs("div",{className:`profile-item ${D?"active":""}`,children:[s.jsxs("label",{className:"profile-radio-label",children:[s.jsx("input",{type:"radio",name:"profile",checked:D,onChange:()=>{console.log(`[Profile] Radio clicked: ${C.id}, isCurrent: ${D}`),D||(console.log(`[Profile] Switching to: ${C.id}`),ll(C.id))}}),s.jsx("span",{className:"profile-name",children:C.name}),D&&s.jsx("span",{className:"profile-badge current",children:"active"})]}),pt&&s.jsx("button",{className:"profile-delete-btn",onClick:async()=>{if(confirm(`Delete profile "${C.name}"? 14 14 15 - The database file will be preserved.`))try{const at=await X("delete_profile",{profileId:C.id});_n(at)}catch(at){alert(`Failed to delete: ${at}`)}},children:"Delete"})]},C.id)})}),s.jsx("div",{className:"profile-add-section",children:s.jsxs("div",{className:"profile-input-row",children:[s.jsx("input",{type:"text",value:Cl,onChange:C=>Dl(C.target.value),placeholder:"New profile name"}),s.jsx("button",{className:"sync-btn secondary",onClick:async()=>{if(Cl.trim())try{const C=await X("create_profile",{name:Cl.trim()});_n(C),Dl("")}catch(C){alert(`Failed to create: ${C}`)}},disabled:!Cl.trim(),children:"Add"})]})})]})})()]})]}),s.jsxs("div",{className:"settings-section",children:[s.jsx("h2",{children:"Display"}),s.jsx("p",{className:"settings-description",children:"Items with this tag are hidden from the main view unless the tag is selected as a filter."}),s.jsx("div",{className:"webhook-input",children:s.jsx("input",{type:"text",value:ea,onChange:c=>gu(c.target.value),placeholder:"archive",autoCapitalize:"none",autoCorrect:"off"})}),s.jsx("button",{onClick:pu,disabled:ea===ta,className:"save-settings-btn",children:"Save Archive Tag"})]}),s.jsxs("div",{className:"settings-section",children:[s.jsx("h2",{children:"Debug"}),s.jsxs("div",{className:"sync-btn-row",style:{flexDirection:"column",gap:"0.5rem"},children:[s.jsx("button",{className:"sync-btn secondary",onClick:async()=>{try{const c=await X("debug_list_container_files");tt("FILES: "+c.join(" | "))}catch(c){tt("ERROR: "+String(c))}},children:"List Container Files"}),s.jsx("button",{className:"sync-btn secondary",onClick:async()=>{try{const c=await X("debug_profiles_json");tt(c)}catch(c){tt("PROFILES ERROR: "+String(c))}},children:"Show profiles.json"}),s.jsx("button",{className:"sync-btn secondary",onClick:async()=>{try{const c=await X("debug_settings_table");tt(c)}catch(c){tt("SETTINGS ERROR: "+String(c))}},children:"Show Settings Table"}),s.jsx("button",{className:"sync-btn secondary",onClick:async()=>{try{const c=await X("debug_query_database");tt(c)}catch(c){tt("DB ERROR: "+String(c))}},children:"Query Database"}),s.jsx("button",{className:"sync-btn secondary",onClick:async()=>{try{tt("Exporting...");const c=await X("debug_export_database");tt("DB_START>>>"+c.substring(0,500)+"...("+c.length+" total chars). Use AirDrop or copy manually."),console.log("FULL_DB_BASE64:",c)}catch(c){tt("EXPORT ERROR: "+String(c))}},children:"Export Database"}),Dt&&Dt.profiles.length>=2&&s.jsx("button",{className:"sync-btn secondary",style:{backgroundColor:"#c44"},onClick:async()=>{const c=Dt.profiles[0],h=Dt.profiles[1];try{tt("Swapping...");const N=await X("swap_profile_databases",{profileIdA:c.id,profileIdB:h.id});tt(N)}catch(N){tt("SWAP ERROR: "+String(N))}},children:"Swap Default ↔ Dev Databases"})]})]})]}),Qe&&s.jsx("div",{className:"modal-overlay",children:s.jsxs("div",{className:"modal-content",children:[s.jsx("h3",{children:"Profile Changed"}),s.jsxs("p",{children:["Switched to ",s.jsx("strong",{children:Dt?.profiles.find(c=>c.id===Dt?.currentProfileId)?.name??"unknown"})," profile."]}),s.jsx("p",{children:"Please restart the app to ensure complete data isolation."}),s.jsxs("div",{className:"modal-buttons",children:[s.jsx("button",{className:"modal-btn secondary",onClick:()=>pe(!1),children:"Later"}),s.jsx("button",{className:"modal-btn primary",onClick:Cn,children:"Quit Now"})]})]})})]});const be=Bi(),Wa=B.length+q.length+rt.length+H.length,Ou=s.jsx("input",{ref:gi,type:"file",accept:"image/*",capture:"environment",onChange:Ga,style:{display:"none"}});return Ma?s.jsxs("div",{className:"app",children:[Ou,s.jsxs("header",{children:[s.jsx("button",{className:"header-btn back-btn",onClick:_u,children:"Cancel"}),s.jsx("h1",{children:"Save Photo"}),s.jsx("div",{className:"header-spacer"})]}),s.jsx("main",{className:"saved-view",children:s.jsxs("div",{className:"captured-image-view",children:[s.jsx("div",{className:"captured-image-preview",children:s.jsx("img",{src:Ma,alt:"Captured"})}),bl.size>0&&s.jsx("div",{className:"edit-section",children:s.jsx("div",{className:"editing-tags",children:Array.from(bl).sort().map(c=>s.jsxs("span",{className:"editing-tag",children:[c,s.jsx("button",{onClick:()=>Qa(c),children:"×"})]},c))})}),s.jsx("div",{className:"edit-section",children:s.jsxs("div",{className:"new-tag-input",children:[s.jsx("input",{type:"text",value:qe,onChange:c=>xl(c.target.value),onKeyDown:c=>{c.key==="Enter"&&(c.preventDefault(),ju())},placeholder:"Add tag...",autoCapitalize:"none",autoCorrect:"off",autoComplete:"off",spellCheck:!1}),s.jsx("button",{onClick:ju,disabled:!qe.trim(),children:"Add"})]})}),$.filter(c=>!bl.has(c.name)&&(!qe.trim()||c.name.toLowerCase().includes(qe.toLowerCase().trim()))).length>0&&s.jsx("div",{className:"edit-section",children:s.jsx("div",{className:"all-tags-list",children:$.filter(c=>!bl.has(c.name)&&(!qe.trim()||c.name.toLowerCase().includes(qe.toLowerCase().trim()))).map(c=>s.jsx("span",{className:"tag-chip",onClick:()=>Qa(c.name),children:c.name},c.name))})}),s.jsxs("div",{className:"edit-buttons",children:[s.jsx("button",{className:"cancel-btn",onClick:_u,children:"Cancel"}),s.jsx("button",{className:"save-btn",onClick:Fc,children:"Save"})]})]})})]}):s.jsxs("div",{className:`app ${Sl?"webview-active":""}`,ref:ka,children:[s.jsx("input",{ref:$l,style:{position:"fixed",opacity:0,top:"-100px"},readOnly:!0}),Ou,s.jsxs("header",{children:[s.jsxs("h1",{onClick:()=>{E!=="all"||Lt||Bt.size>0?Hi():wn()},style:{cursor:"pointer"},children:["Peek ",s.jsx("span",{style:{fontSize:"0.5em",opacity:.5},children:"v1037"})]}),s.jsxs("div",{className:"filter-icons",children:[s.jsxs("button",{className:`filter-btn ${E==="page"?"active":""}`,onClick:()=>Rn("page"),title:"Pages",children:[s.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("circle",{cx:"12",cy:"12",r:"10"}),s.jsx("line",{x1:"2",y1:"12",x2:"22",y2:"12"}),s.jsx("path",{d:"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"})]}),s.jsx("span",{className:"filter-count",children:B.length})]}),s.jsxs("button",{className:`filter-btn ${E==="text"?"active":""}`,onClick:()=>Rn("text"),title:"Notes",children:[s.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("path",{d:"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"}),s.jsx("polyline",{points:"14 2 14 8 20 8"}),s.jsx("line",{x1:"16",y1:"13",x2:"8",y2:"13"}),s.jsx("line",{x1:"16",y1:"17",x2:"8",y2:"17"})]}),s.jsx("span",{className:"filter-count",children:q.length})]}),s.jsxs("button",{className:`filter-btn ${E==="tagset"?"active":""}`,onClick:()=>Rn("tagset"),title:"Tag Sets",children:[s.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("path",{d:"M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z"}),s.jsx("line",{x1:"7",y1:"7",x2:"7.01",y2:"7"})]}),s.jsx("span",{className:"filter-count",children:rt.length})]}),s.jsxs("button",{className:`filter-btn ${E==="image"?"active":""}`,onClick:()=>Rn("image"),title:"Images",children:[s.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",ry:"2"}),s.jsx("circle",{cx:"8.5",cy:"8.5",r:"1.5"}),s.jsx("polyline",{points:"21 15 16 10 5 21"})]}),s.jsx("span",{className:"filter-count",children:H.length})]})]}),s.jsx("button",{className:"sort-btn",onClick:()=>Jc(c=>c==="newest"?"oldest":"newest"),title:Ua==="newest"?"Newest first":"Oldest first",children:Ua==="newest"?s.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("line",{x1:"12",y1:"5",x2:"12",y2:"19"}),s.jsx("polyline",{points:"19 12 12 19 5 12"})]}):s.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("line",{x1:"12",y1:"19",x2:"12",y2:"5"}),s.jsx("polyline",{points:"5 12 12 5 19 12"})]})}),s.jsx("button",{className:`header-btn settings-btn ${_e?"syncing":""}`,onClick:()=>tl(!0),children:s.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("circle",{cx:"12",cy:"12",r:"3"}),s.jsx("path",{d:"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"})]})})]}),Dt&&Dt.profiles.length>0&&Dt.currentProfileId!==Dt.profiles[0].id&&s.jsxs("div",{className:"profile-banner",children:["Profile: ",Dt.profiles.find(c=>c.id===Dt.currentProfileId)?.name??"Unknown"]}),s.jsxs("main",{className:"saved-view",ref:gn,onTouchStart:Xa,onTouchEnd:wi,children:[la!=="idle"&&s.jsx("div",{className:`pull-indicator ${la}`,children:la==="pulling"?"Hold to refresh...":"Release to refresh!"}),s.jsxs("div",{className:"input-row",children:[s.jsx("div",{className:"input-row-card",children:s.jsxs("div",{className:"input-with-clear",style:{flex:1},children:[s.jsx("input",{type:"text",className:"input-row-input",placeholder:"Search...",value:Lt,onChange:c=>Ye(c.target.value),autoCapitalize:"none",autoCorrect:"off",autoComplete:"off",spellCheck:!1}),s.jsx(Kc,{show:Lt.length>0||Bt.size>0,onClear:()=>{Ye(""),hu(new Set)}})]})}),s.jsxs("div",{className:"input-row-card",children:[s.jsx("div",{className:"input-with-clear",style:{flex:1},children:s.jsx("input",{type:"text",className:"input-row-input",placeholder:"Add...",value:F,onChange:c=>nt(c.target.value),onFocus:()=>ge(!0),autoCapitalize:"none",autoCorrect:"off",autoComplete:"off",spellCheck:!1})}),s.jsx("button",{className:"camera-btn",onClick:Eu,title:"Take photo",children:s.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("path",{d:"M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"}),s.jsx("circle",{cx:"12",cy:"13",r:"4"})]})})]})]}),s.jsxs("div",{className:"drag-handle-wrapper",children:[s.jsx("div",{className:"filter-tags-container",ref:Ra,style:{height:`${El}px`},children:zu().length===0?s.jsx("div",{className:"filter-tags-empty",children:"No matching tags"}):s.jsx("div",{className:"filter-tags",children:zu().map(c=>s.jsx("span",{className:`tag-chip ${Bt.has(c.name)?"selected":""}`,onClick:()=>Li(c.name),children:c.name},c.name))})}),s.jsx("div",{className:"drag-handle",onMouseDown:c=>{c.preventDefault(),yu(c.clientY)},onTouchStart:c=>{yu(c.touches[0].clientY)},children:s.jsx("div",{className:"drag-handle-bar"})})]}),s.jsx("div",{className:"unified-list",children:Wa===0?s.jsxs("div",{className:"empty-state",children:[s.jsx("p",{children:"No saved items yet."}),s.jsx("p",{children:"Share a URL from any app to get started!"})]}):be.length===0?s.jsxs("div",{className:"empty-state",children:[s.jsx("p",{children:"No matching items."}),s.jsx("p",{children:"Tap Peek to clear filters."})]}):be.map(c=>hs(c))})]}),ds(),ae&&s.jsxs(hi,{onDismiss:()=>ge(!1),keyboardHeight:Xe,children:[s.jsx(wh,{value:F,onChange:nt,placeholder:"Enter text, URL, or just select tags...",keyboardHeight:Xe,autoFocus:!0,autoCapitalize:"none",autoCorrect:"off"}),s.jsx(mi,{selectedTags:zt,availableTags:$,tagInput:il,onTagInputChange:yl,onToggleTag:Ya,onAddTag:Tu,placeholder:"Add new tag..."}),s.jsx(vi,{onSave:$c,onCancel:()=>ge(!1),cancelLabel:"Close",saveDisabled:!Au()})]}),vs(),ms(),Sn&&s.jsx("div",{className:`toast toast-${Sn.type}`,children:Sn.message}),Qe&&s.jsx("div",{className:"modal-overlay",children:s.jsxs("div",{className:"modal-content",children:[s.jsx("h3",{children:"Profile Changed"}),s.jsxs("p",{children:["Switched to ",s.jsx("strong",{children:Dt?.profiles.find(c=>c.id===Dt?.currentProfileId)?.name??"unknown"})," profile."]}),s.jsx("p",{children:"Please restart the app to ensure complete data isolation."}),s.jsxs("div",{className:"modal-buttons",children:[s.jsx("button",{className:"modal-btn secondary",onClick:()=>pe(!1),children:"Later"}),s.jsx("button",{className:"modal-btn primary",onClick:Cn,children:"Quit Now"})]})]})})]})}mm.createRoot(document.getElementById("root")).render(s.jsx(im.StrictMode,{children:s.jsx(Sm,{})})); 15 + The database file will be preserved.`))try{const at=await X("delete_profile",{profileId:C.id});_n(at)}catch(at){alert(`Failed to delete: ${at}`)}},children:"Delete"})]},C.id)})}),s.jsx("div",{className:"profile-add-section",children:s.jsxs("div",{className:"profile-input-row",children:[s.jsx("input",{type:"text",value:Cl,onChange:C=>Dl(C.target.value),placeholder:"New profile name"}),s.jsx("button",{className:"sync-btn secondary",onClick:async()=>{if(Cl.trim())try{const C=await X("create_profile",{name:Cl.trim()});_n(C),Dl("")}catch(C){alert(`Failed to create: ${C}`)}},disabled:!Cl.trim(),children:"Add"})]})})]})})()]})]}),s.jsxs("div",{className:"settings-section",children:[s.jsx("h2",{children:"Display"}),s.jsx("p",{className:"settings-description",children:"Items with this tag are hidden from the main view unless the tag is selected as a filter."}),s.jsx("div",{className:"webhook-input",children:s.jsx("input",{type:"text",value:ea,onChange:c=>gu(c.target.value),placeholder:"archive",autoCapitalize:"none",autoCorrect:"off"})}),s.jsx("button",{onClick:pu,disabled:ea===ta,className:"save-settings-btn",children:"Save Archive Tag"})]}),s.jsxs("div",{className:"settings-section",children:[s.jsx("h2",{children:"Debug"}),s.jsxs("div",{className:"sync-btn-row",style:{flexDirection:"column",gap:"0.5rem"},children:[s.jsx("button",{className:"sync-btn secondary",onClick:async()=>{try{const c=await X("debug_list_container_files");tt("FILES: "+c.join(" | "))}catch(c){tt("ERROR: "+String(c))}},children:"List Container Files"}),s.jsx("button",{className:"sync-btn secondary",onClick:async()=>{try{const c=await X("debug_profiles_json");tt(c)}catch(c){tt("PROFILES ERROR: "+String(c))}},children:"Show profiles.json"}),s.jsx("button",{className:"sync-btn secondary",onClick:async()=>{try{const c=await X("debug_settings_table");tt(c)}catch(c){tt("SETTINGS ERROR: "+String(c))}},children:"Show Settings Table"}),s.jsx("button",{className:"sync-btn secondary",onClick:async()=>{try{const c=await X("debug_query_database");tt(c)}catch(c){tt("DB ERROR: "+String(c))}},children:"Query Database"}),s.jsx("button",{className:"sync-btn secondary",onClick:async()=>{try{tt("Exporting...");const c=await X("debug_export_database");tt("DB_START>>>"+c.substring(0,500)+"...("+c.length+" total chars). Use AirDrop or copy manually."),console.log("FULL_DB_BASE64:",c)}catch(c){tt("EXPORT ERROR: "+String(c))}},children:"Export Database"}),Dt&&Dt.profiles.length>=2&&s.jsx("button",{className:"sync-btn secondary",style:{backgroundColor:"#c44"},onClick:async()=>{const c=Dt.profiles[0],h=Dt.profiles[1];try{tt("Swapping...");const N=await X("swap_profile_databases",{profileIdA:c.id,profileIdB:h.id});tt(N)}catch(N){tt("SWAP ERROR: "+String(N))}},children:"Swap Default ↔ Dev Databases"})]})]})]}),Qe&&s.jsx("div",{className:"modal-overlay",children:s.jsxs("div",{className:"modal-content",children:[s.jsx("h3",{children:"Profile Changed"}),s.jsxs("p",{children:["Switched to ",s.jsx("strong",{children:Dt?.profiles.find(c=>c.id===Dt?.currentProfileId)?.name??"unknown"})," profile."]}),s.jsx("p",{children:"Please restart the app to ensure complete data isolation."}),s.jsxs("div",{className:"modal-buttons",children:[s.jsx("button",{className:"modal-btn secondary",onClick:()=>pe(!1),children:"Later"}),s.jsx("button",{className:"modal-btn primary",onClick:Cn,children:"Quit Now"})]})]})})]});const be=Bi(),Wa=B.length+q.length+rt.length+H.length,Ou=s.jsx("input",{ref:gi,type:"file",accept:"image/*",capture:"environment",onChange:Ga,style:{display:"none"}});return Ma?s.jsxs("div",{className:"app",children:[Ou,s.jsxs("header",{children:[s.jsx("button",{className:"header-btn back-btn",onClick:_u,children:"Cancel"}),s.jsx("h1",{children:"Save Photo"}),s.jsx("div",{className:"header-spacer"})]}),s.jsx("main",{className:"saved-view",children:s.jsxs("div",{className:"captured-image-view",children:[s.jsx("div",{className:"captured-image-preview",children:s.jsx("img",{src:Ma,alt:"Captured"})}),bl.size>0&&s.jsx("div",{className:"edit-section",children:s.jsx("div",{className:"editing-tags",children:Array.from(bl).sort().map(c=>s.jsxs("span",{className:"editing-tag",children:[c,s.jsx("button",{onClick:()=>Qa(c),children:"×"})]},c))})}),s.jsx("div",{className:"edit-section",children:s.jsxs("div",{className:"new-tag-input",children:[s.jsx("input",{type:"text",value:qe,onChange:c=>xl(c.target.value),onKeyDown:c=>{c.key==="Enter"&&(c.preventDefault(),ju())},placeholder:"Add tag...",autoCapitalize:"none",autoCorrect:"off",autoComplete:"off",spellCheck:!1}),s.jsx("button",{onClick:ju,disabled:!qe.trim(),children:"Add"})]})}),$.filter(c=>!bl.has(c.name)&&(!qe.trim()||c.name.toLowerCase().includes(qe.toLowerCase().trim()))).length>0&&s.jsx("div",{className:"edit-section",children:s.jsx("div",{className:"all-tags-list",children:$.filter(c=>!bl.has(c.name)&&(!qe.trim()||c.name.toLowerCase().includes(qe.toLowerCase().trim()))).map(c=>s.jsx("span",{className:"tag-chip",onClick:()=>Qa(c.name),children:c.name},c.name))})}),s.jsxs("div",{className:"edit-buttons",children:[s.jsx("button",{className:"cancel-btn",onClick:_u,children:"Cancel"}),s.jsx("button",{className:"save-btn",onClick:Fc,children:"Save"})]})]})})]}):s.jsxs("div",{className:`app ${Sl?"webview-active":""}`,ref:ka,children:[s.jsx("input",{ref:$l,style:{position:"fixed",opacity:0,top:"-100px"},readOnly:!0}),Ou,s.jsxs("header",{children:[s.jsxs("h1",{onClick:()=>{E!=="all"||Lt||Bt.size>0?Hi():wn()},style:{cursor:"pointer"},children:["Peek ",s.jsx("span",{style:{fontSize:"0.5em",opacity:.5},children:"v1039"})]}),s.jsxs("div",{className:"filter-icons",children:[s.jsxs("button",{className:`filter-btn ${E==="page"?"active":""}`,onClick:()=>Rn("page"),title:"Pages",children:[s.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("circle",{cx:"12",cy:"12",r:"10"}),s.jsx("line",{x1:"2",y1:"12",x2:"22",y2:"12"}),s.jsx("path",{d:"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"})]}),s.jsx("span",{className:"filter-count",children:B.length})]}),s.jsxs("button",{className:`filter-btn ${E==="text"?"active":""}`,onClick:()=>Rn("text"),title:"Notes",children:[s.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("path",{d:"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"}),s.jsx("polyline",{points:"14 2 14 8 20 8"}),s.jsx("line",{x1:"16",y1:"13",x2:"8",y2:"13"}),s.jsx("line",{x1:"16",y1:"17",x2:"8",y2:"17"})]}),s.jsx("span",{className:"filter-count",children:q.length})]}),s.jsxs("button",{className:`filter-btn ${E==="tagset"?"active":""}`,onClick:()=>Rn("tagset"),title:"Tag Sets",children:[s.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("path",{d:"M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z"}),s.jsx("line",{x1:"7",y1:"7",x2:"7.01",y2:"7"})]}),s.jsx("span",{className:"filter-count",children:rt.length})]}),s.jsxs("button",{className:`filter-btn ${E==="image"?"active":""}`,onClick:()=>Rn("image"),title:"Images",children:[s.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",ry:"2"}),s.jsx("circle",{cx:"8.5",cy:"8.5",r:"1.5"}),s.jsx("polyline",{points:"21 15 16 10 5 21"})]}),s.jsx("span",{className:"filter-count",children:H.length})]})]}),s.jsx("button",{className:"sort-btn",onClick:()=>Jc(c=>c==="newest"?"oldest":"newest"),title:Ua==="newest"?"Newest first":"Oldest first",children:Ua==="newest"?s.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("line",{x1:"12",y1:"5",x2:"12",y2:"19"}),s.jsx("polyline",{points:"19 12 12 19 5 12"})]}):s.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("line",{x1:"12",y1:"19",x2:"12",y2:"5"}),s.jsx("polyline",{points:"5 12 12 5 19 12"})]})}),s.jsx("button",{className:`header-btn settings-btn ${_e?"syncing":""}`,onClick:()=>tl(!0),children:s.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("circle",{cx:"12",cy:"12",r:"3"}),s.jsx("path",{d:"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"})]})})]}),Dt&&Dt.profiles.length>0&&Dt.currentProfileId!==Dt.profiles[0].id&&s.jsxs("div",{className:"profile-banner",children:["Profile: ",Dt.profiles.find(c=>c.id===Dt.currentProfileId)?.name??"Unknown"]}),s.jsxs("main",{className:"saved-view",ref:gn,onTouchStart:Xa,onTouchEnd:wi,children:[la!=="idle"&&s.jsx("div",{className:`pull-indicator ${la}`,children:la==="pulling"?"Hold to refresh...":"Release to refresh!"}),s.jsxs("div",{className:"input-row",children:[s.jsx("div",{className:"input-row-card",children:s.jsxs("div",{className:"input-with-clear",style:{flex:1},children:[s.jsx("input",{type:"text",className:"input-row-input",placeholder:"Search...",value:Lt,onChange:c=>Ye(c.target.value),autoCapitalize:"none",autoCorrect:"off",autoComplete:"off",spellCheck:!1}),s.jsx(Kc,{show:Lt.length>0||Bt.size>0,onClear:()=>{Ye(""),hu(new Set)}})]})}),s.jsxs("div",{className:"input-row-card",children:[s.jsx("div",{className:"input-with-clear",style:{flex:1},children:s.jsx("input",{type:"text",className:"input-row-input",placeholder:"Add...",value:F,onChange:c=>nt(c.target.value),onFocus:()=>ge(!0),autoCapitalize:"none",autoCorrect:"off",autoComplete:"off",spellCheck:!1})}),s.jsx("button",{className:"camera-btn",onClick:Eu,title:"Take photo",children:s.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("path",{d:"M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"}),s.jsx("circle",{cx:"12",cy:"13",r:"4"})]})})]})]}),s.jsxs("div",{className:"drag-handle-wrapper",children:[s.jsx("div",{className:"filter-tags-container",ref:Ra,style:{height:`${El}px`},children:zu().length===0?s.jsx("div",{className:"filter-tags-empty",children:"No matching tags"}):s.jsx("div",{className:"filter-tags",children:zu().map(c=>s.jsx("span",{className:`tag-chip ${Bt.has(c.name)?"selected":""}`,onClick:()=>Li(c.name),children:c.name},c.name))})}),s.jsx("div",{className:"drag-handle",onMouseDown:c=>{c.preventDefault(),yu(c.clientY)},onTouchStart:c=>{yu(c.touches[0].clientY)},children:s.jsx("div",{className:"drag-handle-bar"})})]}),s.jsx("div",{className:"unified-list",children:Wa===0?s.jsxs("div",{className:"empty-state",children:[s.jsx("p",{children:"No saved items yet."}),s.jsx("p",{children:"Share a URL from any app to get started!"})]}):be.length===0?s.jsxs("div",{className:"empty-state",children:[s.jsx("p",{children:"No matching items."}),s.jsx("p",{children:"Tap Peek to clear filters."})]}):be.map(c=>hs(c))})]}),ds(),ae&&s.jsxs(hi,{onDismiss:()=>ge(!1),keyboardHeight:Xe,children:[s.jsx(wh,{value:F,onChange:nt,placeholder:"Enter text, URL, or just select tags...",keyboardHeight:Xe,autoFocus:!0,autoCapitalize:"none",autoCorrect:"off"}),s.jsx(mi,{selectedTags:zt,availableTags:$,tagInput:il,onTagInputChange:yl,onToggleTag:Ya,onAddTag:Tu,placeholder:"Add new tag..."}),s.jsx(vi,{onSave:$c,onCancel:()=>ge(!1),cancelLabel:"Close",saveDisabled:!Au()})]}),vs(),ms(),Sn&&s.jsx("div",{className:`toast toast-${Sn.type}`,children:Sn.message}),Qe&&s.jsx("div",{className:"modal-overlay",children:s.jsxs("div",{className:"modal-content",children:[s.jsx("h3",{children:"Profile Changed"}),s.jsxs("p",{children:["Switched to ",s.jsx("strong",{children:Dt?.profiles.find(c=>c.id===Dt?.currentProfileId)?.name??"unknown"})," profile."]}),s.jsx("p",{children:"Please restart the app to ensure complete data isolation."}),s.jsxs("div",{className:"modal-buttons",children:[s.jsx("button",{className:"modal-btn secondary",onClick:()=>pe(!1),children:"Later"}),s.jsx("button",{className:"modal-btn primary",onClick:Cn,children:"Quit Now"})]})]})})]})}mm.createRoot(document.getElementById("root")).render(s.jsx(im.StrictMode,{children:s.jsx(Sm,{})}));
+1 -1
backend/tauri-mobile/src-tauri/gen/apple/assets/index.html
··· 6 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" /> 7 7 <meta name="color-scheme" content="light dark" /> 8 8 <title>Tauri + React + Typescript</title> 9 - <script type="module" crossorigin src="/assets/index-DbCPW-hJ.js"></script> 9 + <script type="module" crossorigin src="/assets/index-BsaIPLIs.js"></script> 10 10 <link rel="stylesheet" crossorigin href="/assets/index-CH7TEVAW.css"> 11 11 </head> 12 12