mirror of
https://github.com/multipleof4/devsune.git
synced 2026-01-14 08:27:55 +00:00
Update index.html
This commit is contained in:
42
index.html
42
index.html
@@ -18,9 +18,6 @@
|
|||||||
.menu-card{position:fixed;z-index:60;min-width:12rem;border-radius:0.75rem;border:1px solid #e5e7eb;background:#fff;box-shadow:0 10px 20px rgba(0,0,0,.08)}
|
.menu-card{position:fixed;z-index:60;min-width:12rem;border-radius:0.75rem;border:1px solid #e5e7eb;background:#fff;box-shadow:0 10px 20px rgba(0,0,0,.08)}
|
||||||
.menu-item{width:100%;text-align:left;padding:.5rem .75rem;font-size:.875rem;display:flex;align-items:center;gap:.5rem}
|
.menu-item{width:100%;text-align:left;padding:.5rem .75rem;font-size:.875rem;display:flex;align-items:center;gap:.5rem}
|
||||||
.menu-item:hover{background:#f9fafb}
|
.menu-item:hover{background:#f9fafb}
|
||||||
.code-editor{position:relative;height:60vh}
|
|
||||||
.code-editor pre{margin:0;height:100%;overflow:auto;border:1px solid #e5e7eb;border-radius:0.75rem}
|
|
||||||
.code-editor textarea{position:absolute;inset:0;height:100%;resize:none;background:transparent;color:transparent;caret-color:#111;border:0;outline:0}
|
|
||||||
</style>
|
</style>
|
||||||
<script src="https://unpkg.com/htmx.org@1.9.12"></script>
|
<script src="https://unpkg.com/htmx.org@1.9.12"></script>
|
||||||
</head>
|
</head>
|
||||||
@@ -85,7 +82,11 @@
|
|||||||
<div class="rounded-2xl bg-white shadow-xl border border-gray-200 overflow-hidden">
|
<div class="rounded-2xl bg-white shadow-xl border border-gray-200 overflow-hidden">
|
||||||
<div class="px-4 py-3 border-b text-sm font-semibold flex items-center justify-between"><span>Sune Settings</span><button id="closeSettings" class="p-1 rounded hover:bg-gray-100" aria-label="Close"><svg viewBox="0 0 24 24" class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/></svg></button></div>
|
<div class="px-4 py-3 border-b text-sm font-semibold flex items-center justify-between"><span>Sune Settings</span><button id="closeSettings" class="p-1 rounded hover:bg-gray-100" aria-label="Close"><svg viewBox="0 0 24 24" class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/></svg></button></div>
|
||||||
<form id="settingsForm" class="text-sm">
|
<form id="settingsForm" class="text-sm">
|
||||||
<div class="border-b flex text-xs font-medium"><button type="button" id="tabModel" class="flex-1 py-2 px-3 text-center border-b-2 border-black">Model & Sampling</button><button type="button" id="tabPrompt" class="flex-1 py-2 px-3 text-center border-b-2 border-transparent hover:border-gray-300">System Prompt</button><button type="button" id="tabScript" class="flex-1 py-2 px-3 text-center border-b-2 border-transparent hover:border-gray-300">Script</button></div>
|
<div class="border-b grid grid-cols-3 text-xs font-medium">
|
||||||
|
<button type="button" id="tabModel" class="py-1.5 px-2 text-center border-b-2 border-black">Model & Sampling</button>
|
||||||
|
<button type="button" id="tabPrompt" class="py-1.5 px-2 text-center border-b-2 border-transparent hover:border-gray-300">System Prompt</button>
|
||||||
|
<button type="button" id="tabScript" class="py-1.5 px-2 text-center border-b-2 border-transparent hover:border-gray-300">Script</button>
|
||||||
|
</div>
|
||||||
<div id="panelModel" class="p-4 space-y-4">
|
<div id="panelModel" class="p-4 space-y-4">
|
||||||
<div><label class="block text-gray-700 font-medium mb-1">Model name</label><input id="set_model" type="text" class="w-full rounded-xl border border-gray-300 px-3 py-2" placeholder="openai/gpt-4o"/></div>
|
<div><label class="block text-gray-700 font-medium mb-1">Model name</label><input id="set_model" type="text" class="w-full rounded-xl border border-gray-300 px-3 py-2" placeholder="openai/gpt-4o"/></div>
|
||||||
<div class="grid grid-cols-2 gap-3">
|
<div class="grid grid-cols-2 gap-3">
|
||||||
@@ -103,8 +104,14 @@
|
|||||||
<div id="panelPrompt" class="p-4 space-y-4 hidden">
|
<div id="panelPrompt" class="p-4 space-y-4 hidden">
|
||||||
<div><label class="block text-gray-700 font-medium mb-1">System Prompt</label><textarea id="set_system_prompt" rows="8" class="w-full rounded-xl border border-gray-300 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-black/20" placeholder="Enter a system prompt to guide the sune"></textarea><p class="mt-1 text-xs text-gray-500">Saved per sune.</p></div>
|
<div><label class="block text-gray-700 font-medium mb-1">System Prompt</label><textarea id="set_system_prompt" rows="8" class="w-full rounded-xl border border-gray-300 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-black/20" placeholder="Enter a system prompt to guide the sune"></textarea><p class="mt-1 text-xs text-gray-500">Saved per sune.</p></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="panelScript" class="p-4 space-y-3 hidden">
|
<div id="panelScript" class="p-4 space-y-2 hidden">
|
||||||
<div><label class="block text-gray-700 font-medium mb-1">Script</label><div class="code-editor rounded-xl"><pre id="scriptPre" class="rounded-xl bg-white"><code id="scriptHL" class="language-javascript font-mono text-[12px] leading-6"></code></pre><textarea id="set_script" spellcheck="false" autocapitalize="none" autocomplete="off" autocorrect="off" placeholder="Write JavaScript here" class="font-mono text-[12px] leading-6 px-3 py-2"></textarea></div><p class="mt-1 text-xs text-gray-500">Saved per sune. Syntax-highlighted as you type.</p></div>
|
<div><label class="block text-gray-700 font-medium mb-1">Script</label>
|
||||||
|
<div class="relative rounded-xl border border-gray-300 h-[60vh] overflow-hidden bg-white">
|
||||||
|
<pre id="scriptPre" aria-hidden="true" class="absolute inset-0 m-0 p-3 overflow-hidden whitespace-pre-wrap break-words pointer-events-none"><code id="scriptHL" class="language-javascript"></code></pre>
|
||||||
|
<textarea id="set_script" class="absolute inset-0 w-full h-full p-3 font-mono text-[13px] leading-5 bg-transparent text-transparent caret-black resize-none focus:outline-none" placeholder="// Your JavaScript here" spellcheck="false" autocapitalize="none" autocomplete="off" autocorrect="off" inputmode="text"></textarea>
|
||||||
|
</div>
|
||||||
|
<p class="mt-1 text-xs text-gray-500">Syntax-highlighted as you type. Stored with this sune and included in import/export.</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-between gap-2 px-4 py-3 border-t">
|
<div class="flex items-center justify-between gap-2 px-4 py-3 border-t">
|
||||||
<button type="button" id="deleteSuneBtn" class="inline-flex items-center gap-2 px-3 py-2 rounded-xl border border-red-200 text-red-700 hover:bg-red-50"><svg viewBox="0 0 24 24" class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M3 6h18M8 6v12a2 2 0 0 0 2 2h4a2 2 0 0 0 2-2V6m-9 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg><span>Delete sune</span></button>
|
<button type="button" id="deleteSuneBtn" class="inline-flex items-center gap-2 px-3 py-2 rounded-xl border border-red-200 text-red-700 hover:bg-red-50"><svg viewBox="0 0 24 24" class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M3 6h18M8 6v12a2 2 0 0 0 2 2h4a2 2 0 0 0 2-2V6m-9 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg><span>Delete sune</span></button>
|
||||||
@@ -120,7 +127,7 @@
|
|||||||
<script src="https://cdn.jsdelivr.net/npm/tiny-ripple@0.2.0"></script>
|
<script src="https://cdn.jsdelivr.net/npm/tiny-ripple@0.2.0"></script>
|
||||||
<script>
|
<script>
|
||||||
const DEFAULT_MODEL='openai/gpt-5-chat',DEFAULT_API_KEY=''
|
const DEFAULT_MODEL='openai/gpt-5-chat',DEFAULT_API_KEY=''
|
||||||
const el=Object.fromEntries(['chat','messages','composer','input','sendBtn','settingsBtnTop','settingsModal','settingsForm','closeSettings','cancelSettings','tabModel','tabPrompt','tabScript','panelModel','panelPrompt','panelScript','set_model','set_temperature','set_top_p','set_top_k','set_frequency_penalty','set_presence_penalty','set_repetition_penalty','set_min_p','set_top_a','set_reasoning_effort','set_system_prompt','set_script','deleteSuneBtn','sidebar','sidebarOverlay','sidebarBtn','suneList','newSuneBtn','userMenuBtn','userMenu','apiKeyOption','sunesImportOption','sunesExportOption','threadsImportOption','threadsExportOption','importInput','historyBtn','historyPanel','historyOverlay','historyList','closeHistory','historyMenu','suneMenu','footer','attachBtn','attachBadge','fileInput'].map(id=>[id,document.getElementById(id)]))
|
const el=Object.fromEntries(['chat','messages','composer','input','sendBtn','settingsBtnTop','settingsModal','settingsForm','closeSettings','cancelSettings','tabModel','tabPrompt','tabScript','panelModel','panelPrompt','panelScript','set_model','set_temperature','set_top_p','set_top_k','set_frequency_penalty','set_presence_penalty','set_repetition_penalty','set_min_p','set_top_a','set_reasoning_effort','set_system_prompt','set_script','scriptPre','scriptHL','deleteSuneBtn','sidebar','sidebarOverlay','sidebarBtn','suneList','newSuneBtn','userMenuBtn','userMenu','apiKeyOption','sunesImportOption','sunesExportOption','threadsImportOption','threadsExportOption','importInput','historyBtn','historyPanel','historyOverlay','historyList','closeHistory','historyMenu','suneMenu','footer','attachBtn','attachBadge','fileInput'].map(id=>[id,document.getElementById(id)]))
|
||||||
const icons=()=>window.lucide&&lucide.createIcons()
|
const icons=()=>window.lucide&&lucide.createIcons()
|
||||||
const clamp=(v,min,max)=>Math.max(min,Math.min(max,v)),num=(v,d)=>v==null||v===''||isNaN(+v)?d:+v,int=(v,d)=>v==null||v===''||isNaN(parseInt(v))?d:parseInt(v),gid=()=>Math.random().toString(36).slice(2,9),esc=s=>String(s).replace(/[&<>'"`]/g,c=>({"&":"&","<":"<",">":">","\"":""","'":"'","`":"`"}[c]))
|
const clamp=(v,min,max)=>Math.max(min,Math.min(max,v)),num=(v,d)=>v==null||v===''||isNaN(+v)?d:+v,int=(v,d)=>v==null||v===''||isNaN(parseInt(v))?d:parseInt(v),gid=()=>Math.random().toString(36).slice(2,9),esc=s=>String(s).replace(/[&<>'"`]/g,c=>({"&":"&","<":"<",">":">","\"":""","'":"'","`":"`"}[c]))
|
||||||
const globalStore={get apiKey(){return localStorage.getItem('openrouter_api_key')||DEFAULT_API_KEY||''},set apiKey(v){localStorage.setItem('openrouter_api_key',v||'')}}
|
const globalStore={get apiKey(){return localStorage.getItem('openrouter_api_key')||DEFAULT_API_KEY||''},set apiKey(v){localStorage.setItem('openrouter_api_key',v||'')}}
|
||||||
@@ -172,21 +179,20 @@ return null}
|
|||||||
el.attachBtn.addEventListener('click',()=>{if(state.busy)return;if(state.attachments.length){state.attachments=[];updateAttachBadge();el.fileInput.value=''};el.fileInput.click()})
|
el.attachBtn.addEventListener('click',()=>{if(state.busy)return;if(state.attachments.length){state.attachments=[];updateAttachBadge();el.fileInput.value=''};el.fileInput.click()})
|
||||||
el.fileInput.addEventListener('change',async()=>{const files=[...(el.fileInput.files||[])];if(!files.length)return;for(const f of files){const part=await fileToPart(f).catch(()=>null);if(part)state.attachments.push(part)}updateAttachBadge()})
|
el.fileInput.addEventListener('change',async()=>{const files=[...(el.fileInput.files||[])];if(!files.length)return;for(const f of files){const part=await fileToPart(f).catch(()=>null);if(part)state.attachments.push(part)}updateAttachBadge()})
|
||||||
el.composer.addEventListener('submit',async e=>{e.preventDefault();if(state.busy)return;const text=el.input.value.trim();if(!text&&!state.attachments.length)return;if(state.messages.length===0)state.currentThreadId=null;await ensureThreadOnFirstUser(text||'(attachments)');el.input.value='';const names=state.attachments.map(a=>a.label).join(', ');const display=text+(names?`\n\n**Attachments:** ${esc(names)}`:'');const contentParts=[];if(text)contentParts.push({type:'text',text});state.attachments.forEach(a=>contentParts.push(a.part));addMessage({role:'user',content:display,contentParts});state.busy=true;setBtnStop();const a=getActiveSune();const suneMeta={sune_name:a.name,model:store.model,avatar:a.avatar||''};const suneBubble=addSuneBubbleStreaming(suneMeta);let buf='',completed=false;await askOpenRouterStreaming((delta,done)=>{buf+=delta;renderMarkdown(suneBubble,buf,{enhance:false});if(done&&!completed){completed=true;setBtnSend();state.busy=false;enhanceCodeBlocks(suneBubble,true);state.messages.push({role:'assistant',content:buf,...suneMeta});persistThread();queueMicrotask(()=>el.chat.scrollTo({top:el.chat.scrollHeight,behavior:'smooth'}))}});state.attachments=[];updateAttachBadge()})
|
el.composer.addEventListener('submit',async e=>{e.preventDefault();if(state.busy)return;const text=el.input.value.trim();if(!text&&!state.attachments.length)return;if(state.messages.length===0)state.currentThreadId=null;await ensureThreadOnFirstUser(text||'(attachments)');el.input.value='';const names=state.attachments.map(a=>a.label).join(', ');const display=text+(names?`\n\n**Attachments:** ${esc(names)}`:'');const contentParts=[];if(text)contentParts.push({type:'text',text});state.attachments.forEach(a=>contentParts.push(a.part));addMessage({role:'user',content:display,contentParts});state.busy=true;setBtnStop();const a=getActiveSune();const suneMeta={sune_name:a.name,model:store.model,avatar:a.avatar||''};const suneBubble=addSuneBubbleStreaming(suneMeta);let buf='',completed=false;await askOpenRouterStreaming((delta,done)=>{buf+=delta;renderMarkdown(suneBubble,buf,{enhance:false});if(done&&!completed){completed=true;setBtnSend();state.busy=false;enhanceCodeBlocks(suneBubble,true);state.messages.push({role:'assistant',content:buf,...suneMeta});persistThread();queueMicrotask(()=>el.chat.scrollTo({top:el.chat.scrollHeight,behavior:'smooth'}))}});state.attachments=[];updateAttachBadge()})
|
||||||
function openSettings(){const a=getActiveSune(),s=a.settings;el.set_model.value=s.model;el.set_temperature.value=s.temperature;el.set_top_p.value=s.top_p;el.set_top_k.value=s.top_k;el.set_frequency_penalty.value=s.frequency_penalty;el.set_presence_penalty.value=s.presence_penalty;el.set_repetition_penalty.value=s.repetition_penalty;el.set_min_p.value=s.min_p;el.set_top_a.value=s.top_a;el.set_reasoning_effort.value=s.reasoning_effort||'default';el.set_system_prompt.value=s.system_prompt;el.set_script.value=s.script||'';bindScriptEditor();updateScriptHL();showModelTab();el.settingsModal.classList.remove('hidden')}
|
const showTab=name=>{['Model','Prompt','Script'].forEach(k=>{const on=k.toLowerCase()===name;el['tab'+k].classList.toggle('border-black',on);el['tab'+k].classList.toggle('border-transparent',!on);el['panel'+k].classList.toggle('hidden',!on)});if(name==='script'){scriptUpdate();scriptSync()}}
|
||||||
|
function openSettings(){const a=getActiveSune(),s=a.settings;el.set_model.value=s.model;el.set_temperature.value=s.temperature;el.set_top_p.value=s.top_p;el.set_top_k.value=s.top_k;el.set_frequency_penalty.value=s.frequency_penalty;el.set_presence_penalty.value=s.presence_penalty;el.set_repetition_penalty.value=s.repetition_penalty;el.set_min_p.value=s.min_p;el.set_top_a.value=s.top_a;el.set_reasoning_effort.value=s.reasoning_effort||'default';el.set_system_prompt.value=s.system_prompt;el.set_script.value=s.script||'';showTab('model');el.settingsModal.classList.remove('hidden');scriptUpdate();scriptSync()}
|
||||||
const closeSettings=()=>{el.settingsModal.classList.add('hidden')}
|
const closeSettings=()=>{el.settingsModal.classList.add('hidden')}
|
||||||
function showModelTab(){el.tabModel.classList.add('border-black');el.tabPrompt.classList.remove('border-black');el.tabScript.classList.remove('border-black');el.panelModel.classList.remove('hidden');el.panelPrompt.classList.add('hidden');el.panelScript.classList.add('hidden')}
|
|
||||||
function showPromptTab(){el.tabPrompt.classList.add('border-black');el.tabModel.classList.remove('border-black');el.tabScript.classList.remove('border-black');el.panelPrompt.classList.remove('hidden');el.panelModel.classList.add('hidden');el.panelScript.classList.add('hidden')}
|
|
||||||
function showScriptTab(){el.tabScript.classList.add('border-black');el.tabModel.classList.remove('border-black');el.tabPrompt.classList.remove('border-black');el.panelScript.classList.remove('hidden');el.panelModel.classList.add('hidden');el.panelPrompt.classList.add('hidden');updateScriptHL()}
|
|
||||||
let scriptBound=false;function scriptEls(){return {ta:document.getElementById('set_script'),code:document.getElementById('scriptHL')}}
|
|
||||||
function updateScriptHL(){const {ta,code}=scriptEls();if(!ta||!code)return;code.textContent=ta.value;window.hljs&&hljs.highlightElement(code);const pre=document.getElementById('scriptPre');if(pre)pre.scrollTop=ta.scrollTop}
|
|
||||||
function bindScriptEditor(){if(scriptBound)return;const {ta}=scriptEls();if(!ta)return;['input','change'].forEach(ev=>ta.addEventListener(ev,()=>updateScriptHL()));ta.addEventListener('scroll',()=>updateScriptHL());scriptBound=true}
|
|
||||||
el.settingsBtnTop.addEventListener('click',openSettings)
|
el.settingsBtnTop.addEventListener('click',openSettings)
|
||||||
el.closeSettings.addEventListener('click',closeSettings)
|
el.closeSettings.addEventListener('click',closeSettings)
|
||||||
el.cancelSettings.addEventListener('click',closeSettings)
|
el.cancelSettings.addEventListener('click',closeSettings)
|
||||||
el.settingsModal.addEventListener('click',e=>{if(e.target===el.settingsModal||e.target.classList.contains('bg-black/30'))closeSettings()})
|
el.settingsModal.addEventListener('click',e=>{if(e.target===el.settingsModal||e.target.classList.contains('bg-black/30'))closeSettings()})
|
||||||
el.tabModel.addEventListener('click',showModelTab)
|
el.tabModel.addEventListener('click',()=>showTab('model'))
|
||||||
el.tabPrompt.addEventListener('click',showPromptTab)
|
el.tabPrompt.addEventListener('click',()=>showTab('prompt'))
|
||||||
el.tabScript.addEventListener('click',showScriptTab)
|
el.tabScript.addEventListener('click',()=>showTab('script'))
|
||||||
|
const scriptUpdate=()=>{const v=el.set_script.value||'';el.scriptHL.innerHTML=window.hljs?hljs.highlight(v,{language:'javascript'}).value:esc(v)}
|
||||||
|
const scriptSync=()=>{const t=el.set_script,pre=el.scriptPre;pre.style.transform=`translate(${-t.scrollLeft}px,${-t.scrollTop}px)`}
|
||||||
|
el.set_script.addEventListener('input',()=>{scriptUpdate();scriptSync()})
|
||||||
|
el.set_script.addEventListener('scroll',scriptSync)
|
||||||
el.settingsForm.addEventListener('submit',e=>{e.preventDefault();const a=getActiveSune(),s=a.settings;s.model=(el.set_model.value||DEFAULT_MODEL).trim();s.temperature=clamp(num(el.set_temperature.value,1.0),0,2);s.top_p=clamp(num(el.set_top_p.value,1.0),0,1);s.top_k=Math.max(0,int(el.set_top_k.value,0));s.frequency_penalty=clamp(num(el.set_frequency_penalty.value,0.0),-2,2);s.presence_penalty=clamp(num(el.set_presence_penalty.value,0.0),-2,2);s.repetition_penalty=clamp(num(el.set_repetition_penalty.value,1.0),0,2);s.min_p=clamp(num(el.set_min_p.value,0.0),0,1);s.top_a=clamp(num(el.set_top_a.value,0.0),0,1);s.reasoning_effort=(el.set_reasoning_effort.value||'default');s.system_prompt=el.set_system_prompt.value.trim();s.script=el.set_script.value; a.updatedAt=Date.now();su.save(sunes);closeSettings();reflectActiveSune()})
|
el.settingsForm.addEventListener('submit',e=>{e.preventDefault();const a=getActiveSune(),s=a.settings;s.model=(el.set_model.value||DEFAULT_MODEL).trim();s.temperature=clamp(num(el.set_temperature.value,1.0),0,2);s.top_p=clamp(num(el.set_top_p.value,1.0),0,1);s.top_k=Math.max(0,int(el.set_top_k.value,0));s.frequency_penalty=clamp(num(el.set_frequency_penalty.value,0.0),-2,2);s.presence_penalty=clamp(num(el.set_presence_penalty.value,0.0),-2,2);s.repetition_penalty=clamp(num(el.set_repetition_penalty.value,1.0),0,2);s.min_p=clamp(num(el.set_min_p.value,0.0),0,1);s.top_a=clamp(num(el.set_top_a.value,0.0),0,1);s.reasoning_effort=(el.set_reasoning_effort.value||'default');s.system_prompt=el.set_system_prompt.value.trim();s.script=el.set_script.value; a.updatedAt=Date.now();su.save(sunes);closeSettings();reflectActiveSune()})
|
||||||
el.deleteSuneBtn.addEventListener('click',()=>{const activeId=su.getActiveId(),active=getActiveSune(),name=active?.name||'this sune';if(!confirm(`Delete "${name}"?`))return;sunes=sunes.filter(a=>a.id!==activeId);su.save(sunes);if(sunes.length===0){const def=createDefaultSune();sunes=[def];su.save(sunes);su.setActiveId(def.id)}else{su.setActiveId(sunes[0].id)}renderSidebar();reflectActiveSune();state.currentThreadId=null;clearChat();closeSettings()})
|
el.deleteSuneBtn.addEventListener('click',()=>{const activeId=su.getActiveId(),active=getActiveSune(),name=active?.name||'this sune';if(!confirm(`Delete "${name}"?`))return;sunes=sunes.filter(a=>a.id!==activeId);su.save(sunes);if(sunes.length===0){const def=createDefaultSune();sunes=[def];su.save(sunes);su.setActiveId(def.id)}else{su.setActiveId(sunes[0].id)}renderSidebar();reflectActiveSune();state.currentThreadId=null;clearChat();closeSettings()})
|
||||||
el.newSuneBtn.addEventListener('click',()=>{const name=prompt('Name your sune:');if(!name)return;const id=gid();sunes.unshift({id,name:name.trim(),pinned:false,avatar:'',updatedAt:Date.now(),settings:Object.assign({},defaultSettings)});su.save(sunes);su.setActiveId(id);renderSidebar();reflectActiveSune();state.currentThreadId=null;clearChat();document.getElementById('sidebar').classList.add('-translate-x-full');document.getElementById('sidebarOverlay').classList.add('hidden')})
|
el.newSuneBtn.addEventListener('click',()=>{const name=prompt('Name your sune:');if(!name)return;const id=gid();sunes.unshift({id,name:name.trim(),pinned:false,avatar:'',updatedAt:Date.now(),settings:Object.assign({},defaultSettings)});su.save(sunes);su.setActiveId(id);renderSidebar();reflectActiveSune();state.currentThreadId=null;clearChat();document.getElementById('sidebar').classList.add('-translate-x-full');document.getElementById('sidebarOverlay').classList.add('hidden')})
|
||||||
@@ -206,4 +212,4 @@ window.addEventListener('resize',()=>{hideHistoryMenu();hideSuneMenu()})
|
|||||||
init()
|
init()
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user