Add select dialog

This commit is contained in:
2025-01-20 15:02:36 +08:00
parent 7b7710b441
commit d88ae57320
3 changed files with 108 additions and 4 deletions

View File

@@ -1291,5 +1291,22 @@ let UI = {
title: title, title: title,
validator: validator 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
})
} }
} }

View File

@@ -28,11 +28,11 @@ mixin class JsUiApi {
if (onCancel != null && onCancel is! JSInvokable) { if (onCancel != null && onCancel is! JSInvokable) {
return; return;
} }
return showLoading(onCancel); return _showLoading(onCancel);
case 'cancelLoading': case 'cancelLoading':
var id = message['id']; var id = message['id'];
if (id is int) { if (id is int) {
cancelLoading(id); _cancelLoading(id);
} }
case 'showInputDialog': case 'showInputDialog':
var title = message['title']; var title = message['title'];
@@ -40,6 +40,18 @@ mixin class JsUiApi {
if (title is! String) return; if (title is! String) return;
if (validator != null && validator is! JSInvokable) return; if (validator != null && validator is! JSInvokable) return;
return _showInputDialog(title, validator); 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<String>().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 func = onCancel == null ? null : JSAutoFreeFunction(onCancel);
var controller = showLoadingDialog( var controller = showLoadingDialog(
App.rootContext, App.rootContext,
@@ -107,7 +119,7 @@ mixin class JsUiApi {
return i; return i;
} }
void cancelLoading(int id) { void _cancelLoading(int id) {
var controller = _loadingDialogControllers.remove(id); var controller = _loadingDialogControllers.remove(id);
controller?.close(); controller?.close();
} }
@@ -134,6 +146,25 @@ mixin class JsUiApi {
); );
return result; return result;
} }
Future<int?> _showSelectDialog(
String title,
List<String> 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 { class _JSCallbackButton extends StatefulWidget {

View File

@@ -402,3 +402,59 @@ void showInfoDialog({
}, },
); );
} }
Future<int?> showSelectDialog({
required String title,
required List<String> 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;
}