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