v2.5.0 - Ability to add image placeholders on products + more

This commit is contained in:
Anthony 2020-12-24 00:02:39 +00:00
parent 6106e18de9
commit 0968caf300
15 changed files with 125 additions and 89 deletions

View File

@ -1,3 +1,9 @@
## [2.5.0] - 2020-12-23
* Ability to add image placeholders on products
* Dart code formatted
* Pubspec.yaml dependency updates
## [2.4.1] - 2020-12-20
* Fix subtotal bug on order creation

View File

@ -6,4 +6,5 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.VIBRATE"/>
</manifest>

View File

@ -8,6 +8,7 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.VIBRATE"/>
<application
android:name="io.flutter.app.FlutterApplication"

View File

@ -6,4 +6,5 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.VIBRATE"/>
</manifest>

View File

@ -50,7 +50,8 @@ Future<OrderWC> buildOrderWC({TaxRate taxRate, bool markPaid = true}) async {
tmpLineItem.total =
(cartItem.quantity > 1 ? cartItem.getCartTotal() : cartItem.subtotal);
tmpLineItem.subtotal = (parseWcPrice(cartItem.subtotal) * cartItem.quantity).toString();
tmpLineItem.subtotal =
(parseWcPrice(cartItem.subtotal) * cartItem.quantity).toString();
lineItems.add(tmpLineItem);
});

View File

