tasq/lib/widgets/ios_install_prompt.dart

94 lines
2.9 KiB
Dart

import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'ios_install_prompt_stub.dart'
if (dart.library.html) 'ios_install_prompt_web.dart';
/// Wraps the app and shows a persistent banner on iOS Safari when the PWA has
/// not been added to the Home Screen.
///
/// Adding TasQ to the Home Screen is required to:
/// - Receive push notifications on iOS 16.4+
/// - Run in standalone (full-screen) mode without Safari chrome
///
/// The banner is dismissed permanently once the user taps "Got it".
class IosInstallPrompt extends StatefulWidget {
const IosInstallPrompt({required this.child, super.key});
final Widget child;
@override
State<IosInstallPrompt> createState() => _IosInstallPromptState();
}
class _IosInstallPromptState extends State<IosInstallPrompt> {
bool _showBanner = false;
static const _prefKey = 'ios_a2hs_prompt_dismissed_v1';
@override
void initState() {
super.initState();
if (kIsWeb) _checkShouldShow();
}
Future<void> _checkShouldShow() async {
if (!detectIosSafariNotInstalled()) return;
final prefs = await SharedPreferences.getInstance();
final dismissed = prefs.getBool(_prefKey) ?? false;
if (!dismissed && mounted) {
setState(() => _showBanner = true);
}
}
Future<void> _dismiss() async {
final prefs = await SharedPreferences.getInstance();
await prefs.setBool(_prefKey, true);
if (mounted) setState(() => _showBanner = false);
}
@override
Widget build(BuildContext context) {
if (!_showBanner) return widget.child;
final cs = Theme.of(context).colorScheme;
return Column(
children: [
Material(
color: cs.primaryContainer,
child: SafeArea(
bottom: false,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
child: Row(
children: [
Icon(Icons.ios_share, size: 20, color: cs.onPrimaryContainer),
const SizedBox(width: 12),
Expanded(
child: Text(
'Install TasQ: tap Share then "Add to Home Screen" '
'to enable push notifications.',
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: cs.onPrimaryContainer,
),
),
),
TextButton(
onPressed: _dismiss,
child: Text(
'Got it',
style: TextStyle(color: cs.onPrimaryContainer),
),
),
],
),
),
),
),
Expanded(child: widget.child),
],
);
}
}