revised image asset structure
This commit is contained in:
4
pi/ui/assets/.gitignore
vendored
Normal file
4
pi/ui/assets/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
# Ignore font files (may have licensing restrictions)
|
||||
# Keep .gitkeep to preserve directory structure
|
||||
fonts/*
|
||||
!fonts/.gitkeep
|
||||
0
pi/ui/assets/fonts/.gitkeep
Normal file
0
pi/ui/assets/fonts/.gitkeep
Normal file
2
pi/ui/assets/images/.gitignore
vendored
2
pi/ui/assets/images/.gitignore
vendored
@@ -1,2 +0,0 @@
|
||||
# Generated/symlinked images - created by prepare_assets.sh
|
||||
rei_default.png
|
||||
@@ -1,4 +1,6 @@
|
||||
{
|
||||
"assets_path": "/home/pi/smartserow-ui/assets",
|
||||
"navigator": "rei",
|
||||
"overheat": {
|
||||
"threshold_celsius": 75.0,
|
||||
"trigger_duration_sec": 10,
|
||||
|
||||
3
pi/ui/fonts/.gitignore
vendored
3
pi/ui/fonts/.gitignore
vendored
@@ -1,3 +0,0 @@
|
||||
# Generated/symlinked font files - created by prepare_assets.sh
|
||||
din1451alt.ttf
|
||||
NotoSans-*.ttf
|
||||
@@ -21,7 +21,6 @@ class SmartSerowApp extends StatelessWidget {
|
||||
),
|
||||
useMaterial3: true,
|
||||
fontFamily: 'DIN1451',
|
||||
fontFamilyFallback: const ['NotoSans', 'Roboto'],
|
||||
),
|
||||
home: const AppRoot(),
|
||||
);
|
||||
|
||||
@@ -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(),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,10 +45,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fake_async
|
||||
sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc"
|
||||
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.2"
|
||||
version: "1.3.3"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
@@ -71,26 +71,26 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker
|
||||
sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec
|
||||
sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.0.8"
|
||||
version: "11.0.2"
|
||||
leak_tracker_flutter_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_flutter_testing
|
||||
sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
|
||||
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.9"
|
||||
version: "3.0.10"
|
||||
leak_tracker_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_testing
|
||||
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
|
||||
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
version: "3.0.2"
|
||||
lints:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -180,18 +180,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
|
||||
sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.4"
|
||||
version: "0.7.6"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_math
|
||||
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
|
||||
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
version: "2.2.0"
|
||||
vm_service:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -201,5 +201,5 @@ packages:
|
||||
source: hosted
|
||||
version: "14.3.1"
|
||||
sdks:
|
||||
dart: ">=3.7.0-0 <4.0.0"
|
||||
dart: ">=3.8.0-0 <4.0.0"
|
||||
flutter: ">=3.18.0-18.0.pre.54"
|
||||
|
||||
@@ -18,17 +18,7 @@ dev_dependencies:
|
||||
flutter:
|
||||
uses-material-design: true
|
||||
|
||||
assets:
|
||||
- assets/images/
|
||||
|
||||
fonts:
|
||||
- family: DIN1451
|
||||
fonts:
|
||||
- asset: fonts/din1451alt.ttf
|
||||
- family: NotoSans
|
||||
fonts:
|
||||
- asset: fonts/NotoSans-Regular.ttf
|
||||
- asset: fonts/NotoSans-Bold.ttf
|
||||
weight: 700
|
||||
- asset: fonts/NotoSans-Light.ttf
|
||||
weight: 300
|
||||
- asset: assets/fonts/din1451alt.ttf
|
||||
|
||||
Reference in New Issue
Block a user