mirror of
https://github.com/mikodin/obsidian-scribe.git
synced 2026-07-22 11:30:23 +00:00
113 open controls modal window stoping in the background (#114)
* feat: enhance recording modal behavior and state management * chore: bump version to 2.4.2 in manifest.json and package.json
This commit is contained in:
parent
b5e055c6a1
commit
5f91b2398e
7 changed files with 59 additions and 36 deletions
|
|
@ -192,6 +192,8 @@ Always includes a `fileTitle` field for note renaming.
|
|||
### Recording UX State Model
|
||||
|
||||
- Modal, command palette, and ribbon all treat paused recordings as in-progress sessions.
|
||||
- Closing the controls modal does NOT cancel an active recording — it hands off to the persistent tappable recording notice; reopening the modal hides the notice and re-attaches to the live recording. Cancelling is always explicit (modal Reset, ribbon Cancel).
|
||||
- Per-session modal options persist in `state.sessionScribeOptions` while a recording is active; `scribe()` falls back to them when called without options (notice tap, ribbon Stop, palette toggle). Cleared on cancel/cleanup/modal-close-when-idle.
|
||||
- Recording notice/timer messages are derived from recorder-aware elapsed duration (paused time not counted).
|
||||
- `ScribePlugin` exposes helper methods used across entry points to avoid state drift:
|
||||
- `isRecordingActive()`
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "scribe",
|
||||
"name": "Scribe",
|
||||
"version": "2.4.1",
|
||||
"version": "2.4.2",
|
||||
"minAppVersion": "1.8.7",
|
||||
"description": "Record, transcribe, and transform voice notes into structured insights. Leverage Whisper or AssemblyAI and ChatGPT to fill in gaps, generate summaries, and visualize ideas — all seamlessly integrated within your vault.",
|
||||
"author": "Mike Alicea",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "obsidian-scribe-plugin",
|
||||
"version": "2.4.1",
|
||||
"version": "2.4.2",
|
||||
"description": "An Obsidian plugin for recording voice notes, transcribing the audio, and summarizing the text - All in one",
|
||||
"main": "build/main.js",
|
||||
"scripts": {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,11 @@
|
|||
import type ScribePlugin from 'src';
|
||||
import { ScribeControlsModal } from 'src/modal/scribeControlsModal';
|
||||
|
||||
export function handleCommands(plugin: ScribePlugin) {
|
||||
plugin.addCommand({
|
||||
id: 'scribe-recording-modal',
|
||||
name: 'Open recording modal',
|
||||
callback: () => {
|
||||
plugin.state.isOpen = true;
|
||||
new ScribeControlsModal(plugin).open();
|
||||
plugin.controlModal.open();
|
||||
},
|
||||
});
|
||||
plugin.addCommand({
|
||||
|
|
|
|||
35
src/index.ts
35
src/index.ts
|
|
@ -55,6 +55,7 @@ export interface ScribeState {
|
|||
counter: number;
|
||||
audioRecord: AudioRecord | null;
|
||||
isProcessing: boolean;
|
||||
sessionScribeOptions: ScribeOptions | null;
|
||||
}
|
||||
|
||||
const DEFAULT_STATE: ScribeState = {
|
||||
|
|
@ -62,6 +63,7 @@ const DEFAULT_STATE: ScribeState = {
|
|||
counter: 0,
|
||||
audioRecord: null,
|
||||
isProcessing: false,
|
||||
sessionScribeOptions: null,
|
||||
};
|
||||
|
||||
export interface ScribeOptions {
|
||||
|
|
@ -186,27 +188,29 @@ export default class ScribePlugin extends Plugin {
|
|||
|
||||
async cancelRecording() {
|
||||
this.hideRecordingNotice();
|
||||
this.state.sessionScribeOptions = null;
|
||||
if (this.state.audioRecord?.mediaRecorder) {
|
||||
new Notice('Scribe: 🛑️ Recording cancelled');
|
||||
await this.state.audioRecord?.stopRecording();
|
||||
}
|
||||
}
|
||||
|
||||
async scribe(
|
||||
scribeOptions: ScribeOptions = {
|
||||
isAppendToActiveFile: this.settings.isAppendToActiveFile,
|
||||
isOnlyTranscribeActive: this.settings.isOnlyTranscribeActive,
|
||||
isMultiSpeakerEnabled: this.settings.isMultiSpeakerEnabled,
|
||||
isSaveAudioFileActive: this.settings.isSaveAudioFileActive,
|
||||
isDisableLlmTranscription: this.settings.isDisableLlmTranscription,
|
||||
audioFileLanguage: this.settings.audioFileLanguage,
|
||||
scribeOutputLanguage: this.settings.scribeOutputLanguage,
|
||||
transcriptPlatform: this.settings.transcriptPlatform,
|
||||
processPlatform: this.settings.processPlatform,
|
||||
llmModel: resolveLlmConfig(this.settings).model,
|
||||
activeNoteTemplate: this.settings.activeNoteTemplate,
|
||||
},
|
||||
) {
|
||||
async scribe(scribeOptionsOverride?: ScribeOptions) {
|
||||
const scribeOptions: ScribeOptions = scribeOptionsOverride ??
|
||||
this.state.sessionScribeOptions ?? {
|
||||
isAppendToActiveFile: this.settings.isAppendToActiveFile,
|
||||
isOnlyTranscribeActive: this.settings.isOnlyTranscribeActive,
|
||||
isMultiSpeakerEnabled: this.settings.isMultiSpeakerEnabled,
|
||||
isSaveAudioFileActive: this.settings.isSaveAudioFileActive,
|
||||
isDisableLlmTranscription: this.settings.isDisableLlmTranscription,
|
||||
audioFileLanguage: this.settings.audioFileLanguage,
|
||||
scribeOutputLanguage: this.settings.scribeOutputLanguage,
|
||||
transcriptPlatform: this.settings.transcriptPlatform,
|
||||
processPlatform: this.settings.processPlatform,
|
||||
llmModel: resolveLlmConfig(this.settings).model,
|
||||
activeNoteTemplate: this.settings.activeNoteTemplate,
|
||||
};
|
||||
|
||||
this.state.isProcessing = true;
|
||||
try {
|
||||
const baseFileName = formatFilenamePrefix(
|
||||
|
|
@ -602,6 +606,7 @@ export default class ScribePlugin extends Plugin {
|
|||
this.controlModal.close();
|
||||
this.state.audioRecord = null;
|
||||
this.state.isProcessing = false;
|
||||
this.state.sessionScribeOptions = null;
|
||||
}
|
||||
|
||||
showRecordingNotice() {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ export class ScribeControlsModal extends Modal {
|
|||
|
||||
onOpen() {
|
||||
this.plugin.state.isOpen = true;
|
||||
this.plugin.hideRecordingNotice();
|
||||
this.initModal();
|
||||
}
|
||||
|
||||
|
|
@ -28,8 +29,13 @@ export class ScribeControlsModal extends Modal {
|
|||
const { contentEl } = this;
|
||||
contentEl.empty();
|
||||
this.plugin.state.isOpen = false;
|
||||
void this.plugin.cancelRecording();
|
||||
this.root?.unmount();
|
||||
|
||||
if (this.plugin.isRecordingActive()) {
|
||||
this.plugin.showRecordingNotice();
|
||||
} else {
|
||||
this.plugin.state.sessionScribeOptions = null;
|
||||
}
|
||||
}
|
||||
|
||||
initModal() {
|
||||
|
|
@ -58,20 +64,26 @@ const ScribeModal: React.FC<{ plugin: ScribePlugin }> = ({ plugin }) => {
|
|||
const [elapsedRecordingTimeMs, setElapsedRecordingTimeMs] = useState<number>(
|
||||
plugin.getRecordingDurationMs(),
|
||||
);
|
||||
const [scribeOptions, setScribeOptions] = useState<ScribeOptions>({
|
||||
isAppendToActiveFile: plugin.settings.isAppendToActiveFile,
|
||||
isOnlyTranscribeActive: plugin.settings.isOnlyTranscribeActive,
|
||||
isSaveAudioFileActive: plugin.settings.isSaveAudioFileActive,
|
||||
isMultiSpeakerEnabled: plugin.settings.isMultiSpeakerEnabled,
|
||||
isDisableLlmTranscription: plugin.settings.isDisableLlmTranscription,
|
||||
audioFileLanguage: plugin.settings.audioFileLanguage,
|
||||
scribeOutputLanguage: plugin.settings.scribeOutputLanguage,
|
||||
transcriptPlatform: plugin.settings.transcriptPlatform,
|
||||
processPlatform: plugin.settings.processPlatform,
|
||||
llmModel: resolveLlmConfig(plugin.settings).model,
|
||||
activeNoteTemplate: plugin.settings.activeNoteTemplate,
|
||||
additionalSystemPrompt: '',
|
||||
});
|
||||
const [scribeOptions, setScribeOptions] = useState<ScribeOptions>(
|
||||
(isRecordingInProgress && plugin.state.sessionScribeOptions) || {
|
||||
isAppendToActiveFile: plugin.settings.isAppendToActiveFile,
|
||||
isOnlyTranscribeActive: plugin.settings.isOnlyTranscribeActive,
|
||||
isSaveAudioFileActive: plugin.settings.isSaveAudioFileActive,
|
||||
isMultiSpeakerEnabled: plugin.settings.isMultiSpeakerEnabled,
|
||||
isDisableLlmTranscription: plugin.settings.isDisableLlmTranscription,
|
||||
audioFileLanguage: plugin.settings.audioFileLanguage,
|
||||
scribeOutputLanguage: plugin.settings.scribeOutputLanguage,
|
||||
transcriptPlatform: plugin.settings.transcriptPlatform,
|
||||
processPlatform: plugin.settings.processPlatform,
|
||||
llmModel: resolveLlmConfig(plugin.settings).model,
|
||||
activeNoteTemplate: plugin.settings.activeNoteTemplate,
|
||||
additionalSystemPrompt: '',
|
||||
},
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
plugin.state.sessionScribeOptions = scribeOptions;
|
||||
}, [scribeOptions, plugin]);
|
||||
|
||||
useEffect(() => {
|
||||
let timer: number | null = null;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,13 @@ function scribeDropDownMenu(plugin: ScribePlugin): Menu {
|
|||
const recordingState = plugin.getRecordingState();
|
||||
|
||||
if (showRecordingInProgressControls) {
|
||||
menu.addItem((item) => {
|
||||
item.setIcon('joystick');
|
||||
item.setTitle('Open Controls');
|
||||
item.onClick(() => {
|
||||
plugin.controlModal.open();
|
||||
});
|
||||
});
|
||||
menu.addItem((item) => {
|
||||
item.setIcon(recordingState === 'paused' ? 'play' : 'pause');
|
||||
item.setTitle(
|
||||
|
|
@ -49,7 +56,6 @@ function scribeDropDownMenu(plugin: ScribePlugin): Menu {
|
|||
item.setIcon('joystick');
|
||||
item.setTitle('Open Controls');
|
||||
item.onClick(() => {
|
||||
plugin.state.isOpen = true;
|
||||
plugin.controlModal.open();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue