Updates
Rolling release / release (push) Successful in 8m31s

This commit is contained in:
2026-09-13 15:08:05 -04:00
parent b56171da9b
commit c5ccaa490b
29 changed files with 933 additions and 146 deletions
@@ -66,6 +66,8 @@ export default class JarvisExtension extends Extension {
this._applyAccessibility();
this._removeShellService = installShellService();
this._assistantName = 'Jarvis';
this._muted = false;
this._muteTouched = false;
this._indicator = new PanelMenu.Button(0.0, 'Jarvis QVAC', false); this._indicator.accessible_name = 'Jarvis voice assistant';
this._panelBox = new St.BoxLayout({ style_class: 'jarvis-panel-box', y_align: Clutter.ActorAlign.CENTER });
this._mark = new St.Icon({ icon_name: 'audio-input-microphone-symbolic', icon_size: 16, style_class: 'jarvis-panel-mark', y_align: Clutter.ActorAlign.CENTER });
@@ -84,14 +86,14 @@ export default class JarvisExtension extends Extension {
this._mountPopup();
this._indicator.connect('button-press-event', (_actor, event) => {
const button = event.get_button();
if (button === 2) { this._call('Arm'); return Clutter.EVENT_STOP; }
if (button === 2) { if (!this._muted) this._call('SetListening', '(b)', [true]); return Clutter.EVENT_STOP; }
return Clutter.EVENT_PROPAGATE;
});
this._keyName = 'hotkey';
try {
Main.wm.addKeybinding(this._keyName, this.settings, Meta.KeyBindingFlags.NONE, Shell.ActionMode.NORMAL | Shell.ActionMode.OVERVIEW, () => {
this._openPopup();
this._call('Arm');
if (!this._muted) this._call('SetListening', '(b)', [true]);
});
} catch (error) { log(`Jarvis hotkey unavailable: ${error.message}`); }
this._settingsChanged = this.settings.connect('changed::accent-color', () => this._applyAccent());
@@ -102,7 +104,14 @@ export default class JarvisExtension extends Extension {
try { this._lockChanged = Main.screenShield.connect('locked-changed', () => { if (Main.screenShield.locked) { this._closeShell(); this._call('ComputerRevoke'); } }); } catch {}
}
_bindSurface(view) {
view.onTalk = (pressed) => { if (pressed) { this._call('PushToTalk', '(b)', [true]); this._call('Arm'); } else { this._call('PushToTalk', '(b)', [false]); } };
view.onTalk = (pressed) => { if (this._muted) return; if (pressed) this._call('SetListening', '(b)', [true]); else this._call('SetListening', '(b)', [false]); };
view.onListen = () => { if (this._muted) return; this._call('SetListening', '(b)', [view._state !== 'LISTENING']); };
view.onMute = (muted) => {
this._muted = Boolean(muted);
this._muteTouched = true;
this._eachView((surface) => surface.setMuted(this._muted));
this._call('SetMuted', '(b)', [this._muted]);
};
view.onStop = () => this._call('Cancel');
view.onReset = () => { this._eachView((surface) => { surface.clear(); surface.setNotice('New conversation'); }); this._call('ResetContext'); };
view.onAsk = (text) => { this._eachView((surface) => surface.addRow('U', text)); this._call('Ask', '(s)', [text]); };
@@ -257,9 +266,12 @@ export default class JarvisExtension extends Extension {
const voice = status.voice;
this._eachView((view) => view.setConnectionStatus(voice ? 'local' : 'voice-unavailable'));
if (voice) {
const input = Boolean(voice.capture);
const remoteMuted = Boolean(voice.muted ?? status.muted);
if (!this._muteTouched) this._muted = remoteMuted;
const muted = Boolean(this._muted);
const input = Boolean(voice.capture) || muted;
const tts = Boolean(voice.tts || voice.speech);
this._eachView((view) => view.setVoiceStatus({ tts, input, wake: voice.wake }));
this._eachView((view) => view.setVoiceStatus({ tts, input, wake: muted ? false : voice.wake, muted }));
}
const name = status.settings?.assistantName;
if (name) this._applyAssistantName(name);
@@ -267,13 +279,13 @@ export default class JarvisExtension extends Extension {
}
_call(name, signature, value) {
if (!this.proxy?.owned?.()) {
if (name !== 'PushToTalk') this._eachView((view) => view.setNotice(`${this._assistantName || 'Jarvis'} is starting…`));
if (name !== 'PushToTalk' && name !== 'SetMuted' && name !== 'SetListening') this._eachView((view) => view.setNotice(`${this._assistantName || 'Jarvis'} is starting…`));
this._connectDaemon();
return;
}
this.proxy.call(name, signature, value).catch((error) => {
log(`Jarvis ${name}: ${error.message}`);
if (name === 'PushToTalk') return;
if (name === 'PushToTalk' || name === 'SetMuted' || name === 'SetListening') return;
const fallback = name === 'ResetContext' ? 'Could not reset conversation' : `${name} failed: ${shortError(error.message)}`;
this._eachView((view) => view.setNotice(fallback));
});