Files
BlockSeasons/lib/app.dart
T
airkjw 8b5bbd9531 feat: ship ad-supported only — gate Remove Ads IAP behind kIapEnabled=false
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>
2026-06-15 11:55:48 +09:00

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