Skip to content

Commit

Permalink
feat: update button on force update dialog for better ux; update path…
Browse files Browse the repository at this point in the history
… and add logic for account deletion on ios, mac and android
  • Loading branch information
brenodt committed May 28, 2024
1 parent f213872 commit 5c5e920
Show file tree
Hide file tree
Showing 8 changed files with 254 additions and 172 deletions.
54 changes: 27 additions & 27 deletions qaul_ui/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,35 @@ PODS:
- Flutter
- device_info_plus (0.0.1):
- Flutter
- DKImagePickerController/Core (4.3.4):
- DKImagePickerController/Core (4.3.9):
- DKImagePickerController/ImageDataManager
- DKImagePickerController/Resource
- DKImagePickerController/ImageDataManager (4.3.4)
- DKImagePickerController/PhotoGallery (4.3.4):
- DKImagePickerController/ImageDataManager (4.3.9)
- DKImagePickerController/PhotoGallery (4.3.9):
- DKImagePickerController/Core
- DKPhotoGallery
- DKImagePickerController/Resource (4.3.4)
- DKPhotoGallery (0.0.17):
- DKPhotoGallery/Core (= 0.0.17)
- DKPhotoGallery/Model (= 0.0.17)
- DKPhotoGallery/Preview (= 0.0.17)
- DKPhotoGallery/Resource (= 0.0.17)
- DKImagePickerController/Resource (4.3.9)
- DKPhotoGallery (0.0.19):
- DKPhotoGallery/Core (= 0.0.19)
- DKPhotoGallery/Model (= 0.0.19)
- DKPhotoGallery/Preview (= 0.0.19)
- DKPhotoGallery/Resource (= 0.0.19)
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Core (0.0.17):
- DKPhotoGallery/Core (0.0.19):
- DKPhotoGallery/Model
- DKPhotoGallery/Preview
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Model (0.0.17):
- DKPhotoGallery/Model (0.0.19):
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Preview (0.0.17):
- DKPhotoGallery/Preview (0.0.19):
- DKPhotoGallery/Model
- DKPhotoGallery/Resource
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Resource (0.0.17):
- DKPhotoGallery/Resource (0.0.19):
- SDWebImage
- SwiftyGif
- file_picker (0.0.1):
Expand All @@ -53,13 +53,13 @@ PODS:
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- SDWebImage (5.15.2):
- SDWebImage/Core (= 5.15.2)
- SDWebImage/Core (5.15.2)
- SDWebImage (5.19.2):
- SDWebImage/Core (= 5.19.2)
- SDWebImage/Core (5.19.2)
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- SwiftyGif (5.4.4)
- SwiftyGif (5.4.5)
- uni_links (0.0.1):
- Flutter
- url_launcher_ios (0.0.1):
Expand Down Expand Up @@ -121,22 +121,22 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
better_open_file: 03cf320415d4d3f46b6e00adc4a567d76c1a399d
device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6
DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac
DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
file_picker: 15fd9539e4eb735dc54bae8c0534a7a9511a03de
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_app_badger: b87fc231847b03b92ce1412aa351842e7e97932f
flutter_email_sender: 02d7443217d8c41483223627972bfdc09f74276b
flutter_email_sender: 10a22605f92809a11ef52b2f412db806c6082d40
flutter_local_notifications: 4cde75091f6327eb8517fa068a0a5950212d2086
image_picker_ios: 4a8aadfbb6dc30ad5141a2ce3832af9214a705b5
image_picker_ios: b545a5f16c0fa88e3ecbbce3ed4de45567a8ec18
integration_test: 13825b8a9334a850581300559b8839134b124670
package_info_plus: fd030dabf36271f146f1f3beacd48f564b0f17f7
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
SDWebImage: 8ab87d4b3e5cc4927bd47f78db6ceb0b94442577
shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126
SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f
package_info_plus: 115f4ad11e0698c8c1c5d8a689390df880f47e85
path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
SDWebImage: dfe95b2466a9823cf9f0c6d01217c06550d7b29a
shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
uni_links: d97da20c7701486ba192624d99bffaaffcfc298a
url_launcher_ios: bf5ce03e0e2088bad9cc378ea97fa0ed5b49673b
url_launcher_ios: 6116280ddcfe98ab8820085d8d76ae7449447586

PODFILE CHECKSUM: c4c93c5f6502fe2754f48404d3594bf779584011

Expand Down
109 changes: 68 additions & 41 deletions qaul_ui/lib/force_update.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ bool forceUpdateRequired(Version current, Version target) {
if (current == target) {
return int.parse(current.build) < int.parse(target.build);
}
throw UnimplementedError("until now, qaul only has one version. Add logic");
return false;
}

/// Utility class to give support to the Force-update flow
class ForceUpdateSystem {
static final _qaulRepoURL = Uri.parse("https://github.com/qaul/qaul.net");
static final _qaulRepoURL =
Uri.parse("https://github.com/qaul/qaul.net/releases/tag/v2.0.0-beta.18");

static final forceUpdateVersion =
Version(2, 0, 0, preRelease: ["beta"], build: "18");
Expand All @@ -28,10 +29,37 @@ class ForceUpdateSystem {
static bool _isFile(FileSystemEntity e) =>
e.statSync().type == FileSystemEntityType.file;

static Future<(bool required, Version? version)> shouldForceUpdate() async {
// - Android : `/data/user/0/net.qaul.qaul_app/files`
// This is the folder where qaul_rpc stores all user data. Deleting it erases
// user information, which prompts for account creation.
static Future<Directory> _qaulRpcFilesDir() async {
if (Platform.isIOS) {
// - iOS : /var/mobile/Containers/Data/Application/THE-DEVICE-ID/Documents
return getApplicationDocumentsDirectory();
}

// Returns the following Path:
// - Android : /data/user/0/net.qaul.qaul_app/files
// - MacOS : /Users/XYZ/Library/Containers/net.qaul.app/Data/Library/Application Support/net.qaul.app
//
// On iOS, it's easier to use `getApplicationDocumentsDirectory`; however, the path returned would be:
// /var/mobile/Containers/Data/Application/THE-DEVICE-ID/Library/Application Support
final appDocumentDir = await getApplicationSupportDirectory();
print('-' * 80);
print(appDocumentDir);
print('-' * 80);

if (Platform.isMacOS) {
var dir = Directory("${appDocumentDir.parent.path}/net.qaul.qaul");
assert(dir.existsSync());
return dir;
}

// if Platform.isAndroid
return appDocumentDir;
}

static Future<(bool required, Version? version)> shouldForceUpdate() async {
final appDocumentDir = await _qaulRpcFilesDir();
final entities = appDocumentDir.listSync();
for (final e in entities) {
if (!e.path.endsWith('version') || !_isFile(e)) {
Expand Down Expand Up @@ -61,19 +89,26 @@ class ForceUpdateSystem {
launchUrl(_qaulRepoURL);
}
}

static Future<void> deleteAccount() async {
final appDocumentDir = await _qaulRpcFilesDir();
await appDocumentDir.delete(recursive: true);
}
}

class ForceUpdateDialog extends StatelessWidget {
const ForceUpdateDialog({
Key? key,
required this.previous,
required this.required,
required this.current,
this.onLinkPressed,
this.onDeleteAccountPressed,
}) : super(key: key);

final String previous;
final String required;
final String current;
final VoidCallback? onLinkPressed;
final VoidCallback? onDeleteAccountPressed;

@override
Widget build(BuildContext context) {
Expand All @@ -86,57 +121,49 @@ class ForceUpdateDialog extends StatelessWidget {
textAlign: TextAlign.center,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 24),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
child: ListView(
children: [
Text(
l10n.forceUpdateRequired,
style: ttheme.displaySmall,
),
const SizedBox(height: 20),

Text(l10n.forceUpdateDescription1),
const SizedBox(height: 8),

Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(child: Text(l10n.forceUpdateDescription2)),
const SizedBox(height: 8),
IconButton(
onPressed: onLinkPressed,
icon: const Icon(Icons.open_in_new),
),
],
),
Text(l10n.forceUpdateDescription2),
const SizedBox(height: 8),

FilledButton(
onPressed: onLinkPressed,
style: FilledButton.styleFrom(
maximumSize: const Size.fromWidth(200),
),
child: Text(
l10n.forceUpdateDownloadQaul18,
textAlign: TextAlign.center,
),
),
const SizedBox(height: 40),
Text(l10n.forceUpdateDescription3),
const SizedBox(height: 8),
FilledButton(
onPressed: () {},
onPressed: onDeleteAccountPressed,
child: Text(l10n.forceUpdateCreateAccount),
),

const SizedBox(height: 8),
Text(l10n.forceUpdateDisclaimer, style: ttheme.labelLarge),

// const Expanded(child: SizedBox.shrink()),
Expanded(
child: SizedBox(
width: double.maxFinite,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(l10n.previousVersion, style: ttheme.titleSmall),
Text(previous),
const SizedBox(height: 8),
Text(l10n.currentVersion, style: ttheme.titleSmall),
Text(required),
],
),
const SizedBox(height: 40),
SizedBox(
width: double.maxFinite,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(l10n.previousVersion, style: ttheme.titleSmall),
Text(previous),
const SizedBox(height: 8),
Text(l10n.currentVersion, style: ttheme.titleSmall),
Text(current),
],
),
),
],
Expand Down
1 change: 1 addition & 0 deletions qaul_ui/lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@
"forceUpdateRequired": "Upgrade Required",
"forceUpdateDescription1": "info: qaul has a new database format. Users of qaul 2.0.0-beta.17 and earlier who wish to keep their existing account need to migrate their data to the new format.",
"forceUpdateDescription2": "To migrate an existing database, download qaul 2.0.0-beta.18 and run it",
"forceUpdateDownloadQaul18": "Download qaul 2.0.0-beta.18",
"forceUpdateDescription3": "If you don't wish to keep your existing data base",
"forceUpdateCreateAccount": "Create new account",
"forceUpdateDisclaimer": "(you will lose all your data and accounts)",
Expand Down
47 changes: 36 additions & 11 deletions qaul_ui/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import 'dart:async';
import 'package:adaptive_theme/adaptive_theme.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:local_notifications/local_notifications.dart';
import 'package:logging/logging.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:qaul_rpc/qaul_rpc.dart';

import 'coordinators/email_logging_coordinator/email_logging_coordinator.dart';
Expand All @@ -25,23 +27,46 @@ void main() async {
await ForceUpdateSystem.shouldForceUpdate();

if (shouldForceUpdate) {
runApp(MaterialApp(
home: ForceUpdateDialog(
required: ForceUpdateSystem.forceUpdateVersion.toString(),
previous: previousVersion?.toString() ?? '',
onLinkPressed: ForceUpdateSystem.openQaulRepo,
),
));
PackageInfo packageInfo = await PackageInfo.fromPlatform();

runApp(
AdaptiveTheme(
light: QaulApp.lightTheme,
dark: QaulApp.darkTheme,
initial: AdaptiveThemeMode.system,
builder: (theme, darkTheme) {
return MaterialApp(
theme: theme,
darkTheme: darkTheme,

localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
home: ForceUpdateDialog(
current: packageInfo.version,
previous: previousVersion?.toString() ?? '',
onLinkPressed: ForceUpdateSystem.openQaulRepo,
onDeleteAccountPressed: () async {
await ForceUpdateSystem.deleteAccount();
await _defaultAppEntrypoint();
},
),
);
}),
);
return;
}

await Initializer.initialize(_container.read);

final savedThemeMode = await AdaptiveTheme.getThemeMode();
runApp(_CustomProviderScope(QaulApp(themeMode: savedThemeMode)));
await _defaultAppEntrypoint();
}, (error, stack) => Logger.root.severe(error, error, stack));
}

Future<void> _defaultAppEntrypoint() async {
await Initializer.initialize(_container.read);

final savedThemeMode = await AdaptiveTheme.getThemeMode();
runApp(_CustomProviderScope(QaulApp(themeMode: savedThemeMode)));
}

class _CustomProviderScope extends StatefulWidget {
const _CustomProviderScope(this.app);

Expand Down
Loading

0 comments on commit 5c5e920

Please sign in to comment.