@ -16,7 +16,7 @@ import 'dart:ui';
Developer Notes
SUPPORT EMAIL - support@woosignal.com
VERSION - 2.4.1
VERSION - 2.5.0
https://woosignal.com
*/
@ -57,6 +57,8 @@ const List<Locale> app_locales_supported = [
// then create a new lang json file using keys from en.json
// e.g. lang/es.json
const app_product_placeholder_image = "https://woosignal.com/images/woocommerce-placeholder.png";
/*<! ------ PAYMENT GATEWAYS ------!>*/
// Available: "Stripe", "CashOnDelivery", "RazorPay"

View File

@ -39,8 +39,10 @@ class _AboutPageState extends State<AboutPage> {
icon: Icon(Icons.close),
onPressed: () => Navigator.pop(context),
),
title: Text(trans(context, "About"),
style: Theme.of(context).primaryTextTheme.headline6),
title: Text(
trans(context, "About"),
style: Theme.of(context).primaryTextTheme.headline6,
),
centerTitle: true,
),
body: SafeArea(
@ -84,9 +86,7 @@ class _AboutPageState extends State<AboutPage> {
if (snapshot.hasError) return Text("");
return Padding(
child: Text(
trans(context, "Version") +
": " +
snapshot.data.version,
"${trans(context, "Version")}: ${snapshot.data.version}",
style: Theme.of(context)
.primaryTextTheme
.bodyText1),

View File

@ -76,9 +76,11 @@ class _CartPageState extends State<CartPage> {
void _actionProceedToCheckout() async {
List<CartLineItem> cartLineItems = await Cart.getInstance.getCart();
if (_isLoading == true) {
return;
}
if (cartLineItems.length <= 0) {
showEdgeAlertWith(
context,
@ -89,6 +91,7 @@ class _CartPageState extends State<CartPage> {
);
return;
}
if (!cartLineItems.every(
(c) => c.stockStatus == 'instock' || c.stockStatus == 'onbackorder')) {
showEdgeAlertWith(
@ -100,20 +103,24 @@ class _CartPageState extends State<CartPage> {
);
return;
}
CheckoutSession.getInstance.initSession();
CustomerAddress sfCustomerAddress =
await CheckoutSession.getInstance.getBillingAddress();
if (sfCustomerAddress != null) {
CheckoutSession.getInstance.billingDetails.billingAddress =
sfCustomerAddress;
CheckoutSession.getInstance.billingDetails.shippingAddress =
sfCustomerAddress;
}
if (use_wp_login == true && !(await authCheck())) {
UserAuth.instance.redirect = "/checkout";
Navigator.pushNamed(context, "/account-landing");
return;
}
Navigator.pushNamed(context, "/checkout");
}
@ -236,7 +243,9 @@ class _CartPageState extends State<CartPage> {
),
)
: (_isLoading
? Expanded(child: showAppLoader())
? Expanded(
child: showAppLoader(),
)
: Expanded(
child: ListView.builder(
padding: const EdgeInsets.all(8),

View File

@ -15,7 +15,7 @@ import 'package:label_storemax/widgets/app_loader.dart';
import 'package:label_storemax/widgets/cart_icon.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 WS;
import 'package:woosignal/models/response/products.dart' as WSProduct;
import 'package:label_storemax/widgets/woosignal_ui.dart';
class HomePage extends StatefulWidget {
@ -30,7 +30,7 @@ class _HomePageState extends State<HomePage> {
RefreshController _refreshController =
RefreshController(initialRefresh: false);
List<WS.Product> _products = [];
List<WSProduct.Product> _products = [];
List<WS.ProductCategory> _categories = [];
final GlobalKey _key = GlobalKey();
@ -72,8 +72,12 @@ class _HomePageState extends State<HomePage> {
}
waitForNextRequest = true;
List<WS.Product> products = await appWooSignal((api) => api.getProducts(
perPage: 50, page: _page, status: "publish", stockStatus: "instock"));
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;
@ -217,7 +221,7 @@ class _HomePageState extends State<HomePage> {
}
}
_showProduct(WS.Product product) {
_showProduct(WSProduct.Product product) {
Navigator.pushNamed(context, "/product-detail", arguments: product)
.then((value) => _key.currentState.setState(() {}));
}

View File

@ -11,19 +11,20 @@
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
import 'package:label_storemax/helpers/tools.dart';
import 'package:label_storemax/labelconfig.dart';
import 'package:label_storemax/models/cart.dart';
import 'package:label_storemax/models/cart_line_item.dart';
import 'package:label_storemax/widgets/app_loader.dart';
import 'package:label_storemax/widgets/buttons.dart';
import 'package:label_storemax/widgets/cart_icon.dart';
import 'package:woosignal/models/response/product_variation.dart' as WS;
import 'package:woosignal/models/response/products.dart' as WS;
import 'package:woosignal/models/response/products.dart' as WSProduct;
import 'package:flutter_swiper/flutter_swiper.dart';
import 'package:label_storemax/widgets/woosignal_ui.dart';
import 'package:cached_network_image/cached_network_image.dart';
class ProductDetailPage extends StatefulWidget {
final WS.Product product;
final WSProduct.Product product;
const ProductDetailPage({Key key, @required this.product}) : super(key: key);
@override
@ -34,7 +35,7 @@ class _ProductDetailState extends State<ProductDetailPage> {
_ProductDetailState(this._product);
bool _isLoading;
WS.Product _product;
WSProduct.Product _product;
int _quantityIndicator = 1;
List<WS.ProductVariation> _productVariations = [];
@ -103,9 +104,8 @@ class _ProductDetailState extends State<ProductDetailPage> {
void _modalBottomSheetOptionsForAttribute(int attributeIndex) {
wsModalBottom(
context,
title: trans(context, "Select a") +
" " +
_product.attributes[attributeIndex].name,
title:
"${trans(context, "Select a")} ${_product.attributes[attributeIndex].name}",
bodyWidget: ListView.separated(
itemCount: _product.attributes[attributeIndex].options.length,
separatorBuilder: (BuildContext context, int index) => Divider(),
@ -164,9 +164,8 @@ class _ProductDetailState extends State<ProductDetailPage> {
_tmpAttributeObj.containsKey(index))
? Text(_tmpAttributeObj[index]["value"],
style: Theme.of(context).primaryTextTheme.bodyText1)
: Text(trans(context, "Select a") +
" " +
_product.attributes[index].name),
: Text(
"${trans(context, "Select a")} ${_product.attributes[index].name}"),
trailing: (_tmpAttributeObj.isNotEmpty &&
_tmpAttributeObj.containsKey(index))
? Icon(Icons.check, color: Colors.blueAccent)
@ -212,7 +211,8 @@ class _ProductDetailState extends State<ProductDetailPage> {
return;
}
if (findProductVariation() == null) {
WS.ProductVariation productVariation = findProductVariation();
if (productVariation == null) {
showEdgeAlertWith(context,
title: trans(context, "Oops"),
desc: trans(context, "Product variation does not exist"),
@ -220,39 +220,39 @@ class _ProductDetailState extends State<ProductDetailPage> {
return;
}
if (findProductVariation() != null) {
if (findProductVariation().stockStatus != "instock") {
if (productVariation.stockStatus != "instock") {
showEdgeAlertWith(context,
title: trans(context, "Sorry"),
desc: trans(context, "This item is not in stock"),
style: EdgeAlertStyle.WARNING);
return;
}
}
List<String> options = [];
_tmpAttributeObj.forEach((k, v) {
options.add(v["name"] + ": " + v["value"]);
options.add("${v["name"]}: ${v["value"]}");
});
CartLineItem cartLineItem = CartLineItem(
name: _product.name,
productId: _product.id,
variationId: findProductVariation().id,
variationId: productVariation.id,
quantity: 1,
taxStatus: findProductVariation().taxStatus,
shippingClassId:
findProductVariation().shippingClassId.toString(),
subtotal: findProductVariation().price,
stockQuantity: findProductVariation().stockQuantity,
isManagedStock: findProductVariation().manageStock,
taxClass: findProductVariation().taxClass,
imageSrc: (findProductVariation().image != null
? findProductVariation().image.src
taxStatus: productVariation.taxStatus,
shippingClassId: productVariation.shippingClassId.toString(),
subtotal: productVariation.price,
stockQuantity: productVariation.stockQuantity,
isManagedStock: productVariation.manageStock,
taxClass: productVariation.taxClass,
imageSrc: (productVariation.image != null
? productVariation.image.src
: _product.images.length == 0
? app_product_placeholder_image
: _product.images.first.src),
shippingIsTaxable: _product.shippingTaxable,
variationOptions: options.join(", "),
total: findProductVariation().price);
total: productVariation.price,
);
_itemAddToCart(cartLineItem: cartLineItem);
Navigator.of(context).pop();
@ -303,7 +303,9 @@ class _ProductDetailState extends State<ProductDetailPage> {
child: new Swiper(
itemBuilder: (BuildContext context, int index) {
return CachedNetworkImage(
imageUrl: _product.images[index].src,
imageUrl: _product.images.length == 0
? app_product_placeholder_image
: _product.images[index].src,
placeholder: (context, url) => Center(
child: new CircularProgressIndicator(
strokeWidth: 2,
@ -315,7 +317,9 @@ class _ProductDetailState extends State<ProductDetailPage> {
fit: BoxFit.contain,
);
},
itemCount: _product.images.length,
itemCount: _product.images.length == 0
? 1
: _product.images.length,
viewportFraction: 0.85,
scale: 0.9,
onTap: _productImageTapped,
@ -542,7 +546,9 @@ class _ProductDetailState extends State<ProductDetailPage> {
isManagedStock: _product.manageStock,
stockQuantity: _product.stockQuantity,
shippingIsTaxable: _product.shippingTaxable,
imageSrc: _product.images.first.src,
imageSrc: _product.images.length == 0
? app_product_placeholder_image
: _product.images.first.src,
total: _product.price,
);

View File

@ -14,6 +14,7 @@ import 'package:flutter/material.dart';
import 'package:label_storemax/helpers/tools.dart';
import 'package:flutter_swiper/flutter_swiper.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:label_storemax/labelconfig.dart';
class ProductImageViewerPage extends StatefulWidget {
final int initialIndex;
@ -50,7 +51,9 @@ class _ProductImageViewerPageState extends State<ProductImageViewerPage> {
index: _initialIndex,
itemBuilder: (BuildContext context, int index) {
return CachedNetworkImage(
imageUrl: _arrImageSrc[index],
imageUrl: _arrImageSrc.length == 0
? app_product_placeholder_image
: _arrImageSrc[index],
placeholder: (context, url) =>
new CircularProgressIndicator(
strokeWidth: 2,
@ -60,7 +63,7 @@ class _ProductImageViewerPageState extends State<ProductImageViewerPage> {
fit: BoxFit.contain,
);
},
itemCount: _arrImageSrc.length,
itemCount: _arrImageSrc.length == 0 ? 1 : _arrImageSrc.length,
viewportFraction: 0.9,
scale: 0.95,
),

View File

@ -229,7 +229,7 @@ Widget wsCardProductItem(BuildContext context,
CachedNetworkImage(
imageUrl: (product.images.length > 0
? product.images.first.src
: ""),
: app_product_placeholder_image),
placeholder: (context, url) => Container(
child: Center(
child: CircularProgressIndicator(),
@ -541,7 +541,9 @@ Widget wsCardCartItem(BuildContext context,
children: <Widget>[
Flexible(
child: CachedNetworkImage(
imageUrl: cartLineItem.imageSrc,
imageUrl: cartLineItem.imageSrc == ""
? app_product_placeholder_image
: cartLineItem.imageSrc,
width: 100,
height: 100,
fit: BoxFit.contain,

View File

@ -49,7 +49,7 @@ packages:
name: cached_network_image
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.1"
version: "2.5.0"
characters:
dependency: transitive
description:
@ -182,7 +182,7 @@ packages:
name: flare_flutter
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.3"
version: "2.0.6"
flutter:
dependency: "direct main"
description: flutter
@ -208,7 +208,7 @@ packages:
name: flutter_cache_manager
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.1.0"
flutter_launcher_icons:
dependency: "direct main"
description:
@ -248,7 +248,7 @@ packages:
name: flutter_staggered_grid_view
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.2"
version: "0.3.3"
flutter_swiper:
dependency: "direct main"
description:
@ -267,7 +267,7 @@ packages:
name: flutter_web_browser
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.0"
version: "0.13.1"
flutter_web_plugins:
dependency: transitive
description: flutter
@ -286,7 +286,7 @@ packages:
name: html
url: "https://pub.dartlang.org"
source: hosted
version: "0.14.0+3"
version: "0.14.0+4"
http:
dependency: transitive
description:
@ -307,7 +307,7 @@ packages:
name: image
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.12"
version: "2.1.19"
intl:
dependency: "direct main"
description:
@ -349,14 +349,14 @@ packages:
name: package_info
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.3"
version: "0.4.3+2"
page_transition:
dependency: "direct main"
description:
name: page_transition
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.7+2"
version: "1.1.7+3"
path:
dependency: transitive
description:
@ -412,7 +412,7 @@ packages:
name: petitparser
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.0"
version: "3.1.0"
platform:
dependency: transitive
description:
@ -447,14 +447,14 @@ packages:
name: pull_to_refresh
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.2"
version: "1.6.3"
razorpay_flutter:
dependency: "direct main"
description:
name: razorpay_flutter
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.2"
version: "1.2.3"
rxdart:
dependency: transitive
description:
@ -468,7 +468,7 @@ packages:
name: shared_preferences
url: "https://pub.dartlang.org"
source: hosted
version: "0.5.12+2"
version: "0.5.12+4"
shared_preferences_linux:
dependency: transitive
description:
@ -543,7 +543,7 @@ packages:
name: status_alert
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.2"
version: "0.1.3"
stream_channel:
dependency: transitive
description:
@ -599,7 +599,7 @@ packages:
name: url_launcher
url: "https://pub.dartlang.org"
source: hosted
version: "5.7.7"
version: "5.7.10"
url_launcher_linux:
dependency: transitive
description:
@ -662,14 +662,14 @@ packages:
name: woosignal
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
version: "1.3.1"
woosignal_stripe:
dependency: "direct main"
description:
name: woosignal_stripe
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.6"
version: "0.1.0"
wp_json_api:
dependency: "direct main"
description:
@ -690,7 +690,7 @@ packages:
name: xml
url: "https://pub.dartlang.org"
source: hosted
version: "3.6.1"
version: "4.5.1"
yaml:
dependency: transitive
description:
@ -699,5 +699,5 @@ packages:
source: hosted
version: "2.2.1"
sdks:
dart: ">=2.10.0-110 <2.11.0"
dart: ">=2.10.0 <2.11.0"
flutter: ">=1.22.0 <2.0.0"

View File

@ -1,7 +1,7 @@
# Official WooSignal App Template for WooCommerce
# Label StoreMax
# Version 2.4.1
# Version 2.5.0
# Homepage: https://woosignal.com
# Author: Anthony Gordon <agordon@woosignal.com>
# Documentation: https://woosignal.com/docs/app/ios/label-storemax
@ -24,30 +24,30 @@ environment:
dependencies:
woosignal: ^1.3.1
woosignal_stripe: ^0.0.6
razorpay_flutter: ^1.2.2
woosignal_stripe: ^0.1.0
razorpay_flutter: ^1.2.3
wp_json_api: ^2.0.0
shared_preferences: ^0.5.12
cached_network_image: ^2.4.1
page_transition: ^1.1.7+2
package_info: ^0.4.3
url_launcher: ^5.7.5
shared_preferences: ^0.5.12+4
cached_network_image: ^2.5.0
page_transition: ^1.1.7+3
package_info: ^0.4.3+2
url_launcher: ^5.7.10
flutter_money_formatter: ^0.8.3
platform_alert_dialog: ^1.0.0+2
flutter_web_browser: ^0.12.0
pull_to_refresh: ^1.6.2
flutter_web_browser: ^0.13.1
pull_to_refresh: ^1.6.3
intl: ^0.16.1
flutter_swiper: ^1.1.6
edge_alert: ^0.0.1
bubble_tab_indicator: ^0.1.4
status_alert: ^0.1.2
status_alert: ^0.1.3
math_expressions: ^2.0.1
hexcolor: ^1.0.6
flutter_spinkit: ^4.1.2+1
flutter_launcher_icons: ^0.8.1
auto_size_text: ^2.1.0
html: ^0.14.0+3
flutter_staggered_grid_view: ^0.3.2
html: ^0.14.0+4
flutter_staggered_grid_view: ^0.3.3
flutter:
sdk: flutter

View File

@ -4,7 +4,7 @@
# WooCommerce App: Label StoreMax
### Label StoreMax - v2.4.1
### Label StoreMax - v2.5.0
[Official WooSignal WooCommerce App](https://woosignal.com)