Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/core/common/app_eum.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ extension ServerLocationTypeExtension on String {
}
}

enum AuthFlow { resetPassword, oauth, signUp, lanternProLicense, changeEmail }
enum AuthFlow { resetPassword, oauth, signUp, lanternProLicense, changeEmail,renewSubscription }

enum BillingType { subscription, one_time }

Expand Down
2 changes: 1 addition & 1 deletion lib/core/widgets/logs_path.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class LogsPath extends StatelessWidget {
...logoPaths.map<Widget>(
(p) => Padding(
padding: const EdgeInsets.only(right: 4),
child: SvgPicture.network(p, height: 30),
child: SvgPicture.network(p, height: 30,),
),
)
],
Expand Down
18 changes: 10 additions & 8 deletions lib/features/auth/choose_payment_method.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,7 @@ class ChoosePaymentMethod extends HookConsumerWidget {
title: '',
appBar: CustomAppBar(
title: Text('choose_payment_method'.i18n),
actions: [
IconButton(
icon: Icon(Icons.more_vert),
onPressed: () => onMoreOptionsPressed(context),
),
],

),
body: Column(
children: <Widget>[
Expand Down Expand Up @@ -139,12 +134,10 @@ class ChoosePaymentMethod extends HookConsumerWidget {
await desktopPurchaseFlow(provider, ref, context);
return;
}

if (isAndroidSideload) {
await androidStripeSubscription(provider, ref, context);
return;
}

break;

case 'shepherd':
Expand Down Expand Up @@ -302,6 +295,15 @@ class ChoosePaymentMethod extends HookConsumerWidget {
case AuthFlow.changeEmail:
// TODO: Handle this case.
throw UnimplementedError('change email flow should not reach here');
case AuthFlow.renewSubscription:

/// User is renewing subscription, pop until payment screen and show success dialog
AppDialog.showLanternProDialog(
context: context,
onPressed: () {
appRouter.popUntilRoot();
},
);
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions lib/features/auth/confirm_email.dart
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ class ConfirmEmail extends HookConsumerWidget {
throw Exception('OAuth flow should not reach this point');
case AuthFlow.changeEmail:
completeChangeEmail(context, ref, code);
case AuthFlow.renewSubscription:
// TODO: Handle this case.
throw UnimplementedError();
}
}

Expand Down Expand Up @@ -239,6 +242,9 @@ class ConfirmEmail extends HookConsumerWidget {
case AuthFlow.changeEmail:
// TODO: Handle this case.
throw UnimplementedError();
case AuthFlow.renewSubscription:
// TODO: Handle this case.
throw UnimplementedError();
}
}

Expand All @@ -255,6 +261,9 @@ class ConfirmEmail extends HookConsumerWidget {
case AuthFlow.changeEmail:
resendChangeEmail(context, ref);
break;
case AuthFlow.renewSubscription:
// TODO: Handle this case.
throw UnimplementedError();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to implement these?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, renewals do not need verification.

}
}

Expand Down
30 changes: 22 additions & 8 deletions lib/features/plans/plans.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import 'package:lantern/core/utils/screen_utils.dart';
import 'package:lantern/core/widgets/loading_indicator.dart';
import 'package:lantern/features/auth/provider/auth_notifier.dart';
import 'package:lantern/features/home/provider/app_setting_notifier.dart';
import 'package:lantern/features/home/provider/home_notifier.dart';
import 'package:lantern/features/plans/feature_list.dart';
import 'package:lantern/features/plans/plans_list.dart';
import 'package:lantern/features/plans/provider/payment_notifier.dart';
Expand Down Expand Up @@ -360,28 +361,41 @@ class _PlansState extends ConsumerState<Plans> {

/// IOS Send old purchases to stream
sl<AppPurchase>().clearCallbacks();

final appSetting = ref.read(appSettingProvider);
if (appSetting.userLoggedIn) {
/// If user logged in and purchase is successful then check user account status
/// to reflect new purchase and send user to pro flow
userRenewalFlow();
return;
}
await signUpFlow();
}

Future<void> signUpFlow() async {
final appSetting = ref.read(appSettingProvider);
if (appSetting.userLoggedIn) {
/// Check if user is expired or not, if expired send to pro flow if not send to home screen
final isUserExpired = ref.read(isUserExpiredProvider);
if (isUserExpired) {
await userExpiredFlow();
/// Check if user is pro or not
final isPro = ref.read(isUserProProvider);
if (isPro) {
appLogger.info('User is already Pro, sending to Pro flow');
useProFlow();
return;
}
appLogger.info('User already logged in, checking account status');
useProFlow();
final user = ref.read(homeProvider).value;
final email = user!.legacyUserData.email;

/// User is logged but not pro, this can be because user has created account but did not complete purchase flow or user has created account and their plan is expired
appRouter.push(ChoosePaymentMethod(
email: email, authFlow: AuthFlow.renewSubscription));
return;
}
appLogger.debug('Sending user to AddEmail screen for sign up');
appRouter.push(AddEmail(authFlow: AuthFlow.signUp));
}

Future<void> userExpiredFlow() async {
appLogger.info('User account is expired, sending to Pro flow');
Future<void> userRenewalFlow() async {
appLogger.info('User account is expired/free, sending to Pro flow');
context.showLoadingDialog();
appLogger.debug("Checking user account status");
final isPro = await checkUserAccountStatus(ref, context);
Expand Down
73 changes: 73 additions & 0 deletions lib/features/setting/setting.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import 'package:lantern/features/setting/follow_us.dart'
show showFollowUsBottomSheet;

import '../../core/services/injection_container.dart';
import '../../lantern/lantern_service_notifier.dart';

enum _SettingType {
account,
Expand Down Expand Up @@ -193,6 +194,16 @@ class _SettingState extends ConsumerState<Setting> {
),
},
const SizedBox(height: defaultSize),
if (appSetting.userLoggedIn && !hasProSession) ...[
AppCard(
padding: EdgeInsets.zero,
child: AppTile(
label: 'logout'.i18n,
icon: AppImagePaths.signIn,
onPressed: () => logoutDialog(context, ref)),
),
const SizedBox(height: defaultSize),
],
Padding(
padding: const EdgeInsets.only(left: 16),
child: Text(
Expand Down Expand Up @@ -297,4 +308,66 @@ class _SettingState extends ConsumerState<Setting> {
);
}
}

void logoutDialog(BuildContext context, WidgetRef ref) {
final theme = TextTheme.of(context);
final isExpired = ref.read(isUserExpiredProvider);
AppDialog.customDialog(
context: context,
action: [
AppTextButton(
label: 'not_now'.i18n,
textColor: AppColors.gray8,
onPressed: () {
appRouter.pop();
},
),
AppTextButton(
label: 'logout'.i18n,
onPressed: () {
onLogout(context, ref);
appRouter.pop();
},
),
],
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizedBox(height: defaultSize),
Text(
'logout'.i18n,
style: theme.headlineSmall,
),
SizedBox(height: defaultSize),
Text(
isExpired ? 'logout_message_expired'.i18n : 'logout_message'.i18n,
style: theme.bodyMedium!.copyWith(
color: AppColors.gray8,
),
),
],
),
);
}

Future<void> onLogout(BuildContext context, WidgetRef ref) async {
context.showLoadingDialog();
final appSetting = ref.read(appSettingProvider);
final result =
await ref.read(lanternServiceProvider).logout(appSetting.email);
result.fold(
(l) {
context.hideLoadingDialog();
appLogger.error('Logout error: ${l.localizedErrorMessage}');
},
(user) {
context.hideLoadingDialog();
appRouter.popUntilRoot();
ref.read(homeProvider.notifier).clearLogoutData();
ref.read(homeProvider.notifier).updateUserData(user);

appLogger.info('Logout success: $user');
},
);
}
}
4 changes: 2 additions & 2 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1693,8 +1693,8 @@ packages:
dependency: "direct main"
description:
path: "packages/tray_manager"
ref: "7987b6f3aea4fc6e512e91de150c8a6ce87df98d"
resolved-ref: "7987b6f3aea4fc6e512e91de150c8a6ce87df98d"
ref: e4f69663ca467c1108c1ccad9f55cf5a2154adc2
resolved-ref: e4f69663ca467c1108c1ccad9f55cf5a2154adc2
url: "https://github.com/getlantern/tray_manager.git"
source: git
version: "0.5.1"
Expand Down
Loading