add featureBridge func for listenservice

This commit is contained in:
sanio 2025-07-13 04:57:54 +09:00
parent 3bece73f78
commit a951d02a59
5 changed files with 158 additions and 51 deletions

2
aec

@ -1 +1 @@
Subproject commit f00bb1fb948053c752b916adfee19f90644a0b2f
Subproject commit 9e11f4f95707714464194bdfc9db0222ec5c6163

View File

@ -29,6 +29,21 @@ module.exports = {
});
console.log('[FeatureBridge] Initialized with settings handlers.');
ipcMain.handle('listen:changeSession', async (event, listenButtonText) => {
console.log('[FeatureBridge] listen:changeSession from mainheader', listenButtonText);
try {
await listenService.handleListenRequest(listenButtonText);
return { success: true };
} catch (error) {
console.error('[FeatureBridge] listen:changeSession failed', error.message);
return { success: false, error: error.message };
}
});
},
// Renderer로 상태를 전송

View File

@ -51,6 +51,47 @@ class ListenService {
console.log('[ListenService] Initialized and ready.');
}
async handleListenRequest(listenButtonText) {
const { windowPool, updateLayout } = require('../../window/windowManager');
const listenWindow = windowPool.get('listen');
const header = windowPool.get('header');
try {
switch (listenButtonText) {
case 'Listen':
console.log('[ListenService] changeSession to "Listen"');
listenWindow.show();
updateLayout();
listenWindow.webContents.send('window-show-animation');
await this.initializeSession();
listenWindow.webContents.send('session-state-changed', { isActive: true });
break;
case 'Stop':
console.log('[ListenService] changeSession to "Stop"');
await this.closeSession();
listenWindow.webContents.send('session-state-changed', { isActive: false });
break;
case 'Done':
console.log('[ListenService] changeSession to "Done"');
listenWindow.webContents.send('window-hide-animation');
listenWindow.webContents.send('session-state-changed', { isActive: false });
break;
default:
throw new Error(`[ListenService] unknown listenButtonText: ${listenButtonText}`);
}
header.webContents.send('listen:changeSessionResult', { success: true });
} catch (error) {
console.error('[ListenService] error in handleListenRequest:', error);
header.webContents.send('listen:changeSessionResult', { success: false });
throw error;
}
}
async handleTranscriptionComplete(speaker, text) {
console.log(`[ListenService] Transcription complete: ${speaker} - ${text}`);

View File

@ -4,8 +4,8 @@ export class MainHeader extends LitElement {
static properties = {
// isSessionActive: { type: Boolean, state: true },
isTogglingSession: { type: Boolean, state: true },
actionText: { type: String, state: true },
shortcuts: { type: Object, state: true },
listenSessionStatus: { type: String, state: true },
};
static styles = css`
@ -348,9 +348,8 @@ export class MainHeader extends LitElement {
this.isAnimating = false;
this.hasSlidIn = false;
this.settingsHideTimer = null;
// this.isSessionActive = false;
this.isTogglingSession = false;
this.actionText = 'Listen';
this.listenSessionStatus = 'beforeSession';
this.animationEndTimer = null;
this.handleAnimationEnd = this.handleAnimationEnd.bind(this);
this.handleMouseMove = this.handleMouseMove.bind(this);
@ -359,6 +358,15 @@ export class MainHeader extends LitElement {
this.wasJustDragged = false;
}
_getListenButtonText(status) {
switch (status) {
case 'beforeSession': return 'Listen';
case 'inSession' : return 'Stop';
case 'afterSession': return 'Done';
default : return 'Listen';
}
}
async handleMouseDown(e) {
e.preventDefault();
@ -469,18 +477,20 @@ export class MainHeader extends LitElement {
if (window.require) {
const { ipcRenderer } = window.require('electron');
this._sessionStateTextListener = (event, text) => {
this.actionText = text;
this.isTogglingSession = false;
this._sessionStateTextListener = (event, { success }) => {
if (success) {
this.listenSessionStatus = ({
beforeSession: 'inSession',
inSession: 'afterSession',
afterSession: 'beforeSession',
})[this.listenSessionStatus] || 'beforeSession';
} else {
this.listenSessionStatus = 'beforeSession';
}
this.isTogglingSession = false; // ✨ 로딩 상태만 해제
};
ipcRenderer.on('session-state-text', this._sessionStateTextListener);
ipcRenderer.on('listen:changeSessionResult', this._sessionStateTextListener);
// this._sessionStateListener = (event, { isActive }) => {
// this.isSessionActive = isActive;
// this.isTogglingSession = false;
// };
// ipcRenderer.on('session-state-changed', this._sessionStateListener);
this._shortcutListener = (event, keybinds) => {
console.log('[MainHeader] Received updated shortcuts:', keybinds);
this.shortcuts = keybinds;
@ -501,11 +511,8 @@ export class MainHeader extends LitElement {
if (window.require) {
const { ipcRenderer } = window.require('electron');
if (this._sessionStateTextListener) {
ipcRenderer.removeListener('session-state-text', this._sessionStateTextListener);
ipcRenderer.removeListener('listen:changeSessionResult', this._sessionStateTextListener);
}
// if (this._sessionStateListener) {
// ipcRenderer.removeListener('session-state-changed', this._sessionStateListener);
// }
if (this._shortcutListener) {
ipcRenderer.removeListener('shortcuts-updated', this._shortcutListener);
}
@ -557,11 +564,11 @@ export class MainHeader extends LitElement {
this.isTogglingSession = true;
try {
const channel = 'toggle-feature';
const args = ['listen'];
await this.invoke(channel, ...args);
const channel = 'listen:changeSession';
const listenButtonText = this._getListenButtonText(this.listenSessionStatus);
await this.invoke(channel, listenButtonText);
} catch (error) {
console.error('IPC invoke for session toggle failed:', error);
console.error('IPC invoke for session change failed:', error);
this.isTogglingSession = false;
}
}
@ -591,11 +598,13 @@ export class MainHeader extends LitElement {
}
render() {
const listenButtonText = this._getListenButtonText(this.listenSessionStatus);
const buttonClasses = {
active: this.actionText === 'Stop',
done: this.actionText === 'Done',
active: listenButtonText === 'Stop',
done: listenButtonText === 'Done',
};
const showStopIcon = this.actionText === 'Stop' || this.actionText === 'Done';
const showStopIcon = listenButtonText === 'Stop' || listenButtonText === 'Done';
return html`
<div class="header" @mousedown=${this.handleMouseDown}>
@ -612,7 +621,7 @@ export class MainHeader extends LitElement {
`
: html`
<div class="action-text">
<div class="action-text-content">${this.actionText}</div>
<div class="action-text-content">${listenButtonText}</div>
</div>
<div class="listen-icon">
${showStopIcon

View File

@ -1025,6 +1025,47 @@ function setupIpcHandlers(movementManager) {
toggleFeature('ask', {ask: { questionText: question }});
return { success: true };
});
// ipcMain.handle('listen:changeSession', async (event, actionText) => {
// console.log('📨 Main process: Received actionText', actionText);
// const header = windowPool.get('header');
// const listenWindow = windowPool.get('listen');
// try {
// if (listenService && listenService.isSessionActive()) {
// console.log('[WindowManager] Listen session is active, closing it.');
// // ✨ closeSession도 비동기일 수 있으므로 await 처리 (만약 동기 함수라면 await는 무시됨)
// await listenService.closeSession();
// listenWindow.webContents.send('session-state-changed', { isActive: false });
// } else {
// if (listenWindow.isVisible()) {
// listenWindow.webContents.send('window-hide-animation');
// listenWindow.webContents.send('session-state-changed', { isActive: false });
// } else {
// listenWindow.show();
// updateLayout();
// listenWindow.webContents.send('window-show-animation');
// // ✨ 핵심: initializeSession 작업이 끝날 때까지 기다림
// await listenService.initializeSession();
// listenWindow.webContents.send('session-state-changed', { isActive: true });
// }
// }
// // ✨ 모든 비동기 작업이 성공적으로 끝난 후 결과 전송
// header.webContents.send('listen:changeSessionResult', { success: true });
// return { success: true };
// } catch (error) {
// console.error('[WindowManager] Failed to change listen session:', error);
// // ✨ 작업 실패 시 UI에 실패 결과를 알려 로딩 상태를 해제하도록 함
// header.webContents.send('listen:changeSessionResult', { success: false });
// return { success: false, error: error.message };
// }
// });
}
@ -1043,31 +1084,31 @@ async function toggleFeature(featureName, options = {}) {
}
const header = windowPool.get('header');
if (featureName === 'listen') {
console.log(`[WindowManager] Toggling feature: ${featureName}`);
const listenWindow = windowPool.get(featureName);
// const listenService = global.listenService;
if (listenService && listenService.isSessionActive()) {
console.log('[WindowManager] Listen session is active, closing it via toggle.');
await listenService.closeSession();
listenWindow.webContents.send('session-state-changed', { isActive: false });
header.webContents.send('session-state-text', 'Done');
// return;
} else {
if (listenWindow.isVisible()) {
listenWindow.webContents.send('window-hide-animation');
listenWindow.webContents.send('session-state-changed', { isActive: false });
header.webContents.send('session-state-text', 'Listen');
} else {
listenWindow.show();
updateLayout();
listenWindow.webContents.send('window-show-animation');
await listenService.initializeSession();
listenWindow.webContents.send('session-state-changed', { isActive: true });
header.webContents.send('session-state-text', 'Stop');
}
}
}
// if (featureName === 'listen') {
// console.log(`[WindowManager] Toggling feature: ${featureName}`);
// const listenWindow = windowPool.get(featureName);
// // const listenService = global.listenService;
// if (listenService && listenService.isSessionActive()) {
// console.log('[WindowManager] Listen session is active, closing it via toggle.');
// await listenService.closeSession();
// listenWindow.webContents.send('session-state-changed', { isActive: false });
// header.webContents.send('session-state-text', 'Done');
// // return;
// } else {
// if (listenWindow.isVisible()) {
// listenWindow.webContents.send('window-hide-animation');
// listenWindow.webContents.send('session-state-changed', { isActive: false });
// header.webContents.send('session-state-text', 'Listen');
// } else {
// listenWindow.show();
// updateLayout();
// listenWindow.webContents.send('window-show-animation');
// await listenService.initializeSession();
// listenWindow.webContents.send('session-state-changed', { isActive: true });
// header.webContents.send('session-state-text', 'Stop');
// }
// }
// }
if (featureName === 'ask') {
let askWindow = windowPool.get('ask');
@ -1428,6 +1469,7 @@ async function captureScreenshot(options = {}) {
}
module.exports = {
updateLayout,
createWindows,
windowPool,
fixedYPosition,