Skip to content

Commit db514e6

Browse files
committed
chore: Updated the app design.
1 parent 94e632d commit db514e6

98 files changed

Lines changed: 3462 additions & 2115 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

lib/main.dart

Lines changed: 81 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import 'dart:async';
22

33
import 'package:flutter/foundation.dart';
44
import 'package:flutter/material.dart';
5-
import 'package:flutter/services.dart';
65
import 'package:flutter_localizations/flutter_localizations.dart';
76
import 'package:flutter_riverpod/flutter_riverpod.dart';
7+
import 'package:forui/forui.dart';
88
import 'package:open_authenticator/app.dart'; // TODO
99
import 'package:open_authenticator/i18n/translations.g.dart';
1010
import 'package:open_authenticator/model/app_links.dart';
@@ -19,11 +19,13 @@ import 'package:open_authenticator/pages/intro/page.dart';
1919
import 'package:open_authenticator/pages/scan.dart';
2020
import 'package:open_authenticator/pages/settings/page.dart';
2121
import 'package:open_authenticator/pages/totp.dart';
22+
import 'package:open_authenticator/themes.dart';
23+
import 'package:open_authenticator/utils/brightness_listener.dart';
2224
import 'package:open_authenticator/utils/platform.dart';
2325
import 'package:open_authenticator/utils/rate_my_app.dart';
2426
import 'package:open_authenticator/utils/utils.dart';
2527
import 'package:open_authenticator/widgets/centered_circular_progress_indicator.dart';
26-
import 'package:open_authenticator/widgets/dialog/totp_limit.dart';
28+
import 'package:open_authenticator/widgets/dialog/totp_limit_dialog.dart';
2729
import 'package:open_authenticator/widgets/unlock_challenge.dart';
2830
import 'package:open_authenticator/widgets/waiting_overlay.dart';
2931
import 'package:rate_my_app/rate_my_app.dart';
@@ -43,6 +45,7 @@ Future<void> main() async {
4345
size: Size(800, 600),
4446
minimumSize: Size(400, 400),
4547
center: true,
48+
titleBarStyle: TitleBarStyle.hidden,
4649
),
4750
() async {
4851
await windowManager.show();
@@ -125,110 +128,82 @@ class OpenAuthenticatorApp extends ConsumerWidget {
125128
required Locale locale,
126129
String? initialRoute,
127130
Widget? home,
128-
}) {
129-
ColorScheme light = ColorScheme.fromSeed(
130-
seedColor: Colors.green,
131-
);
132-
ColorScheme dark = ColorScheme.fromSeed(
133-
seedColor: Colors.green,
134-
brightness: Brightness.dark,
135-
);
136-
return MaterialApp(
137-
key: ValueKey('materialApp.$showIntroState'),
138-
title: App.appName,
139-
locale: locale,
140-
localizationsDelegates: const [
141-
GlobalMaterialLocalizations.delegate,
142-
GlobalWidgetsLocalizations.delegate,
143-
GlobalCupertinoLocalizations.delegate,
144-
],
145-
supportedLocales: AppLocaleUtils.supportedLocales,
146-
themeMode: theme.value,
147-
darkTheme: ThemeData(
148-
brightness: Brightness.dark,
149-
appBarTheme: AppBarTheme(
150-
systemOverlayStyle: SystemUiOverlayStyle(
151-
statusBarIconBrightness: Brightness.light,
152-
systemNavigationBarColor: dark.surface,
153-
),
154-
shape: const RoundedRectangleBorder(),
155-
surfaceTintColor: Colors.green,
156-
),
157-
colorScheme: dark,
158-
// iconButtonTheme: IconButtonThemeData(
159-
// style: ButtonStyle(
160-
// foregroundColor: MaterialStatePropertyAll(Colors.green.shade300),
161-
// ),
162-
// ),
163-
buttonTheme: const ButtonThemeData(
164-
alignedDropdown: true,
165-
),
166-
floatingActionButtonTheme: FloatingActionButtonThemeData(
167-
shape: const CircleBorder(),
168-
backgroundColor: Colors.green.shade700,
169-
foregroundColor: Colors.green.shade50,
170-
),
171-
),
172-
theme: ThemeData(
173-
colorScheme: light,
174-
appBarTheme: AppBarTheme(
175-
systemOverlayStyle: SystemUiOverlayStyle(
176-
statusBarIconBrightness: Brightness.dark,
177-
systemNavigationBarColor: light.surface,
178-
),
179-
shape: const RoundedRectangleBorder(),
180-
),
181-
buttonTheme: const ButtonThemeData(
182-
alignedDropdown: true,
183-
),
184-
floatingActionButtonTheme: FloatingActionButtonThemeData(
185-
shape: const CircleBorder(),
186-
backgroundColor: Colors.green.shade50,
187-
foregroundColor: Colors.green.shade700,
188-
),
189-
inputDecorationTheme: InputDecorationTheme(
190-
disabledBorder: UnderlineInputBorder(
191-
borderSide: BorderSide(color: Colors.grey.shade400),
192-
),
193-
),
194-
dividerTheme: const DividerThemeData(
195-
color: Colors.black12,
196-
),
197-
),
198-
routes: home == null
199-
? {
200-
IntroPage.name: (_) => const _RouteWidget(
201-
child: IntroPage(),
202-
),
203-
HomePage.name: (_) => const _RouteWidget(
204-
listen: true,
205-
rateMyApp: true,
206-
child: HomePage(),
207-
),
208-
ScanPage.name: (_) => const _RouteWidget(
209-
child: ScanPage(),
210-
),
211-
SettingsPage.name: (_) => const _RouteWidget(
212-
child: SettingsPage(),
213-
),
214-
TotpPage.name: (context) {
215-
Map<String, dynamic>? arguments = ModalRoute.of(context)!.settings.arguments as Map<String, dynamic>?;
216-
return _RouteWidget(
217-
child: TotpPage(
218-
totp: arguments?[kRouteParameterTotp],
219-
add: arguments?[kRouteParameterAddTotp],
220-
),
221-
);
222-
},
223-
ContributorPlanPaywallPage.name: (_) => const _RouteWidget(
224-
child: ContributorPlanPaywallPage(),
225-
),
226-
}
227-
: {},
228-
initialRoute: home == null ? initialRoute : null,
229-
home: home,
230-
);
231-
}
131+
}) => MaterialApp(
132+
key: ValueKey('materialApp.$showIntroState'),
133+
title: App.appName,
134+
locale: locale,
135+
localizationsDelegates: const [
136+
GlobalMaterialLocalizations.delegate,
137+
GlobalWidgetsLocalizations.delegate,
138+
GlobalCupertinoLocalizations.delegate,
139+
],
140+
supportedLocales: AppLocaleUtils.supportedLocales,
141+
themeMode: theme.value,
142+
darkTheme: greenTheme.dark.toApproximateMaterialTheme(),
143+
theme: greenTheme.light.toApproximateMaterialTheme(),
144+
builder: (context, child) => _AnimatedTheme(
145+
light: greenTheme.light,
146+
dark: greenTheme.dark,
147+
child: FToaster(child: child!),
148+
),
149+
routes: home == null
150+
? {
151+
IntroPage.name: (_) => const _RouteWidget(
152+
child: IntroPage(),
153+
),
154+
HomePage.name: (_) => const _RouteWidget(
155+
listen: true,
156+
rateMyApp: true,
157+
child: HomePage(),
158+
),
159+
ScanPage.name: (_) => const _RouteWidget(
160+
child: ScanPage(),
161+
),
162+
SettingsPage.name: (_) => const _RouteWidget(
163+
child: SettingsPage(),
164+
),
165+
TotpPage.name: (context) {
166+
Map<String, dynamic>? arguments = ModalRoute.of(context)!.settings.arguments as Map<String, dynamic>?;
167+
return _RouteWidget(
168+
child: TotpPage(
169+
totp: arguments?[kRouteParameterTotp],
170+
add: arguments?[kRouteParameterAddTotp],
171+
),
172+
);
173+
},
174+
ContributorPlanPaywallPage.name: (_) => const _RouteWidget(
175+
child: ContributorPlanPaywallPage(),
176+
),
177+
}
178+
: {},
179+
initialRoute: home == null ? initialRoute : null,
180+
home: home,
181+
);
182+
}
183+
184+
class _AnimatedTheme extends ConsumerStatefulWidget {
185+
final FThemeData light;
186+
final FThemeData dark;
187+
final Widget child;
188+
189+
const _AnimatedTheme({
190+
required this.light,
191+
required this.dark,
192+
required this.child,
193+
});
194+
195+
@override
196+
ConsumerState<ConsumerStatefulWidget> createState() => _AnimatedThemeState();
197+
198+
}
199+
200+
class _AnimatedThemeState extends ConsumerState<_AnimatedTheme> with BrightnessListener {
201+
@override
202+
Widget build(BuildContext context) => FAnimatedTheme(
203+
data: currentBrightness == Brightness.dark ? widget.dark : widget.light,
204+
child: widget.child,
205+
);
206+
232207
}
233208

234209
/// A route that allows to listen to dynamic links and [totpLimitExceededProvider].

lib/model/app_unlock/methods/method.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,15 @@ sealed class AppUnlockMethod<T> {
6363
return const ResultCancelled();
6464
}
6565
return await _tryUnlock(context, reason);
66-
} catch (ex, stacktrace) {
66+
} catch (ex, stackTrace) {
6767
if (ex is LocalAuthException) {
6868
if (ex.code == LocalAuthExceptionCode.userCanceled || ex.code == LocalAuthExceptionCode.systemCanceled) {
6969
return const ResultCancelled();
7070
}
7171
}
7272
return ResultError(
7373
exception: ex,
74-
stacktrace: stacktrace,
74+
stackTrace: stackTrace,
7575
);
7676
}
7777
}

lib/model/backend/authentication/providers/email.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,10 @@ class EmailAuthenticationProvider extends AuthenticationProvider {
5656
}
5757
Uri uri = response.value.url;
5858
return await onRedirectReceived(uri);
59-
} catch (ex, stacktrace) {
59+
} catch (ex, stackTrace) {
6060
return ResultError(
6161
exception: ex,
62-
stacktrace: stacktrace,
62+
stackTrace: stackTrace,
6363
);
6464
}
6565
}
@@ -83,10 +83,10 @@ class EmailAuthenticationProvider extends AuthenticationProvider {
8383
}
8484
await _ref.read(emailConfirmationStateProvider.notifier)._cancelConfirmation();
8585
return const ResultSuccess();
86-
} catch (ex, stacktrace) {
86+
} catch (ex, stackTrace) {
8787
return ResultError(
8888
exception: ex,
89-
stacktrace: stacktrace,
89+
stackTrace: stackTrace,
9090
);
9191
}
9292
}

