This repository has been archived on 2026-06-02. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
FabledApp/lib/providers/settings_provider.dart
T
bvandeusen aba0ca6256 feat: gate News tab and briefing news cards on server rss_enabled setting
Fetch server-side settings on app launch via new serverSettingsProvider.
Hide News from bottom sheet and NavigationRail when RSS is disabled.
Skip news card rendering in briefing messages when disabled.
Refactor tab navigation to use dynamic tabs list and route-based refresh.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 14:29:05 -04:00

116 lines
3.3 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'api_client_provider.dart';
const _kServerUrl = 'server_url';
const _kThemeMode = 'theme_mode';
const _kForgejoRepoUrl = 'forgejo_repo_url';
final sharedPreferencesProvider = Provider<SharedPreferences>((ref) {
throw UnimplementedError('Override in ProviderScope');
});
final cookiesPathProvider = Provider<String>((ref) {
throw UnimplementedError('Override in ProviderScope');
});
final themeModeProvider =
NotifierProvider<ThemeModeNotifier, ThemeMode>(ThemeModeNotifier.new);
class ThemeModeNotifier extends Notifier<ThemeMode> {
@override
ThemeMode build() {
final prefs = ref.watch(sharedPreferencesProvider);
return _fromString(prefs.getString(_kThemeMode));
}
static ThemeMode _fromString(String? value) => switch (value) {
'light' => ThemeMode.light,
'dark' => ThemeMode.dark,
_ => ThemeMode.system,
};
Future<void> setMode(ThemeMode mode) async {
final value = switch (mode) {
ThemeMode.light => 'light',
ThemeMode.dark => 'dark',
_ => 'system',
};
await ref.read(sharedPreferencesProvider).setString(_kThemeMode, value);
state = mode;
}
}
final forgejoRepoUrlProvider =
NotifierProvider<ForgejoRepoUrlNotifier, String?>(
ForgejoRepoUrlNotifier.new);
class ForgejoRepoUrlNotifier extends Notifier<String?> {
@override
String? build() {
final prefs = ref.watch(sharedPreferencesProvider);
return prefs.getString(_kForgejoRepoUrl) ??
'https://git.fabledsword.com/bvandeusen/FabledApp';
}
Future<void> setUrl(String url) async {
final clean = url.endsWith('/') ? url.substring(0, url.length - 1) : url;
await ref.read(sharedPreferencesProvider).setString(_kForgejoRepoUrl, clean);
state = clean;
}
}
final serverUrlProvider =
NotifierProvider<ServerUrlNotifier, String?>(ServerUrlNotifier.new);
class ServerUrlNotifier extends Notifier<String?> {
@override
String? build() {
final prefs = ref.watch(sharedPreferencesProvider);
return prefs.getString(_kServerUrl);
}
Future<void> setUrl(String url) async {
// Strip trailing slash
final clean = url.endsWith('/') ? url.substring(0, url.length - 1) : url;
await ref.read(sharedPreferencesProvider).setString(_kServerUrl, clean);
state = clean;
}
Future<void> clear() async {
await ref.read(sharedPreferencesProvider).remove(_kServerUrl);
state = null;
}
}
final serverSettingsProvider =
AsyncNotifierProvider<ServerSettingsNotifier, Map<String, dynamic>>(
ServerSettingsNotifier.new);
class ServerSettingsNotifier extends AsyncNotifier<Map<String, dynamic>> {
@override
Future<Map<String, dynamic>> build() async {
try {
return await ref.read(settingsApiProvider).getAll();
} catch (_) {
return {};
}
}
bool get rssEnabled {
final data = state.value ?? {};
return data['rss_enabled']?.toString().toLowerCase() == 'true';
}
Future<void> refresh() async {
state = AsyncData(await ref.read(settingsApiProvider).getAll());
}
}
final rssEnabledProvider = Provider<bool>((ref) {
final settings = ref.watch(serverSettingsProvider).value ?? {};
return settings['rss_enabled']?.toString().toLowerCase() == 'true';
});