revised image asset structure

This commit is contained in:
Mikkeli Matlock
2026-01-25 23:13:30 +09:00
parent d7a1f2fabd
commit b1e23fdd10
16 changed files with 92 additions and 169 deletions

View File

@@ -21,7 +21,6 @@ class SmartSerowApp extends StatelessWidget {
),
useMaterial3: true,
fontFamily: 'DIN1451',
fontFamilyFallback: const ['NotoSans', 'Roboto'],
),
home: const AppRoot(),
);

View File

@@ -1,7 +1,9 @@
import 'dart:async';
import 'dart:io';
import 'dart:math';
import 'package:flutter/material.dart';
import '../services/config_service.dart';
import '../services/pi_io.dart';
import '../widgets/stat_box.dart';
@@ -46,6 +48,21 @@ class _DashboardScreenState extends State<DashboardScreen> {
super.dispose();
}
/// Build navigator image from filesystem
Widget _buildNavigatorImage() {
final config = ConfigService.instance;
final imagePath = '${config.assetsPath}/navigator/${config.navigator}/default.png';
return Image.file(
File(imagePath),
fit: BoxFit.contain,
errorBuilder: (context, error, stackTrace) {
// Graceful fallback - empty box if image missing
return const SizedBox.shrink();
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
@@ -127,14 +144,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
Expanded(
flex: 1,
child: Center(
child: Image.asset(
'assets/images/rei_default.png',
fit: BoxFit.contain,
errorBuilder: (context, error, stackTrace) {
// Graceful fallback - empty box if image missing
return const SizedBox.shrink();
},
),
child: _buildNavigatorImage(),
),
),
],

View File

@@ -16,6 +16,10 @@ class ConfigService {
static const double _defaultThreshold = 80.0;
static const int _defaultTriggerDuration = 10;
static const int _defaultShutdownDelay = 10;
static const String _defaultNavigator = 'rei';
// Executable directory (for fallback paths)
late final String _exeDir;
/// Load config from JSON file
///
@@ -24,11 +28,12 @@ class ConfigService {
Future<void> load() async {
if (_loaded) return;
// Config file sits next to the executable
final exePath = Platform.resolvedExecutable;
_exeDir = File(exePath).parent.path;
try {
// Config file sits next to the executable
final exePath = Platform.resolvedExecutable;
final exeDir = File(exePath).parent.path;
final configPath = '$exeDir${Platform.pathSeparator}config.json';
final configPath = '$_exeDir${Platform.pathSeparator}config.json';
final file = File(configPath);
if (await file.exists()) {
@@ -66,4 +71,19 @@ class ConfigService {
if (value is int) return Duration(seconds: value);
return Duration(seconds: _defaultShutdownDelay);
}
/// Path to external assets directory
String get assetsPath {
final value = _config?['assets_path'];
if (value is String && value.isNotEmpty) return value;
// Fallback: assets/ next to executable
return '$_exeDir${Platform.pathSeparator}assets';
}
/// Navigator character name (subfolder in assets/navigator/)
String get navigator {
final value = _config?['navigator'];
if (value is String && value.isNotEmpty) return value;
return _defaultNavigator;
}
}