v5.0.0 - Major release

This commit is contained in:
Anthony Gordon 2021-04-11 23:39:35 +01:00
parent 075dfdb752
commit 1737fa1604
54 changed files with 1399 additions and 587 deletions

View File

@ -28,6 +28,13 @@ STRIPE_LIVE_MODE="false"
RAZORPAY_ID="" RAZORPAY_ID=""
# Razorpay ID from https://razorpay.com # Razorpay ID from https://razorpay.com
# *<! ------ PAYPAL (OPTIONAL) ------!>*
PAYPAL_ACCOUNT_EMAIL="mystore@business.com"
# Your PayPal account email e.g. mystore@business.com
PAYPAL_LIVE_MODE="false"
# Change to 'true' for live payments
# *<! ------ EXTRAS ------!>* # *<! ------ EXTRAS ------!>*
PRODUCT_PLACEHOLDER_IMAGE="https://woosignal.com/images/woocommerce-placeholder.png" PRODUCT_PLACEHOLDER_IMAGE="https://woosignal.com/images/woocommerce-placeholder.png"

View File

@ -1,3 +1,14 @@
## [5.0.0] - 2020-04-11
* Major release
# Null safety libraries added
# PayPal Payment Gateway Added
# New theme customization
# Fixed Drawer Widget when using Light/Dark mode
# New config file for currency
* Pubspec.yaml dependency updates
# Bug fixes
## [4.0.0] - 2020-03-28 ## [4.0.0] - 2020-03-28
* Major release * Major release

View File

@ -4,7 +4,7 @@
# WooCommerce App: Label StoreMax # WooCommerce App: Label StoreMax
### Label StoreMax - v4.0.0 ### Label StoreMax - v5.0.0
[Official WooSignal WooCommerce App](https://woosignal.com) [Official WooSignal WooCommerce App](https://woosignal.com)
@ -44,7 +44,7 @@ Full documentation this available [here](https://woosignal.com/docs/app/ios/labe
- Browse products, make orders, customer login (via WordPress) - Browse products, make orders, customer login (via WordPress)
- Change app name, logo, customize default language, currency + more - Change app name, logo, customize default language, currency + more
- Light and dark mode - Light and dark mode
- Stripe, Cash On Delivery, RazorPay - Stripe, Cash On Delivery, RazorPay, PayPal
- Localized for en, es, pt, it, hi, fr - Localized for en, es, pt, it, hi, fr
- Orders show as normal in WooCommerce - Orders show as normal in WooCommerce

View File

@ -1,3 +0,0 @@
[
]

View File

@ -176,5 +176,13 @@
"Retry": "Wiederholen", "Retry": "Wiederholen",
"Retry later": "Versuchen Sie es später erneut", "Retry later": "Versuchen Sie es später erneut",
"Light Mode": "Lichtmodus", "Light Mode": "Lichtmodus",
"Dark Mode": "Dunkler Modus" "Dark Mode": "Dunkler Modus",
"PayPal Checkout": "PayPal Checkout",
"Processing Payment": "Zahlung verarbeiten",
"Please wait, your order is being processed and you will be redirected to the PayPal website.": "Bitte warten Sie, Ihre Bestellung wird bearbeitet und Sie werden auf die PayPal-Website weitergeleitet.",
"If you are not automatically redirected to PayPal within 5 seconds": "Wenn Sie nicht innerhalb von 5 Sekunden automatisch zu PayPal weitergeleitet werden",
"Payment Cancelled": "Zahlung storniert",
"The payment has been cancelled": "Die Zahlung wurde storniert",
"Must have": "Haben müssen",
"Our selection of new items": "Unsere Auswahl an Neuheiten"
} }

View File

@ -176,5 +176,13 @@
"Retry": "Retry", "Retry": "Retry",
"Retry later": "Retry later", "Retry later": "Retry later",
"Light Mode": "Light Mode", "Light Mode": "Light Mode",
"Dark Mode": "Dark Mode" "Dark Mode": "Dark Mode",
"PayPal Checkout": "PayPal Checkout",
"Processing Payment": "Processing Payment",
"Please wait, your order is being processed and you will be redirected to the PayPal website.": "Please wait, your order is being processed and you will be redirected to the PayPal website.",
"If you are not automatically redirected to PayPal within 5 seconds": "If you are not automatically redirected to PayPal within 5 seconds",
"Payment Cancelled": "Payment Cancelled",
"The payment has been cancelled": "The payment has been cancelled",
"Must have": "Must have",
"Our selection of new items": "Our selection of new items"
} }

View File

@ -176,5 +176,13 @@
"Retry": "Rever", "Retry": "Rever",
"Retry later": "Reintentar más tarde", "Retry later": "Reintentar más tarde",
"Light Mode": "Modo de luz", "Light Mode": "Modo de luz",
"Dark Mode": "Modo oscuro" "Dark Mode": "Modo oscuro",
"PayPal Checkout": "Pago con PayPal",
"Processing Payment": "Procesando el pago",
"Please wait, your order is being processed and you will be redirected to the PayPal website.": "Espere, su pedido se está procesando y será redirigido al sitio web de PayPal.",
"If you are not automatically redirected to PayPal within 5 seconds": "Si no se le redirige automáticamente a PayPal en 5 segundos",
"Payment Cancelled": "Pago cancelado",
"The payment has been cancelled": "El pago ha sido cancelado",
"Must have": "Debe tener",
"Our selection of new items": "Nuestra selección de novedades"
} }

View File

@ -176,5 +176,13 @@
"Retry": "Recommencez", "Retry": "Recommencez",
"Retry later": "Réessayer plus tard", "Retry later": "Réessayer plus tard",
"Light Mode": "Mode lumière", "Light Mode": "Mode lumière",
"Dark Mode": "Mode sombre" "Dark Mode": "Mode sombre",
"PayPal Checkout": "Paiement PayPal",
"Processing Payment": "Traitement du paiement",
"Please wait, your order is being processed and you will be redirected to the PayPal website.": "Veuillez patienter, votre commande est en cours de traitement et vous serez redirigé vers le site PayPal.",
"If you are not automatically redirected to PayPal within 5 seconds": "Si vous n'êtes pas automatiquement redirigé vers PayPal dans les 5 secondes",
"Payment Cancelled": "Paiement annulé",
"The payment has been cancelled": "Le paiement a été annulé",
"Must have": "Doit avoir",
"Our selection of new items": "Notre sélection de nouveautés"
} }

View File

@ -176,5 +176,13 @@
"Retry": "pun: prayaas karen", "Retry": "pun: prayaas karen",
"Retry later": "baad mein pun: prayaas karen", "Retry later": "baad mein pun: prayaas karen",
"Light Mode": "lait mod", "Light Mode": "lait mod",
"Dark Mode": "daark mod" "Dark Mode": "daark mod",
"PayPal Checkout": "pepaal chekaut",
"Processing Payment": "sansaadhan sambandhee bhugataan",
"Please wait, your order is being processed and you will be redirected to the PayPal website.": "krpaya prateeksha karen, aapaka aadesh sansaadhit kiya ja raha hai aur aapako pepaal vebasait par punah nirdeshit kiya jaega.",
"If you are not automatically redirected to PayPal within 5 seconds": "yadi aap 5 sekand ke bheetar svachaalit roop se pepail par punarnirdeshit nahin hote hain",
"Payment Cancelled": "bhugataan radd kiya gaya",
"The payment has been cancelled": "bhugataan radd kar diya gaya hai",
"Must have": "hona aavashyak hai",
"Our selection of new items": "naee vastuon ka hamaara chayan"
} }

View File

@ -176,5 +176,13 @@
"Retry": "Riprova", "Retry": "Riprova",
"Retry later": "Riprova più tardi", "Retry later": "Riprova più tardi",
"Light Mode": "Modalità luce", "Light Mode": "Modalità luce",
"Dark Mode": "Modalità scura" "Dark Mode": "Modalità scura",
"PayPal Checkout": "Pagamento PayPal",
"Processing Payment": "Pagamento in elaborazione",
"Please wait, your order is being processed and you will be redirected to the PayPal website.": "Attendi, il tuo ordine è in fase di elaborazione e verrai reindirizzato al sito web di PayPal.",
"If you are not automatically redirected to PayPal within 5 seconds": "Se non vieni reindirizzato automaticamente a PayPal entro 5 secondi",
"Payment Cancelled": "Pagamento annullato",
"The payment has been cancelled": "Il pagamento è stato annullato",
"Must have": "Deve avere",
"Our selection of new items": "La nostra selezione di nuovi articoli"
} }

View File

@ -176,5 +176,13 @@
"Retry": "Tentar novamente", "Retry": "Tentar novamente",
"Retry later": "Tentar mais tarde", "Retry later": "Tentar mais tarde",
"Light Mode": "Modo de luz", "Light Mode": "Modo de luz",
"Dark Mode": "Modo escuro" "Dark Mode": "Modo escuro",
"PayPal Checkout": "PayPal Checkout",
"Processing Payment": "Processando o pagamento",
"Please wait, your order is being processed and you will be redirected to the PayPal website.": "Aguarde, seu pedido está sendo processado e você será redirecionado para o site do PayPal.",
"If you are not automatically redirected to PayPal within 5 seconds": "Se você não for redirecionado automaticamente para o PayPal em 5 segundos",
"Payment Cancelled": "Pagamento Cancelado",
"The payment has been cancelled": "O pagamento foi cancelado",
"Must have": "Deve ter",
"Our selection of new items": "Nossa seleção de novos itens"
} }

View File

@ -47,7 +47,7 @@ class CartLineItem {
this.metaData}); this.metaData});
String getCartTotal() { String getCartTotal() {
return (quantity * parseWcPrice(subtotal)).toString(); return (quantity * parseWcPrice(subtotal)).toStringAsFixed(2);
} }
CartLineItem.fromJson(Map<String, dynamic> json) CartLineItem.fromJson(Map<String, dynamic> json)

View File

@ -30,19 +30,19 @@ cashOnDeliveryPay(context,
if (order != null) { if (order != null) {
Navigator.pushNamed(context, "/checkout-status", arguments: order); Navigator.pushNamed(context, "/checkout-status", arguments: order);
} else { } else {
showEdgeAlertWith( showToastNotification(
context, context,
title: trans(context, "Error"), title: trans(context, "Error"),
desc: trans(context, description: trans(context,
trans(context, "Something went wrong, please contact our store")), trans(context, "Something went wrong, please contact our store")),
); );
state.reloadState(showLoader: false); state.reloadState(showLoader: false);
} }
} catch (_) { } catch (_) {
showEdgeAlertWith( showToastNotification(
context, context,
title: trans(context, "Error"), title: trans(context, "Error"),
desc: trans(context, description: trans(context,
trans(context, "Something went wrong, please contact our store")), trans(context, "Something went wrong, please contact our store")),
); );
state.reloadState(showLoader: false); state.reloadState(showLoader: false);

View File

@ -50,10 +50,10 @@ examplePay(context,
if (order != null) { if (order != null) {
Navigator.pushNamed(context, "/checkout-status", arguments: order); Navigator.pushNamed(context, "/checkout-status", arguments: order);
} else { } else {
showEdgeAlertWith( showToastNotification(
context, context,
title: trans(context, "Error"), title: trans(context, "Error"),
desc: trans(context, description: trans(context,
trans(context, "Something went wrong, please contact our store")), trans(context, "Something went wrong, please contact our store")),
); );
state.reloadState(showLoader: false); state.reloadState(showLoader: false);

View File

@ -0,0 +1,78 @@
//
// LabelCore
// Label StoreMax
//
// Created by Anthony Gordon.
// 2021, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_app/app/models/cart_line_item.dart';
import 'package:flutter_app/bootstrap/data/order_wc.dart';
import 'package:flutter_app/bootstrap/helpers.dart';
import 'package:flutter_app/resources/pages/checkout_confirmation.dart';
import 'package:flutter_app/resources/widgets/checkout_paypal.dart';
import 'package:nylo_framework/helpers/helper.dart';
import 'package:woosignal/models/payload/order_wc.dart';
import 'package:woosignal/models/response/order.dart';
import 'package:woosignal/models/response/tax_rate.dart';
payPalPay(context,
{@required CheckoutConfirmationPageState state, TaxRate taxRate}) async {
await checkout(taxRate, (total, billingDetails, cart) async {
List<CartLineItem> cartLineItems = await cart.getCart();
String description = await cart.cartShortDesc();
state.reloadState(showLoader: true);
await Navigator.push(
context,
MaterialPageRoute(
builder: (_) => PayPalCheckout(
description: description,
amount: total,
cartLineItems: cartLineItems))).then((value) async {
if (value is Map<String, dynamic>) {
if (value.containsKey("status") && value["status"] == "success") {
OrderWC orderWC =
await buildOrderWC(taxRate: taxRate, markPaid: true);
Order order = await appWooSignal((api) => api.createOrder(orderWC));
if (order != null) {
Navigator.pushNamed(context, "/checkout-status", arguments: order);
} else {
showToastNotification(
context,
title: trans(context, "Error"),
description: trans(
context,
trans(context,
"Something went wrong, please contact our store")),
);
state.reloadState(showLoader: false);
}
} else {
showToastNotification(
context,
title: trans(context, "Payment Cancelled"),
description: trans(
context, trans(context, "The payment has been cancelled")),
);
state.reloadState(showLoader: false);
}
} else {
showToastNotification(
context,
title: trans(context, "Payment Cancelled"),
description:
trans(context, trans(context, "The payment has been cancelled")),
);
state.reloadState(showLoader: false);
}
});
});
}

View File

@ -36,33 +36,33 @@ razorPay(context,
razorPay.clear(); razorPay.clear();
Navigator.pushNamed(context, "/checkout-status", arguments: order); Navigator.pushNamed(context, "/checkout-status", arguments: order);
} else { } else {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Error"), title: trans(context, "Error"),
desc: trans( description: trans(
context, context,
trans(context, "Something went wrong, please contact our store"), trans(context, "Something went wrong, please contact our store"),
), ),
style: EdgeAlertStyle.WARNING); style: ToastNotificationStyleType.WARNING);
razorPay.clear(); razorPay.clear();
state.reloadState(showLoader: false); state.reloadState(showLoader: false);
} }
}); });
razorPay.on(Razorpay.EVENT_PAYMENT_ERROR, (PaymentFailureResponse response) { razorPay.on(Razorpay.EVENT_PAYMENT_ERROR, (PaymentFailureResponse response) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Error"), title: trans(context, "Error"),
desc: response.message, description: response.message,
style: EdgeAlertStyle.WARNING); style: ToastNotificationStyleType.WARNING);
razorPay.clear(); razorPay.clear();
state.reloadState(showLoader: false); state.reloadState(showLoader: false);
}); });
razorPay.on(Razorpay.EVENT_EXTERNAL_WALLET, razorPay.on(Razorpay.EVENT_EXTERNAL_WALLET,
(ExternalWalletResponse response) { (ExternalWalletResponse response) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Error"), title: trans(context, "Error"),
desc: trans(context, "Not supported, try a card payment"), description: trans(context, "Not supported, try a card payment"),
style: EdgeAlertStyle.WARNING); style: ToastNotificationStyleType.WARNING);
razorPay.clear(); razorPay.clear();
state.reloadState(showLoader: false); state.reloadState(showLoader: false);
}); });

View File

@ -64,11 +64,12 @@ stripePay(context,
)); ));
if (rsp == null) { if (rsp == null) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Oops!"), title: trans(context, "Oops!"),
desc: trans(context, "Something went wrong, please try again."), description:
trans(context, "Something went wrong, please try again."),
icon: Icons.payment, icon: Icons.payment,
style: EdgeAlertStyle.WARNING); style: ToastNotificationStyleType.WARNING);
state.reloadState(showLoader: false); state.reloadState(showLoader: false);
return; return;
} }
@ -87,10 +88,10 @@ stripePay(context,
if (order != null) { if (order != null) {
Navigator.pushNamed(context, "/checkout-status", arguments: order); Navigator.pushNamed(context, "/checkout-status", arguments: order);
} else { } else {
showEdgeAlertWith( showToastNotification(
context, context,
title: trans(context, "Error"), title: trans(context, "Error"),
desc: trans( description: trans(
context, context,
trans(context, trans(context,
"Something went wrong, please contact our store")), "Something went wrong, please contact our store")),
@ -101,10 +102,10 @@ stripePay(context,
if (getEnv('APP_DEBUG', defaultValue: true)) { if (getEnv('APP_DEBUG', defaultValue: true)) {
NyLogger.error(intentResponse.errorMessage); NyLogger.error(intentResponse.errorMessage);
} }
showEdgeAlertWith( showToastNotification(
context, context,
title: trans(context, "Error"), title: trans(context, "Error"),
desc: intentResponse.errorMessage, description: intentResponse.errorMessage,
); );
state.reloadState(showLoader: false); state.reloadState(showLoader: false);
} else { } else {
@ -115,12 +116,12 @@ stripePay(context,
state.reloadState(showLoader: false); state.reloadState(showLoader: false);
} }
} catch (ex) { } catch (ex) {
showEdgeAlertWith( showToastNotification(
context, context,
title: trans(context, "Oops!"), title: trans(context, "Oops!"),
desc: trans(context, "Something went wrong, please try again."), description: trans(context, "Something went wrong, please try again."),
icon: Icons.payment, icon: Icons.payment,
style: EdgeAlertStyle.WARNING, style: ToastNotificationStyleType.WARNING,
); );
state.reloadState(showLoader: false); state.reloadState(showLoader: false);
} }

View File

@ -13,6 +13,7 @@ import 'package:woosignal/models/response/woosignal_app.dart';
class AppHelper { class AppHelper {
AppHelper._privateConstructor(); AppHelper._privateConstructor();
String themeType;
static final AppHelper instance = AppHelper._privateConstructor(); static final AppHelper instance = AppHelper._privateConstructor();
WooSignalApp appConfig; WooSignalApp appConfig;

View File

@ -15,7 +15,6 @@ import 'package:flutter_app/app/models/cart.dart';
import 'package:flutter_app/app/models/cart_line_item.dart'; import 'package:flutter_app/app/models/cart_line_item.dart';
import 'package:flutter_app/app/models/checkout_session.dart'; import 'package:flutter_app/app/models/checkout_session.dart';
import 'package:flutter_app/bootstrap/app_helper.dart'; import 'package:flutter_app/bootstrap/app_helper.dart';
import 'package:flutter_app/bootstrap/helpers.dart';
import 'package:flutter_app/bootstrap/shared_pref/sp_auth.dart'; import 'package:flutter_app/bootstrap/shared_pref/sp_auth.dart';
import 'package:woosignal/models/payload/order_wc.dart'; import 'package:woosignal/models/payload/order_wc.dart';
import 'package:woosignal/models/response/tax_rate.dart'; import 'package:woosignal/models/response/tax_rate.dart';
@ -50,11 +49,7 @@ Future<OrderWC> buildOrderWC({TaxRate taxRate, bool markPaid = true}) async {
tmpLineItem.variationId = cartItem.variationId; tmpLineItem.variationId = cartItem.variationId;
} }
tmpLineItem.total = tmpLineItem.subtotal = cartItem.subtotal;
(cartItem.quantity > 1 ? cartItem.getCartTotal() : cartItem.subtotal);
tmpLineItem.subtotal =
(parseWcPrice(cartItem.subtotal) * cartItem.quantity).toString();
lineItems.add(tmpLineItem); lineItems.add(tmpLineItem);
}); });

View File

@ -0,0 +1,11 @@
// Label StoreMax
//
// Created by Anthony Gordon.
// 2021, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
enum SymbolPositionType { left, right }

View File

@ -9,6 +9,7 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
import 'dart:convert'; import 'dart:convert';
import 'package:animate_do/animate_do.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter_app/app/models/billing_details.dart'; import 'package:flutter_app/app/models/billing_details.dart';
import 'package:flutter_app/app/models/cart.dart'; import 'package:flutter_app/app/models/cart.dart';
@ -18,18 +19,20 @@ import 'package:flutter_app/app/models/default_shipping.dart';
import 'package:flutter_app/app/models/payment_type.dart'; import 'package:flutter_app/app/models/payment_type.dart';
import 'package:flutter_app/app/models/user.dart'; import 'package:flutter_app/app/models/user.dart';
import 'package:flutter_app/bootstrap/app_helper.dart'; import 'package:flutter_app/bootstrap/app_helper.dart';
import 'package:flutter_app/bootstrap/enums/symbol_position_enums.dart';
import 'package:flutter_app/bootstrap/shared_pref/shared_key.dart'; import 'package:flutter_app/bootstrap/shared_pref/shared_key.dart';
import 'package:flutter_app/config/app_currency.dart';
import 'package:flutter_app/config/app_payment_gateways.dart'; import 'package:flutter_app/config/app_payment_gateways.dart';
import 'package:flutter_app/resources/widgets/no_results_for_products_widget.dart'; import 'package:flutter_app/resources/widgets/no_results_for_products_widget.dart';
import 'package:flutter_app/resources/widgets/woosignal_ui.dart'; import 'package:flutter_app/resources/widgets/woosignal_ui.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:flutter_styled_toast/flutter_styled_toast.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:edge_alert/edge_alert.dart';
import 'package:html/parser.dart'; import 'package:html/parser.dart';
import 'package:flutter_web_browser/flutter_web_browser.dart'; import 'package:flutter_web_browser/flutter_web_browser.dart';
import 'package:flutter_money_formatter/flutter_money_formatter.dart';
import 'package:math_expressions/math_expressions.dart'; import 'package:math_expressions/math_expressions.dart';
import 'package:money_formatter/money_formatter.dart';
import 'package:nylo_framework/helpers/helper.dart'; import 'package:nylo_framework/helpers/helper.dart';
import 'package:platform_alert_dialog/platform_alert_dialog.dart'; import 'package:platform_alert_dialog/platform_alert_dialog.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart';
@ -79,61 +82,167 @@ showStatusAlert(context,
); );
} }
class EdgeAlertStyle { enum ToastNotificationStyleType {
static const int SUCCESS = 1; SUCCESS,
static const int WARNING = 2; WARNING,
static const int INFO = 3; INFO,
static const int DANGER = 4; DANGER,
} }
void showEdgeAlertWith(context, class ToastNotificationStyleMetaHelper {
{title = "", static ToastMeta getValue(ToastNotificationStyleType style) {
desc = "",
int gravity = 1,
int style = 1,
IconData icon,
int duration}) {
switch (style) { switch (style) {
case 1: // SUCCESS case ToastNotificationStyleType.SUCCESS:
EdgeAlert.show(context, return ToastMeta.success(action: () {
title: title, ToastManager().dismissAll(showAnim: true);
description: desc, });
gravity: gravity, case ToastNotificationStyleType.WARNING:
backgroundColor: Colors.green, return ToastMeta.warning(action: () {
icon: icon ?? Icons.check, ToastManager().dismissAll(showAnim: true);
duration: duration ?? EdgeAlert.LENGTH_LONG); });
break; case ToastNotificationStyleType.INFO:
case 2: // WARNING return ToastMeta.info(action: () {
EdgeAlert.show(context, ToastManager().dismissAll(showAnim: true);
title: title, });
description: desc, case ToastNotificationStyleType.DANGER:
gravity: gravity, return ToastMeta.danger(action: () {
backgroundColor: Colors.orange, ToastManager().dismissAll(showAnim: true);
icon: icon ?? Icons.error_outline, });
duration: duration ?? EdgeAlert.LENGTH_LONG);
break;
case 3: // INFO
EdgeAlert.show(context,
title: title,
description: desc,
gravity: gravity,
backgroundColor: Colors.teal,
icon: icon ?? Icons.info,
duration: duration ?? EdgeAlert.LENGTH_LONG);
break;
case 4: // DANGER
EdgeAlert.show(context,
title: title,
description: desc,
gravity: gravity,
backgroundColor: Colors.redAccent,
icon: icon ?? Icons.warning,
duration: duration ?? EdgeAlert.LENGTH_LONG);
break;
default: default:
break; return ToastMeta.success(action: () {
ToastManager().dismissAll(showAnim: true);
});
} }
} }
}
class ToastMeta {
Widget icon;
String title;
String description;
Color color;
Function action;
Duration duration;
ToastMeta(
{this.icon,
this.title,
this.description,
this.color,
this.action,
this.duration = const Duration(seconds: 2)});
ToastMeta.success(
{this.icon = const Icon(Icons.check, color: Colors.white, size: 30),
this.title = "Success",
this.description = "",
this.color = Colors.green,
this.action,
this.duration = const Duration(seconds: 5)});
ToastMeta.info(
{this.icon = const Icon(Icons.info, color: Colors.white, size: 30),
this.title = "",
this.description = "",
this.color = Colors.teal,
this.action,
this.duration = const Duration(seconds: 5)});
ToastMeta.warning(
{this.icon =
const Icon(Icons.error_outline, color: Colors.white, size: 30),
this.title = "Oops!",
this.description = "",
this.color = Colors.orange,
this.action,
this.duration = const Duration(seconds: 6)});
ToastMeta.danger(
{this.icon = const Icon(Icons.warning, color: Colors.white, size: 30),
this.title = "Oops!",
this.description = "",
this.color = Colors.redAccent,
this.action,
this.duration = const Duration(seconds: 7)});
}
showToastNotification(BuildContext context,
{ToastNotificationStyleType style,
String title,
IconData icon,
String description = "",
Duration duration}) {
ToastMeta toastMeta = ToastNotificationStyleMetaHelper.getValue(style);
toastMeta.title = trans(context, toastMeta.title);
if (title != null) {
toastMeta.title = title;
}
toastMeta.description = description;
Widget _icon = toastMeta.icon;
if (icon != null) {
_icon = Icon(icon, color: Colors.white);
}
showToastWidget(
InkWell(
onTap: () => ToastManager().dismissAll(showAnim: true),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 18.0),
margin: EdgeInsets.symmetric(horizontal: 8.0),
height: 100,
decoration: ShapeDecoration(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
color: toastMeta.color,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Pulse(
child: Container(
child: Center(
child: IconButton(
onPressed: () {},
icon: _icon,
padding: EdgeInsets.only(right: 16),
),
),
),
infinite: true,
duration: Duration(milliseconds: 1500),
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
toastMeta.title,
style: Theme.of(context)
.textTheme
.headline5
.copyWith(color: Colors.white),
),
Text(
toastMeta.description,
style: Theme.of(context)
.textTheme
.bodyText1
.copyWith(color: Colors.white),
),
],
),
),
],
),
),
),
context: context,
isIgnoring: false,
position: StyledToastPosition.top,
animation: StyledToastAnimation.slideFromTopFade,
duration: duration ?? toastMeta.duration,
);
}
String parseHtmlString(String htmlString) { String parseHtmlString(String htmlString) {
var document = parse(htmlString); var document = parse(htmlString);
@ -141,30 +250,31 @@ String parseHtmlString(String htmlString) {
return parsedString; return parsedString;
} }
String formatDoubleCurrency({double total}) { String moneyFormatter(double amount) {
FlutterMoneyFormatter fmf = FlutterMoneyFormatter( MoneyFormatter fmf = MoneyFormatter(
amount: total, amount: amount,
settings: MoneyFormatterSettings( settings: MoneyFormatterSettings(
symbol: AppHelper.instance.appConfig.currencyMeta.symbolNative, symbol: AppHelper.instance.appConfig.currencyMeta.symbolNative,
), ),
); );
if (app_currency_symbol_position == SymbolPositionType.left) {
return fmf.output.symbolOnLeft;
} else if (app_currency_symbol_position == SymbolPositionType.right) {
return fmf.output.symbolOnRight;
}
return fmf.output.symbolOnLeft; return fmf.output.symbolOnLeft;
} }
String formatDoubleCurrency({@required double total}) {
return moneyFormatter(total);
}
String formatStringCurrency({@required String total}) { String formatStringCurrency({@required String total}) {
double tmpVal; double tmpVal = 0;
if (total == null || total == "") { if (total != null && total != "") {
tmpVal = 0;
} else {
tmpVal = parseWcPrice(total); tmpVal = parseWcPrice(total);
} }
FlutterMoneyFormatter fmf = FlutterMoneyFormatter( return moneyFormatter(tmpVal);
amount: tmpVal,
settings: MoneyFormatterSettings(
symbol: AppHelper.instance.appConfig.currencyMeta.symbolNative,
),
);
return fmf.output.symbolOnLeft;
} }
String workoutSaleDiscount( String workoutSaleDiscount(
@ -562,3 +672,7 @@ Future<List<DefaultShipping>> getDefaultShipping(BuildContext context) async {
}); });
return shipping; return shipping;
} }
String truncateString(String data, int length) {
return (data.length >= length) ? '${data.substring(0, length)}...' : data;
}

