Referral: integrate the APIs
This commit is contained in:
parent
db27608b9c
commit
8e9eebe2b4
7 changed files with 458 additions and 167 deletions
|
@ -28,6 +28,7 @@ import "package:photos/services/object_detection/object_detection_service.dart";
|
|||
import 'package:photos/services/push_service.dart';
|
||||
import 'package:photos/services/remote_sync_service.dart';
|
||||
import 'package:photos/services/search_service.dart';
|
||||
import "package:photos/services/storage_bonus_service.dart";
|
||||
import 'package:photos/services/sync_service.dart';
|
||||
import 'package:photos/services/trash_sync_service.dart';
|
||||
import 'package:photos/services/update_service.dart';
|
||||
|
@ -153,6 +154,7 @@ Future<void> _init(bool isBackground, {String via = ''}) async {
|
|||
LocalSettings.instance.init(preferences);
|
||||
LocalFileUpdateService.instance.init(preferences);
|
||||
SearchService.instance.init();
|
||||
StorageBonusService.instance.init(preferences);
|
||||
if (Platform.isIOS) {
|
||||
PushService.instance.init().then((_) {
|
||||
FirebaseMessaging.onBackgroundMessage(
|
||||
|
|
|
@ -4,6 +4,7 @@ class ReferralView {
|
|||
bool enableApplyCode;
|
||||
bool isFamilyMember;
|
||||
bool hasAppliedCode;
|
||||
int claimedStorage;
|
||||
|
||||
ReferralView({
|
||||
required this.planInfo,
|
||||
|
@ -11,6 +12,7 @@ class ReferralView {
|
|||
required this.enableApplyCode,
|
||||
required this.isFamilyMember,
|
||||
required this.hasAppliedCode,
|
||||
required this.claimedStorage,
|
||||
});
|
||||
|
||||
factory ReferralView.fromJson(Map<String, dynamic> json) => ReferralView(
|
||||
|
@ -19,6 +21,7 @@ class ReferralView {
|
|||
enableApplyCode: json["enableApplyCode"],
|
||||
isFamilyMember: json["isFamilyMember"],
|
||||
hasAppliedCode: json["hasAppliedCode"],
|
||||
claimedStorage: json["claimedStorage"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
|
@ -27,6 +30,7 @@ class ReferralView {
|
|||
"enableApplyCode": enableApplyCode,
|
||||
"isFamilyMember": isFamilyMember,
|
||||
"hasAppliedCode": hasAppliedCode,
|
||||
"claimedStorage": claimedStorage,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -15,4 +15,9 @@ class StorageBonusService {
|
|||
|
||||
static StorageBonusService instance =
|
||||
StorageBonusService._privateConstructor();
|
||||
|
||||
// getter for gateway
|
||||
StorageBonusGateway getGateway() {
|
||||
return gateway;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
import "package:dotted_border/dotted_border.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:photos/models/api/storage_bonus/storage_bonus.dart";
|
||||
import "package:photos/models/user_details.dart";
|
||||
import "package:photos/services/storage_bonus_service.dart";
|
||||
import "package:photos/services/user_service.dart";
|
||||
import "package:photos/theme/ente_theme.dart";
|
||||
import "package:photos/ui/common/loading_widget.dart";
|
||||
import "package:photos/ui/common/web_page.dart";
|
||||
import "package:photos/ui/components/captioned_text_widget.dart";
|
||||
import "package:photos/ui/components/divider_widget.dart";
|
||||
import "package:photos/ui/components/icon_button_widget.dart";
|
||||
|
@ -8,7 +14,8 @@ import "package:photos/ui/components/menu_item_widget/menu_item_widget.dart";
|
|||
import "package:photos/ui/components/title_bar_title_widget.dart";
|
||||
import "package:photos/ui/components/title_bar_widget.dart";
|
||||
import "package:photos/ui/growth/apply_code_screen.dart";
|
||||
import "package:photos/ui/tools/debug/app_storage_viewer.dart";
|
||||
import "package:photos/ui/growth/storage_details_screen.dart";
|
||||
import "package:photos/utils/data_util.dart";
|
||||
import "package:photos/utils/navigation_util.dart";
|
||||
|
||||
class ReferralScreen extends StatefulWidget {
|
||||
|
@ -20,6 +27,7 @@ class ReferralScreen extends StatefulWidget {
|
|||
|
||||
class _ReferralScreenState extends State<ReferralScreen> {
|
||||
bool canApplyCode = true;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
@ -27,8 +35,6 @@ class _ReferralScreenState extends State<ReferralScreen> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = getEnteColorScheme(context);
|
||||
final textStyle = getEnteTextTheme(context);
|
||||
return Scaffold(
|
||||
body: CustomScrollView(
|
||||
primary: false,
|
||||
|
@ -37,7 +43,7 @@ class _ReferralScreenState extends State<ReferralScreen> {
|
|||
flexibleSpaceTitle: const TitleBarTitleWidget(
|
||||
title: "Claim free storage",
|
||||
),
|
||||
flexibleSpaceCaption: "Invite friends to claim free storage",
|
||||
flexibleSpaceCaption: "Invite your friends",
|
||||
actionIcons: [
|
||||
IconButtonWidget(
|
||||
icon: Icons.close_outlined,
|
||||
|
@ -53,169 +59,22 @@ class _ReferralScreenState extends State<ReferralScreen> {
|
|||
delegate: SliverChildBuilderDelegate(
|
||||
(delegateBuildContext, index) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 20),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Container with 8 border radius and red color
|
||||
Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: colorScheme.strokeFaint,
|
||||
width: 1,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 12,
|
||||
horizontal: 12,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
"1. Give this code to your "
|
||||
"friends",
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Center(
|
||||
child: DottedBorder(
|
||||
color: colorScheme.strokeMuted,
|
||||
//color of dotted/dash line
|
||||
strokeWidth: 1,
|
||||
//thickness of dash/dots
|
||||
dashPattern: const [6, 6],
|
||||
radius: const Radius.circular(8),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 26.0,
|
||||
top: 14,
|
||||
right: 12,
|
||||
bottom: 14,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
"AX17D9EB",
|
||||
style:
|
||||
textStyle.bodyBold.copyWith(
|
||||
color: colorScheme.primary700,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Icon(
|
||||
Icons.adaptive.share,
|
||||
size: 22,
|
||||
color: colorScheme.strokeMuted,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
const Text(
|
||||
"2. They sign up for a paid plan",
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
const Text(
|
||||
"3. Both of you get 10 GB* free",
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
"* You can at max double your storage",
|
||||
style: textStyle.mini.copyWith(
|
||||
color: colorScheme.textMuted,
|
||||
),
|
||||
textAlign: TextAlign.left,
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
canApplyCode
|
||||
? MenuItemWidget(
|
||||
captionedTextWidget:
|
||||
const CaptionedTextWidget(
|
||||
title: "Apply code",
|
||||
),
|
||||
menuItemColor: colorScheme.fillFaint,
|
||||
trailingWidget: Icon(
|
||||
Icons.chevron_right_outlined,
|
||||
color: colorScheme.strokeBase,
|
||||
),
|
||||
singleBorderRadius: 8,
|
||||
alignCaptionedTextToLeft: true,
|
||||
isBottomBorderRadiusRemoved: true,
|
||||
onTap: () async {
|
||||
routeToPage(
|
||||
context, const ApplyCodeScreen());
|
||||
},
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
canApplyCode
|
||||
? DividerWidget(
|
||||
dividerType: DividerType.menu,
|
||||
bgColor: colorScheme.fillFaint,
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
MenuItemWidget(
|
||||
captionedTextWidget: const CaptionedTextWidget(
|
||||
title: "FAQ",
|
||||
),
|
||||
menuItemColor: colorScheme.fillFaint,
|
||||
trailingWidget: Icon(
|
||||
Icons.chevron_right_outlined,
|
||||
color: colorScheme.strokeBase,
|
||||
),
|
||||
singleBorderRadius: 8,
|
||||
isTopBorderRadiusRemoved: canApplyCode,
|
||||
alignCaptionedTextToLeft: true,
|
||||
onTap: () async {
|
||||
routeToPage(context, const AppStorageViewer());
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8.0,
|
||||
vertical: 6.0,
|
||||
),
|
||||
child: Text(
|
||||
"You have claimed 0 GB so far",
|
||||
style: textStyle.small.copyWith(
|
||||
color: colorScheme.textMuted,
|
||||
),
|
||||
),
|
||||
),
|
||||
MenuItemWidget(
|
||||
captionedTextWidget: const CaptionedTextWidget(
|
||||
title: "Details",
|
||||
),
|
||||
menuItemColor: colorScheme.fillFaint,
|
||||
trailingWidget: Icon(
|
||||
Icons.chevron_right_outlined,
|
||||
color: colorScheme.strokeBase,
|
||||
),
|
||||
singleBorderRadius: 8,
|
||||
alignCaptionedTextToLeft: true,
|
||||
onTap: () async {
|
||||
routeToPage(context, const AppStorageViewer());
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 16, vertical: 20),
|
||||
child: FutureBuilder<ReferralView>(
|
||||
future: StorageBonusService.instance
|
||||
.getGateway()
|
||||
.getReferralView(),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
return ReferralWidget(
|
||||
snapshot.data!,
|
||||
UserService.instance.getCachedUserDetails()!,
|
||||
);
|
||||
} else {
|
||||
return const EnteLoadingWidget();
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
|
@ -227,3 +86,198 @@ class _ReferralScreenState extends State<ReferralScreen> {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ReferralWidget extends StatelessWidget {
|
||||
final ReferralView referralView;
|
||||
final UserDetails userDetails;
|
||||
|
||||
const ReferralWidget(this.referralView, this.userDetails, {super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = getEnteColorScheme(context);
|
||||
final textStyle = getEnteTextTheme(context);
|
||||
final bool isReferralEnabled = referralView.planInfo.isEnabled;
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Container with 8 border radius and red color
|
||||
isReferralEnabled
|
||||
? Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: colorScheme.strokeFaint,
|
||||
width: 1,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 12,
|
||||
horizontal: 12,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
"1. Give this code to your "
|
||||
"friends",
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Center(
|
||||
child: DottedBorder(
|
||||
color: colorScheme.strokeMuted,
|
||||
//color of dotted/dash line
|
||||
strokeWidth: 1,
|
||||
//thickness of dash/dots
|
||||
dashPattern: const [6, 6],
|
||||
radius: const Radius.circular(8),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 26.0,
|
||||
top: 14,
|
||||
right: 12,
|
||||
bottom: 14,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
referralView.code,
|
||||
style: textStyle.bodyBold.copyWith(
|
||||
color: colorScheme.primary700,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Icon(
|
||||
Icons.adaptive.share,
|
||||
size: 22,
|
||||
color: colorScheme.strokeMuted,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
const Text(
|
||||
"2. They sign up for a paid plan",
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Text(
|
||||
"3. Both of you get ${referralView.planInfo.storageInGB} "
|
||||
"GB* free",
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 48),
|
||||
child: Center(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.error_outline,
|
||||
color: colorScheme.strokeMuted,
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Text("Referrals are currently paused",
|
||||
style: textStyle.small
|
||||
.copyWith(color: colorScheme.textFaint)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
isReferralEnabled
|
||||
? Text(
|
||||
"* You can at max double your storage",
|
||||
style: textStyle.mini.copyWith(
|
||||
color: colorScheme.textMuted,
|
||||
),
|
||||
textAlign: TextAlign.left,
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
const SizedBox(height: 24),
|
||||
referralView.enableApplyCode
|
||||
? MenuItemWidget(
|
||||
captionedTextWidget: const CaptionedTextWidget(
|
||||
title: "Apply code",
|
||||
),
|
||||
menuItemColor: colorScheme.fillFaint,
|
||||
trailingWidget: Icon(
|
||||
Icons.chevron_right_outlined,
|
||||
color: colorScheme.strokeBase,
|
||||
),
|
||||
singleBorderRadius: 8,
|
||||
alignCaptionedTextToLeft: true,
|
||||
isBottomBorderRadiusRemoved: true,
|
||||
onTap: () async {
|
||||
routeToPage(
|
||||
context,
|
||||
const ApplyCodeScreen(),
|
||||
);
|
||||
},
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
referralView.enableApplyCode
|
||||
? DividerWidget(
|
||||
dividerType: DividerType.menu,
|
||||
bgColor: colorScheme.fillFaint,
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
MenuItemWidget(
|
||||
captionedTextWidget: const CaptionedTextWidget(
|
||||
title: "FAQ",
|
||||
),
|
||||
menuItemColor: colorScheme.fillFaint,
|
||||
trailingWidget: Icon(
|
||||
Icons.chevron_right_outlined,
|
||||
color: colorScheme.strokeBase,
|
||||
),
|
||||
singleBorderRadius: 8,
|
||||
isTopBorderRadiusRemoved: referralView.enableApplyCode,
|
||||
alignCaptionedTextToLeft: true,
|
||||
onTap: () async {
|
||||
routeToPage(context, const WebPage("FAQ", "https://ente.io/faq"));
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8.0,
|
||||
vertical: 6.0,
|
||||
),
|
||||
child: Text(
|
||||
"${referralView.isFamilyMember ? 'Your family has' : 'You have'} claimed "
|
||||
"${convertBytesToAbsoluteGBs(referralView.claimedStorage)} GB so far",
|
||||
style: textStyle.small.copyWith(
|
||||
color: colorScheme.textMuted,
|
||||
),
|
||||
),
|
||||
),
|
||||
MenuItemWidget(
|
||||
captionedTextWidget: const CaptionedTextWidget(
|
||||
title: "Details",
|
||||
),
|
||||
menuItemColor: colorScheme.fillFaint,
|
||||
trailingWidget: Icon(
|
||||
Icons.chevron_right_outlined,
|
||||
color: colorScheme.strokeBase,
|
||||
),
|
||||
singleBorderRadius: 8,
|
||||
alignCaptionedTextToLeft: true,
|
||||
onTap: () async {
|
||||
routeToPage(
|
||||
context,
|
||||
StorageDetailsScreen(referralView, userDetails),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
221
lib/ui/growth/storage_details_screen.dart
Normal file
221
lib/ui/growth/storage_details_screen.dart
Normal file
|
@ -0,0 +1,221 @@
|
|||
import "dart:math";
|
||||
|
||||
import "package:flutter/material.dart";
|
||||
import "package:photos/models/api/storage_bonus/storage_bonus.dart";
|
||||
import "package:photos/models/user_details.dart";
|
||||
import "package:photos/services/storage_bonus_service.dart";
|
||||
import "package:photos/theme/ente_theme.dart";
|
||||
import "package:photos/ui/common/loading_widget.dart";
|
||||
import "package:photos/ui/components/icon_button_widget.dart";
|
||||
import "package:photos/ui/components/title_bar_title_widget.dart";
|
||||
import "package:photos/ui/components/title_bar_widget.dart";
|
||||
import "package:photos/utils/data_util.dart";
|
||||
|
||||
class StorageDetailsScreen extends StatefulWidget {
|
||||
final ReferralView referralView;
|
||||
final UserDetails userDetails;
|
||||
const StorageDetailsScreen(this.referralView, this.userDetails, {super.key});
|
||||
|
||||
@override
|
||||
State<StorageDetailsScreen> createState() => _StorageDetailsScreenState();
|
||||
}
|
||||
|
||||
class _StorageDetailsScreenState extends State<StorageDetailsScreen> {
|
||||
bool canApplyCode = true;
|
||||
int maxClaimableStorageBonus = 2000;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
maxClaimableStorageBonus =
|
||||
widget.referralView.planInfo.maxClaimableStorageInGB;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = getEnteColorScheme(context);
|
||||
final textStyle = getEnteTextTheme(context);
|
||||
return Scaffold(
|
||||
body: CustomScrollView(
|
||||
primary: false,
|
||||
slivers: <Widget>[
|
||||
TitleBarWidget(
|
||||
flexibleSpaceTitle: const TitleBarTitleWidget(
|
||||
title: "Claim free storage",
|
||||
),
|
||||
flexibleSpaceCaption: "Details",
|
||||
actionIcons: [
|
||||
IconButtonWidget(
|
||||
icon: Icons.close_outlined,
|
||||
iconButtonType: IconButtonType.secondary,
|
||||
onTap: () {
|
||||
Navigator.of(context)
|
||||
..pop()
|
||||
..pop()
|
||||
..pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
SliverList(
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
(delegateBuildContext, index) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 20),
|
||||
// wrap the child inside a FutureBuilder to get the
|
||||
// current state of the TextField
|
||||
child: FutureBuilder<BonusDetails>(
|
||||
future: StorageBonusService.instance
|
||||
.getGateway()
|
||||
.getBonusDetails(),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState ==
|
||||
ConnectionState.waiting) {
|
||||
return const Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(top: 48.0),
|
||||
child: EnteLoadingWidget(),
|
||||
),
|
||||
);
|
||||
}
|
||||
if (snapshot.hasError) {
|
||||
debugPrint(snapshot.error.toString());
|
||||
return const Text("Oops, something went wrong");
|
||||
} else {
|
||||
final BonusDetails data = snapshot.data!;
|
||||
return Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 12.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
BonusInfoSection(
|
||||
sectionName: "People using your code",
|
||||
leftValue: data.refUpgradeCount,
|
||||
leftUnitName: "eligible",
|
||||
rightValue: data.refUpgradeCount >= 0
|
||||
? data.refCount
|
||||
: null,
|
||||
rightUnitName: "total",
|
||||
showUnit: data.refCount > 0,
|
||||
),
|
||||
data.hasAppliedCode
|
||||
? const BonusInfoSection(
|
||||
sectionName: "Code used by you",
|
||||
leftValue: 1,
|
||||
showUnit: false,
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
BonusInfoSection(
|
||||
sectionName: "Free storage claimed",
|
||||
leftValue: data.refUpgradeCount,
|
||||
leftUnitName: "GB",
|
||||
rightValue: maxClaimableStorageBonus,
|
||||
rightUnitName: "GB",
|
||||
),
|
||||
BonusInfoSection(
|
||||
sectionName: "Free storage usable",
|
||||
leftValue: min(
|
||||
widget.referralView.claimedStorage,
|
||||
widget.userDetails.getTotalStorage(),
|
||||
),
|
||||
leftUnitName: "GB",
|
||||
rightValue: convertBytesToAbsoluteGBs(
|
||||
widget.userDetails.getTotalStorage()),
|
||||
rightUnitName: "GB",
|
||||
),
|
||||
const SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
Text(
|
||||
"Usable storage is limited by your current"
|
||||
" plan, but you can claim upto "
|
||||
"$maxClaimableStorageBonus GB. Excess"
|
||||
" claimed storage will automatically become"
|
||||
" usable when you upgrade your plan.",
|
||||
style: textStyle.small
|
||||
.copyWith(color: colorScheme.textMuted),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
childCount: 1,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class BonusInfoSection extends StatelessWidget {
|
||||
final String sectionName;
|
||||
final bool showUnit;
|
||||
final String leftUnitName;
|
||||
final String rightUnitName;
|
||||
final int leftValue;
|
||||
final int? rightValue;
|
||||
|
||||
const BonusInfoSection({
|
||||
super.key,
|
||||
required this.sectionName,
|
||||
required this.leftValue,
|
||||
this.leftUnitName = "GB",
|
||||
this.rightValue,
|
||||
this.rightUnitName = "GB",
|
||||
this.showUnit = true,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = getEnteColorScheme(context);
|
||||
final textStyle = getEnteTextTheme(context);
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
sectionName,
|
||||
style: textStyle.body.copyWith(
|
||||
color: colorScheme.textMuted,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
RichText(
|
||||
text: TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: leftValue.toString(),
|
||||
style: textStyle.h3,
|
||||
),
|
||||
TextSpan(
|
||||
text: showUnit ? " $leftUnitName" : "",
|
||||
style: textStyle.large,
|
||||
),
|
||||
TextSpan(
|
||||
text: (rightValue != null && rightValue! > 0)
|
||||
? " / ${rightValue.toString()}"
|
||||
: "",
|
||||
style: textStyle.h3,
|
||||
),
|
||||
TextSpan(
|
||||
text: showUnit && (rightValue != null && rightValue! > 0)
|
||||
? " $rightUnitName"
|
||||
: "",
|
||||
style: textStyle.large,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -63,6 +63,7 @@ class GeneralSectionWidget extends StatelessWidget {
|
|||
routeToPage(
|
||||
context,
|
||||
const ReferralScreen(),
|
||||
forceCustomPageRoute: true,
|
||||
);
|
||||
},
|
||||
),
|
||||
|
|
|
@ -35,6 +35,10 @@ num convertBytesToGBs(int bytes) {
|
|||
return num.parse((bytes / (pow(1024, 3))).toStringAsFixed(1));
|
||||
}
|
||||
|
||||
int convertBytesToAbsoluteGBs(int bytes) {
|
||||
return (bytes / pow(1024, 3)).round();
|
||||
}
|
||||
|
||||
int convertBytesToMBs(int bytes) {
|
||||
return (bytes / pow(1024, 2)).round();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue