Skip to content

Commit dd4da2e

Browse files
committed
Merge branch 'main' into jay/releases
2 parents efcdce9 + 1b129cb commit dd4da2e

File tree

8 files changed

+275
-147
lines changed

8 files changed

+275
-147
lines changed

assets/locales/en.po

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,9 @@ msgstr "Connected"
881881
msgid "status_off"
882882
msgstr "Disconnected"
883883

884+
msgid "select_location"
885+
msgstr "Select Location"
886+
884887
msgid "select_your_server_location"
885888
msgstr "Select your server location"
886889

lib/features/account/account.dart

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class Account extends HookConsumerWidget {
3131
Widget _buildBody(BuildContext buildContext, WidgetRef ref) {
3232
final user = sl<LocalStorageService>().getUser();
3333
final isExpired = ref.watch(isUserExpiredProvider);
34-
final appSettings = ref.read(appSettingProvider);
34+
final appSettings = ref.watch(appSettingProvider);
3535
final theme = Theme.of(buildContext).textTheme;
3636

3737
return Column(
@@ -134,6 +134,15 @@ class Account extends HookConsumerWidget {
134134
),
135135
),
136136
UserDevices(),
137+
SizedBox(height: defaultSize),
138+
if (appSettings.userLoggedIn)
139+
AppCard(
140+
padding: EdgeInsets.zero,
141+
child: AppTile(
142+
label: 'logout'.i18n,
143+
icon: AppImagePaths.signIn,
144+
onPressed: () => logoutDialog(buildContext, ref)),
145+
),
137146
Spacer(),
138147
Padding(
139148
padding: const EdgeInsets.only(left: 16),
@@ -301,4 +310,66 @@ class Account extends HookConsumerWidget {
301310
}
302311
}
303312
}
313+
314+
void logoutDialog(BuildContext context, WidgetRef ref) {
315+
final theme = TextTheme.of(context);
316+
final isExpired = ref.read(isUserExpiredProvider);
317+
AppDialog.customDialog(
318+
context: context,
319+
action: [
320+
AppTextButton(
321+
label: 'not_now'.i18n,
322+
textColor: AppColors.gray8,
323+
onPressed: () {
324+
appRouter.pop();
325+
},
326+
),
327+
AppTextButton(
328+
label: 'logout'.i18n,
329+
onPressed: () {
330+
onLogout(context, ref);
331+
appRouter.pop();
332+
},
333+
),
334+
],
335+
content: Column(
336+
mainAxisSize: MainAxisSize.min,
337+
children: <Widget>[
338+
SizedBox(height: defaultSize),
339+
Text(
340+
'logout'.i18n,
341+
style: theme.headlineSmall,
342+
),
343+
SizedBox(height: defaultSize),
344+
Text(
345+
isExpired ? 'logout_message_expired'.i18n : 'logout_message'.i18n,
346+
style: theme.bodyMedium!.copyWith(
347+
color: AppColors.gray8,
348+
),
349+
),
350+
],
351+
),
352+
);
353+
}
354+
355+
Future<void> onLogout(BuildContext context, WidgetRef ref) async {
356+
context.showLoadingDialog();
357+
final appSetting = ref.read(appSettingProvider);
358+
final result =
359+
await ref.read(lanternServiceProvider).logout(appSetting.email);
360+
result.fold(
361+
(l) {
362+
context.hideLoadingDialog();
363+
appLogger.error('Logout error: ${l.localizedErrorMessage}');
364+
},
365+
(user) {
366+
context.hideLoadingDialog();
367+
appRouter.popUntilRoot();
368+
ref.read(homeProvider.notifier).clearLogoutData();
369+
ref.read(homeProvider.notifier).updateUserData(user);
370+
371+
appLogger.info('Logout success: $user');
372+
},
373+
);
374+
}
304375
}

