From 44d14b84f3d69981197330c706d05e6dd3208322 Mon Sep 17 00:00:00 2001 From: Muhammed Kaplan Date: Thu, 21 Sep 2023 23:25:14 +0200 Subject: [PATCH] refactor: migrate to isar v4.0 --- lib/analysis_options.yaml | 6 + .../auth/controllers/auth.controller.dart | 32 +- .../shared/toast/views/toast.component.dart | 12 +- lib/lib/core/storage/account.storage.dart | 23 +- lib/lib/core/storage/isar/base.db.dart | 11 +- .../core/storage/isar/local_account.db.dart | 18 +- lib/lib/core/storage/messages.storage.dart | 37 +- .../app/controller/app.controller.dart | 14 +- .../controller/new_account.controller.dart | 27 +- lib/lib/features/app/views/app.view.dart | 6 +- .../components/new_account.component.dart | 116 ++-- .../components/welcomeSheet.component.dart | 6 +- .../mails/controller/messages.controller.dart | 22 +- lib/lib/features/mails/views/mail.view.dart | 5 +- lib/lib/features/mails/views/mails.view.dart | 17 +- .../checkForUpdateSheet.component.dart | 8 +- .../settings/views/settings.view.dart | 22 +- lib/lib/main.dart | 15 +- lib/lib/types/domains.dart | 2 +- lib/lib/types/messages/message.dart | 45 +- .../types/single_message/single_message.dart | 7 +- .../Flutter/GeneratedPluginRegistrant.swift | 6 +- lib/macos/Podfile | 2 +- lib/macos/Podfile.lock | 36 +- lib/macos/Runner.xcodeproj/project.pbxproj | 14 +- .../xcshareddata/xcschemes/Runner.xcscheme | 2 +- lib/macos/Runner/AppDelegate.swift | 1 - lib/pubspec.lock | 656 ++++++++---------- lib/pubspec.yaml | 28 +- 29 files changed, 603 insertions(+), 593 deletions(-) diff --git a/lib/analysis_options.yaml b/lib/analysis_options.yaml index 61b6c4d..6e0d887 100644 --- a/lib/analysis_options.yaml +++ b/lib/analysis_options.yaml @@ -9,6 +9,12 @@ # packages, and plugins designed to encourage good coding practices. include: package:flutter_lints/flutter.yaml +analyzer: + enable-experiment: + - records + - patterns + - sealed-class + linter: # The lint rules applied to this project can be customized in the # section below to disable rules from the `package:flutter_lints/flutter.yaml` diff --git a/lib/lib/core/auth/controllers/auth.controller.dart b/lib/lib/core/auth/controllers/auth.controller.dart index 75f02ea..b7edd4e 100644 --- a/lib/lib/core/auth/controllers/auth.controller.dart +++ b/lib/lib/core/auth/controllers/auth.controller.dart @@ -1,14 +1,15 @@ import 'dart:async'; import 'package:barbox/core/services/di.service.dart'; -import 'package:barbox/features/home/repositories/account.repository.dart'; -import 'package:barbox/utils.dart'; -import 'package:injectable/injectable.dart'; -import 'package:mobx/mobx.dart'; import 'package:barbox/core/storage/account.storage.dart'; import 'package:barbox/core/storage/isar/local_account.db.dart'; import 'package:barbox/core/storage/messages.storage.dart'; +import 'package:barbox/features/home/repositories/account.repository.dart'; import 'package:barbox/types/account.dart'; +import 'package:barbox/utils.dart'; +import 'package:injectable/injectable.dart'; +import 'package:mobx/mobx.dart'; + part 'auth.controller.g.dart'; enum AuthState { loggedIn, none } @@ -71,14 +72,16 @@ abstract class _AuthControllerBase with Store { accountId: acc.id, ); + print(token); + await _accountStorage.saveAccount(account.value!); availableAccounts.add(account.value!); authState.value = AuthState.loggedIn; } @action - Future switchAccount(int id) async { - final toAccount = await _accountStorage.getAccount(id: id); + Future switchAccount(String accountId) async { + final toAccount = await _accountStorage.getAccount(accountId: accountId); account.value = toAccount; } @@ -86,21 +89,16 @@ abstract class _AuthControllerBase with Store { {required String username, required String selectedDomain, required String password}) async { - try { - final _accountRepository = getIt(); - final address = "$username@$selectedDomain"; + final _accountRepository = getIt(); + final address = "$username@$selectedDomain"; - final _account = - await _accountRepository.createAccount(address, password); + final _account = await _accountRepository.createAccount(address, password); - final token = await _accountRepository.login(_account.address, password); + final token = await _accountRepository.login(_account.address, password); - await login(acc: _account, password: password, token: token.token); + await login(acc: _account, password: password, token: token.token); - return true; - } catch (e) { - rethrow; - } + return true; } Future registerWithRandomUsername() async { diff --git a/lib/lib/core/shared/toast/views/toast.component.dart b/lib/lib/core/shared/toast/views/toast.component.dart index 29704cb..d29fe5e 100644 --- a/lib/lib/core/shared/toast/views/toast.component.dart +++ b/lib/lib/core/shared/toast/views/toast.component.dart @@ -26,20 +26,20 @@ class ToastComponent extends StatelessWidget { return closeDialog(); } - Widget renderPrimaryButton() { + PushButton renderPrimaryButton() { if (action != null) { return PushButton( child: Text(action!.label), - buttonSize: ButtonSize.large, + controlSize: ControlSize.large, onPressed: onPressed, ); } return PushButton( - buttonSize: ButtonSize.large, + controlSize: ControlSize.large, child: const Text("Close"), + secondary: true, onPressed: onPressed, - isSecondary: true, ); } @@ -61,10 +61,10 @@ class ToastComponent extends StatelessWidget { primaryButton: renderPrimaryButton(), secondaryButton: action != null ? PushButton( - buttonSize: ButtonSize.large, + controlSize: ControlSize.large, child: const Text("Close"), onPressed: closeDialog, - isSecondary: true, + secondary: true, ) : null, ); diff --git a/lib/lib/core/storage/account.storage.dart b/lib/lib/core/storage/account.storage.dart index 4f28386..861696c 100644 --- a/lib/lib/core/storage/account.storage.dart +++ b/lib/lib/core/storage/account.storage.dart @@ -1,34 +1,37 @@ -import 'package:injectable/injectable.dart'; import 'package:barbox/core/storage/isar/base.db.dart'; import 'package:barbox/core/storage/isar/local_account.db.dart'; +import 'package:injectable/injectable.dart'; import 'package:isar/isar.dart'; @LazySingleton() class AccountStorage { Future saveAccount(LocalAccount account) async { - isarInstance.writeTxn(() async { - await isarInstance.localAccounts.put(account); + isarInstance.writeAsync((isar) async { + isar.localAccounts.put(account); }); } Future removeAccount(LocalAccount account) async { - isarInstance.writeTxn(() async { - await isarInstance.localAccounts.delete(account.id); + isarInstance.writeAsync((isar) async { + isar.localAccounts.delete(account.id); }); } Future removeAllAccounts() async { - isarInstance.writeTxn(() async { - await isarInstance.localAccounts.clear(); + isarInstance.writeAsync((isar) async { + isar.localAccounts.clear(); }); } - Future getAccount({int? id}) async { - return isarInstance.localAccounts.get(id ?? 1); + Future getAccount({required String accountId}) async { + return isarInstance.localAccounts + .where() + .accountIdEqualTo(accountId) + .findFirstAsync(); } Future> getAllAvailableAccounts() async { - return isarInstance.localAccounts.where().findAll(); + return isarInstance.localAccounts.where().findAllAsync(); } Future isLoggedIn() async { diff --git a/lib/lib/core/storage/isar/base.db.dart b/lib/lib/core/storage/isar/base.db.dart index ff1e4ab..36ce7c5 100644 --- a/lib/lib/core/storage/isar/base.db.dart +++ b/lib/lib/core/storage/isar/base.db.dart @@ -1,7 +1,14 @@ import 'package:isar/isar.dart'; +import 'package:path_provider/path_provider.dart'; late Isar isarInstance; -Future initDb(List> schemas) async { - isarInstance = await Isar.open(schemas); +Future initDb(List schemas) async { + final path = await getApplicationDocumentsDirectory(); + print(path); + isarInstance = await Isar.openAsync( + schemas: schemas, + directory: path.path, + inspector: true, + ); } diff --git a/lib/lib/core/storage/isar/local_account.db.dart b/lib/lib/core/storage/isar/local_account.db.dart index bf6b000..a3a1ecc 100644 --- a/lib/lib/core/storage/isar/local_account.db.dart +++ b/lib/lib/core/storage/isar/local_account.db.dart @@ -1,18 +1,24 @@ +import 'dart:math'; + import 'package:isar/isar.dart'; part 'local_account.db.g.dart'; @collection class LocalAccount { - LocalAccount({this.address, this.password, this.token, this.accountId}); + LocalAccount( + {required this.address, + required this.password, + required this.token, + required this.accountId}); - Id id = Isar.autoIncrement; + int get id => Random().nextInt(999999); - String? address; + final String address; - String? password; + final String password; - String? token; + final String token; - String? accountId; + final String accountId; } diff --git a/lib/lib/core/storage/messages.storage.dart b/lib/lib/core/storage/messages.storage.dart index b291c3d..cbd56f1 100644 --- a/lib/lib/core/storage/messages.storage.dart +++ b/lib/lib/core/storage/messages.storage.dart @@ -1,39 +1,39 @@ +import 'package:barbox/core/storage/isar/base.db.dart'; import 'package:barbox/core/storage/isar/local_account.db.dart'; +import 'package:barbox/types/messages/message.dart'; import 'package:injectable/injectable.dart'; import 'package:isar/isar.dart'; -import 'package:barbox/core/storage/isar/base.db.dart'; -import 'package:barbox/types/messages/message.dart'; @LazySingleton() class MessagesStorage { Future saveMessage(Message message) async { - await isarInstance.writeTxn(() async { - await isarInstance.messages.put(message); + await isarInstance.writeAsync((isar) async { + isar.messages.put(message); }); } Future saveMessages(List message) async { - await isarInstance.writeTxn(() async { - await isarInstance.messages.putAll(message); + await isarInstance.writeAsync((isar) async { + isar.messages.putAll(message); }); } //Isar's put() method will either insert or update the object depending on //whether it already exists in the collection. Future updateMessageSeen(String msgId, bool seen) async { - await isarInstance.writeTxn(() async { - Message? message = await isarInstance.messages.getById(msgId); + await isarInstance.writeAsync((isar) async { + Message? message = + await isar.messages.where().idEqualTo(msgId).findFirstAsync(); if (message != null) { message = message.copyWith(seen: seen); - await isarInstance.messages.putById(message); + isar.messages.put(message); } }); } Future containsMessage(Message message) async { - final entries = - await isarInstance.messages.where().idEqualTo(message.id).count(); + final entries = isarInstance.messages.where().idEqualTo(message.id).count(); if (entries > 0) { return true; @@ -47,23 +47,20 @@ class MessagesStorage { } Future deleteMessage(int isarId) async { - return isarInstance.writeTxn(() async { - await isarInstance.messages.delete(isarId); + return isarInstance.writeAsync((isar) async { + isar.messages.delete(isarId); }); } Future clear() async { - return isarInstance.writeTxn(() async { - await isarInstance.messages.clear(); + return isarInstance.writeAsync((isar) async { + isar.messages.clear(); }); } Future clearMessagesByAddress(LocalAccount account) async { - return isarInstance.writeTxn(() async { - await isarInstance.messages - .where() - .accountIdEqualTo(account.accountId!) - .deleteAll(); + return isarInstance.writeAsync((isar) async { + isar.messages.where().accountIdEqualTo(account.accountId).deleteAll(); }); } } diff --git a/lib/lib/features/app/controller/app.controller.dart b/lib/lib/features/app/controller/app.controller.dart index cb1665b..a2e595e 100644 --- a/lib/lib/features/app/controller/app.controller.dart +++ b/lib/lib/features/app/controller/app.controller.dart @@ -1,16 +1,16 @@ import 'dart:async'; +import 'package:barbox/core/auth/controllers/auth.controller.dart'; +import 'package:barbox/core/services/notification.service.dart'; +import 'package:barbox/core/services/router/router.service.dart'; import 'package:barbox/core/shared/toast/views/controllers/toast.controller.dart'; +import 'package:barbox/core/storage/account.storage.dart'; +import 'package:barbox/features/app/views/components/sidebarItem.component.dart'; import 'package:beamer/beamer.dart'; import 'package:flutter/cupertino.dart'; import 'package:injectable/injectable.dart'; import 'package:macos_ui/macos_ui.dart'; import 'package:mobx/mobx.dart'; -import 'package:barbox/core/auth/controllers/auth.controller.dart'; -import 'package:barbox/core/services/notification.service.dart'; -import 'package:barbox/features/app/views/components/sidebarItem.component.dart'; -import 'package:barbox/core/services/router/router.service.dart'; -import 'package:barbox/core/storage/account.storage.dart'; part 'app.controller.g.dart'; @@ -58,11 +58,11 @@ abstract class _AppViewControllerBase with Store { return authController.availableAccounts .where((element) => element.id != authController.account.value?.id) .map((e) => MacosListTile( - title: Text(e.address ?? "s", + title: Text(e.address, style: const TextStyle(fontWeight: FontWeight.normal)), leading: const MacosIcon(CupertinoIcons.person_circle), mouseCursor: SystemMouseCursors.click, - onClick: () => authController.switchAccount(e.id), + onClick: () => authController.switchAccount(e.accountId), )) .toList(); } diff --git a/lib/lib/features/app/controller/new_account.controller.dart b/lib/lib/features/app/controller/new_account.controller.dart index 55f4af8..b4699d7 100644 --- a/lib/lib/features/app/controller/new_account.controller.dart +++ b/lib/lib/features/app/controller/new_account.controller.dart @@ -73,19 +73,15 @@ abstract class _NewAccountControllerBase with Store { return; } - try { - await _authController.register( - username: username!, - selectedDomain: selectedDomain!, - password: password!); - - _toastService.showToast("Account created successfully", - toastType: ToastType.success); - - Navigator.of(context).pop(); - } catch (e) { - _toastService.showToast(e.toString(), toastType: ToastType.error); - } + await _authController.register( + username: username!, + selectedDomain: selectedDomain!, + password: password!); + + _toastService.showToast("Account created successfully", + toastType: ToastType.success); + + Navigator.of(context).pop(); } @action @@ -129,7 +125,10 @@ abstract class _NewAccountControllerBase with Store { selectedDomain = value; } - void dispose() {} + void dispose() { + controllerPassword.dispose(); + controllerUsername.dispose(); + } } disposeNewAccountController(NewAccountController instance) { diff --git a/lib/lib/features/app/views/app.view.dart b/lib/lib/features/app/views/app.view.dart index 630388c..8f68e14 100644 --- a/lib/lib/features/app/views/app.view.dart +++ b/lib/lib/features/app/views/app.view.dart @@ -1,3 +1,6 @@ +import 'package:barbox/core/services/di.service.dart'; +import 'package:barbox/core/services/router/router.service.dart'; +import 'package:barbox/features/app/controller/app.controller.dart'; import 'package:barbox/features/app/views/components/new_account.component.dart'; import 'package:barbox/main.dart'; import 'package:beamer/beamer.dart'; @@ -5,9 +8,6 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:macos_ui/macos_ui.dart'; -import 'package:barbox/core/services/router/router.service.dart'; -import 'package:barbox/features/app/controller/app.controller.dart'; -import 'package:barbox/core/services/di.service.dart'; class App extends StatefulWidget { const App({super.key}); diff --git a/lib/lib/features/app/views/components/new_account.component.dart b/lib/lib/features/app/views/components/new_account.component.dart index e0ea3d4..a758859 100644 --- a/lib/lib/features/app/views/components/new_account.component.dart +++ b/lib/lib/features/app/views/components/new_account.component.dart @@ -5,6 +5,20 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:macos_ui/macos_ui.dart'; +class ss extends PushButton { + final NewAccountController controller; + final BuildContext context; + + ss({super.key, required this.controller, required this.context}) + : super( + child: const Text("Create"), + onPressed: controller.isFormValid + ? () => controller.createAddress(context) + : null, + controlSize: ControlSize.large, + ); +} + class NewAccountComponent extends StatefulWidget { const NewAccountComponent({super.key}); @@ -24,62 +38,62 @@ class _NewAccounSheettComponentState extends State { @override void dispose() { - controller.dispose(); + getIt.resetLazySingleton(); super.dispose(); } @override Widget build(BuildContext context) { - return MacosAlertDialog( - horizontalActions: true, - appIcon: const MacosIcon( - CupertinoIcons.person_add, - size: 30, - ), - title: Text( - "Create new address", - style: MacosTheme.of(context).typography.headline, - ), - message: Column( - children: [ - FocusTraversalGroup( - policy: WidgetOrderTraversalPolicy(), - child: Column( - children: [ - MacosTextField( - placeholder: "Username", - suffix: _usernameSuffix(), - controller: controller.controllerUsername, - onChanged: controller.updateUsername, - ), - Observer(builder: (_) { - return MacosTextField( - placeholder: "Password", - suffix: _passwordSuffix(), - controller: controller.controllerPassword, - obscureText: controller.obsecuredText, - onChanged: controller.updatePassword, - ); - }) - ], - )) - ], - ), - secondaryButton: PushButton( - child: const Text("Cancel"), - isSecondary: true, - buttonSize: ButtonSize.large, - onPressed: () => Navigator.of(context).pop(), - ), - primaryButton: Observer( - builder: (context) => PushButton( - child: const Text("Create"), - buttonSize: ButtonSize.large, - onPressed: controller.isFormValid - ? () => controller.createAddress(context) - : null, - ), - ), + return Observer( + builder: (_) { + return MacosAlertDialog( + horizontalActions: true, + appIcon: const MacosIcon( + CupertinoIcons.person_add, + size: 30, + ), + title: Text( + "Create new address", + style: MacosTheme.of(context).typography.headline, + ), + message: Column( + children: [ + FocusTraversalGroup( + policy: WidgetOrderTraversalPolicy(), + child: Column( + children: [ + MacosTextField( + placeholder: "Username", + suffix: _usernameSuffix(), + controller: controller.controllerUsername, + onChanged: controller.updateUsername, + ), + MacosTextField( + placeholder: "Password", + suffix: _passwordSuffix(), + controller: controller.controllerPassword, + obscureText: controller.obsecuredText, + onChanged: controller.updatePassword, + ) + ], + )) + ], + ), + secondaryButton: PushButton( + secondary: true, + child: const Text("Cancel"), + controlSize: ControlSize.large, + onPressed: () => Navigator.of(context).pop(), + ), + primaryButton: PushButton( + child: const Text("Create"), + controlSize: ControlSize.large, + secondary: false, + onPressed: controller.isFormValid + ? () => controller.createAddress(context) + : null, + )); + }, ); } diff --git a/lib/lib/features/home/views/components/welcomeSheet.component.dart b/lib/lib/features/home/views/components/welcomeSheet.component.dart index 9d0f78e..409c830 100644 --- a/lib/lib/features/home/views/components/welcomeSheet.component.dart +++ b/lib/lib/features/home/views/components/welcomeSheet.component.dart @@ -1,8 +1,8 @@ import 'package:barbox/config.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:macos_ui/macos_ui.dart'; import 'package:barbox/core/services/di.service.dart'; import 'package:barbox/features/home/controllers/home.controller.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:macos_ui/macos_ui.dart'; class HomeWelcomeSheet extends StatelessWidget { const HomeWelcomeSheet({super.key}); @@ -53,7 +53,7 @@ class HomeWelcomeSheet extends StatelessWidget { PushButton( onPressed: () => controller.closeHomeSheet(context), child: const Text("Dismiss"), - buttonSize: ButtonSize.large, + controlSize: ControlSize.large, ) ], ), diff --git a/lib/lib/features/mails/controller/messages.controller.dart b/lib/lib/features/mails/controller/messages.controller.dart index ac71d5e..52b3570 100644 --- a/lib/lib/features/mails/controller/messages.controller.dart +++ b/lib/lib/features/mails/controller/messages.controller.dart @@ -1,16 +1,16 @@ import 'dart:async'; import 'package:barbox/core/auth/controllers/auth.controller.dart'; +import 'package:barbox/core/services/notification.service.dart'; import 'package:barbox/core/storage/isar/local_account.db.dart'; +import 'package:barbox/core/storage/messages.storage.dart'; +import 'package:barbox/features/mails/repositories/messages.repository.dart'; +import 'package:barbox/types/messages/message.dart'; +import 'package:barbox/types/single_message/single_message.dart'; import 'package:dio/dio.dart'; import 'package:flutter/services.dart'; import 'package:injectable/injectable.dart'; import 'package:mobx/mobx.dart'; -import 'package:barbox/core/services/notification.service.dart'; -import 'package:barbox/features/mails/repositories/messages.repository.dart'; -import 'package:barbox/core/storage/messages.storage.dart'; -import 'package:barbox/types/messages/message.dart'; -import 'package:barbox/types/single_message/single_message.dart'; part 'messages.controller.g.dart'; @@ -56,14 +56,14 @@ abstract class _MessagesControllerBase with Store { @action init() async { - await fetchLocalMessages(_authController.account.value!.accountId!); + await fetchLocalMessages(_authController.account.value!.accountId); await fetchMessages(); await listenToNewMessages(); _authController.account.observe( (_) async { if (_.newValue != null) { - await fetchLocalMessages(_.newValue!.accountId!); + await fetchLocalMessages(_.newValue!.accountId); await fetchMessages(); } }, @@ -79,14 +79,14 @@ abstract class _MessagesControllerBase with Store { Future listenToNewMessages() async { final _messages = _messagesWithoutStream; - for (var account in _authController.availableAccounts!) { + for (var account in _authController.availableAccounts) { final cToken = CancelToken(); - final String accountId = account.accountId!; + final String accountId = account.accountId; _cancelTokens.add(cToken); final stream = await _messagesRepository.listenToNewMessages( - cToken, accountId, account.token!); + cToken, accountId, account.token); final _newMessagesStream = stream.listen((message) { final isAlreadyExists = @@ -222,7 +222,7 @@ abstract class _MessagesControllerBase with Store { Future copyAddress() async { final clipboardData = - ClipboardData(text: _authController.account.value?.address); + ClipboardData(text: _authController.account.value!.address); await Clipboard.setData(clipboardData); } diff --git a/lib/lib/features/mails/views/mail.view.dart b/lib/lib/features/mails/views/mail.view.dart index e535055..20ea137 100644 --- a/lib/lib/features/mails/views/mail.view.dart +++ b/lib/lib/features/mails/views/mail.view.dart @@ -1,9 +1,9 @@ +import 'package:barbox/core/services/di.service.dart'; +import 'package:barbox/features/mails/controller/message.controller.dart'; import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter_widget_from_html/flutter_widget_from_html.dart'; import 'package:macos_ui/macos_ui.dart'; -import 'package:barbox/core/services/di.service.dart'; -import 'package:barbox/features/mails/controller/message.controller.dart'; class MailView extends StatefulWidget { const MailView({super.key, required this.msgId}); @@ -46,7 +46,6 @@ class _MailViewState extends State { enableCaching: true, buildAsync: true, renderMode: RenderMode.listView, - rebuildTriggers: RebuildTriggers([]), onLoadingBuilder: (_, __, v) => ProgressCircle( value: v, ), diff --git a/lib/lib/features/mails/views/mails.view.dart b/lib/lib/features/mails/views/mails.view.dart index 2f3db4a..eb6d98b 100644 --- a/lib/lib/features/mails/views/mails.view.dart +++ b/lib/lib/features/mails/views/mails.view.dart @@ -1,17 +1,17 @@ import 'dart:async'; -import 'package:beamer/beamer.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:macos_ui/macos_ui.dart'; import 'package:barbox/core/constants/theme.dart'; +import 'package:barbox/core/services/di.service.dart'; import 'package:barbox/core/services/router/router.controller.dart'; import 'package:barbox/core/services/router/router.service.dart'; import 'package:barbox/features/mails/controller/messages.controller.dart'; import 'package:barbox/features/mails/views/components/message.component.dart'; -import 'package:barbox/core/services/di.service.dart'; import 'package:barbox/types/messages/message.dart'; +import 'package:beamer/beamer.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_mobx/flutter_mobx.dart'; +import 'package:macos_ui/macos_ui.dart'; class MailsView extends StatefulWidget { const MailsView({super.key}); @@ -144,11 +144,10 @@ class _MailsViewState extends State { } }); }, - startWidth: 250, - maxWidth: 300, - minWidth: 150, resizableSide: ResizableSide.right, isResizable: true, + minSize: 150, + startSize: 250, ), ContentArea( builder: (context, _) { diff --git a/lib/lib/features/settings/views/components/checkForUpdateSheet.component.dart b/lib/lib/features/settings/views/components/checkForUpdateSheet.component.dart index a85e0d9..70939a2 100644 --- a/lib/lib/features/settings/views/components/checkForUpdateSheet.component.dart +++ b/lib/lib/features/settings/views/components/checkForUpdateSheet.component.dart @@ -1,9 +1,9 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:macos_ui/macos_ui.dart'; import 'package:barbox/core/constants/theme.dart'; import 'package:barbox/core/services/di.service.dart'; import 'package:barbox/features/settings/controllers/settings.controller.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_mobx/flutter_mobx.dart'; +import 'package:macos_ui/macos_ui.dart'; class CheckForUpdateSheet extends StatelessWidget { const CheckForUpdateSheet({ @@ -63,7 +63,7 @@ class CheckForUpdateSheet extends StatelessWidget { }), PushButton( child: const Text("Download"), - buttonSize: ButtonSize.large, + controlSize: ControlSize.large, onPressed: controller.navigateToDownloads, ) ], diff --git a/lib/lib/features/settings/views/settings.view.dart b/lib/lib/features/settings/views/settings.view.dart index 792d271..ecba0fd 100644 --- a/lib/lib/features/settings/views/settings.view.dart +++ b/lib/lib/features/settings/views/settings.view.dart @@ -1,11 +1,11 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:macos_ui/macos_ui.dart'; import 'package:barbox/core/auth/controllers/auth.controller.dart'; import 'package:barbox/core/constants/theme.dart'; -import 'package:barbox/features/settings/controllers/settings.controller.dart'; import 'package:barbox/core/services/di.service.dart'; +import 'package:barbox/features/settings/controllers/settings.controller.dart'; import 'package:barbox/features/settings/views/components/checkForUpdateSheet.component.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_mobx/flutter_mobx.dart'; +import 'package:macos_ui/macos_ui.dart'; class SettingsView extends StatefulWidget { const SettingsView({super.key}); @@ -70,7 +70,7 @@ class _SettingsViewState extends State { children: [ PushButton( child: const Text("Logout"), - buttonSize: ButtonSize.large, + controlSize: ControlSize.large, onPressed: controller.logout, ), Padding( @@ -78,8 +78,8 @@ class _SettingsViewState extends State { EdgeInsets.only(top: ThemePadding.medium.padding), child: PushButton( child: const Text("Check for updates"), - buttonSize: ButtonSize.large, - isSecondary: true, + controlSize: ControlSize.large, + secondary: true, onPressed: () => controller.checkForUpdates(toggledFromUi: true), ), @@ -88,9 +88,9 @@ class _SettingsViewState extends State { padding: EdgeInsets.only(top: ThemePadding.medium.padding), child: PushButton( + secondary: true, child: const Text("Clear all cached mail"), - buttonSize: ButtonSize.small, - isSecondary: true, + controlSize: ControlSize.small, onPressed: controller.clearAllCachedMessages, ), ), @@ -99,8 +99,8 @@ class _SettingsViewState extends State { EdgeInsets.only(top: ThemePadding.medium.padding), child: PushButton( child: const Text("Clear cache"), - buttonSize: ButtonSize.small, - isSecondary: true, + controlSize: ControlSize.small, + secondary: true, onPressed: controller.clearCache, ), ), diff --git a/lib/lib/main.dart b/lib/lib/main.dart index 818dfc8..80f5761 100644 --- a/lib/lib/main.dart +++ b/lib/lib/main.dart @@ -1,21 +1,24 @@ import 'package:barbox/config.dart'; -import 'package:beamer/beamer.dart'; -import 'package:flutter/material.dart'; -import 'package:macos_ui/macos_ui.dart'; - import 'package:barbox/core/services/di.service.dart'; import 'package:barbox/core/services/router/router.service.dart'; import 'package:barbox/core/storage/isar/base.db.dart'; import 'package:barbox/core/storage/isar/local_account.db.dart'; import 'package:barbox/types/messages/message.dart'; +import 'package:beamer/beamer.dart'; +import 'package:flutter/material.dart'; +import 'package:isar/isar.dart'; +import 'package:macos_ui/macos_ui.dart'; final GlobalKey mainAppKey = GlobalKey(); void main() async { configureDependencies(); - await initDb([LocalAccountSchema, MessageSchema]) - .then((_) => runApp(const MyApp())); + WidgetsFlutterBinding.ensureInitialized(); + await Isar.initialize(); + await initDb([LocalAccountSchema, MessageSchema]); + + runApp(const MyApp()); } class MyApp extends StatelessWidget { diff --git a/lib/lib/types/domains.dart b/lib/lib/types/domains.dart index 7d3e48a..09035a4 100644 --- a/lib/lib/types/domains.dart +++ b/lib/lib/types/domains.dart @@ -40,7 +40,7 @@ class HydraSearch with _$HydraSearch { @JsonKey(name: "@type") String? type, @JsonKey(name: "hydra:template") required String hydraTemplate, @JsonKey(name: "hydra:variableRepresentation") - required String hydraVariableRepresentation, + required String hydraVariableRepresentation, @JsonKey(name: "hydra:mapping") required List hydraMapping, }) = _HydraSearch; diff --git a/lib/lib/types/messages/message.dart b/lib/lib/types/messages/message.dart index ab619d7..a5cea1a 100644 --- a/lib/lib/types/messages/message.dart +++ b/lib/lib/types/messages/message.dart @@ -1,6 +1,5 @@ import 'dart:convert'; -import 'package:copy_with_extension/copy_with_extension.dart'; import 'package:equatable/equatable.dart'; import 'package:isar/isar.dart'; @@ -10,9 +9,9 @@ import 'to.dart'; part 'message.g.dart'; @Collection(inheritance: false) -@CopyWith() class Message extends Equatable { - final Id isarId = Isar.autoIncrement; + @Id() + late int isarId; final String privateId; final String privateType; @Index(unique: true) @@ -32,7 +31,7 @@ class Message extends Equatable { final DateTime createdAt; final DateTime updatedAt; - const Message({ + Message({ required this.id, required this.privateType, required this.privateId, @@ -103,6 +102,44 @@ class Message extends Equatable { /// Converts [HydraMember] to a JSON string. String toJson() => json.encode(toMap()); + Message copyWith({ + String? id, + String? privateType, + String? privateId, + String? accountId, + String? msgid, + From? from, + List? to, + String? subject, + String? intro, + bool? seen, + bool? isDeleted, + bool? hasAttachments, + int? size, + String? downloadUrl, + DateTime? createdAt, + DateTime? updatedAt, + }) { + return Message( + id: id ?? this.id, + privateType: privateType ?? this.privateType, + privateId: privateId ?? this.privateId, + accountId: accountId ?? this.accountId, + msgid: msgid ?? this.msgid, + from: from ?? this.from, + to: to ?? this.to, + subject: subject ?? this.subject, + intro: intro ?? this.intro, + seen: seen ?? this.seen, + isDeleted: isDeleted ?? this.isDeleted, + hasAttachments: hasAttachments ?? this.hasAttachments, + size: size ?? this.size, + downloadUrl: downloadUrl ?? this.downloadUrl, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + ); + } + @override @ignore bool get stringify => true; diff --git a/lib/lib/types/single_message/single_message.dart b/lib/lib/types/single_message/single_message.dart index b18da54..3d6a2f6 100644 --- a/lib/lib/types/single_message/single_message.dart +++ b/lib/lib/types/single_message/single_message.dart @@ -1,8 +1,9 @@ import 'dart:convert'; +import 'dart:math'; +import 'package:barbox/types/single_message/attachment.dart'; import 'package:equatable/equatable.dart'; import 'package:isar/isar.dart'; -import 'package:barbox/types/single_message/attachment.dart'; import 'from.dart'; import 'to.dart'; @@ -11,10 +12,12 @@ part 'single_message.g.dart'; @Collection(inheritance: false) class SingleMessage extends Equatable { - final Id isarId = Isar.autoIncrement; + @Id() + int get isarId => Random().nextInt(99999); final String? privateContext; final String? privateId; final String? privateType; + @Index(unique: true) final String id; final String accountId; final String msgid; diff --git a/lib/macos/Flutter/GeneratedPluginRegistrant.swift b/lib/macos/Flutter/GeneratedPluginRegistrant.swift index 81fc783..6e6f2f6 100644 --- a/lib/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/lib/macos/Flutter/GeneratedPluginRegistrant.swift @@ -10,12 +10,13 @@ import flutter_local_notifications import isar_flutter_libs import just_audio import macos_ui +import macos_window_utils import package_info_plus import path_provider_foundation import shared_preferences_foundation import sqflite import url_launcher_macos -import wakelock_macos +import wakelock_plus func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin")) @@ -23,10 +24,11 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { IsarFlutterLibsPlugin.register(with: registry.registrar(forPlugin: "IsarFlutterLibsPlugin")) JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin")) MacOSUiPlugin.register(with: registry.registrar(forPlugin: "MacOSUiPlugin")) + MacOSWindowUtilsPlugin.register(with: registry.registrar(forPlugin: "MacOSWindowUtilsPlugin")) FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) - WakelockMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockMacosPlugin")) + WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin")) } diff --git a/lib/macos/Podfile b/lib/macos/Podfile index 049abe2..7ed4260 100644 --- a/lib/macos/Podfile +++ b/lib/macos/Podfile @@ -1,4 +1,4 @@ -platform :osx, '10.14' +platform :osx, '10.14.6' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/lib/macos/Podfile.lock b/lib/macos/Podfile.lock index cdef30f..5a1b548 100644 --- a/lib/macos/Podfile.lock +++ b/lib/macos/Podfile.lock @@ -13,6 +13,8 @@ PODS: - FlutterMacOS - macos_ui (0.1.0): - FlutterMacOS + - macos_window_utils (1.0.0): + - FlutterMacOS - package_info_plus (0.0.1): - FlutterMacOS - path_provider_foundation (0.0.1): @@ -26,7 +28,7 @@ PODS: - FMDB (>= 2.7.5) - url_launcher_macos (0.0.1): - FlutterMacOS - - wakelock_macos (0.0.1): + - wakelock_plus (0.0.1): - FlutterMacOS DEPENDENCIES: @@ -36,12 +38,13 @@ DEPENDENCIES: - isar_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/isar_flutter_libs/macos`) - just_audio (from `Flutter/ephemeral/.symlinks/plugins/just_audio/macos`) - macos_ui (from `Flutter/ephemeral/.symlinks/plugins/macos_ui/macos`) + - macos_window_utils (from `Flutter/ephemeral/.symlinks/plugins/macos_window_utils/macos`) - package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`) - - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/macos`) - - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/macos`) + - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) + - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`) - sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/macos`) - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) - - wakelock_macos (from `Flutter/ephemeral/.symlinks/plugins/wakelock_macos/macos`) + - wakelock_plus (from `Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos`) SPEC REPOS: trunk: @@ -60,18 +63,20 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/just_audio/macos macos_ui: :path: Flutter/ephemeral/.symlinks/plugins/macos_ui/macos + macos_window_utils: + :path: Flutter/ephemeral/.symlinks/plugins/macos_window_utils/macos package_info_plus: :path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos path_provider_foundation: - :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/macos + :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin shared_preferences_foundation: - :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/macos + :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin sqflite: :path: Flutter/ephemeral/.symlinks/plugins/sqflite/macos url_launcher_macos: :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos - wakelock_macos: - :path: Flutter/ephemeral/.symlinks/plugins/wakelock_macos/macos + wakelock_plus: + :path: Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos SPEC CHECKSUMS: audio_session: dea1f41890dbf1718f04a56f1d6150fd50039b72 @@ -80,14 +85,15 @@ SPEC CHECKSUMS: FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a isar_flutter_libs: 43385c99864c168fadba7c9adeddc5d38838ca6a just_audio: 9b67ca7b97c61cfc9784ea23cd8cc55eb226d489 - macos_ui: 125c911559d646194386d84c017ad6819122e2db + macos_ui: 6229a8922cd97bafb7d9636c8eb8dfb0744183ca + macos_window_utils: 933f91f64805e2eb91a5bd057cf97cd097276663 package_info_plus: 02d7a575e80f194102bef286361c6c326e4c29ce - path_provider_foundation: 37748e03f12783f9de2cb2c4eadfaa25fe6d4852 - shared_preferences_foundation: 986fc17f3d3251412d18b0265f9c64113a8c2472 + path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 + shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126 sqflite: a5789cceda41d54d23f31d6de539d65bb14100ea - url_launcher_macos: c04e4fa86382d4f94f6b38f14625708be3ae52e2 - wakelock_macos: bc3f2a9bd8d2e6c89fee1e1822e7ddac3bd004a9 + url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95 + wakelock_plus: 4783562c9a43d209c458cb9b30692134af456269 -PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7 +PODFILE CHECKSUM: ff0a9a3ce75ee73f200ca7e2f47745698c917ef9 -COCOAPODS: 1.11.3 +COCOAPODS: 1.12.1 diff --git a/lib/macos/Runner.xcodeproj/project.pbxproj b/lib/macos/Runner.xcodeproj/project.pbxproj index ddce277..51f3518 100644 --- a/lib/macos/Runner.xcodeproj/project.pbxproj +++ b/lib/macos/Runner.xcodeproj/project.pbxproj @@ -205,7 +205,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0920; - LastUpgradeCheck = 1300; + LastUpgradeCheck = 1430; ORGANIZATIONNAME = ""; TargetAttributes = { 33CC10EC2044A3C60003C045 = { @@ -408,7 +408,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.14; + MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -432,7 +432,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 10.14; + MACOSX_DEPLOYMENT_TARGET = 10.14.6; MARKETING_VERSION = 1.3.0; PRODUCT_BUNDLE_IDENTIFIER = com.muhammedkpln.barbox; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -492,7 +492,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.14; + MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -539,7 +539,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.14; + MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -563,7 +563,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 10.14; + MACOSX_DEPLOYMENT_TARGET = 10.14.6; MARKETING_VERSION = 1.3.0; PRODUCT_BUNDLE_IDENTIFIER = com.muhammedkpln.barbox; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -588,7 +588,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 10.14; + MACOSX_DEPLOYMENT_TARGET = 10.14.6; MARKETING_VERSION = 1.3.0; PRODUCT_BUNDLE_IDENTIFIER = com.muhammedkpln.barbox; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/lib/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/lib/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index dd1693b..bf2c06d 100644 --- a/lib/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/lib/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ =2.19.0 <3.0.0" - flutter: ">=3.7.0" + dart: ">=3.2.0-157.0.dev <4.0.0" + flutter: ">=3.10.0" diff --git a/lib/pubspec.yaml b/lib/pubspec.yaml index 73d2638..6277614 100644 --- a/lib/pubspec.yaml +++ b/lib/pubspec.yaml @@ -4,45 +4,53 @@ description: Your one-click solution for disposable emails, right from your Mac version: 2.3.0 environment: - sdk: ">=2.19.0 <3.0.0" + sdk: ">=3.0.0 <4.0.0" + +isar_version: &isar_version 4.0.0-dev.14 dependencies: - macos_ui: ^1.10.0 - flutter_local_notifications: ^13.0.0 + macos_ui: ^2.0.0 + flutter_local_notifications: ^15.1.0+1 url_launcher: ^6.1.8 flutter_svg: ^2.0.2 cupertino_icons: ^1.0.5 pub_semver: ^2.1.3 - package_info_plus: ^3.0.2 + package_info_plus: ^4.0.2 dio: ^4.0.6 injectable: ^2.1.0 get_it: ^7.2.0 flutter_mobx: ^2.0.6+5 freezed_annotation: ^2.2.0 json_annotation: ^4.8.0 - isar: ^3.0.5 - isar_flutter_libs: ^3.0.5 + isar: *isar_version + isar_flutter_libs: *isar_version jiffy: ^5.0.0 beamer: ^1.5.3 equatable: ^2.0.5 - flutter_widget_from_html: ^0.10.0 + flutter_widget_from_html: ^0.13.0-alpha.4 shared_preferences: ^2.0.18 - copy_with_extension: ^5.0.0 cherry_toast: ^1.1.0 + chewie: ^1.5.0 + path_provider: ^2.0.15 flutter: sdk: flutter +dependency_overrides: + cached_network_image: + git: + url: https://github.com/gauravmehta13/flutter_cached_network_image.git + path: cached_network_image + dev_dependencies: + analyzer: ^6.0.0 build_runner: ^2.3.3 injectable_generator: ^2.1.4 mobx_codegen: ^2.1.1 flutter_lints: ^1.0.0 json_serializable: ^6.6.1 freezed: ^2.3.2 - isar_generator: ^3.0.5 - copy_with_extension_gen: ^5.0.2 flutter_test: sdk: flutter