8b5bbd9531
The developer is an individual without a Korean business registration, so the App Store / Play paid-apps (merchant) agreements can't be completed. Hide the Remove Ads + Restore tiles and skip IAP init; ads always show. AdMob revenue is independent of those agreements. Reversible: flip kIapEnabled to re-enable once a merchant agreement exists. Bump to build 2; drop the now-unused IAP review-screenshot generator. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
76 lines
2.5 KiB
Dart
76 lines
2.5 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
|
import 'core/feature_flags.dart';
|
|
import 'l10n/gen/app_localizations.dart';
|
|
import 'state/providers.dart';
|
|
import 'ui/screens/splash_screen.dart';
|
|
|
|
class BlockSeasonsApp extends ConsumerStatefulWidget {
|
|
const BlockSeasonsApp({super.key});
|
|
|
|
@override
|
|
ConsumerState<BlockSeasonsApp> createState() => _BlockSeasonsAppState();
|
|
}
|
|
|
|
class _BlockSeasonsAppState extends ConsumerState<BlockSeasonsApp>
|
|
with WidgetsBindingObserver {
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
WidgetsBinding.instance.addObserver(this);
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
ref.read(consentServiceProvider).ensureConsentAndInitialize();
|
|
// Eagerly start the IAP service so its purchase stream is live for the
|
|
// whole session — restores and interrupted/deferred transactions are
|
|
// delivered (and completed) even if the player never opens Settings.
|
|
if (kIapEnabled) ref.read(iapServiceProvider);
|
|
// Start background music for the current context (menu by default).
|
|
ref.read(musicServiceProvider).playKey(ref.read(activeThemeProvider).bgm);
|
|
});
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
WidgetsBinding.instance.removeObserver(this);
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
void didChangeAppLifecycleState(AppLifecycleState state) {
|
|
// Pause music while the app is not in the foreground.
|
|
ref
|
|
.read(musicServiceProvider)
|
|
.setBackgrounded(state != AppLifecycleState.resumed);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
// Switch the looping track whenever the active season theme changes
|
|
// (home/menu -> a season -> back). playKey is a no-op if unchanged.
|
|
ref.listen(activeThemeProvider, (_, next) {
|
|
ref.read(musicServiceProvider).playKey(next.bgm);
|
|
});
|
|
return MaterialApp(
|
|
onGenerateTitle: (context) => AppLocalizations.of(context)!.appTitle,
|
|
debugShowCheckedModeBanner: false,
|
|
localizationsDelegates: const [
|
|
AppLocalizations.delegate,
|
|
GlobalMaterialLocalizations.delegate,
|
|
GlobalWidgetsLocalizations.delegate,
|
|
GlobalCupertinoLocalizations.delegate,
|
|
],
|
|
supportedLocales: const [Locale('en'), Locale('ko')],
|
|
theme: ThemeData(
|
|
colorScheme: ColorScheme.fromSeed(
|
|
seedColor: const Color(0xFF5B7FFF),
|
|
brightness: Brightness.dark,
|
|
),
|
|
useMaterial3: true,
|
|
),
|
|
home: const SplashScreen(),
|
|
);
|
|
}
|
|
}
|