1.0.2 updater removed
This commit is contained in:
@@ -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
|
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:upgrader/upgrader.dart';
|
|
||||||
import '../utils/translations.dart';
|
import '../utils/translations.dart';
|
||||||
|
|
||||||
class SettingsScreen extends StatefulWidget {
|
class SettingsScreen extends StatefulWidget {
|
||||||
@@ -171,223 +170,6 @@ Future<void> _saveLanguage(String language) async {
|
|||||||
_loadCameraIPs();
|
_loadCameraIPs();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _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) {
|
void _editCameraIP(int index) {
|
||||||
TextEditingController controller = TextEditingController(
|
TextEditingController controller = TextEditingController(
|
||||||
@@ -533,8 +315,6 @@ Future<void> _saveLanguage(String language) async {
|
|||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
_buildLanguageSelector(),
|
_buildLanguageSelector(),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
_buildCheckUpdateButton(),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
_buildBulletColorSelector(),
|
_buildBulletColorSelector(),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
|
|
||||||
@@ -593,46 +373,6 @@ Future<void> _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() {
|
Widget _buildBulletColorSelector() {
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
|||||||
@@ -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<void> 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();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -584,46 +584,6 @@ class AppTranslations {
|
|||||||
'English': 'copied to clipboard',
|
'English': 'copied to clipboard',
|
||||||
'Slovenian': 'kopirano v odložišče',
|
'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) {
|
static String translate(String key, String language) {
|
||||||
|
|||||||
@@ -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<CustomUpgradeAlert> createState() => _CustomUpgradeAlertState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _CustomUpgradeAlertState extends State<CustomUpgradeAlert> {
|
|
||||||
@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,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -137,14 +137,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.6"
|
version: "3.0.6"
|
||||||
csslib:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: csslib
|
|
||||||
sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.2"
|
|
||||||
cupertino_icons:
|
cupertino_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -352,14 +344,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.6.0"
|
version: "1.6.0"
|
||||||
html:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: html
|
|
||||||
sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "0.15.6"
|
|
||||||
http:
|
http:
|
||||||
dependency: "direct overridden"
|
dependency: "direct overridden"
|
||||||
description:
|
description:
|
||||||
@@ -528,14 +512,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
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:
|
package_info_plus:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -821,14 +797,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.0"
|
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:
|
url_launcher:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -925,14 +893,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.4"
|
version: "2.1.4"
|
||||||
version:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: version
|
|
||||||
sha256: "3d4140128e6ea10d83da32fef2fa4003fccbf6852217bb854845802f04191f94"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.2"
|
|
||||||
visibility_detector:
|
visibility_detector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
+1
-2
@@ -2,7 +2,7 @@ name: test1
|
|||||||
description: A new Flutter project.
|
description: A new Flutter project.
|
||||||
publish_to: 'none' # This prevents publishing to pub.dev
|
publish_to: 'none' # This prevents publishing to pub.dev
|
||||||
|
|
||||||
version: 1.0.2+1
|
version: 1.0.1+1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=3.3.0 <4.0.0'
|
sdk: '>=3.3.0 <4.0.0'
|
||||||
@@ -35,7 +35,6 @@ dependencies:
|
|||||||
image_picker: ^1.0.4
|
image_picker: ^1.0.4
|
||||||
wakelock_plus: ^1.2.11
|
wakelock_plus: ^1.2.11
|
||||||
url_launcher: ^6.1.0
|
url_launcher: ^6.1.0
|
||||||
upgrader: ^12.3.0
|
|
||||||
|
|
||||||
dependency_overrides:
|
dependency_overrides:
|
||||||
http: ^0.13.6
|
http: ^0.13.6
|
||||||
|
|||||||
Reference in New Issue
Block a user