Remove unused widgets

This commit is contained in:
Neeraj Gupta 2023-04-08 17:08:53 +05:30
parent c10655e353
commit 33b141916f
No known key found for this signature in database
GPG key ID: 3C5A1684DC1729E1
5 changed files with 0 additions and 789 deletions

View file

@ -1,153 +0,0 @@
// @dart=2.9
import 'dart:convert';
import 'package:ente_auth/core/network.dart';
import 'package:ente_auth/ente_theme_data.dart';
import 'package:ente_auth/ui/common/loading_widget.dart';
import 'package:expansion_tile_card/expansion_tile_card.dart';
import 'package:flutter/material.dart';
class BillingQuestionsWidget extends StatelessWidget {
const BillingQuestionsWidget({
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: Network.instance
.getDio()
.get("https://static.ente.io/faq.json")
.then((response) {
final faqItems = <FaqItem>[];
for (final item in response.data as List) {
faqItems.add(FaqItem.fromMap(item));
}
return faqItems;
}),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
final faqs = <Widget>[];
faqs.add(
const Padding(
padding: EdgeInsets.all(24),
child: Text(
"FAQs",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
),
);
for (final faq in snapshot.data) {
faqs.add(FaqWidget(faq: faq));
}
faqs.add(
const Padding(
padding: EdgeInsets.all(16),
),
);
return SingleChildScrollView(
child: Column(
children: faqs,
),
);
} else {
return const EnteLoadingWidget();
}
},
);
}
}
class FaqWidget extends StatelessWidget {
const FaqWidget({
Key key,
@required this.faq,
}) : super(key: key);
final FaqItem faq;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(2),
child: ExpansionTileCard(
elevation: 0,
title: Text(faq.q),
expandedTextColor: Theme.of(context).colorScheme.alternativeColor,
baseColor: Theme.of(context).cardColor,
children: [
Padding(
padding: const EdgeInsets.only(
left: 16,
right: 16,
bottom: 12,
),
child: Text(
faq.a,
style: const TextStyle(
height: 1.5,
),
),
)
],
),
);
}
}
class FaqItem {
final String q;
final String a;
FaqItem({
this.q,
this.a,
});
FaqItem copyWith({
String q,
String a,
}) {
return FaqItem(
q: q ?? this.q,
a: a ?? this.a,
);
}
Map<String, dynamic> toMap() {
return {
'q': q,
'a': a,
};
}
factory FaqItem.fromMap(Map<String, dynamic> map) {
if (map == null) return null;
return FaqItem(
q: map['q'],
a: map['a'],
);
}
String toJson() => json.encode(toMap());
factory FaqItem.fromJson(String source) =>
FaqItem.fromMap(json.decode(source));
@override
String toString() => 'FaqItem(q: $q, a: $a)';
@override
bool operator ==(Object o) {
if (identical(this, o)) return true;
return o is FaqItem && o.q == q && o.a == a;
}
@override
int get hashCode => q.hashCode ^ a.hashCode;
}

View file

@ -1,149 +0,0 @@
// @dart=2.9
import 'package:ente_auth/ente_theme_data.dart';
import 'package:ente_auth/l10n/l10n.dart';
import 'package:ente_auth/models/user_details.dart';
import 'package:ente_auth/services/user_service.dart';
import 'package:ente_auth/ui/common/dialogs.dart';
import 'package:ente_auth/utils/dialog_util.dart';
import 'package:flutter/material.dart';
class ChildSubscriptionWidget extends StatelessWidget {
const ChildSubscriptionWidget({
Key key,
@required this.userDetails,
}) : super(key: key);
final UserDetails userDetails;
@override
Widget build(BuildContext context) {
final l10n = context.l10n;
final String familyAdmin = userDetails.familyData.members
.firstWhere((element) => element.isAdmin)
.email;
return Padding(
padding: const EdgeInsets.symmetric(vertical: 32),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Center(
child: Text(
l10n.inFamilyPlanMessage,
style: Theme.of(context).textTheme.bodyText1,
),
),
const Padding(
padding: EdgeInsets.symmetric(vertical: 8),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
children: [
const TextSpan(
text: "Please contact ",
),
TextSpan(
text: familyAdmin,
style:
const TextStyle(color: Color.fromRGBO(29, 185, 84, 1)),
),
const TextSpan(
text: " to manage your subscription",
),
],
style: Theme.of(context).textTheme.bodyText1,
),
),
),
const Padding(
padding: EdgeInsets.symmetric(vertical: 8),
),
Image.asset(
"assets/family_plan_leave.png",
height: 256,
),
const Padding(
padding: EdgeInsets.symmetric(vertical: 0),
),
InkWell(
child: OutlinedButton(
style: OutlinedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
padding:
const EdgeInsets.symmetric(vertical: 18, horizontal: 100),
backgroundColor: Colors.red[500],
),
child: Text(
l10n.leaveFamily,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
color: Colors.white, // same for both themes
),
textAlign: TextAlign.center,
),
onPressed: () async => {await _leaveFamilyPlan(context)},
),
),
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
children: [
TextSpan(
text: "Please contact ",
style: Theme.of(context).textTheme.bodyText2,
),
TextSpan(
text: "support@ente.io",
style: Theme.of(context).textTheme.bodyText2.copyWith(
color: const Color.fromRGBO(29, 185, 84, 1),
),
),
TextSpan(
text: " for help",
style: Theme.of(context).textTheme.bodyText2,
),
],
),
),
),
),
],
),
);
}
Future<void> _leaveFamilyPlan(BuildContext context) async {
final l10n = context.l10n;
final choice = await showChoiceDialog(
context,
l10n.leaveFamily,
l10n.leaveFamilyMessage,
firstAction: l10n.no,
secondAction: l10n.yes,
firstActionColor: Theme.of(context).colorScheme.alternativeColor,
secondActionColor: Theme.of(context).colorScheme.onSurface,
);
if (choice != DialogUserChoice.secondChoice) {
return;
}
final dialog = createProgressDialog(context, l10n.pleaseWaitTitle);
await dialog.show();
try {
await UserService.instance.leaveFamilyPlan();
dialog.hide();
Navigator.of(context).pop('');
} catch (e) {
dialog.hide();
showGenericErrorDialog(context);
}
}
}

View file

