Signals' page copy says what happens, not that Jev does it; Auto spins while it picks (#263)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -444,8 +444,8 @@ async function prefsModal(){
|
||||
<div class="inline"><input type="password" id="stskey" autocomplete="off" spellcheck="false"
|
||||
placeholder="${S.me?.typesafe_key_set?'Saved. Paste a new one to replace it':'Paste your key'}">
|
||||
<button class="btn ico" id="stsforget" title="Forget the key" aria-label="Forget the key"${S.me?.typesafe_key_set?'':' hidden'}>${ICON.trash}</button></div>
|
||||
<span class="hint">Signals pick what matters out of everything you subscribe to, using TypeSafe's
|
||||
Jev on your own key, from <a href="https://typesafe.ai" target="_blank" rel="noopener">typesafe.ai</a>.
|
||||
<span class="hint">Signals pick what matters out of everything you subscribe to, on your own
|
||||
key from <a href="https://typesafe.ai" target="_blank" rel="noopener">typesafe.ai</a>.
|
||||
The key is kept on this server and never shown again.</span></div>
|
||||
<div class="field boxed"><label for="tokname">API tokens</label>
|
||||
<div id="tokens"></div>
|
||||
|
||||
@@ -134,7 +134,7 @@ function renderEntries(){
|
||||
// Said only for a search, where the words typed are why; an empty feed or tab speaks for itself.
|
||||
if(S.q) box.innerHTML='<p class="empty">Nothing matches that search.</p>';
|
||||
// A new Signal is empty while Jev reads, which would otherwise look broken.
|
||||
else if(sg&&S.filter==='all') box.innerHTML='<p class="empty">Nothing has come through yet. Jev reads new items as your feeds are checked.</p>';
|
||||
else if(sg&&S.filter==='all') box.innerHTML='<p class="empty">Nothing has come through yet. New items are read as your feeds are checked.</p>';
|
||||
return;
|
||||
}
|
||||
for(const e of S.entries) box.appendChild(epEl(e));
|
||||
|
||||
@@ -139,7 +139,7 @@ function signalModal(sg?: Signal){
|
||||
<input type="text" id="sgname" value="${esc(sg?.name||'')}" placeholder="Formula 1"></div>
|
||||
<div id="sgpicker" hidden>
|
||||
<div class="inline"><input type="search" id="sgiconq" placeholder="Search icons: robot, car, music…" autocomplete="off">
|
||||
<button type="button" class="dlink" id="sgjev" title="Let Jev pick an icon">Auto</button>
|
||||
<button type="button" class="dlink" id="sgjev" title="Pick an icon for me">Auto</button>
|
||||
<button type="button" class="dlink" id="sgnoicon">Initials</button></div>
|
||||
<div class="icongrid" id="sgicons" role="listbox" aria-label="Icons"></div>
|
||||
</div></div>
|
||||
@@ -147,10 +147,10 @@ function signalModal(sg?: Signal){
|
||||
<div class="chips" id="sgkw">${chipsHTML(sg?.keywords||[],'sgkwin')}</div></div>
|
||||
<div class="field"><label for="sgdesc">In your own words (optional)</label>
|
||||
<input type="text" id="sgdesc" value="${esc(sg?.description||'')}" placeholder="AI tools for writing software: coding agents, vibe coding">
|
||||
<span class="hint">TypeSafe's Jev reads every item in the feeds you subscribe to, the last 30
|
||||
days of them and each new one, and pulls out the ones about this subject: its name, these
|
||||
words and your sentence together. The rest stays noise, in its own feed. Each item is one
|
||||
call on your TypeSafe key.${sg?' A change here reads everything again.':''}</span></div>
|
||||
<span class="hint">Every item in the feeds you subscribe to is read, the last 30 days of them
|
||||
and each new one, and the ones about this subject are pulled out: its name, these words and
|
||||
your sentence together. The rest stays noise, in its own feed. Each item is one call on your
|
||||
TypeSafe key.${sg?' A change here reads everything again.':''}</span></div>
|
||||
${nokey?'<p class="hint" style="color:var(--warn)">Add your TypeSafe key in Settings first: without one, nothing is picked out.</p>':''}
|
||||
<div class="cardacts"><button class="btn ico" onclick="closeModal()" title="Cancel" aria-label="Cancel">${ICON.close}</button>
|
||||
<button class="btn ico primary" id="sgsave" title="${sg?'Save':'Make signal'}" aria-label="${sg?'Save':'Make signal'}">${sg?ICON.check:ICON.plus}</button></div>`);
|
||||
@@ -179,14 +179,15 @@ function signalModal(sg?: Signal){
|
||||
};
|
||||
$<HTMLButtonElement>('#sgnoicon').onclick=()=>{ icon=null; drawPick(); $('#sgpicker').hidden=true; };
|
||||
$<HTMLButtonElement>('#sgjev').onclick=async()=>{
|
||||
const b=$<HTMLButtonElement>('#sgjev'); b.disabled=true; b.textContent='Asking Jev…';
|
||||
// A spinner while it is picked: what picks it is nobody's concern.
|
||||
const b=$<HTMLButtonElement>('#sgjev'); b.disabled=true; b.classList.add('busy'); b.setAttribute('aria-busy','true');
|
||||
try{
|
||||
const got=await jevIcon($<HTMLInputElement>('#sgname').value.trim(),chipWords($('#sgkw')).filter((w): w is string=>!!w),
|
||||
$<HTMLInputElement>('#sgdesc').value.trim()||null);
|
||||
if(got){ icon=got; drawPick(); $('#sgpicker').hidden=true; $('#sgicon').setAttribute('aria-expanded','false'); }
|
||||
else toast('No icon matches those words');
|
||||
}catch(e){ toast(why(e),true); }
|
||||
finally{ b.disabled=false; b.textContent='Auto'; }
|
||||
finally{ b.disabled=false; b.classList.remove('busy'); b.removeAttribute('aria-busy'); }
|
||||
};
|
||||
$<HTMLInputElement>('#sgname').focus();
|
||||
$<HTMLButtonElement>('#sgsave').onclick=async()=>{
|
||||
@@ -204,7 +205,7 @@ function signalModal(sg?: Signal){
|
||||
if(!sg&&!icon) jevIcon(name,keywords,description)
|
||||
.then(got=>{ if(got) return api(`/api/signals/${r.id}`,{method:'PATCH',body:JSON.stringify({icon:got})}).then(refreshSignals); })
|
||||
.catch(()=>{});
|
||||
closeModal(); toast(sg?'Saved. Jev reads everything again':'Listening. What Jev picks out shows up here');
|
||||
closeModal(); toast(sg?'Saved. Everything is read again':'Listening. What comes through shows up here');
|
||||
// Open, so the new one is there to see.
|
||||
if(!expanded.has(SIGNALS)) toggleGroup(SIGNALS);
|
||||
await loadFeeds(true); selectFeed(':signal:'+(sg?sg.id:r.id));
|
||||
|
||||
Reference in New Issue
Block a user