import 'dart:async'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../services/license_service.dart'; /// 起動時にキャッシュから事前ロードした値を保持するプロバイダー /// /// main() で override して初期値を渡すことで、 /// licenseStatusProvider が loading 状態を経由せず即座に AsyncData になる。 final licenseInitialStatusProvider = Provider((ref) => null); /// ライセンス状態プロバイダー /// /// - build() は licenseInitialStatusProvider に値がある場合は同期で返す(ちらつきなし) /// - 同時にバックグラウンドでサーバー検証を実行し、差異があれば状態を更新する final licenseStatusProvider = AsyncNotifierProvider( LicenseStatusNotifier.new, ); class LicenseStatusNotifier extends AsyncNotifier { @override FutureOr build() { final initial = ref.read(licenseInitialStatusProvider); if (initial != null) { // キャッシュ値を同期で返すことで loading 状態をスキップ _refreshFromServer(); return initial; } // override なし(テスト等): 通常フロー return LicenseService.checkStatus(); } /// バックグラウンドでサーバー検証を実行し、変化があれば状態を更新する Future _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((ref) { final statusAsync = ref.watch(licenseStatusProvider); return statusAsync.maybeWhen( data: (status) => status == LicenseStatus.pro, orElse: () => false, ); });