Initial commit
This commit is contained in:
@@ -0,0 +1,188 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'shared/settings_persistence.dart';
|
||||
|
||||
enum TmdbAuthMode { bearer, apiKey }
|
||||
|
||||
|
||||
enum TmdbAccessMode {
|
||||
|
||||
official,
|
||||
|
||||
|
||||
smAccount,
|
||||
}
|
||||
|
||||
class TmdbSettingsState {
|
||||
|
||||
static const officialApiBaseUrl = 'https://api.themoviedb.org/3';
|
||||
static const officialImageBaseUrl = 'https://image.tmdb.org/t/p';
|
||||
|
||||
|
||||
static const smAccountApiBaseUrl = 'https://your-server.example';
|
||||
|
||||
final bool enabled;
|
||||
final TmdbAccessMode accessMode;
|
||||
final TmdbAuthMode authMode;
|
||||
final String accessToken;
|
||||
final String apiKey;
|
||||
final String language;
|
||||
|
||||
const TmdbSettingsState({
|
||||
this.enabled = false,
|
||||
this.accessMode = TmdbAccessMode.official,
|
||||
this.authMode = TmdbAuthMode.apiKey,
|
||||
this.accessToken = '',
|
||||
this.apiKey = '',
|
||||
this.language = 'zh-CN',
|
||||
});
|
||||
|
||||
bool get isConfigured => switch (accessMode) {
|
||||
TmdbAccessMode.smAccount => true,
|
||||
TmdbAccessMode.official => switch (authMode) {
|
||||
TmdbAuthMode.bearer => accessToken.isNotEmpty,
|
||||
TmdbAuthMode.apiKey => apiKey.isNotEmpty,
|
||||
},
|
||||
};
|
||||
|
||||
bool get canRequest => enabled && isConfigured;
|
||||
|
||||
|
||||
bool canRequestWithAccount({required bool dataPlaneReady}) =>
|
||||
switch (accessMode) {
|
||||
TmdbAccessMode.official => canRequest,
|
||||
TmdbAccessMode.smAccount => enabled && dataPlaneReady,
|
||||
};
|
||||
|
||||
String get effectiveApiBaseUrl => switch (accessMode) {
|
||||
TmdbAccessMode.smAccount => smAccountApiBaseUrl,
|
||||
TmdbAccessMode.official => officialApiBaseUrl,
|
||||
};
|
||||
|
||||
|
||||
String get effectiveImageBaseUrl => officialImageBaseUrl;
|
||||
|
||||
String get effectiveAccessToken =>
|
||||
accessMode == TmdbAccessMode.official && authMode == TmdbAuthMode.bearer
|
||||
? accessToken
|
||||
: '';
|
||||
|
||||
String get effectiveApiKey =>
|
||||
accessMode == TmdbAccessMode.official && authMode == TmdbAuthMode.apiKey
|
||||
? apiKey
|
||||
: '';
|
||||
|
||||
TmdbSettingsState copyWith({
|
||||
bool? enabled,
|
||||
TmdbAccessMode? accessMode,
|
||||
TmdbAuthMode? authMode,
|
||||
String? accessToken,
|
||||
String? apiKey,
|
||||
String? language,
|
||||
}) => TmdbSettingsState(
|
||||
enabled: enabled ?? this.enabled,
|
||||
accessMode: accessMode ?? this.accessMode,
|
||||
authMode: authMode ?? this.authMode,
|
||||
accessToken: accessToken ?? this.accessToken,
|
||||
apiKey: apiKey ?? this.apiKey,
|
||||
language: language ?? this.language,
|
||||
);
|
||||
}
|
||||
|
||||
class TmdbSettingsNotifier extends AsyncNotifier<TmdbSettingsState>
|
||||
with SettingsPersistence {
|
||||
static const _keyEnabled = 'smplayer.tmdb_enabled';
|
||||
static const _keyAccessMode = 'smplayer.tmdb_access_mode';
|
||||
static const _keyAuthMode = 'smplayer.tmdb_auth_mode';
|
||||
static const _keyAccessToken = 'smplayer.tmdb_access_token';
|
||||
static const _keyApiKey = 'smplayer.tmdb_api_key';
|
||||
static const _keyLanguage = 'smplayer.tmdb_language';
|
||||
|
||||
@override
|
||||
Future<TmdbSettingsState> build() async {
|
||||
final prefs = await getPrefs();
|
||||
final accessToken = prefs.getString(_keyAccessToken)?.trim() ?? '';
|
||||
final apiKey = prefs.getString(_keyApiKey)?.trim() ?? '';
|
||||
return TmdbSettingsState(
|
||||
enabled: prefs.getBool(_keyEnabled) ?? false,
|
||||
accessMode: _parseAccessMode(prefs.getString(_keyAccessMode)),
|
||||
authMode: _parseAuthMode(
|
||||
prefs.getString(_keyAuthMode),
|
||||
hasLegacyAccessToken: accessToken.isNotEmpty,
|
||||
),
|
||||
accessToken: accessToken,
|
||||
apiKey: apiKey,
|
||||
language: prefs.getString(_keyLanguage) ?? 'zh-CN',
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> setEnabled(bool v) async {
|
||||
final current = state.value ?? const TmdbSettingsState();
|
||||
state = AsyncValue.data(current.copyWith(enabled: v));
|
||||
await persistField(_keyEnabled, v);
|
||||
}
|
||||
|
||||
Future<void> setAccessMode(TmdbAccessMode mode) async {
|
||||
final current = state.value ?? const TmdbSettingsState();
|
||||
state = AsyncValue.data(current.copyWith(accessMode: mode));
|
||||
await persistField(_keyAccessMode, mode.name);
|
||||
}
|
||||
|
||||
Future<void> enableSmAccountProxy() async {
|
||||
final current = state.value ?? await future;
|
||||
state = AsyncValue.data(
|
||||
current.copyWith(enabled: true, accessMode: TmdbAccessMode.smAccount),
|
||||
);
|
||||
await persistFields(<String, dynamic>{
|
||||
_keyEnabled: true,
|
||||
_keyAccessMode: TmdbAccessMode.smAccount.name,
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> setAuthMode(TmdbAuthMode mode) async {
|
||||
final current = state.value ?? const TmdbSettingsState();
|
||||
state = AsyncValue.data(current.copyWith(authMode: mode));
|
||||
await persistField(_keyAuthMode, mode.name);
|
||||
}
|
||||
|
||||
Future<void> setAccessToken(String token) async {
|
||||
final trimmed = token.trim();
|
||||
final current = state.value ?? const TmdbSettingsState();
|
||||
state = AsyncValue.data(current.copyWith(accessToken: trimmed));
|
||||
await persistField(_keyAccessToken, trimmed);
|
||||
}
|
||||
|
||||
Future<void> setApiKey(String key) async {
|
||||
final trimmed = key.trim();
|
||||
final current = state.value ?? const TmdbSettingsState();
|
||||
state = AsyncValue.data(current.copyWith(apiKey: trimmed));
|
||||
await persistField(_keyApiKey, trimmed);
|
||||
}
|
||||
|
||||
Future<void> setLanguage(String lang) async {
|
||||
final current = state.value ?? const TmdbSettingsState();
|
||||
state = AsyncValue.data(current.copyWith(language: lang));
|
||||
await persistField(_keyLanguage, lang);
|
||||
}
|
||||
}
|
||||
|
||||
final tmdbSettingsProvider =
|
||||
AsyncNotifierProvider<TmdbSettingsNotifier, TmdbSettingsState>(
|
||||
TmdbSettingsNotifier.new,
|
||||
);
|
||||
|
||||
TmdbAccessMode _parseAccessMode(String? value) => TmdbAccessMode.values
|
||||
.firstWhere((m) => m.name == value, orElse: () => TmdbAccessMode.official);
|
||||
|
||||
TmdbAuthMode _parseAuthMode(
|
||||
String? value, {
|
||||
bool hasLegacyAccessToken = false,
|
||||
}) {
|
||||
if (value == null && hasLegacyAccessToken) {
|
||||
return TmdbAuthMode.bearer;
|
||||
}
|
||||
return TmdbAuthMode.values.firstWhere(
|
||||
(mode) => mode.name == value,
|
||||
orElse: () => TmdbAuthMode.apiKey,
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user