@ -1,268 +0,0 @@
// @dart=2.9
import 'dart:io';
import 'package:ente_auth/ente_theme_data.dart';
import 'package:ente_auth/l10n/l10n.dart';
import 'package:ente_auth/models/subscription.dart';
import 'package:ente_auth/services/billing_service.dart';
import 'package:ente_auth/services/user_service.dart';
import 'package:ente_auth/ui/common/loading_widget.dart';
import 'package:ente_auth/ui/common/progress_dialog.dart';
import 'package:ente_auth/utils/dialog_util.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:logging/logging.dart';
class PaymentWebPage extends StatefulWidget {
final String planId;
final String actionType;
const PaymentWebPage({Key key, this.planId, this.actionType})
: super(key: key);
@override
State<StatefulWidget> createState() => _PaymentWebPageState();
}
class _PaymentWebPageState extends State<PaymentWebPage> {
final _logger = Logger("PaymentWebPageState");
final UserService userService = UserService.instance;
final BillingService billingService = BillingService.instance;
final String basePaymentUrl = kWebPaymentBaseEndpoint;
ProgressDialog _dialog;
InAppWebViewController webView;
double progress = 0;
Uri initPaymentUrl;
@override
void initState() {
userService.getPaymentToken().then((token) {
initPaymentUrl = _getPaymentUrl(token);
setState(() {});
});
if (Platform.isAndroid && kDebugMode) {
AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true);
}
super.initState();
}
@override
Widget build(BuildContext context) {
final l10n = context.l10n;
_dialog = createProgressDialog(context, l10n.pleaseWaitTitle);
if (initPaymentUrl == null) {
return const EnteLoadingWidget();
}
return WillPopScope(
onWillPop: () async => _buildPageExitWidget(context),
child: Scaffold(
appBar: AppBar(
title: const Text('Subscription'),
),
body: Column(
children: <Widget>[
(progress != 1.0)
? LinearProgressIndicator(value: progress)
: Container(),
Expanded(
child: InAppWebView(
initialUrlRequest: URLRequest(url: initPaymentUrl),
onProgressChanged:
(InAppWebViewController controller, int progress) {
setState(() {
this.progress = progress / 100;
});
},
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
useShouldOverrideUrlLoading: true,
),
),
shouldOverrideUrlLoading: (controller, navigationAction) async {
final loadingUri = navigationAction.request.url;
_logger.info("Loading url $loadingUri");
// handle the payment response
if (_isPaymentActionComplete(loadingUri)) {
await _handlePaymentResponse(loadingUri);
return NavigationActionPolicy.CANCEL;
}
return NavigationActionPolicy.ALLOW;
},
onConsoleMessage: (controller, consoleMessage) {
_logger.info(consoleMessage);
},
onLoadStart: (controller, navigationAction) async {
if (!_dialog.isShowing()) {
await _dialog.show();
}
},
onLoadError: (controller, navigationAction, code, msg) async {
if (_dialog.isShowing()) {
await _dialog.hide();
}
},
onLoadHttpError:
(controller, navigationAction, code, msg) async {
_logger.info("onHttpError with $code and msg = $msg");
},
onLoadStop: (controller, navigationAction) async {
_logger.info("loadStart" + navigationAction.toString());
if (_dialog.isShowing()) {
await _dialog.hide();
}
},
),
),
].where((Object o) => o != null).toList(),
),
),
);
}
@override
void dispose() {
_dialog.hide();
super.dispose();
}
Uri _getPaymentUrl(String paymentToken) {
final queryParameters = {
'productID': widget.planId,
'paymentToken': paymentToken,
'action': widget.actionType,
'redirectURL': kWebPaymentRedirectUrl,
};
final tryParse = Uri.tryParse(kWebPaymentBaseEndpoint);
if (kDebugMode && kWebPaymentBaseEndpoint.startsWith("http://")) {
return Uri.http(tryParse.authority, tryParse.path, queryParameters);
} else {
return Uri.https(tryParse.authority, tryParse.path, queryParameters);
}
}
// show dialog to handle accidental back press.
Future<bool> _buildPageExitWidget(BuildContext context) {
return showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('Are you sure you want to exit?'),
actions: <Widget>[
TextButton(
child: const Text(
'Yes',
style: TextStyle(
color: Colors.redAccent,
),
),
onPressed: () => Navigator.of(context).pop(true),
),
TextButton(
child: Text(
'No',
style: TextStyle(
color: Theme.of(context).colorScheme.alternativeColor,
),
),
onPressed: () => Navigator.of(context).pop(false),
),
],
),
);
}
bool _isPaymentActionComplete(Uri loadingUri) {
return loadingUri.toString().startsWith(kWebPaymentRedirectUrl);
}
Future<void> _handlePaymentResponse(Uri uri) async {
final queryParams = uri.queryParameters;
final paymentStatus = uri.queryParameters['status'] ?? '';
_logger.fine('handle payment response with status $paymentStatus');
if (paymentStatus == 'success') {
await _handlePaymentSuccess(queryParams);
} else if (paymentStatus == 'fail') {
final reason = queryParams['reason'] ?? '';
await _handlePaymentFailure(reason);
} else {
// should never reach here
_logger.severe("unexpected status", uri.toString());
showGenericErrorDialog(context);
}
}
Future<void> _handlePaymentFailure(String reason) async {
await showDialog(
context: context,
barrierDismissible: false,
builder: (context) => AlertDialog(
title: const Text('Payment failed'),
content: Text("Unfortunately your payment failed due to $reason"),
actions: <Widget>[
TextButton(
child: const Text('Ok'),
onPressed: () {
Navigator.of(context).pop('dialog');
},
),
],
),
);
Navigator.of(context).pop(true);
}
// return true if verifySubscription didn't throw any exceptions
Future<void> _handlePaymentSuccess(Map<String, String> queryParams) async {
final checkoutSessionID = queryParams['session_id'] ?? '';
await _dialog.show();
try {
final response = await billingService.verifySubscription(
widget.planId,
checkoutSessionID,
paymentProvider: stripe,
);
await _dialog.hide();
if (response != null) {
final content = widget.actionType == 'buy'
? 'Your purchase was successful'
: 'Your subscription was updated successfully';
await _showExitPageDialog(title: 'Thank you', content: content);
} else {
throw Exception("verifySubscription api failed");
}
} catch (error) {
_logger.severe(error);
await _dialog.hide();
await _showExitPageDialog(
title: 'Failed to verify payment status',
content: 'Please wait for sometime before retrying',
);
}
}
// warn the user to wait for sometime before trying another payment
Future<dynamic> _showExitPageDialog({String title, String content}) {
return showDialog(
context: context,
barrierDismissible: false,
builder: (context) => AlertDialog(
title: Text(title),
content: Text(content),
actions: <Widget>[
TextButton(
child: Text(
'Ok',
style: TextStyle(
color: Theme.of(context).colorScheme.alternativeColor,
),
),
onPressed: () {
Navigator.of(context).pop('dialog');
},
),
],
),
).then((val) => Navigator.pop(context, true));
}
}

View file

