A whole lot of stuff
This commit is contained in:
parent
faf319322a
commit
ad850d2be6
50 changed files with 3013 additions and 213 deletions
|
|
@ -3,6 +3,7 @@ import 'package:flutter/services.dart';
|
|||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../services/app_state.dart';
|
||||
import 'faq_screen.dart';
|
||||
|
||||
/// The very first thing shown on a fresh install — before the onboarding
|
||||
/// tour, before anything else — gating [MainShell] entirely until the user
|
||||
|
|
@ -11,16 +12,32 @@ import '../services/app_state.dart';
|
|||
/// Its whole purpose is the liability section below: this app stores data
|
||||
/// on the user's own device (and, optionally, their own cloud storage
|
||||
/// account) with no server or backend of ours involved, so we have no
|
||||
/// ability to recover anything for them if it's lost.
|
||||
/// ability to recover anything for them if it's lost — plus the privacy
|
||||
/// section, disclosing that we don't track/log anything ourselves, and
|
||||
/// that AdMob (only active for users on the free, ad-supported tier) is
|
||||
/// the sole source of any data collection, governed by Google's own
|
||||
/// practices rather than anything this app adds.
|
||||
class UserAgreementScreen extends StatelessWidget {
|
||||
const UserAgreementScreen({super.key});
|
||||
/// True when reached from Settings (see [SettingsScreen]) to re-read the
|
||||
/// agreement/privacy policy at any time — required so this content stays
|
||||
/// reachable in the app beyond the one-time first-launch gate, not just
|
||||
/// something a user saw once and can never get back to. Hides the
|
||||
/// Decline/I Agree actions (already answered, and "Decline" quitting the
|
||||
/// app would be a bizarre side effect of just re-reading this) and shows
|
||||
/// a normal back button instead of gating navigation away entirely.
|
||||
final bool isReview;
|
||||
|
||||
const UserAgreementScreen({super.key, this.isReview = false});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final textTheme = Theme.of(context).textTheme;
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('User Agreement'), automaticallyImplyLeading: false),
|
||||
appBar: AppBar(
|
||||
title: const Text('User Agreement'),
|
||||
automaticallyImplyLeading: isReview,
|
||||
),
|
||||
body: SafeArea(
|
||||
child: Column(
|
||||
children: [
|
||||
|
|
@ -29,8 +46,11 @@ class UserAgreementScreen extends StatelessWidget {
|
|||
padding: const EdgeInsets.all(20),
|
||||
children: [
|
||||
Text(
|
||||
'Please read and accept the following before using Show Me The Fuel '
|
||||
'Refund.',
|
||||
isReview
|
||||
? 'This is the agreement you accepted when you first opened Show Me '
|
||||
'The Fuel Refund.'
|
||||
: 'Please read and accept the following before using Show Me The Fuel '
|
||||
'Refund.',
|
||||
style: textTheme.bodyLarge,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
|
|
@ -43,6 +63,17 @@ class UserAgreementScreen extends StatelessWidget {
|
|||
'also kept there — in storage you control, not on any server we run. '
|
||||
"We don't operate a backend, and we don't have a copy of your data.",
|
||||
),
|
||||
_Section(
|
||||
title: 'Privacy',
|
||||
body:
|
||||
"We don't track or log your data in any way — there's no analytics, no "
|
||||
"crash reporting, and no server of ours receiving anything you enter. If "
|
||||
'you haven\'t purchased "Remove Ads for a Year" and are using the free, '
|
||||
'ad-supported version, the only data collected is whatever Google AdMob '
|
||||
'itself requires to serve ads (e.g. a device advertising identifier) — '
|
||||
"that collection is Google's, governed by its own privacy practices, not "
|
||||
'something this app adds on top of.',
|
||||
),
|
||||
_Section(
|
||||
title: 'We Are Not Responsible for Your Data or Any Data Loss',
|
||||
body:
|
||||
|
|
@ -66,37 +97,55 @@ class UserAgreementScreen extends StatelessWidget {
|
|||
_Section(
|
||||
title: 'Not Tax or Legal Advice',
|
||||
body:
|
||||
"This app helps you organize receipts for Missouri's Motor Fuel Tax "
|
||||
'Refund program; it does not provide tax or legal advice, and does not '
|
||||
'guarantee your eligibility for any refund. The program itself is set '
|
||||
'by Missouri law, which can change at any time — always confirm current '
|
||||
'eligibility and rates with the Missouri Department of Revenue.',
|
||||
'This app is purely informational. Missouri actually offers two '
|
||||
'separate fuel tax refunds — up to 12.5¢ per gallon for highway use, '
|
||||
"and up to 29.5¢ per gallon for non-highway use — and it's worth "
|
||||
"evaluating both to see how you could benefit. This app helps you "
|
||||
"organize the receipts you'd need for either one.\n\n"
|
||||
"Nothing here is tax or legal advice, and using this app doesn't "
|
||||
'guarantee your eligibility for either refund. For guidance on your '
|
||||
'specific situation, consult a tax professional. Both refunds are set '
|
||||
'by Missouri law, which can change at any time — always confirm '
|
||||
'current eligibility and rates with the Missouri Department of '
|
||||
'Revenue before filing.',
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: TextButton.icon(
|
||||
onPressed: () => Navigator.of(context).push(
|
||||
MaterialPageRoute(builder: (_) => const FaqScreen()),
|
||||
),
|
||||
icon: const Icon(Icons.help_outline),
|
||||
label: const Text('See the FAQ for more'),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
],
|
||||
),
|
||||
),
|
||||
const Divider(height: 1),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: OutlinedButton(
|
||||
onPressed: () => SystemNavigator.pop(),
|
||||
child: const Text('Decline'),
|
||||
if (!isReview) ...[
|
||||
const Divider(height: 1),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: OutlinedButton(
|
||||
onPressed: () => SystemNavigator.pop(),
|
||||
child: const Text('Decline'),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: FilledButton(
|
||||
onPressed: () => context.read<AppState>().acceptUserAgreement(),
|
||||
child: const Text('I Agree'),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: FilledButton(
|
||||
onPressed: () => context.read<AppState>().acceptUserAgreement(),
|
||||
child: const Text('I Agree'),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue