diff --git a/.gitignore b/.gitignore
index 3820a95..c4d850c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -43,3 +43,5 @@ app.*.map.json
/android/app/debug
/android/app/profile
/android/app/release
+upload-keystore.jks
+android/key.properties
diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts
index 0c43895..a0d3e67 100644
--- a/android/app/build.gradle.kts
+++ b/android/app/build.gradle.kts
@@ -1,3 +1,6 @@
+import java.util.Properties
+import java.io.FileInputStream
+
plugins {
id("com.android.application")
id("kotlin-android")
@@ -5,6 +8,12 @@ plugins {
id("dev.flutter.flutter-gradle-plugin")
}
+val keystorePropertiesFile = rootProject.file("key.properties")
+val keystoreProperties = Properties()
+if (keystorePropertiesFile.exists()) {
+ keystoreProperties.load(FileInputStream(keystorePropertiesFile))
+}
+
android {
namespace = "com.payfrit.add_months"
compileSdk = flutter.compileSdkVersion
@@ -30,11 +39,18 @@ android {
versionName = flutter.versionName
}
+ signingConfigs {
+ create("release") {
+ keyAlias = keystoreProperties["keyAlias"] as String?
+ keyPassword = keystoreProperties["keyPassword"] as String?
+ storeFile = keystoreProperties["storeFile"]?.let { file(it) }
+ storePassword = keystoreProperties["storePassword"] as String?
+ }
+ }
+
buildTypes {
release {
- // TODO: Add your own signing config for the release build.
- // Signing with the debug keys for now, so `flutter run --release` works.
- signingConfig = signingConfigs.getByName("debug")
+ signingConfig = signingConfigs.getByName("release")
}
}
}
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index dbaa3a6..c01ef47 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -41,5 +41,9 @@
+
+
+
+
diff --git a/android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png b/android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png
index a8b72c0..b3e9a23 100644
Binary files a/android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png and b/android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png differ
diff --git a/android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png b/android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png
index 5547e49..13c7d59 100644
Binary files a/android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png and b/android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png differ
diff --git a/android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png b/android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png
index ea4a32a..11a0aaf 100644
Binary files a/android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png and b/android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png differ
diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png
index c2a87a2..2b4ea28 100644
Binary files a/android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png and b/android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png differ
diff --git a/android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png
index 2817529..d6fd697 100644
Binary files a/android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png and b/android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png differ
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
index 5f838b2..e80be8a 100644
Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
index df44a59..cc76a1a 100644
Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
index 1ca9cf1..6a8e522 100644
Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
index 9ff6097..2fe0cf9 100644
Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
index 75c2191..fea11fb 100644
Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml
index c5d5899..42161e1 100644
--- a/android/app/src/main/res/values/colors.xml
+++ b/android/app/src/main/res/values/colors.xml
@@ -1,4 +1,4 @@
- #FFFFFF
+ #2D2D2D
\ No newline at end of file
diff --git a/assets/icon/app_icon.png b/assets/icon/app_icon.png
index a769dea..3a52b2c 100644
Binary files a/assets/icon/app_icon.png and b/assets/icon/app_icon.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
index 5b0c147..4fdc9cd 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
index e051b03..d8b4ff1 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
index 39ce2c8..1f7cc84 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
index 39eb09c..ebd39ff 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
index 2d5b2a5..d4f28bd 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
index fc2c489..37b37f0 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
index 934c856..ba7a715 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
index 39ce2c8..1f7cc84 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
index 9a29ac4..01618e2 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
index 3007c01..16c0fb7 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png
index 110f7ec..0fb8027 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png
index c52e444..65bd6a8 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png
index 3b64fb3..780d36c 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png
index 581f6d2..f9544f6 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
index 3007c01..16c0fb7 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
index f9f623a..b935559 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png
index 5f838b2..e80be8a 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png
index 9ff6097..2fe0cf9 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
index 807e9fc..d21e1e6 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
index a991457..c0247d1 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
index fa706b6..1c0e3b2 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ
diff --git a/lib/screens/about_screen.dart b/lib/screens/about_screen.dart
index 7e5c8ce..a928bf6 100644
--- a/lib/screens/about_screen.dart
+++ b/lib/screens/about_screen.dart
@@ -5,8 +5,10 @@ import '../theme.dart';
class AboutScreen extends StatelessWidget {
const AboutScreen({super.key});
- static const String _helpUrl = 'https://addmonths.app/help';
- static const String _privacyUrl = 'https://addmonths.app/privacy';
+ static const String _howItWorksUrl = 'https://addmonths.com/#how-it-works';
+ static const String _privacyUrl = 'https://addmonths.com/privacy/';
+ static const String _termsUrl = 'https://addmonths.com/terms/';
+ static const String _disclaimerUrl = 'https://addmonths.com/disclaimer/';
@override
Widget build(BuildContext context) {
@@ -112,14 +114,50 @@ class AboutScreen extends StatelessWidget {
],
),
),
+ const SizedBox(height: 16),
+
+ // No ads promise
+ Container(
+ padding: const EdgeInsets.all(16),
+ decoration: BoxDecoration(
+ color: AppColors.surfaceVariant,
+ borderRadius: BorderRadius.circular(12),
+ ),
+ child: Row(
+ children: [
+ const Icon(
+ Icons.block,
+ color: AppColors.primary,
+ ),
+ const SizedBox(width: 12),
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ 'No ads. Ever.',
+ style: Theme.of(context).textTheme.titleSmall,
+ ),
+ const SizedBox(height: 4),
+ Text(
+ 'No trackers, no monetization schemes. '
+ 'Just a simple tool that respects your time.',
+ style: Theme.of(context).textTheme.bodySmall,
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ ),
const SizedBox(height: 32),
// Links
_buildLinkButton(
context,
icon: Icons.help_outline,
- label: 'How it works',
- onTap: () => _launchUrl(_helpUrl),
+ label: 'How It Works',
+ onTap: () => _launchUrl(_howItWorksUrl),
),
const SizedBox(height: 12),
_buildLinkButton(
@@ -128,23 +166,19 @@ class AboutScreen extends StatelessWidget {
label: 'Privacy Policy',
onTap: () => _launchUrl(_privacyUrl),
),
- const SizedBox(height: 32),
-
- // Disclaimer
- Text(
- 'Disclaimer',
- style: Theme.of(context).textTheme.titleSmall?.copyWith(
- color: AppColors.textSecondary,
- ),
+ const SizedBox(height: 12),
+ _buildLinkButton(
+ context,
+ icon: Icons.description_outlined,
+ label: 'Terms of Service',
+ onTap: () => _launchUrl(_termsUrl),
),
- const SizedBox(height: 8),
- Text(
- 'This app provides general information based on population-level '
- 'research and is not medical advice. Individual results vary widely. '
- 'Consult a healthcare provider for personalized guidance.',
- style: Theme.of(context).textTheme.bodySmall?.copyWith(
- color: AppColors.textSecondary,
- ),
+ const SizedBox(height: 12),
+ _buildLinkButton(
+ context,
+ icon: Icons.medical_information_outlined,
+ label: 'Medical Disclaimer',
+ onTap: () => _launchUrl(_disclaimerUrl),
),
],
),
diff --git a/lib/screens/baseline_screen.dart b/lib/screens/baseline_screen.dart
index 319cb0c..fb6fd4f 100644
--- a/lib/screens/baseline_screen.dart
+++ b/lib/screens/baseline_screen.dart
@@ -484,4 +484,5 @@ class _BaselineScreenState extends State {
);
}
}
+
}
diff --git a/lib/screens/behavioral_screen.dart b/lib/screens/behavioral_screen.dart
index b177725..34ea395 100644
--- a/lib/screens/behavioral_screen.dart
+++ b/lib/screens/behavioral_screen.dart
@@ -336,4 +336,5 @@ class _BehavioralScreenState extends State {
),
);
}
+
}
diff --git a/lib/screens/lifestyle_screen.dart b/lib/screens/lifestyle_screen.dart
index 9f2ae68..2f27e5f 100644
--- a/lib/screens/lifestyle_screen.dart
+++ b/lib/screens/lifestyle_screen.dart
@@ -361,4 +361,5 @@ class _LifestyleScreenState extends State {
);
}
}
+
}
diff --git a/lib/screens/onboarding_screen.dart b/lib/screens/onboarding_screen.dart
index ef422a1..22af2c9 100644
--- a/lib/screens/onboarding_screen.dart
+++ b/lib/screens/onboarding_screen.dart
@@ -1,6 +1,8 @@
import 'package:flutter/material.dart';
+import '../storage/local_storage.dart';
import '../theme.dart';
import 'baseline_screen.dart';
+import 'welcome_screen.dart';
class OnboardingScreen extends StatefulWidget {
const OnboardingScreen({super.key});
@@ -93,16 +95,26 @@ class _OnboardingScreenState extends State {
),
),
const SizedBox(height: 12),
- if (_currentPage < _slides.length - 1)
- TextButton(
- onPressed: _skip,
- child: Text(
- 'Skip',
- style: TextStyle(color: AppColors.textTertiary),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ TextButton(
+ onPressed: _skip,
+ child: Text(
+ 'Skip',
+ style: TextStyle(color: AppColors.textTertiary),
+ ),
),
- )
- else
- const SizedBox(height: 40),
+ const SizedBox(width: 24),
+ TextButton(
+ onPressed: _showSkipForeverConfirmation,
+ child: Text(
+ 'Skip Forever',
+ style: TextStyle(color: AppColors.textTertiary),
+ ),
+ ),
+ ],
+ ),
],
),
),
@@ -250,6 +262,38 @@ class _OnboardingScreenState extends State {
MaterialPageRoute(builder: (_) => const BaselineScreen()),
);
}
+
+ void _showSkipForeverConfirmation() {
+ showDialog(
+ context: context,
+ builder: (dialogContext) => AlertDialog(
+ title: const Text('Skip Forever?'),
+ content: const Text(
+ 'You won\'t be asked to complete the questionnaire again. '
+ 'You can still access the app from the About screen.',
+ ),
+ actions: [
+ TextButton(
+ onPressed: () => Navigator.pop(dialogContext),
+ child: const Text('Cancel'),
+ ),
+ TextButton(
+ onPressed: () async {
+ await LocalStorage.setSkipForever(true);
+ Navigator.pop(dialogContext);
+ if (mounted) {
+ Navigator.of(context).pushAndRemoveUntil(
+ MaterialPageRoute(builder: (_) => const WelcomeScreen()),
+ (route) => false,
+ );
+ }
+ },
+ child: const Text('Skip Forever'),
+ ),
+ ],
+ ),
+ );
+ }
}
class _SlideData {
diff --git a/lib/screens/welcome_screen.dart b/lib/screens/welcome_screen.dart
index 6e90a64..f891239 100644
--- a/lib/screens/welcome_screen.dart
+++ b/lib/screens/welcome_screen.dart
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
+import '../storage/local_storage.dart';
import '../theme.dart';
import 'about_screen.dart';
import 'baseline_screen.dart';
@@ -61,13 +62,23 @@ class WelcomeScreen extends StatelessWidget {
),
),
const SizedBox(height: 16),
- // About link
- TextButton(
- onPressed: () => Navigator.push(
- context,
- MaterialPageRoute(builder: (_) => const AboutScreen()),
- ),
- child: const Text('About'),
+ // Skip Forever and About links
+ Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ TextButton(
+ onPressed: () => _showSkipForeverConfirmation(context),
+ child: const Text('Skip Forever'),
+ ),
+ const SizedBox(width: 24),
+ TextButton(
+ onPressed: () => Navigator.push(
+ context,
+ MaterialPageRoute(builder: (_) => const AboutScreen()),
+ ),
+ child: const Text('About'),
+ ),
+ ],
),
const SizedBox(height: 16),
],
@@ -82,4 +93,38 @@ class WelcomeScreen extends StatelessWidget {
MaterialPageRoute(builder: (_) => const BaselineScreen()),
);
}
+
+ void _showSkipForeverConfirmation(BuildContext context) {
+ showDialog(
+ context: context,
+ builder: (dialogContext) => AlertDialog(
+ title: const Text('Skip Forever?'),
+ content: const Text(
+ 'You won\'t be asked to complete the questionnaire again. '
+ 'You can still access the app from the About screen.',
+ ),
+ actions: [
+ TextButton(
+ onPressed: () => Navigator.pop(dialogContext),
+ child: const Text('Cancel'),
+ ),
+ TextButton(
+ onPressed: () async {
+ await LocalStorage.setSkipForever(true);
+ Navigator.pop(dialogContext);
+ if (context.mounted) {
+ ScaffoldMessenger.of(context).showSnackBar(
+ const SnackBar(
+ content: Text('Questionnaire skipped'),
+ duration: Duration(seconds: 2),
+ ),
+ );
+ }
+ },
+ child: const Text('Skip Forever'),
+ ),
+ ],
+ ),
+ );
+ }
}
diff --git a/lib/storage/local_storage.dart b/lib/storage/local_storage.dart
index 100bd73..06f4504 100644
--- a/lib/storage/local_storage.dart
+++ b/lib/storage/local_storage.dart
@@ -270,4 +270,14 @@ class LocalStorage {
if (json == null) return false; // Default to imperial (US)
return json['value'] as bool;
}
+
+ static Future setSkipForever(bool skip) async {
+ await _put('skipForever', {'value': skip});
+ }
+
+ static Future getSkipForever() async {
+ final json = await _get('skipForever');
+ if (json == null) return false;
+ return json['value'] as bool;
+ }
}
diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift
index 8419574..79a65a4 100644
--- a/macos/Flutter/GeneratedPluginRegistrant.swift
+++ b/macos/Flutter/GeneratedPluginRegistrant.swift
@@ -7,8 +7,10 @@ import Foundation
import flutter_secure_storage_macos
import sqflite_darwin
+import url_launcher_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
+ UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
}
diff --git a/pubspec.yaml b/pubspec.yaml
index 91c10c0..4cdc8d4 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -48,8 +48,8 @@ flutter_launcher_icons:
ios: true
remove_alpha_ios: true
image_path: "assets/icon/app_icon.png"
- adaptive_icon_background: "#FFFFFF"
- adaptive_icon_foreground: "assets/icon/app_icon_foreground.png"
+ adaptive_icon_background: "#2D2D2D"
+ adaptive_icon_foreground: "assets/icon/app_icon.png"
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec