feat(flutter): show app version at the bottom of the home screen

Adds a muted "OSTP · v<version> (<build>)" line pinned below the metrics bar on
the mobile home screen. The version is read from the build via package_info
(already a dependency) rather than hardcoded, so it tracks the release
automatically. Blank-safe if package info can't be read.
This commit is contained in:
ospab 2026-08-24 14:42:47 +03:00
parent 80a2db2b97
commit 219acc99a7
1 changed files with 28 additions and 0 deletions

View File

@ -4,6 +4,7 @@ import 'dart:ui';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:package_info_plus/package_info_plus.dart';
import '../models/connection_state_enum.dart'; import '../models/connection_state_enum.dart';
import '../models/ostp_profile.dart'; import '../models/ostp_profile.dart';
import 'settings_screen.dart'; import 'settings_screen.dart';
@ -55,10 +56,15 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
String _pingText = '-- ms'; String _pingText = '-- ms';
Color _pingColor = Colors.white54; Color _pingColor = Colors.white54;
// App version, shown at the bottom of the home screen. Read from the build
// (pubspec) via package_info rather than hardcoded, so it never drifts.
String _version = '';
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_loadSettings(); _loadSettings();
_loadVersion();
_pulseController = AnimationController( _pulseController = AnimationController(
vsync: this, vsync: this,
duration: const Duration(seconds: 2), duration: const Duration(seconds: 2),
@ -71,6 +77,17 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
_startPolling(); _startPolling();
} }
Future<void> _loadVersion() async {
try {
final info = await PackageInfo.fromPlatform();
if (mounted) {
setState(() => _version = 'v${info.version} (${info.buildNumber})');
}
} catch (_) {
// Non-fatal: just leave the version line blank if it can't be read.
}
}
Future<void> _checkInitialState() async { Future<void> _checkInitialState() async {
try { try {
final isRunning = await platform.invokeMethod('isRunning'); final isRunning = await platform.invokeMethod('isRunning');
@ -517,6 +534,17 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
_buildTopBar(theme), _buildTopBar(theme),
Expanded(child: _buildStage(theme)), Expanded(child: _buildStage(theme)),
_buildMetricsBar(theme), _buildMetricsBar(theme),
Padding(
padding: const EdgeInsets.only(top: 8, bottom: 10),
child: Text(
_version.isEmpty ? 'OSTP' : 'OSTP · $_version',
style: TextStyle(
fontSize: 11,
letterSpacing: 0.5,
color: Colors.white.withOpacity(0.28),
),
),
),
], ],
), ),
), ),