Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -423,15 +423,14 @@
box-shadow:0 6px 22px rgba(59,110,246,.45);display:flex;align-items:center;justify-content:center;
}
.micfab:active{transform:scale(.92)}
.micfab.live{background:var(--red);box-shadow:0 6px 22px rgba(226,72,61,.5);animation:pulse 1.1s infinite}
.vmodal{position:fixed;inset:0;z-index:60;display:none;align-items:center;justify-content:center;
padding:20px;background:rgba(20,24,35,.4)}
.vmodal.show{display:flex}
/* capture window: floating, docked bottom-right ABOVE the mic; no dimming, mic stays clickable (it sits at a higher z-index) */
/* capture window: floating, docked bottom-right ABOVE the + button; no dimming, + stays clickable (higher z-index) */
#vmodal{background:transparent;pointer-events:none}
#vmodal.show{justify-content:flex-end;align-items:flex-end;padding:0 18px 102px 0}
#vmodal.show .capwrap,#vmodal.show .caprestore{pointer-events:auto}
/* minimized chat: collapse the window to a small restore pill above the mic */
/* minimized chat: collapse the window to a small restore pill above the + button */
.capmin{font-size:18px;line-height:1;font-weight:800;padding:5px 11px 8px}
.caprestore{display:none;align-items:center;gap:9px;background:var(--surface);color:var(--ink);
border-radius:15px;box-shadow:0 16px 50px rgba(20,24,35,.28);border:1px solid var(--line);
Expand Down Expand Up @@ -502,7 +501,7 @@
.mini{flex:none;width:30px;height:30px;border-radius:9px;background:var(--accent-soft);color:var(--accent);font-size:16px;font-weight:700;
display:inline-flex;align-items:center;justify-content:center}
.mini:active{transform:scale(.92)}
.cappanel.chatp .caprow{flex:none} /* keep the mic row pinned & visible */
.cappanel.chatp .caprow{flex:none} /* keep the input row pinned & visible */
.crow.col{flex-direction:column;align-items:stretch;gap:7px}
.caphead{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:12px}
.ttsbtn{font-size:12px;font-weight:700;color:var(--ink-2);background:#eef0f4;border-radius:8px;padding:7px 11px}
Expand Down Expand Up @@ -668,7 +667,7 @@
<button class="sbicon" title="New project" onclick="addProject()">
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M3.5 6.2h5.2l1.4 1.6h6.4v8.6a1.6 1.6 0 0 1-1.6 1.6H5.1a1.6 1.6 0 0 1-1.6-1.6V6.2z"/><path d="M10 10.2v4.2M8 12.3h4"/></svg>
</button>
<button class="sbicon" title="New (talk to assistant)" onclick="micFabTap()">
<button class="sbicon" title="Open assistant" onclick="micFabTap()">
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"><path d="M10 4.5v11M4.5 10h11"/></svg>
</button>
<button class="sbicon" title="Process a conversation transcript" onclick="openTranscript()">
Expand Down Expand Up @@ -756,7 +755,9 @@
</div>
</main>

<button class="micfab" id="micFab" onclick="micFabTap()" aria-label="Talk to assistant">πŸŽ™</button>
<button class="micfab" id="micFab" onclick="micFabTap()" aria-label="Open assistant">
<svg width="28" height="28" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M10 4.5v11M4.5 10h11"/></svg>
</button>

<div class="vmodal" id="vmodal">
<div class="capwrap">
Expand All @@ -780,8 +781,9 @@ <h3>Assistant</h3>
<input type="file" accept=".txt,.md,.vtt,.srt,.text,text/plain" style="display:none" onchange="attachTranscript(this)">
<svg width="19" height="19" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M15.5 9.2l-5.4 5.4a3.3 3.3 0 0 1-4.7-4.7l6-6a2.2 2.2 0 0 1 3.1 3.1l-6 6a1.1 1.1 0 0 1-1.6-1.6l5.4-5.4"/></svg>
</label>
<input id="capInput" class="capinput" placeholder="Type, or tap the mic below…" autocomplete="off"
<input id="capInput" class="capinput" placeholder="Type, or tap the mic to talk…" autocomplete="off"
onkeydown="if(event.key==='Enter'){event.preventDefault();sendTurn();}">
<button class="micbtn" id="capVoice" type="button" onclick="toggleListen()" aria-label="Voice chat" title="Voice chat">πŸŽ™</button>
<button class="capsend" id="capSend" onclick="sendTurn()">Send</button>
</div>
</div>
Expand Down
9 changes: 5 additions & 4 deletions src/app/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -1547,11 +1547,12 @@ function pushApproved(){ if(!PROP) return; snap(); let np=0;
/* ---- continuous mic: stays live, auto-sends each finished sentence as a turn until you
stop it. Finished sentences are queued so a slow extract call never drops one. ---- */
let capQueue=[], speaking=false, micPaused=false;
function setMic(on){ listening=on; const f=$id("micFab"); if(f) f.classList.toggle("live",on); }
/* the bottom-right mic is the only mic: tap to open the chat (if needed) and talk; tap again to stop */
function setMic(on){ listening=on; const v=$id("capVoice"); if(v) v.classList.toggle("live",on); }
/* bottom-right + opens chat; voice is started from the mic button beside Send */
function micFabTap(){ const m=$id("vmodal");
if(CAP&&m&&m.classList.contains("min")){ restoreCapture(); return; } // expand instead of toggling mic
if(!CAP){ openCapture(); setTimeout(toggleListen,150); } else toggleListen(); }
if(CAP&&m&&m.classList.contains("min")){ restoreCapture(); return; }
if(!CAP) openCapture();
else setTimeout(()=>$id("capInput")?.focus(),50); }
function pushTurn(text){ capQueue.push(text); drainQueue(); }
async function drainQueue(){ if(!CAP||CAP.busy) return;
while(capQueue.length){ $id("capInput").value=capQueue.shift(); await sendTurn(); } }
Expand Down
Loading