Update lot features

This commit is contained in:
2026-05-28 16:29:23 +07:00
parent 6272ece15d
commit 1110e5a42d
81 changed files with 4306 additions and 29813 deletions
@@ -158,8 +158,10 @@ class _GuardianEndpointScreenState extends State<_GuardianEndpointScreen> {
context: context,
builder: (dialogContext) => StatefulBuilder(
builder: (context, setDialogState) => AlertDialog(
title: Text(_labelFromKey(item['commandKey']?.toString() ?? '') ??
'Voice Command'),
title: Text(
_labelFromKey(item['commandKey']?.toString() ?? '') ??
'Voice Command',
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
@@ -180,11 +182,13 @@ class _GuardianEndpointScreenState extends State<_GuardianEndpointScreen> {
),
actions: [
TextButton(
onPressed: () => Navigator.pop(dialogContext, false),
child: const Text('Cancel')),
onPressed: () => Navigator.pop(dialogContext, false),
child: const Text('Cancel'),
),
FilledButton(
onPressed: () => Navigator.pop(dialogContext, true),
child: const Text('Save')),
onPressed: () => Navigator.pop(dialogContext, true),
child: const Text('Save'),
),
],
),
),
@@ -209,8 +213,9 @@ class _GuardianEndpointScreenState extends State<_GuardianEndpointScreen> {
context: context,
builder: (dialogContext) => StatefulBuilder(
builder: (context, setDialogState) => AlertDialog(
title: Text(_labelFromKey(item['shortcutKey']?.toString() ?? '') ??
'Shortcut'),
title: Text(
_labelFromKey(item['shortcutKey']?.toString() ?? '') ?? 'Shortcut',
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
@@ -230,6 +235,31 @@ class _GuardianEndpointScreenState extends State<_GuardianEndpointScreen> {
prefixIcon: Icon(Icons.numbers_outlined),
),
),
const SizedBox(height: 10),
Wrap(
spacing: 8,
runSpacing: 8,
children: [
ActionChip(
avatar: const Icon(Icons.volume_up_outlined, size: 18),
label: const Text('Volume Up'),
onPressed: () {
buttonName.text = 'Volume Up';
buttonCode.text = '24';
setDialogState(() {});
},
),
ActionChip(
avatar: const Icon(Icons.volume_down_outlined, size: 18),
label: const Text('Volume Down'),
onPressed: () {
buttonName.text = 'Volume Down';
buttonCode.text = '25';
setDialogState(() {});
},
),
],
),
SwitchListTile(
contentPadding: EdgeInsets.zero,
value: enabled,
@@ -240,11 +270,13 @@ class _GuardianEndpointScreenState extends State<_GuardianEndpointScreen> {
),
actions: [
TextButton(
onPressed: () => Navigator.pop(dialogContext, false),
child: const Text('Cancel')),
onPressed: () => Navigator.pop(dialogContext, false),
child: const Text('Cancel'),
),
FilledButton(
onPressed: () => Navigator.pop(dialogContext, true),
child: const Text('Save')),
onPressed: () => Navigator.pop(dialogContext, true),
child: const Text('Save'),
),
],
),
),
@@ -273,8 +305,9 @@ class _GuardianEndpointScreenState extends State<_GuardianEndpointScreen> {
},
onError: (message) {
if (!mounted) return;
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text(message)));
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text(message)));
},
fallback: 'Konfigurasi belum bisa disimpan.',
);
@@ -301,18 +334,15 @@ class _EndpointCard extends StatelessWidget {
'',
) ??
'Item #${item['id'] ?? '-'}';
final subtitle = _firstText(
item,
[
'triggerPhrase',
'buttonName',
'description',
'action',
'shortcut',
'status',
'createdAt'
],
) ??
final subtitle = _firstText(item, [
'triggerPhrase',
'buttonName',
'description',
'action',
'shortcut',
'status',
'createdAt',
]) ??
'Data aktif';
final enabled = item['enabled'] != false;
return Container(
@@ -338,11 +368,15 @@ class _EndpointCard extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title,
style: const TextStyle(fontWeight: FontWeight.w800)),
Text(
title,
style: const TextStyle(fontWeight: FontWeight.w800),
),
const SizedBox(height: 3),
Text(subtitle,
style: const TextStyle(color: Color(0xFF64748B))),
Text(
subtitle,
style: const TextStyle(color: Color(0xFF64748B)),
),
const SizedBox(height: 6),
Wrap(
spacing: 8,
@@ -415,7 +449,6 @@ String? _labelFromKey(String value) {
return value
.split('_')
.where((part) => part.isNotEmpty)
.map((part) =>
part[0].toUpperCase() + part.substring(1).toLowerCase())
.map((part) => part[0].toUpperCase() + part.substring(1).toLowerCase())
.join(' ');
}