2023-04-18 16:46:04 +00:00
|
|
|
import 'dart:convert';
|
|
|
|
|
|
|
|
import 'package:flutter/material.dart';
|
2023-04-18 15:15:52 +00:00
|
|
|
import 'package:isar/isar.dart';
|
2023-04-18 16:46:04 +00:00
|
|
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
|
|
|
import 'package:stackwallet/utilities/extensions/impl/gradient.dart';
|
|
|
|
import 'package:stackwallet/utilities/extensions/impl/string.dart';
|
|
|
|
import 'package:stackwallet/utilities/theme/color_theme.dart';
|
|
|
|
import 'package:uuid/uuid.dart';
|
2023-04-18 15:15:52 +00:00
|
|
|
|
|
|
|
@Collection(inheritance: false)
|
2023-04-20 15:32:50 +00:00
|
|
|
class StackTheme {
|
2023-04-18 16:46:04 +00:00
|
|
|
final String assetBundleUrl;
|
|
|
|
|
2023-04-18 15:15:52 +00:00
|
|
|
/// should be a uuid
|
|
|
|
@Index(unique: true, replace: true)
|
2023-04-20 15:32:50 +00:00
|
|
|
final String internalId;
|
2023-04-18 15:15:52 +00:00
|
|
|
|
|
|
|
/// the theme name that will be displayed in app
|
|
|
|
final String name;
|
|
|
|
|
|
|
|
// system brightness
|
|
|
|
final String brightnessString;
|
|
|
|
|
|
|
|
/// convenience enum conversion for stored [brightnessString]
|
|
|
|
@ignore
|
|
|
|
Brightness get brightness {
|
|
|
|
switch (brightnessString) {
|
|
|
|
case "light":
|
|
|
|
return Brightness.light;
|
|
|
|
case "dark":
|
|
|
|
return Brightness.dark;
|
|
|
|
default:
|
|
|
|
// just return light instead of a possible crash causing error
|
|
|
|
return Brightness.light;
|
|
|
|
}
|
|
|
|
}
|
2023-04-18 16:46:04 +00:00
|
|
|
|
|
|
|
@ignore
|
2023-04-20 15:32:50 +00:00
|
|
|
Color get background => _background ??= Color(backgroundInt);
|
2023-04-18 16:46:04 +00:00
|
|
|
@ignore
|
|
|
|
Color? _background;
|
2023-04-20 15:32:50 +00:00
|
|
|
final int backgroundInt;
|
2023-04-18 16:46:04 +00:00
|
|
|
|
|
|
|
// ==== backgroundAppBar =====================================================
|
|
|
|
@ignore
|
2023-04-20 15:32:50 +00:00
|
|
|
Color get backgroundAppBar =>
|
|
|
|
_backgroundAppBar ??= Color(backgroundAppBarInt);
|
2023-04-18 16:46:04 +00:00
|
|
|
@ignore
|
|
|
|
Color? _backgroundAppBar;
|
2023-04-20 15:32:50 +00:00
|
|
|
final int backgroundAppBarInt;
|
2023-04-18 16:46:04 +00:00
|
|
|
// ===========================================================================
|
|
|
|
|
|
|
|
@ignore
|
|
|
|
Gradient get gradientBackground =>
|
|
|
|
_gradientBackground ??= GradientExt.fromJson(
|
|
|
|
Map<String, dynamic>.from(
|
|
|
|
jsonDecode(gradientBackgroundString) as Map,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
@ignore
|
|
|
|
Gradient? _gradientBackground;
|
|
|
|
final String gradientBackgroundString;
|
|
|
|
|
2023-04-20 15:32:50 +00:00
|
|
|
// ===========================================================================
|
|
|
|
|
2023-04-18 16:46:04 +00:00
|
|
|
@ignore
|
|
|
|
Map<Coin, Color> get coinColors =>
|
2023-04-20 15:32:50 +00:00
|
|
|
_coinColors ??= parseCoinColors(coinColorsJsonString);
|
2023-04-18 16:46:04 +00:00
|
|
|
@ignore
|
|
|
|
Map<Coin, Color>? _coinColors;
|
2023-04-20 15:32:50 +00:00
|
|
|
final String coinColorsJsonString;
|
|
|
|
|
|
|
|
// ===========================================================================
|
2023-04-18 16:46:04 +00:00
|
|
|
|
2023-04-20 15:32:50 +00:00
|
|
|
// ===========================================================================
|
|
|
|
// ===========================================================================
|
2023-04-18 16:46:04 +00:00
|
|
|
|
2023-04-20 15:32:50 +00:00
|
|
|
final ThemeAssets assets;
|
|
|
|
|
|
|
|
// ===========================================================================
|
|
|
|
// ===========================================================================
|
|
|
|
|
|
|
|
StackTheme({
|
|
|
|
required this.internalId,
|
2023-04-18 16:46:04 +00:00
|
|
|
required this.assetBundleUrl,
|
|
|
|
required this.name,
|
|
|
|
required this.brightnessString,
|
2023-04-20 15:32:50 +00:00
|
|
|
required this.backgroundInt,
|
|
|
|
required this.backgroundAppBarInt,
|
2023-04-18 16:46:04 +00:00
|
|
|
required this.gradientBackgroundString,
|
2023-04-20 15:32:50 +00:00
|
|
|
required this.coinColorsJsonString,
|
|
|
|
required this.assets,
|
2023-04-18 16:46:04 +00:00
|
|
|
});
|
|
|
|
|
2023-04-20 15:32:50 +00:00
|
|
|
factory StackTheme.fromJson({
|
|
|
|
required Map<String, dynamic> json,
|
|
|
|
required String applicationThemesDirectoryPath,
|
|
|
|
}) {
|
2023-04-18 16:46:04 +00:00
|
|
|
final _id = const Uuid().v1();
|
2023-04-20 15:32:50 +00:00
|
|
|
return StackTheme(
|
|
|
|
internalId: _id,
|
2023-04-18 16:46:04 +00:00
|
|
|
name: json["name"] as String,
|
|
|
|
assetBundleUrl: json["assetBundleUrl"] as String,
|
|
|
|
brightnessString: json["brightness"] as String,
|
2023-04-20 15:32:50 +00:00
|
|
|
backgroundInt: parseColor(json["colors"]["background"] as String),
|
|
|
|
backgroundAppBarInt:
|
|
|
|
parseColor(json["colors"]["backgroundAppBar"] as String),
|
2023-04-18 16:46:04 +00:00
|
|
|
gradientBackgroundString:
|
|
|
|
jsonEncode(json["gradients"]["gradientBackground"] as Map),
|
2023-04-20 15:32:50 +00:00
|
|
|
coinColorsJsonString: jsonEncode(json["coinColors"] as Map),
|
|
|
|
assets: ThemeAssets.fromJson(
|
|
|
|
json: json,
|
|
|
|
applicationThemesDirectoryPath: applicationThemesDirectoryPath,
|
|
|
|
internalThemeUuid: _id,
|
|
|
|
),
|
2023-04-18 16:46:04 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2023-04-20 15:32:50 +00:00
|
|
|
/// Grab the int value of the hex color string.
|
|
|
|
/// 8 char string value expected where the first 2 are opacity
|
|
|
|
static int parseColor(String colorHex) {
|
|
|
|
try {
|
|
|
|
final int colorValue = colorHex.toBigIntFromHex.toInt();
|
|
|
|
if (colorValue >= 0 && colorValue <= 0xFFFFFFFF) {
|
|
|
|
return colorValue;
|
|
|
|
} else {
|
|
|
|
throw ArgumentError(
|
|
|
|
'"$colorHex" and corresponding int '
|
|
|
|
'value "$colorValue" is not a valid color.',
|
|
|
|
);
|
|
|
|
}
|
|
|
|
} catch (_) {
|
|
|
|
throw ArgumentError(
|
|
|
|
'"$colorHex" is not a valid hex number',
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// parse coin colors json and fetch color or use default
|
2023-04-18 16:46:04 +00:00
|
|
|
static Map<Coin, Color> parseCoinColors(String jsonString) {
|
|
|
|
final json = jsonDecode(jsonString) as Map;
|
|
|
|
final map = Map<String, dynamic>.from(json);
|
|
|
|
|
|
|
|
final Map<Coin, Color> result = {};
|
|
|
|
|
|
|
|
for (final coin in Coin.values) {
|
|
|
|
if (map[coin.name] is String) {
|
|
|
|
result[coin] = Color(
|
|
|
|
(map[coin.name] as String).toBigIntFromHex.toInt(),
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
result[coin] = kCoinThemeColorDefaults.forCoin(coin);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
2023-04-18 15:15:52 +00:00
|
|
|
}
|
2023-04-20 15:32:50 +00:00
|
|
|
|
|
|
|
@Embedded(inheritance: false)
|
|
|
|
class ThemeAssets {
|
|
|
|
final String plus;
|
|
|
|
|
|
|
|
// todo: add all assets expected in json
|
|
|
|
|
|
|
|
ThemeAssets({
|
|
|
|
required this.plus,
|
|
|
|
});
|
|
|
|
|
|
|
|
factory ThemeAssets.fromJson({
|
|
|
|
required Map<String, dynamic> json,
|
|
|
|
required String applicationThemesDirectoryPath,
|
|
|
|
required String internalThemeUuid,
|
|
|
|
}) {
|
|
|
|
return ThemeAssets(
|
|
|
|
plus:
|
|
|
|
"$applicationThemesDirectoryPath/$internalThemeUuid/${json["assets"]["svg"]["plus.svg"] as String}",
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|