feat(flutter): token + asset sync from web; gen_tokens.dart
shared/fabledsword.tokens.json mirrors web/src/lib/styles/tokens.json; assets/error-copy.json mirrors the web's error-code copy table; assets/svg/album-fallback.svg mirrors the web placeholder. Together these give Flutter the same visual + copy starting point as the SPA. tool/gen_tokens.dart emits lib/theme/tokens.dart from the JSON; the generated file is committed so CI can verify the JSON and the Dart file haven't drifted (gate added in Task 21). tool/sync_shared.sh mkdirs the shared/ + assets/ destinations before copying so the script works on a fresh checkout (the original plan-text shape only mkdir'd assets/svg). pubspec.yaml assets block uncommented now that the three asset paths exist on disk.
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"unknown": "Something went wrong.",
|
||||
"unauthenticated": "Your session has ended. Please sign in again.",
|
||||
"connection_refused": "Couldn't reach the server. Check the URL and try again.",
|
||||
"lidarr_unreachable": "Lidarr is unreachable right now. Try again, or check Admin → Integrations.",
|
||||
"lidarr_disabled": "Lidarr integration is not enabled.",
|
||||
"lidarr_auth_failed": "Lidarr authentication failed.",
|
||||
"lidarr_defaults_incomplete": "Lidarr is missing a default quality profile or root folder. Set them in Admin → Integrations.",
|
||||
"lidarr_server_error": "Lidarr returned an error. Check Lidarr's logs for the cause.",
|
||||
"lidarr_rejected": "Lidarr rejected the request. Check the server logs for the field-level reason.",
|
||||
"lidarr_album_lookup_failed": "Lidarr doesn't recognize this album. Try Resolve or Delete file instead.",
|
||||
"album_mbid_missing": "This track has no Lidarr album to remove.",
|
||||
"request_not_pending": "This request is no longer pending.",
|
||||
"request_not_found": "That request no longer exists.",
|
||||
"track_not_found": "That track no longer exists."
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Album cover fallback. Used by AlbumCard, CompactTrackCard, and the
|
||||
PlayerBar's onerror handler when an album has no cover_art_path. Colors
|
||||
are FabledSword tokens hard-coded as hex (data-URL / static SVGs can't
|
||||
resolve CSS variables): iron background to match the card surface, a
|
||||
pewter border to give the placeholder a visible edge consistent with
|
||||
real album art, and an ash-tone beamed-pair glyph centered inside.
|
||||
|
||||
Beamed-pair path is from SVG Repo (svgrepo.com), CC0; rescaled and
|
||||
recolored from the original solid-black 800px source.
|
||||
-->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
||||
<rect width="512" height="512" fill="#1E2228"/>
|
||||
<rect x="6" y="6" width="500" height="500"
|
||||
fill="none" stroke="#3F4651" stroke-width="10"/>
|
||||
<g fill="#9C9A92" transform="translate(76.8 76.8) scale(0.7)">
|
||||
<path d="M503.319,5.939c-5.506-4.705-12.783-6.767-19.958-5.635L169.555,49.852c-12.04,1.901-20.909,12.28-20.909,24.47v99.097 v156.903H99.097C44.455,330.323,0,371.073,0,421.161C0,471.25,44.455,512,99.097,512c54.642,0,99.097-40.75,99.097-90.839v-66.065 V194.588l264.258-41.725v136.169h-49.548c-54.642,0-99.097,40.75-99.097,90.839s44.455,90.839,99.097,90.839 S512,429.959,512,379.871v-66.065V123.871V24.774C512,17.529,508.827,10.646,503.319,5.939z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,27 @@
|
||||
// GENERATED — do not edit. Source: shared/fabledsword.tokens.json
|
||||
// Run `dart run tool/gen_tokens.dart` to regenerate.
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class FabledSwordTokens {
|
||||
static const Color obsidian = Color(0xFF14171A);
|
||||
static const Color iron = Color(0xFF1E2228);
|
||||
static const Color slate = Color(0xFF2C313A);
|
||||
static const Color pewter = Color(0xFF3F4651);
|
||||
static const Color parchment = Color(0xFFE8E4D8);
|
||||
static const Color vellum = Color(0xFFC2BFB4);
|
||||
static const Color ash = Color(0xFF9C9A92);
|
||||
static const Color moss = Color(0xFF4A5D3F);
|
||||
static const Color bronze = Color(0xFF8B7355);
|
||||
static const Color oxblood = Color(0xFF6B2118);
|
||||
static const Color warning = Color(0xFF8B6F1E);
|
||||
static const Color error = Color(0xFFC04A1F);
|
||||
static const Color info = Color(0xFF3D5A6E);
|
||||
static const Color accent = Color(0xFF4A6B5C);
|
||||
static const double radiusSm = 4;
|
||||
static const double radiusMd = 8;
|
||||
static const double radiusLg = 12;
|
||||
static const double radiusXl = 16;
|
||||
static const String fontDisplay = "Fraunces";
|
||||
static const String fontBody = "Inter";
|
||||
static const String fontMono = "JetBrains Mono";
|
||||
}
|
||||
@@ -30,10 +30,7 @@ dev_dependencies:
|
||||
|
||||
flutter:
|
||||
uses-material-design: true
|
||||
# assets:
|
||||
# - assets/svg/
|
||||
# - assets/error-copy.json
|
||||
# - shared/fabledsword.tokens.json
|
||||
# NOTE: Task 5 will sync assets/ + shared/ and uncomment the block above.
|
||||
# The flutter test runner refuses to build a bundle with missing asset
|
||||
# paths, even though `flutter pub get` and `flutter analyze` only warn.
|
||||
assets:
|
||||
- assets/svg/
|
||||
- assets/error-copy.json
|
||||
- shared/fabledsword.tokens.json
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"colors": {
|
||||
"obsidian": "#14171A",
|
||||
"iron": "#1E2228",
|
||||
"slate": "#2C313A",
|
||||
"pewter": "#3F4651",
|
||||
"parchment": "#E8E4D8",
|
||||
"vellum": "#C2BFB4",
|
||||
"ash": "#9C9A92",
|
||||
"moss": "#4A5D3F",
|
||||
"bronze": "#8B7355",
|
||||
"oxblood": "#6B2118",
|
||||
"warning": "#8B6F1E",
|
||||
"error": "#C04A1F",
|
||||
"info": "#3D5A6E",
|
||||
"accent": "#4A6B5C"
|
||||
},
|
||||
"radii": {
|
||||
"sm": "4px",
|
||||
"md": "8px",
|
||||
"lg": "12px",
|
||||
"xl": "16px"
|
||||
},
|
||||
"fonts": {
|
||||
"display": "Fraunces",
|
||||
"body": "Inter",
|
||||
"mono": "JetBrains Mono"
|
||||
},
|
||||
"fontStacks": {
|
||||
"display": "'Fraunces', Georgia, serif",
|
||||
"body": "'Inter', system-ui, sans-serif",
|
||||
"mono": "'JetBrains Mono', ui-monospace, monospace"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// Reads shared/fabledsword.tokens.json and emits lib/theme/tokens.dart.
|
||||
// Run via `dart run tool/gen_tokens.dart`. The generated file is
|
||||
// committed (CI validates it matches the JSON to catch drift).
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
void main() {
|
||||
final jsonFile = File('shared/fabledsword.tokens.json');
|
||||
final tokens = jsonDecode(jsonFile.readAsStringSync()) as Map<String, dynamic>;
|
||||
final colors = (tokens['colors'] as Map).cast<String, String>();
|
||||
final radii = (tokens['radii'] as Map).cast<String, String>();
|
||||
final fonts = (tokens['fonts'] as Map).cast<String, String>();
|
||||
|
||||
final out = StringBuffer()
|
||||
..writeln('// GENERATED — do not edit. Source: shared/fabledsword.tokens.json')
|
||||
..writeln('// Run `dart run tool/gen_tokens.dart` to regenerate.')
|
||||
..writeln("import 'package:flutter/material.dart';")
|
||||
..writeln()
|
||||
..writeln('class FabledSwordTokens {');
|
||||
|
||||
colors.forEach((name, hex) {
|
||||
final value = hex.replaceFirst('#', '0xFF');
|
||||
out.writeln(' static const Color ${_camel(name)} = Color($value);');
|
||||
});
|
||||
|
||||
radii.forEach((name, px) {
|
||||
final v = px.replaceAll('px', '');
|
||||
out.writeln(' static const double radius${_pascal(name)} = $v;');
|
||||
});
|
||||
|
||||
fonts.forEach((name, family) {
|
||||
out.writeln(' static const String font${_pascal(name)} = ${jsonEncode(family)};');
|
||||
});
|
||||
|
||||
out.writeln('}');
|
||||
|
||||
File('lib/theme/tokens.dart').writeAsStringSync(out.toString());
|
||||
stdout.writeln('wrote lib/theme/tokens.dart');
|
||||
}
|
||||
|
||||
String _camel(String s) => s; // tokens are already lowerCamel-friendly
|
||||
String _pascal(String s) => s[0].toUpperCase() + s.substring(1);
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copies shared assets from web/ into flutter_client/. Run before
|
||||
# `flutter build` and as part of CI. Idempotent.
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
mkdir -p shared assets/svg
|
||||
cp ../web/src/lib/styles/tokens.json shared/fabledsword.tokens.json
|
||||
cp ../web/src/lib/styles/error-copy.json assets/error-copy.json
|
||||
cp ../web/static/placeholders/album-fallback.svg assets/svg/album-fallback.svg
|
||||
|
||||
echo "shared assets synced from web/"
|
||||
Reference in New Issue
Block a user