mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-12 23:45:18 +00:00
Initial accent theme & background theme support
This commit is contained in:
parent
211affa79d
commit
94db62baa5
3
.vscode/c_cpp_properties.json
vendored
3
.vscode/c_cpp_properties.json
vendored
@ -14,7 +14,8 @@
|
|||||||
"compilerPath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.29.30133\\bin\\Hostx64\\x64\\cl.exe",
|
"compilerPath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.29.30133\\bin\\Hostx64\\x64\\cl.exe",
|
||||||
"cStandard": "c17",
|
"cStandard": "c17",
|
||||||
"cppStandard": "c++17",
|
"cppStandard": "c++17",
|
||||||
"intelliSenseMode": "windows-msvc-x64"
|
"intelliSenseMode": "windows-msvc-x64",
|
||||||
|
"configurationProvider": "ms-vscode.makefile-tools"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"version": 4
|
"version": 4
|
||||||
|
@ -12,6 +12,8 @@ import 'package:spotube/provider/AudioPlayer.dart';
|
|||||||
import 'package:spotube/provider/UserPreferences.dart';
|
import 'package:spotube/provider/UserPreferences.dart';
|
||||||
import 'package:spotube/provider/YouTube.dart';
|
import 'package:spotube/provider/YouTube.dart';
|
||||||
import 'package:just_audio_background/just_audio_background.dart';
|
import 'package:just_audio_background/just_audio_background.dart';
|
||||||
|
import 'package:spotube/themes/dark-theme.dart';
|
||||||
|
import 'package:spotube/themes/light-theme.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
if (Platform.isAndroid || Platform.isIOS) {
|
if (Platform.isAndroid || Platform.isIOS) {
|
||||||
@ -59,98 +61,13 @@ class MyApp extends HookConsumerWidget {
|
|||||||
routerDelegate: _router.routerDelegate,
|
routerDelegate: _router.routerDelegate,
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
title: 'Spotube',
|
title: 'Spotube',
|
||||||
theme: ThemeData(
|
theme: lightTheme(
|
||||||
primaryColor: Colors.green,
|
accentMaterialColor: Colors.deepPurple,
|
||||||
primarySwatch: Colors.green,
|
backgroundMaterialColor: Colors.grey,
|
||||||
buttonTheme: const ButtonThemeData(
|
|
||||||
buttonColor: Colors.green,
|
|
||||||
),
|
),
|
||||||
shadowColor: Colors.grey[300],
|
darkTheme: darkTheme(
|
||||||
backgroundColor: Colors.white,
|
accentMaterialColor: Colors.purple,
|
||||||
textTheme: TextTheme(
|
backgroundMaterialColor: Colors.grey,
|
||||||
bodyText1: TextStyle(color: Colors.grey[850]),
|
|
||||||
headline1: TextStyle(color: Colors.grey[850]),
|
|
||||||
headline2: TextStyle(color: Colors.grey[850]),
|
|
||||||
headline3: TextStyle(color: Colors.grey[850]),
|
|
||||||
headline4: TextStyle(color: Colors.grey[850]),
|
|
||||||
headline5: TextStyle(color: Colors.grey[850]),
|
|
||||||
headline6: TextStyle(color: Colors.grey[850]),
|
|
||||||
),
|
|
||||||
listTileTheme: ListTileThemeData(
|
|
||||||
iconColor: Colors.grey[850],
|
|
||||||
horizontalTitleGap: 0,
|
|
||||||
),
|
|
||||||
inputDecorationTheme: InputDecorationTheme(
|
|
||||||
focusedBorder: OutlineInputBorder(
|
|
||||||
borderSide: BorderSide(
|
|
||||||
color: Colors.green[400]!,
|
|
||||||
width: 2.0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
enabledBorder: OutlineInputBorder(
|
|
||||||
borderSide: BorderSide(
|
|
||||||
color: Colors.grey[800]!,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
navigationRailTheme: NavigationRailThemeData(
|
|
||||||
backgroundColor: Colors.blueGrey[50],
|
|
||||||
unselectedIconTheme:
|
|
||||||
IconThemeData(color: Colors.grey[850], opacity: 1),
|
|
||||||
unselectedLabelTextStyle: TextStyle(
|
|
||||||
color: Colors.grey[850],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
navigationBarTheme: NavigationBarThemeData(
|
|
||||||
backgroundColor: Colors.blueGrey[50],
|
|
||||||
height: 55,
|
|
||||||
),
|
|
||||||
cardTheme: CardTheme(
|
|
||||||
shape:
|
|
||||||
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
darkTheme: ThemeData(
|
|
||||||
brightness: Brightness.dark,
|
|
||||||
primaryColor: Colors.green,
|
|
||||||
primarySwatch: Colors.green,
|
|
||||||
backgroundColor: Colors.blueGrey[900],
|
|
||||||
scaffoldBackgroundColor: Colors.blueGrey[900],
|
|
||||||
dialogBackgroundColor: Colors.blueGrey[800],
|
|
||||||
shadowColor: Colors.black26,
|
|
||||||
popupMenuTheme: PopupMenuThemeData(color: Colors.blueGrey[800]),
|
|
||||||
buttonTheme: const ButtonThemeData(
|
|
||||||
buttonColor: Colors.green,
|
|
||||||
),
|
|
||||||
inputDecorationTheme: InputDecorationTheme(
|
|
||||||
focusedBorder: OutlineInputBorder(
|
|
||||||
borderSide: BorderSide(
|
|
||||||
color: Colors.green[400]!,
|
|
||||||
width: 2.0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
enabledBorder: OutlineInputBorder(
|
|
||||||
borderSide: BorderSide(
|
|
||||||
color: Colors.grey[800]!,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
navigationRailTheme: NavigationRailThemeData(
|
|
||||||
backgroundColor: Colors.blueGrey[800],
|
|
||||||
unselectedIconTheme: const IconThemeData(opacity: 1),
|
|
||||||
),
|
|
||||||
navigationBarTheme: NavigationBarThemeData(
|
|
||||||
backgroundColor: Colors.blueGrey[800],
|
|
||||||
height: 55,
|
|
||||||
),
|
|
||||||
cardTheme: CardTheme(
|
|
||||||
shape:
|
|
||||||
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
|
|
||||||
color: Colors.blueGrey[900],
|
|
||||||
elevation: 20,
|
|
||||||
),
|
|
||||||
canvasColor: Colors.blueGrey[900],
|
|
||||||
),
|
),
|
||||||
themeMode: themeMode,
|
themeMode: themeMode,
|
||||||
);
|
);
|
||||||
|
@ -68,8 +68,8 @@ class Auth extends PersistedChangeNotifier {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
FutureOr<void> loadFromLocal(Map<String, dynamic> map) {
|
FutureOr<void> loadFromLocal(Map<String, dynamic> map) {
|
||||||
_clientId = map["clientId"].isNotEmpty ? map["clientId"] : null;
|
_clientId = map["clientId"];
|
||||||
_clientSecret = map["clientSecret"].isNotEmpty ? map["clientSecret"] : null;
|
_clientSecret = map["clientSecret"];
|
||||||
_accessToken = map["accessToken"];
|
_accessToken = map["accessToken"];
|
||||||
_refreshToken = map["refreshToken"];
|
_refreshToken = map["refreshToken"];
|
||||||
_expiration = DateTime.tryParse(map["expiration"]);
|
_expiration = DateTime.tryParse(map["expiration"]);
|
||||||
|
@ -1,24 +1,25 @@
|
|||||||
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:hotkey_manager/hotkey_manager.dart';
|
import 'package:hotkey_manager/hotkey_manager.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
|
||||||
import 'package:spotube/helpers/get-random-element.dart';
|
import 'package:spotube/helpers/get-random-element.dart';
|
||||||
import 'package:spotube/models/LocalStorageKeys.dart';
|
|
||||||
import 'package:spotube/models/Logger.dart';
|
|
||||||
import 'package:spotube/models/generated_secrets.dart';
|
import 'package:spotube/models/generated_secrets.dart';
|
||||||
|
import 'package:spotube/utils/PersistedChangeNotifier.dart';
|
||||||
|
|
||||||
class UserPreferences extends ChangeNotifier {
|
class UserPreferences extends PersistedChangeNotifier {
|
||||||
ThemeMode themeMode;
|
ThemeMode themeMode;
|
||||||
String ytSearchFormat;
|
String ytSearchFormat;
|
||||||
String recommendationMarket;
|
String recommendationMarket;
|
||||||
bool saveTrackLyrics;
|
bool saveTrackLyrics;
|
||||||
String geniusAccessToken;
|
String geniusAccessToken;
|
||||||
SharedPreferences? localStorage;
|
|
||||||
HotKey? nextTrackHotKey;
|
HotKey? nextTrackHotKey;
|
||||||
HotKey? prevTrackHotKey;
|
HotKey? prevTrackHotKey;
|
||||||
HotKey? playPauseHotKey;
|
HotKey? playPauseHotKey;
|
||||||
|
|
||||||
|
MaterialColor? accentColorScheme;
|
||||||
|
MaterialColor? backgroundColorScheme;
|
||||||
UserPreferences({
|
UserPreferences({
|
||||||
required this.geniusAccessToken,
|
required this.geniusAccessToken,
|
||||||
required this.recommendationMarket,
|
required this.recommendationMarket,
|
||||||
@ -28,135 +29,101 @@ class UserPreferences extends ChangeNotifier {
|
|||||||
this.nextTrackHotKey,
|
this.nextTrackHotKey,
|
||||||
this.prevTrackHotKey,
|
this.prevTrackHotKey,
|
||||||
this.playPauseHotKey,
|
this.playPauseHotKey,
|
||||||
}) {
|
this.accentColorScheme,
|
||||||
onInit();
|
this.backgroundColorScheme,
|
||||||
}
|
}) : super();
|
||||||
|
|
||||||
final logger = getLogger(UserPreferences);
|
|
||||||
|
|
||||||
Future<HotKey?> _getHotKeyFromLocalStorage(String key) async {
|
|
||||||
String? str = localStorage?.getString(key);
|
|
||||||
if (str != null) {
|
|
||||||
Map<String, dynamic> json = await jsonDecode(str);
|
|
||||||
if (json.isEmpty) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return HotKey.fromJson(json);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> onInit() async {
|
|
||||||
try {
|
|
||||||
localStorage = await SharedPreferences.getInstance();
|
|
||||||
String? accessToken =
|
|
||||||
localStorage?.getString(LocalStorageKeys.geniusAccessToken);
|
|
||||||
|
|
||||||
saveTrackLyrics =
|
|
||||||
localStorage?.getBool(LocalStorageKeys.saveTrackLyrics) ?? false;
|
|
||||||
|
|
||||||
final themeModeRaw = localStorage?.getString(LocalStorageKeys.themeMode);
|
|
||||||
switch (themeModeRaw) {
|
|
||||||
case "light":
|
|
||||||
themeMode = ThemeMode.light;
|
|
||||||
break;
|
|
||||||
case "dark":
|
|
||||||
themeMode = ThemeMode.dark;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
themeMode = ThemeMode.system;
|
|
||||||
}
|
|
||||||
|
|
||||||
recommendationMarket =
|
|
||||||
localStorage?.getString(LocalStorageKeys.recommendationMarket) ??
|
|
||||||
'US';
|
|
||||||
geniusAccessToken = accessToken != null && accessToken.isNotEmpty
|
|
||||||
? accessToken
|
|
||||||
: getRandomElement(lyricsSecrets);
|
|
||||||
|
|
||||||
nextTrackHotKey ??= (await _getHotKeyFromLocalStorage(
|
|
||||||
LocalStorageKeys.nextTrackHotKey,
|
|
||||||
)) ??
|
|
||||||
HotKey(
|
|
||||||
KeyCode.slash,
|
|
||||||
modifiers: [KeyModifier.control, KeyModifier.alt],
|
|
||||||
);
|
|
||||||
|
|
||||||
prevTrackHotKey ??= (await _getHotKeyFromLocalStorage(
|
|
||||||
LocalStorageKeys.prevTrackHotKey,
|
|
||||||
)) ??
|
|
||||||
HotKey(
|
|
||||||
KeyCode.comma,
|
|
||||||
modifiers: [KeyModifier.control, KeyModifier.alt],
|
|
||||||
);
|
|
||||||
|
|
||||||
playPauseHotKey ??= (await _getHotKeyFromLocalStorage(
|
|
||||||
LocalStorageKeys.playPauseHotKey,
|
|
||||||
)) ??
|
|
||||||
HotKey(
|
|
||||||
KeyCode.period,
|
|
||||||
modifiers: [KeyModifier.control, KeyModifier.alt],
|
|
||||||
);
|
|
||||||
notifyListeners();
|
|
||||||
} catch (e, stack) {
|
|
||||||
logger.e("onInit", e, stack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setThemeMode(ThemeMode mode) {
|
void setThemeMode(ThemeMode mode) {
|
||||||
themeMode = mode;
|
themeMode = mode;
|
||||||
localStorage?.setString(LocalStorageKeys.themeMode, mode.name);
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
updatePersistence();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSaveTrackLyrics(bool shouldSave) {
|
void setSaveTrackLyrics(bool shouldSave) {
|
||||||
saveTrackLyrics = shouldSave;
|
saveTrackLyrics = shouldSave;
|
||||||
localStorage?.setBool(LocalStorageKeys.saveTrackLyrics, shouldSave);
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
updatePersistence();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setRecommendationMarket(String country) {
|
void setRecommendationMarket(String country) {
|
||||||
recommendationMarket = country;
|
recommendationMarket = country;
|
||||||
localStorage?.setString(LocalStorageKeys.recommendationMarket, country);
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
updatePersistence();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setGeniusAccessToken(String token) {
|
void setGeniusAccessToken(String token) {
|
||||||
geniusAccessToken = token;
|
geniusAccessToken = token;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
updatePersistence();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setNextTrackHotKey(HotKey? value) {
|
void setNextTrackHotKey(HotKey? value) {
|
||||||
nextTrackHotKey = value;
|
nextTrackHotKey = value;
|
||||||
localStorage?.setString(
|
|
||||||
LocalStorageKeys.nextTrackHotKey,
|
|
||||||
jsonEncode(value?.toJson() ?? {}),
|
|
||||||
);
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
updatePersistence();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPrevTrackHotKey(HotKey? value) {
|
void setPrevTrackHotKey(HotKey? value) {
|
||||||
prevTrackHotKey = value;
|
prevTrackHotKey = value;
|
||||||
localStorage?.setString(
|
|
||||||
LocalStorageKeys.prevTrackHotKey,
|
|
||||||
jsonEncode(value?.toJson() ?? {}),
|
|
||||||
);
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
updatePersistence();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPlayPauseHotKey(HotKey? value) {
|
void setPlayPauseHotKey(HotKey? value) {
|
||||||
playPauseHotKey = value;
|
playPauseHotKey = value;
|
||||||
localStorage?.setString(
|
|
||||||
LocalStorageKeys.playPauseHotKey,
|
|
||||||
jsonEncode(value?.toJson() ?? {}),
|
|
||||||
);
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
updatePersistence();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setYtSearchFormat(String format) {
|
void setYtSearchFormat(String format) {
|
||||||
ytSearchFormat = format;
|
ytSearchFormat = format;
|
||||||
localStorage?.setString(LocalStorageKeys.ytSearchFormate, format);
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
updatePersistence();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAccentColorScheme(MaterialColor color) {
|
||||||
|
accentColorScheme = color;
|
||||||
|
notifyListeners();
|
||||||
|
updatePersistence();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBackgroundColorScheme(MaterialColor color) {
|
||||||
|
backgroundColorScheme = color;
|
||||||
|
notifyListeners();
|
||||||
|
updatePersistence();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
FutureOr<void> loadFromLocal(Map<String, dynamic> map) {
|
||||||
|
saveTrackLyrics = map["saveTrackLyrics"] ?? false;
|
||||||
|
recommendationMarket = map["recommendationMarket"] ?? recommendationMarket;
|
||||||
|
geniusAccessToken =
|
||||||
|
map["geniusAccessToken"] ?? getRandomElement(lyricsSecrets);
|
||||||
|
nextTrackHotKey = map["nextTrackHotKey"] != null
|
||||||
|
? HotKey.fromJson(jsonDecode(map["nextTrackHotKey"]))
|
||||||
|
: null;
|
||||||
|
prevTrackHotKey = map["prevTrackHotKey"] != null
|
||||||
|
? HotKey.fromJson(jsonDecode(map["prevTrackHotKey"]))
|
||||||
|
: null;
|
||||||
|
playPauseHotKey = map["playPauseHotKey"] != null
|
||||||
|
? HotKey.fromJson(jsonDecode(map["playPauseHotKey"]))
|
||||||
|
: null;
|
||||||
|
ytSearchFormat = map["ytSearchFormat"] ?? ytSearchFormat;
|
||||||
|
themeMode = ThemeMode.values[map["themeMode"] ?? 0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
FutureOr<Map<String, dynamic>> toMap() {
|
||||||
|
return {
|
||||||
|
"saveTrackLyrics": saveTrackLyrics,
|
||||||
|
"recommendationMarket": recommendationMarket,
|
||||||
|
"geniusAccessToken": geniusAccessToken,
|
||||||
|
"nextTrackHotKey": jsonEncode(nextTrackHotKey?.toJson() ?? {}),
|
||||||
|
"prevTrackHotKey": jsonEncode(prevTrackHotKey?.toJson() ?? {}),
|
||||||
|
"playPauseHotKey": jsonEncode(playPauseHotKey?.toJson() ?? {}),
|
||||||
|
"ytSearchFormat": ytSearchFormat,
|
||||||
|
"themeMode": themeMode.index,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
62
lib/themes/dark-theme.dart
Normal file
62
lib/themes/dark-theme.dart
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
ThemeData darkTheme({
|
||||||
|
MaterialColor accentMaterialColor = Colors.green,
|
||||||
|
MaterialColor backgroundMaterialColor = Colors.blueGrey,
|
||||||
|
}) {
|
||||||
|
return ThemeData(
|
||||||
|
useMaterial3: true,
|
||||||
|
brightness: Brightness.dark,
|
||||||
|
primaryColor: accentMaterialColor,
|
||||||
|
primarySwatch: accentMaterialColor,
|
||||||
|
backgroundColor: backgroundMaterialColor[900],
|
||||||
|
scaffoldBackgroundColor: backgroundMaterialColor[900],
|
||||||
|
dialogBackgroundColor: backgroundMaterialColor[800],
|
||||||
|
shadowColor: Colors.black26,
|
||||||
|
popupMenuTheme: PopupMenuThemeData(color: backgroundMaterialColor[800]),
|
||||||
|
buttonTheme: ButtonThemeData(
|
||||||
|
buttonColor: accentMaterialColor,
|
||||||
|
),
|
||||||
|
inputDecorationTheme: InputDecorationTheme(
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: accentMaterialColor[400]!,
|
||||||
|
width: 2.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: backgroundMaterialColor[800]!,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
navigationRailTheme: NavigationRailThemeData(
|
||||||
|
backgroundColor: backgroundMaterialColor[800],
|
||||||
|
unselectedIconTheme: IconThemeData(color: Colors.grey[300], opacity: 1),
|
||||||
|
selectedIconTheme: IconThemeData(color: backgroundMaterialColor[850]),
|
||||||
|
selectedLabelTextStyle: TextStyle(color: accentMaterialColor[300]),
|
||||||
|
unselectedLabelTextStyle: TextStyle(color: Colors.grey[300]),
|
||||||
|
indicatorColor: accentMaterialColor[300],
|
||||||
|
),
|
||||||
|
navigationBarTheme: NavigationBarThemeData(
|
||||||
|
backgroundColor: backgroundMaterialColor[800],
|
||||||
|
height: 55,
|
||||||
|
indicatorColor: accentMaterialColor[300],
|
||||||
|
),
|
||||||
|
cardTheme: CardTheme(
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
|
||||||
|
color: backgroundMaterialColor[900],
|
||||||
|
elevation: 20,
|
||||||
|
),
|
||||||
|
elevatedButtonTheme: ElevatedButtonThemeData(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
onPrimary: accentMaterialColor[300],
|
||||||
|
textStyle: const TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
cardColor: backgroundMaterialColor[800],
|
||||||
|
canvasColor: backgroundMaterialColor[900],
|
||||||
|
);
|
||||||
|
}
|
88
lib/themes/light-theme.dart
Normal file
88
lib/themes/light-theme.dart
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
final materialWhite = MaterialColor(Colors.white.value, {
|
||||||
|
50: Colors.white,
|
||||||
|
100: Colors.blueGrey[50]!,
|
||||||
|
200: Colors.white,
|
||||||
|
300: Colors.white,
|
||||||
|
400: Colors.white,
|
||||||
|
500: Colors.blueGrey,
|
||||||
|
600: Colors.white,
|
||||||
|
700: Colors.white,
|
||||||
|
800: Colors.white,
|
||||||
|
900: Colors.white,
|
||||||
|
});
|
||||||
|
|
||||||
|
ThemeData lightTheme({
|
||||||
|
MaterialColor accentMaterialColor = Colors.green,
|
||||||
|
MaterialColor? backgroundMaterialColor,
|
||||||
|
}) {
|
||||||
|
backgroundMaterialColor ??= materialWhite;
|
||||||
|
return ThemeData(
|
||||||
|
useMaterial3: true,
|
||||||
|
primaryColor: accentMaterialColor,
|
||||||
|
primarySwatch: accentMaterialColor,
|
||||||
|
buttonTheme: ButtonThemeData(
|
||||||
|
buttonColor: accentMaterialColor,
|
||||||
|
),
|
||||||
|
shadowColor: Colors.grey[300],
|
||||||
|
backgroundColor: backgroundMaterialColor[50],
|
||||||
|
textTheme: TextTheme(
|
||||||
|
bodyText1: TextStyle(color: Colors.grey[850]),
|
||||||
|
headline1: TextStyle(color: Colors.grey[850]),
|
||||||
|
headline2: TextStyle(color: Colors.grey[850]),
|
||||||
|
headline3: TextStyle(color: Colors.grey[850]),
|
||||||
|
headline4: TextStyle(color: Colors.grey[850]),
|
||||||
|
headline5: TextStyle(color: Colors.grey[850]),
|
||||||
|
headline6: TextStyle(color: Colors.grey[850]),
|
||||||
|
),
|
||||||
|
listTileTheme: ListTileThemeData(
|
||||||
|
iconColor: Colors.grey[850],
|
||||||
|
horizontalTitleGap: 0,
|
||||||
|
),
|
||||||
|
inputDecorationTheme: InputDecorationTheme(
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: accentMaterialColor[400]!,
|
||||||
|
width: 2.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: Colors.grey[800]!,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
navigationRailTheme: NavigationRailThemeData(
|
||||||
|
backgroundColor: backgroundMaterialColor[100],
|
||||||
|
indicatorColor: accentMaterialColor[300],
|
||||||
|
selectedIconTheme: IconThemeData(color: accentMaterialColor[850]),
|
||||||
|
unselectedIconTheme: IconThemeData(color: Colors.grey[850], opacity: 1),
|
||||||
|
unselectedLabelTextStyle: TextStyle(
|
||||||
|
color: Colors.grey[850],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
navigationBarTheme: NavigationBarThemeData(
|
||||||
|
backgroundColor: backgroundMaterialColor[100],
|
||||||
|
height: 55,
|
||||||
|
indicatorColor: accentMaterialColor[300],
|
||||||
|
iconTheme: MaterialStateProperty.all(
|
||||||
|
IconThemeData(color: Colors.grey[850]),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
cardTheme: CardTheme(
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
|
||||||
|
color: backgroundMaterialColor[50],
|
||||||
|
),
|
||||||
|
elevatedButtonTheme: ElevatedButtonThemeData(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
onPrimary: accentMaterialColor[800],
|
||||||
|
textStyle: const TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
cardColor: backgroundMaterialColor[50],
|
||||||
|
canvasColor: backgroundMaterialColor[50],
|
||||||
|
);
|
||||||
|
}
|
@ -14,13 +14,13 @@ abstract class PersistedChangeNotifier extends ChangeNotifier {
|
|||||||
.fold<Map<String, dynamic>>({}, (acc, entry) {
|
.fold<Map<String, dynamic>>({}, (acc, entry) {
|
||||||
if (entry.value != null) {
|
if (entry.value != null) {
|
||||||
if (entry.value is bool) {
|
if (entry.value is bool) {
|
||||||
acc[entry.key] = _localStorage.getBool(entry.key) ?? false;
|
acc[entry.key] = _localStorage.getBool(entry.key);
|
||||||
} else if (entry.value is int) {
|
} else if (entry.value is int) {
|
||||||
acc[entry.key] = _localStorage.getInt(entry.key) ?? -1;
|
acc[entry.key] = _localStorage.getInt(entry.key);
|
||||||
} else if (entry.value is double) {
|
} else if (entry.value is double) {
|
||||||
acc[entry.key] = _localStorage.getDouble(entry.key) ?? -1.0;
|
acc[entry.key] = _localStorage.getDouble(entry.key);
|
||||||
} else if (entry.value is String) {
|
} else if (entry.value is String) {
|
||||||
acc[entry.key] = _localStorage.getString(entry.key) ?? "";
|
acc[entry.key] = _localStorage.getString(entry.key);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
acc[entry.key] = _localStorage.get(entry.key);
|
acc[entry.key] = _localStorage.get(entry.key);
|
||||||
|
Loading…
Reference in New Issue
Block a user