View File

@ -0,0 +1,24 @@
/*
|--------------------------------------------------------------------------
| CURRENCY
|
| Configure which currency you want to use.
| Docs here: https://woosignal.com/docs/app/ios/label-storemax
|--------------------------------------------------------------------------
*/
import 'package:flutter_app/bootstrap/enums/symbol_position_enums.dart';
/*
|--------------------------------------------------------------------------
| APP CURRENCY
|
| Configure the currency settings. To change the currency used (e.g. "USD"),
| update the "currency" value in the WooSignal dashboard.
|--------------------------------------------------------------------------
*/
const SymbolPositionType app_currency_symbol_position = SymbolPositionType.left;
// currency_symbol_position example.
// left: $15
// right: 15

View File

@ -1,5 +1,6 @@
import 'package:flutter_app/app/models/payment_type.dart'; import 'package:flutter_app/app/models/payment_type.dart';
import 'package:flutter_app/app/providers/cash_on_delivery.dart'; import 'package:flutter_app/app/providers/cash_on_delivery.dart';
import 'package:flutter_app/app/providers/paypal_pay.dart';
import 'package:flutter_app/app/providers/razor_pay.dart'; import 'package:flutter_app/app/providers/razor_pay.dart';
import 'package:flutter_app/app/providers/stripe_pay.dart'; import 'package:flutter_app/app/providers/stripe_pay.dart';
import 'package:flutter_app/bootstrap/helpers.dart'; import 'package:flutter_app/bootstrap/helpers.dart';
@ -13,7 +14,7 @@ import 'package:flutter_app/bootstrap/helpers.dart';
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
*/ */
const app_payment_gateways = ["Stripe"]; const app_payment_gateways = ["Stripe", "CashOnDelivery", "PayPal"];
// Available: "Stripe", "CashOnDelivery", "RazorPay" // Available: "Stripe", "CashOnDelivery", "RazorPay"
// e.g. app_payment_gateways = ["Stripe", "CashOnDelivery"]; will only use Stripe and Cash on Delivery. // e.g. app_payment_gateways = ["Stripe", "CashOnDelivery"]; will only use Stripe and Cash on Delivery.
@ -42,10 +43,18 @@ List<PaymentType> paymentTypeList = [
pay: razorPay, pay: razorPay,
), ),
addPayment(
id: 4,
name: "PayPal",
desc: "Debit or Credit Card",
assetImage: "paypal_logo.png",
pay: payPalPay,
),
// e.g. add more here // e.g. add more here
// addPayment( // addPayment(
// id: 4, // id: 5,
// name: "MyNewPaymentMethod", // name: "MyNewPaymentMethod",
// desc: "Debit or Credit Card", // desc: "Debit or Credit Card",
// assetImage: "add icon image to public/assets/images/myimage.png", // assetImage: "add icon image to public/assets/images/myimage.png",

View File

@ -31,6 +31,7 @@ void main() async {
if (wooSignalApp != null) { if (wooSignalApp != null) {
initialRoute = "/home"; initialRoute = "/home";
AppHelper.instance.appConfig = wooSignalApp; AppHelper.instance.appConfig = wooSignalApp;
AppHelper.instance.themeType = wooSignalApp.theme;
if (wooSignalApp.wpLoginEnabled == 1) { if (wooSignalApp.wpLoginEnabled == 1) {
WPJsonAPI.instance.initWith( WPJsonAPI.instance.initWith(

View File

@ -222,10 +222,10 @@ class _AccountBillingDetailsPageState extends State<AccountBillingDetailsPage> {
billingPostcode: postalCode, billingPostcode: postalCode,
billingCountry: country)); billingCountry: country));
} on Exception catch (_) { } on Exception catch (_) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Oops!"), title: trans(context, "Oops!"),
desc: trans(context, "Something went wrong"), description: trans(context, "Something went wrong"),
style: EdgeAlertStyle.DANGER); style: ToastNotificationStyleType.DANGER);
} finally { } finally {
setState(() { setState(() {
_isUpdating = false; _isUpdating = false;
@ -234,10 +234,10 @@ class _AccountBillingDetailsPageState extends State<AccountBillingDetailsPage> {
if (wcCustomerUpdatedResponse != null && if (wcCustomerUpdatedResponse != null &&
wcCustomerUpdatedResponse.status == 200) { wcCustomerUpdatedResponse.status == 200) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Success"), title: trans(context, "Success"),
desc: trans(context, "Account updated"), description: trans(context, "Account updated"),
style: EdgeAlertStyle.SUCCESS); style: ToastNotificationStyleType.SUCCESS);
Navigator.pop(context); Navigator.pop(context);
} }
} }

View File

@ -72,11 +72,11 @@ class _AccountDetailPageState extends State<AccountDetailPage>
wcCustomerInfoResponse = await WPJsonAPI.instance wcCustomerInfoResponse = await WPJsonAPI.instance
.api((request) => request.wcCustomerInfo(userToken)); .api((request) => request.wcCustomerInfo(userToken));
} on Exception catch (_) { } on Exception catch (_) {
showEdgeAlertWith( showToastNotification(
context, context,
title: trans(context, "Oops!"), title: trans(context, "Oops!"),
desc: trans(context, "Something went wrong"), description: trans(context, "Something went wrong"),
style: EdgeAlertStyle.DANGER, style: ToastNotificationStyleType.DANGER,
); );
} finally { } finally {
setState(() { setState(() {

View File

@ -163,18 +163,19 @@ class _AccountLandingPageState extends State<AccountLandingPage> {
} }
if (email == "" || password == "") { if (email == "" || password == "") {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Invalid details"), title: trans(context, "Invalid details"),
desc: trans(context, "The email and password field cannot be empty"), description:
style: EdgeAlertStyle.DANGER); trans(context, "The email and password field cannot be empty"),
style: ToastNotificationStyleType.DANGER);
return; return;
} }
if (!isEmail(email)) { if (!isEmail(email)) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Oops"), title: trans(context, "Oops"),
desc: trans(context, "That email address is not valid"), description: trans(context, "That email address is not valid"),
style: EdgeAlertStyle.DANGER); style: ToastNotificationStyleType.DANGER);
return; return;
} }
@ -188,31 +189,34 @@ class _AccountLandingPageState extends State<AccountLandingPage> {
wpUserLoginResponse = await WPJsonAPI.instance.api( wpUserLoginResponse = await WPJsonAPI.instance.api(
(request) => request.wpLogin(email: email, password: password)); (request) => request.wpLogin(email: email, password: password));
} on InvalidNonceException catch (_) { } on InvalidNonceException catch (_) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Invalid details"), title: trans(context, "Invalid details"),
desc: trans( description: trans(
context, "Something went wrong, please contact our store"), context, "Something went wrong, please contact our store"),
style: EdgeAlertStyle.DANGER); style: ToastNotificationStyleType.DANGER);
} on InvalidEmailException catch (_) { } on InvalidEmailException catch (_) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Invalid details"), title: trans(context, "Invalid details"),
desc: trans(context, "That email does not match our records"), description:
style: EdgeAlertStyle.DANGER); trans(context, "That email does not match our records"),
style: ToastNotificationStyleType.DANGER);
} on InvalidUsernameException catch (_) { } on InvalidUsernameException catch (_) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Invalid details"), title: trans(context, "Invalid details"),
desc: trans(context, "That username does not match our records"), description:
style: EdgeAlertStyle.DANGER); trans(context, "That username does not match our records"),
style: ToastNotificationStyleType.DANGER);
} on IncorrectPasswordException catch (_) { } on IncorrectPasswordException catch (_) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Invalid details"), title: trans(context, "Invalid details"),
desc: trans(context, "That password does not match our records"), description:
style: EdgeAlertStyle.DANGER); trans(context, "That password does not match our records"),
style: ToastNotificationStyleType.DANGER);
} on Exception catch (_) { } on Exception catch (_) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Oops!"), title: trans(context, "Oops!"),
desc: trans(context, "Invalid login credentials"), description: trans(context, "Invalid login credentials"),
style: EdgeAlertStyle.DANGER, style: ToastNotificationStyleType.DANGER,
icon: Icons.account_circle); icon: Icons.account_circle);
} finally { } finally {
setState(() { setState(() {
@ -226,10 +230,10 @@ class _AccountLandingPageState extends State<AccountLandingPage> {
User user = User.fromUserAuthResponse(token: token, userId: userId); User user = User.fromUserAuthResponse(token: token, userId: userId);
user.save(SharedKey.authUser); user.save(SharedKey.authUser);
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Hello"), title: trans(context, "Hello"),
desc: trans(context, "Welcome back"), description: trans(context, "Welcome back"),
style: EdgeAlertStyle.SUCCESS, style: ToastNotificationStyleType.SUCCESS,
icon: Icons.account_circle); icon: Icons.account_circle);
navigatorPush(context, navigatorPush(context,
routeName: UserAuth.instance.redirect, forgetLast: 1); routeName: UserAuth.instance.redirect, forgetLast: 1);

View File

@ -18,10 +18,10 @@ import 'package:flutter_app/resources/widgets/woosignal_ui.dart';
import 'package:hexcolor/hexcolor.dart'; import 'package:hexcolor/hexcolor.dart';
import 'package:nylo_framework/helpers/helper.dart'; import 'package:nylo_framework/helpers/helper.dart';
import 'package:nylo_framework/widgets/ny_state.dart'; import 'package:nylo_framework/widgets/ny_state.dart';
import 'package:nylo_framework/widgets/stateful_page_widget.dart'; import 'package:nylo_framework/widgets/ny_stateful_widget.dart';
import 'package:woosignal/models/response/order.dart'; import 'package:woosignal/models/response/order.dart';
class AccountOrderDetailPage extends StatefulPageWidget { class AccountOrderDetailPage extends NyStatefulWidget {
final AccountOrderDetailController controller = final AccountOrderDetailController controller =
AccountOrderDetailController(); AccountOrderDetailController();
AccountOrderDetailPage({Key key}) : super(key: key); AccountOrderDetailPage({Key key}) : super(key: key);

View File

@ -140,10 +140,10 @@ class _AccountProfileUpdatePageState extends State<AccountProfileUpdatePage> {
request.wpUpdateUserInfo(userToken, request.wpUpdateUserInfo(userToken,
firstName: firstName, lastName: lastName)); firstName: firstName, lastName: lastName));
} on Exception catch (_) { } on Exception catch (_) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Invalid details"), title: trans(context, "Invalid details"),
desc: trans(context, "Please check your email and password"), description: trans(context, "Please check your email and password"),
style: EdgeAlertStyle.DANGER); style: ToastNotificationStyleType.DANGER);
} finally { } finally {
setState(() { setState(() {
isLoading = false; isLoading = false;
@ -152,10 +152,10 @@ class _AccountProfileUpdatePageState extends State<AccountProfileUpdatePage> {
if (wpUserInfoUpdatedResponse != null && if (wpUserInfoUpdatedResponse != null &&
wpUserInfoUpdatedResponse.status == 200) { wpUserInfoUpdatedResponse.status == 200) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Success"), title: trans(context, "Success"),
desc: trans(context, "Account updated"), description: trans(context, "Account updated"),
style: EdgeAlertStyle.SUCCESS); style: ToastNotificationStyleType.SUCCESS);
Navigator.pop(context); Navigator.pop(context);
} }
} }

View File

@ -148,28 +148,28 @@ class _AccountRegistrationPageState extends State<AccountRegistrationPage> {
} }
_signUpTapped() async { _signUpTapped() async {
String email = _tfEmailAddressController.text; String email = _tfEmailAddressController.text,
String password = _tfPasswordController.text; password = _tfPasswordController.text,
String firstName = _tfFirstNameController.text; firstName = _tfFirstNameController.text,
String lastName = _tfLastNameController.text; lastName = _tfLastNameController.text;
if (email.isNotEmpty) { if (email.isNotEmpty) {
email = email.trim(); email = email.trim();
} }
if (!isEmail(email)) { if (!isEmail(email)) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Oops"), title: trans(context, "Oops"),
desc: trans(context, "That email address is not valid"), description: trans(context, "That email address is not valid"),
style: EdgeAlertStyle.DANGER); style: ToastNotificationStyleType.DANGER);
return; return;
} }
if (password.length <= 5) { if (password.length <= 5) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Oops"), title: trans(context, "Oops"),
desc: trans(context, "Password must be a min 6 characters"), description: trans(context, "Password must be a min 6 characters"),
style: EdgeAlertStyle.DANGER); style: ToastNotificationStyleType.DANGER);
return; return;
} }
@ -191,41 +191,41 @@ class _AccountRegistrationPageState extends State<AccountRegistrationPage> {
), ),
); );
} on UsernameTakenException catch (e) { } on UsernameTakenException catch (e) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Oops!"), title: trans(context, "Oops!"),
desc: trans(context, e.message), description: trans(context, e.message),
style: EdgeAlertStyle.DANGER); style: ToastNotificationStyleType.DANGER);
} on InvalidNonceException catch (_) { } on InvalidNonceException catch (_) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Invalid details"), title: trans(context, "Invalid details"),
desc: trans( description: trans(
context, "Something went wrong, please contact our store"), context, "Something went wrong, please contact our store"),
style: EdgeAlertStyle.DANGER); style: ToastNotificationStyleType.DANGER);
} on ExistingUserLoginException catch (_) { } on ExistingUserLoginException catch (_) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Oops!"), title: trans(context, "Oops!"),
desc: trans(context, "A user already exists"), description: trans(context, "A user already exists"),
style: EdgeAlertStyle.DANGER); style: ToastNotificationStyleType.DANGER);
} on ExistingUserEmailException catch (_) { } on ExistingUserEmailException catch (_) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Oops!"), title: trans(context, "Oops!"),
desc: trans(context, "That email is taken, try another"), description: trans(context, "That email is taken, try another"),
style: EdgeAlertStyle.DANGER); style: ToastNotificationStyleType.DANGER);
} on UserAlreadyExistException catch (_) { } on UserAlreadyExistException catch (_) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Oops!"), title: trans(context, "Oops!"),
desc: trans(context, "A user already exists"), description: trans(context, "A user already exists"),
style: EdgeAlertStyle.DANGER); style: ToastNotificationStyleType.DANGER);
} on EmptyUsernameException catch (e) { } on EmptyUsernameException catch (e) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Oops!"), title: trans(context, "Oops!"),
desc: trans(context, e.message), description: trans(context, e.message),
style: EdgeAlertStyle.DANGER); style: ToastNotificationStyleType.DANGER);
} on Exception catch (_) { } on Exception catch (_) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Oops!"), title: trans(context, "Oops!"),
desc: trans(context, "Something went wrong"), description: trans(context, "Something went wrong"),
style: EdgeAlertStyle.DANGER); style: ToastNotificationStyleType.DANGER);
} finally { } finally {
setState(() { setState(() {
_hasTappedRegister = false; _hasTappedRegister = false;
@ -242,10 +242,10 @@ class _AccountRegistrationPageState extends State<AccountRegistrationPage> {
await WPJsonAPI.instance.api((request) => request await WPJsonAPI.instance.api((request) => request
.wpUpdateUserInfo(token, firstName: firstName, lastName: lastName)); .wpUpdateUserInfo(token, firstName: firstName, lastName: lastName));
showEdgeAlertWith(context, showToastNotification(context,
title: "${trans(context, "Hello")} $firstName", title: "${trans(context, "Hello")} $firstName",
desc: trans(context, "you're now logged in"), description: trans(context, "you're now logged in"),
style: EdgeAlertStyle.SUCCESS, style: ToastNotificationStyleType.SUCCESS,
icon: Icons.account_circle); icon: Icons.account_circle);
navigatorPush(context, navigatorPush(context,
routeName: UserAuth.instance.redirect, forgetLast: 2); routeName: UserAuth.instance.redirect, forgetLast: 2);

View File

@ -61,11 +61,11 @@ class _AccountShippingDetailsPageState
wcCustomerInfoResponse = await WPJsonAPI.instance wcCustomerInfoResponse = await WPJsonAPI.instance
.api((request) => request.wcCustomerInfo(userToken)); .api((request) => request.wcCustomerInfo(userToken));
} on Exception catch (_) { } on Exception catch (_) {
showEdgeAlertWith( showToastNotification(
context, context,
title: trans(context, "Oops!"), title: trans(context, "Oops!"),
desc: trans(context, "Something went wrong"), description: trans(context, "Something went wrong"),
style: EdgeAlertStyle.DANGER, style: ToastNotificationStyleType.DANGER,
); );
Navigator.pop(context); Navigator.pop(context);
return; return;
@ -246,10 +246,10 @@ class _AccountShippingDetailsPageState
), ),
); );
} on Exception catch (_) { } on Exception catch (_) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Oops!"), title: trans(context, "Oops!"),
desc: trans(context, "Something went wrong"), description: trans(context, "Something went wrong"),
style: EdgeAlertStyle.DANGER); style: ToastNotificationStyleType.DANGER);
} finally { } finally {
setState(() { setState(() {
_isUpdating = true; _isUpdating = true;
@ -258,10 +258,10 @@ class _AccountShippingDetailsPageState
if (wcCustomerUpdatedResponse != null && if (wcCustomerUpdatedResponse != null &&
wcCustomerUpdatedResponse.status == 200) { wcCustomerUpdatedResponse.status == 200) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Success"), title: trans(context, "Success"),
desc: trans(context, "Account updated"), description: trans(context, "Account updated"),
style: EdgeAlertStyle.SUCCESS); style: ToastNotificationStyleType.SUCCESS);
Navigator.pop(context); Navigator.pop(context);
} }
} }

View File

@ -18,12 +18,12 @@ import 'package:flutter_app/resources/widgets/buttons.dart';
import 'package:flutter_app/resources/widgets/woosignal_ui.dart'; import 'package:flutter_app/resources/widgets/woosignal_ui.dart';
import 'package:nylo_framework/helpers/helper.dart'; import 'package:nylo_framework/helpers/helper.dart';
import 'package:nylo_framework/widgets/ny_state.dart'; import 'package:nylo_framework/widgets/ny_state.dart';
import 'package:nylo_framework/widgets/stateful_page_widget.dart'; import 'package:nylo_framework/widgets/ny_stateful_widget.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:woosignal/models/response/product_category.dart'; import 'package:woosignal/models/response/product_category.dart';
import 'package:woosignal/models/response/products.dart' as WS; import 'package:woosignal/models/response/products.dart' as WS;
class BrowseCategoryPage extends StatefulPageWidget { class BrowseCategoryPage extends NyStatefulWidget {
final BrowseCategoryController controller = BrowseCategoryController(); final BrowseCategoryController controller = BrowseCategoryController();
BrowseCategoryPage({Key key}) : super(key: key); BrowseCategoryPage({Key key}) : super(key: key);

View File

@ -14,11 +14,11 @@ import 'package:flutter_app/bootstrap/helpers.dart';
import 'package:flutter_app/resources/widgets/app_loader_widget.dart'; import 'package:flutter_app/resources/widgets/app_loader_widget.dart';
import 'package:nylo_framework/helpers/helper.dart'; import 'package:nylo_framework/helpers/helper.dart';
import 'package:nylo_framework/widgets/ny_state.dart'; import 'package:nylo_framework/widgets/ny_state.dart';
import 'package:nylo_framework/widgets/stateful_page_widget.dart'; import 'package:nylo_framework/widgets/ny_stateful_widget.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:woosignal/models/response/products.dart' as WS; import 'package:woosignal/models/response/products.dart' as WS;
class BrowseSearchPage extends StatefulPageWidget { class BrowseSearchPage extends NyStatefulWidget {
final BrowseSearchController controller = BrowseSearchController(); final BrowseSearchController controller = BrowseSearchController();
BrowseSearchPage({Key key}) : super(key: key); BrowseSearchPage({Key key}) : super(key: key);

View File

@ -81,11 +81,11 @@ class _CartPageState extends State<CartPage> {
} }
if (cartLineItems.length <= 0) { if (cartLineItems.length <= 0) {
showEdgeAlertWith( showToastNotification(
context, context,
title: trans(context, "Cart"), title: trans(context, "Cart"),
desc: trans(context, "You need items in your cart to checkout"), description: trans(context, "You need items in your cart to checkout"),
style: EdgeAlertStyle.WARNING, style: ToastNotificationStyleType.WARNING,
icon: Icons.shopping_cart, icon: Icons.shopping_cart,
); );
return; return;
@ -93,11 +93,11 @@ class _CartPageState extends State<CartPage> {
if (!cartLineItems.every( if (!cartLineItems.every(
(c) => c.stockStatus == 'instock' || c.stockStatus == 'onbackorder')) { (c) => c.stockStatus == 'instock' || c.stockStatus == 'onbackorder')) {
showEdgeAlertWith( showToastNotification(
context, context,
title: trans(context, "Cart"), title: trans(context, "Cart"),
desc: trans(context, "There is an item out of stock"), description: trans(context, "There is an item out of stock"),
style: EdgeAlertStyle.WARNING, style: ToastNotificationStyleType.WARNING,
icon: Icons.shopping_cart, icon: Icons.shopping_cart,
); );
return; return;
@ -127,11 +127,11 @@ class _CartPageState extends State<CartPage> {
actionIncrementQuantity({CartLineItem cartLineItem}) { actionIncrementQuantity({CartLineItem cartLineItem}) {
if (cartLineItem.isManagedStock && if (cartLineItem.isManagedStock &&
cartLineItem.quantity + 1 > cartLineItem.stockQuantity) { cartLineItem.quantity + 1 > cartLineItem.stockQuantity) {
showEdgeAlertWith( showToastNotification(
context, context,
title: trans(context, "Cart"), title: trans(context, "Cart"),
desc: trans(context, "Maximum stock reached"), description: trans(context, "Maximum stock reached"),
style: EdgeAlertStyle.WARNING, style: ToastNotificationStyleType.WARNING,
icon: Icons.shopping_cart, icon: Icons.shopping_cart,
); );
return; return;
@ -155,11 +155,11 @@ class _CartPageState extends State<CartPage> {
actionRemoveItem({int index}) { actionRemoveItem({int index}) {
Cart.getInstance.removeCartItemForIndex(index: index); Cart.getInstance.removeCartItemForIndex(index: index);
_cartLines.removeAt(index); _cartLines.removeAt(index);
showEdgeAlertWith( showToastNotification(
context, context,
title: trans(context, "Updated"), title: trans(context, "Updated"),
desc: trans(context, "Item removed"), description: trans(context, "Item removed"),
style: EdgeAlertStyle.WARNING, style: ToastNotificationStyleType.WARNING,
icon: Icons.remove_shopping_cart, icon: Icons.remove_shopping_cart,
); );
if (_cartLines.length == 0) { if (_cartLines.length == 0) {
@ -171,10 +171,10 @@ class _CartPageState extends State<CartPage> {
_clearCart() { _clearCart() {
Cart.getInstance.clear(); Cart.getInstance.clear();
_cartLines = []; _cartLines = [];
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Success"), title: trans(context, "Success"),
desc: trans(context, "Cart cleared"), description: trans(context, "Cart cleared"),
style: EdgeAlertStyle.SUCCESS, style: ToastNotificationStyleType.SUCCESS,
icon: Icons.delete_outline); icon: Icons.delete_outline);
_isCartEmpty = true; _isCartEmpty = true;
setState(() {}); setState(() {});

View File

@ -165,9 +165,9 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
CustomerAddress shippingAddress = CustomerAddress shippingAddress =
CheckoutSession.getInstance.billingDetails.shippingAddress; CheckoutSession.getInstance.billingDetails.shippingAddress;
if (shippingAddress == null || shippingAddress.customerCountry == null) { if (shippingAddress == null || shippingAddress.customerCountry == null) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Oops"), title: trans(context, "Oops"),
desc: trans(context, "Add your shipping details first"), description: trans(context, "Add your shipping details first"),
icon: Icons.local_shipping); icon: Icons.local_shipping);
return; return;
} }
@ -362,12 +362,12 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
_handleCheckout() async { _handleCheckout() async {
if (CheckoutSession.getInstance.billingDetails.billingAddress == null) { if (CheckoutSession.getInstance.billingDetails.billingAddress == null) {
showEdgeAlertWith( showToastNotification(
context, context,
title: trans(context, "Oops"), title: trans(context, "Oops"),
desc: trans(context, description: trans(context,
"Please select add your billing/shipping address to proceed"), "Please select add your billing/shipping address to proceed"),
style: EdgeAlertStyle.WARNING, style: ToastNotificationStyleType.WARNING,
icon: Icons.local_shipping, icon: Icons.local_shipping,
); );
return; return;
@ -375,11 +375,12 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
if (CheckoutSession.getInstance.billingDetails.billingAddress if (CheckoutSession.getInstance.billingDetails.billingAddress
.hasMissingFields()) { .hasMissingFields()) {
showEdgeAlertWith( showToastNotification(
context, context,
title: trans(context, "Oops"), title: trans(context, "Oops"),
desc: trans(context, "Your billing/shipping details are incomplete"), description:
style: EdgeAlertStyle.WARNING, trans(context, "Your billing/shipping details are incomplete"),
style: ToastNotificationStyleType.WARNING,
icon: Icons.local_shipping, icon: Icons.local_shipping,
); );
return; return;
@ -387,22 +388,24 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
if (_wooSignalApp.disableShipping == 1 && if (_wooSignalApp.disableShipping == 1 &&
CheckoutSession.getInstance.shippingType == null) { CheckoutSession.getInstance.shippingType == null) {
showEdgeAlertWith( showToastNotification(
context, context,
title: trans(context, "Oops"), title: trans(context, "Oops"),
desc: trans(context, "Please select a shipping method to proceed"), description:
style: EdgeAlertStyle.WARNING, trans(context, "Please select a shipping method to proceed"),
style: ToastNotificationStyleType.WARNING,
icon: Icons.local_shipping, icon: Icons.local_shipping,
); );
return; return;
} }
if (CheckoutSession.getInstance.paymentType == null) { if (CheckoutSession.getInstance.paymentType == null) {
showEdgeAlertWith( showToastNotification(
context, context,
title: trans(context, "Oops"), title: trans(context, "Oops"),
desc: trans(context, "Please select a payment method to proceed"), description:
style: EdgeAlertStyle.WARNING, trans(context, "Please select a payment method to proceed"),
style: ToastNotificationStyleType.WARNING,
icon: Icons.payment, icon: Icons.payment,
); );
return; return;
@ -419,12 +422,12 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
double.parse(CheckoutSession.getInstance.shippingType?.minimumValue); double.parse(CheckoutSession.getInstance.shippingType?.minimumValue);
if (doubleTotal < doubleMinimumValue) { if (doubleTotal < doubleMinimumValue) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Sorry"), title: trans(context, "Sorry"),
desc: description:
"${trans(context, "Spend a minimum of")} ${formatDoubleCurrency(total: doubleMinimumValue)} ${trans(context, "for")} ${CheckoutSession.getInstance.shippingType.getTitle()}", "${trans(context, "Spend a minimum of")} ${formatDoubleCurrency(total: doubleMinimumValue)} ${trans(context, "for")} ${CheckoutSession.getInstance.shippingType.getTitle()}",
style: EdgeAlertStyle.INFO, style: ToastNotificationStyleType.INFO,
duration: 3); duration: Duration(seconds: 3));
return; return;
} }
} }
@ -432,11 +435,11 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
bool appStatus = await appWooSignal((api) => api.checkAppStatus()); bool appStatus = await appWooSignal((api) => api.checkAppStatus());
if (!appStatus) { if (!appStatus) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Sorry"), title: trans(context, "Sorry"),
desc: "${trans(context, "Retry later")}", description: "${trans(context, "Retry later")}",
style: EdgeAlertStyle.INFO, style: ToastNotificationStyleType.INFO,
duration: 3); duration: Duration(seconds: 3));
return; return;
} }

View File

@ -320,15 +320,15 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
customerCountry: _shippingCountry); customerCountry: _shippingCountry);
if (customerShippingAddress.hasMissingFields()) { if (customerShippingAddress.hasMissingFields()) {
showEdgeAlertWith( showToastNotification(
context, context,
title: trans(context, "Oops"), title: trans(context, "Oops"),
desc: trans( description: trans(
context, context,
trans(context, trans(context,
"Invalid shipping address, please check your shipping details"), "Invalid shipping address, please check your shipping details"),
), ),
style: EdgeAlertStyle.WARNING, style: ToastNotificationStyleType.WARNING,
); );
return; return;
} }

View File

@ -36,18 +36,13 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
_CheckoutShippingTypePageState(); _CheckoutShippingTypePageState();
AppTheme _appTheme = AppTheme(); AppTheme _appTheme = AppTheme();
bool _isShippingSupported, _isLoading; bool _isShippingSupported = true, _isLoading = true;
List<Map<String, dynamic>> _wsShippingOptions; List<Map<String, dynamic>> _wsShippingOptions = [];
WSShipping _shipping; WSShipping _shipping;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_isShippingSupported = true;
_wsShippingOptions = [];
_isLoading = true;
_getShippingMethods(); _getShippingMethods();
} }
@ -159,7 +154,6 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
total += classTotal; total += classTotal;
} }
} }
break; break;
default: default:
break; break;
@ -247,10 +241,7 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
appBar: AppBar( appBar: AppBar(
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
title: Text( title: Text(
trans( trans(context, "Shipping Methods"),
context,
"Shipping Methods",
),
style: Theme.of(context).textTheme.headline6, style: Theme.of(context).textTheme.headline6,
), ),
automaticallyImplyLeading: false, automaticallyImplyLeading: false,

View File

@ -16,13 +16,13 @@ import 'package:flutter_app/app/models/checkout_session.dart';
import 'package:flutter_app/bootstrap/helpers.dart'; import 'package:flutter_app/bootstrap/helpers.dart';
import 'package:flutter_app/resources/widgets/buttons.dart'; import 'package:flutter_app/resources/widgets/buttons.dart';
import 'package:nylo_framework/widgets/ny_state.dart'; import 'package:nylo_framework/widgets/ny_state.dart';
import 'package:nylo_framework/widgets/stateful_page_widget.dart'; import 'package:nylo_framework/widgets/ny_stateful_widget.dart';
import 'package:woosignal/models/response/order.dart' as WS; import 'package:woosignal/models/response/order.dart' as WS;
import 'package:nylo_framework/helpers/helper.dart'; import 'package:nylo_framework/helpers/helper.dart';
import '../widgets/woosignal_ui.dart'; import '../widgets/woosignal_ui.dart';
class CheckoutStatusPage extends StatefulPageWidget { class CheckoutStatusPage extends NyStatefulWidget {
final CheckoutStatusController controller = CheckoutStatusController(); final CheckoutStatusController controller = CheckoutStatusController();
CheckoutStatusPage({Key key}) : super(key: key); CheckoutStatusPage({Key key}) : super(key: key);

View File

@ -10,15 +10,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_app/bootstrap/app_helper.dart'; import 'package:flutter_app/bootstrap/app_helper.dart';
import 'package:flutter_app/bootstrap/helpers.dart'; import 'package:flutter_app/resources/widgets/mello_theme_widget.dart';
import 'package:flutter_app/resources/widgets/app_loader_widget.dart'; import 'package:flutter_app/resources/widgets/notic_theme_widget.dart';
import 'package:flutter_app/resources/widgets/cart_icon_widget.dart';
import 'package:flutter_app/resources/widgets/home_drawer_widget.dart';
import 'package:flutter_app/resources/widgets/woosignal_ui.dart';
import 'package:nylo_framework/helpers/helper.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:woosignal/models/response/product_category.dart' as WS;
import 'package:woosignal/models/response/products.dart' as WSProduct;
import 'package:woosignal/models/response/woosignal_app.dart'; import 'package:woosignal/models/response/woosignal_app.dart';
class HomePage extends StatefulWidget { class HomePage extends StatefulWidget {
@ -34,153 +27,13 @@ class _HomePageState extends State<HomePage> {
final GlobalKey _key = GlobalKey(); final GlobalKey _key = GlobalKey();
final WooSignalApp _wooSignalApp = AppHelper.instance.appConfig; final WooSignalApp _wooSignalApp = AppHelper.instance.appConfig;
RefreshController _refreshController =
RefreshController(initialRefresh: false);
List<WSProduct.Product> _products = [];
List<WS.ProductCategory> _categories = [];
int _page = 1;
bool _shouldStopRequests = false,
waitForNextRequest = false,
_isLoading = true;
@override
void initState() {
super.initState();
_home();
}
_home() async {
await _fetchMoreProducts();
await _fetchCategories();
setState(() {
_isLoading = false;
});
}
_fetchCategories() async {
_categories =
await appWooSignal((api) => api.getProductCategories(perPage: 100));
}
_fetchMoreProducts() async {
if (_shouldStopRequests) {
return;
}
if (waitForNextRequest) {
return;
}
waitForNextRequest = true;
List<WSProduct.Product> products = await appWooSignal((api) =>
api.getProducts(
perPage: 50,
page: _page,
status: "publish",
stockStatus: "instock"));
_page = _page + 1;
if (products.length == 0) {
_shouldStopRequests = true;
}
waitForNextRequest = false;
setState(() {
_products.addAll(products.toList());
});
}
_modalBottomSheetMenu() {
_key.currentState.setState(() {});
wsModalBottom(
context,
title: trans(context, "Categories"),
bodyWidget: ListView.separated(
itemCount: _categories.length,
separatorBuilder: (cxt, i) => Divider(),
itemBuilder: (BuildContext context, int index) => ListTile(
title: Text(parseHtmlString(_categories[index].name)),
onTap: () {
Navigator.pop(context);
Navigator.pushNamed(context, "/browse-category",
arguments: _categories[index])
.then((value) => setState(() {}));
},
),
),
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
List<String> bannerImages = _wooSignalApp.bannerImages; Widget theme =
return Scaffold( MelloThemeWidget(globalKey: _key, wooSignalApp: _wooSignalApp);
drawer: HomeDrawerWidget(wooSignalApp: _wooSignalApp), if (AppHelper.instance.themeType == "notic") {
appBar: AppBar( theme = NoticThemeWidget(globalKey: _key, wooSignalApp: _wooSignalApp);
title: StoreLogo(height: 55),
centerTitle: true,
actions: <Widget>[
IconButton(
alignment: Alignment.centerLeft,
icon: Icon(
Icons.search,
size: 35,
),
onPressed: () => Navigator.pushNamed(context, "/home-search")
.then((value) => _key.currentState.setState(() {})),
),
CartIconWidget(key: _key),
],
),
body: SafeArea(
minimum: safeAreaDefault(),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
(_isLoading
? Expanded(child: AppLoaderWidget())
: Expanded(
child: RefreshableScrollContainer(
controller: _refreshController,
onRefresh: _onRefresh,
onLoading: _onLoading,
products: _products,
onTap: _showProduct,
bannerHeight: MediaQuery.of(context).size.height / 3.5,
bannerImages: bannerImages,
modalBottomSheetMenu: _modalBottomSheetMenu,
),
flex: 1,
)),
],
),
),
);
} }
return theme;
_onRefresh() async {
_products = [];
_page = 1;
_shouldStopRequests = false;
waitForNextRequest = false;
await _fetchMoreProducts();
_refreshController.refreshCompleted();
}
_onLoading() async {
await _fetchMoreProducts();
if (mounted) {
setState(() {});
if (_shouldStopRequests) {
_refreshController.loadNoData();
} else {
_refreshController.loadComplete();
} }
} }
}
_showProduct(WSProduct.Product product) =>
Navigator.pushNamed(context, "/product-detail", arguments: product)
.then((value) => _key.currentState.setState(() {}));
}

View File

@ -9,6 +9,7 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_app/bootstrap/app_helper.dart';
import 'package:flutter_app/bootstrap/helpers.dart'; import 'package:flutter_app/bootstrap/helpers.dart';
import 'package:flutter_app/resources/widgets/buttons.dart'; import 'package:flutter_app/resources/widgets/buttons.dart';
import 'package:nylo_framework/helpers/helper.dart'; import 'package:nylo_framework/helpers/helper.dart';
@ -36,7 +37,9 @@ class _HomeSearchPageState extends State<HomeSearchPage> {
Navigator.pushNamed(context, "/product-search", Navigator.pushNamed(context, "/product-search",
arguments: _txtSearchController.text) arguments: _txtSearchController.text)
.then((search) { .then((search) {
if (AppHelper.instance.themeType != "notic") {
Navigator.pop(context); Navigator.pop(context);
}
}); });
} }

View File

@ -68,7 +68,8 @@ class _NoConnectionPageState extends State<NoConnectionPage> {
Navigator.pushNamed(context, "/home"); Navigator.pushNamed(context, "/home");
return; return;
} }
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Oops"), desc: trans(context, "Retry later")); title: trans(context, "Oops"),
description: trans(context, "Retry later"));
} }
} }

View File

@ -23,12 +23,12 @@ import 'package:flutter_app/resources/widgets/cart_icon_widget.dart';
import 'package:flutter_app/resources/widgets/woosignal_ui.dart'; import 'package:flutter_app/resources/widgets/woosignal_ui.dart';
import 'package:nylo_framework/helpers/helper.dart'; import 'package:nylo_framework/helpers/helper.dart';
import 'package:nylo_framework/widgets/ny_state.dart'; import 'package:nylo_framework/widgets/ny_state.dart';
import 'package:nylo_framework/widgets/stateful_page_widget.dart'; import 'package:nylo_framework/widgets/ny_stateful_widget.dart';
import 'package:woosignal/models/response/product_variation.dart' as WS; import 'package:woosignal/models/response/product_variation.dart' as WS;
import 'package:woosignal/models/response/products.dart' as WSProduct; import 'package:woosignal/models/response/products.dart' as WSProduct;
import 'package:flutter_swiper/flutter_swiper.dart'; import 'package:flutter_swiper/flutter_swiper.dart';
class ProductDetailPage extends StatefulPageWidget { class ProductDetailPage extends NyStatefulWidget {
final ProductDetailController controller = ProductDetailController(); final ProductDetailController controller = ProductDetailController();
ProductDetailPage({Key key}) : super(key: key); ProductDetailPage({Key key}) : super(key: key);
@ -205,29 +205,30 @@ class _ProductDetailState extends NyState<ProductDetailPage> {
action: () { action: () {
if (_product.attributes.length != if (_product.attributes.length !=
_tmpAttributeObj.values.length) { _tmpAttributeObj.values.length) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Oops"), title: trans(context, "Oops"),
desc: description:
trans(context, "Please select valid options first"), trans(context, "Please select valid options first"),
style: EdgeAlertStyle.WARNING); style: ToastNotificationStyleType.WARNING);
return; return;
} }
WS.ProductVariation productVariation = findProductVariation(); WS.ProductVariation productVariation = findProductVariation();
if (productVariation == null) { if (productVariation == null) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Oops"), title: trans(context, "Oops"),
desc: description:
trans(context, "Product variation does not exist"), trans(context, "Product variation does not exist"),
style: EdgeAlertStyle.WARNING); style: ToastNotificationStyleType.WARNING);
return; return;
} }
if (productVariation.stockStatus != "instock") { if (productVariation.stockStatus != "instock") {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Sorry"), title: trans(context, "Sorry"),
desc: trans(context, "This item is not in stock"), description:
style: EdgeAlertStyle.WARNING); trans(context, "This item is not in stock"),
style: ToastNotificationStyleType.WARNING);
return; return;
} }
@ -551,10 +552,10 @@ class _ProductDetailState extends NyState<ProductDetailPage> {
return; return;
} }
if (_product.stockStatus != "instock") { if (_product.stockStatus != "instock") {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Sorry"), title: trans(context, "Sorry"),
desc: trans(context, "This item is out of stock"), description: trans(context, "This item is out of stock"),
style: EdgeAlertStyle.WARNING, style: ToastNotificationStyleType.WARNING,
icon: Icons.local_shipping); icon: Icons.local_shipping);
return; return;
} }
@ -580,11 +581,11 @@ class _ProductDetailState extends NyState<ProductDetailPage> {
_addQuantityTapped() { _addQuantityTapped() {
if (_product.manageStock != null && _product.manageStock == true) { if (_product.manageStock != null && _product.manageStock == true) {
if (_quantityIndicator >= _product.stockQuantity) { if (_quantityIndicator >= _product.stockQuantity) {
showEdgeAlertWith(context, showToastNotification(context,
title: trans(context, "Maximum quantity reached"), title: trans(context, "Maximum quantity reached"),
desc: description:
"${trans(context, "Sorry, only")} ${_product.stockQuantity} ${trans(context, "left")}", "${trans(context, "Sorry, only")} ${_product.stockQuantity} ${trans(context, "left")}",
style: EdgeAlertStyle.INFO); style: ToastNotificationStyleType.INFO);
return; return;
} }
} }

View File

@ -16,9 +16,9 @@ import 'package:flutter_app/resources/widgets/cached_image_widget.dart';
import 'package:flutter_swiper/flutter_swiper.dart'; import 'package:flutter_swiper/flutter_swiper.dart';
import 'package:nylo_framework/helpers/helper.dart'; import 'package:nylo_framework/helpers/helper.dart';
import 'package:nylo_framework/widgets/ny_state.dart'; import 'package:nylo_framework/widgets/ny_state.dart';
import 'package:nylo_framework/widgets/stateful_page_widget.dart'; import 'package:nylo_framework/widgets/ny_stateful_widget.dart';
class ProductImageViewerPage extends StatefulPageWidget { class ProductImageViewerPage extends NyStatefulWidget {
final ProductImageViewerController controller = final ProductImageViewerController controller =
ProductImageViewerController(); ProductImageViewerController();
ProductImageViewerPage({Key key}) : super(key: key); ProductImageViewerPage({Key key}) : super(key: key);

View File

@ -20,8 +20,8 @@ class AppLoaderWidget extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
AdaptiveThemeMode adaptiveThemeMode = AdaptiveTheme.of(context).mode; AdaptiveThemeMode adaptiveThemeMode = AdaptiveTheme.of(context).mode;
return SpinKitDoubleBounce( return SpinKitDoubleBounce(
color: adaptiveThemeMode.isLight color:
? HexColor("#424242") adaptiveThemeMode.isLight ? HexColor("#424242") : HexColor("#c7c7c7"),
: HexColor("#c7c7c7")); );
} }
} }

View File

@ -0,0 +1,156 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_app/app/models/cart_line_item.dart';
import 'package:flutter_app/app/models/checkout_session.dart';
import 'package:flutter_app/app/models/customer_address.dart';
import 'package:flutter_app/bootstrap/app_helper.dart';
import 'package:flutter_app/bootstrap/helpers.dart';
import 'dart:async';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
import 'package:nylo_framework/helpers/helper.dart';
import 'package:nylo_framework/widgets/ny_state.dart';
import 'package:woosignal/models/response/woosignal_app.dart';
class PayPalCheckout extends StatefulWidget {
final String description;
final String amount;
final List<CartLineItem> cartLineItems;
PayPalCheckout({this.description, this.amount, this.cartLineItems});
@override
WebViewState createState() => WebViewState();
}
class WebViewState extends NyState<PayPalCheckout> {
final flutterWebViewPlugin = new FlutterWebviewPlugin();
String payerId = '';
int intCount = 0;
StreamSubscription<String> _onUrlChanged;
WooSignalApp _wooSignalApp = AppHelper.instance.appConfig;
String formCheckoutShippingAddress;
setCheckoutShippingAddress(CustomerAddress customerAddress) {
String tmp = "";
if (customerAddress.firstName != null) {
tmp +=
'<input type="hidden" name="first_name" value="${customerAddress.firstName}">\n';
}
if (customerAddress.lastName != null) {
tmp +=
'<input type="hidden" name="last_name" value="${customerAddress.lastName}">\n';
}
if (customerAddress.addressLine != null) {
tmp +=
'<input type="hidden" name="address1" value="${customerAddress.addressLine}">\n';
}
if (customerAddress.city != null) {
tmp +=
'<input type="hidden" name="city" value="${customerAddress.city}">\n';
}
if (customerAddress.customerCountry.hasState() &&
customerAddress.customerCountry.state.name != null) {
tmp +=
'<input type="hidden" name="state" value="${customerAddress.customerCountry.state.name}">\n';
}
if (customerAddress.postalCode != null) {
tmp +=
'<input type="hidden" name="zip" value="${customerAddress.postalCode}">\n';
}
if (customerAddress.customerCountry.countryCode != null) {
tmp +=
'<input type="hidden" name="country" value="${customerAddress.customerCountry.countryCode}">\n';
}
formCheckoutShippingAddress = tmp;
}
String getPayPalItemName() {
return truncateString(widget.description, 124);
}
String getPayPalPaymentType() {
return Platform.isAndroid ? "PayPal - Android App" : "PayPal - IOS App";
}
String getPayPalUrl() {
bool liveMode = getEnv('PAYPAL_LIVE_MODE', defaultValue: false);
return liveMode == true
? "https://www.paypal.com/cgi-bin/webscr"
: "https://www.sandbox.paypal.com/cgi-bin/webscr";
}
@override
void initState() {
super.initState();
setCheckoutShippingAddress(
CheckoutSession.getInstance.billingDetails.shippingAddress);
setState(() {});
_onUrlChanged = flutterWebViewPlugin.onUrlChanged.listen((String url) {
if (intCount > 0) {
url = url.replaceAll("~", "_");
}
intCount = intCount + 1;
if (url.contains("payment_success")) {
var uri = Uri.dataFromString(url);
setState(() {
payerId = uri.queryParameters['PayerID'];
});
Navigator.pop(context, {"status": "success", "payerId": payerId});
} else if (url.contains("payment_failure")) {
Navigator.pop(context, {"status": "cancelled"});
}
});
}
@override
void dispose() {
_onUrlChanged.cancel();
flutterWebViewPlugin.dispose();
super.dispose();
}
String _loadHTML() {
return '''
<html><head><title>${trans(context, "Processing Payment")}...</title></head>
<body onload="document.forms['paypal_form'].submit();">
<div style="text-align:center;">
<img src="https://woosignal.com/images/paypal_logo.png" height="50" />
</div>
<center><h4>${trans(context, "Please wait, your order is being processed and you will be redirected to the PayPal website.")}</h4></center>
<form method="post" name="paypal_form" action="${getPayPalUrl()}">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="amount" value="${widget.amount}">
<input type="hidden" name="currency_code" value="${_wooSignalApp.currencyMeta.code}">
<input type="hidden" name="business" value="${getEnv('PAYPAL_ACCOUNT_EMAIL')}">
<input type="hidden" name="return" value="https://woosignal.com/paypal/payment~success">
<input type="hidden" name="cancel_return" value="https://woosignal.com/paypal/payment~failure">
<input type="hidden" name="item_name" value="${getPayPalItemName()}">
<input type="hidden" name="custom" value="${getPayPalPaymentType()}">
<input type="hidden" name="address_override" value="1">
$formCheckoutShippingAddress
<center><br><br>${trans(context, "If you are not automatically redirected to PayPal within 5 seconds")}...<br><br>
<input type="submit" value="Click Here"></center>
</form></body></html>
''';
}
@override
Widget build(BuildContext context) {
return WebviewScaffold(
url: Uri.dataFromString(_loadHTML(), mimeType: 'text/html').toString(),
appBar: AppBar(
centerTitle: true,
automaticallyImplyLeading: false,
title: Text(
trans(context, "PayPal Checkout"),
textAlign: TextAlign.center,
),
),
);
}
}

View File

@ -87,14 +87,19 @@ class _HomeDrawerWidgetState extends State<HomeDrawerWidget> {
onTap: _actionPrivacy, onTap: _actionPrivacy,
), ),
ListTile( ListTile(
title: Text(adaptiveTheme.isDark title: Text(
adaptiveTheme.isDark
? trans(context, "Light Mode") ? trans(context, "Light Mode")
: trans(context, "Dark Mode")), : trans(context, "Dark Mode"),
),
leading: Icon(Icons.brightness_4_rounded), leading: Icon(Icons.brightness_4_rounded),
onTap: () { onTap: () {
setState(() { if (adaptiveTheme.isDark) {
AdaptiveTheme.of(context).toggleThemeMode(); AdaptiveTheme.of(context).setLight();
}); } else {
AdaptiveTheme.of(context).setDark();
}
setState(() {});
}, },
), ),
ListTile( ListTile(

View File

@ -0,0 +1,174 @@
import 'package:flutter/material.dart';
import 'package:flutter_app/bootstrap/helpers.dart';
import 'package:flutter_app/resources/widgets/app_loader_widget.dart';
import 'package:flutter_app/resources/widgets/cart_icon_widget.dart';
import 'package:flutter_app/resources/widgets/home_drawer_widget.dart';
import 'package:flutter_app/resources/widgets/woosignal_ui.dart';
import 'package:nylo_framework/helpers/helper.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:woosignal/models/response/woosignal_app.dart';
import 'package:woosignal/models/response/product_category.dart' as WS;
import 'package:woosignal/models/response/products.dart' as WSProduct;
class MelloThemeWidget extends StatefulWidget {
MelloThemeWidget(
{Key key, @required this.globalKey, @required this.wooSignalApp})
: super(key: key);
final GlobalKey globalKey;
final WooSignalApp wooSignalApp;
@override
_MelloThemeWidgetState createState() => _MelloThemeWidgetState();
}
class _MelloThemeWidgetState extends State<MelloThemeWidget> {
RefreshController _refreshController =
RefreshController(initialRefresh: false);
List<WSProduct.Product> _products = [];
List<WS.ProductCategory> _categories = [];
int _page = 1;
bool _shouldStopRequests = false,
waitForNextRequest = false,
_isLoading = true;
@override
void initState() {
super.initState();
_home();
}
_home() async {
await _fetchMoreProducts();
await _fetchCategories();
setState(() {
_isLoading = false;
});
}
_fetchCategories() async {
_categories =
await appWooSignal((api) => api.getProductCategories(perPage: 100));
}
_fetchMoreProducts() async {
if (_shouldStopRequests) {
return;
}
if (waitForNextRequest) {
return;
}
waitForNextRequest = true;
List<WSProduct.Product> products = await appWooSignal((api) =>
api.getProducts(
perPage: 50,
page: _page,
status: "publish",
stockStatus: "instock"));
_page = _page + 1;
if (products.length == 0) {
_shouldStopRequests = true;
}
waitForNextRequest = false;
setState(() {
_products.addAll(products.toList());
});
}
_modalBottomSheetMenu() {
widget.globalKey.currentState.setState(() {});
wsModalBottom(
context,
title: trans(context, "Categories"),
bodyWidget: ListView.separated(
itemCount: _categories.length,
separatorBuilder: (cxt, i) => Divider(),
itemBuilder: (BuildContext context, int index) => ListTile(
title: Text(parseHtmlString(_categories[index].name)),
onTap: () {
Navigator.pop(context);
Navigator.pushNamed(context, "/browse-category",
arguments: _categories[index])
.then((value) => setState(() {}));
},
),
),
);
}
@override
Widget build(BuildContext context) {
List<String> bannerImages = widget.wooSignalApp.bannerImages;
return Scaffold(
drawer: HomeDrawerWidget(wooSignalApp: widget.wooSignalApp),
appBar: AppBar(
title: StoreLogo(height: 55),
centerTitle: true,
actions: <Widget>[
IconButton(
alignment: Alignment.centerLeft,
icon: Icon(
Icons.search,
size: 35,
),
onPressed: () => Navigator.pushNamed(context, "/home-search")
.then((value) => widget.globalKey.currentState.setState(() {})),
),
CartIconWidget(key: widget.globalKey),
],
),
body: SafeArea(
minimum: safeAreaDefault(),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
(_isLoading
? Expanded(child: AppLoaderWidget())
: Expanded(
child: RefreshableScrollContainer(
controller: _refreshController,
onRefresh: _onRefresh,
onLoading: _onLoading,
products: _products,
onTap: _showProduct,
bannerHeight: MediaQuery.of(context).size.height / 3.5,
bannerImages: bannerImages,
modalBottomSheetMenu: _modalBottomSheetMenu,
),
flex: 1,
)),
],
),
),
);
}
_onRefresh() async {
_products = [];
_page = 1;
_shouldStopRequests = false;
waitForNextRequest = false;
await _fetchMoreProducts();
_refreshController.refreshCompleted();
}
_onLoading() async {
await _fetchMoreProducts();
if (mounted) {
setState(() {});
if (_shouldStopRequests) {
_refreshController.loadNoData();
} else {
_refreshController.loadComplete();
}
}
}
_showProduct(WSProduct.Product product) =>
Navigator.pushNamed(context, "/product-detail", arguments: product)
.then((value) => widget.globalKey.currentState.setState(() {}));
}

