11 changed files with 280 additions and 2 deletions
@ -0,0 +1,22 @@ |
|||||
|
// 与 proto 中 TranscribeService 枚举保持一致 |
||||
|
enum TranscribeService { |
||||
|
unknown(0, 'Unknown'), |
||||
|
byteDance(1, 'ByteDance'), |
||||
|
ali(2, 'Ali'), |
||||
|
auto(3, 'Auto'), |
||||
|
google(4, 'Google'), |
||||
|
microsoft(5, 'Microsoft'); |
||||
|
|
||||
|
const TranscribeService(this.value, this.code); |
||||
|
|
||||
|
final int value; |
||||
|
// 与后台 / env 字段(MeetServers)中保持一致的字符串编码 |
||||
|
final String code; |
||||
|
|
||||
|
static TranscribeService fromCode(String code) { |
||||
|
for (final s in TranscribeService.values) { |
||||
|
if (s.code.toLowerCase() == code.trim().toLowerCase()) return s; |
||||
|
} |
||||
|
return TranscribeService.auto; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,173 @@ |
|||||
|
import 'package:flutter/material.dart'; |
||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
||||
|
import 'package:get/get.dart'; |
||||
|
|
||||
|
import '../../../../data/models/appconfig.dart'; |
||||
|
import '../../model/transcribe_service.dart'; |
||||
|
|
||||
|
class TranscribeServiceBottomSheet extends StatefulWidget { |
||||
|
final TranscribeService selected; |
||||
|
|
||||
|
const TranscribeServiceBottomSheet(this.selected, {super.key}); |
||||
|
|
||||
|
@override |
||||
|
State<TranscribeServiceBottomSheet> createState() => |
||||
|
_TranscribeServiceBottomSheetState(); |
||||
|
|
||||
|
// 读取 env 中 MeetServers 字段并解析为可选服务列表(首项始终为 Auto)。 |
||||
|
// env 形如:"ByteDance,Ali,Google,Microsoft" |
||||
|
static List<TranscribeService> resolveOptions() { |
||||
|
final raw = AppConfig.isInitialized() |
||||
|
? (AppConfig.env('MeetServers') ?? '') |
||||
|
: ''; |
||||
|
const whitelist = { |
||||
|
TranscribeService.byteDance, |
||||
|
TranscribeService.ali, |
||||
|
TranscribeService.google, |
||||
|
TranscribeService.microsoft, |
||||
|
}; |
||||
|
final result = <TranscribeService>[TranscribeService.auto]; |
||||
|
for (final part in raw.split(',')) { |
||||
|
final s = TranscribeService.fromCode(part); |
||||
|
if (whitelist.contains(s) && !result.contains(s)) result.add(s); |
||||
|
} |
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
class _TranscribeServiceBottomSheetState |
||||
|
extends State<TranscribeServiceBottomSheet> { |
||||
|
late final List<TranscribeService> _options; |
||||
|
|
||||
|
@override |
||||
|
void initState() { |
||||
|
super.initState(); |
||||
|
_options = TranscribeServiceBottomSheet.resolveOptions(); |
||||
|
} |
||||
|
|
||||
|
String _label(TranscribeService s) { |
||||
|
switch (s) { |
||||
|
case TranscribeService.auto: |
||||
|
return 'transcribeServiceAuto'.tr; // 对应中文:自动 |
||||
|
case TranscribeService.byteDance: |
||||
|
return 'transcribeServiceByteDance'.tr; // 对应中文:字节跳动 |
||||
|
case TranscribeService.ali: |
||||
|
return 'transcribeServiceAli'.tr; // 对应中文:阿里云 |
||||
|
case TranscribeService.google: |
||||
|
return 'transcribeServiceGoogle'.tr; // 对应中文:谷歌 |
||||
|
case TranscribeService.microsoft: |
||||
|
return 'transcribeServiceMicrosoft'.tr; // 对应中文:微软 |
||||
|
case TranscribeService.unknown: |
||||
|
return s.code; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@override |
||||
|
Widget build(BuildContext context) { |
||||
|
final isDarkMode = Theme.of(context).brightness == Brightness.dark; |
||||
|
return SafeArea( |
||||
|
top: false, |
||||
|
child: Padding( |
||||
|
padding: EdgeInsets.symmetric(horizontal: 12.w), |
||||
|
child: Column( |
||||
|
mainAxisSize: MainAxisSize.min, |
||||
|
children: [ |
||||
|
Container( |
||||
|
padding: EdgeInsets.symmetric(vertical: 10.w), |
||||
|
child: Row( |
||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
||||
|
children: [ |
||||
|
Text( |
||||
|
'transcribeService'.tr, // 对应中文:转写服务 |
||||
|
style: TextStyle( |
||||
|
fontSize: 16.sp, |
||||
|
color: isDarkMode ? Colors.white : Colors.black87, |
||||
|
fontWeight: FontWeight.bold, |
||||
|
), |
||||
|
), |
||||
|
GestureDetector( |
||||
|
onTap: () => Get.back(), |
||||
|
child: Container( |
||||
|
width: 26.w, |
||||
|
height: 26.w, |
||||
|
decoration: BoxDecoration( |
||||
|
color: isDarkMode ? Colors.grey[700] : Colors.white, |
||||
|
borderRadius: BorderRadius.circular(26.r), |
||||
|
), |
||||
|
child: Icon( |
||||
|
Icons.close, |
||||
|
size: 18.w, |
||||
|
color: isDarkMode ? Colors.grey[300] : Colors.grey[400], |
||||
|
), |
||||
|
), |
||||
|
) |
||||
|
], |
||||
|
), |
||||
|
), |
||||
|
Divider( |
||||
|
height: 1, |
||||
|
color: isDarkMode ? Colors.grey[700] : Colors.grey[300], |
||||
|
), |
||||
|
Container( |
||||
|
margin: EdgeInsets.symmetric(vertical: 20.w), |
||||
|
constraints: BoxConstraints( |
||||
|
maxHeight: 1.sh - 180.w, |
||||
|
), |
||||
|
decoration: BoxDecoration( |
||||
|
color: isDarkMode ? const Color(0xFF2D2D2D) : Colors.white, |
||||
|
borderRadius: BorderRadius.circular(8.r), |
||||
|
), |
||||
|
child: ListView.builder( |
||||
|
itemCount: _options.length, |
||||
|
shrinkWrap: true, |
||||
|
itemBuilder: (BuildContext context, int index) { |
||||
|
return _item(index, _options[index], isDarkMode); |
||||
|
}, |
||||
|
), |
||||
|
), |
||||
|
], |
||||
|
), |
||||
|
), |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
Widget _item(int index, TranscribeService data, bool isDarkMode) { |
||||
|
return GestureDetector( |
||||
|
onTap: () => Get.back(result: data), |
||||
|
child: Padding( |
||||
|
padding: EdgeInsets.only(left: 15.w), |
||||
|
child: Container( |
||||
|
height: 46.w, |
||||
|
padding: EdgeInsets.only(right: 10.w), |
||||
|
decoration: BoxDecoration( |
||||
|
border: index != 0 |
||||
|
? Border( |
||||
|
top: BorderSide( |
||||
|
color: isDarkMode ? Colors.grey[700]! : Colors.grey[300]!, |
||||
|
), |
||||
|
) |
||||
|
: null, |
||||
|
), |
||||
|
child: Row( |
||||
|
children: [ |
||||
|
Expanded( |
||||
|
child: Text( |
||||
|
_label(data), |
||||
|
style: TextStyle( |
||||
|
fontSize: 14.sp, |
||||
|
color: isDarkMode ? Colors.white : Colors.black87, |
||||
|
), |
||||
|
), |
||||
|
), |
||||
|
if (widget.selected == data) |
||||
|
Icon( |
||||
|
Icons.check, |
||||
|
color: isDarkMode ? Colors.white : Colors.black87, |
||||
|
), |
||||
|
], |
||||
|
), |
||||
|
), |
||||
|
), |
||||
|
); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue