TempoFlow/lib/pages/settings_page.dart

197 lines
5.6 KiB
Dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:share_plus/share_plus.dart';
import 'package:url_launcher/url_launcher.dart';
import '../theme/app_theme.dart';
import '../models/app_settings.dart';
import 'feedback_page.dart';
import 'about_page.dart';
class SettingsPage extends StatefulWidget {
const SettingsPage({super.key});
@override
State<SettingsPage> createState() => _SettingsPageState();
}
class _SettingsPageState extends State<SettingsPage> {
bool _haptics = AppSettings.enableHaptics;
bool _strict = AppSettings.strictMode;
void _onShare(BuildContext context) {
final box = context.findRenderObject() as RenderBox?;
Share.share(
'Check out Tempo - The minimalist flow state timer. \n\nGet it here: https://tempo.app',
subject: 'Invite to Tempo',
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
);
}
Future<void> _onPrivacy() async {
final Uri url = Uri.parse('https://policies.google.com/privacy?hl=en');
try {
if (!await launchUrl(url, mode: LaunchMode.externalApplication)) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("Could not open browser")),
);
}
}
} catch (e) {
debugPrint('Browser Error: $e');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppTheme.bgLight,
appBar: AppBar(
title: const Text("Settings"),
centerTitle: true,
backgroundColor: Colors.transparent,
),
body: ListView(
padding: const EdgeInsets.all(20),
children: [
_buildSettingsSection("PREFERENCES", [
_buildSettingsTile(
Icons.vibration,
"Haptic Feedback",
trailing: CupertinoSwitch(
activeColor: AppTheme.primary,
value: _haptics,
onChanged: (v) {
setState(() {
_haptics = v;
AppSettings.enableHaptics = v;
});
if (v) HapticFeedback.lightImpact();
},
),
),
_buildSettingsTile(
Icons.screen_rotation,
"Flip to Focus",
subtitle: "Strict Mode",
trailing: CupertinoSwitch(
activeColor: AppTheme.primary,
value: _strict,
onChanged: (v) {
setState(() {
_strict = v;
AppSettings.strictMode = v;
});
},
),
),
]),
_buildSettingsSection("GENERAL", [
_buildSettingsTile(
Icons.share_outlined,
"Share Tempo",
onTap: () => _onShare(context),
),
_buildSettingsTile(
Icons.mail_outline,
"Send Feedback",
onTap: () => Navigator.push(
context,
CupertinoPageRoute(builder: (_) => const FeedbackPage()),
),
),
_buildSettingsTile(
Icons.privacy_tip_outlined,
"Privacy Policy",
onTap: () => _onPrivacy(),
),
_buildSettingsTile(
Icons.info_outline,
"About",
onTap: () => Navigator.push(
context,
CupertinoPageRoute(builder: (_) => const AboutPage()),
),
),
]),
],
),
);
}
Widget _buildSettingsSection(String title, List<Widget> children) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(left: 12, bottom: 8, top: 20),
child: Text(
title,
style: TextStyle(
color: Colors.grey[600],
fontSize: 13,
fontWeight: FontWeight.w800,
letterSpacing: 1.2,
),
),
),
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 4),
)
],
),
child: Column(children: children),
)
],
);
}
Widget _buildSettingsTile(
IconData icon,
String title, {
String? subtitle,
Widget? trailing,
VoidCallback? onTap,
}) {
return ListTile(
onTap: onTap,
leading: Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: AppTheme.bgLight,
borderRadius: BorderRadius.circular(8),
),
child: Icon(icon, size: 20, color: AppTheme.primary),
),
title: Text(
title,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w700,
color: AppTheme.textMain,
),
),
subtitle: subtitle != null
? Text(
subtitle,
style: const TextStyle(
fontSize: 13,
color: AppTheme.textSub,
fontWeight: FontWeight.w500,
),
)
: null,
trailing: trailing ??
const Icon(Icons.chevron_right, size: 18, color: Colors.grey),
);
}
}