View File

@ -0,0 +1,257 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app/bootstrap/helpers.dart';
import 'package:flutter_app/resources/widgets/app_loader_widget.dart';
import 'package:flutter_app/resources/widgets/cached_image_widget.dart';
import 'package:flutter_app/resources/widgets/home_drawer_widget.dart';
import 'package:flutter_app/resources/widgets/no_results_for_products_widget.dart';
import 'package:flutter_app/resources/widgets/woosignal_ui.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:flutter_swiper/flutter_swiper.dart';
import 'package:nylo_framework/helpers/helper.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:woosignal/models/response/woosignal_app.dart';
import 'package:woosignal/models/response/product_category.dart' as WS;
import 'package:woosignal/models/response/products.dart' as WSProduct;
class NoticHomeWidget extends StatefulWidget {
NoticHomeWidget({Key key, @required this.wooSignalApp}) : super(key: key);
final WooSignalApp wooSignalApp;
@override
_NoticHomeWidgetState createState() => _NoticHomeWidgetState();
}
class _NoticHomeWidgetState extends State<NoticHomeWidget> {
Widget activeWidget;
RefreshController _refreshController =
RefreshController(initialRefresh: false);
List<WSProduct.Product> _products = [];
List<WS.ProductCategory> _categories = [];
int _page = 1;
bool _shouldStopRequests = false,
waitForNextRequest = false,
_isLoading = true;
@override
void initState() {
super.initState();
_home();
}
_home() async {
await _fetchMoreProducts();
await _fetchCategories();
setState(() {
_isLoading = false;
});
}
_fetchCategories() async {
_categories =
await appWooSignal((api) => api.getProductCategories(perPage: 100));
}
_fetchMoreProducts() async {
if (_shouldStopRequests) {
return;
}
if (waitForNextRequest) {
return;
}
waitForNextRequest = true;
List<WSProduct.Product> products = await appWooSignal((api) =>
api.getProducts(
perPage: 50,
page: _page,
status: "publish",
stockStatus: "instock"));
_page = _page + 1;
if (products.length == 0) {
_shouldStopRequests = true;
}
waitForNextRequest = false;
setState(() {
_products.addAll(products.toList());
});
}
_modalBottomSheetMenu() {
wsModalBottom(
context,
title: trans(context, "Categories"),
bodyWidget: ListView.separated(
itemCount: _categories.length,
separatorBuilder: (cxt, i) => Divider(),
itemBuilder: (BuildContext context, int index) => ListTile(
title: Text(parseHtmlString(_categories[index].name)),
onTap: () {
Navigator.pop(context);
Navigator.pushNamed(context, "/browse-category",
arguments: _categories[index])
.then((value) => setState(() {}));
},
),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
drawer: HomeDrawerWidget(wooSignalApp: widget.wooSignalApp),
appBar: AppBar(
title: StoreLogo(height: 55),
centerTitle: true,
actions: [
Center(
child: Container(
margin: EdgeInsets.only(right: 8),
child: InkWell(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
onTap: _modalBottomSheetMenu,
child: Text(
trans(context, "Categories"),
),
),
),
),
],
),
body: SafeArea(
minimum: safeAreaDefault(),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
(_isLoading
? Expanded(child: AppLoaderWidget())
: Expanded(
child: ListView(
shrinkWrap: true,
children: [
Container(
margin: EdgeInsets.only(bottom: 15),
child: Swiper(
itemBuilder: (BuildContext context, int index) {
return CachedImageWidget(
image: widget.wooSignalApp.bannerImages[index],
fit: BoxFit.cover,
);
},
itemCount: widget.wooSignalApp.bannerImages.length,
viewportFraction: 0.8,
scale: 0.9,
),
height: MediaQuery.of(context).size.height / 2.5,
),
Container(
height: 80,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(trans(context, "Must have")),
Text(
trans(context, "Our selection of new items"),
style: Theme.of(context).textTheme.headline4,
)
],
),
),
Container(
height: 250,
child: SmartRefresher(
enablePullDown: true,
enablePullUp: true,
footer: CustomFooter(
builder: (BuildContext context, LoadStatus mode) {
Widget body;
if (mode == LoadStatus.idle) {
body = Text(trans(context, "pull up load"));
} else if (mode == LoadStatus.loading) {
body = CupertinoActivityIndicator();
} else if (mode == LoadStatus.failed) {
body = Text(trans(
context, "Load Failed! Click retry!"));
} else if (mode == LoadStatus.canLoading) {
body = Text(
trans(context, "release to load more"));
} else {
body =
Text(trans(context, "No more products"));
}
return Container(
height: 55.0,
child: Center(child: body),
);
},
),
controller: _refreshController,
onRefresh: _onRefresh,
onLoading: _onLoading,
child: (_products.length != null &&
_products.length > 0
? StaggeredGridView.countBuilder(
crossAxisCount: 2,
scrollDirection: Axis.horizontal,
itemCount: _products.length,
itemBuilder:
(BuildContext context, int index) {
return Container(
height: 250,
child: ProductItemContainer(
index: index,
product: _products[index],
onTap: _showProduct,
),
);
},
staggeredTileBuilder: (int index) {
return new StaggeredTile.fit(2);
},
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
)
: NoResultsForProductsWidget()),
),
)
],
),
flex: 1,
)),
],
),
),
);
}
_onRefresh() async {
_products = [];
_page = 1;
_shouldStopRequests = false;
waitForNextRequest = false;
await _fetchMoreProducts();
_refreshController.refreshCompleted();
}
_onLoading() async {
await _fetchMoreProducts();
if (mounted) {
setState(() {});
if (_shouldStopRequests) {
_refreshController.loadNoData();
} else {
_refreshController.loadComplete();
}
}
}
_showProduct(WSProduct.Product product) =>
Navigator.pushNamed(context, "/product-detail", arguments: product);
}

