mirror of
https://github.com/venera-app/venera.git
synced 2025-09-27 15:57:25 +00:00
Add select dialog
This commit is contained in:
@@ -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
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -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 {
|
||||||
|
@@ -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;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user