mirror of
https://github.com/yusufipk/dikte.git
synced 2026-09-11 19:06:11 +00:00
Run a dictation and a command to the agent at the same time
The two shared one state machine, which meant an agent thinking for a minute was a minute in which nothing could be dictated. That is the wrong trade: the work has nothing in common past the microphone, and the microphone is busy for the seconds you are speaking, not the minute afterwards. So they are two flows now, each with its own state, its own pipeline and its own indicator. Either can be working while the other records. Only the recorder is taken in turns, because there is one of it: whichever asks second is refused while the first holds it, and the menu entry greys out to say so rather than failing quietly. "Am I recording" is read off the two states rather than off the recorder's owner, which outlives the recording by the moment it takes the audio to arrive, and would otherwise report a microphone as busy after it was free. Two indicators in one corner would sit on top of each other, so an indicator can be told what it stacks on: it offsets by that one's height while it is showing and drops back into the corner when it goes, which the animation timer notices without anything having to tell it. Pasting is now under a lock. It is three steps rather than one, read the clipboard, write ours, press the key, and two runs finishing together would paste one answer and restore the other's clipboard over it. Calling off the agent is its own menu entry and its own command, instead of a cancel that meant different things depending on what was running. The tray icon still ends whichever recording is going.
This commit is contained in:
+24
-2
@@ -11,6 +11,7 @@ HEIGHT = 56
|
||||
MIN_WIDTH = 210
|
||||
MAX_WIDTH = 460
|
||||
MARGIN = 28
|
||||
GAP = 10 # between two indicators sharing a corner
|
||||
|
||||
BG = QColor(22, 24, 29, 238)
|
||||
BORDER = QColor(255, 255, 255, 28)
|
||||
@@ -31,9 +32,15 @@ LIVE = ("recording", "asking", "meeting")
|
||||
|
||||
|
||||
class Overlay(QWidget):
|
||||
def __init__(self, corner="bottom-left"):
|
||||
"""One indicator. Give it `below` and it stacks on top of that one instead
|
||||
of covering it, which is what lets a dictation and a command to the agent be
|
||||
under way at the same time and still both be visible."""
|
||||
|
||||
def __init__(self, corner="bottom-left", below=None):
|
||||
super().__init__(None)
|
||||
self.corner = corner
|
||||
self.below = below
|
||||
self._stacked = False
|
||||
self.state = "idle"
|
||||
self.message = ""
|
||||
self.levels = [0.0] * BARS
|
||||
@@ -114,6 +121,12 @@ class Overlay(QWidget):
|
||||
self._hide_timer.stop()
|
||||
self._conceal()
|
||||
|
||||
@property
|
||||
def showing(self):
|
||||
"""Mapped and actually painting something. The window stays mapped while
|
||||
idle, so isVisible() alone would always say yes."""
|
||||
return self.isVisible() and not self._concealed
|
||||
|
||||
def push_level(self, level):
|
||||
self.levels = self.levels[1:] + [level]
|
||||
|
||||
@@ -168,12 +181,21 @@ class Overlay(QWidget):
|
||||
area = screen.availableGeometry()
|
||||
left = "left" in self.corner
|
||||
top = "top" in self.corner
|
||||
self._stacked = self.below is not None and self.below.showing
|
||||
# Stack away from the edge the corner sits on, so the pair grows into the
|
||||
# screen rather than off it.
|
||||
step = (self.below.height() + GAP) if self._stacked else 0
|
||||
x = area.left() + MARGIN if left else area.right() - self.width() - MARGIN
|
||||
y = area.top() + MARGIN if top else area.bottom() - self.height() - MARGIN
|
||||
y = (area.top() + MARGIN + step if top
|
||||
else area.bottom() - self.height() - MARGIN - step)
|
||||
self.move(int(x), int(y))
|
||||
|
||||
def _tick(self):
|
||||
self._phase += 0.12
|
||||
# The one underneath can come and go while this one is up; drop back to
|
||||
# the corner when it does rather than leaving a gap where it was.
|
||||
if self.below is not None and self.below.showing != self._stacked:
|
||||
self._reposition()
|
||||
if self.state in LIVE:
|
||||
# keep the ribbon moving even through a pause in speech
|
||||
self.levels = self.levels[1:] + [self.levels[-1] * 0.72]
|
||||
|
||||
Reference in New Issue
Block a user