Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 3 additions & 10 deletions integration_test/helpers/test_app_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,11 @@ class TestAppHelper {
///
/// [tester] - The WidgetTester instance from the test.
/// [prefValues] - Optional initial SharedPreferences values.
/// [additionalOverrides] - Optional additional Riverpod provider overrides.
/// [settleDuration] - Duration to wait for app to settle (default 5 seconds).

static Future<void> initializeApp(
WidgetTester tester, {
Map<String, Object>? prefValues,
List<Override>? additionalOverrides,
Duration settleDuration = const Duration(seconds: 5),
}) async {
// Set up SharedPreferences with test values.
Expand All @@ -55,18 +53,13 @@ class TestAppHelper {

await initializeHive();

// Build provider overrides list.

final overrides = <Override>[
sharedPreferencesProvider.overrideWithValue(prefs),
if (additionalOverrides != null) ...additionalOverrides,
];

// Pump the app with ProviderScope.

await tester.pumpWidget(
ProviderScope(
overrides: overrides,
overrides: [
sharedPreferencesProvider.overrideWithValue(prefs),
],
child: const MovieStar(),
),
);
Expand Down
2 changes: 1 addition & 1 deletion lib/my_home_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class _MyHomePageState extends ConsumerState<MyHomePage> {
// Set the service in the provider after widget tree is done building.

Future(() {
ref.read(apiKeyServiceProvider.notifier).state = _apiKeyService;
ref.read(apiKeyServiceProvider.notifier).setService(_apiKeyService);
});

// Listen for API key changes.
Expand Down
60 changes: 11 additions & 49 deletions lib/providers/cached_movie_service_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,9 @@ library;
import 'package:flutter_riverpod/flutter_riverpod.dart';

import 'package:moviestar/core/services/api/content_service.dart';
import 'package:moviestar/core/services/api/key_service.dart';
import 'package:moviestar/core/services/api/movie_service.dart';
import 'package:moviestar/core/services/cache/cached_movie_service.dart';
import 'package:moviestar/core/services/cache/hive_movie_cache_service.dart';
import 'package:moviestar/core/services/cache/settings_service.dart';
import 'package:moviestar/providers/cached_movie_service_provider/direct_movie_service.dart';
import 'package:moviestar/providers/cached_movie_service_provider/state_notifiers.dart';

Expand All @@ -42,17 +40,6 @@ export 'package:moviestar/providers/cached_movie_service_provider/direct_movie_s
export 'package:moviestar/providers/cached_movie_service_provider/provider_definitions.dart';
export 'package:moviestar/providers/cached_movie_service_provider/state_notifiers.dart';

/// Provider for the API key service.
/// Note: This should be overridden with a proper instance from MyHomePage.
/// Use ProviderScope.overrideWithValue() to provide the actual service instance.

final apiKeyServiceProvider = StateProvider<ApiKeyService?>((ref) {
// This will be set by MyHomePage with the actual service instance.
// If not set, it returns null.

return null;
});

/// Direct API key provider - deprecated, returns null to force use of ApiKeyService.
/// API keys are now stored in POD only, which requires ApiKeyService for access.

Expand All @@ -66,12 +53,8 @@ final directApiKeyProvider = FutureProvider<String?>((ref) async {

/// Provider for the API key state that watches for changes.

final apiKeyProvider = StateNotifierProvider<ApiKeyNotifier, String?>(
(ref) {
final apiKeyService = ref.watch(apiKeyServiceProvider);
return ApiKeyNotifier(apiKeyService);
},
dependencies: [apiKeyServiceProvider],
final apiKeyProvider = NotifierProvider<ApiKeyNotifier, String?>(
ApiKeyNotifier.new,
);

/// FutureProvider that waits for the API key to be loaded.
Expand All @@ -85,7 +68,6 @@ final apiKeyFutureProvider = FutureProvider<String?>(
final apiKey = await apiKeyService.getApiKey();
return apiKey;
},
dependencies: [apiKeyServiceProvider],
);

/// Provider for the movie service using API key from POD.
Expand All @@ -108,10 +90,6 @@ final movieServiceProvider = Provider.autoDispose<MovieService>(

return movieService;
},
dependencies: [
apiKeyProvider,
apiKeyServiceProvider,
],
);

/// Provider for the content service (handles both movies and TV shows).
Expand Down Expand Up @@ -189,35 +167,24 @@ final cachedMovieServiceProvider = Provider<CachedMovieService>((ref) {
return cachedService;
});

/// Provider for the cache settings service.

final cacheSettingsServiceProvider = Provider<CacheSettingsService>((ref) {
return CacheSettingsService.instance;
});

/// Provider for offline mode state with persistence.

final cacheOnlyModeProvider =
StateNotifierProvider<CacheOnlyModeNotifier, bool>((ref) {
final settingsService = ref.watch(cacheSettingsServiceProvider);
return CacheOnlyModeNotifier(settingsService);
});
final cacheOnlyModeProvider = NotifierProvider<CacheOnlyModeNotifier, bool>(
CacheOnlyModeNotifier.new,
);

/// Provider for caching enabled state with persistence.

final cachingEnabledProvider =
StateNotifierProvider<CachingEnabledNotifier, bool>((ref) {
final settingsService = ref.watch(cacheSettingsServiceProvider);
return CachingEnabledNotifier(settingsService);
});
final cachingEnabledProvider = NotifierProvider<CachingEnabledNotifier, bool>(
CachingEnabledNotifier.new,
);

/// Provider for local API key caching state with persistence.

final localApiKeyCachingProvider =
StateNotifierProvider<LocalApiKeyCachingNotifier, bool>((ref) {
final settingsService = ref.watch(cacheSettingsServiceProvider);
return LocalApiKeyCachingNotifier(settingsService);
});
NotifierProvider<LocalApiKeyCachingNotifier, bool>(
LocalApiKeyCachingNotifier.new,
);

/// Provider for configured cached movie service (with settings).

Expand All @@ -244,9 +211,4 @@ final configuredCachedMovieServiceProvider =

return cachedService;
},
dependencies: [
movieServiceProvider,
apiKeyProvider,
apiKeyServiceProvider,
],
);
92 changes: 59 additions & 33 deletions lib/providers/cached_movie_service_provider/state_notifiers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,113 +13,139 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:moviestar/core/services/api/key_service.dart';
import 'package:moviestar/core/services/cache/settings_service.dart';

/// StateNotifier for managing caching enabled setting with persistence.
/// Notifier for managing caching enabled setting with persistence.

class CachingEnabledNotifier extends StateNotifier<bool> {
final CacheSettingsService _settingsService;

CachingEnabledNotifier(this._settingsService) : super(true) {
class CachingEnabledNotifier extends Notifier<bool> {
@override
bool build() {
_init();
return true;
}

CacheSettingsService get _settingsService =>
ref.read(cacheSettingsServiceProvider);

Future<void> _init() async {
await _settingsService.initialize();
if (!mounted) return;
state = _settingsService.cachingEnabled;
}

Future<void> setCachingEnabled(bool enabled) async {
await _settingsService.setCachingEnabled(enabled);
if (!mounted) return;
state = enabled;
}
}

/// StateNotifier for managing offline mode setting with persistence.
/// Provider for cache settings service.

final cacheSettingsServiceProvider = Provider<CacheSettingsService>((ref) {
return CacheSettingsService.instance;
});

class CacheOnlyModeNotifier extends StateNotifier<bool> {
final CacheSettingsService _settingsService;
/// Notifier for managing offline mode setting with persistence.

CacheOnlyModeNotifier(this._settingsService) : super(false) {
class CacheOnlyModeNotifier extends Notifier<bool> {
@override
bool build() {
_init();
return false;
}

CacheSettingsService get _settingsService =>
ref.read(cacheSettingsServiceProvider);

Future<void> _init() async {
await _settingsService.initialize();
if (!mounted) return;
state = _settingsService.cacheOnlyMode;
}

Future<void> setCacheOnlyMode(bool enabled) async {
await _settingsService.setCacheOnlyMode(enabled);
if (!mounted) return;
state = enabled;
}
}

/// StateNotifier for managing API key state and changes.
/// Notifier for managing API key state and changes.

class ApiKeyNotifier extends StateNotifier<String?> {
final ApiKeyService? _apiKeyService;
class ApiKeyNotifier extends Notifier<String?> {
ApiKeyService? _apiKeyService;

ApiKeyNotifier(this._apiKeyService) : super(null) {
@override
String? build() {
_apiKeyService = ref.watch(apiKeyServiceProvider);
if (_apiKeyService != null) {
_init();

// Listen for API key changes.

_apiKeyService.addListener(_onApiKeyChanged);
_apiKeyService!.addListener(_onApiKeyChanged);
ref.onDispose(() {
_apiKeyService?.removeListener(_onApiKeyChanged);
});
}
return null;
}

Future<void> _init() async {
if (_apiKeyService == null) {
return;
}
try {
final apiKey = await _apiKeyService.getApiKey();
if (!mounted) return;
final apiKey = await _apiKeyService!.getApiKey();
state = apiKey;
} catch (e) {
// Failed to get API key.
}
}

void _onApiKeyChanged() async {
if (!mounted || _apiKeyService == null) return;
if (_apiKeyService == null) return;
try {
final apiKey = await _apiKeyService.getApiKey();
if (!mounted) return;
final apiKey = await _apiKeyService!.getApiKey();
state = apiKey;
} catch (e) {
if (mounted) {}
// Failed to update API key.
}
}
}

/// Notifier for managing the API key service instance.

class ApiKeyServiceNotifier extends Notifier<ApiKeyService?> {
@override
void dispose() {
_apiKeyService?.removeListener(_onApiKeyChanged);
super.dispose();
ApiKeyService? build() => null;

void setService(ApiKeyService? service) {
state = service;
}
}

/// StateNotifier for managing local API key caching setting with persistence.
/// Provider for the API key service.

class LocalApiKeyCachingNotifier extends StateNotifier<bool> {
final CacheSettingsService _settingsService;
final apiKeyServiceProvider =
NotifierProvider<ApiKeyServiceNotifier, ApiKeyService?>(
ApiKeyServiceNotifier.new,
);

LocalApiKeyCachingNotifier(this._settingsService) : super(false) {
/// Notifier for managing local API key caching setting with persistence.

class LocalApiKeyCachingNotifier extends Notifier<bool> {
@override
bool build() {
_init();
return false;
}

CacheSettingsService get _settingsService =>
ref.read(cacheSettingsServiceProvider);

Future<void> _init() async {
await _settingsService.initialize();
if (!mounted) return;
state = _settingsService.localApiKeyCachingEnabled;
}

Future<void> setLocalApiKeyCachingEnabled(bool enabled) async {
await _settingsService.setLocalApiKeyCachingEnabled(enabled);
if (!mounted) return;
state = enabled;
}
}
15 changes: 8 additions & 7 deletions lib/providers/view_mode_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,15 @@ enum HomeViewMode {
}
}

/// StateNotifier for managing view mode state with persistence.
/// Notifier for managing view mode state with persistence.

class ViewModeNotifier extends StateNotifier<HomeViewMode> {
class ViewModeNotifier extends Notifier<HomeViewMode> {
static const String _key = 'home_view_mode';

ViewModeNotifier() : super(HomeViewMode.kanban) {
@override
HomeViewMode build() {
_loadViewMode();
return HomeViewMode.kanban;
}

// Load the view mode from shared preferences.
Expand Down Expand Up @@ -101,7 +103,6 @@ class ViewModeNotifier extends StateNotifier<HomeViewMode> {

/// Provider for the view mode state.

final viewModeProvider =
StateNotifierProvider<ViewModeNotifier, HomeViewMode>((ref) {
return ViewModeNotifier();
});
final viewModeProvider = NotifierProvider<ViewModeNotifier, HomeViewMode>(
ViewModeNotifier.new,
);
15 changes: 14 additions & 1 deletion lib/utils/create_solid_login.dart
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,19 @@ class _ApiKeyCheckWrapperState extends State<ApiKeyCheckWrapper> {
}
}

// Notifier for server URL state.

class ServerURLNotifier extends Notifier<String> {
@override
String build() => '';

void setServerURL(String url) {
state = url;
}
}

// Define provider for server URL.

final serverURLProvider = StateProvider<String>((ref) => '');
final serverURLProvider = NotifierProvider<ServerURLNotifier, String>(
ServerURLNotifier.new,
);
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ dependencies:
hive_flutter: ^1.1.0
flutter:
sdk: flutter
flutter_riverpod: 2.6.1
flutter_riverpod: ^3.1.0
flutter_secure_storage: ^10.0.0-beta.4
gap: ^3.0.1
http: ^1.1.0
Expand Down
Loading