@ -1,142 +0,0 @@
// @dart=2.9
import 'package:ente_auth/ente_theme_data.dart';
import 'package:ente_auth/models/subscription.dart';
import 'package:ente_auth/ui/payment/billing_questions_widget.dart';
import 'package:ente_auth/utils/data_util.dart';
import 'package:ente_auth/utils/date_time_util.dart';
import 'package:flutter/material.dart';
class SubscriptionHeaderWidget extends StatefulWidget {
final bool isOnboarding;
final int currentUsage;
const SubscriptionHeaderWidget({
Key key,
this.isOnboarding,
this.currentUsage,
}) : super(key: key);
@override
State<StatefulWidget> createState() {
return _SubscriptionHeaderWidgetState();
}
}
class _SubscriptionHeaderWidgetState extends State<SubscriptionHeaderWidget> {
@override
Widget build(BuildContext context) {
if (widget.isOnboarding) {
return Padding(
padding: const EdgeInsets.fromLTRB(20, 20, 20, 24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
"Select your plan",
style: Theme.of(context).textTheme.headline4,
),
],
),
const SizedBox(
height: 10,
),
Text(
"Ente preserves your memories, so they're always available to you, even if you lose your device ",
style: Theme.of(context).textTheme.caption,
),
],
),
);
} else {
return SizedBox(
height: 72,
width: double.infinity,
child: Padding(
padding: const EdgeInsets.all(24.0),
child: RichText(
text: TextSpan(
children: [
TextSpan(
text: "Current usage is ",
style: Theme.of(context).textTheme.subtitle1,
),
TextSpan(
text: formatBytes(widget.currentUsage),
style: Theme.of(context)
.textTheme
.subtitle1
.copyWith(fontWeight: FontWeight.bold),
)
],
),
),
),
);
}
}
}
class ValidityWidget extends StatelessWidget {
final Subscription currentSubscription;
const ValidityWidget({Key key, this.currentSubscription}) : super(key: key);
@override
Widget build(BuildContext context) {
if (currentSubscription == null) {
return const SizedBox.shrink();
}
final endDate = getDateAndMonthAndYear(
DateTime.fromMicrosecondsSinceEpoch(currentSubscription.expiryTime),
);
var message = "Renews on $endDate";
if (currentSubscription.productID == freeProductID) {
message = "Free plan valid till $endDate";
} else if (currentSubscription.attributes?.isCancelled ?? false) {
message = "Your subscription will be cancelled on $endDate";
}
return Padding(
padding: const EdgeInsets.only(top: 8),
child: Text(
message,
style: Theme.of(context).textTheme.caption,
),
);
}
}
class SubFaqWidget extends StatelessWidget {
const SubFaqWidget({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Align(
alignment: Alignment.bottomCenter,
child: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
showModalBottomSheet<void>(
backgroundColor: Theme.of(context).colorScheme.bgColorForQuestions,
barrierColor: Colors.black87,
context: context,
builder: (context) {
return const BillingQuestionsWidget();
},
);
},
child: Container(
padding: const EdgeInsets.all(40),
child: RichText(
text: TextSpan(
text: "Questions?",
style: Theme.of(context).textTheme.overline,
),
),
),
),
);
}
}

View file

@ -1,77 +0,0 @@
// @dart=2.9
import 'package:ente_auth/utils/data_util.dart';
import 'package:flutter/material.dart';
class SubscriptionPlanWidget extends StatelessWidget {
const SubscriptionPlanWidget({
Key key,
@required this.storage,
@required this.price,
@required this.period,
this.isActive = false,
}) : super(key: key);
final int storage;
final String price;
final String period;
final bool isActive;
String _displayPrice() {
final result = price + (period.isNotEmpty ? " / " + period : "");
return result.isNotEmpty ? result : "Trial plan";
}
@override
Widget build(BuildContext context) {
final Color textColor = isActive ? Colors.white : Colors.black;
return Container(
width: double.infinity,
color: Theme.of(context).colorScheme.onPrimary,
padding: EdgeInsets.symmetric(horizontal: isActive ? 8 : 16, vertical: 4),
child: Container(
decoration: BoxDecoration(
color: isActive
? const Color(0xFF22763F)
: const Color.fromRGBO(240, 240, 240, 1.0),
gradient: isActive
? const LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color(0xFF2CD267),
Color(0xFF1DB954),
],
)
: null,
),
// color: Colors.yellow,
padding:
EdgeInsets.symmetric(horizontal: isActive ? 22 : 20, vertical: 18),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
convertBytesToReadableFormat(storage),
style: Theme.of(context)
.textTheme
.headline6
.copyWith(color: textColor),
),
Text(
_displayPrice(),
style: Theme.of(context).textTheme.headline6.copyWith(
color: textColor,
fontWeight: FontWeight.normal,
),
),
],
),
],
),
),
);
}
}