1
1
import 'package:flutter/material.dart' ;
2
2
import 'package:shared_preferences/shared_preferences.dart' ;
3
+ import '../services/atcoder_service.dart' ;
4
+ import '../utils/atcoder_colors.dart' ;
3
5
4
6
const String _navOpacityKey = 'nav_opacity' ; // Key for bottom nav opacity
5
7
const String _useMaterialYouKey = 'use_material_you' ; // Key for Material You setting
6
8
const String _codeFontFamilyKey = 'code_font_family' ; // Key for code font family
7
9
const String _customCodeFontsKey = 'custom_code_fonts' ; // Key for custom code fonts list
10
+ const String _useAtcoderRatingColorKey = 'use_atcoder_rating_color' ; // Key for AtCoder accent option
8
11
9
12
// Built-in supported Google fonts and generic fallback
10
13
const List <String > defaultCodeFontFamilies = [
@@ -32,6 +35,8 @@ class ThemeProvider extends ChangeNotifier {
32
35
String _codeFontFamily = defaultCodeFontFamilies.first; // Default font
33
36
final List <String > _customCodeFonts = []; // User-added font family names (must be declared in pubspec)
34
37
bool _isLoading = true ;
38
+ bool _useAtcoderRatingColor = false ; // Default off
39
+ Color ? _atcoderAccentColor; // Resolved accent color based on rating
35
40
36
41
ThemeProvider () {
37
42
_loadFromPrefs ();
@@ -46,6 +51,12 @@ class ThemeProvider extends ChangeNotifier {
46
51
// Material Youを使用するかどうか
47
52
bool get useMaterialYou => _useMaterialYou;
48
53
54
+ // AtCoderレート色をアクセントとして使うか
55
+ bool get useAtcoderRatingColor => _useAtcoderRatingColor;
56
+
57
+ // 解決済みのアクセントカラー(nullの場合は未設定/無効)
58
+ Color ? get atcoderAccentColor => _atcoderAccentColor;
59
+
49
60
// Code block font family
50
61
String get codeFontFamily => _codeFontFamily;
51
62
@@ -74,6 +85,20 @@ class ThemeProvider extends ChangeNotifier {
74
85
notifyListeners ();
75
86
}
76
87
88
+ // AtCoderレート色の使用設定を変更
89
+ Future <void > setUseAtcoderRatingColor (bool use) async {
90
+ if (_useAtcoderRatingColor == use) return ;
91
+
92
+ _useAtcoderRatingColor = use;
93
+ await _saveToPrefs ();
94
+ if (use) {
95
+ await refreshAtcoderAccentColor ();
96
+ } else {
97
+ _atcoderAccentColor = null ;
98
+ notifyListeners ();
99
+ }
100
+ }
101
+
77
102
// Material Youの使用設定を変更
78
103
Future <void > setUseMaterialYou (bool use) async {
79
104
if (_useMaterialYou == use) return ;
@@ -131,6 +156,11 @@ class ThemeProvider extends ChangeNotifier {
131
156
if (savedUseMaterialYou != null ) {
132
157
_useMaterialYou = savedUseMaterialYou;
133
158
}
159
+ // Load AtCoder accent option
160
+ final savedUseAtcoder = prefs.getBool (_useAtcoderRatingColorKey);
161
+ if (savedUseAtcoder != null ) {
162
+ _useAtcoderRatingColor = savedUseAtcoder;
163
+ }
134
164
// Load code font family if exists
135
165
final savedFontFamily = prefs.getString (_codeFontFamilyKey);
136
166
// Load custom fonts list
@@ -150,6 +180,11 @@ class ThemeProvider extends ChangeNotifier {
150
180
_themeMode = ThemeModeOption .values[themeModeIndex];
151
181
}
152
182
183
+ // If using AtCoder accent, resolve it now
184
+ if (_useAtcoderRatingColor) {
185
+ await refreshAtcoderAccentColor ();
186
+ }
187
+
153
188
_isLoading = false ;
154
189
notifyListeners ();
155
190
}
@@ -161,6 +196,7 @@ class ThemeProvider extends ChangeNotifier {
161
196
await prefs.setBool (_useMaterialYouKey, _useMaterialYou); // Save Material You setting
162
197
await prefs.setString (_codeFontFamilyKey, _codeFontFamily); // Save font family
163
198
await prefs.setStringList (_customCodeFontsKey, _customCodeFonts); // Save custom fonts
199
+ await prefs.setBool (_useAtcoderRatingColorKey, _useAtcoderRatingColor); // Save AtCoder accent option
164
200
}
165
201
166
202
// Set bottom nav opacity and persist
@@ -170,6 +206,32 @@ class ThemeProvider extends ChangeNotifier {
170
206
await prefs.setDouble (_navOpacityKey, opacity);
171
207
notifyListeners ();
172
208
}
209
+
210
+ /// Fetch current user's AtCoder rating and resolve accent color.
211
+ /// Uses 'atcoder_username' from SharedPreferences. If missing or fetch fails,
212
+ /// falls back to null and leaves theme unchanged.
213
+ Future <void > refreshAtcoderAccentColor () async {
214
+ if (! _useAtcoderRatingColor) return ;
215
+ try {
216
+ final prefs = await SharedPreferences .getInstance ();
217
+ final username = prefs.getString ('atcoder_username' );
218
+ if (username == null || username.trim ().isEmpty) {
219
+ _atcoderAccentColor = null ;
220
+ notifyListeners ();
221
+ return ;
222
+ }
223
+ final service = AtCoderService ();
224
+ final rating = await service.fetchAtCoderRate (username.trim ());
225
+ if (rating == null ) {
226
+ _atcoderAccentColor = null ;
227
+ } else {
228
+ _atcoderAccentColor = atcoderRatingToColor (rating);
229
+ }
230
+ } catch (_) {
231
+ _atcoderAccentColor = null ;
232
+ }
233
+ notifyListeners ();
234
+ }
173
235
}
174
236
175
237
// テーマモードの選択肢
0 commit comments