From 5ae91d70e6b233cadf7961450d6312e244c92994 Mon Sep 17 00:00:00 2001 From: bl3kunja Date: Thu, 13 Nov 2025 19:59:42 +0100 Subject: [PATCH] 1.0.2 updater removed --- RELEASE_GUIDE.md | 200 -------------------- lib/screens/settings_screen.dart | 260 -------------------------- lib/services/update_checker.dart | 73 -------- lib/utils/translations.dart | 40 ---- lib/widgets/custom_upgrade_alert.dart | 155 --------------- pubspec.lock | 40 ---- pubspec.yaml | 3 +- 7 files changed, 1 insertion(+), 770 deletions(-) delete mode 100644 RELEASE_GUIDE.md delete mode 100644 lib/services/update_checker.dart delete mode 100644 lib/widgets/custom_upgrade_alert.dart diff --git a/RELEASE_GUIDE.md b/RELEASE_GUIDE.md deleted file mode 100644 index a184be5..0000000 --- a/RELEASE_GUIDE.md +++ /dev/null @@ -1,200 +0,0 @@ -# Release Guide - Shooting App - -## Overview -This guide explains how to create and publish a new release of the Shooting App. The app uses GitHub releases and semantic versioning for update management. - -## Current Setup -- **Repository**: https://github.com/Bl3kiiie/shooting_app -- **Update Method**: Manual check via Settings button (no automatic prompts) -- **Version File**: `pubspec.yaml` -- **Update Detection**: Compares app version with GitHub release tags - ---- - -## Step-by-Step Release Process - -### 1. Update Version in pubspec.yaml -Open `pubspec.yaml` and update the version number: - -```yaml -version: 1.0.2+2 -``` - -Format: `MAJOR.MINOR.PATCH+BUILD_NUMBER` - -Examples: -- `1.0.1+1` → `1.0.2+1` (patch release, new build) -- `1.0.2+1` → `1.0.2+2` (same version, new build) -- `1.0.2+2` → `1.1.0+1` (minor release) - -**Important**: New tag must be HIGHER than previous version for users to see update prompt. - -### 2. Build Release APK - -```bash -# Navigate to project directory -cd /home/bl3kunja/Documents/Programming/Strelišče/shooting_app - -# Build release APK -flutter build apk --release -``` - -The APK will be generated at: `build/app/outputs/flutter-app/release/app-release.apk` - -### 3. Create GitHub Release (Option A: Web Interface - Recommended) - -1. Go to: https://github.com/Bl3kiiie/shooting_app/releases -2. Click **Draft a new release** or **Create a new release** -3. Fill in the form: - - **Tag version**: `v1.0.2` (must match your new version number) - - **Release title**: e.g., `Version 1.0.2 - Bug Fixes and Improvements` - - **Description** (example): - ``` - ## Changes in v1.0.2 - - Fixed camera calibration issue - - Improved bullet detection accuracy - - Added German language support - - Performance optimizations - - ## Installation - Download the APK from the assets below and install on your device. - ``` - -4. **Upload APK**: - - Click "Attach binaries by dropping them here or selecting them" - - Select: `build/app/outputs/flutter-app/release/app-release.apk` - -5. Click **Publish release** - -### 3. Create GitHub Release (Option B: Command Line) - -If using GitHub CLI (`gh` command): - -```bash -# Create tag locally -git tag v1.0.2 - -# Push tag to GitHub -git push origin v1.0.2 - -# Create release (interactive) -gh release create v1.0.2 \ - --title "Version 1.0.2" \ - --notes "Your changelog here" - -# Upload APK to release -gh release upload v1.0.2 build/app/outputs/flutter-app/release/app-release.apk -``` - -### 4. Commit Version Update (Optional) -If you want to track version changes in git: - -```bash -git add pubspec.yaml -git commit -m "bump version to 1.0.2+2" -git push origin main -``` - ---- - -## How Users Update - -1. User opens app → Settings screen -2. User taps **"Check for Updates"** button -3. App compares: - - Current version: `1.0.1+1` - - Latest GitHub release tag: `v1.0.2` -4. Since `v1.0.2 > v1.0.1`, update is available -5. Dialog shows **"Update Available"** -6. User clicks **"Update"** → Opens GitHub release page -7. User downloads and installs new APK - ---- - -## Important Notes - -### Version Numbering -- Always increment version number before creating release -- Tag format: `vX.Y.Z` (e.g., `v1.0.2`, `v1.1.0`) -- App checks: `tag_version > app_version` - -### GitHub Token -- Stored in: `lib/services/update_checker.dart` -- Token: `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` -- Scopes: `repo` (for private repo access) -- Consider rotating this token periodically for security - -### Testing Before Release -```bash -# Test the build -flutter build apk --release - -# Verify APK was created -ls -lh build/app/outputs/flutter-app/release/app-release.apk - -# Optionally install on connected device -flutter install build/app/outputs/flutter-app/release/app-release.apk -``` - -### Troubleshooting Update Detection - -If users don't see update prompt: - -1. Check GitHub release exists: https://github.com/Bl3kiiie/shooting_app/releases -2. Verify tag format is `vX.Y.Z` (must start with 'v') -3. Confirm new version > current version -4. User must tap "Check for Updates" manually -5. Check app logs for errors - ---- - -## Checklist for Next Release - -- [ ] Update version in `pubspec.yaml` -- [ ] Test build: `flutter build apk --release` -- [ ] Create GitHub release with tag `vX.Y.Z` -- [ ] Upload APK to release -- [ ] Write changelog/description -- [ ] Publish release -- [ ] (Optional) Test update detection in app - ---- - -## Example Release Workflow - -```bash -# 1. Update version in pubspec.yaml (manually edit to 1.0.2+1) - -# 2. Build APK -flutter build apk --release - -# 3. Create tag and push -git tag v1.0.2 -git push origin v1.0.2 - -# 4. Create release via GitHub web: -# - Go to https://github.com/Bl3kiiie/shooting_app/releases -# - Draft new release -# - Tag: v1.0.2 -# - Upload APK from build/app/outputs/flutter-app/release/app-release.apk -# - Publish - -# 5. Users can now "Check for Updates" and see the new version -``` - ---- - -## Files Referenced -- `pubspec.yaml` - Version number -- `lib/services/update_checker.dart` - GitHub token and update logic -- `lib/screens/settings_screen.dart` - "Check for Updates" button -- `lib/utils/translations.dart` - Update dialog translations - ---- - -**Last Updated**: November 13, 2025 -**Current Version**: 1.0.1 -**Next Planned Version**: 1.0.2 diff --git a/lib/screens/settings_screen.dart b/lib/screens/settings_screen.dart index d97a6b0..8b3595b 100644 --- a/lib/screens/settings_screen.dart +++ b/lib/screens/settings_screen.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:upgrader/upgrader.dart'; import '../utils/translations.dart'; class SettingsScreen extends StatefulWidget { @@ -171,223 +170,6 @@ Future _saveLanguage(String language) async { _loadCameraIPs(); } - Future _checkForUpdatesManual() async { - // Check for updates without the 24-hour throttling - final upgrader = Upgrader(); - try { - final isUpdateAvailable = await upgrader.isUpdateAvailable(); - if (isUpdateAvailable && mounted) { - _showCustomUpdateDialog(true); - } else if (mounted) { - // Show "No updates available" dialog - _showNoUpdatesDialog(); - } - } catch (e) { - if (mounted) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text(_t('Update check failed'))), - ); - } - } - } - - void _showCustomUpdateDialog(bool updateAvailable) { - showDialog( - context: context, - barrierDismissible: false, - builder: (BuildContext context) { - return Dialog( - backgroundColor: Colors.grey[900], - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), - child: Padding( - padding: const EdgeInsets.all(24), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Container( - width: 80, - height: 80, - decoration: BoxDecoration( - color: Colors.blue, - borderRadius: BorderRadius.circular(16), - ), - child: const Icon( - Icons.update, - color: Colors.white, - size: 40, - ), - ), - const SizedBox(height: 24), - Text( - _t('Update Available'), - style: const TextStyle( - fontSize: 20, - fontWeight: FontWeight.bold, - color: Colors.white, - ), - textAlign: TextAlign.center, - ), - const SizedBox(height: 16), - Text( - _t('A new version of the app is available'), - style: TextStyle( - fontSize: 16, - color: Colors.grey[300], - height: 1.5, - ), - textAlign: TextAlign.center, - ), - const SizedBox(height: 32), - Row( - children: [ - Expanded( - child: GestureDetector( - onTap: () => Navigator.of(context).pop(), - child: Container( - padding: const EdgeInsets.symmetric(vertical: 12), - decoration: BoxDecoration( - color: Colors.grey[800], - borderRadius: BorderRadius.circular(8), - ), - child: Center( - child: Text( - _t('Later'), - style: const TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - color: Colors.grey, - ), - ), - ), - ), - ), - ), - const SizedBox(width: 12), - Expanded( - child: GestureDetector( - onTap: () { - Navigator.of(context).pop(); - // Trigger the update using the upgrader package - _triggerUpdate(); - }, - child: Container( - padding: const EdgeInsets.symmetric(vertical: 12), - decoration: BoxDecoration( - color: Colors.blue, - borderRadius: BorderRadius.circular(8), - ), - child: Center( - child: Text( - _t('Update'), - style: const TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - color: Colors.white, - ), - ), - ), - ), - ), - ), - ], - ), - ], - ), - ), - ); - }, - ); - } - - void _showNoUpdatesDialog() { - showDialog( - context: context, - builder: (BuildContext context) { - return Dialog( - backgroundColor: Colors.grey[900], - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), - child: Padding( - padding: const EdgeInsets.all(24), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Container( - width: 80, - height: 80, - decoration: BoxDecoration( - color: Colors.green, - borderRadius: BorderRadius.circular(16), - ), - child: const Icon( - Icons.check_circle, - color: Colors.white, - size: 40, - ), - ), - const SizedBox(height: 24), - Text( - _t('No updates available'), - style: const TextStyle( - fontSize: 20, - fontWeight: FontWeight.bold, - color: Colors.white, - ), - textAlign: TextAlign.center, - ), - const SizedBox(height: 16), - Text( - _t('You are using the latest version'), - style: TextStyle( - fontSize: 16, - color: Colors.grey[300], - height: 1.5, - ), - textAlign: TextAlign.center, - ), - const SizedBox(height: 32), - SizedBox( - width: double.infinity, - child: GestureDetector( - onTap: () => Navigator.of(context).pop(), - child: Container( - padding: const EdgeInsets.symmetric(vertical: 12), - decoration: BoxDecoration( - color: Colors.blue, - borderRadius: BorderRadius.circular(8), - ), - child: Center( - child: Text( - _t('OK'), - style: const TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - color: Colors.white, - ), - ), - ), - ), - ), - ), - ], - ), - ), - ); - }, - ); - } - - void _triggerUpdate() { - // Use Upgrader to trigger the app store/play store - try { - Upgrader().sendUserToAppStore(); - } catch (e) { - if (mounted) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text(_t('Failed to open app store'))), - ); - } - } - } void _editCameraIP(int index) { TextEditingController controller = TextEditingController( @@ -533,8 +315,6 @@ Future _saveLanguage(String language) async { const SizedBox(height: 8), _buildLanguageSelector(), const SizedBox(height: 16), - _buildCheckUpdateButton(), - const SizedBox(height: 16), _buildBulletColorSelector(), const SizedBox(height: 16), @@ -593,46 +373,6 @@ Future _saveLanguage(String language) async { ); } - Widget _buildCheckUpdateButton() { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - _t("Updates"), - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - color: Colors.black87, - ), - ), - const SizedBox(height: 8), - GestureDetector( - onTap: _checkForUpdatesManual, - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14), - decoration: BoxDecoration( - color: Colors.grey[300], - borderRadius: BorderRadius.circular(12), - ), - child: Row( - children: [ - const Icon(Icons.system_update, color: Colors.black54), - const SizedBox(width: 12), - Expanded( - child: Text( - _t('Check for Updates'), - style: const TextStyle(color: Colors.black87, fontSize: 14), - ), - ), - const Icon(Icons.chevron_right, color: Colors.black54), - ], - ), - ), - ), - ], - ); - } - Widget _buildBulletColorSelector() { return Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/services/update_checker.dart b/lib/services/update_checker.dart deleted file mode 100644 index be8f895..0000000 --- a/lib/services/update_checker.dart +++ /dev/null @@ -1,73 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:upgrader/upgrader.dart'; -import 'package:shared_preferences/shared_preferences.dart'; -import '../utils/translations.dart'; -import '../widgets/custom_upgrade_alert.dart'; - -// GitHub Configuration -const String _githubRepoOwner = 'Bl3kiiie'; -const String _githubRepoName = 'shooting_app'; -const String _githubToken = - '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'; // Replace with your GitHub Personal Access Token - -class UpdateChecker { - static final UpdateChecker _instance = UpdateChecker._internal(); - - factory UpdateChecker() { - return _instance; - } - - UpdateChecker._internal(); - - Future checkForUpdate(BuildContext context, String language) async { - // Check if we've already checked today - final prefs = await SharedPreferences.getInstance(); - final lastCheckTime = prefs.getInt('last_update_check_time') ?? 0; - final now = DateTime.now().millisecondsSinceEpoch; - final oneDayInMilliseconds = 24 * 60 * 60 * 1000; - - // Only check once per day - if (now - lastCheckTime < oneDayInMilliseconds) { - return; - } - - // Update the last check time - await prefs.setInt('last_update_check_time', now); - - final upgrader = Upgrader(); - - try { - // Check if update is available - final isUpdateAvailable = await upgrader.isUpdateAvailable(); - - if (isUpdateAvailable && context.mounted) { - _showCustomUpdateDialog(context, language); - } - } catch (e) { - // Silently fail if update check fails - print('Update check failed: $e'); - } - } - - void _showCustomUpdateDialog(BuildContext context, String language) { - showDialog( - context: context, - barrierDismissible: false, - builder: (BuildContext context) { - return CustomUpdateDialog( - title: AppTranslations.translate('Update Available', language), - message: AppTranslations.translate( - 'A new version of the app is available', language), - updateButtonText: AppTranslations.translate('Update', language), - laterButtonText: AppTranslations.translate('Later', language), - onUpdate: () { - Upgrader().sendUserToAppStore(); - }, - onLater: () { - Navigator.of(context).pop(); - }, - ); - }, - ); - } -} diff --git a/lib/utils/translations.dart b/lib/utils/translations.dart index dac49d5..8ce3edc 100644 --- a/lib/utils/translations.dart +++ b/lib/utils/translations.dart @@ -584,46 +584,6 @@ class AppTranslations { 'English': 'copied to clipboard', 'Slovenian': 'kopirano v odložišče', }, - - // App Update translations - 'Update Available': { - 'English': 'Update Available', - 'Slovenian': 'Posodobitev je na voljo', - }, - 'A new version of the app is available': { - 'English': 'A new version of the app is available', - 'Slovenian': 'Nova različica aplikacije je na voljo', - }, - 'Update': { - 'English': 'Update', - 'Slovenian': 'Posodobi', - }, - 'Later': { - 'English': 'Later', - 'Slovenian': 'Kasneje', - }, - - // App Update Check Button - 'Check for Updates': { - 'English': 'Check for Updates', - 'Slovenian': 'Preveri za posodobitve', - }, - 'No updates available': { - 'English': 'No updates available', - 'Slovenian': 'Ni dostopnih posodobitev', - }, - 'You are using the latest version': { - 'English': 'You are using the latest version', - 'Slovenian': 'Uporabljate najnovejšo različico', - }, - 'Updates': { - 'English': 'Updates', - 'Slovenian': 'Posodobitve', - }, - 'OK': { - 'English': 'OK', - 'Slovenian': 'V redu', - }, }; static String translate(String key, String language) { diff --git a/lib/widgets/custom_upgrade_alert.dart b/lib/widgets/custom_upgrade_alert.dart deleted file mode 100644 index f7a126b..0000000 --- a/lib/widgets/custom_upgrade_alert.dart +++ /dev/null @@ -1,155 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:upgrader/upgrader.dart'; -import '../utils/translations.dart'; - -class CustomUpgradeAlert extends StatefulWidget { - final Widget child; - final String language; - - const CustomUpgradeAlert({ - super.key, - required this.child, - required this.language, - }); - - @override - State createState() => _CustomUpgradeAlertState(); -} - -class _CustomUpgradeAlertState extends State { - @override - Widget build(BuildContext context) { - return UpgradeAlert( - child: widget.child, - upgrader: Upgrader( - debugDisplayAlways: true, - ), - dialogStyle: UpgradeDialogStyle.material, - shouldPopScope: () => true, - ); - } -} - -class CustomUpdateDialog extends StatelessWidget { - final String title; - final String message; - final String updateButtonText; - final String laterButtonText; - final VoidCallback onUpdate; - final VoidCallback onLater; - - const CustomUpdateDialog({ - super.key, - required this.title, - required this.message, - required this.updateButtonText, - required this.laterButtonText, - required this.onUpdate, - required this.onLater, - }); - - @override - Widget build(BuildContext context) { - return Dialog( - backgroundColor: Colors.grey[900], - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), - child: Padding( - padding: const EdgeInsets.all(24), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - // App Icon - Container( - width: 80, - height: 80, - decoration: BoxDecoration( - color: Colors.blue, - borderRadius: BorderRadius.circular(16), - ), - child: const Icon( - Icons.update, - color: Colors.white, - size: 40, - ), - ), - const SizedBox(height: 24), - // Title - Text( - title, - style: const TextStyle( - fontSize: 20, - fontWeight: FontWeight.bold, - color: Colors.white, - ), - textAlign: TextAlign.center, - ), - const SizedBox(height: 16), - // Message - Text( - message, - style: TextStyle( - fontSize: 16, - color: Colors.grey[300], - height: 1.5, - ), - textAlign: TextAlign.center, - ), - const SizedBox(height: 32), - // Buttons - Row( - children: [ - // Later Button - Expanded( - child: GestureDetector( - onTap: onLater, - child: Container( - padding: const EdgeInsets.symmetric(vertical: 12), - decoration: BoxDecoration( - color: Colors.grey[800], - borderRadius: BorderRadius.circular(8), - ), - child: Center( - child: Text( - laterButtonText, - style: const TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - color: Colors.grey, - ), - ), - ), - ), - ), - ), - const SizedBox(width: 12), - // Update Button - Expanded( - child: GestureDetector( - onTap: onUpdate, - child: Container( - padding: const EdgeInsets.symmetric(vertical: 12), - decoration: BoxDecoration( - color: Colors.blue, - borderRadius: BorderRadius.circular(8), - ), - child: Center( - child: Text( - updateButtonText, - style: const TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - color: Colors.white, - ), - ), - ), - ), - ), - ), - ], - ), - ], - ), - ), - ); - } -} diff --git a/pubspec.lock b/pubspec.lock index b844b10..1f1e997 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -137,14 +137,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.6" - csslib: - dependency: transitive - description: - name: csslib - sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" - url: "https://pub.dev" - source: hosted - version: "1.0.2" cupertino_icons: dependency: "direct main" description: @@ -352,14 +344,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.6.0" - html: - dependency: transitive - description: - name: html - sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602" - url: "https://pub.dev" - source: hosted - version: "0.15.6" http: dependency: "direct overridden" description: @@ -528,14 +512,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0" - os_detect: - dependency: transitive - description: - name: os_detect - sha256: "7d87c0dd98c6faf110d5aa498e9a6df02ffce4bb78cc9cfc8ad02929be9bb71f" - url: "https://pub.dev" - source: hosted - version: "2.0.3" package_info_plus: dependency: transitive description: @@ -821,14 +797,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" - upgrader: - dependency: "direct main" - description: - name: upgrader - sha256: "4ba3f840691ffa43c6d71a93a6ad3ae01590c7895c3eb33f9f683513f736a9f7" - url: "https://pub.dev" - source: hosted - version: "12.3.0" url_launcher: dependency: "direct main" description: @@ -925,14 +893,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" - version: - dependency: transitive - description: - name: version - sha256: "3d4140128e6ea10d83da32fef2fa4003fccbf6852217bb854845802f04191f94" - url: "https://pub.dev" - source: hosted - version: "3.0.2" visibility_detector: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index ca2799f..e46e921 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: test1 description: A new Flutter project. publish_to: 'none' # This prevents publishing to pub.dev -version: 1.0.2+1 +version: 1.0.1+1 environment: sdk: '>=3.3.0 <4.0.0' @@ -35,7 +35,6 @@ dependencies: image_picker: ^1.0.4 wakelock_plus: ^1.2.11 url_launcher: ^6.1.0 - upgrader: ^12.3.0 dependency_overrides: http: ^0.13.6