From d88ae57320a6e5782b6cae8c0d04399d3ce5684c Mon Sep 17 00:00:00 2001 From: nyne Date: Mon, 20 Jan 2025 15:02:36 +0800 Subject: [PATCH] Add select dialog --- assets/init.js | 17 +++++++++++ lib/components/js_ui.dart | 39 +++++++++++++++++++++++--- lib/components/message.dart | 56 +++++++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 4 deletions(-) diff --git a/assets/init.js b/assets/init.js index cf4b3b4..372231a 100644 --- a/assets/init.js +++ b/assets/init.js @@ -1291,5 +1291,22 @@ let UI = { title: title, validator: validator }) + }, + + /** + * Show a select dialog + * @param title {string} + * @param options {string[]} + * @param initialIndex {number?} + * @returns {number | null} - The selected index. If the dialog is canceled, return null. + */ + showSelectDialog: (title, options, initialIndex) => { + return sendMessage({ + method: 'UI', + function: 'showSelectDialog', + title: title, + options: options, + initialIndex: initialIndex + }) } } \ No newline at end of file diff --git a/lib/components/js_ui.dart b/lib/components/js_ui.dart index 2f5cffe..16b238a 100644 --- a/lib/components/js_ui.dart +++ b/lib/components/js_ui.dart @@ -28,11 +28,11 @@ mixin class JsUiApi { if (onCancel != null && onCancel is! JSInvokable) { return; } - return showLoading(onCancel); + return _showLoading(onCancel); case 'cancelLoading': var id = message['id']; if (id is int) { - cancelLoading(id); + _cancelLoading(id); } case 'showInputDialog': var title = message['title']; @@ -40,6 +40,18 @@ mixin class JsUiApi { if (title is! String) return; if (validator != null && validator is! JSInvokable) return; return _showInputDialog(title, validator); + case 'showSelectDialog': + var title = message['title']; + var options = message['options']; + var initialIndex = message['initialIndex']; + if (title is! String) return; + if (options is! List) return; + if (initialIndex != null && initialIndex is! int) return; + return _showSelectDialog( + title, + options.whereType().toList(), + initialIndex, + ); } } @@ -87,7 +99,7 @@ mixin class JsUiApi { }); } - int showLoading(JSInvokable? onCancel) { + int _showLoading(JSInvokable? onCancel) { var func = onCancel == null ? null : JSAutoFreeFunction(onCancel); var controller = showLoadingDialog( App.rootContext, @@ -107,7 +119,7 @@ mixin class JsUiApi { return i; } - void cancelLoading(int id) { + void _cancelLoading(int id) { var controller = _loadingDialogControllers.remove(id); controller?.close(); } @@ -134,6 +146,25 @@ mixin class JsUiApi { ); return result; } + + Future _showSelectDialog( + String title, + List options, + int? initialIndex, + ) { + if (options.isEmpty) { + return Future.value(null); + } + if (initialIndex != null && + (initialIndex >= options.length || initialIndex < 0)) { + initialIndex = null; + } + return showSelectDialog( + title: title, + options: options, + initialIndex: initialIndex, + ); + } } class _JSCallbackButton extends StatefulWidget { diff --git a/lib/components/message.dart b/lib/components/message.dart index cfa07ff..42b4374 100644 --- a/lib/components/message.dart +++ b/lib/components/message.dart @@ -402,3 +402,59 @@ void showInfoDialog({ }, ); } + +Future showSelectDialog({ + required String title, + required List options, + int? initialIndex, +}) async { + int? current = initialIndex; + + await showDialog( + context: App.rootContext, + builder: (context) { + return StatefulBuilder( + builder: (context, setState) { + return ContentDialog( + title: title, + content: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Select( + current: current == null ? "" : options[current!], + values: options, + minWidth: 156, + onTap: (i) { + setState(() { + current = i; + }); + }, + ) + ], + ), + ), + actions: [ + TextButton( + onPressed: () { + current = null; + context.pop(); + }, + child: Text('Cancel'.tl), + ), + FilledButton( + onPressed: current == null + ? null + : context.pop, + child: Text('Confirm'.tl), + ), + ], + ); + }, + ); + }, + ); + + return current; +}