@@ -116,19 +116,14 @@ export class TranscriptionService {
116
116
*/
117
117
cancelTranscription ( ) : void {
118
118
if ( ! this . isTranscribing ) {
119
- new Notice ( "No transcription is currently in progress." ) ;
120
119
return ;
121
120
}
122
121
123
122
this . cancelRequested = true ;
124
123
this . processingStatus = "Cancelling..." ;
125
124
126
- if ( this . activeNotice ) {
127
- this . activeNotice . update ( "Cancelling transcription. Please wait..." ) ;
128
- }
129
-
130
125
// The cancellation will be handled in the transcription process
131
- new Notice ( "Transcription cancellation requested. This may take a moment..." ) ;
126
+ // No notifications, everything will be shown in the UI
132
127
}
133
128
134
129
/**
@@ -223,7 +218,10 @@ export class TranscriptionService {
223
218
// Get current episode first
224
219
const currentEpisode = this . plugin . api . podcast ;
225
220
if ( ! currentEpisode ) {
226
- new Notice ( "No episode is currently playing." ) ;
221
+ this . processingStatus = "Error: No episode is playing" ;
222
+ setTimeout ( ( ) => {
223
+ this . isTranscribing = false ;
224
+ } , 2000 ) ;
227
225
return ;
228
226
}
229
227
@@ -242,7 +240,10 @@ export class TranscriptionService {
242
240
// Validate API key
243
241
if ( ! this . initializeClient ( ) ) {
244
242
// Reset state if validation fails
245
- this . isTranscribing = false ;
243
+ this . processingStatus = "Error: Invalid API key" ;
244
+ setTimeout ( ( ) => {
245
+ this . isTranscribing = false ;
246
+ } , 2000 ) ;
246
247
return ;
247
248
}
248
249
@@ -254,24 +255,24 @@ export class TranscriptionService {
254
255
) ;
255
256
const existingFile = this . plugin . app . vault . getAbstractFileByPath ( transcriptPath ) ;
256
257
if ( existingFile instanceof TFile ) {
257
- new Notice ( `You've already transcribed this episode - found ${ transcriptPath } .` ) ;
258
- this . isTranscribing = false ;
258
+ this . processingStatus = `Already transcribed: ${ transcriptPath } ` ;
259
+ setTimeout ( ( ) => {
260
+ this . isTranscribing = false ;
261
+ } , 2000 ) ;
259
262
return ;
260
263
}
261
264
}
262
265
263
266
// Reset cancellation flag
264
267
this . cancelRequested = false ;
265
-
266
- // Create a notice for traditional display (we'll also show in the UI)
267
- const notice = TimerNotice ( "Transcription" , "Preparing to transcribe..." ) ;
268
- this . activeNotice = notice ;
269
268
270
269
try {
271
270
// Use setTimeout to allow UI to update before heavy processing starts
272
271
await new Promise ( resolve => setTimeout ( resolve , 50 ) ) ;
273
272
274
- notice . update ( "Downloading episode..." ) ;
273
+ // Update UI status
274
+ this . processingStatus = "Downloading episode..." ;
275
+
275
276
const downloadPath = await downloadEpisode (
276
277
currentEpisode ,
277
278
this . plugin . settings . download . path ,
@@ -290,7 +291,9 @@ export class TranscriptionService {
290
291
const formattedSize = this . formatFileSize ( fileSize ) ;
291
292
const estimatedTime = this . estimateTranscriptionTime ( fileSize ) ;
292
293
293
- notice . update ( `Preparing audio (${ formattedSize } ) for transcription...\nEstimated time: ${ estimatedTime } ` ) ;
294
+ // Update UI status
295
+ this . processingStatus = `Preparing audio (${ formattedSize } )...` ;
296
+ this . timeRemaining = `Estimated time: ${ estimatedTime } ` ;
294
297
this . progressSize = formattedSize ;
295
298
296
299
// Read the audio file in chunks to reduce memory pressure
@@ -310,70 +313,53 @@ export class TranscriptionService {
310
313
// @ts -ignore - using a workaround to help release memory
311
314
const tempFileBuffer = null ;
312
315
313
- notice . update ( `Starting transcription of ${ formattedSize } audio...\nEstimated time: ${ estimatedTime } \n\nYou can cancel using the "Cancel Transcription" button below the player or via command palette.` ) ;
316
+ // Update UI status
317
+ this . processingStatus = `Starting transcription (${ formattedSize } )...` ;
314
318
315
- // Create commands for consistent control
319
+ // Create command for cancellation via command palette
316
320
this . plugin . addCommand ( {
317
321
id : 'cancel-transcription' ,
318
322
name : 'Cancel Current Transcription' ,
319
323
callback : ( ) => this . cancelTranscription ( )
320
324
} ) ;
321
325
322
- // Create a notice with a cancel button for better visibility
323
- const cancelNotice = new Notice (
324
- "Transcription in progress. Click to cancel." ,
325
- 0 , // Duration 0 = until manually closed
326
- [ {
327
- text : "Cancel" ,
328
- onClick : ( ) => {
329
- this . cancelTranscription ( ) ;
330
- cancelNotice . hide ( ) ;
331
- }
332
- } ]
333
- ) ;
326
+ // Create a no-op update function since we're not using notices anymore
327
+ const updateStatus = ( message : string ) => {
328
+ // We're not doing anything with this message since we update UI directly
329
+ } ;
334
330
335
331
// Process transcription with concurrent chunks
336
332
const transcription = await this . transcribeChunks (
337
333
files ,
338
- notice . update ,
334
+ updateStatus ,
339
335
currentEpisode . id ,
340
336
fileSize ,
341
337
resume ? this . resumeData : null
342
338
) ;
343
339
344
340
// If cancelled, stop here
345
341
if ( this . cancelRequested ) {
346
- notice . update ( "Transcription cancelled by user." ) ;
347
- notice . stop ( ) ;
342
+ this . processingStatus = "Transcription cancelled" ;
343
+
344
+ // Keep the UI visible for a moment before removing
345
+ setTimeout ( ( ) => {
346
+ this . isTranscribing = false ;
347
+ } , 2000 ) ;
348
348
return ;
349
349
}
350
350
351
351
// Schedule processing in the next event loop iteration to avoid UI blocking
352
352
await new Promise ( resolve => setTimeout ( resolve , 50 ) ) ;
353
353
354
- notice . update ( "Processing timestamps..." ) ;
354
+ // Update UI status
355
355
this . processingStatus = "Formatting timestamps..." ;
356
356
const formattedTranscription = await this . formatTranscriptionWithTimestamps ( transcription ) ;
357
357
358
- notice . update ( "Saving transcription..." ) ;
358
+ // Update UI status
359
359
this . processingStatus = "Saving..." ;
360
- await this . saveTranscription ( currentEpisode , formattedTranscription ) ;
361
-
362
- // Clean up notices
363
- try {
364
- this . plugin . app . workspace . iterateAllLeaves ( leaf => {
365
- const notices = document . querySelectorAll ( '.notice' ) ;
366
- notices . forEach ( noticeEl => {
367
- if ( noticeEl . textContent . includes ( 'Transcription in progress' ) ) {
368
- noticeEl . querySelector ( 'button' ) ?. click ( ) ;
369
- }
370
- } ) ;
371
- } ) ;
372
- } catch ( e ) {
373
- console . log ( "Error cleaning up notices:" , e ) ;
374
- }
360
+ const transcriptPath = await this . saveTranscription ( currentEpisode , formattedTranscription ) ;
375
361
376
- // Remove the cancel command
362
+ // Remove command for cancellation
377
363
try {
378
364
this . plugin . app . commands . removeCommand ( `${ this . plugin . manifest . id } :cancel-transcription` ) ;
379
365
} catch ( e ) {
@@ -383,29 +369,32 @@ export class TranscriptionService {
383
369
// Clear resume data since we've completed successfully
384
370
this . clearResumeState ( ) ;
385
371
386
- notice . stop ( ) ;
387
- notice . update ( "Transcription completed and saved successfully." ) ;
372
+ // Show completion status in the UI
373
+ this . processingStatus = `Saved: ${ transcriptPath } ` ;
374
+ this . progressPercent = 100 ;
375
+
376
+ // Keep the UI visible for a moment before removing
377
+ setTimeout ( ( ) => {
378
+ this . isTranscribing = false ;
379
+ } , 2000 ) ;
388
380
389
- // Show a success notice with a link to the file
390
- new Notice (
391
- `Transcription complete!\nFile saved to: ${ transcriptPath } ` ,
392
- 10000 // Show for 10 seconds
393
- ) ;
394
381
} catch ( error ) {
395
382
console . error ( "Transcription error:" , error ) ;
396
- notice . update ( `Transcription failed: ${ error . message } ` ) ;
397
- new Notice ( `Transcription failed: ${ error . message } ` , 5000 ) ;
398
- } finally {
399
- this . isTranscribing = false ;
400
- this . activeNotice = null ;
401
383
384
+ // Show error in UI
385
+ this . processingStatus = `Error: ${ error . message } ` ;
386
+
387
+ // Keep the error visible for a moment before removing
388
+ setTimeout ( ( ) => {
389
+ this . isTranscribing = false ;
390
+ } , 3000 ) ;
391
+ } finally {
392
+ // Remove the command in case it wasn't removed earlier
402
393
try {
403
394
this . plugin . app . commands . removeCommand ( `${ this . plugin . manifest . id } :cancel-transcription` ) ;
404
395
} catch ( e ) {
405
396
// Command may have already been removed, ignore
406
397
}
407
-
408
- setTimeout ( ( ) => notice . hide ( ) , 5000 ) ;
409
398
}
410
399
}
411
400
@@ -917,7 +906,7 @@ export class TranscriptionService {
917
906
private async saveTranscription (
918
907
episode : Episode ,
919
908
transcription : string ,
920
- ) : Promise < void > {
909
+ ) : Promise < string > {
921
910
const transcriptPath = FilePathTemplateEngine (
922
911
this . plugin . settings . transcript . path ,
923
912
episode ,
@@ -945,6 +934,7 @@ export class TranscriptionService {
945
934
if ( ! file ) {
946
935
const newFile = await vault . create ( transcriptPath , transcriptContent ) ;
947
936
await this . plugin . app . workspace . getLeaf ( ) . openFile ( newFile ) ;
937
+ return transcriptPath ;
948
938
} else {
949
939
throw new Error ( "Expected a file but got a folder" ) ;
950
940
}
0 commit comments