Release v2.0.0: Responsive layout with precise tap targets

- Responsive portrait/landscape layout system
- Precise tap targets: speed text cycles units, compass area cycles themes
- Screen wake lock to prevent dimming during navigation
- Custom DIN1451Alt font integration
- Updated app icons and Flutter dependencies

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Mikkeli Matlock
2025-08-24 23:35:22 +09:00
parent fb7926d38d
commit 88d22154ab
32 changed files with 137 additions and 61 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 544 B

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 442 B

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 721 B

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

+2 -2
View File
@@ -427,7 +427,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++"; CLANG_CXX_LIBRARY = "libc++";
@@ -484,7 +484,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++"; CLANG_CXX_LIBRARY = "libc++";
Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 450 B

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 282 B

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 462 B

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 704 B

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 586 B

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 862 B

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 862 B

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 762 B

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

+64 -58
View File
@@ -145,33 +145,33 @@ class _SpeedometerScreenState extends State<SpeedometerScreen> {
Widget _buildPortraitLayout(String speedText, ColorTheme currentTheme) { Widget _buildPortraitLayout(String speedText, ColorTheme currentTheme) {
return Column( return Column(
children: [ children: [
// Speed area - takes most space // Speed area - takes most space, precise tap targets on text only
Expanded( Expanded(
flex: 7, flex: 7,
child: GestureDetector( child: Container(
onTap: _cycleUnit, width: double.infinity,
child: Container( color: Colors.transparent,
width: double.infinity, padding: const EdgeInsets.all(16),
color: Colors.transparent, child: Column(
padding: const EdgeInsets.all(16), mainAxisAlignment: MainAxisAlignment.center,
child: Column( children: [
mainAxisAlignment: MainAxisAlignment.center, if (_errorMessage.isNotEmpty)
children: [ Flexible(
if (_errorMessage.isNotEmpty) child: Text(
Flexible( _errorMessage,
child: Text( style: TextStyle(
_errorMessage, color: currentTheme.speedText,
style: TextStyle( fontSize: 18,
color: currentTheme.speedText, fontFamily: 'DIN1451Alt',
fontSize: 18,
fontFamily: 'DIN1451Alt',
),
textAlign: TextAlign.center,
), ),
) textAlign: TextAlign.center,
else ...[ ),
Flexible( )
flex: 3, else ...[
Flexible(
flex: 3,
child: GestureDetector(
onTap: _cycleUnit,
child: FittedBox( child: FittedBox(
fit: BoxFit.scaleDown, fit: BoxFit.scaleDown,
child: Text( child: Text(
@@ -185,8 +185,11 @@ class _SpeedometerScreenState extends State<SpeedometerScreen> {
), ),
), ),
), ),
Flexible( ),
flex: 1, Flexible(
flex: 1,
child: GestureDetector(
onTap: _cycleUnit,
child: FittedBox( child: FittedBox(
fit: BoxFit.scaleDown, fit: BoxFit.scaleDown,
child: Text( child: Text(
@@ -199,13 +202,13 @@ class _SpeedometerScreenState extends State<SpeedometerScreen> {
), ),
), ),
), ),
], ),
], ],
), ],
), ),
), ),
), ),
// Compass area - compact but tappable // Compass area - compact but fully tappable for theme cycling
Expanded( Expanded(
flex: 3, flex: 3,
child: GestureDetector( child: GestureDetector(
@@ -251,33 +254,33 @@ class _SpeedometerScreenState extends State<SpeedometerScreen> {
Widget _buildLandscapeLayout(String speedText, ColorTheme currentTheme) { Widget _buildLandscapeLayout(String speedText, ColorTheme currentTheme) {
return Row( return Row(
children: [ children: [
// Speed area - takes majority of space // Speed area - takes majority of space, precise tap targets on text only
Expanded( Expanded(
flex: 65, flex: 65,
child: GestureDetector( child: Container(
onTap: _cycleUnit, height: double.infinity,
child: Container( color: Colors.transparent,
height: double.infinity, padding: const EdgeInsets.all(16),
color: Colors.transparent, child: Column(
padding: const EdgeInsets.all(16), mainAxisAlignment: MainAxisAlignment.center,
child: Column( children: [
mainAxisAlignment: MainAxisAlignment.center, if (_errorMessage.isNotEmpty)
children: [ Flexible(
if (_errorMessage.isNotEmpty) child: Text(
Flexible( _errorMessage,
child: Text( style: TextStyle(
_errorMessage, color: currentTheme.speedText,
style: TextStyle( fontSize: 16,
color: currentTheme.speedText, fontFamily: 'DIN1451Alt',
fontSize: 16,
fontFamily: 'DIN1451Alt',
),
textAlign: TextAlign.center,
), ),
) textAlign: TextAlign.center,
else ...[ ),
Flexible( )
flex: 3, else ...[
Flexible(
flex: 3,
child: GestureDetector(
onTap: _cycleUnit,
child: FittedBox( child: FittedBox(
fit: BoxFit.scaleDown, fit: BoxFit.scaleDown,
child: Text( child: Text(
@@ -291,8 +294,11 @@ class _SpeedometerScreenState extends State<SpeedometerScreen> {
), ),
), ),
), ),
Flexible( ),
flex: 1, Flexible(
flex: 1,
child: GestureDetector(
onTap: _cycleUnit,
child: FittedBox( child: FittedBox(
fit: BoxFit.scaleDown, fit: BoxFit.scaleDown,
child: Text( child: Text(
@@ -305,13 +311,13 @@ class _SpeedometerScreenState extends State<SpeedometerScreen> {
), ),
), ),
), ),
], ),
], ],
), ],
), ),
), ),
), ),
// Compass area - smaller but prominent // Compass area - smaller but fully tappable for theme cycling
Expanded( Expanded(
flex: 35, flex: 35,
child: GestureDetector( child: GestureDetector(
+64
View File
@@ -1,6 +1,14 @@
# Generated by pub # Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile # See https://dart.dev/tools/pub/glossary#lockfile
packages: packages:
archive:
dependency: transitive
description:
name: archive
sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd"
url: "https://pub.dev"
source: hosted
version: "4.0.7"
args: args:
dependency: transitive dependency: transitive
description: description:
@@ -33,6 +41,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.4.0" version: "1.4.0"
checked_yaml:
dependency: transitive
description:
name: checked_yaml
sha256: "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f"
url: "https://pub.dev"
source: hosted
version: "2.0.4"
cli_util:
dependency: transitive
description:
name: cli_util
sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c
url: "https://pub.dev"
source: hosted
version: "0.4.2"
clock: clock:
dependency: transitive dependency: transitive
description: description:
@@ -94,6 +118,14 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_launcher_icons:
dependency: "direct dev"
description:
name: flutter_launcher_icons
sha256: "10f13781741a2e3972126fae08393d3c4e01fa4cd7473326b94b72cf594195e7"
url: "https://pub.dev"
source: hosted
version: "0.14.4"
flutter_lints: flutter_lints:
dependency: "direct dev" dependency: "direct dev"
description: description:
@@ -200,6 +232,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.1.2" version: "4.1.2"
image:
dependency: transitive
description:
name: image
sha256: "4e973fcf4caae1a4be2fa0a13157aa38a8f9cb049db6529aa00b4d71abc4d928"
url: "https://pub.dev"
source: hosted
version: "4.5.4"
json_annotation:
dependency: transitive
description:
name: json_annotation
sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
url: "https://pub.dev"
source: hosted
version: "4.9.0"
leak_tracker: leak_tracker:
dependency: transitive dependency: transitive
description: description:
@@ -344,6 +392,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.8" version: "2.1.8"
posix:
dependency: transitive
description:
name: posix
sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61"
url: "https://pub.dev"
source: hosted
version: "6.0.3"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
@@ -485,6 +541,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.6.1" version: "6.6.1"
yaml:
dependency: transitive
description:
name: yaml
sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
url: "https://pub.dev"
source: hosted
version: "3.1.3"
sdks: sdks:
dart: ">=3.9.0 <4.0.0" dart: ">=3.9.0 <4.0.0"
flutter: ">=3.24.0" flutter: ">=3.24.0"
+7 -1
View File
@@ -25,6 +25,7 @@ dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
flutter_lints: ^6.0.0 flutter_lints: ^6.0.0
flutter_launcher_icons: "^0.14.4"
flutter: flutter:
uses-material-design: true uses-material-design: true
@@ -32,4 +33,9 @@ flutter:
fonts: fonts:
- family: DIN1451Alt - family: DIN1451Alt
fonts: fonts:
- asset: fonts/din1451alt.ttf - asset: fonts/din1451alt.ttf
flutter_launcher_icons:
android: true
ios: true
image_path: "icon/speedo.png"