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

57 lines
2.1 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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,
);
});