feat(tv-admin): fix action/focus flows, update app title, randomize unsplash, bump 1.0.9+10

This commit is contained in:
dwindown
2026-04-05 14:59:55 +07:00
parent c70a6baf7b
commit 98b8437e87
13 changed files with 144 additions and 131 deletions

View File

@@ -344,6 +344,40 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
);
}
Future<void> _pickSlideshowImages() async {
try {
final res = await FilePicker.platform.pickFiles(
type: FileType.image,
allowMultiple: true,
);
if (res == null) return;
var hasNewImage = false;
setState(() {
for (final path in res.paths) {
if (path != null &&
File(path).existsSync() &&
!_slideshowImages.contains(path)) {
_slideshowImages.add(path);
hasNewImage = true;
}
}
});
if (hasNewImage) {
_queueTampilanAutoSave(
message: 'Galeri slideshow otomatis tersimpan',
);
}
} catch (e) {
if (!mounted) return;
_showStatusBadge(
'Gagal membuka pemilih file. Pastikan file manager tersedia di perangkat.',
isError: true,
);
}
}
Future<void> _savePengumuman({
String message = 'Pengaturan pengumuman otomatis tersimpan',
}) async {
@@ -1270,7 +1304,6 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
count += 1;
count += 1;
count += _slideshowImages.length;
count += 1;
return count;
}
@@ -1375,9 +1408,7 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
_focusNavTab(index + 1);
return KeyEventResult.handled;
}
if (key == LogicalKeyboardKey.arrowRight ||
key == LogicalKeyboardKey.select ||
key == LogicalKeyboardKey.enter) {
if (key == LogicalKeyboardKey.arrowRight || _isActivateKey(key)) {
_focusEntryForTab(index);
return KeyEventResult.handled;
}
@@ -1410,7 +1441,7 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
if (key == LogicalKeyboardKey.arrowRight) {
return KeyEventResult.handled;
}
if (key == LogicalKeyboardKey.select || key == LogicalKeyboardKey.enter) {
if (_isActivateKey(key)) {
onActivate();
return KeyEventResult.handled;
}
@@ -1453,7 +1484,7 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
if (key == LogicalKeyboardKey.arrowRight) {
return KeyEventResult.handled;
}
if (key == LogicalKeyboardKey.select || key == LogicalKeyboardKey.enter) {
if (_isActivateKey(key)) {
onActivate();
return KeyEventResult.handled;
}
@@ -1485,7 +1516,7 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
if (key == LogicalKeyboardKey.arrowRight) {
return KeyEventResult.handled;
}
if (key == LogicalKeyboardKey.select || key == LogicalKeyboardKey.enter) {
if (_isActivateKey(key)) {
onActivate();
return KeyEventResult.handled;
}
@@ -1517,7 +1548,7 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
if (key == LogicalKeyboardKey.arrowRight) {
return KeyEventResult.handled;
}
if (key == LogicalKeyboardKey.select || key == LogicalKeyboardKey.enter) {
if (_isActivateKey(key)) {
onActivate();
return KeyEventResult.handled;
}
@@ -1548,7 +1579,7 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
if (key == LogicalKeyboardKey.arrowRight) {
return KeyEventResult.handled;
}
if (key == LogicalKeyboardKey.select || key == LogicalKeyboardKey.enter) {
if (_isActivateKey(key)) {
onActivate();
return KeyEventResult.handled;
}
@@ -1579,13 +1610,21 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
if (key == LogicalKeyboardKey.arrowRight) {
return KeyEventResult.handled;
}
if (key == LogicalKeyboardKey.select || key == LogicalKeyboardKey.enter) {
if (_isActivateKey(key)) {
onActivate();
return KeyEventResult.handled;
}
return KeyEventResult.ignored;
}
bool _isActivateKey(LogicalKeyboardKey key) {
return key == LogicalKeyboardKey.enter ||
key == LogicalKeyboardKey.select ||
key == LogicalKeyboardKey.numpadEnter ||
key == LogicalKeyboardKey.space ||
key == LogicalKeyboardKey.gameButtonA;
}
Widget _buildJumatTab(double s) {
return FocusTraversalGroup(
policy: WidgetOrderTraversalPolicy(),
@@ -1743,7 +1782,6 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
_slideshowImages.length,
(_) => row++,
);
final openPengumumanRow = row++;
return FocusTraversalGroup(
policy: WidgetOrderTraversalPolicy(),
@@ -2050,41 +2088,9 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
_buildTampilanActionButton(
rowIndex: addSlideshowImageRow,
s: s,
onActivate: () async {
final res = await FilePicker.platform.pickFiles(type: FileType.image, allowMultiple: true);
if (res != null) {
setState(() {
for (var path in res.paths) {
if (path != null &&
File(path).existsSync() &&
!_slideshowImages.contains(path)) {
_slideshowImages.add(path);
}
}
});
_queueTampilanAutoSave(
message: 'Galeri slideshow otomatis tersimpan',
);
}
},
onActivate: _pickSlideshowImages,
child: ElevatedButton.icon(
onPressed: () async {
final res = await FilePicker.platform.pickFiles(type: FileType.image, allowMultiple: true);
if (res != null) {
setState(() {
for (var path in res.paths) {
if (path != null &&
File(path).existsSync() &&
!_slideshowImages.contains(path)) {
_slideshowImages.add(path);
}
}
});
_queueTampilanAutoSave(
message: 'Galeri slideshow otomatis tersimpan',
);
}
},
onPressed: _pickSlideshowImages,
icon: HugeIcon(icon: HugeIcons.strokeRoundedPlusSign, color: SacredColors.onPrimary, size: 18 * s),
label: Text('TAMBAH FOTO', style: TextStyle(fontSize: 14 * s)),
style: _tvElevatedActionStyle(
@@ -2180,58 +2186,6 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
],
),
),
SizedBox(height: 24 * s),
_adminCard(
s,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_sectionLabel('Pengumuman Dipisah ke Tab Sendiri', s),
SizedBox(height: 8 * s),
Text(
'Text slide tengah dan running text bawah sekarang dipindahkan ke tab Pengumuman agar halaman Tampilan & Media lebih ringkas.',
style: GoogleFonts.manrope(
fontSize: 14 * s,
color: SacredColors.onSurfaceVariant,
),
),
SizedBox(height: 16 * s),
_buildTampilanActionButton(
rowIndex: openPengumumanRow,
s: s,
onActivate: () {
_setSelectedTab(3);
_focusEntryForTab(3);
},
child: ElevatedButton.icon(
onPressed: () {
_setSelectedTab(3);
_focusEntryForTab(3);
},
icon: HugeIcon(
icon: HugeIcons.strokeRoundedNotification03,
color: SacredColors.onPrimary,
size: 18 * s,
),
label: Text(
'BUKA TAB PENGUMUMAN',
style: TextStyle(fontSize: 14 * s),
),
style: _tvElevatedActionStyle(
s: s,
normalBackground: SacredColors.secondary,
normalForeground: SacredColors.onPrimary,
padding: EdgeInsets.symmetric(
horizontal: 20 * s,
vertical: 14 * s,
),
fontSize: 14 * s,
),
),
),
],
),
),
SizedBox(height: 40 * s),
],
),