import 'package:audioplayers/audioplayers.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:toastification/toastification.dart'; import '../../app/constant.dart'; import '../../app/route.dart'; import '../../provider/current_user_provider.dart'; import '../../provider/voice_to_text_provider.dart'; import '../home/list_riwayat_rekaman_provider.dart'; import 'edit_rekam_provider.dart'; class EditRekamScreen extends HookConsumerWidget { const EditRekamScreen({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { SystemChrome.setEnabledSystemUIMode( SystemUiMode.manual, overlays: [SystemUiOverlay.bottom], ); final currentUser = ref.watch(currentUserProvider); final host = currentUser?.host ?? ""; final userId = currentUser?.model.userId ?? ""; final qrCodeStr = useState(""); final editData = ref.watch(selectedEdit); final baseUrl = "https://$host/"; final player = useState(AudioPlayer()); final urlRekaman = baseUrl + editData.Voice2text_Url; final isPlaying = useState(false); final isLoading = useState(false); useEffect(() { WidgetsBinding.instance.addPostFrameCallback((timestamp) { ref.read(noteCtr.notifier).state = TextEditingController( text: editData.Voice2text_Note, ); ref.read(textCtr.notifier).state = TextEditingController( text: editData.Voice2text_Text, ); String afterVoice = editData.Voice2text_Url.split("voice-")[1]; String qrCodeExtract = afterVoice.split(".mp3")[0]; qrCodeStr.value = "Qrcode : $qrCodeExtract"; }); return () {}; }, []); void showLongToast( String title, String message, String typeToast, Duration waktu, ) { if (typeToast == "success") { toastification.show( context: context, title: Text(title), description: Text(message), autoCloseDuration: waktu, type: ToastificationType.success, style: ToastificationStyle.fillColored, ); } else if (typeToast == "error") { toastification.show( context: context, title: Text(title), description: Text(message), autoCloseDuration: waktu, type: ToastificationType.error, style: ToastificationStyle.fillColored, ); } else if (typeToast == "warning") { toastification.show( context: context, title: Text(title), description: Text(message), autoCloseDuration: waktu, type: ToastificationType.warning, style: ToastificationStyle.fillColored, ); } } Future playRekaman() async { if (urlRekaman.isNotEmpty) { try { if (isPlaying.value) { await player.value.stop(); // Jika sedang diputar, maka stop } else { await player.value.setSourceUrl(urlRekaman); await player.value.resume(); // Jika tidak diputar, mulai pemutaran } isPlaying.value = !isPlaying.value; } catch (e) { print("Error saat memutar rekaman: ${e.toString()}"); showLongToast( 'Error', "Error saat memutar rekaman: ${e.toString()}", 'error', Duration(seconds: 3), ); } } else { print("URL rekaman kosong"); showLongToast( 'Error', "URL rekaman kosong", 'error', Duration(seconds: 3), ); } } // list Riwayat Rekam ref.listen(listRiwayatRekamanProvider, (prev, next) { if (next is ListRiwayatRekamanStateLoading) { // isLoading.value = true; } else if (next is ListRiwayatRekamanStateError) { // isLoading.value = false; // errorMessage.value = next.message; showLongToast( 'Error', next.message, 'error', Duration(seconds: 3), ); } else if (next is ListRiwayatRekamanStateDone) { // isLoading.value = false; Navigator.of(context).pop(); Navigator.of(context).pushNamedAndRemoveUntil( homeRoute, (route) => false, ); } }); // proses edit ref.listen(editRekamProvider, (prev, next) { if (next is EditRekamStateLoading) { isLoading.value = true; } else if (next is EditRekamStateError) { isLoading.value = false; // errorMessage.value = next.message; showLongToast( 'Error', next.message, 'error', Duration(seconds: 3), ); } else if (next is EditRekamStateDone) { isLoading.value = false; ref.read(listRiwayatRekamanProvider.notifier).listRiwayatRekaman( host: host, userId: userId, ); } }); return GestureDetector( onTap: () { FocusManager.instance.primaryFocus!.unfocus(); }, child: Scaffold( resizeToAvoidBottomInset: true, backgroundColor: Constant.bgGrey, bottomNavigationBar: BottomAppBar( color: Colors.blueGrey.shade100, height: Constant.getActualYPhone(context: context, y: 100), shape: const CircularNotchedRectangle(), child: Row( children: [ ElevatedButton.icon( onPressed: () { Navigator.of(context).pop(); }, icon: Icon(Icons.arrow_back, size: 17, color: Constant.textWhite), label: Text( 'Kembali', style: Constant.cardText(context: context) .copyWith(color: Constant.textWhite), ), style: ElevatedButton.styleFrom( backgroundColor: Constant.textBlack, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), elevation: 8, ), ), const Spacer(), ElevatedButton( onPressed: isLoading.value ? null : () async { isLoading.value = true; ref.read(editRekamProvider.notifier).editRekam( host: host, Voice2text_ID: editData.Voice2text_ID, Voice2text_Note: ref.read(noteCtr).text, Voice2text_Text: ref.read(textCtr).text, ); }, style: ElevatedButton.styleFrom( backgroundColor: Constant.bgButton, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), elevation: 8, ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ isLoading.value ? Text( 'LOADING', style: Constant.titleButton500(context: context) .copyWith( color: Constant.textWhite, ), ) : Text( 'SAVE', style: Constant.titleButton500(context: context) .copyWith( color: Constant.textWhite, ), ), ], ), ), ], ), ), body: ListView( children: [ // atas Image.asset( 'images/vektoratas.png', width: double.infinity, fit: BoxFit.cover, ), SizedBox( height: Constant.getActualYPhone( context: context, y: 50, ), ), // qrcode Padding( padding: EdgeInsets.symmetric( horizontal: 20, ), child: Container( alignment: Alignment.center, padding: EdgeInsets.symmetric(vertical: 10), color: Constant.inputanGrey, child: Text( qrCodeStr.value, style: TextStyle(color: Colors.white), ), ), ), SizedBox( height: Constant.getActualYPhone( context: context, y: 20, ), ), // button play record Padding( padding: EdgeInsets.symmetric( horizontal: 20, ), child: SizedBox( width: double.infinity, child: ElevatedButton( onPressed: playRekaman, style: ElevatedButton.styleFrom( backgroundColor: Constant.textRed, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), elevation: 8, shadowColor: Constant.bgButton.withOpacity(0.24), ), child: Text( isPlaying.value ? 'STOP' : 'PUTAR REKAMAN', style: Constant.titleButton500(context: context).copyWith( color: Constant.textWhite, ), ), ), ), ), SizedBox( height: Constant.getActualYPhone( context: context, y: 20, ), ), // note Padding( padding: EdgeInsets.symmetric( horizontal: 20, ), child: TextField( controller: ref.read(noteCtr), maxLines: null, keyboardType: TextInputType.multiline, decoration: InputDecoration( label: Text('Note'), hintText: "Note", enabledBorder: const OutlineInputBorder( borderSide: BorderSide( color: Colors.grey, width: 1, ), ), focusedBorder: const OutlineInputBorder( borderSide: BorderSide( color: Colors.blue, width: 2, ), ), ), ), ), SizedBox( height: Constant.getActualYPhone( context: context, y: 20, ), ), // hasil transcribe Padding( padding: EdgeInsets.symmetric( horizontal: 20, ), child: TextField( controller: ref.read(textCtr), maxLines: null, keyboardType: TextInputType.multiline, decoration: InputDecoration( label: Text('Text'), hintText: "Text", enabledBorder: const OutlineInputBorder( borderSide: BorderSide( color: Colors.grey, width: 1, ), ), focusedBorder: const OutlineInputBorder( borderSide: BorderSide( color: Colors.blue, width: 2, ), ), ), ), ), ], ), ), ); } }