mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-03-03 10:36:47 +00:00
switch to go_router
This commit is contained in:
parent
dbc3ee62d0
commit
61a5352bb8
42 changed files with 632 additions and 793 deletions
|
|
@ -5,7 +5,6 @@
|
|||
android:icon="@mipmap/ic_launcher">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:enableOnBackInvokedCallback="true"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTop"
|
||||
android:taskAffinity=""
|
||||
|
|
|
|||
45
lib/app.dart
45
lib/app.dart
|
|
@ -7,8 +7,11 @@ import 'package:twonly/globals.dart';
|
|||
import 'package:twonly/src/localization/generated/app_localizations.dart';
|
||||
import 'package:twonly/src/providers/connection.provider.dart';
|
||||
import 'package:twonly/src/providers/purchases.provider.dart';
|
||||
import 'package:twonly/src/providers/routing.provider.dart';
|
||||
import 'package:twonly/src/providers/settings.provider.dart';
|
||||
import 'package:twonly/src/services/subscription.service.dart';
|
||||
import 'package:twonly/src/themes/dark.dart';
|
||||
import 'package:twonly/src/themes/light.dart';
|
||||
import 'package:twonly/src/utils/log.dart';
|
||||
import 'package:twonly/src/utils/pow.dart';
|
||||
import 'package:twonly/src/utils/storage.dart';
|
||||
|
|
@ -16,7 +19,7 @@ import 'package:twonly/src/views/components/app_outdated.dart';
|
|||
import 'package:twonly/src/views/home.view.dart';
|
||||
import 'package:twonly/src/views/onboarding/onboarding.view.dart';
|
||||
import 'package:twonly/src/views/onboarding/register.view.dart';
|
||||
import 'package:twonly/src/views/settings/backup/twonly_safe_backup.view.dart';
|
||||
import 'package:twonly/src/views/settings/backup/setup_backup.view.dart';
|
||||
import 'package:twonly/src/views/updates/62_database_migration.view.dart';
|
||||
|
||||
class App extends StatefulWidget {
|
||||
|
|
@ -93,50 +96,24 @@ class _AppState extends State<App> with WidgetsBindingObserver {
|
|||
return ListenableBuilder(
|
||||
listenable: context.watch<SettingsChangeProvider>(),
|
||||
builder: (BuildContext context, Widget? child) {
|
||||
return MaterialApp(
|
||||
return MaterialApp.router(
|
||||
routerConfig: routerProvider,
|
||||
scaffoldMessengerKey: globalRootScaffoldMessengerKey,
|
||||
restorationScopeId: 'app',
|
||||
localizationsDelegates: const [
|
||||
AppLocalizations.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
debugShowCheckedModeBanner: false,
|
||||
supportedLocales: const [
|
||||
Locale('en', ''),
|
||||
Locale('de', ''),
|
||||
],
|
||||
onGenerateTitle: (BuildContext context) => 'twonly',
|
||||
theme: ThemeData(
|
||||
colorScheme: ColorScheme.fromSeed(
|
||||
seedColor: const Color(0xFF57CC99),
|
||||
),
|
||||
pageTransitionsTheme: const PageTransitionsTheme(
|
||||
builders: {
|
||||
TargetPlatform.android: PredictiveBackPageTransitionsBuilder(),
|
||||
},
|
||||
),
|
||||
inputDecorationTheme: const InputDecorationTheme(
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
),
|
||||
darkTheme: ThemeData.dark().copyWith(
|
||||
colorScheme: ColorScheme.fromSeed(
|
||||
brightness: Brightness.dark,
|
||||
seedColor: const Color(0xFF57CC99),
|
||||
surface: const Color.fromARGB(255, 20, 18, 23),
|
||||
surfaceContainer: const Color.fromARGB(255, 33, 30, 39),
|
||||
),
|
||||
inputDecorationTheme: const InputDecorationTheme(
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
),
|
||||
title: 'twonly',
|
||||
theme: lightTheme,
|
||||
darkTheme: darkTheme,
|
||||
themeMode: context.watch<SettingsChangeProvider>().themeMode,
|
||||
initialRoute: '/',
|
||||
routes: {
|
||||
'/': (context) => const AppMainWidget(initialPage: 1),
|
||||
'/chats': (context) => const AppMainWidget(initialPage: 0),
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
|
|
@ -213,7 +190,7 @@ class _AppMainWidgetState extends State<AppMainWidget> {
|
|||
child = const DatabaseMigrationView();
|
||||
} else if (_isUserCreated) {
|
||||
if (gUser.twonlySafeBackup == null && !_skipBackup && kReleaseMode) {
|
||||
child = TwonlyIdentityBackupView(
|
||||
child = SetupBackupView(
|
||||
callBack: () {
|
||||
_skipBackup = true;
|
||||
setState(() {});
|
||||
|
|
|
|||
55
lib/src/constants/routes.keys.dart
Normal file
55
lib/src/constants/routes.keys.dart
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
class Routes {
|
||||
static const String home = '/';
|
||||
static const String chats = '/chats';
|
||||
static const String chatsAddNewUser = '/chats/add_new_user';
|
||||
static const String chatsArchived = '/chats/archived';
|
||||
static const String chatsStartNewChat = '/chats/start_new_chat';
|
||||
static const String chatsCameraSendTo = '/chats/camera_send_to';
|
||||
static const String chatsMediaViewer = '/chats/media_viewer';
|
||||
static const String chatsMessages = '/chats/messages';
|
||||
|
||||
static String groupCreateSelectMember(String? groupId) =>
|
||||
'/group/create/select_member${groupId == null ? '' : '/$groupId'}';
|
||||
|
||||
static String profileGroup(String groupId) => '/profile/group/$groupId';
|
||||
static String profileContact(int contactId) => '/profile/contact/$contactId';
|
||||
|
||||
static const String cameraQRScanner = '/camera/qr_scanner';
|
||||
|
||||
static const String settings = '/settings';
|
||||
static const String settingsProfile = '/settings/profile';
|
||||
static const String settingsPublicProfile = '/settings/public_profile';
|
||||
static const String settingsProfileModifyAvatar =
|
||||
'/settings/profile/modify_avatar';
|
||||
static const String settingsAccount = '/settings/account';
|
||||
static const String settingsSubscription = '/settings/subscription';
|
||||
static const String settingsBackup = '/settings/backup';
|
||||
static const String settingsBackupServer = '/settings/backup/server';
|
||||
static const String settingsBackupRecovery = '/settings/backup/recovery';
|
||||
static const String settingsBackupSetup = '/settings/backup/setup';
|
||||
static const String settingsAppearance = '/settings/appearance';
|
||||
static const String settingsChats = '/settings/chats';
|
||||
static const String settingsChatsReactions = '/settings/chats/reactions';
|
||||
static const String settingsPrivacy = '/settings/privacy';
|
||||
static const String settingsPrivacyBlockUsers =
|
||||
'/settings/privacy/block_users';
|
||||
static const String settingsNotification = '/settings/notification';
|
||||
static const String settingsStorage = '/settings/storage_data';
|
||||
static const String settingsStorageImport = '/settings/storage_data/import';
|
||||
static const String settingsStorageExport = '/settings/storage_data/export';
|
||||
static const String settingsHelp = '/settings/help';
|
||||
static const String settingsHelpFaq = '/settings/help/faq';
|
||||
static const String settingsHelpContactUs = '/settings/help/contact_us';
|
||||
static const String settingsHelpDiagnostics = '/settings/help/diagnostics';
|
||||
static const String settingsHelpUserStudy = '/settings/help/user_study';
|
||||
static const String settingsHelpUserStudyQuestionnaire =
|
||||
'/settings/help/user_study/questionnaire';
|
||||
static const String settingsHelpCredits = '/settings/help/credits';
|
||||
static const String settingsHelpChangelog = '/settings/help/changelog';
|
||||
static const String settingsDeveloper = '/settings/developer';
|
||||
static const String settingsDeveloperRetransmissionDatabase =
|
||||
'/settings/developer/retransmission_database';
|
||||
static const String settingsDeveloperAutomatedTesting =
|
||||
'/settings/developer/automated_testing';
|
||||
static const String settingsInvite = '/settings/invite';
|
||||
}
|
||||
285
lib/src/providers/routing.provider.dart
Normal file
285
lib/src/providers/routing.provider.dart
Normal file
|
|
@ -0,0 +1,285 @@
|
|||
import 'package:go_router/go_router.dart';
|
||||
import 'package:twonly/app.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/database/twonly.db.dart';
|
||||
import 'package:twonly/src/views/camera/camera_qr_scanner.view.dart';
|
||||
import 'package:twonly/src/views/camera/camera_send_to.view.dart';
|
||||
import 'package:twonly/src/views/chats/add_new_user.view.dart';
|
||||
import 'package:twonly/src/views/chats/archived_chats.view.dart';
|
||||
import 'package:twonly/src/views/chats/chat_messages.view.dart';
|
||||
import 'package:twonly/src/views/chats/media_viewer.view.dart';
|
||||
import 'package:twonly/src/views/chats/start_new_chat.view.dart';
|
||||
import 'package:twonly/src/views/contact/contact.view.dart';
|
||||
import 'package:twonly/src/views/groups/group.view.dart';
|
||||
import 'package:twonly/src/views/groups/group_create_select_members.view.dart';
|
||||
import 'package:twonly/src/views/onboarding/recover.view.dart';
|
||||
import 'package:twonly/src/views/public_profile.view.dart';
|
||||
import 'package:twonly/src/views/settings/account.view.dart';
|
||||
import 'package:twonly/src/views/settings/appearance.view.dart';
|
||||
import 'package:twonly/src/views/settings/backup/backup.view.dart';
|
||||
import 'package:twonly/src/views/settings/backup/backup_server.view.dart';
|
||||
import 'package:twonly/src/views/settings/backup/setup_backup.view.dart';
|
||||
import 'package:twonly/src/views/settings/chat/chat_reactions.view.dart';
|
||||
import 'package:twonly/src/views/settings/chat/chat_settings.view.dart';
|
||||
import 'package:twonly/src/views/settings/data_and_storage.view.dart';
|
||||
import 'package:twonly/src/views/settings/data_and_storage/export_media.view.dart';
|
||||
import 'package:twonly/src/views/settings/data_and_storage/import_media.view.dart';
|
||||
import 'package:twonly/src/views/settings/developer/automated_testing.view.dart';
|
||||
import 'package:twonly/src/views/settings/developer/developer.view.dart';
|
||||
import 'package:twonly/src/views/settings/developer/retransmission_data.view.dart';
|
||||
import 'package:twonly/src/views/settings/help/changelog.view.dart';
|
||||
import 'package:twonly/src/views/settings/help/contact_us.view.dart';
|
||||
import 'package:twonly/src/views/settings/help/credits.view.dart';
|
||||
import 'package:twonly/src/views/settings/help/diagnostics.view.dart';
|
||||
import 'package:twonly/src/views/settings/help/faq.view.dart';
|
||||
import 'package:twonly/src/views/settings/help/help.view.dart';
|
||||
import 'package:twonly/src/views/settings/notification.view.dart';
|
||||
import 'package:twonly/src/views/settings/privacy.view.dart';
|
||||
import 'package:twonly/src/views/settings/privacy_view_block.view.dart';
|
||||
import 'package:twonly/src/views/settings/profile/modify_avatar.view.dart';
|
||||
import 'package:twonly/src/views/settings/profile/profile.view.dart';
|
||||
import 'package:twonly/src/views/settings/settings_main.view.dart';
|
||||
import 'package:twonly/src/views/settings/share_with_friends.view.dart';
|
||||
import 'package:twonly/src/views/settings/subscription/subscription.view.dart';
|
||||
import 'package:twonly/src/views/user_study/user_study_questionnaire.view.dart';
|
||||
import 'package:twonly/src/views/user_study/user_study_welcome.view.dart';
|
||||
|
||||
final routerProvider = GoRouter(
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: Routes.home,
|
||||
builder: (context, state) => const AppMainWidget(initialPage: 1),
|
||||
),
|
||||
|
||||
// Chats
|
||||
GoRoute(
|
||||
path: Routes.chats,
|
||||
builder: (context, state) => const AppMainWidget(initialPage: 0),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'add_new_user',
|
||||
builder: (context, state) => const AddNewUserView(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'archived',
|
||||
builder: (context, state) => const ArchivedChatsView(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'start_new_chat',
|
||||
builder: (context, state) => const StartNewChatView(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'camera_send_to',
|
||||
builder: (context, state) {
|
||||
final group = state.extra! as Group;
|
||||
return CameraSendToView(group);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: 'media_viewer',
|
||||
builder: (context, state) {
|
||||
final group = state.extra! as Group;
|
||||
return MediaViewerView(group);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: 'messages',
|
||||
builder: (context, state) {
|
||||
final group = state.extra! as Group;
|
||||
return ChatMessagesView(group);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
GoRoute(
|
||||
path: '/profile/contact/:contactId',
|
||||
builder: (context, state) {
|
||||
final contactId = state.pathParameters['contactId']!;
|
||||
return ContactView(int.parse(contactId));
|
||||
},
|
||||
),
|
||||
|
||||
GoRoute(
|
||||
path: '/profile/group/:groupId',
|
||||
builder: (context, state) {
|
||||
final groupId = state.pathParameters['groupId']!;
|
||||
return GroupView(groupId);
|
||||
},
|
||||
),
|
||||
|
||||
GoRoute(
|
||||
path: '/group/create/select_member',
|
||||
builder: (context, state) {
|
||||
return const GroupCreateSelectMembersView();
|
||||
},
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: ':groupId',
|
||||
builder: (context, state) {
|
||||
final groupId = state.pathParameters['groupId'];
|
||||
return GroupCreateSelectMembersView(groupId: groupId);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
GoRoute(
|
||||
path: Routes.cameraQRScanner,
|
||||
builder: (context, state) {
|
||||
return const QrCodeScannerView();
|
||||
},
|
||||
),
|
||||
|
||||
// settings
|
||||
GoRoute(
|
||||
path: Routes.settings,
|
||||
builder: (context, state) => const SettingsMainView(),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'profile',
|
||||
builder: (context, state) => const ProfileView(),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'modify_avatar',
|
||||
builder: (context, state) => const ModifyAvatarView(),
|
||||
)
|
||||
],
|
||||
),
|
||||
GoRoute(
|
||||
path: 'public_profile',
|
||||
builder: (context, state) => const PublicProfileView(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'account',
|
||||
builder: (context, state) => const AccountView(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'subscription',
|
||||
builder: (context, state) => const SubscriptionView(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'backup',
|
||||
builder: (context, state) => const BackupView(),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'server',
|
||||
builder: (context, state) => const BackupServerView(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'recovery',
|
||||
builder: (context, state) => const BackupRecoveryView(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'setup',
|
||||
builder: (context, state) => SetupBackupView(
|
||||
isPasswordChangeOnly: state.extra as bool? ?? false,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
GoRoute(
|
||||
path: 'appearance',
|
||||
builder: (context, state) => const AppearanceView(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'chats',
|
||||
builder: (context, state) => const ChatSettingsView(),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'reactions',
|
||||
builder: (context, state) => const ChatReactionSelectionView(),
|
||||
),
|
||||
],
|
||||
),
|
||||
GoRoute(
|
||||
path: 'privacy',
|
||||
builder: (context, state) => const PrivacyView(),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'block_users',
|
||||
builder: (context, state) => const PrivacyViewBlockUsersView(),
|
||||
)
|
||||
],
|
||||
),
|
||||
GoRoute(
|
||||
path: 'notification',
|
||||
builder: (context, state) => const NotificationView(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'storage_data',
|
||||
builder: (context, state) => const DataAndStorageView(),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'import',
|
||||
builder: (context, state) => const ImportMediaView(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'export',
|
||||
builder: (context, state) => const ExportMediaView(),
|
||||
),
|
||||
],
|
||||
),
|
||||
GoRoute(
|
||||
path: 'help',
|
||||
builder: (context, state) => const HelpView(),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'faq',
|
||||
builder: (context, state) => const FaqView(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'contact_us',
|
||||
builder: (context, state) => const ContactUsView(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'diagnostics',
|
||||
builder: (context, state) => const DiagnosticsView(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'user_study',
|
||||
builder: (context, state) => UserStudyWelcomeView(
|
||||
wasOpenedAutomatic: state.extra as bool? ?? false,
|
||||
),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'questionnaire',
|
||||
builder: (context, state) =>
|
||||
const UserStudyQuestionnaireView(),
|
||||
),
|
||||
],
|
||||
),
|
||||
GoRoute(
|
||||
path: 'credits',
|
||||
builder: (context, state) => const CreditsView(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'changelog',
|
||||
builder: (context, state) => ChangeLogView(
|
||||
changeLog: state.extra as String?,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
GoRoute(
|
||||
path: 'developer',
|
||||
builder: (context, state) => const DeveloperSettingsView(),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'retransmission_database',
|
||||
builder: (context, state) => const RetransmissionDataView(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'automated_testing',
|
||||
builder: (context, state) => const AutomatedTestingView(),
|
||||
),
|
||||
],
|
||||
),
|
||||
GoRoute(
|
||||
path: 'invite',
|
||||
builder: (context, state) => const ShareWithFriendsView(),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
|
|
@ -5,8 +5,11 @@ import 'dart:typed_data';
|
|||
import 'package:collection/collection.dart';
|
||||
import 'package:drift/drift.dart' show Value;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_sharing_intent/flutter_sharing_intent.dart';
|
||||
import 'package:flutter_sharing_intent/model/sharing_file.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:twonly/globals.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/database/tables/mediafiles.table.dart';
|
||||
import 'package:twonly/src/database/twonly.db.dart';
|
||||
import 'package:twonly/src/services/api/mediafiles/upload.service.dart';
|
||||
|
|
@ -16,8 +19,6 @@ import 'package:twonly/src/utils/misc.dart';
|
|||
import 'package:twonly/src/views/camera/share_image_editor.view.dart';
|
||||
import 'package:twonly/src/views/chats/add_new_user.view.dart';
|
||||
import 'package:twonly/src/views/components/alert_dialog.dart';
|
||||
import 'package:twonly/src/views/contact/contact.view.dart';
|
||||
import 'package:twonly/src/views/public_profile.view.dart';
|
||||
|
||||
Future<bool> handleIntentUrl(BuildContext context, Uri uri) async {
|
||||
if (!uri.scheme.startsWith('http')) return false;
|
||||
|
|
@ -32,14 +33,7 @@ Future<bool> handleIntentUrl(BuildContext context, Uri uri) async {
|
|||
if (!context.mounted) return false;
|
||||
|
||||
if (username == gUser.username) {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const PublicProfileView();
|
||||
},
|
||||
),
|
||||
);
|
||||
await context.push(Routes.settingsPublicProfile);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -91,14 +85,7 @@ Future<bool> handleIntentUrl(BuildContext context, Uri uri) async {
|
|||
);
|
||||
}
|
||||
} else {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return ContactView(contact.userId);
|
||||
},
|
||||
),
|
||||
);
|
||||
await context.push(Routes.profileContact(contact.userId));
|
||||
}
|
||||
} else {
|
||||
await showAlertDialog(
|
||||
|
|
@ -149,6 +136,27 @@ Future<void> handleIntentMediaFile(
|
|||
);
|
||||
}
|
||||
|
||||
StreamSubscription<List<SharedFile>> initIntentStreams(
|
||||
BuildContext context,
|
||||
void Function(Uri) onUrlCallBack,
|
||||
) {
|
||||
FlutterSharingIntent.instance.getInitialSharing().then((f) {
|
||||
if (!context.mounted) return;
|
||||
handleIntentSharedFile(context, f, onUrlCallBack);
|
||||
});
|
||||
|
||||
return FlutterSharingIntent.instance.getMediaStream().listen(
|
||||
(f) {
|
||||
if (!context.mounted) return;
|
||||
handleIntentSharedFile(context, f, onUrlCallBack);
|
||||
},
|
||||
// ignore: inference_failure_on_untyped_parameter
|
||||
onError: (err) {
|
||||
Log.error('getIntentDataStream error: $err');
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> handleIntentSharedFile(
|
||||
BuildContext context,
|
||||
List<SharedFile> files,
|
||||
|
|
|
|||
13
lib/src/themes/dark.dart
Normal file
13
lib/src/themes/dark.dart
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
final ThemeData darkTheme = ThemeData.dark().copyWith(
|
||||
colorScheme: ColorScheme.fromSeed(
|
||||
brightness: Brightness.dark,
|
||||
seedColor: const Color(0xFF57CC99),
|
||||
surface: const Color.fromARGB(255, 20, 18, 23),
|
||||
surfaceContainer: const Color.fromARGB(255, 33, 30, 39),
|
||||
),
|
||||
inputDecorationTheme: const InputDecorationTheme(
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
);
|
||||
10
lib/src/themes/light.dart
Normal file
10
lib/src/themes/light.dart
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
final ThemeData lightTheme = ThemeData(
|
||||
colorScheme: ColorScheme.fromSeed(
|
||||
seedColor: const Color(0xFF57CC99),
|
||||
),
|
||||
inputDecorationTheme: const InputDecorationTheme(
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
);
|
||||
|
|
@ -4,13 +4,13 @@ import 'package:twonly/src/views/camera/camera_preview_components/camera_preview
|
|||
import 'package:twonly/src/views/camera/camera_preview_components/camera_preview_controller_view.dart';
|
||||
import 'package:twonly/src/views/camera/camera_preview_components/main_camera_controller.dart';
|
||||
|
||||
class QrCodeScanner extends StatefulWidget {
|
||||
const QrCodeScanner({super.key});
|
||||
class QrCodeScannerView extends StatefulWidget {
|
||||
const QrCodeScannerView({super.key});
|
||||
@override
|
||||
State<QrCodeScanner> createState() => QrCodeScannerState();
|
||||
State<QrCodeScannerView> createState() => QrCodeScannerViewState();
|
||||
}
|
||||
|
||||
class QrCodeScannerState extends State<QrCodeScanner> {
|
||||
class QrCodeScannerViewState extends State<QrCodeScannerView> {
|
||||
final MainCameraController _mainCameraController = MainCameraController();
|
||||
|
||||
@override
|
||||
|
|
|
|||
|
|
@ -4,28 +4,21 @@ import 'package:flutter/foundation.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:twonly/globals.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/database/twonly.db.dart';
|
||||
import 'package:twonly/src/providers/connection.provider.dart';
|
||||
import 'package:twonly/src/providers/purchases.provider.dart';
|
||||
import 'package:twonly/src/services/subscription.service.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/utils/storage.dart';
|
||||
import 'package:twonly/src/views/chats/add_new_user.view.dart';
|
||||
import 'package:twonly/src/views/chats/archived_chats.view.dart';
|
||||
import 'package:twonly/src/views/chats/chat_list_components/connection_info.comp.dart';
|
||||
import 'package:twonly/src/views/chats/chat_list_components/feedback_btn.dart';
|
||||
import 'package:twonly/src/views/chats/chat_list_components/group_list_item.dart';
|
||||
import 'package:twonly/src/views/chats/start_new_chat.view.dart';
|
||||
import 'package:twonly/src/views/components/avatar_icon.component.dart';
|
||||
import 'package:twonly/src/views/components/notification_badge.dart';
|
||||
import 'package:twonly/src/views/public_profile.view.dart';
|
||||
import 'package:twonly/src/views/settings/help/changelog.view.dart';
|
||||
import 'package:twonly/src/views/settings/profile/profile.view.dart';
|
||||
import 'package:twonly/src/views/settings/settings_main.view.dart';
|
||||
import 'package:twonly/src/views/settings/subscription/subscription.view.dart';
|
||||
import 'package:twonly/src/views/user_study/user_study_welcome.view.dart';
|
||||
|
||||
class ChatListView extends StatefulWidget {
|
||||
const ChatListView({super.key});
|
||||
|
|
@ -64,15 +57,9 @@ class _ChatListViewState extends State<ChatListView> {
|
|||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
if (gUser.subscriptionPlan == SubscriptionPlan.Tester.name &&
|
||||
!gUser.askedForUserStudyPermission) {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const UserStudyWelcomeView(
|
||||
wasOpenedAutomatic: true,
|
||||
);
|
||||
},
|
||||
),
|
||||
await context.push(
|
||||
Routes.settingsHelpUserStudy,
|
||||
extra: true,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -89,15 +76,9 @@ class _ChatListViewState extends State<ChatListView> {
|
|||
// only show changelog to people who already have contacts
|
||||
// this prevents that this is shown directly after the user registered
|
||||
if (_groupsNotPinned.isNotEmpty) {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return ChangeLogView(
|
||||
changeLog: changeLog,
|
||||
);
|
||||
},
|
||||
),
|
||||
await context.push(
|
||||
Routes.settingsHelpChangelog,
|
||||
extra: changeLog,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -120,14 +101,7 @@ class _ChatListViewState extends State<ChatListView> {
|
|||
children: [
|
||||
GestureDetector(
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const ProfileView();
|
||||
},
|
||||
),
|
||||
);
|
||||
await context.push(Routes.settingsProfile);
|
||||
if (!mounted) return;
|
||||
setState(() {}); // gUser has updated
|
||||
},
|
||||
|
|
@ -141,16 +115,7 @@ class _ChatListViewState extends State<ChatListView> {
|
|||
const Text('twonly '),
|
||||
if (plan != SubscriptionPlan.Free)
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const SubscriptionView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(Routes.settingsSubscription),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: context.color.primary,
|
||||
|
|
@ -184,28 +149,15 @@ class _ChatListViewState extends State<ChatListView> {
|
|||
child: IconButton(
|
||||
key: searchForOtherUsers,
|
||||
icon: const FaIcon(FontAwesomeIcons.userPlus, size: 18),
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const AddNewUserView(),
|
||||
),
|
||||
);
|
||||
},
|
||||
onPressed: () => context.push(Routes.chatsAddNewUser),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const SettingsMainView(),
|
||||
),
|
||||
);
|
||||
if (!mounted) return;
|
||||
setState(() {}); // gUser may has changed...
|
||||
await context.push(Routes.settings);
|
||||
if (mounted) setState(() {}); // gUser may has changed...
|
||||
},
|
||||
icon: const FaIcon(FontAwesomeIcons.gear, size: 19),
|
||||
),
|
||||
|
|
@ -234,14 +186,7 @@ class _ChatListViewState extends State<ChatListView> {
|
|||
padding: const EdgeInsets.all(10),
|
||||
child: OutlinedButton.icon(
|
||||
icon: const Icon(Icons.person_add),
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const AddNewUserView(),
|
||||
),
|
||||
);
|
||||
},
|
||||
onPressed: () => context.push(Routes.chatsAddNewUser),
|
||||
label: Text(
|
||||
context.lang.chatListViewSearchUserNameBtn,
|
||||
),
|
||||
|
|
@ -265,16 +210,7 @@ class _ChatListViewState extends State<ChatListView> {
|
|||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(fontSize: 13),
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const ArchivedChatsView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(Routes.chatsArchived),
|
||||
);
|
||||
}
|
||||
// Check if the index is for the pinned users
|
||||
|
|
@ -320,16 +256,7 @@ class _ChatListViewState extends State<ChatListView> {
|
|||
color: context.color.primary,
|
||||
child: InkWell(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const PublicProfileView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(Routes.settingsPublicProfile),
|
||||
child: SizedBox(
|
||||
width: 45,
|
||||
height: 45,
|
||||
|
|
@ -345,16 +272,7 @@ class _ChatListViewState extends State<ChatListView> {
|
|||
const SizedBox(height: 12),
|
||||
FloatingActionButton(
|
||||
backgroundColor: context.color.primary,
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const StartNewChatView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onPressed: () => context.push(Routes.chatsStartNewChat),
|
||||
child: FaIcon(
|
||||
FontAwesomeIcons.penToSquare,
|
||||
color: isDarkMode(context) ? Colors.black : Colors.white,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/utils/storage.dart';
|
||||
import 'package:twonly/src/views/settings/help/contact_us.view.dart';
|
||||
|
||||
class FeedbackIconButton extends StatefulWidget {
|
||||
const FeedbackIconButton({super.key});
|
||||
|
|
@ -37,14 +37,7 @@ class _FeedbackIconButtonState extends State<FeedbackIconButton> {
|
|||
}
|
||||
|
||||
return IconButton(
|
||||
onPressed: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const ContactUsView(),
|
||||
),
|
||||
);
|
||||
},
|
||||
onPressed: () => context.push(Routes.settingsHelpContactUs),
|
||||
color: Colors.grey,
|
||||
tooltip: context.lang.feedbackTooltip,
|
||||
icon: const FaIcon(FontAwesomeIcons.commentDots, size: 19),
|
||||
|
|
|
|||
|
|
@ -1,24 +1,22 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:mutex/mutex.dart';
|
||||
import 'package:twonly/globals.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/database/daos/contacts.dao.dart';
|
||||
import 'package:twonly/src/database/tables/mediafiles.table.dart';
|
||||
import 'package:twonly/src/database/tables/messages.table.dart';
|
||||
import 'package:twonly/src/database/twonly.db.dart';
|
||||
import 'package:twonly/src/services/api/mediafiles/download.service.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/views/camera/camera_send_to.view.dart';
|
||||
import 'package:twonly/src/views/chats/chat_list_components/last_message_time.dart';
|
||||
import 'package:twonly/src/views/chats/chat_messages.view.dart';
|
||||
import 'package:twonly/src/views/chats/chat_messages_components/message_send_state_icon.dart';
|
||||
import 'package:twonly/src/views/chats/media_viewer.view.dart';
|
||||
import 'package:twonly/src/views/components/avatar_icon.component.dart';
|
||||
import 'package:twonly/src/views/components/flame.dart';
|
||||
import 'package:twonly/src/views/components/group_context_menu.component.dart';
|
||||
import 'package:twonly/src/views/contact/contact.view.dart';
|
||||
import 'package:twonly/src/views/groups/group.view.dart';
|
||||
|
||||
class GroupListItem extends StatefulWidget {
|
||||
const GroupListItem({
|
||||
|
|
@ -161,13 +159,9 @@ class _UserListItem extends State<GroupListItem> {
|
|||
|
||||
Future<void> onTap() async {
|
||||
if (_currentMessage == null && widget.group.totalMediaCounter == 0) {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return CameraSendToView(widget.group);
|
||||
},
|
||||
),
|
||||
await context.push(
|
||||
Routes.chatsCameraSendTo,
|
||||
extra: widget.group,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
|
@ -185,26 +179,18 @@ class _UserListItem extends State<GroupListItem> {
|
|||
}
|
||||
if (mediaFile.downloadState! == DownloadState.ready) {
|
||||
if (!mounted) return;
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return MediaViewerView(widget.group);
|
||||
},
|
||||
),
|
||||
await context.push(
|
||||
Routes.chatsMediaViewer,
|
||||
extra: widget.group,
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!mounted) return;
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return ChatMessagesView(widget.group);
|
||||
},
|
||||
),
|
||||
await context.push(
|
||||
Routes.chatsMessages,
|
||||
extra: widget.group,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -250,42 +236,27 @@ class _UserListItem extends State<GroupListItem> {
|
|||
),
|
||||
leading: GestureDetector(
|
||||
onTap: () async {
|
||||
Widget pushWidget = GroupView(widget.group);
|
||||
|
||||
if (widget.group.isDirectChat) {
|
||||
final contacts = await twonlyDB.groupsDao
|
||||
.getGroupContact(widget.group.groupId);
|
||||
pushWidget = ContactView(contacts.first.userId);
|
||||
if (!context.mounted) return;
|
||||
await context.push(Routes.profileContact(contacts.first.userId));
|
||||
return;
|
||||
} else {
|
||||
await context.push(Routes.profileGroup(widget.group.groupId));
|
||||
}
|
||||
if (!context.mounted) return;
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return pushWidget;
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
child: AvatarIcon(group: widget.group),
|
||||
),
|
||||
trailing: (widget.group.leftGroup)
|
||||
? null
|
||||
: IconButton(
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
if (_hasNonOpenedMediaFile) {
|
||||
return ChatMessagesView(widget.group);
|
||||
} else {
|
||||
return CameraSendToView(widget.group);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onPressed: () => context.push(
|
||||
_hasNonOpenedMediaFile
|
||||
? Routes.chatsMessages
|
||||
: Routes.chatsCameraSendTo,
|
||||
extra: widget.group,
|
||||
),
|
||||
icon: FaIcon(
|
||||
_hasNonOpenedMediaFile
|
||||
? FontAwesomeIcons.solidComments
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
import 'dart:async';
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:mutex/mutex.dart';
|
||||
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
|
||||
import 'package:twonly/globals.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/database/daos/contacts.dao.dart';
|
||||
import 'package:twonly/src/database/tables/messages.table.dart';
|
||||
import 'package:twonly/src/database/twonly.db.dart';
|
||||
|
|
@ -21,8 +22,6 @@ import 'package:twonly/src/views/components/avatar_icon.component.dart';
|
|||
import 'package:twonly/src/views/components/blink.component.dart';
|
||||
import 'package:twonly/src/views/components/flame.dart';
|
||||
import 'package:twonly/src/views/components/verified_shield.dart';
|
||||
import 'package:twonly/src/views/contact/contact.view.dart';
|
||||
import 'package:twonly/src/views/groups/group.view.dart';
|
||||
|
||||
Color getMessageColor(Message message) {
|
||||
return (message.senderId == null)
|
||||
|
|
@ -291,23 +290,10 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
|
|||
await twonlyDB.groupsDao.getAllGroupMembers(group.groupId);
|
||||
if (!context.mounted) return;
|
||||
if (member.isEmpty) return;
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return ContactView(member.first.contactId);
|
||||
},
|
||||
),
|
||||
);
|
||||
await context
|
||||
.push(Routes.profileContact(member.first.contactId));
|
||||
} else {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return GroupView(group);
|
||||
},
|
||||
),
|
||||
);
|
||||
await context.push(Routes.profileGroup(group.groupId));
|
||||
}
|
||||
},
|
||||
child: Row(
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:twonly/globals.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/database/tables/mediafiles.table.dart';
|
||||
import 'package:twonly/src/database/tables/messages.table.dart'
|
||||
hide MessageActions;
|
||||
|
|
@ -17,7 +19,6 @@ import 'package:twonly/src/views/chats/chat_messages_components/message_actions.
|
|||
import 'package:twonly/src/views/chats/chat_messages_components/message_context_menu.dart';
|
||||
import 'package:twonly/src/views/chats/chat_messages_components/response_container.dart';
|
||||
import 'package:twonly/src/views/components/avatar_icon.component.dart';
|
||||
import 'package:twonly/src/views/contact/contact.view.dart';
|
||||
|
||||
class ChatListEntry extends StatefulWidget {
|
||||
const ChatListEntry({
|
||||
|
|
@ -204,15 +205,9 @@ class _ChatListEntryState extends State<ChatListEntry> {
|
|||
hideContactAvatar
|
||||
? const SizedBox(width: 24)
|
||||
: GestureDetector(
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
ContactView(widget.message.senderId!),
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(
|
||||
Routes.profileContact(widget.message.senderId!),
|
||||
),
|
||||
child: AvatarIcon(
|
||||
contactId: widget.message.senderId,
|
||||
fontSize: 12,
|
||||
|
|
|
|||
|
|
@ -2,13 +2,14 @@ import 'dart:collection';
|
|||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/database/daos/contacts.dao.dart';
|
||||
import 'package:twonly/src/database/tables/mediafiles.table.dart';
|
||||
import 'package:twonly/src/database/tables/messages.table.dart';
|
||||
import 'package:twonly/src/database/twonly.db.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/views/components/animate_icon.dart';
|
||||
import 'package:twonly/src/views/settings/subscription/subscription.view.dart';
|
||||
|
||||
enum MessageSendState {
|
||||
received,
|
||||
|
|
@ -163,16 +164,7 @@ class _MessageSendStateIconState extends State<MessageSendStateIcon> {
|
|||
style: const TextStyle(fontSize: 9),
|
||||
);
|
||||
|
||||
onTap = () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const SubscriptionView();
|
||||
},
|
||||
),
|
||||
);
|
||||
};
|
||||
onTap = () => context.push(Routes.settingsSubscription);
|
||||
}
|
||||
if (mediaFile.uploadState == UploadState.preprocessing ||
|
||||
mediaFile.uploadState == UploadState.initialized) {
|
||||
|
|
|
|||
|
|
@ -2,17 +2,17 @@ import 'dart:async';
|
|||
import 'package:drift/drift.dart' hide Column;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:twonly/globals.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/database/daos/contacts.dao.dart';
|
||||
import 'package:twonly/src/database/twonly.db.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/views/chats/add_new_user.view.dart';
|
||||
import 'package:twonly/src/views/chats/chat_messages.view.dart';
|
||||
import 'package:twonly/src/views/components/avatar_icon.component.dart';
|
||||
import 'package:twonly/src/views/components/flame.dart';
|
||||
import 'package:twonly/src/views/components/group_context_menu.component.dart';
|
||||
import 'package:twonly/src/views/components/user_context_menu.component.dart';
|
||||
import 'package:twonly/src/views/groups/group_create_select_members.view.dart';
|
||||
|
||||
class StartNewChatView extends StatefulWidget {
|
||||
const StartNewChatView({super.key});
|
||||
|
|
@ -165,15 +165,8 @@ class _StartNewChatView extends State<StartNewChatView> {
|
|||
size: 13,
|
||||
),
|
||||
),
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
const GroupCreateSelectMembersView(),
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context
|
||||
.push(Routes.groupCreateSelectMember(null)),
|
||||
);
|
||||
}
|
||||
if (i == 1) {
|
||||
|
|
@ -185,14 +178,7 @@ class _StartNewChatView extends State<StartNewChatView> {
|
|||
size: 13,
|
||||
),
|
||||
),
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const AddNewUserView(),
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(Routes.chatsAddNewUser),
|
||||
);
|
||||
}
|
||||
if (i == 2) {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import 'package:drift/drift.dart' hide Column;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:twonly/globals.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/database/twonly.db.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/views/chats/chat_messages.view.dart';
|
||||
import 'package:twonly/src/views/components/alert_dialog.dart';
|
||||
import 'package:twonly/src/views/components/context_menu.component.dart';
|
||||
|
||||
|
|
@ -45,16 +46,10 @@ class GroupContextMenu extends StatelessWidget {
|
|||
),
|
||||
ContextMenuItem(
|
||||
title: context.lang.contextMenuOpenChat,
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return ChatMessagesView(group);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(
|
||||
Routes.chatsMessages,
|
||||
extra: group,
|
||||
),
|
||||
icon: FontAwesomeIcons.comments,
|
||||
),
|
||||
if (!group.archived)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@ import 'dart:async';
|
|||
import 'package:clock/clock.dart';
|
||||
import 'package:drift/drift.dart' show Value;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:twonly/globals.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/database/twonly.db.dart';
|
||||
import 'package:twonly/src/services/flame.service.dart';
|
||||
import 'package:twonly/src/services/subscription.service.dart';
|
||||
|
|
@ -10,7 +12,6 @@ import 'package:twonly/src/utils/log.dart';
|
|||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/views/components/animate_icon.dart';
|
||||
import 'package:twonly/src/views/components/better_list_title.dart';
|
||||
import 'package:twonly/src/views/settings/subscription/subscription.view.dart';
|
||||
|
||||
class MaxFlameListTitle extends StatefulWidget {
|
||||
const MaxFlameListTitle({
|
||||
|
|
@ -46,14 +47,7 @@ class _MaxFlameListTitleState extends State<MaxFlameListTitle> {
|
|||
|
||||
Future<void> _restoreFlames() async {
|
||||
if (!isPayingUser(getCurrentPlan())) {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const SubscriptionView();
|
||||
},
|
||||
),
|
||||
);
|
||||
await context.push(Routes.settingsSubscription);
|
||||
return;
|
||||
}
|
||||
Log.info(
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/database/twonly.db.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/views/components/context_menu.component.dart';
|
||||
import 'package:twonly/src/views/contact/contact.view.dart';
|
||||
|
||||
class UserContextMenu extends StatelessWidget {
|
||||
const UserContextMenu({
|
||||
|
|
@ -20,16 +21,7 @@ class UserContextMenu extends StatelessWidget {
|
|||
items: [
|
||||
ContextMenuItem(
|
||||
title: context.lang.contextMenuUserProfile,
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return ContactView(contact.userId);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(Routes.profileContact(contact.userId)),
|
||||
icon: FontAwesomeIcons.user,
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:twonly/globals.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/database/twonly.db.dart';
|
||||
import 'package:twonly/src/views/public_profile.view.dart';
|
||||
|
||||
class VerifiedShield extends StatefulWidget {
|
||||
const VerifiedShield({
|
||||
|
|
@ -58,16 +59,7 @@ class _VerifiedShieldState extends State<VerifiedShield> {
|
|||
return GestureDetector(
|
||||
onTap: (contact == null)
|
||||
? null
|
||||
: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const PublicProfileView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
: () => context.push(Routes.settingsPublicProfile),
|
||||
child: Tooltip(
|
||||
message: isVerified
|
||||
? 'You verified this contact'
|
||||
|
|
|
|||
|
|
@ -19,16 +19,16 @@ import 'package:twonly/src/views/groups/group_member.context.dart';
|
|||
import 'package:twonly/src/views/settings/profile/profile.view.dart';
|
||||
|
||||
class GroupView extends StatefulWidget {
|
||||
const GroupView(this.group, {super.key});
|
||||
const GroupView(this.groupId, {super.key});
|
||||
|
||||
final Group group;
|
||||
final String groupId;
|
||||
|
||||
@override
|
||||
State<GroupView> createState() => _GroupViewState();
|
||||
}
|
||||
|
||||
class _GroupViewState extends State<GroupView> {
|
||||
late Group group;
|
||||
Group? _group;
|
||||
|
||||
List<(Contact, GroupMember)> members = [];
|
||||
|
||||
|
|
@ -37,7 +37,6 @@ class _GroupViewState extends State<GroupView> {
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
group = widget.group;
|
||||
initAsync();
|
||||
super.initState();
|
||||
}
|
||||
|
|
@ -50,16 +49,15 @@ class _GroupViewState extends State<GroupView> {
|
|||
}
|
||||
|
||||
Future<void> initAsync() async {
|
||||
final groupStream = twonlyDB.groupsDao.watchGroup(widget.group.groupId);
|
||||
final groupStream = twonlyDB.groupsDao.watchGroup(widget.groupId);
|
||||
groupSub = groupStream.listen((update) {
|
||||
if (update != null) {
|
||||
setState(() {
|
||||
group = update;
|
||||
_group = update;
|
||||
});
|
||||
}
|
||||
});
|
||||
final membersStream =
|
||||
twonlyDB.groupsDao.watchGroupMembers(widget.group.groupId);
|
||||
final membersStream = twonlyDB.groupsDao.watchGroupMembers(widget.groupId);
|
||||
membersSub = membersStream.listen((update) {
|
||||
setState(() {
|
||||
members = update;
|
||||
|
|
@ -71,13 +69,13 @@ class _GroupViewState extends State<GroupView> {
|
|||
}
|
||||
|
||||
Future<void> _updateGroupName() async {
|
||||
final newGroupName = await showGroupNameChangeDialog(context, group);
|
||||
final newGroupName = await showGroupNameChangeDialog(context, _group!);
|
||||
|
||||
if (context.mounted &&
|
||||
newGroupName != null &&
|
||||
newGroupName != '' &&
|
||||
newGroupName != group.groupName) {
|
||||
if (!await updateGroupName(group, newGroupName)) {
|
||||
newGroupName != _group!.groupName) {
|
||||
if (!await updateGroupName(_group!, newGroupName)) {
|
||||
if (mounted) {
|
||||
showNetworkIssue(context);
|
||||
}
|
||||
|
|
@ -89,11 +87,13 @@ class _GroupViewState extends State<GroupView> {
|
|||
final selectedUserIds = await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => GroupCreateSelectMembersView(group: group),
|
||||
builder: (context) => GroupCreateSelectMembersView(
|
||||
groupId: _group?.groupId,
|
||||
),
|
||||
),
|
||||
) as List<int>?;
|
||||
if (selectedUserIds == null) return;
|
||||
if (!await addNewGroupMembers(group, selectedUserIds)) {
|
||||
if (!await addNewGroupMembers(_group!, selectedUserIds)) {
|
||||
if (mounted) {
|
||||
showNetworkIssue(context);
|
||||
}
|
||||
|
|
@ -115,7 +115,7 @@ class _GroupViewState extends State<GroupView> {
|
|||
if (members.isNotEmpty) {
|
||||
// In case there are other members, check that there is at least one other admin before I leave the group.
|
||||
|
||||
if (group.isGroupAdmin) {
|
||||
if (_group!.isGroupAdmin) {
|
||||
if (!members.any((m) => m.$2.memberState == MemberState.admin)) {
|
||||
if (!mounted) return;
|
||||
await showAlertDialog(
|
||||
|
|
@ -131,16 +131,17 @@ class _GroupViewState extends State<GroupView> {
|
|||
|
||||
late bool success;
|
||||
|
||||
if (group.isGroupAdmin) {
|
||||
if (_group!.isGroupAdmin) {
|
||||
// Current user is a admin, to the state can be updated by the user him self.
|
||||
final keyPair = IdentityKeyPair.fromSerialized(group.myGroupPrivateKey!);
|
||||
final keyPair =
|
||||
IdentityKeyPair.fromSerialized(_group!.myGroupPrivateKey!);
|
||||
success = await removeMemberFromGroup(
|
||||
group,
|
||||
_group!,
|
||||
keyPair.getPublicKey().serialize(),
|
||||
gUser.userId,
|
||||
);
|
||||
} else {
|
||||
success = await leaveAsNonAdminFromGroup(group);
|
||||
success = await leaveAsNonAdminFromGroup(_group!);
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
|
|
@ -153,6 +154,9 @@ class _GroupViewState extends State<GroupView> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (_group == null) {
|
||||
return Container();
|
||||
}
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text(''),
|
||||
|
|
@ -162,7 +166,7 @@ class _GroupViewState extends State<GroupView> {
|
|||
Padding(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: AvatarIcon(
|
||||
group: group,
|
||||
group: _group,
|
||||
fontSize: 30,
|
||||
),
|
||||
),
|
||||
|
|
@ -171,24 +175,24 @@ class _GroupViewState extends State<GroupView> {
|
|||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 10),
|
||||
child: VerifiedShield(key: Key(group.groupId), group: group),
|
||||
child: VerifiedShield(key: Key(_group!.groupId), group: _group),
|
||||
),
|
||||
Text(
|
||||
substringBy(group.groupName, 25),
|
||||
substringBy(_group!.groupName, 25),
|
||||
style: const TextStyle(fontSize: 20),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 50),
|
||||
if (group.isGroupAdmin && !group.leftGroup)
|
||||
if (_group!.isGroupAdmin && !_group!.leftGroup)
|
||||
BetterListTile(
|
||||
icon: FontAwesomeIcons.pencil,
|
||||
text: context.lang.groupNameInput,
|
||||
onTap: _updateGroupName,
|
||||
),
|
||||
SelectChatDeletionTimeListTitle(
|
||||
groupId: widget.group.groupId,
|
||||
disabled: !group.isGroupAdmin,
|
||||
groupId: widget.groupId,
|
||||
disabled: !_group!.isGroupAdmin,
|
||||
),
|
||||
const Divider(),
|
||||
ListTile(
|
||||
|
|
@ -203,7 +207,7 @@ class _GroupViewState extends State<GroupView> {
|
|||
),
|
||||
),
|
||||
),
|
||||
if (group.isGroupAdmin && !group.leftGroup)
|
||||
if (_group!.isGroupAdmin && !_group!.leftGroup)
|
||||
BetterListTile(
|
||||
icon: FontAwesomeIcons.plus,
|
||||
text: context.lang.addMember,
|
||||
|
|
@ -216,7 +220,7 @@ class _GroupViewState extends State<GroupView> {
|
|||
fontSize: 16,
|
||||
),
|
||||
text: context.lang.you,
|
||||
trailing: (group.isGroupAdmin) ? Text(context.lang.admin) : null,
|
||||
trailing: (_group!.isGroupAdmin) ? Text(context.lang.admin) : null,
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
|
|
@ -229,7 +233,7 @@ class _GroupViewState extends State<GroupView> {
|
|||
...members.map((member) {
|
||||
return GroupMemberContextMenu(
|
||||
key: ValueKey(member.$1.userId),
|
||||
group: group,
|
||||
group: _group!,
|
||||
contact: member.$1,
|
||||
member: member.$2,
|
||||
child: BetterListTile(
|
||||
|
|
@ -256,7 +260,7 @@ class _GroupViewState extends State<GroupView> {
|
|||
const SizedBox(height: 10),
|
||||
const Divider(),
|
||||
const SizedBox(height: 10),
|
||||
if (!group.leftGroup)
|
||||
if (!_group!.leftGroup)
|
||||
BetterListTile(
|
||||
icon: FontAwesomeIcons.rightFromBracket,
|
||||
color: Colors.red,
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ import 'package:twonly/src/views/components/user_context_menu.component.dart';
|
|||
import 'package:twonly/src/views/groups/group_create_select_group_name.view.dart';
|
||||
|
||||
class GroupCreateSelectMembersView extends StatefulWidget {
|
||||
const GroupCreateSelectMembersView({this.group, super.key});
|
||||
final Group? group;
|
||||
const GroupCreateSelectMembersView({this.groupId, super.key});
|
||||
final String? groupId;
|
||||
@override
|
||||
State<GroupCreateSelectMembersView> createState() => _StartNewChatView();
|
||||
}
|
||||
|
|
@ -46,9 +46,8 @@ class _StartNewChatView extends State<GroupCreateSelectMembersView> {
|
|||
}
|
||||
|
||||
Future<void> initAsync() async {
|
||||
if (widget.group != null) {
|
||||
final members =
|
||||
await twonlyDB.groupsDao.getGroupContact(widget.group!.groupId);
|
||||
if (widget.groupId != null) {
|
||||
final members = await twonlyDB.groupsDao.getGroupContact(widget.groupId!);
|
||||
for (final member in members) {
|
||||
alreadyInGroup.add(member.userId);
|
||||
}
|
||||
|
|
@ -101,7 +100,7 @@ class _StartNewChatView extends State<GroupCreateSelectMembersView> {
|
|||
}
|
||||
|
||||
Future<void> submitChanges() async {
|
||||
if (widget.group != null) {
|
||||
if (widget.groupId != null) {
|
||||
Navigator.pop(context, selectedUsers.toList());
|
||||
return;
|
||||
}
|
||||
|
|
@ -125,7 +124,7 @@ class _StartNewChatView extends State<GroupCreateSelectMembersView> {
|
|||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
widget.group == null
|
||||
widget.groupId == null
|
||||
? context.lang.selectMembers
|
||||
: context.lang.addMember,
|
||||
),
|
||||
|
|
@ -133,7 +132,9 @@ class _StartNewChatView extends State<GroupCreateSelectMembersView> {
|
|||
floatingActionButton: FilledButton.icon(
|
||||
onPressed: selectedUsers.isEmpty ? null : submitChanges,
|
||||
label: Text(
|
||||
widget.group == null ? context.lang.next : context.lang.updateGroup,
|
||||
widget.groupId == null
|
||||
? context.lang.next
|
||||
: context.lang.updateGroup,
|
||||
),
|
||||
icon: const FaIcon(FontAwesomeIcons.penToSquare),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import 'package:drift/drift.dart' show Value;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:twonly/globals.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/database/daos/contacts.dao.dart';
|
||||
import 'package:twonly/src/database/tables/groups.table.dart';
|
||||
import 'package:twonly/src/database/twonly.db.dart';
|
||||
|
|
@ -9,7 +11,6 @@ import 'package:twonly/src/model/protobuf/client/generated/messages.pb.dart';
|
|||
import 'package:twonly/src/services/api/messages.dart';
|
||||
import 'package:twonly/src/services/group.services.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/views/chats/chat_messages.view.dart';
|
||||
import 'package:twonly/src/views/components/alert_dialog.dart';
|
||||
import 'package:twonly/src/views/components/context_menu.component.dart';
|
||||
import 'package:twonly/src/views/groups/group.view.dart';
|
||||
|
|
@ -128,12 +129,7 @@ class GroupMemberContextMenu extends StatelessWidget {
|
|||
return;
|
||||
}
|
||||
if (!context.mounted) return;
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ChatMessagesView(directChat),
|
||||
),
|
||||
);
|
||||
await context.push(Routes.chatsMessages, extra: directChat);
|
||||
},
|
||||
icon: FontAwesomeIcons.message,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import 'dart:async';
|
|||
import 'package:app_links/app_links.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||
import 'package:flutter_sharing_intent/flutter_sharing_intent.dart';
|
||||
import 'package:flutter_sharing_intent/model/sharing_file.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:twonly/globals.dart';
|
||||
|
|
@ -126,31 +125,10 @@ class HomeViewState extends State<HomeView> {
|
|||
}
|
||||
});
|
||||
|
||||
_intentStreamSub = FlutterSharingIntent.instance.getMediaStream().listen(
|
||||
(f) {
|
||||
if (mounted) {
|
||||
handleIntentSharedFile(
|
||||
context,
|
||||
f,
|
||||
_mainCameraController.setSharedLinkForPreview,
|
||||
);
|
||||
}
|
||||
},
|
||||
// ignore: inference_failure_on_untyped_parameter
|
||||
onError: (err) {
|
||||
Log.error('getIntentDataStream error: $err');
|
||||
},
|
||||
_intentStreamSub = initIntentStreams(
|
||||
context,
|
||||
_mainCameraController.setSharedLinkForPreview,
|
||||
);
|
||||
|
||||
FlutterSharingIntent.instance.getInitialSharing().then((f) {
|
||||
if (mounted) {
|
||||
handleIntentSharedFile(
|
||||
context,
|
||||
f,
|
||||
_mainCameraController.setSharedLinkForPreview,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:restart_app/restart_app.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/model/json/userdata.dart';
|
||||
import 'package:twonly/src/services/twonly_safe/restore.twonly_safe.dart';
|
||||
import 'package:twonly/src/utils/log.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/views/components/alert_dialog.dart';
|
||||
import 'package:twonly/src/views/settings/backup/twonly_safe_server.view.dart';
|
||||
|
||||
class BackupRecoveryView extends StatefulWidget {
|
||||
const BackupRecoveryView({super.key});
|
||||
|
|
@ -135,14 +136,8 @@ class _BackupRecoveryViewState extends State<BackupRecoveryView> {
|
|||
Center(
|
||||
child: OutlinedButton(
|
||||
onPressed: () async {
|
||||
backupServer = await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const TwonlySafeServerView();
|
||||
},
|
||||
),
|
||||
);
|
||||
backupServer =
|
||||
await context.push(Routes.settingsBackupServer);
|
||||
setState(() {});
|
||||
},
|
||||
child: Text(context.lang.backupExpertSettings),
|
||||
|
|
|
|||
|
|
@ -2,11 +2,12 @@
|
|||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:twonly/globals.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/constants/secure_storage_keys.dart';
|
||||
import 'package:twonly/src/model/json/userdata.dart';
|
||||
import 'package:twonly/src/model/protobuf/api/websocket/error.pb.dart';
|
||||
|
|
@ -17,7 +18,6 @@ import 'package:twonly/src/utils/pow.dart';
|
|||
import 'package:twonly/src/utils/storage.dart';
|
||||
import 'package:twonly/src/views/components/alert_dialog.dart';
|
||||
import 'package:twonly/src/views/groups/group.view.dart';
|
||||
import 'package:twonly/src/views/onboarding/recover.view.dart';
|
||||
|
||||
class RegisterView extends StatefulWidget {
|
||||
const RegisterView({
|
||||
|
|
@ -302,16 +302,8 @@ class _RegisterViewState extends State<RegisterView> {
|
|||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
OutlinedButton.icon(
|
||||
onPressed: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const BackupRecoveryView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onPressed: () =>
|
||||
context.push(Routes.settingsBackupRecovery),
|
||||
label: Text(context.lang.twonlySafeRecoverBtn),
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:qr_flutter/qr_flutter.dart';
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
import 'package:twonly/globals.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/utils/avatars.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/utils/qr.dart';
|
||||
import 'package:twonly/src/views/camera/camera_qr_scanner.view.dart';
|
||||
import 'package:twonly/src/views/components/better_list_title.dart';
|
||||
|
||||
class PublicProfileView extends StatefulWidget {
|
||||
|
|
@ -96,14 +96,7 @@ class _PublicProfileViewState extends State<PublicProfileView> {
|
|||
BetterListTile(
|
||||
leading: const FaIcon(FontAwesomeIcons.qrcode),
|
||||
text: context.lang.scanOtherProfile,
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const QrCodeScanner(),
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(Routes.cameraQRScanner),
|
||||
),
|
||||
BetterListTile(
|
||||
leading: const FaIcon(
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:twonly/globals.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/model/json/userdata.dart';
|
||||
import 'package:twonly/src/services/twonly_safe/create_backup.twonly_safe.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/views/settings/backup/twonly_safe_backup.view.dart';
|
||||
|
||||
void Function() gUpdateBackupView = () {};
|
||||
|
||||
|
|
@ -60,16 +61,7 @@ class _BackupViewState extends State<BackupView> {
|
|||
}
|
||||
|
||||
Future<void> changeTwonlySafePassword() async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const TwonlyIdentityBackupView(
|
||||
isPasswordChangeOnly: true,
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
await context.push(Routes.settingsBackupSetup, extra: true);
|
||||
setState(() {
|
||||
// gUser was updated
|
||||
});
|
||||
|
|
|
|||
|
|
@ -11,14 +11,14 @@ import 'package:twonly/src/utils/log.dart';
|
|||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/utils/storage.dart';
|
||||
|
||||
class TwonlySafeServerView extends StatefulWidget {
|
||||
const TwonlySafeServerView({super.key});
|
||||
class BackupServerView extends StatefulWidget {
|
||||
const BackupServerView({super.key});
|
||||
|
||||
@override
|
||||
State<TwonlySafeServerView> createState() => _TwonlySafeServerViewState();
|
||||
State<BackupServerView> createState() => _BackupServerViewState();
|
||||
}
|
||||
|
||||
class _TwonlySafeServerViewState extends State<TwonlySafeServerView> {
|
||||
class _BackupServerViewState extends State<BackupServerView> {
|
||||
final TextEditingController _urlController = TextEditingController();
|
||||
final TextEditingController _usernameController = TextEditingController();
|
||||
final TextEditingController _passwordController = TextEditingController();
|
||||
|
|
@ -2,13 +2,14 @@ import 'package:flutter/foundation.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart' show rootBundle;
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/services/twonly_safe/common.twonly_safe.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/views/components/alert_dialog.dart';
|
||||
import 'package:twonly/src/views/settings/backup/twonly_safe_server.view.dart';
|
||||
|
||||
class TwonlyIdentityBackupView extends StatefulWidget {
|
||||
const TwonlyIdentityBackupView({
|
||||
class SetupBackupView extends StatefulWidget {
|
||||
const SetupBackupView({
|
||||
this.isPasswordChangeOnly = false,
|
||||
this.callBack,
|
||||
super.key,
|
||||
|
|
@ -20,11 +21,10 @@ class TwonlyIdentityBackupView extends StatefulWidget {
|
|||
final bool isPasswordChangeOnly;
|
||||
|
||||
@override
|
||||
State<TwonlyIdentityBackupView> createState() =>
|
||||
_TwonlyIdentityBackupViewState();
|
||||
State<SetupBackupView> createState() => _SetupBackupViewState();
|
||||
}
|
||||
|
||||
class _TwonlyIdentityBackupViewState extends State<TwonlyIdentityBackupView> {
|
||||
class _SetupBackupViewState extends State<SetupBackupView> {
|
||||
bool obscureText = true;
|
||||
bool isLoading = false;
|
||||
final TextEditingController passwordCtrl = TextEditingController();
|
||||
|
|
@ -179,16 +179,7 @@ class _TwonlyIdentityBackupViewState extends State<TwonlyIdentityBackupView> {
|
|||
const SizedBox(height: 10),
|
||||
Center(
|
||||
child: OutlinedButton(
|
||||
onPressed: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const TwonlySafeServerView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onPressed: () => context.push(Routes.settingsBackupServer),
|
||||
child: Text(context.lang.backupExpertSettings),
|
||||
),
|
||||
),
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/views/settings/chat/chat_reactions.view.dart';
|
||||
|
||||
class ChatSettingsView extends StatefulWidget {
|
||||
const ChatSettingsView({super.key});
|
||||
|
|
@ -25,16 +26,7 @@ class _ChatSettingsViewState extends State<ChatSettingsView> {
|
|||
children: [
|
||||
ListTile(
|
||||
title: Text(context.lang.settingsPreSelectedReactions),
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const ChatReactionSelectionView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(Routes.settingsChatsReactions),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:twonly/globals.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/services/api/mediafiles/download.service.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/utils/storage.dart';
|
||||
import 'package:twonly/src/views/settings/data_and_storage/export_media.view.dart';
|
||||
import 'package:twonly/src/views/settings/data_and_storage/import_media.view.dart';
|
||||
|
||||
class DataAndStorageView extends StatefulWidget {
|
||||
const DataAndStorageView({super.key});
|
||||
|
|
@ -91,32 +90,14 @@ class _DataAndStorageViewState extends State<DataAndStorageView> {
|
|||
title: Text(
|
||||
context.lang.exportMemories,
|
||||
),
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (_) {
|
||||
return const ExportMediaView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(Routes.settingsStorageExport),
|
||||
),
|
||||
if (Platform.isAndroid)
|
||||
ListTile(
|
||||
title: Text(
|
||||
context.lang.importMemories,
|
||||
),
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (_) {
|
||||
return const ImportMediaView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(Routes.settingsStorageImport),
|
||||
),
|
||||
const Divider(),
|
||||
ListTile(
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import 'dart:async';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:restart_app/restart_app.dart';
|
||||
import 'package:twonly/globals.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/utils/storage.dart';
|
||||
import 'package:twonly/src/views/components/alert_dialog.dart';
|
||||
import 'package:twonly/src/views/settings/developer/automated_testing.view.dart';
|
||||
import 'package:twonly/src/views/settings/developer/retransmission_data.view.dart';
|
||||
|
||||
class DeveloperSettingsView extends StatefulWidget {
|
||||
const DeveloperSettingsView({super.key});
|
||||
|
|
@ -55,16 +55,8 @@ class _DeveloperSettingsViewState extends State<DeveloperSettingsView> {
|
|||
),
|
||||
ListTile(
|
||||
title: const Text('Show Retransmission Database'),
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const RetransmissionDataView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () =>
|
||||
context.push(Routes.settingsDeveloperRetransmissionDatabase),
|
||||
),
|
||||
ListTile(
|
||||
title: const Text('Delete all (!) app data'),
|
||||
|
|
@ -97,16 +89,8 @@ class _DeveloperSettingsViewState extends State<DeveloperSettingsView> {
|
|||
if (!kReleaseMode)
|
||||
ListTile(
|
||||
title: const Text('Automated Testing'),
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const AutomatedTestingView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () =>
|
||||
context.push(Routes.settingsDeveloperAutomatedTesting),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,17 +1,13 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:twonly/globals.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/utils/storage.dart';
|
||||
import 'package:twonly/src/views/components/alert_dialog.dart';
|
||||
import 'package:twonly/src/views/settings/help/changelog.view.dart';
|
||||
import 'package:twonly/src/views/settings/help/contact_us.view.dart';
|
||||
import 'package:twonly/src/views/settings/help/credits.view.dart';
|
||||
import 'package:twonly/src/views/settings/help/diagnostics.view.dart';
|
||||
import 'package:twonly/src/views/settings/help/faq.view.dart';
|
||||
import 'package:twonly/src/views/user_study/user_study_welcome.view.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class HelpView extends StatefulWidget {
|
||||
|
|
@ -40,50 +36,12 @@ class _HelpViewState extends State<HelpView> {
|
|||
children: [
|
||||
ListTile(
|
||||
title: Text(context.lang.settingsHelpFAQ),
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const FaqView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(Routes.settingsHelpFaq),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(context.lang.settingsHelpContactUs),
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const ContactUsView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(Routes.settingsHelpContactUs),
|
||||
),
|
||||
// ListTile(
|
||||
// title: Text(context.lang.settingsResetTutorials),
|
||||
// subtitle: Text(
|
||||
// context.lang.settingsResetTutorialsDesc,
|
||||
// style: const TextStyle(fontSize: 12),
|
||||
// ),
|
||||
// onTap: () async {
|
||||
// await updateUserdata((user) {
|
||||
// user.tutorialDisplayed = [];
|
||||
// return user;
|
||||
// });
|
||||
// if (!context.mounted) return;
|
||||
// ScaffoldMessenger.of(context).showSnackBar(
|
||||
// SnackBar(
|
||||
// content: Text(context.lang.settingsResetTutorialsSuccess),
|
||||
// duration: const Duration(seconds: 3),
|
||||
// ),
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
const Divider(),
|
||||
ListTile(
|
||||
title: Text(context.lang.allowErrorTracking),
|
||||
|
|
@ -99,32 +57,13 @@ class _HelpViewState extends State<HelpView> {
|
|||
),
|
||||
ListTile(
|
||||
title: Text(context.lang.settingsHelpDiagnostics),
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const DiagnosticsView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(Routes.settingsHelpDiagnostics),
|
||||
),
|
||||
const Divider(),
|
||||
if (gUser.userStudyParticipantsToken == null || kDebugMode)
|
||||
ListTile(
|
||||
title: const Text('Teilnahme an Nutzerstudie'),
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const UserStudyWelcomeView();
|
||||
},
|
||||
),
|
||||
);
|
||||
setState(() {}); // gUser has changed
|
||||
},
|
||||
onTap: () => context.push(Routes.settingsHelpUserStudy),
|
||||
),
|
||||
FutureBuilder(
|
||||
future: PackageInfo.fromPlatform(),
|
||||
|
|
@ -141,59 +80,34 @@ class _HelpViewState extends State<HelpView> {
|
|||
),
|
||||
ListTile(
|
||||
title: Text(context.lang.settingsHelpLicenses),
|
||||
onTap: () {
|
||||
showLicensePage(context: context);
|
||||
},
|
||||
onTap: () => showLicensePage(context: context),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(context.lang.settingsHelpCredits),
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const CreditsView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(Routes.settingsHelpCredits),
|
||||
),
|
||||
ListTile(
|
||||
title: const Text('Changelog'),
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const ChangeLogView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(Routes.settingsHelpChangelog),
|
||||
),
|
||||
ListTile(
|
||||
title: const Text('Open Source'),
|
||||
onTap: () async {
|
||||
await launchUrl(
|
||||
Uri.parse('https://github.com/twonlyapp/twonly-app'),
|
||||
);
|
||||
},
|
||||
onTap: () => launchUrl(
|
||||
Uri.parse('https://github.com/twonlyapp/twonly-app'),
|
||||
),
|
||||
trailing:
|
||||
const FaIcon(FontAwesomeIcons.arrowUpRightFromSquare, size: 15),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(context.lang.settingsHelpImprint),
|
||||
onTap: () async {
|
||||
await launchUrl(Uri.parse('https://twonly.eu/de/legal/'));
|
||||
},
|
||||
onTap: () => launchUrl(Uri.parse('https://twonly.eu/de/legal/')),
|
||||
trailing:
|
||||
const FaIcon(FontAwesomeIcons.arrowUpRightFromSquare, size: 15),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(context.lang.settingsHelpTerms),
|
||||
onTap: () async {
|
||||
await launchUrl(Uri.parse('https://twonly.eu/de/legal/agb.html'));
|
||||
},
|
||||
onTap: () =>
|
||||
launchUrl(Uri.parse('https://twonly.eu/de/legal/agb.html')),
|
||||
trailing:
|
||||
const FaIcon(FontAwesomeIcons.arrowUpRightFromSquare, size: 15),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:twonly/globals.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/views/settings/privacy_view_block.users.dart';
|
||||
|
||||
class PrivacyView extends StatefulWidget {
|
||||
const PrivacyView({super.key});
|
||||
|
|
@ -40,16 +41,7 @@ class _PrivacyViewState extends State<PrivacyView> {
|
|||
}
|
||||
},
|
||||
),
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const PrivacyViewBlockUsers();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(Routes.settingsPrivacyBlockUsers),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -7,14 +7,14 @@ import 'package:twonly/src/utils/misc.dart';
|
|||
import 'package:twonly/src/views/components/avatar_icon.component.dart';
|
||||
import 'package:twonly/src/views/components/user_context_menu.component.dart';
|
||||
|
||||
class PrivacyViewBlockUsers extends StatefulWidget {
|
||||
const PrivacyViewBlockUsers({super.key});
|
||||
class PrivacyViewBlockUsersView extends StatefulWidget {
|
||||
const PrivacyViewBlockUsersView({super.key});
|
||||
|
||||
@override
|
||||
State<PrivacyViewBlockUsers> createState() => _PrivacyViewBlockUsers();
|
||||
State<PrivacyViewBlockUsersView> createState() => _PrivacyViewBlockUsers();
|
||||
}
|
||||
|
||||
class _PrivacyViewBlockUsers extends State<PrivacyViewBlockUsers> {
|
||||
class _PrivacyViewBlockUsers extends State<PrivacyViewBlockUsersView> {
|
||||
late Stream<List<Contact>> allUsers;
|
||||
List<Contact> filteredUsers = [];
|
||||
String filter = '';
|
||||
|
|
@ -6,14 +6,14 @@ import 'package:twonly/globals.dart';
|
|||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/utils/storage.dart';
|
||||
|
||||
class ModifyAvatar extends StatefulWidget {
|
||||
const ModifyAvatar({super.key});
|
||||
class ModifyAvatarView extends StatefulWidget {
|
||||
const ModifyAvatarView({super.key});
|
||||
|
||||
@override
|
||||
State<ModifyAvatar> createState() => _ModifyAvatarState();
|
||||
State<ModifyAvatarView> createState() => _ModifyAvatarViewState();
|
||||
}
|
||||
|
||||
class _ModifyAvatarState extends State<ModifyAvatar> {
|
||||
class _ModifyAvatarViewState extends State<ModifyAvatarView> {
|
||||
final AvatarMakerController _avatarMakerController =
|
||||
PersistentAvatarMakerController(customizedPropertyCategories: []);
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@ import 'package:avatar_maker/avatar_maker.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:twonly/globals.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/model/protobuf/api/websocket/error.pb.dart';
|
||||
import 'package:twonly/src/services/twonly_safe/common.twonly_safe.dart';
|
||||
import 'package:twonly/src/services/twonly_safe/create_backup.twonly_safe.dart';
|
||||
|
|
@ -11,7 +13,6 @@ import 'package:twonly/src/utils/misc.dart';
|
|||
import 'package:twonly/src/utils/storage.dart';
|
||||
import 'package:twonly/src/views/components/better_list_title.dart';
|
||||
import 'package:twonly/src/views/groups/group.view.dart';
|
||||
import 'package:twonly/src/views/settings/profile/modify_avatar.view.dart';
|
||||
|
||||
class ProfileView extends StatefulWidget {
|
||||
const ProfileView({super.key});
|
||||
|
|
@ -110,12 +111,7 @@ class _ProfileViewState extends State<ProfileView> {
|
|||
icon: const Icon(Icons.edit),
|
||||
label: Text(context.lang.settingsProfileCustomizeAvatar),
|
||||
onPressed: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const ModifyAvatar(),
|
||||
),
|
||||
);
|
||||
await context.push(Routes.settingsProfileModifyAvatar);
|
||||
await _avatarMakerController.performRestore();
|
||||
setState(() {});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,23 +1,12 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:twonly/globals.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/database/daos/contacts.dao.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/views/components/avatar_icon.component.dart';
|
||||
import 'package:twonly/src/views/components/better_list_title.dart';
|
||||
import 'package:twonly/src/views/public_profile.view.dart';
|
||||
import 'package:twonly/src/views/settings/account.view.dart';
|
||||
import 'package:twonly/src/views/settings/appearance.view.dart';
|
||||
import 'package:twonly/src/views/settings/backup/backup.view.dart';
|
||||
import 'package:twonly/src/views/settings/chat/chat_settings.view.dart';
|
||||
import 'package:twonly/src/views/settings/data_and_storage.view.dart';
|
||||
import 'package:twonly/src/views/settings/developer/developer.view.dart';
|
||||
import 'package:twonly/src/views/settings/help/help.view.dart';
|
||||
import 'package:twonly/src/views/settings/notification.view.dart';
|
||||
import 'package:twonly/src/views/settings/privacy.view.dart';
|
||||
import 'package:twonly/src/views/settings/profile/profile.view.dart';
|
||||
import 'package:twonly/src/views/settings/share_with_friends.view.dart';
|
||||
import 'package:twonly/src/views/settings/subscription/subscription.view.dart';
|
||||
|
||||
class SettingsMainView extends StatefulWidget {
|
||||
const SettingsMainView({super.key});
|
||||
|
|
@ -42,14 +31,7 @@ class _SettingsMainViewState extends State<SettingsMainView> {
|
|||
Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const ProfileView();
|
||||
},
|
||||
),
|
||||
);
|
||||
await context.push(Routes.settingsProfile);
|
||||
setState(() {});
|
||||
},
|
||||
child: ColoredBox(
|
||||
|
|
@ -86,16 +68,7 @@ class _SettingsMainViewState extends State<SettingsMainView> {
|
|||
Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const PublicProfileView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onPressed: () => context.push(Routes.settingsPublicProfile),
|
||||
icon: const FaIcon(FontAwesomeIcons.qrcode),
|
||||
),
|
||||
),
|
||||
|
|
@ -105,160 +78,61 @@ class _SettingsMainViewState extends State<SettingsMainView> {
|
|||
BetterListTile(
|
||||
icon: FontAwesomeIcons.user,
|
||||
text: context.lang.settingsAccount,
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const AccountView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(Routes.settingsAccount),
|
||||
),
|
||||
BetterListTile(
|
||||
icon: FontAwesomeIcons.shieldHeart,
|
||||
text: context.lang.settingsSubscription,
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const SubscriptionView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(Routes.settingsSubscription),
|
||||
),
|
||||
BetterListTile(
|
||||
icon: Icons.lock_clock_rounded,
|
||||
text: context.lang.settingsBackup,
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const BackupView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(Routes.settingsBackup),
|
||||
),
|
||||
const Divider(),
|
||||
BetterListTile(
|
||||
icon: FontAwesomeIcons.sun,
|
||||
text: context.lang.settingsAppearance,
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const AppearanceView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(Routes.settingsAppearance),
|
||||
),
|
||||
BetterListTile(
|
||||
icon: FontAwesomeIcons.comment,
|
||||
text: context.lang.settingsChats,
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const ChatSettingsView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(Routes.settingsChats),
|
||||
),
|
||||
BetterListTile(
|
||||
icon: FontAwesomeIcons.lock,
|
||||
text: context.lang.settingsPrivacy,
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const PrivacyView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(Routes.settingsPrivacy),
|
||||
),
|
||||
BetterListTile(
|
||||
icon: FontAwesomeIcons.bell,
|
||||
text: context.lang.settingsNotification,
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const NotificationView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(Routes.settingsNotification),
|
||||
),
|
||||
BetterListTile(
|
||||
icon: FontAwesomeIcons.chartPie,
|
||||
iconSize: 15,
|
||||
text: context.lang.settingsStorageData,
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const DataAndStorageView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(Routes.settingsStorage),
|
||||
),
|
||||
const Divider(),
|
||||
BetterListTile(
|
||||
icon: FontAwesomeIcons.circleQuestion,
|
||||
text: context.lang.settingsHelp,
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const HelpView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(Routes.settingsHelp),
|
||||
),
|
||||
if (gUser.isDeveloper)
|
||||
BetterListTile(
|
||||
icon: FontAwesomeIcons.code,
|
||||
text: 'Developer Settings',
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const DeveloperSettingsView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(Routes.settingsDeveloper),
|
||||
),
|
||||
BetterListTile(
|
||||
icon: FontAwesomeIcons.shareFromSquare,
|
||||
text: context.lang.inviteFriends,
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const ShareWithFriendsView();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onTap: () => context.push(Routes.settingsInvite),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -2,19 +2,22 @@
|
|||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:twonly/src/utils/keyvalue.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/utils/storage.dart';
|
||||
import 'package:twonly/src/views/user_study/user_study_data_collection.dart';
|
||||
|
||||
class UserStudyQuestionnaire extends StatefulWidget {
|
||||
const UserStudyQuestionnaire({super.key});
|
||||
class UserStudyQuestionnaireView extends StatefulWidget {
|
||||
const UserStudyQuestionnaireView({super.key});
|
||||
|
||||
@override
|
||||
State<UserStudyQuestionnaire> createState() => _UserStudyQuestionnaireState();
|
||||
State<UserStudyQuestionnaireView> createState() =>
|
||||
_UserStudyQuestionnaireViewState();
|
||||
}
|
||||
|
||||
class _UserStudyQuestionnaireState extends State<UserStudyQuestionnaire> {
|
||||
class _UserStudyQuestionnaireViewState
|
||||
extends State<UserStudyQuestionnaireView> {
|
||||
final Map<String, dynamic> _responses = {
|
||||
'age': null,
|
||||
'education': null,
|
||||
|
|
@ -62,7 +65,7 @@ class _UserStudyQuestionnaireState extends State<UserStudyQuestionnaire> {
|
|||
const SnackBar(content: Text('Vielen Dank für deine Teilnahme!')),
|
||||
);
|
||||
|
||||
Navigator.pop(context);
|
||||
context.pop();
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:twonly/src/constants/routes.keys.dart';
|
||||
import 'package:twonly/src/utils/storage.dart';
|
||||
import 'package:twonly/src/views/user_study/user_study_questionnaire.view.dart';
|
||||
|
||||
class UserStudyWelcomeView extends StatefulWidget {
|
||||
const UserStudyWelcomeView({super.key, this.wasOpenedAutomatic = false});
|
||||
|
|
@ -54,16 +55,8 @@ class _UserStudyWelcomeViewState extends State<UserStudyWelcomeView> {
|
|||
const SizedBox(height: 40),
|
||||
Center(
|
||||
child: FilledButton(
|
||||
onPressed: () {
|
||||
Navigator.pushReplacement(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const UserStudyQuestionnaire();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onPressed: () => context
|
||||
.pushReplacement(Routes.settingsHelpUserStudyQuestionnaire),
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 30, vertical: 15),
|
||||
child: Text(
|
||||
|
|
@ -77,9 +70,7 @@ class _UserStudyWelcomeViewState extends State<UserStudyWelcomeView> {
|
|||
if (widget.wasOpenedAutomatic)
|
||||
Center(
|
||||
child: OutlinedButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
onPressed: () => context.pop(),
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
|
||||
child: Text(
|
||||
|
|
@ -98,7 +89,7 @@ class _UserStudyWelcomeViewState extends State<UserStudyWelcomeView> {
|
|||
u.askedForUserStudyPermission = true;
|
||||
return u;
|
||||
});
|
||||
if (context.mounted) Navigator.pop(context);
|
||||
if (context.mounted) context.pop();
|
||||
},
|
||||
child: const Text(
|
||||
'Nicht mehr anzeigen',
|
||||
|
|
|
|||
|
|
@ -852,6 +852,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.3"
|
||||
go_router:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: go_router
|
||||
sha256: "7974313e217a7771557add6ff2238acb63f635317c35fa590d348fb238f00896"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "17.1.0"
|
||||
google_mlkit_barcode_scanning:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ dependencies:
|
|||
vector_graphics: ^1.1.19
|
||||
video_player: ^2.10.1
|
||||
in_app_purchase: ^3.2.3
|
||||
go_router: ^17.1.0
|
||||
|
||||
|
||||
# Trusted publisher fluttercommunity.dev
|
||||
|
|
|
|||
Loading…
Reference in a new issue