lib/model/backend/authentication/providers/provider.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,10 @@ sealed class AuthenticationProvider {
7676
provider: this,
7777
),
7878
);
79-
} catch (ex, stacktrace) {
79+
} catch (ex, stackTrace) {
8080
return ResultError(
8181
exception: ex,
82-
stacktrace: stacktrace,
82+
stackTrace: stackTrace,
8383
);
8484
}
8585
}
@@ -132,10 +132,10 @@ sealed class AuthenticationProvider {
132132
await _ref.read(userProvider.notifier).changeUser(_changeId(user, response.value.providerUserId));
133133
}
134134
return const ResultSuccess();
135-
} catch (ex, stacktrace) {
135+
} catch (ex, stackTrace) {
136136
return ResultError(
137137
exception: ex,
138-
stacktrace: stacktrace,
138+
stackTrace: stackTrace,
139139
);
140140
}
141141
}

lib/model/backend/authentication/session.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ class Session {
3131
refreshToken: response.refreshToken,
3232
),
3333
);
34-
} catch (ex, stacktrace) {
34+
} catch (ex, stackTrace) {
3535
return ResultError(
3636
exception: ex,
37-
stacktrace: stacktrace,
37+
stackTrace: stackTrace,
3838
);
3939
}
4040
}
@@ -71,13 +71,13 @@ class StoredSessionNotifier extends AsyncNotifier<Session?> {
7171
}
7272
await storeAndUse(result.value);
7373
return const ResultSuccess();
74-
} catch (ex, stacktrace) {
74+
} catch (ex, stackTrace) {
7575
if (ex is BackendRequestError && (ex.errorCode == BackendRequestError.kInvalidPayloadError || ex.errorCode == BackendRequestError.kInvalidTokenError)) {
7676
await clear();
7777
}
7878
return ResultError(
7979
exception: ex,
80-
stacktrace: stacktrace,
80+
stackTrace: stackTrace,
8181
);
8282
}
8383
}