lib/features/macos_extension/macos_extension_dialog.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,11 @@ class _MacOSExtensionDialogState extends ConsumerState<MacOSExtensionDialog> {
3737
}
3838
if (systemExtensionStatus.status == SystemExtensionStatus.installed ||
3939
systemExtensionStatus.status == SystemExtensionStatus.activated) {
40-
appLogger.info(
41-
"System Extension is installed and activated. Closing dialog.");
42-
appRouter.pop();
40+
WidgetsBinding.instance.addPostFrameCallback((_) {
41+
appLogger.info(
42+
"System Extension is installed and activated. Closing dialog.");
43+
appRouter.pop();
44+
});
4345
}
4446
return null;
4547
}, [systemExtensionStatus.status]);

lib/features/onboarding/onboarding.dart

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,17 @@ class _OnboardingState extends ConsumerState<Onboarding> {
2626

2727
void onboardingCompleted() {
2828
ref.read(appSettingProvider.notifier).setOnboardingCompleted(true);
29+
final shouldShowExtensionDialog =
30+
appSetting.showSplashScreen && PlatformUtils.isMacOS;
2931
appRouter.pop();
30-
if (appSetting.showSplashScreen && PlatformUtils.isMacOS) {
32+
if (shouldShowExtensionDialog) {
3133
appLogger.info("Showing System Extension Dialog");
32-
appRouter.push(const MacOSExtensionDialog());
34+
// Defer the push to the next frame to avoid calling setState during build
35+
WidgetsBinding.instance.addPostFrameCallback((_) {
36+
appRouter.push(const MacOSExtensionDialog());
37+
});
3338
// User has seen dialog, do not show again
3439
appLogger.info("Setting showSplashScreen to false");
35-
3640
ref.read(appSettingProvider.notifier).setSplashScreen(false);
3741
return;
3842
}
@@ -48,7 +52,8 @@ class _OnboardingState extends ConsumerState<Onboarding> {
4852
child: DividerSpace(padding: EdgeInsets.zero),
4953
),
5054
),
51-
body: Padding(
55+
body: Container(
56+
color: AppColors.white,
5257
padding: const EdgeInsets.symmetric(horizontal: 16.0),
5358
child: Column(
5459
children: [
@@ -120,7 +125,6 @@ class _OnboardingState extends ConsumerState<Onboarding> {
120125
label: 'skip_connect_now'.i18n,
121126
textColor: AppColors.gray9,
122127
onPressed: () {
123-
appRouter.pop();
124128
onboardingCompleted();
125129
},
126130
)
@@ -243,14 +247,16 @@ class _OnboardingState extends ConsumerState<Onboarding> {
243247
final routeMode =
244248
ref.watch(appSettingProvider.select((value) => value.routingMode));
245249
useEffect(() {
246-
final routeMode =
247-
ref.read(appSettingProvider.select((v) => v.routingMode));
250+
Future(() {
251+
final routeMode =
252+
ref.read(appSettingProvider.select((v) => v.routingMode));
248253

249-
if (routeMode == RoutingMode.full) {
250-
ref
251-
.read(appSettingProvider.notifier)
252-
.setRoutingMode(RoutingMode.smart);
253-
}
254+
if (routeMode == RoutingMode.full) {
255+
ref
256+
.read(appSettingProvider.notifier)
257+
.setRoutingMode(RoutingMode.smart);
258+
}
259+
});
254260

255261
return null;
256262
}, const []);
@@ -332,7 +338,12 @@ class RouteModeContainer extends StatelessWidget {
332338
value: true,
333339
),
334340
SizedBox(width: 16.0),
335-
Text(title()),
341+
Text(
342+
title(),
343+
style: textTheme.titleMedium!.copyWith(
344+
color: AppColors.black,
345+
),
346+
),
336347
SizedBox(width: 8.0),
337348
Container(
338349
padding:
@@ -352,10 +363,8 @@ class RouteModeContainer extends StatelessWidget {
352363
SizedBox(height: 4.0),
353364
Padding(
354365
padding: const EdgeInsets.only(left: 38),
355-
child: Text(
356-
description(),
357-
style: textTheme.bodyMedium!.copyWith(color: AppColors.gray8),
358-
),
366+
child: Text(description(),
367+
style: textTheme.bodyMedium!.copyWith(color: AppColors.gray8)),
359368
)
360369
],
361370
),

lib/features/setting/setting.dart

Lines changed: 1 addition & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
import 'dart:io';
2-
31
import 'package:auto_route/auto_route.dart';
4-
import 'package:auto_updater/auto_updater.dart';
52
import 'package:flutter/foundation.dart';
63
import 'package:flutter/material.dart';
74
import 'package:hooks_riverpod/hooks_riverpod.dart';
@@ -16,7 +13,6 @@ import 'package:lantern/features/home/provider/app_setting_notifier.dart';
1613
import 'package:lantern/features/home/provider/home_notifier.dart';
1714
import 'package:lantern/features/setting/follow_us.dart'
1815
show showFollowUsBottomSheet;
19-
import 'package:lantern/lantern/lantern_service_notifier.dart';
2016

2117
import '../../core/services/injection_container.dart';
2218

@@ -31,7 +27,6 @@ enum _SettingType {
3127
getPro,
3228
downloadLinks,
3329
checkForUpdates,
34-
logout,
3530
browserUnbounded,
3631
}
3732

@@ -184,19 +179,8 @@ class _SettingState extends ConsumerState<Setting> {
184179
],
185180
),
186181
),
187-
if (appSetting.userLoggedIn) ...[
188-
const SizedBox(height: defaultSize),
189-
AppCard(
190-
padding: EdgeInsets.zero,
191-
child: AppTile(
192-
label: 'logout'.i18n,
193-
icon: AppImagePaths.signIn,
194-
onPressed: () => settingMenuTap(_SettingType.logout),
195-
),
196-
),
197-
],
198-
const SizedBox(height: defaultSize),
199182
if (kDebugMode || AppBuildInfo.buildType == 'nightly') ...{
183+
SizedBox(height: defaultSize),
200184
AppCard(
201185
padding: EdgeInsets.zero,
202186
child: AppTile(
@@ -295,9 +279,6 @@ class _SettingState extends ConsumerState<Setting> {
295279
case _SettingType.vpnSetting:
296280
appRouter.push(VPNSetting());
297281
break;
298-
case _SettingType.logout:
299-
logoutDialog();
300-
break;
301282
case _SettingType.browserUnbounded:
302283
// TODO: Handle this case.
303284
throw UnimplementedError();
@@ -316,66 +297,4 @@ class _SettingState extends ConsumerState<Setting> {
316297
);
317298
}
318299
}
319-
320-
void logoutDialog() {
321-
final theme = Theme.of(context).textTheme;
322-
final isExpired = ref.watch(isUserExpiredProvider);
323-
AppDialog.customDialog(
324-
context: context,
325-
action: [
326-
AppTextButton(
327-
label: 'not_now'.i18n,
328-
textColor: AppColors.gray8,
329-
onPressed: () {
330-
context.maybePop();
331-
},
332-
),
333-
AppTextButton(
334-
label: 'logout'.i18n,
335-
onPressed: () {
336-
onLogout();
337-
context.maybePop();
338-
},
339-
),
340-
],
341-
content: Column(
342-
mainAxisSize: MainAxisSize.min,
343-
children: <Widget>[
344-
SizedBox(height: defaultSize),
345-
Text(
346-
'logout'.i18n,
347-
style: theme.headlineSmall,
348-
),
349-
SizedBox(height: defaultSize),
350-
Text(
351-
isExpired ? 'logout_message_expired'.i18n : 'logout_message'.i18n,
352-
style: theme.bodyMedium!.copyWith(
353-
color: AppColors.gray8,
354-
),
355-
),
356-
],
357-
),
358-
);
359-
}
360-
361-
Future<void> onLogout() async {
362-
context.showLoadingDialog();
363-
final appSetting = ref.read(appSettingProvider);
364-
final result =
365-
await ref.read(lanternServiceProvider).logout(appSetting.email);
366-
result.fold(
367-
(l) {
368-
context.hideLoadingDialog();
369-
appLogger.error('Logout error: ${l.localizedErrorMessage}');
370-
},
371-
(user) {
372-
context.hideLoadingDialog();
373-
appRouter.popUntilRoot();
374-
ref.read(homeProvider.notifier).clearLogoutData();
375-
ref.read(homeProvider.notifier).updateUserData(user);
376-
377-
appLogger.info('Logout success: $user');
378-
},
379-
);
380-
}
381300
}

0 commit comments

Comments
 (0)