Skip to content

Commit

Permalink
feat: transcribe button in speech modal
Browse files Browse the repository at this point in the history
  • Loading branch information
matthiasn committed Nov 17, 2024
1 parent 86464ea commit d5ba0b4
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 32 deletions.
32 changes: 0 additions & 32 deletions lib/features/speech/ui/widgets/audio_player.dart
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
import 'dart:io';

import 'package:audio_video_progress_bar/audio_video_progress_bar.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:lotti/classes/journal_entities.dart';
import 'package:lotti/features/journal/state/entry_controller.dart';
import 'package:lotti/features/speech/state/asr_service.dart';
import 'package:lotti/features/speech/state/player_cubit.dart';
import 'package:lotti/features/speech/state/player_state.dart';
import 'package:lotti/features/speech/ui/widgets/transcription_progress_modal.dart';
import 'package:lotti/get_it.dart';
import 'package:lotti/themes/theme.dart';

class AudioPlayerWidget extends ConsumerWidget {
Expand Down Expand Up @@ -40,9 +34,6 @@ class AudioPlayerWidget extends ConsumerWidget {
2: '2x',
};

final provider = entryControllerProvider(id: journalAudio.meta.id);
final notifier = ref.read(provider.notifier);

return BlocBuilder<AudioPlayerCubit, AudioPlayerState>(
builder: (BuildContext context, AudioPlayerState state) {
final isActive = state.audioNote?.meta.id == journalAudio.meta.id;
Expand Down Expand Up @@ -100,29 +91,6 @@ class AudioPlayerWidget extends ConsumerWidget {
],
),
),
if (Platform.isMacOS || Platform.isIOS)
IconButton(
icon: const Icon(Icons.transcribe_rounded),
iconSize: 20,
tooltip: 'Transcribe',
color: context.colorScheme.outline,
onPressed: () async {
final isQueueEmpty =
getIt<AsrService>().enqueue(entry: journalAudio);

if (await isQueueEmpty) {
if (!context.mounted) return;
await TranscriptionProgressModal.show(context);
}

await Future<void>.delayed(
const Duration(milliseconds: 100),
);
notifier
..setController()
..emitState();
},
),
],
),
Row(
Expand Down
3 changes: 3 additions & 0 deletions lib/features/speech/ui/widgets/speech_modal/speech_modal.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:lotti/classes/journal_entities.dart';
import 'package:lotti/features/journal/state/entry_controller.dart';
import 'package:lotti/features/speech/ui/widgets/speech_modal/transcribe_button.dart';
import 'package:lotti/features/speech/ui/widgets/speech_modal/transcripts_list.dart';
import 'package:lotti/l10n/app_localizations_context.dart';
import 'package:lotti/themes/theme.dart';
Expand Down Expand Up @@ -32,6 +33,8 @@ class SpeechModal {
),
child: Column(
children: [
const SizedBox(height: 20),
TranscribeButton(entryId: entryId),
TranscriptsList(entryId: entryId),
],
),
Expand Down
66 changes: 66 additions & 0 deletions lib/features/speech/ui/widgets/speech_modal/transcribe_button.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:lotti/classes/journal_entities.dart';
import 'package:lotti/features/journal/state/entry_controller.dart';
import 'package:lotti/features/speech/state/asr_service.dart';
import 'package:lotti/features/speech/ui/widgets/transcription_progress_modal.dart';
import 'package:lotti/get_it.dart';
import 'package:lotti/l10n/app_localizations_context.dart';

class TranscribeButton extends ConsumerWidget {
const TranscribeButton({
required this.entryId,
super.key,
});

final String entryId;

@override
Widget build(BuildContext context, WidgetRef ref) {
if (!(Platform.isMacOS || Platform.isIOS)) {
return const SizedBox.shrink();
}

final provider = entryControllerProvider(id: entryId);

final notifier = ref.read(provider.notifier);

final entryState = ref.watch(provider).value;

final item = entryState?.entry;
if (item == null || item is! JournalAudio) {
return const SizedBox.shrink();
}

return TextButton(
onPressed: () async {
final isQueueEmpty = getIt<AsrService>().enqueue(entry: item);

if (await isQueueEmpty) {
if (!context.mounted) return;
await TranscriptionProgressModal.show(context);
}

await Future<void>.delayed(
const Duration(milliseconds: 100),
);
notifier
..setController()
..emitState();
},
child: Padding(
padding: const EdgeInsets.all(10),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.transcribe_rounded),
const SizedBox(width: 10),
Text(context.messages.speechModalAddTranscription),
],
),
),
);
}
}
1 change: 1 addition & 0 deletions lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@
"settingThemingDark": "Dark Theme",
"settingThemingLight": "Light Theme",
"speechModalTitle": "Manage Speech Recognition",
"speechModalAddTranscription": "Add Transcription",
"syncAssistantHeadline": "Sync Assistant",
"syncAssistantPage1": "Let's get the synchronization between Lotti on Desktop and Lotti on your mobile device set up, shall we? You need to start on the desktop side.",
"syncAssistantPage2": "The communication between happens without you having to give your data away to cloud-based services. Instead, you provide your own email account and each device in the communication stores encrypted messages for your other devices in an IMAP folder. Please provide your server settings on the next page.",
Expand Down

0 comments on commit d5ba0b4

Please sign in to comment.