View File

@ -0,0 +1,95 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app/bootstrap/app_helper.dart';
import 'package:flutter_app/resources/pages/account_landing.dart';
import 'package:flutter_app/resources/pages/cart.dart';
import 'package:flutter_app/resources/pages/home_search.dart';
import 'package:flutter_app/resources/widgets/notic_home_widget.dart';
import 'package:woosignal/models/response/woosignal_app.dart';
class NoticThemeWidget extends StatefulWidget {
NoticThemeWidget(
{Key key, @required this.globalKey, @required this.wooSignalApp})
: super(key: key);
final GlobalKey globalKey;
final WooSignalApp wooSignalApp;
@override
_NoticThemeWidgetState createState() => _NoticThemeWidgetState();
}
class _NoticThemeWidgetState extends State<NoticThemeWidget> {
Widget activeWidget;
int _currentIndex = 0;
@override
void initState() {
super.initState();
_changeMainWidget();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: activeWidget,
bottomNavigationBar: BottomNavigationBar(
onTap: _onTabTapped,
currentIndex: _currentIndex,
unselectedItemColor: Colors.black54,
fixedColor: Colors.black87,
selectedLabelStyle: TextStyle(color: Colors.black),
unselectedLabelStyle: TextStyle(
color: Colors.black87,
),
showSelectedLabels: false,
showUnselectedLabels: false,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
label: 'Search',
),
BottomNavigationBarItem(
icon: Icon(Icons.shopping_cart), label: 'Cart'),
if (AppHelper.instance.appConfig.wpLoginEnabled == 1)
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Account')
],
),
);
}
_onTabTapped(int i) {
_currentIndex = i;
_changeMainWidget();
setState(() {});
}
_changeMainWidget() {
switch (_currentIndex) {
case 0:
{
activeWidget = NoticHomeWidget(wooSignalApp: widget.wooSignalApp);
break;
}
case 1:
{
activeWidget = HomeSearchPage();
break;
}
case 2:
{
activeWidget = CartPage();
break;
}
case 3:
{
activeWidget = AccountLandingPage();
break;
}
}
}
}

