2024-11-05 22:55:00 +08:00
|
|
|
import 'package:fluent_ui/fluent_ui.dart';
|
|
|
|
import 'package:flutter/services.dart';
|
|
|
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
|
|
|
import 'package:go_router/go_router.dart';
|
|
|
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
|
|
import 'package:starcitizen_doctor/ui/home/input_method/input_method_dialog_ui_model.dart';
|
2024-11-07 00:34:11 +08:00
|
|
|
import 'package:starcitizen_doctor/ui/home/input_method/server.dart';
|
2024-11-05 22:55:00 +08:00
|
|
|
import 'package:starcitizen_doctor/widgets/widgets.dart';
|
2024-11-07 21:33:30 +08:00
|
|
|
import 'package:url_launcher/url_launcher_string.dart';
|
2024-11-05 22:55:00 +08:00
|
|
|
|
2024-11-07 00:34:11 +08:00
|
|
|
import 'server_qr_dialog_ui.dart';
|
|
|
|
|
2024-11-05 22:55:00 +08:00
|
|
|
class InputMethodDialogUI extends HookConsumerWidget {
|
|
|
|
const InputMethodDialogUI({super.key});
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
|
|
final state = ref.watch(inputMethodDialogUIModelProvider);
|
|
|
|
final model = ref.read(inputMethodDialogUIModelProvider.notifier);
|
2024-11-07 00:34:11 +08:00
|
|
|
final serverState = ref.watch(inputMethodServerProvider);
|
|
|
|
final serverModel = ref.read(inputMethodServerProvider.notifier);
|
2024-11-05 22:55:00 +08:00
|
|
|
final srcTextCtrl = useTextEditingController();
|
|
|
|
final destTextCtrl = useTextEditingController();
|
|
|
|
|
2024-11-07 00:34:11 +08:00
|
|
|
useEffect(() {
|
|
|
|
model.setUpController(srcTextCtrl, destTextCtrl);
|
|
|
|
return null;
|
|
|
|
}, const []);
|
|
|
|
|
2024-11-05 22:55:00 +08:00
|
|
|
return ContentDialog(
|
|
|
|
constraints: BoxConstraints(
|
|
|
|
maxWidth: MediaQuery.of(context).size.width * .8,
|
|
|
|
),
|
|
|
|
title: makeTitle(context, state, model, destTextCtrl),
|
|
|
|
content: state.keyMaps == null
|
|
|
|
? makeLoading(context)
|
|
|
|
: Column(
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
children: [
|
|
|
|
SizedBox(height: 12),
|
|
|
|
InfoBar(
|
2024-11-07 21:33:30 +08:00
|
|
|
title: Text(S.current.input_method_usage_instructions),
|
|
|
|
content: Text(S.current.input_method_input_text_instructions),
|
2024-11-05 22:55:00 +08:00
|
|
|
),
|
2024-11-07 21:33:30 +08:00
|
|
|
SizedBox(height: 12),
|
|
|
|
Row(
|
|
|
|
mainAxisAlignment: MainAxisAlignment.end,
|
|
|
|
children: [
|
|
|
|
GestureDetector(
|
|
|
|
child: Padding(
|
|
|
|
padding: const EdgeInsets.all(3),
|
|
|
|
child: Text(
|
|
|
|
S.current.input_method_online_version_prompt,
|
|
|
|
style: TextStyle(
|
|
|
|
color: Color(0xff4ca0e0),
|
|
|
|
fontSize: 12,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
onTap: () {
|
|
|
|
launchUrlString("https://ime.citizenwiki.cn/");
|
|
|
|
}),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
SizedBox(height: 12),
|
2024-11-05 22:55:00 +08:00
|
|
|
TextFormBox(
|
2024-11-07 21:33:30 +08:00
|
|
|
placeholder: S.current.input_method_input_placeholder,
|
2024-11-05 22:55:00 +08:00
|
|
|
controller: srcTextCtrl,
|
|
|
|
maxLines: 5,
|
|
|
|
placeholderStyle:
|
|
|
|
TextStyle(color: Colors.white.withOpacity(.6)),
|
|
|
|
style: TextStyle(fontSize: 16, color: Colors.white),
|
2024-11-23 21:51:36 +08:00
|
|
|
onChanged: (str) async {
|
2024-11-05 22:55:00 +08:00
|
|
|
final text = model.onTextChange("src", str);
|
2024-11-23 21:51:36 +08:00
|
|
|
destTextCtrl.text = text ?? "";
|
2024-11-05 22:55:00 +08:00
|
|
|
if (text != null) {
|
2024-11-23 21:51:36 +08:00
|
|
|
model.checkAutoTranslate();
|
2024-11-05 22:55:00 +08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
),
|
|
|
|
SizedBox(height: 16),
|
|
|
|
Center(
|
2024-11-23 21:51:36 +08:00
|
|
|
child: Row(
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
children: [
|
|
|
|
if (state.isAutoTranslateWorking)
|
|
|
|
SizedBox(width: 24, height: 24, child: ProgressRing())
|
|
|
|
else
|
|
|
|
SizedBox(
|
|
|
|
width: 24,
|
|
|
|
height: 24,
|
|
|
|
child: Icon(FluentIcons.down))
|
|
|
|
],
|
|
|
|
),
|
2024-11-05 22:55:00 +08:00
|
|
|
),
|
|
|
|
SizedBox(height: 16),
|
|
|
|
TextFormBox(
|
2024-11-07 21:33:30 +08:00
|
|
|
placeholder: S.current.input_method_encoded_text_placeholder,
|
2024-11-05 22:55:00 +08:00
|
|
|
controller: destTextCtrl,
|
|
|
|
maxLines: 5,
|
|
|
|
placeholderStyle:
|
|
|
|
TextStyle(color: Colors.white.withOpacity(.6)),
|
|
|
|
style: TextStyle(fontSize: 16, color: Colors.white),
|
|
|
|
enabled: true,
|
|
|
|
onChanged: (str) {
|
|
|
|
// final text = model.onTextChange("dest", str);
|
|
|
|
// if (text != null) {
|
|
|
|
// srcTextCtrl.text = text;
|
|
|
|
// }
|
|
|
|
},
|
|
|
|
),
|
2024-11-07 00:34:11 +08:00
|
|
|
SizedBox(height: 24),
|
|
|
|
Row(
|
|
|
|
mainAxisAlignment: MainAxisAlignment.end,
|
|
|
|
children: [
|
2024-11-23 21:51:36 +08:00
|
|
|
Row(
|
|
|
|
children: [
|
|
|
|
Text(S.current.input_method_auto_translate),
|
|
|
|
SizedBox(width: 6),
|
|
|
|
ToggleSwitch(
|
|
|
|
checked: state.isEnableAutoTranslate,
|
|
|
|
onChanged: (b) =>
|
|
|
|
_onSwitchAutoTranslate(context, model, b),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
SizedBox(width: 24),
|
2024-11-07 21:33:30 +08:00
|
|
|
Row(
|
|
|
|
children: [
|
|
|
|
Text(S.current.input_method_remote_input_service),
|
|
|
|
SizedBox(width: 6),
|
|
|
|
if (serverState.isServerStartup)
|
|
|
|
Button(
|
|
|
|
onPressed: () {
|
|
|
|
showDialog(
|
|
|
|
context: context,
|
|
|
|
builder: (BuildContext context) =>
|
|
|
|
ServerQrDialogUI(),
|
|
|
|
);
|
|
|
|
},
|
|
|
|
child: Text(
|
|
|
|
serverState.serverAddressText ?? "...",
|
|
|
|
style: TextStyle(
|
|
|
|
fontSize: 14,
|
|
|
|
),
|
|
|
|
),
|
2024-11-07 00:34:11 +08:00
|
|
|
),
|
2024-11-07 21:33:30 +08:00
|
|
|
SizedBox(width: 14),
|
|
|
|
ToggleSwitch(
|
|
|
|
checked: serverState.isServerStartup,
|
|
|
|
onChanged: (b) =>
|
|
|
|
_onSwitchServer(context, b, serverModel)),
|
|
|
|
],
|
|
|
|
),
|
2024-11-07 00:34:11 +08:00
|
|
|
],
|
|
|
|
),
|
|
|
|
SizedBox(height: 24),
|
2024-11-05 22:55:00 +08:00
|
|
|
Row(
|
|
|
|
children: [
|
|
|
|
Expanded(
|
|
|
|
child: Text(
|
|
|
|
textAlign: TextAlign.end,
|
2024-11-07 21:33:30 +08:00
|
|
|
S.current.input_method_disclaimer,
|
2024-11-05 22:55:00 +08:00
|
|
|
style: TextStyle(
|
|
|
|
fontSize: 13,
|
|
|
|
color: Colors.white.withOpacity(.6),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
)
|
|
|
|
],
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
Widget makeTitle(BuildContext context, InputMethodDialogUIState state,
|
|
|
|
InputMethodDialogUIModel model, TextEditingController destTextCtrl) {
|
|
|
|
return Row(
|
|
|
|
children: [
|
|
|
|
IconButton(
|
|
|
|
icon: const Icon(
|
|
|
|
FluentIcons.back,
|
|
|
|
size: 22,
|
|
|
|
),
|
|
|
|
onPressed: () {
|
|
|
|
context.pop();
|
|
|
|
}),
|
|
|
|
const SizedBox(width: 12),
|
2024-11-07 21:33:30 +08:00
|
|
|
Text(S.current.input_method_experimental_input_method),
|
2024-11-05 22:55:00 +08:00
|
|
|
Spacer(),
|
|
|
|
Row(
|
|
|
|
mainAxisAlignment: MainAxisAlignment.end,
|
|
|
|
children: [
|
|
|
|
Text(
|
2024-11-07 21:33:30 +08:00
|
|
|
S.current.input_method_auto_copy,
|
2024-11-05 22:55:00 +08:00
|
|
|
style: TextStyle(fontSize: 14),
|
|
|
|
),
|
|
|
|
SizedBox(width: 12),
|
|
|
|
ToggleSwitch(
|
|
|
|
checked: state.enableAutoCopy,
|
|
|
|
onChanged: model.onSwitchAutoCopy),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
SizedBox(width: 24),
|
|
|
|
FilledButton(
|
|
|
|
child: Padding(
|
|
|
|
padding: const EdgeInsets.all(6),
|
|
|
|
child: Icon(FluentIcons.copy),
|
|
|
|
),
|
|
|
|
onPressed: () {
|
|
|
|
if (destTextCtrl.text.isNotEmpty) {
|
|
|
|
Clipboard.setData(ClipboardData(text: destTextCtrl.text));
|
|
|
|
}
|
|
|
|
},
|
|
|
|
)
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
2024-11-07 00:34:11 +08:00
|
|
|
|
|
|
|
Future<void> _onSwitchServer(
|
|
|
|
BuildContext context, bool value, InputMethodServer serverModel) async {
|
|
|
|
if (value) {
|
|
|
|
final userOK = await showConfirmDialogs(
|
2024-11-07 21:33:30 +08:00
|
|
|
context,
|
|
|
|
S.current.input_method_confirm_enable_remote_input,
|
|
|
|
Text(S.current.input_method_enable_remote_input_instructions));
|
2024-11-07 00:34:11 +08:00
|
|
|
if (userOK) {
|
|
|
|
// ignore: use_build_context_synchronously
|
|
|
|
await serverModel.startServer().unwrap(context: context);
|
|
|
|
if (!context.mounted) return;
|
2024-11-07 20:16:08 +08:00
|
|
|
await showDialog(
|
2024-11-07 00:34:11 +08:00
|
|
|
context: context,
|
|
|
|
builder: (BuildContext context) => ServerQrDialogUI(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
await serverModel.stopServer().unwrap(context: context);
|
|
|
|
}
|
|
|
|
}
|
2024-11-23 21:51:36 +08:00
|
|
|
|
|
|
|
_onSwitchAutoTranslate(
|
|
|
|
BuildContext context, InputMethodDialogUIModel model, bool b) async {
|
|
|
|
if (b) {
|
|
|
|
final ok = await showConfirmDialogs(
|
|
|
|
context,
|
|
|
|
S.current.input_method_auto_translate_dialog_title,
|
|
|
|
Text(S.current.input_method_auto_translate_dialog_title_content));
|
|
|
|
if (ok != true) return;
|
|
|
|
}
|
|
|
|
model.toggleAutoTranslate(b);
|
|
|
|
}
|
2024-11-05 22:55:00 +08:00
|
|
|
}
|