From bf98f6843864b0894f4131aad3c3ec98f153295d Mon Sep 17 00:00:00 2001 From: atavism Date: Sat, 25 Nov 2023 15:19:11 -0800 Subject: [PATCH] working plans page --- desktop/lib.go | 23 ++-- lib/app_desktop.dart | 14 +- lib/home.dart | 20 ++- lib/plans/plans.dart | 317 +++++++++++++++++++------------------------ 4 files changed, 176 insertions(+), 198 deletions(-) diff --git a/desktop/lib.go b/desktop/lib.go index 85de9d048..3a7ca64b7 100644 --- a/desktop/lib.go +++ b/desktop/lib.go @@ -73,16 +73,23 @@ func userHeaders() (string, string, string) { return deviceID, userID, token } +func sendError(err error) *C.char { + if err == nil { + return C.CString("") + } + errors := map[string]interface{}{ + "error": err.Error(), + } + b, _ := json.Marshal(errors) + return C.CString(string(b)) +} + //export Plans func Plans() *C.char { deviceID, userID, token := userHeaders() resp, err := proClient.Plans(deviceID, userID, token) if err != nil { - errors := map[string]interface{}{ - "error": err.Error(), - } - b, _ := json.Marshal(errors) - return C.CString(string(b)) + return sendError(err) } b, _ := json.Marshal(resp.Plans) return C.CString(string(b)) @@ -93,11 +100,7 @@ func UserData() *C.char { deviceID, userID, token := userHeaders() resp, err := proClient.UserData(deviceID, userID, token) if err != nil { - errors := map[string]interface{}{ - "error": err.Error(), - } - b, _ := json.Marshal(errors) - return C.CString(string(b)) + return sendError(err) } b, _ := json.Marshal(resp) return C.CString(string(b)) diff --git a/lib/app_desktop.dart b/lib/app_desktop.dart index 4258fe694..8d5beea89 100644 --- a/lib/app_desktop.dart +++ b/lib/app_desktop.dart @@ -12,6 +12,9 @@ import 'package:lantern/vpn/vpn_tab.dart'; import 'package:logger/logger.dart'; import 'package:lantern/core/router/router.dart'; +final navigatorKey = GlobalKey(); +final globalRouter = AppRouter(); + class DesktopApp extends StatefulWidget { const DesktopApp({Key? key}) : super(key: key); @@ -22,19 +25,14 @@ class DesktopApp extends StatefulWidget { class _DesktopAppState extends State { @override Widget build(BuildContext context) { - return MaterialApp( + return MaterialApp.router( title: 'Lantern Desktop'.i18n, + routeInformationParser: globalRouter.defaultRouteParser(), + routerDelegate: globalRouter.delegate(), theme: ThemeData( fontFamily: 'Roboto', primarySwatch: Colors.blue, ), - home: Scaffold( - body: buildBody(TAB_VPN), - bottomNavigationBar: CustomBottomBar( - selectedTab: TAB_VPN, - isDevelop: true, - ), - ), ); } diff --git a/lib/home.dart b/lib/home.dart index ba855bc83..42345a0f4 100644 --- a/lib/home.dart +++ b/lib/home.dart @@ -115,8 +115,7 @@ class _HomePageState extends State { super.dispose(); } - @override - Widget build(BuildContext context) { + Widget build2(BuildContext context) { _context = context; return sessionModel.acceptedTermsVersion( (BuildContext context, int version, Widget? child) { @@ -145,7 +144,7 @@ class _HomePageState extends State { ).toLowerCase() == 'true'; return Scaffold( - body: buildBody(selectedTab, isOnboarded), + //body: buildBody(selectedTab, isOnboarded), bottomNavigationBar: CustomBottomBar( selectedTab: selectedTab, isDevelop: developmentMode, @@ -160,7 +159,20 @@ class _HomePageState extends State { ); } - Widget buildBody(String selectedTab, bool? isOnboarded) { + @override + Widget build(BuildContext context) { + return Scaffold( + body: buildBody(TAB_VPN, true), + bottomNavigationBar: CustomBottomBar( + selectedTab: TAB_VPN, + isDevelop: true, + isTesting: true, + ), + ); + } + + @override + Widget buildBody(String selectedTab, bool isOnboarded) { switch (selectedTab) { case TAB_CHATS: return isOnboarded == null diff --git a/lib/plans/plans.dart b/lib/plans/plans.dart index 6ab9f3268..33fab230b 100644 --- a/lib/plans/plans.dart +++ b/lib/plans/plans.dart @@ -1,5 +1,9 @@ import 'package:lantern/common/common.dart'; import 'package:lantern/plans/plan_details.dart'; +import 'dart:ffi' as ffi; // For FFI +import 'package:ffi/ffi.dart'; +import 'package:ffi/src/utf8.dart'; +import 'package:lantern/ffi.dart'; final featuresList = [ 'unlimited_data'.i18n, @@ -13,204 +17,165 @@ final featuresList = [ class PlansPage extends StatelessWidget { @override Widget build(BuildContext context) { + var proUser = false; + var plans = json.decode(getPlans().toDartString()); + print("${plans}"); return FullScreenDialog( - widget: sessionModel - .proUser((BuildContext context, bool proUser, Widget? child) { - return sessionModel.plans( - builder: ( - context, - Iterable> plans, - Widget? child, - ) { - if (plans.isEmpty) { - return Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - CAssetImage( - path: ImagePaths.error, - size: 100, - color: grey5, + widget: StatefulBuilder( + builder: (context, setState) => Container( + color: white, + child: Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Expanded( + child: ListView( + shrinkWrap: true, + children: [ + Container( + padding: const EdgeInsetsDirectional.only( + top: 10, + bottom: 10, + start: 32, + end: 16, ), - Padding( - padding: const EdgeInsetsDirectional.all(24.0), - child: CText( - 'error_fetching_plans'.i18n, - style: tsBody1, - ), + color: white, + child: Row( + children: [ + Container( + child: const CAssetImage( + path: ImagePaths.lantern_pro_logotype, + size: 20, + ), + ), + const Spacer(), + IconButton( + icon: mirrorLTR( + context: context, + child: CAssetImage( + path: ImagePaths.cancel, + color: black, + ), + ), + onPressed: () => Navigator.pop(context, null), + ), + ], ), - ], - ), - ); - } - return StatefulBuilder( - builder: (context, setState) => Container( - color: white, - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Expanded( - child: ListView( - shrinkWrap: true, - children: [ - Container( + ), + Container( + color: white, + padding: const EdgeInsetsDirectional.only( + start: 24, + end: 24, + ), + child: Column( + children: [ + // * Renewal text or upsell + if (proUser && plans.last.value.renewalText != '') + Padding( padding: const EdgeInsetsDirectional.only( - top: 10, - bottom: 10, - start: 32, - end: 16, + bottom: 12.0, ), - color: white, - child: Row( - children: [ - Container( - child: const CAssetImage( - path: ImagePaths.lantern_pro_logotype, - size: 20, - ), - ), - const Spacer(), - IconButton( - icon: mirrorLTR( - context: context, - child: CAssetImage( - path: ImagePaths.cancel, - color: black, - ), - ), - onPressed: () => Navigator.pop(context, null), - ), - ], + child: CText( + plans.last.value.renewalText, + style: tsBody1, ), ), - Container( - color: white, + const Padding( + padding: EdgeInsetsDirectional.only( + bottom: 8.0, + ), + child: CDivider(), + ), + ...featuresList.map( + (feature) => Container( padding: const EdgeInsetsDirectional.only( - start: 24, - end: 24, + start: 8, ), - child: Column( + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, children: [ - // * Renewal text or upsell - if (proUser && - plans.last.value.renewalText != '') - Padding( - padding: const EdgeInsetsDirectional.only( - bottom: 12.0, - ), - child: CText( - plans.last.value.renewalText, - style: tsBody1, - ), - ), - const Padding( - padding: EdgeInsetsDirectional.only( - bottom: 8.0, - ), - child: CDivider(), + const CAssetImage( + path: ImagePaths.check_green_large, + size: 24, ), - ...featuresList.map( - (feature) => Container( - padding: const EdgeInsetsDirectional.only( - start: 8, - ), - child: Row( - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - const CAssetImage( - path: ImagePaths.check_green_large, - size: 24, - ), - Padding( - padding: - const EdgeInsetsDirectional.only( - start: 4.0, - bottom: 4.0, - ), - child: CText( - feature, - textAlign: TextAlign.center, - style: tsBody1, - ), - ), - ], - ), + Padding( + padding: const EdgeInsetsDirectional.only( + start: 4.0, + bottom: 4.0, + ), + child: CText( + feature, + textAlign: TextAlign.center, + style: tsBody1, ), ), - const CDivider(height: 24), ], ), ), - // * Step - Container( - color: white, - padding: const EdgeInsetsDirectional.only( - top: 16.0, - bottom: 16.0, - start: 32.0, - end: 32.0, - ), - child: Container( - margin: - const EdgeInsetsDirectional.only(start: 4.0), - child: PlanStep( - stepNum: '1', - description: 'choose_plan'.i18n, - ), - ), - ), - // * Card - ...plans.toList().reversed.map( - (plan) => Container( - color: white, - padding: const EdgeInsetsDirectional.only( - start: 32.0, - end: 32.0, - ), - child: PlanCard( - plan: plan.value, - isPro: proUser, - ), - ), - ), - ], + ), + const CDivider(height: 24), + ], + ), + ), + // * Step + Container( + color: white, + padding: const EdgeInsetsDirectional.only( + top: 16.0, + bottom: 16.0, + start: 32.0, + end: 32.0, + ), + child: Container( + margin: const EdgeInsetsDirectional.only(start: 4.0), + child: PlanStep( + stepNum: '1', + description: 'choose_plan'.i18n, ), ), - // * Footer - Padding( - padding: const EdgeInsetsDirectional.only(top: 24.0), - child: Container( - height: 40, - alignment: Alignment.center, - width: MediaQuery.of(context).size.width, - decoration: BoxDecoration( - border: Border( - top: BorderSide(width: 1.0, color: grey3), + ), + // * Card + ...plans.toList().reversed.map( + (plan) => Container( + color: white, + padding: const EdgeInsetsDirectional.only( + start: 32.0, + end: 32.0, ), - color: grey1, ), - child: GestureDetector( - onTap: () async => await context.pushRoute( - ResellerCodeCheckout(isPro: proUser), - ), - child: CText( - 'Have a Lantern Pro activation code? Click here.', - style: tsBody1.copiedWith(color: grey5), - ), - ), // Translations ), - ), - ], + ], + ), + ), + // * Footer + Padding( + padding: const EdgeInsetsDirectional.only(top: 24.0), + child: Container( + height: 40, + alignment: Alignment.center, + width: MediaQuery.of(context).size.width, + decoration: BoxDecoration( + border: Border( + top: BorderSide(width: 1.0, color: grey3), + ), + color: grey1, ), + child: GestureDetector( + onTap: () async => await context.pushRoute( + ResellerCodeCheckout(isPro: proUser), + ), + child: CText( + 'Have a Lantern Pro activation code? Click here.', + style: tsBody1.copiedWith(color: grey5), + ), + ), // Translations ), - ); - }, - ); - }), - ); + ), + ], + ), + ), + )); } }