import 'dart:io'; import 'package:electronic_assistant/base/base_controller.dart'; import 'package:electronic_assistant/data/bean/talks.dart'; import 'package:electronic_assistant/data/repositories/agenda_repository.dart'; import 'package:electronic_assistant/data/repositories/config_repository.dart'; import 'package:electronic_assistant/data/repositories/talk_repository.dart'; import 'package:electronic_assistant/module/main/controller.dart'; import 'package:electronic_assistant/module/talk/view.dart'; import 'package:electronic_assistant/resource/string.gen.dart'; import 'package:electronic_assistant/router/app_pages.dart'; import 'package:electronic_assistant/utils/event_bus.dart'; import 'package:electronic_assistant/widget/pull_to_refresh.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/cupertino.dart'; import 'package:get/get.dart'; import 'package:just_audio/just_audio.dart'; import 'package:uuid/uuid.dart'; import '../../data/api/response/example_info_response.dart'; import '../../data/bean/agenda.dart'; import '../../data/repositories/account_repository.dart'; import '../../dialog/loading_dialog.dart'; import '../../utils/error_handler.dart'; import '../../utils/toast_util.dart'; import 'package:path_provider/path_provider.dart'; class HomePageController extends BaseController { get isLogin => accountRepository.isLogin.value; get loginTxt => accountRepository.isLogin.value ? accountRepository.getUserSubName(accountRepository.phone) : StringName.homeGoLogin.tr; final refreshController = PullToRefreshController(); BuildContext? todoTargetContext; RxList get talkList => talkRepository.talkList; RxList get agendaList => agendaRepository.agendaList; @override void onReady() { super.onReady(); refreshController.requestRefresh(); eventBus.on(EventUserLogin, (arg) { requestHomeData(); }); eventBus.on(EventUserLogout, (arg) { talkRepository.setTalkList([]); agendaRepository.setAgendaList([]); requestHomeData(); }); } @override void dispose() { // TODO: implement dispose super.dispose(); eventBus.off(EventUserLogin); eventBus.off(EventUserLogout); } void requestHomeData() async { try { if (accountRepository.isLogin.value) { await Future.wait([ talkRepository.refreshHomeTalkData(), agendaRepository.requestHomeAgendaData(), ]); } else { ExampleInfoResponse exampleInfo = await configRepository.getExampleInfo(); talkRepository.setTalkList( exampleInfo.talkInfoList != null ? exampleInfo.talkInfoList! : []); agendaRepository.setAgendaList( exampleInfo.agendaList != null ? exampleInfo.agendaList! : []); } } catch (e) { refreshController.refreshCompleted(); // Handle errors if necessary } finally { refreshController.refreshCompleted(); } } void requestName(String? newName, TalkBean bean) { talkRepository.talkRename(bean.id, newName).then((data) { bean.title.value = newName; ToastUtil.showToast(StringName.talkRenameSuccess.tr); }).catchError((error) { ErrorHandler.toastError(error, message: StringName.talkRenameFail.tr); }); } void goTalkRecordPage() { Get.find().updateIndexByPageName(StringName.mainTabFile); } void showLoginDrawer() { Get.find().openDrawer(); } void requestDelete(TalkBean item) { talkRepository.talkDelete(item.id).then((data) { requestHomeData(); }).catchError((error) { ErrorHandler.toastError(error, message: StringName.talkDeleteFail.tr); }); } void agendaComplete(Agenda item) { agendaRepository.agendaFinish(item.id, true).then((data) { agendaRepository.removeItem(item); }).catchError((error) { ErrorHandler.toastError(error); }); } void onPickerAudioFile() async { if (!accountRepository.isLogin.value) { Get.toNamed(RoutePath.login); ToastUtil.showToast(StringName.errorCodeNoLogin.tr); return; } FilePickerResult? result = await FilePicker.platform .pickFiles(type: FileType.custom, allowedExtensions: [ 'wav', 'mp3', 'm4a', 'flv', 'mp4', 'wma', '3gp', 'amr', 'aac', 'ogg-opus', 'flac' ]); if (result != null) { LoadingDialog.show(StringName.fileImporting.tr); AudioPlayer? player; try { String filePath = result.files.single.path!; File file = File(filePath); //文件不能超过500M if (file.lengthSync() > 500 * 1024 * 1024) { ToastUtil.showToast(StringName.fileChoiceSizeLimit.tr); return; } player = AudioPlayer(); player.setAudioSource(AudioSource.uri(file.uri)); Duration? duration = await player.durationStream .firstWhere((duration) => duration != null); if (duration == null) { ToastUtil.showToast(StringName.fileAudioDurationCannotObtained.tr); return; } //录音时长不能超过5小时 if (duration.inHours > 5) { ToastUtil.showToast(StringName.fileAudioDurationLimit.tr); return; } late TalkBean bean; try { bean = await talkRepository.talkCreate( const Uuid().v4(), duration.inSeconds, localAudioUrl: filePath, uploadType: 1); } catch (e) { ErrorHandler.toastError(e); return; } String childDirName = bean.id; Directory dir = await _getChoiceUploadDir(childDirName); await moveFileToDirectory(file, dir); TalkPage.start(bean); } catch (e) { ErrorHandler.toastError(e, message: StringName.fileImportFail.tr); } finally { player?.dispose(); LoadingDialog.hide(); } } } Future moveFileToDirectory(File file, Directory dir) async { if (!dir.existsSync()) { dir.createSync(recursive: true); } String newFilePath = '${dir.path}/${file.uri.pathSegments.last}'; file.renameSync(newFilePath); } } Future _getChoiceUploadDir(String talkId) async { Directory documentDir = await getApplicationDocumentsDirectory(); return Directory("${documentDir.path}/.atmob/choice/$talkId"); } Future getChoiceUploadFile(String talkId) async { Directory dir = await _getChoiceUploadDir(talkId); if (!dir.existsSync()) { return null; } List list = dir.listSync(); if (list.isEmpty) { return null; } return list.first as File; }