View File

@ -12,6 +12,7 @@ import 'package:adaptive_theme/adaptive_theme.dart';
import 'package:auto_size_text/auto_size_text.dart'; import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_app/app/models/cart.dart'; import 'package:flutter_app/app/models/cart.dart';
import 'package:flutter_app/app/models/cart_line_item.dart'; import 'package:flutter_app/app/models/cart_line_item.dart';
import 'package:flutter_app/app/models/checkout_session.dart'; import 'package:flutter_app/app/models/checkout_session.dart';

View File

@ -19,6 +19,7 @@ import 'package:flutter_app/resources/pages/home_search.dart';
import 'package:flutter_app/resources/pages/no_connection_page.dart'; import 'package:flutter_app/resources/pages/no_connection_page.dart';
import 'package:flutter_app/resources/pages/product_detail.dart'; import 'package:flutter_app/resources/pages/product_detail.dart';
import 'package:flutter_app/resources/pages/product_image_viewer_page.dart'; import 'package:flutter_app/resources/pages/product_image_viewer_page.dart';
import 'package:flutter_app/resources/widgets/checkout_paypal.dart';
import 'package:nylo_framework/router/router.dart'; import 'package:nylo_framework/router/router.dart';
import 'package:page_transition/page_transition.dart'; import 'package:page_transition/page_transition.dart';
@ -68,6 +69,8 @@ buildRouter() => nyCreateRoutes((router) {
router.route("/home-search", (context) => HomeSearchPage(), router.route("/home-search", (context) => HomeSearchPage(),
transition: PageTransitionType.bottomToTop); transition: PageTransitionType.bottomToTop);
router.route('/paypal', (context) => PayPalCheckout());
router.route("/customer-countries", (context) => CustomerCountriesPage(), router.route("/customer-countries", (context) => CustomerCountriesPage(),
transition: PageTransitionType.bottomToTop); transition: PageTransitionType.bottomToTop);

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1,34 +1,48 @@
# Generated by pub # Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile # See https://dart.dev/tools/pub/glossary#lockfile
packages: packages:
_fe_analyzer_shared:
dependency: transitive
description:
name: _fe_analyzer_shared
url: "https://pub.dartlang.org"
source: hosted
version: "20.0.0"
adaptive_theme: adaptive_theme:
dependency: "direct main" dependency: "direct main"
description: description:
name: adaptive_theme name: adaptive_theme
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "2.1.1"
analyzer: analyzer:
dependency: "direct main" dependency: "direct main"
description: description:
name: analyzer name: analyzer
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.38.5" version: "1.4.0"
animate_do:
dependency: "direct main"
description:
name: animate_do
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
archive: archive:
dependency: transitive dependency: transitive
description: description:
name: archive name: archive
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.13" version: "3.1.2"
args: args:
dependency: transitive dependency: transitive
description: description:
name: args name: args
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.6.0" version: "2.0.0"
async: async:
dependency: transitive dependency: transitive
description: description:
@ -63,7 +77,7 @@ packages:
name: cached_network_image name: cached_network_image
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.5.1" version: "3.0.0"
characters: characters:
dependency: transitive dependency: transitive
description: description:
@ -78,6 +92,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "1.2.0"
cli_util:
dependency: transitive
description:
name: cli_util
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.0"
clock: clock:
dependency: transitive dependency: transitive
description: description:
@ -98,21 +119,21 @@ packages:
name: convert name: convert
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.1" version: "3.0.0"
crypto: crypto:
dependency: transitive dependency: transitive
description: description:
name: crypto name: crypto
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.4" version: "3.0.1"
csslib: csslib:
dependency: transitive dependency: transitive
description: description:
name: csslib name: csslib
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.16.1" version: "0.17.0"
cupertino_icons: cupertino_icons:
dependency: "direct main" dependency: "direct main"
description: description:
@ -120,48 +141,27 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.2" version: "1.0.2"
dart_style:
dependency: transitive
description:
name: dart_style
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.3"
device_info: device_info:
dependency: transitive dependency: transitive
description: description:
name: device_info name: device_info
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.0" version: "2.0.0"
device_info_platform_interface: device_info_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: device_info_platform_interface name: device_info_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.1" version: "2.0.1"
dio: dio:
dependency: transitive dependency: transitive
description: description:
name: dio name: dio
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.10" version: "4.0.0"
edge_alert:
dependency: "direct main"
description:
name: edge_alert
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.1"
equatable:
dependency: transitive
description:
name: equatable
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.5"
eventify: eventify:
dependency: transitive dependency: transitive
description: description:
@ -209,53 +209,39 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_application_id:
dependency: "direct dev"
description:
name: flutter_application_id
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
flutter_blurhash: flutter_blurhash:
dependency: transitive dependency: transitive
description: description:
name: flutter_blurhash name: flutter_blurhash
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.5.0" version: "0.6.0"
flutter_cache_manager: flutter_cache_manager:
dependency: transitive dependency: transitive
description: description:
name: flutter_cache_manager name: flutter_cache_manager
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.2" version: "3.0.1"
flutter_dotenv: flutter_dotenv:
dependency: transitive dependency: transitive
description: description:
name: flutter_dotenv name: flutter_dotenv
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0" version: "4.0.0-nullsafety.0"
flutter_launcher_icons: flutter_launcher_icons:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_launcher_icons name: flutter_launcher_icons
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.8.1" version: "0.9.0"
flutter_localizations: flutter_localizations:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_money_formatter:
dependency: "direct main"
description:
name: flutter_money_formatter
url: "https://pub.dartlang.org"
source: hosted
version: "0.8.3"
flutter_page_indicator: flutter_page_indicator:
dependency: transitive dependency: transitive
description: description:
@ -269,7 +255,7 @@ packages:
name: flutter_secure_storage name: flutter_secure_storage
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.3.5" version: "4.1.0"
flutter_spinkit: flutter_spinkit:
dependency: "direct main" dependency: "direct main"
description: description:
@ -284,6 +270,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.3.4" version: "0.3.4"
flutter_styled_toast:
dependency: "direct main"
description:
name: flutter_styled_toast
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
flutter_swiper: flutter_swiper:
dependency: "direct main" dependency: "direct main"
description: description:
@ -308,34 +301,27 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
front_end: flutter_webview_plugin:
dependency: transitive dependency: "direct main"
description: description:
name: front_end name: flutter_webview_plugin
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.27" version: "0.3.11"
glob: glob:
dependency: transitive dependency: transitive
description: description:
name: glob name: glob
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "2.0.1"
google_fonts: google_fonts:
dependency: "direct main" dependency: "direct main"
description: description:
name: google_fonts name: google_fonts
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.2" version: "2.0.0"
grapheme_splitter:
dependency: transitive
description:
name: grapheme_splitter
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
hexcolor: hexcolor:
dependency: "direct main" dependency: "direct main"
description: description:
@ -349,28 +335,28 @@ packages:
name: html name: html
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.14.0+4" version: "0.15.0"
http: http:
dependency: transitive dependency: transitive
description: description:
name: http name: http
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.12.2" version: "0.13.1"
http_parser: http_parser:
dependency: transitive dependency: transitive
description: description:
name: http_parser name: http_parser
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.1.4" version: "4.0.0"
image: image:
dependency: transitive dependency: transitive
description: description:
name: image name: image
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.19" version: "3.0.2"
intl: intl:
dependency: "direct main" dependency: "direct main"
description: description:
@ -385,34 +371,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.6.3" version: "0.6.3"
json_ast:
dependency: transitive
description:
name: json_ast
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.5"
json_to_dart:
dependency: transitive
description:
name: json_to_dart
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
kernel:
dependency: transitive
description:
name: kernel
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.27"
logger: logger:
dependency: transitive dependency: transitive
description: description:
name: logger name: logger
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.9.4" version: "1.0.0"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
@ -434,41 +399,34 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.0" version: "1.3.0"
node_interop: money_formatter:
dependency: transitive dependency: "direct main"
description: description:
name: node_interop name: money_formatter
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.1" version: "0.0.3"
node_io:
dependency: transitive
description:
name: node_io
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
nylo_framework: nylo_framework:
dependency: "direct main" dependency: "direct main"
description: description:
name: nylo_framework name: nylo_framework
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.7.0+1" version: "0.8.2"
octo_image: octo_image:
dependency: transitive dependency: transitive
description: description:
name: octo_image name: octo_image
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.3.0" version: "1.0.0+1"
package_config: package_config:
dependency: transitive dependency: transitive
description: description:
name: package_config name: package_config
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.9.3" version: "2.0.0"
package_info: package_info:
dependency: "direct main" dependency: "direct main"
description: description:
@ -482,7 +440,7 @@ packages:
name: page_transition name: page_transition
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.7+6" version: "2.0.1-nullsafety.0"
path: path:
dependency: transitive dependency: transitive
description: description:
@ -496,49 +454,49 @@ packages:
name: path_provider name: path_provider
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.6.27" version: "2.0.1"
path_provider_linux: path_provider_linux:
dependency: transitive dependency: transitive
description: description:
name: path_provider_linux name: path_provider_linux
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.0.1+2" version: "2.0.0"
path_provider_macos: path_provider_macos:
dependency: transitive dependency: transitive
description: description:
name: path_provider_macos name: path_provider_macos
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.0.4+3" version: "2.0.0"
path_provider_platform_interface: path_provider_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: path_provider_platform_interface name: path_provider_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.4" version: "2.0.1"
path_provider_windows: path_provider_windows:
dependency: transitive dependency: transitive
description: description:
name: path_provider_windows name: path_provider_windows
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.0.5" version: "2.0.0"
pedantic: pedantic:
dependency: transitive dependency: transitive
description: description:
name: pedantic name: pedantic
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.9.0" version: "1.11.0"
petitparser: petitparser:
dependency: transitive dependency: transitive
description: description:
name: petitparser name: petitparser
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.4" version: "4.1.0"
platform: platform:
dependency: transitive dependency: transitive
description: description:
@ -559,21 +517,21 @@ packages:
name: plugin_platform_interface name: plugin_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.2" version: "2.0.0"
process: process:
dependency: transitive dependency: transitive
description: description:
name: process name: process
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.1.0" version: "4.2.1"
pub_semver: pub_semver:
dependency: transitive dependency: transitive
description: description:
name: pub_semver name: pub_semver
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.4.4" version: "2.0.0"
pull_to_refresh: pull_to_refresh:
dependency: "direct main" dependency: "direct main"
description: description:
@ -587,7 +545,7 @@ packages:
name: queue name: queue
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.7+2" version: "3.1.0"
razorpay_flutter: razorpay_flutter:
dependency: "direct main" dependency: "direct main"
description: description:
@ -601,49 +559,49 @@ packages:
name: rxdart name: rxdart
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.25.0" version: "0.26.0"
shared_preferences: shared_preferences:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences name: shared_preferences
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.5.12+4" version: "2.0.5"
shared_preferences_linux: shared_preferences_linux:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_linux name: shared_preferences_linux
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.0.2+4" version: "2.0.0"
shared_preferences_macos: shared_preferences_macos:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_macos name: shared_preferences_macos
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.0.1+10" version: "2.0.0"
shared_preferences_platform_interface: shared_preferences_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_platform_interface name: shared_preferences_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.4" version: "2.0.0"
shared_preferences_web: shared_preferences_web:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_web name: shared_preferences_web
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.2+7" version: "2.0.0"
shared_preferences_windows: shared_preferences_windows:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_windows name: shared_preferences_windows
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.0.2+3" version: "2.0.0"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
@ -662,7 +620,7 @@ packages:
name: sqflite name: sqflite
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.0+2" version: "2.0.0+3"
sqflite_common: sqflite_common:
dependency: transitive dependency: transitive
description: description:
@ -739,7 +697,7 @@ packages:
name: uuid name: uuid
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.2.2" version: "3.0.4"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
@ -753,21 +711,21 @@ packages:
name: watcher name: watcher
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.9.7+15" version: "1.0.0"
win32: win32:
dependency: transitive dependency: transitive
description: description:
name: win32 name: win32
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.3" version: "2.0.5"
woosignal: woosignal:
dependency: "direct main" dependency: "direct main"
description: description:
name: woosignal name: woosignal
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.5.1+1" version: "2.0.2"
woosignal_stripe: woosignal_stripe:
dependency: "direct main" dependency: "direct main"
description: description:
@ -781,28 +739,28 @@ packages:
name: wp_json_api name: wp_json_api
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.0" version: "3.0.0"
xdg_directories: xdg_directories:
dependency: transitive dependency: transitive
description: description:
name: xdg_directories name: xdg_directories
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.2" version: "0.2.0"
xml: xml:
dependency: transitive dependency: transitive
description: description:
name: xml name: xml
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.2.0" version: "5.1.0"
yaml: yaml:
dependency: transitive dependency: transitive
description: description:
name: yaml name: yaml
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.2.1" version: "3.1.0"
sdks: sdks:
dart: ">=2.12.0 <3.0.0" dart: ">=2.12.0 <3.0.0"
flutter: ">=2.0.0" flutter: ">=2.0.0"

View File

@ -1,7 +1,7 @@
# Official WooSignal App Template for WooCommerce # Official WooSignal App Template for WooCommerce
# Label StoreMax # Label StoreMax
# Version: 4.0.0 # Version: 5.0.0
# Author: Anthony Gordon # Author: Anthony Gordon
# Homepage: https://woosignal.com # Homepage: https://woosignal.com
# Documentation: https://woosignal.com/docs/app/ios/label-storemax # Documentation: https://woosignal.com/docs/app/ios/label-storemax
@ -25,32 +25,34 @@ environment:
sdk: ">=2.7.0 <3.0.0" sdk: ">=2.7.0 <3.0.0"
dependencies: dependencies:
google_fonts: ^1.1.2 google_fonts: ^2.0.0
analyzer: ^0.38.2 analyzer: ^1.3.0
adaptive_theme: ^1.1.0 adaptive_theme: ^2.0.0
intl: ^0.17.0 intl: ^0.17.0
page_transition: ^1.1.7+6 page_transition: ^2.0.1-nullsafety.0
nylo_framework: ^0.7.0+1 nylo_framework: ^0.8.2
woosignal: ^1.5.1+1 woosignal: ^2.0.2
woosignal_stripe: ^0.1.0 woosignal_stripe: ^0.1.0
razorpay_flutter: ^1.2.5 razorpay_flutter: ^1.2.5
wp_json_api: ^2.0.0 wp_json_api: ^3.0.0
cached_network_image: ^2.5.0 cached_network_image: ^3.0.0
package_info: ^2.0.0 package_info: ^2.0.0
flutter_money_formatter: ^0.8.3 money_formatter: ^0.0.3
platform_alert_dialog: ^1.0.0+2 platform_alert_dialog: ^1.0.0+2
flutter_web_browser: ^0.14.0 flutter_web_browser: ^0.14.0
flutter_webview_plugin: ^0.3.11
pull_to_refresh: 1.6.4 pull_to_refresh: 1.6.4
flutter_swiper: ^1.1.6 flutter_swiper: ^1.1.6
edge_alert: ^0.0.1 flutter_styled_toast: ^2.0.0
animate_do: ^2.0.0
bubble_tab_indicator: ^0.1.5 bubble_tab_indicator: ^0.1.5
status_alert: ^0.1.3 status_alert: ^0.1.3
math_expressions: ^2.1.0 math_expressions: ^2.1.0
hexcolor: ^2.0.3 hexcolor: ^2.0.3
flutter_spinkit: ^5.0.0 flutter_spinkit: ^5.0.0
flutter_launcher_icons: ^0.8.1 flutter_launcher_icons: ^0.9.0
auto_size_text: ^2.1.0 auto_size_text: ^2.1.0
html: ^0.14.0+4 html: ^0.15.0
flutter_staggered_grid_view: ^0.3.4 flutter_staggered_grid_view: ^0.3.4
flutter: flutter:
sdk: flutter sdk: flutter
@ -62,7 +64,6 @@ dependencies:
cupertino_icons: ^1.0.2 cupertino_icons: ^1.0.2
dev_dependencies: dev_dependencies:
flutter_application_id: "^1.0.0"
flutter_test: flutter_test:
sdk: flutter sdk: flutter
@ -73,7 +74,7 @@ flutter_icons:
image_path: "public/assets/app_icon/appicon.png" image_path: "public/assets/app_icon/appicon.png"
dependency_overrides: dependency_overrides:
intl: ^0.17.0-nullsafety.2 intl: ^0.17.0
flutter: flutter:
@ -91,6 +92,7 @@ flutter:
- public/assets/images/dark_powered_by_stripe.png - public/assets/images/dark_powered_by_stripe.png
- public/assets/images/cash_on_delivery.jpeg - public/assets/images/cash_on_delivery.jpeg
- public/assets/images/razorpay.png - public/assets/images/razorpay.png
- public/assets/images/paypal_logo.png
- public/assets/json/default_shipping.json - public/assets/json/default_shipping.json
- lang/en.json - lang/en.json
- lang/es.json - lang/es.json