ponshu-room-lite/lib/providers/license_provider.dart

57 lines
2.1 KiB
Dart
Raw Normal View History

import 'dart:async';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../services/license_service.dart';
/// 起動時にキャッシュから事前ロードした値を保持するプロバイダー
///
/// main() で override して初期値を渡すことで、
/// licenseStatusProvider が loading 状態を経由せず即座に AsyncData になる。
final licenseInitialStatusProvider = Provider<LicenseStatus?>((ref) => null);
/// ライセンス状態プロバイダー
///
/// - build() は licenseInitialStatusProvider に値がある場合は同期で返す(ちらつきなし)
/// - 同時にバックグラウンドでサーバー検証を実行し、差異があれば状態を更新する
final licenseStatusProvider =
AsyncNotifierProvider<LicenseStatusNotifier, LicenseStatus>(
LicenseStatusNotifier.new,
);
class LicenseStatusNotifier extends AsyncNotifier<LicenseStatus> {
@override
FutureOr<LicenseStatus> build() {
final initial = ref.read(licenseInitialStatusProvider);
if (initial != null) {
// キャッシュ値を同期で返すことで loading 状態をスキップ
_refreshFromServer();
return initial;
}
// override なし(テスト等): 通常フロー
return LicenseService.checkStatus();
}
/// バックグラウンドでサーバー検証を実行し、変化があれば状態を更新する
Future<void> _refreshFromServer() async {
try {
final fresh = await LicenseService.checkStatus();
if (state.hasValue && state.value != fresh) {
state = AsyncData(fresh);
}
} catch (_) {
// ネットワークエラーはキャッシュ値を維持
}
}
}
/// Pro版かどうかナビゲーション・機能解放の分岐に使う
///
/// licenseStatusProvider が同期で AsyncData を返すため、
/// アプリ起動時に false をちらつかせることなく正しい値を返す。
final isProProvider = Provider<bool>((ref) {
final statusAsync = ref.watch(licenseStatusProvider);
return statusAsync.maybeWhen(
data: (status) => status == LicenseStatus.pro,
orElse: () => false,
);
});