lib/model/backend/backend.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class Backend extends AsyncNotifier<Map<String, String>> {
5353
retries: retries,
5454
),
5555
);
56-
} catch (ex, stacktrace) {
56+
} catch (ex, stackTrace) {
5757
if (autoRefreshAccessToken && (Session.hasExpired(ex) || ex is _NoAccessTokenException)) {
5858
Result result = await ref.read(storedSessionProvider.notifier).refresh();
5959
if (result is! ResultSuccess) {
@@ -66,7 +66,7 @@ class Backend extends AsyncNotifier<Map<String, String>> {
6666
}
6767
return ResultError(
6868
exception: ex,
69-
stacktrace: stacktrace,
69+
stackTrace: stackTrace,
7070
);
7171
}
7272
}

lib/model/backend/synchronization/queue.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,12 +211,12 @@ class SynchronizationController extends Notifier<SynchronizationStatus> with Wid
211211

212212
retry = pendingAfter.isNotEmpty;
213213
}
214-
} catch (ex, stacktrace) {
214+
} catch (ex, stackTrace) {
215215
List<PushOperation> pending = await ref.read(pushOperationsQueueProvider.future);
216216
state = state.update(
217217
phase: SynchronizationPhaseError(
218218
exception: ex,
219-
stacktrace: stacktrace,
219+
stackTrace: stackTrace,
220220
),
221221
pendingOperations: pending.length,
222222
);

lib/model/backend/synchronization/status.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,10 @@ class SynchronizationPhaseError extends SynchronizationPhase {
8282
final Object? exception;
8383

8484
/// The current stacktrace.
85-
final StackTrace stacktrace;
85+
final StackTrace stackTrace;
8686

8787
SynchronizationPhaseError({
8888
this.exception,
89-
StackTrace? stacktrace,
90-
}) : stacktrace = stacktrace ?? StackTrace.current;
89+
StackTrace? stackTrace,
90+
}) : stackTrace = stackTrace ?? StackTrace.current;
9191
}

lib/model/backend/user.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,10 @@ class UserNotifier extends AsyncNotifier<User?> {
146146
}
147147
await ref.read(storedSessionProvider.notifier).clear();
148148
return const ResultSuccess();
149-
} catch (ex, stacktrace) {
149+
} catch (ex, stackTrace) {
150150
return ResultError(
151151
exception: ex,
152-
stacktrace: stacktrace,
152+
stackTrace: stackTrace,
153153
);
154154
}
155155
}
@@ -163,10 +163,10 @@ class UserNotifier extends AsyncNotifier<User?> {
163163
);
164164
await ref.read(storedSessionProvider.notifier).clear();
165165
return result;
166-
} catch (ex, stacktrace) {
166+
} catch (ex, stackTrace) {
167167
return ResultError<DeleteUserResponse>(
168168
exception: ex,
169-
stacktrace: stacktrace,
169+
stackTrace: stackTrace,
170170
);
171171
}
172172
}

0 commit comments

Comments
 (0)