From d5ba0b495c232a05db8db5992b0f446c166a94e1 Mon Sep 17 00:00:00 2001 From: Matthias Nehlsen Date: Sun, 17 Nov 2024 19:15:27 +0100 Subject: [PATCH] feat: transcribe button in speech modal --- .../speech/ui/widgets/audio_player.dart | 32 --------- .../ui/widgets/speech_modal/speech_modal.dart | 3 + .../speech_modal/transcribe_button.dart | 66 +++++++++++++++++++ lib/l10n/app_en.arb | 1 + 4 files changed, 70 insertions(+), 32 deletions(-) create mode 100644 lib/features/speech/ui/widgets/speech_modal/transcribe_button.dart diff --git a/lib/features/speech/ui/widgets/audio_player.dart b/lib/features/speech/ui/widgets/audio_player.dart index 1a8a7c163..0114b4083 100644 --- a/lib/features/speech/ui/widgets/audio_player.dart +++ b/lib/features/speech/ui/widgets/audio_player.dart @@ -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 { @@ -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( builder: (BuildContext context, AudioPlayerState state) { final isActive = state.audioNote?.meta.id == journalAudio.meta.id; @@ -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().enqueue(entry: journalAudio); - - if (await isQueueEmpty) { - if (!context.mounted) return; - await TranscriptionProgressModal.show(context); - } - - await Future.delayed( - const Duration(milliseconds: 100), - ); - notifier - ..setController() - ..emitState(); - }, - ), ], ), Row( diff --git a/lib/features/speech/ui/widgets/speech_modal/speech_modal.dart b/lib/features/speech/ui/widgets/speech_modal/speech_modal.dart index 7f7fde6e6..59b00ff63 100644 --- a/lib/features/speech/ui/widgets/speech_modal/speech_modal.dart +++ b/lib/features/speech/ui/widgets/speech_modal/speech_modal.dart @@ -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'; @@ -32,6 +33,8 @@ class SpeechModal { ), child: Column( children: [ + const SizedBox(height: 20), + TranscribeButton(entryId: entryId), TranscriptsList(entryId: entryId), ], ), diff --git a/lib/features/speech/ui/widgets/speech_modal/transcribe_button.dart b/lib/features/speech/ui/widgets/speech_modal/transcribe_button.dart new file mode 100644 index 000000000..cddc123fe --- /dev/null +++ b/lib/features/speech/ui/widgets/speech_modal/transcribe_button.dart @@ -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().enqueue(entry: item); + + if (await isQueueEmpty) { + if (!context.mounted) return; + await TranscriptionProgressModal.show(context); + } + + await Future.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), + ], + ), + ), + ); + } +} diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 7c1cb7de1..c10ad1747 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -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.",