initial commit to gitea
This commit is contained in:
BIN
android/app/src/main/res/mipmap-hdpi/launcher_icon.png
Normal file
BIN
android/app/src/main/res/mipmap-hdpi/launcher_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
BIN
android/app/src/main/res/mipmap-mdpi/launcher_icon.png
Normal file
BIN
android/app/src/main/res/mipmap-mdpi/launcher_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
android/app/src/main/res/mipmap-xhdpi/launcher_icon.png
Normal file
BIN
android/app/src/main/res/mipmap-xhdpi/launcher_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.6 KiB |
BIN
android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png
Normal file
BIN
android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
BIN
android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png
Normal file
BIN
android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.4 KiB |
@@ -3,6 +3,8 @@ class Constants {
|
||||
|
||||
static const bool ENABLE_NATIVE_PAY = false;
|
||||
|
||||
static const bool isPreview = false;
|
||||
|
||||
static const int FONT_GOOGLE = 0xe800;
|
||||
static const int FONT_ALEXA = 0xe801;
|
||||
static const int FONT_APPLE = 0xe802;
|
||||
@@ -36,7 +38,7 @@ class Constants {
|
||||
static const int BLOG_PER_PAGE_MOBILE = 20;
|
||||
static const int BLOG_PER_PAGE_DESKTOP = 30;
|
||||
|
||||
static const double BREADCRUMB_HEIGHT = 38;
|
||||
static const double BREADCRUMB_HEIGHT = 42;
|
||||
|
||||
static const int HOT_SALE_ID = -1;
|
||||
static const int FEATURED_PRODUCT_ID = -2;
|
||||
@@ -64,4 +66,9 @@ class Constants {
|
||||
static const String PAYMENT_STATUS_UNPAID = 'UNPAID';
|
||||
static const String PAYMENT_STATUS_PAID = 'PAID';
|
||||
static const String PAYMENT_STATUS_PARTIALPAID = 'PARTIALPAID';
|
||||
|
||||
static const double PRODUCT_ITEM_HEIGHT_H = 180;
|
||||
static const double PRODUCT_ITEM_HEIGHT_V = 278;
|
||||
|
||||
static const String WEB_MINISTORE_SERVICE = 'web-ministore-service';
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import '../models/category_products.dart';
|
||||
|
||||
import '../models/business.dart';
|
||||
import '../models/comment.dart';
|
||||
@@ -120,4 +121,24 @@ class GetCurrentPositionSuccess {
|
||||
class GetCurrentPositionFailed {
|
||||
Exception exception;
|
||||
GetCurrentPositionFailed(this.exception);
|
||||
}
|
||||
|
||||
class ShopPageScrollUpdated {
|
||||
double offset;
|
||||
ShopPageScrollUpdated(this.offset);
|
||||
}
|
||||
|
||||
class GetCategoryProducts {
|
||||
dynamic data;
|
||||
GetCategoryProducts(this.data);
|
||||
}
|
||||
|
||||
class MoreCategoryProducts {
|
||||
List<CategoryProducts> data;
|
||||
MoreCategoryProducts(this.data);
|
||||
}
|
||||
|
||||
class CategoryChangeEvent {
|
||||
int categoryId;
|
||||
CategoryChangeEvent(this.categoryId);
|
||||
}
|
||||
@@ -35,53 +35,57 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
|
||||
static m7(discount) => "-\$${discount}";
|
||||
|
||||
static m8(oss) => "Download at ${oss}";
|
||||
static m8(domain) => "${domain} (available)";
|
||||
|
||||
static m9(expirationDate) => "Expires on ${expirationDate}";
|
||||
static m9(domain) => "${domain} (unavailable)";
|
||||
|
||||
static m10(mon, yer) => "Exp: ${mon}/${yer}";
|
||||
static m10(oss) => "Download at ${oss}";
|
||||
|
||||
static m11(name, rate) => "${name}(${rate}%)";
|
||||
static m11(expirationDate) => "Expires on ${expirationDate}";
|
||||
|
||||
static m12(num) => "${num} follow-ups";
|
||||
static m12(mon, yer) => "Exp: ${mon}/${yer}";
|
||||
|
||||
static m13(second) => "Retry after ${second}s";
|
||||
static m13(name, rate) => "${name}(${rate}%)";
|
||||
|
||||
static m14(hours) => "${Intl.plural(hours, one: '1 hr', other: '${hours} hrs')}";
|
||||
static m14(num) => "${num} follow-ups";
|
||||
|
||||
static m15(minamount) => "\$${minamount}+";
|
||||
static m15(second) => "Retry after ${second}s";
|
||||
|
||||
static m16(shipfee) => "Delivery \$${shipfee}+";
|
||||
static m16(hours) => "${Intl.plural(hours, one: '1 hr', other: '${hours} hrs')}";
|
||||
|
||||
static m17(minutes) => "${Intl.plural(minutes, one: '1 min', other: '${minutes} mins')}";
|
||||
static m17(minamount) => "\$${minamount}+";
|
||||
|
||||
static m18(minprice) => "${minprice} more";
|
||||
static m18(shipfee) => "Delivery \$${shipfee}+";
|
||||
|
||||
static m19(amount) => "Pay \$${amount} now";
|
||||
static m19(minutes) => "${Intl.plural(minutes, one: '1 min', other: '${minutes} mins')}";
|
||||
|
||||
static m20(method) => "Pay with ${method}";
|
||||
static m20(minprice) => "${minprice} more";
|
||||
|
||||
static m21(mobile) => "Payment verification code has been sent to your mobile phone ${mobile}. Please enter the verification code below.";
|
||||
static m21(amount) => "Pay \$${amount} now";
|
||||
|
||||
static m22(discount) => "${discount}%off";
|
||||
static m22(method) => "Pay with ${method}";
|
||||
|
||||
static m23(amount, discount) => "-\$${amount}(${discount}%off)";
|
||||
static m23(p1, p2) => "Payment verification code has been sent to your ${p1} ${p2}. Please enter the verification code below.";
|
||||
|
||||
static m24(optionName) => "Please choice ${optionName}.";
|
||||
static m24(discount) => "${discount}%off";
|
||||
|
||||
static m25(sold_qty) => " ${sold_qty} sold/mo";
|
||||
static m25(amount, discount) => "-\$${amount}(${discount}%off)";
|
||||
|
||||
static m26(subtotal) => "Subtotal: ${subtotal}";
|
||||
static m26(optionName) => "Please choice ${optionName}.";
|
||||
|
||||
static m27(num) => "Table#: ${num}";
|
||||
static m27(sold_qty) => " ${sold_qty} sold/mo";
|
||||
|
||||
static m28(num) => "Ticket #${num}";
|
||||
static m28(subtotal) => "Subtotal: ${subtotal}";
|
||||
|
||||
static m29(time) => "Today ${time}";
|
||||
static m29(num) => "Table#: ${num}";
|
||||
|
||||
static m30(time) => "Tomorrow ${time}";
|
||||
static m30(num) => "Ticket #${num}";
|
||||
|
||||
static m31(weight) => "Weight: ${weight}";
|
||||
static m31(time) => "Today ${time}";
|
||||
|
||||
static m32(time) => "Tomorrow ${time}";
|
||||
|
||||
static m33(weight) => "Weight: ${weight}";
|
||||
|
||||
final messages = _notInlinedMessages(_notInlinedMessages);
|
||||
static _notInlinedMessages(_) => <String, Function> {
|
||||
@@ -130,6 +134,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"change_nickname" : MessageLookupByLibrary.simpleMessage("Change nickname"),
|
||||
"change_password" : MessageLookupByLibrary.simpleMessage("Change password"),
|
||||
"change_password_desc" : MessageLookupByLibrary.simpleMessage("Please enter the old password and your desired new password."),
|
||||
"check_domain_name" : MessageLookupByLibrary.simpleMessage("Check availability"),
|
||||
"check_option_is_optional" : MessageLookupByLibrary.simpleMessage("Optional. You can tap Next without selection."),
|
||||
"check_option_is_required" : MessageLookupByLibrary.simpleMessage("Option is required. Select at lease an option then tap Next."),
|
||||
"check_option_select_token" : m3,
|
||||
@@ -152,6 +157,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"contact_us" : MessageLookupByLibrary.simpleMessage("Contact us"),
|
||||
"copy" : MessageLookupByLibrary.simpleMessage("Copy"),
|
||||
"coupons" : MessageLookupByLibrary.simpleMessage("Coupons"),
|
||||
"create_a_online_store" : MessageLookupByLibrary.simpleMessage("Open an online store"),
|
||||
"credit_card" : MessageLookupByLibrary.simpleMessage("Credit card"),
|
||||
"credit_coupon" : MessageLookupByLibrary.simpleMessage("Credit/Coupon"),
|
||||
"credit_debit_card" : MessageLookupByLibrary.simpleMessage("Credit or debit card"),
|
||||
@@ -174,9 +180,13 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"discount_amount_token" : m7,
|
||||
"document_langage" : MessageLookupByLibrary.simpleMessage("Document language"),
|
||||
"document_type" : MessageLookupByLibrary.simpleMessage("Document type"),
|
||||
"domain_available_token" : m8,
|
||||
"domain_name" : MessageLookupByLibrary.simpleMessage("Domain name"),
|
||||
"domain_unavailable_token" : m9,
|
||||
"domains_separated_comma" : MessageLookupByLibrary.simpleMessage("Domains separated by comma"),
|
||||
"dont_use" : MessageLookupByLibrary.simpleMessage("Do not redeem"),
|
||||
"download" : MessageLookupByLibrary.simpleMessage("Download"),
|
||||
"download_with_token" : m8,
|
||||
"download_with_token" : m10,
|
||||
"downloads" : MessageLookupByLibrary.simpleMessage("Downloads"),
|
||||
"edit_address" : MessageLookupByLibrary.simpleMessage("Edit address"),
|
||||
"email" : MessageLookupByLibrary.simpleMessage("Email"),
|
||||
@@ -190,22 +200,24 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"english" : MessageLookupByLibrary.simpleMessage("English"),
|
||||
"enter_coupon_code" : MessageLookupByLibrary.simpleMessage("Enter coupon code"),
|
||||
"enter_delivery_address" : MessageLookupByLibrary.simpleMessage("Enter delivery address"),
|
||||
"enter_desired_domain" : MessageLookupByLibrary.simpleMessage("Your desired domain name"),
|
||||
"enter_keyword" : MessageLookupByLibrary.simpleMessage("Enter keyword"),
|
||||
"enter_mobile_or_email" : MessageLookupByLibrary.simpleMessage("Enter mobile or email"),
|
||||
"enter_new_nickname" : MessageLookupByLibrary.simpleMessage("Enter new nickname"),
|
||||
"enter_product_keyword" : MessageLookupByLibrary.simpleMessage("Enter product keyword"),
|
||||
"error" : MessageLookupByLibrary.simpleMessage("Error"),
|
||||
"error_read_file" : MessageLookupByLibrary.simpleMessage("Error occurred while reading the file."),
|
||||
"expiration_date" : MessageLookupByLibrary.simpleMessage("Expiration date"),
|
||||
"expiration_date_token" : m9,
|
||||
"expire_token" : m10,
|
||||
"expiration_date_token" : m11,
|
||||
"expire_token" : m12,
|
||||
"expired_at" : MessageLookupByLibrary.simpleMessage("Expired at"),
|
||||
"extra_fee_token" : m11,
|
||||
"extra_fee_token" : m13,
|
||||
"fax" : MessageLookupByLibrary.simpleMessage("Fax"),
|
||||
"feature_not_available_web" : MessageLookupByLibrary.simpleMessage("This feature is not available on the web. Please install the App version."),
|
||||
"featured_product" : MessageLookupByLibrary.simpleMessage("Featured"),
|
||||
"finish" : MessageLookupByLibrary.simpleMessage("Finish"),
|
||||
"follow_ups" : MessageLookupByLibrary.simpleMessage("Follow ups"),
|
||||
"followups_token" : m12,
|
||||
"followups_token" : m14,
|
||||
"forgot_password" : MessageLookupByLibrary.simpleMessage("Forgot password"),
|
||||
"forgot_password_description" : MessageLookupByLibrary.simpleMessage("Enter the Email or mobile number you used when registering, and then click the \'Get code\' button to get the validation code."),
|
||||
"forgot_password_question" : MessageLookupByLibrary.simpleMessage("Forgot password?"),
|
||||
@@ -217,7 +229,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"general_coupon" : MessageLookupByLibrary.simpleMessage("General coupon"),
|
||||
"get_code" : MessageLookupByLibrary.simpleMessage("Get code"),
|
||||
"get_code_again" : MessageLookupByLibrary.simpleMessage("Get code again"),
|
||||
"get_code_token" : m13,
|
||||
"get_code_token" : m15,
|
||||
"get_coupon" : MessageLookupByLibrary.simpleMessage("Get coupon"),
|
||||
"get_picture" : MessageLookupByLibrary.simpleMessage("Get picture"),
|
||||
"get_picture_from" : MessageLookupByLibrary.simpleMessage("Get picture from..."),
|
||||
@@ -226,7 +238,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"group_number_can_be_found" : MessageLookupByLibrary.simpleMessage("Group number can be found..."),
|
||||
"home" : MessageLookupByLibrary.simpleMessage("Home"),
|
||||
"hot_sale" : MessageLookupByLibrary.simpleMessage("Hot sale"),
|
||||
"hour_token" : m14,
|
||||
"hour_token" : m16,
|
||||
"igoshow" : MessageLookupByLibrary.simpleMessage("iGoShow"),
|
||||
"includes" : MessageLookupByLibrary.simpleMessage("Includes"),
|
||||
"information" : MessageLookupByLibrary.simpleMessage("Information"),
|
||||
@@ -245,10 +257,11 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"logout" : MessageLookupByLibrary.simpleMessage("Logout"),
|
||||
"main_content_1" : MessageLookupByLibrary.simpleMessage("Since 1999, we have been committed to developing a complete and powerful sales system, helping thousands of small businesses handle sales smoothly. Currently we have two main products."),
|
||||
"me" : MessageLookupByLibrary.simpleMessage("Me"),
|
||||
"min_order_amount_token" : m15,
|
||||
"min_shipping_fee" : m16,
|
||||
"min_order_amount_token" : m17,
|
||||
"min_shipping_fee" : m18,
|
||||
"minipos" : MessageLookupByLibrary.simpleMessage("MiniPOS"),
|
||||
"minute_token" : m17,
|
||||
"minute_token" : m19,
|
||||
"mobile" : MessageLookupByLibrary.simpleMessage("mobile"),
|
||||
"mobile_email_username" : MessageLookupByLibrary.simpleMessage("Mobile, Email or MiniOffice username"),
|
||||
"mobile_is_required" : MessageLookupByLibrary.simpleMessage("Mobile is required"),
|
||||
"mobile_number" : MessageLookupByLibrary.simpleMessage("Mobile number"),
|
||||
@@ -293,6 +306,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"ok" : MessageLookupByLibrary.simpleMessage("OK"),
|
||||
"old_password" : MessageLookupByLibrary.simpleMessage("Old password"),
|
||||
"online_payment" : MessageLookupByLibrary.simpleMessage("Online payment"),
|
||||
"open_online_store" : MessageLookupByLibrary.simpleMessage("Open an online store"),
|
||||
"optional_information" : MessageLookupByLibrary.simpleMessage("Optional Info."),
|
||||
"order_acceipt" : MessageLookupByLibrary.simpleMessage("Accept"),
|
||||
"order_again" : MessageLookupByLibrary.simpleMessage("Order again"),
|
||||
@@ -302,7 +316,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"order_detail" : MessageLookupByLibrary.simpleMessage("Order detail"),
|
||||
"order_fulfillment" : MessageLookupByLibrary.simpleMessage("Order fulfillment"),
|
||||
"order_info" : MessageLookupByLibrary.simpleMessage("Order info."),
|
||||
"order_more" : m18,
|
||||
"order_more" : m20,
|
||||
"order_number" : MessageLookupByLibrary.simpleMessage("Order No."),
|
||||
"order_number_copied_to_clipboard" : MessageLookupByLibrary.simpleMessage("Order number copied to clipboard"),
|
||||
"order_processing" : MessageLookupByLibrary.simpleMessage("Processing"),
|
||||
@@ -317,30 +331,31 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"password_is_required" : MessageLookupByLibrary.simpleMessage("Password is required."),
|
||||
"pay" : MessageLookupByLibrary.simpleMessage("Pay"),
|
||||
"pay_after_meal" : MessageLookupByLibrary.simpleMessage("Pay after meal"),
|
||||
"pay_amount_token" : m19,
|
||||
"pay_amount_token" : m21,
|
||||
"pay_later" : MessageLookupByLibrary.simpleMessage("Pay later"),
|
||||
"pay_now" : MessageLookupByLibrary.simpleMessage("Pay now"),
|
||||
"pay_on_deliery" : MessageLookupByLibrary.simpleMessage("Pay on delivery"),
|
||||
"pay_on_deliery_pickup" : MessageLookupByLibrary.simpleMessage("Pay on delivery or pickup"),
|
||||
"pay_with" : MessageLookupByLibrary.simpleMessage("Pay with"),
|
||||
"pay_with_existing_cards" : MessageLookupByLibrary.simpleMessage("Pay with existing cards"),
|
||||
"pay_with_token" : m20,
|
||||
"pay_with_token" : m22,
|
||||
"payment_amount" : MessageLookupByLibrary.simpleMessage("Payment amount"),
|
||||
"payment_method" : MessageLookupByLibrary.simpleMessage("Payment method"),
|
||||
"payment_method_not_set" : MessageLookupByLibrary.simpleMessage("No payment method specified. Please pay on delivery or pickup."),
|
||||
"payment_status" : MessageLookupByLibrary.simpleMessage("Payment status"),
|
||||
"payment_verification" : MessageLookupByLibrary.simpleMessage("Payment verification"),
|
||||
"payment_verification_sent" : m21,
|
||||
"payment_verification_sent" : m23,
|
||||
"paypal" : MessageLookupByLibrary.simpleMessage("Paypal"),
|
||||
"pending" : MessageLookupByLibrary.simpleMessage("Pending"),
|
||||
"percent_discount" : MessageLookupByLibrary.simpleMessage("%OFF"),
|
||||
"percentage_discount_token" : m22,
|
||||
"percentage_discount_token2" : m23,
|
||||
"percentage_discount_token" : m24,
|
||||
"percentage_discount_token2" : m25,
|
||||
"pick_a_coupon" : MessageLookupByLibrary.simpleMessage("Pick a coupon"),
|
||||
"pickup" : MessageLookupByLibrary.simpleMessage("Pickup"),
|
||||
"pickup_address" : MessageLookupByLibrary.simpleMessage("Pickup address"),
|
||||
"pickup_at" : MessageLookupByLibrary.simpleMessage("Please pickup at"),
|
||||
"pickup_discount" : MessageLookupByLibrary.simpleMessage("Pickup discount"),
|
||||
"place_order_now" : MessageLookupByLibrary.simpleMessage("Place order now"),
|
||||
"please_enter_coupon_code" : MessageLookupByLibrary.simpleMessage("Please enter a coupon code."),
|
||||
"please_enter_group_number" : MessageLookupByLibrary.simpleMessage("Please enter your group number."),
|
||||
"please_login" : MessageLookupByLibrary.simpleMessage("Please login"),
|
||||
@@ -364,7 +379,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"quick_input" : MessageLookupByLibrary.simpleMessage("Quick input"),
|
||||
"radio_option_is_optional" : MessageLookupByLibrary.simpleMessage("Optional. You can tap Next without selection."),
|
||||
"radio_option_is_required" : MessageLookupByLibrary.simpleMessage("Option is required. Select an option then tap Next."),
|
||||
"radio_option_select_token" : m24,
|
||||
"radio_option_select_token" : m26,
|
||||
"recalculating" : MessageLookupByLibrary.simpleMessage("Recalculating..."),
|
||||
"red_coupon" : MessageLookupByLibrary.simpleMessage("Coupon"),
|
||||
"redeem_coupon" : MessageLookupByLibrary.simpleMessage("Redeem"),
|
||||
@@ -372,6 +387,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"registration" : MessageLookupByLibrary.simpleMessage("Registration"),
|
||||
"release_to_load_more" : MessageLookupByLibrary.simpleMessage("Release to load more"),
|
||||
"renew_license" : MessageLookupByLibrary.simpleMessage("Renew license"),
|
||||
"renew_service_now" : MessageLookupByLibrary.simpleMessage("Renew service now"),
|
||||
"renewal_fee" : MessageLookupByLibrary.simpleMessage("Renewal fee"),
|
||||
"reply" : MessageLookupByLibrary.simpleMessage("Reply"),
|
||||
"reset_password" : MessageLookupByLibrary.simpleMessage("Reset password"),
|
||||
@@ -384,12 +400,14 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"saturday" : MessageLookupByLibrary.simpleMessage("Saturday"),
|
||||
"save" : MessageLookupByLibrary.simpleMessage("Save"),
|
||||
"schedule_delivery" : MessageLookupByLibrary.simpleMessage("Schedule delivery"),
|
||||
"search" : MessageLookupByLibrary.simpleMessage("Search"),
|
||||
"search_place" : MessageLookupByLibrary.simpleMessage("Search place"),
|
||||
"search_product" : MessageLookupByLibrary.simpleMessage("Search product"),
|
||||
"search_products" : MessageLookupByLibrary.simpleMessage("Search products"),
|
||||
"select" : MessageLookupByLibrary.simpleMessage("Select"),
|
||||
"select_a_payment_method" : MessageLookupByLibrary.simpleMessage("Select a payment method"),
|
||||
"select_a_plan" : MessageLookupByLibrary.simpleMessage("Select a plan"),
|
||||
"select_a_store" : MessageLookupByLibrary.simpleMessage("Select a store"),
|
||||
"select_canada_post_shipping_rate" : MessageLookupByLibrary.simpleMessage("Please select Canada Post shipping rate."),
|
||||
"select_delivery_time" : MessageLookupByLibrary.simpleMessage("Select delivery time"),
|
||||
"select_document_lanuage" : MessageLookupByLibrary.simpleMessage("Select a language"),
|
||||
@@ -404,7 +422,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"shop" : MessageLookupByLibrary.simpleMessage("Shop"),
|
||||
"show_less" : MessageLookupByLibrary.simpleMessage("Show less"),
|
||||
"show_more" : MessageLookupByLibrary.simpleMessage("Show more"),
|
||||
"sold_per_month_token" : m25,
|
||||
"sold_per_month_token" : m27,
|
||||
"specification" : MessageLookupByLibrary.simpleMessage("Specification"),
|
||||
"store" : MessageLookupByLibrary.simpleMessage("Store"),
|
||||
"store_closed" : MessageLookupByLibrary.simpleMessage("Store closed"),
|
||||
@@ -420,13 +438,13 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"submitting" : MessageLookupByLibrary.simpleMessage("Submitting..."),
|
||||
"submitting_please_wait" : MessageLookupByLibrary.simpleMessage("Submitting, please wait..."),
|
||||
"subtotal" : MessageLookupByLibrary.simpleMessage("Subtotal"),
|
||||
"subtotal_token" : m26,
|
||||
"subtotal_token" : m28,
|
||||
"success" : MessageLookupByLibrary.simpleMessage("Success"),
|
||||
"sun" : MessageLookupByLibrary.simpleMessage("Sun"),
|
||||
"sunday" : MessageLookupByLibrary.simpleMessage("Sunday"),
|
||||
"support" : MessageLookupByLibrary.simpleMessage("Support"),
|
||||
"support_ticket" : MessageLookupByLibrary.simpleMessage("Support ticket"),
|
||||
"table_token" : m27,
|
||||
"table_token" : m29,
|
||||
"tap_back_again_to_exit" : MessageLookupByLibrary.simpleMessage("Tap back again to exit"),
|
||||
"tax" : MessageLookupByLibrary.simpleMessage("Tax"),
|
||||
"thank_you_for_your_comment" : MessageLookupByLibrary.simpleMessage("Thank you for your comment."),
|
||||
@@ -439,12 +457,12 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"thu" : MessageLookupByLibrary.simpleMessage("Thu"),
|
||||
"thursday" : MessageLookupByLibrary.simpleMessage("Thursday"),
|
||||
"ticket_created_success" : MessageLookupByLibrary.simpleMessage("Ticket has been created successfully."),
|
||||
"ticket_number_token" : m28,
|
||||
"ticket_number_token" : m30,
|
||||
"today" : MessageLookupByLibrary.simpleMessage("Today"),
|
||||
"today_with_time" : m29,
|
||||
"today_with_time" : m31,
|
||||
"toll_free" : MessageLookupByLibrary.simpleMessage("Toll free: "),
|
||||
"tomorrow" : MessageLookupByLibrary.simpleMessage("Tomorrow"),
|
||||
"tomorrow_with_time" : m30,
|
||||
"tomorrow_with_time" : m32,
|
||||
"total" : MessageLookupByLibrary.simpleMessage("Total"),
|
||||
"tue" : MessageLookupByLibrary.simpleMessage("Tue"),
|
||||
"tuesday" : MessageLookupByLibrary.simpleMessage("Tuesday"),
|
||||
@@ -469,7 +487,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"wechatpay" : MessageLookupByLibrary.simpleMessage("Wechat pay"),
|
||||
"wed" : MessageLookupByLibrary.simpleMessage("Wed"),
|
||||
"wednesday" : MessageLookupByLibrary.simpleMessage("Wednesday"),
|
||||
"weight_token" : m31,
|
||||
"weight_token" : m33,
|
||||
"wiki" : MessageLookupByLibrary.simpleMessage("Wiki"),
|
||||
"wrong_payment_verification_code" : MessageLookupByLibrary.simpleMessage("Wrong payment verification code. Please check and enter again."),
|
||||
"yes" : MessageLookupByLibrary.simpleMessage("Yes"),
|
||||
|
||||
@@ -35,53 +35,57 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
|
||||
static m7(discount) => "-\$${discount}";
|
||||
|
||||
static m8(oss) => "在${oss}下载";
|
||||
static m8(domain) => "${domain} (可用)";
|
||||
|
||||
static m9(expirationDate) => "${expirationDate}到期";
|
||||
static m9(domain) => "${domain} (不可用)";
|
||||
|
||||
static m10(mon, yer) => "到期:${mon}/${yer}";
|
||||
static m10(oss) => "在${oss}下载";
|
||||
|
||||
static m11(name, rate) => "${name}(${rate}%)";
|
||||
static m11(expirationDate) => "${expirationDate}到期";
|
||||
|
||||
static m12(num) => "${num}条回复";
|
||||
static m12(mon, yer) => "到期:${mon}/${yer}";
|
||||
|
||||
static m13(second) => "${second}秒后重试";
|
||||
static m13(name, rate) => "${name}(${rate}%)";
|
||||
|
||||
static m14(hours) => "${Intl.plural(hours, one: '1小时', other: '${hours}小时')}";
|
||||
static m14(num) => "${num}条回复";
|
||||
|
||||
static m15(minamount) => "\$${minamount}起送";
|
||||
static m15(second) => "${second}秒后重试";
|
||||
|
||||
static m16(shipfee) => "配送费\$${shipfee}起";
|
||||
static m16(hours) => "${Intl.plural(hours, one: '1小时', other: '${hours}小时')}";
|
||||
|
||||
static m17(minutes) => "${Intl.plural(minutes, one: '1分钟', other: '${minutes}分钟')}";
|
||||
static m17(minamount) => "\$${minamount}起送";
|
||||
|
||||
static m18(minprice) => "还差${minprice}起送";
|
||||
static m18(shipfee) => "配送费\$${shipfee}起";
|
||||
|
||||
static m19(amount) => "马上付款 \$${amount}";
|
||||
static m19(minutes) => "${Intl.plural(minutes, one: '1分钟', other: '${minutes}分钟')}";
|
||||
|
||||
static m20(method) => "使用${method}付款";
|
||||
static m20(minprice) => "还差${minprice}起送";
|
||||
|
||||
static m21(mobile) => "付款码已经发送到您的手机${mobile}。请在下面输入付款码。";
|
||||
static m21(amount) => "马上付款 \$${amount}";
|
||||
|
||||
static m22(discount) => "${discount}%折扣";
|
||||
static m22(method) => "使用${method}付款";
|
||||
|
||||
static m23(amount, discount) => "-\$${amount}(${discount}%折扣)";
|
||||
static m23(p1, p2) => "付款码已经发送到您的${p1}${p2}。请在下面输入付款码。";
|
||||
|
||||
static m24(optionName) => "请选择${optionName}";
|
||||
static m24(discount) => "${discount}%折扣";
|
||||
|
||||
static m25(sold_qty) => " 月售${sold_qty}单";
|
||||
static m25(amount, discount) => "-\$${amount}(${discount}%折扣)";
|
||||
|
||||
static m26(subtotal) => "小计:${subtotal}";
|
||||
static m26(optionName) => "请选择${optionName}";
|
||||
|
||||
static m27(num) => "桌号:${num}";
|
||||
static m27(sold_qty) => " 月售${sold_qty}单";
|
||||
|
||||
static m28(num) => "票号 #${num}";
|
||||
static m28(subtotal) => "小计:${subtotal}";
|
||||
|
||||
static m29(time) => "今天${time}";
|
||||
static m29(num) => "桌号:${num}";
|
||||
|
||||
static m30(time) => "明天${time}";
|
||||
static m30(num) => "票号 #${num}";
|
||||
|
||||
static m31(weight) => "重量:${weight}";
|
||||
static m31(time) => "今天${time}";
|
||||
|
||||
static m32(time) => "明天${time}";
|
||||
|
||||
static m33(weight) => "重量:${weight}";
|
||||
|
||||
final messages = _notInlinedMessages(_notInlinedMessages);
|
||||
static _notInlinedMessages(_) => <String, Function> {
|
||||
@@ -129,6 +133,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"change_nickname" : MessageLookupByLibrary.simpleMessage("修改昵称"),
|
||||
"change_password" : MessageLookupByLibrary.simpleMessage("修改密码"),
|
||||
"change_password_desc" : MessageLookupByLibrary.simpleMessage("请输入旧密码和希望的新密码。"),
|
||||
"check_domain_name" : MessageLookupByLibrary.simpleMessage("检查是否可用"),
|
||||
"check_option_is_optional" : MessageLookupByLibrary.simpleMessage("可选选项。如果不选择可以直接点下一步。"),
|
||||
"check_option_is_required" : MessageLookupByLibrary.simpleMessage("选项必选。选择至少一项再点击下一步。"),
|
||||
"check_option_select_token" : m3,
|
||||
@@ -150,6 +155,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"contact_us" : MessageLookupByLibrary.simpleMessage("联系我们"),
|
||||
"copy" : MessageLookupByLibrary.simpleMessage("复制"),
|
||||
"coupons" : MessageLookupByLibrary.simpleMessage("优惠券"),
|
||||
"create_a_online_store" : MessageLookupByLibrary.simpleMessage("开网店"),
|
||||
"credit_card" : MessageLookupByLibrary.simpleMessage("信用卡"),
|
||||
"credit_coupon" : MessageLookupByLibrary.simpleMessage("红包/抵用券"),
|
||||
"credit_debit_card" : MessageLookupByLibrary.simpleMessage("信用卡或银行卡"),
|
||||
@@ -172,9 +178,13 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"discount_amount_token" : m7,
|
||||
"document_langage" : MessageLookupByLibrary.simpleMessage("文档语言"),
|
||||
"document_type" : MessageLookupByLibrary.simpleMessage("文件类型"),
|
||||
"domain_available_token" : m8,
|
||||
"domain_name" : MessageLookupByLibrary.simpleMessage("域名"),
|
||||
"domain_unavailable_token" : m9,
|
||||
"domains_separated_comma" : MessageLookupByLibrary.simpleMessage("逗号分开多个域名"),
|
||||
"dont_use" : MessageLookupByLibrary.simpleMessage("不使用"),
|
||||
"download" : MessageLookupByLibrary.simpleMessage("下载"),
|
||||
"download_with_token" : m8,
|
||||
"download_with_token" : m10,
|
||||
"downloads" : MessageLookupByLibrary.simpleMessage("下载"),
|
||||
"edit_address" : MessageLookupByLibrary.simpleMessage("修改地址"),
|
||||
"email" : MessageLookupByLibrary.simpleMessage("电子邮箱"),
|
||||
@@ -188,22 +198,24 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"english" : MessageLookupByLibrary.simpleMessage("英文"),
|
||||
"enter_coupon_code" : MessageLookupByLibrary.simpleMessage("输入红包号码"),
|
||||
"enter_delivery_address" : MessageLookupByLibrary.simpleMessage("输入送货地址"),
|
||||
"enter_desired_domain" : MessageLookupByLibrary.simpleMessage("您想要的域名"),
|
||||
"enter_keyword" : MessageLookupByLibrary.simpleMessage("输入关键字"),
|
||||
"enter_mobile_or_email" : MessageLookupByLibrary.simpleMessage("输入手机号码或电子邮箱地址"),
|
||||
"enter_new_nickname" : MessageLookupByLibrary.simpleMessage("输入新昵称"),
|
||||
"enter_product_keyword" : MessageLookupByLibrary.simpleMessage("输入产品关键字"),
|
||||
"error" : MessageLookupByLibrary.simpleMessage("错误"),
|
||||
"error_read_file" : MessageLookupByLibrary.simpleMessage("读取文件过程中出错。"),
|
||||
"expiration_date" : MessageLookupByLibrary.simpleMessage("到期日期"),
|
||||
"expiration_date_token" : m9,
|
||||
"expire_token" : m10,
|
||||
"expiration_date_token" : m11,
|
||||
"expire_token" : m12,
|
||||
"expired_at" : MessageLookupByLibrary.simpleMessage("到期日期"),
|
||||
"extra_fee_token" : m11,
|
||||
"extra_fee_token" : m13,
|
||||
"fax" : MessageLookupByLibrary.simpleMessage("传真"),
|
||||
"feature_not_available_web" : MessageLookupByLibrary.simpleMessage("该功能在网页版上不能用。请下载App版本。"),
|
||||
"featured_product" : MessageLookupByLibrary.simpleMessage("特色产品"),
|
||||
"finish" : MessageLookupByLibrary.simpleMessage("完成"),
|
||||
"follow_ups" : MessageLookupByLibrary.simpleMessage("跟进"),
|
||||
"followups_token" : m12,
|
||||
"followups_token" : m14,
|
||||
"forgot_password" : MessageLookupByLibrary.simpleMessage("忘记密码"),
|
||||
"forgot_password_description" : MessageLookupByLibrary.simpleMessage("输入您注册时用的Email或手机号码,然后点击‘获取验证码’ 按钮。"),
|
||||
"forgot_password_question" : MessageLookupByLibrary.simpleMessage("忘记密码?"),
|
||||
@@ -215,7 +227,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"general_coupon" : MessageLookupByLibrary.simpleMessage("通用优惠券"),
|
||||
"get_code" : MessageLookupByLibrary.simpleMessage("获取验证码"),
|
||||
"get_code_again" : MessageLookupByLibrary.simpleMessage("重新获取验证码"),
|
||||
"get_code_token" : m13,
|
||||
"get_code_token" : m15,
|
||||
"get_coupon" : MessageLookupByLibrary.simpleMessage("获取红包"),
|
||||
"get_picture" : MessageLookupByLibrary.simpleMessage("获取图片"),
|
||||
"get_picture_from" : MessageLookupByLibrary.simpleMessage("从...获取图片"),
|
||||
@@ -224,7 +236,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"group_number_can_be_found" : MessageLookupByLibrary.simpleMessage("按如下图找到集团号码..."),
|
||||
"home" : MessageLookupByLibrary.simpleMessage("首页"),
|
||||
"hot_sale" : MessageLookupByLibrary.simpleMessage("热卖"),
|
||||
"hour_token" : m14,
|
||||
"hour_token" : m16,
|
||||
"igoshow" : MessageLookupByLibrary.simpleMessage("iGoShow"),
|
||||
"includes" : MessageLookupByLibrary.simpleMessage("包含"),
|
||||
"information" : MessageLookupByLibrary.simpleMessage("信息"),
|
||||
@@ -243,10 +255,11 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"logout" : MessageLookupByLibrary.simpleMessage("登出"),
|
||||
"main_content_1" : MessageLookupByLibrary.simpleMessage("自从1999年来,我们一直致力于开发完整的强大的销售系统,帮助了上千小企业平滑的处理销售业务。当前我们有两个主要的产品。"),
|
||||
"me" : MessageLookupByLibrary.simpleMessage("我的"),
|
||||
"min_order_amount_token" : m15,
|
||||
"min_shipping_fee" : m16,
|
||||
"min_order_amount_token" : m17,
|
||||
"min_shipping_fee" : m18,
|
||||
"minipos" : MessageLookupByLibrary.simpleMessage("MiniPOS"),
|
||||
"minute_token" : m17,
|
||||
"minute_token" : m19,
|
||||
"mobile" : MessageLookupByLibrary.simpleMessage("手机"),
|
||||
"mobile_email_username" : MessageLookupByLibrary.simpleMessage("手机号码,Email或MiniOffice用户名"),
|
||||
"mobile_is_required" : MessageLookupByLibrary.simpleMessage("手机号码必填"),
|
||||
"mobile_number" : MessageLookupByLibrary.simpleMessage("手机号码"),
|
||||
@@ -290,6 +303,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"ok" : MessageLookupByLibrary.simpleMessage("确定"),
|
||||
"old_password" : MessageLookupByLibrary.simpleMessage("旧密码"),
|
||||
"online_payment" : MessageLookupByLibrary.simpleMessage("在线付款"),
|
||||
"open_online_store" : MessageLookupByLibrary.simpleMessage("开网店"),
|
||||
"optional_information" : MessageLookupByLibrary.simpleMessage("可选填信息"),
|
||||
"order_acceipt" : MessageLookupByLibrary.simpleMessage("已接单"),
|
||||
"order_again" : MessageLookupByLibrary.simpleMessage("再来一单"),
|
||||
@@ -299,7 +313,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"order_detail" : MessageLookupByLibrary.simpleMessage("订单详情"),
|
||||
"order_fulfillment" : MessageLookupByLibrary.simpleMessage("订单完成度"),
|
||||
"order_info" : MessageLookupByLibrary.simpleMessage("订单信息"),
|
||||
"order_more" : m18,
|
||||
"order_more" : m20,
|
||||
"order_number" : MessageLookupByLibrary.simpleMessage("订单号码"),
|
||||
"order_number_copied_to_clipboard" : MessageLookupByLibrary.simpleMessage("订单号码复制到剪切板"),
|
||||
"order_processing" : MessageLookupByLibrary.simpleMessage("准备中"),
|
||||
@@ -314,30 +328,31 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"password_is_required" : MessageLookupByLibrary.simpleMessage("密码必填。"),
|
||||
"pay" : MessageLookupByLibrary.simpleMessage("付款"),
|
||||
"pay_after_meal" : MessageLookupByLibrary.simpleMessage("餐后付款"),
|
||||
"pay_amount_token" : m19,
|
||||
"pay_amount_token" : m21,
|
||||
"pay_later" : MessageLookupByLibrary.simpleMessage("稍后付款"),
|
||||
"pay_now" : MessageLookupByLibrary.simpleMessage("去支付"),
|
||||
"pay_on_deliery" : MessageLookupByLibrary.simpleMessage("到货付款"),
|
||||
"pay_on_deliery_pickup" : MessageLookupByLibrary.simpleMessage("自提或到货付款"),
|
||||
"pay_with" : MessageLookupByLibrary.simpleMessage("使用"),
|
||||
"pay_with_existing_cards" : MessageLookupByLibrary.simpleMessage("用现有的卡付款"),
|
||||
"pay_with_token" : m20,
|
||||
"pay_with_token" : m22,
|
||||
"payment_amount" : MessageLookupByLibrary.simpleMessage("付款金额"),
|
||||
"payment_method" : MessageLookupByLibrary.simpleMessage("付款方式"),
|
||||
"payment_method_not_set" : MessageLookupByLibrary.simpleMessage("没有指定付款方式,请货到付款或自提付款。"),
|
||||
"payment_status" : MessageLookupByLibrary.simpleMessage("付款状态"),
|
||||
"payment_verification" : MessageLookupByLibrary.simpleMessage("付款验证"),
|
||||
"payment_verification_sent" : m21,
|
||||
"payment_verification_sent" : m23,
|
||||
"paypal" : MessageLookupByLibrary.simpleMessage("Paypal"),
|
||||
"pending" : MessageLookupByLibrary.simpleMessage("待接单"),
|
||||
"percent_discount" : MessageLookupByLibrary.simpleMessage("%折扣"),
|
||||
"percentage_discount_token" : m22,
|
||||
"percentage_discount_token2" : m23,
|
||||
"percentage_discount_token" : m24,
|
||||
"percentage_discount_token2" : m25,
|
||||
"pick_a_coupon" : MessageLookupByLibrary.simpleMessage("使用红包"),
|
||||
"pickup" : MessageLookupByLibrary.simpleMessage("到店自提"),
|
||||
"pickup_address" : MessageLookupByLibrary.simpleMessage("自提地址"),
|
||||
"pickup_at" : MessageLookupByLibrary.simpleMessage("自提地址"),
|
||||
"pickup_discount" : MessageLookupByLibrary.simpleMessage("自提折扣"),
|
||||
"place_order_now" : MessageLookupByLibrary.simpleMessage("马上下单"),
|
||||
"please_enter_coupon_code" : MessageLookupByLibrary.simpleMessage("请输入红包号码。"),
|
||||
"please_enter_group_number" : MessageLookupByLibrary.simpleMessage("请输入您的集团号码。"),
|
||||
"please_login" : MessageLookupByLibrary.simpleMessage("请登陆"),
|
||||
@@ -361,7 +376,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"quick_input" : MessageLookupByLibrary.simpleMessage("快速输入"),
|
||||
"radio_option_is_optional" : MessageLookupByLibrary.simpleMessage("可选选项。如果不选择可以直接点下一步。"),
|
||||
"radio_option_is_required" : MessageLookupByLibrary.simpleMessage("选项必选。选择一个选项后点下一步。"),
|
||||
"radio_option_select_token" : m24,
|
||||
"radio_option_select_token" : m26,
|
||||
"recalculating" : MessageLookupByLibrary.simpleMessage("运算中..."),
|
||||
"red_coupon" : MessageLookupByLibrary.simpleMessage("红包"),
|
||||
"redeem_coupon" : MessageLookupByLibrary.simpleMessage("去使用"),
|
||||
@@ -369,6 +384,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"registration" : MessageLookupByLibrary.simpleMessage("注册"),
|
||||
"release_to_load_more" : MessageLookupByLibrary.simpleMessage("松开载入"),
|
||||
"renew_license" : MessageLookupByLibrary.simpleMessage("证书续期"),
|
||||
"renew_service_now" : MessageLookupByLibrary.simpleMessage("马上续期"),
|
||||
"renewal_fee" : MessageLookupByLibrary.simpleMessage("续订费用"),
|
||||
"reply" : MessageLookupByLibrary.simpleMessage("回复"),
|
||||
"reset_password" : MessageLookupByLibrary.simpleMessage("重置密码"),
|
||||
@@ -381,12 +397,14 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"saturday" : MessageLookupByLibrary.simpleMessage("星期六"),
|
||||
"save" : MessageLookupByLibrary.simpleMessage("保存"),
|
||||
"schedule_delivery" : MessageLookupByLibrary.simpleMessage("预约送货时间"),
|
||||
"search" : MessageLookupByLibrary.simpleMessage("搜索"),
|
||||
"search_place" : MessageLookupByLibrary.simpleMessage("搜索地址"),
|
||||
"search_product" : MessageLookupByLibrary.simpleMessage("搜索产品"),
|
||||
"search_products" : MessageLookupByLibrary.simpleMessage("搜索产品"),
|
||||
"select" : MessageLookupByLibrary.simpleMessage("选取"),
|
||||
"select_a_payment_method" : MessageLookupByLibrary.simpleMessage("选择付款方式"),
|
||||
"select_a_plan" : MessageLookupByLibrary.simpleMessage("选择一个计划"),
|
||||
"select_a_store" : MessageLookupByLibrary.simpleMessage("选择一个店子"),
|
||||
"select_canada_post_shipping_rate" : MessageLookupByLibrary.simpleMessage("请选择加拿大邮政运费。"),
|
||||
"select_delivery_time" : MessageLookupByLibrary.simpleMessage("选择配送时间"),
|
||||
"select_document_lanuage" : MessageLookupByLibrary.simpleMessage("选择一种语言"),
|
||||
@@ -401,7 +419,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"shop" : MessageLookupByLibrary.simpleMessage("线上购买"),
|
||||
"show_less" : MessageLookupByLibrary.simpleMessage("显示更少"),
|
||||
"show_more" : MessageLookupByLibrary.simpleMessage("显示更多"),
|
||||
"sold_per_month_token" : m25,
|
||||
"sold_per_month_token" : m27,
|
||||
"specification" : MessageLookupByLibrary.simpleMessage("规格"),
|
||||
"store" : MessageLookupByLibrary.simpleMessage("店家"),
|
||||
"store_closed" : MessageLookupByLibrary.simpleMessage("商店已关"),
|
||||
@@ -417,13 +435,13 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"submitting" : MessageLookupByLibrary.simpleMessage("提交中..."),
|
||||
"submitting_please_wait" : MessageLookupByLibrary.simpleMessage("提交中,清稍候..."),
|
||||
"subtotal" : MessageLookupByLibrary.simpleMessage("小计"),
|
||||
"subtotal_token" : m26,
|
||||
"subtotal_token" : m28,
|
||||
"success" : MessageLookupByLibrary.simpleMessage("成功"),
|
||||
"sun" : MessageLookupByLibrary.simpleMessage("周日"),
|
||||
"sunday" : MessageLookupByLibrary.simpleMessage("星期日"),
|
||||
"support" : MessageLookupByLibrary.simpleMessage("技术支持"),
|
||||
"support_ticket" : MessageLookupByLibrary.simpleMessage("客户提问"),
|
||||
"table_token" : m27,
|
||||
"table_token" : m29,
|
||||
"tap_back_again_to_exit" : MessageLookupByLibrary.simpleMessage("再次点击返回退出"),
|
||||
"tax" : MessageLookupByLibrary.simpleMessage("税费"),
|
||||
"thank_you_for_your_comment" : MessageLookupByLibrary.simpleMessage("谢谢您的评价。"),
|
||||
@@ -435,12 +453,12 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"thu" : MessageLookupByLibrary.simpleMessage("周四"),
|
||||
"thursday" : MessageLookupByLibrary.simpleMessage("星期四"),
|
||||
"ticket_created_success" : MessageLookupByLibrary.simpleMessage("支持票成功创建。"),
|
||||
"ticket_number_token" : m28,
|
||||
"ticket_number_token" : m30,
|
||||
"today" : MessageLookupByLibrary.simpleMessage("今天"),
|
||||
"today_with_time" : m29,
|
||||
"today_with_time" : m31,
|
||||
"toll_free" : MessageLookupByLibrary.simpleMessage("无费号码:"),
|
||||
"tomorrow" : MessageLookupByLibrary.simpleMessage("明天"),
|
||||
"tomorrow_with_time" : m30,
|
||||
"tomorrow_with_time" : m32,
|
||||
"total" : MessageLookupByLibrary.simpleMessage("总计"),
|
||||
"tue" : MessageLookupByLibrary.simpleMessage("周二"),
|
||||
"tuesday" : MessageLookupByLibrary.simpleMessage("星期二"),
|
||||
@@ -465,7 +483,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"wechatpay" : MessageLookupByLibrary.simpleMessage("微信支付"),
|
||||
"wed" : MessageLookupByLibrary.simpleMessage("周三"),
|
||||
"wednesday" : MessageLookupByLibrary.simpleMessage("星期三"),
|
||||
"weight_token" : m31,
|
||||
"weight_token" : m33,
|
||||
"wiki" : MessageLookupByLibrary.simpleMessage("维基"),
|
||||
"wrong_payment_verification_code" : MessageLookupByLibrary.simpleMessage("错误的付款码,请查证后再输入。"),
|
||||
"yes" : MessageLookupByLibrary.simpleMessage("是的"),
|
||||
|
||||
@@ -3439,13 +3439,13 @@ class S {
|
||||
);
|
||||
}
|
||||
|
||||
/// `Payment verification code has been sent to your mobile phone {mobile}. Please enter the verification code below.`
|
||||
String payment_verification_sent(Object mobile) {
|
||||
/// `Payment verification code has been sent to your {p1} {p2}. Please enter the verification code below.`
|
||||
String payment_verification_sent(Object p1, Object p2) {
|
||||
return Intl.message(
|
||||
'Payment verification code has been sent to your mobile phone $mobile. Please enter the verification code below.',
|
||||
'Payment verification code has been sent to your $p1 $p2. Please enter the verification code below.',
|
||||
name: 'payment_verification_sent',
|
||||
desc: '',
|
||||
args: [mobile],
|
||||
args: [p1, p2],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3978,6 +3978,146 @@ class S {
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Enter keyword`
|
||||
String get enter_keyword {
|
||||
return Intl.message(
|
||||
'Enter keyword',
|
||||
name: 'enter_keyword',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Search`
|
||||
String get search {
|
||||
return Intl.message(
|
||||
'Search',
|
||||
name: 'search',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Open an online store`
|
||||
String get create_a_online_store {
|
||||
return Intl.message(
|
||||
'Open an online store',
|
||||
name: 'create_a_online_store',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Open an online store`
|
||||
String get open_online_store {
|
||||
return Intl.message(
|
||||
'Open an online store',
|
||||
name: 'open_online_store',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Select a store`
|
||||
String get select_a_store {
|
||||
return Intl.message(
|
||||
'Select a store',
|
||||
name: 'select_a_store',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Domain name`
|
||||
String get domain_name {
|
||||
return Intl.message(
|
||||
'Domain name',
|
||||
name: 'domain_name',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Your desired domain name`
|
||||
String get enter_desired_domain {
|
||||
return Intl.message(
|
||||
'Your desired domain name',
|
||||
name: 'enter_desired_domain',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Check availability`
|
||||
String get check_domain_name {
|
||||
return Intl.message(
|
||||
'Check availability',
|
||||
name: 'check_domain_name',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Domains separated by comma`
|
||||
String get domains_separated_comma {
|
||||
return Intl.message(
|
||||
'Domains separated by comma',
|
||||
name: 'domains_separated_comma',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `{domain} (available)`
|
||||
String domain_available_token(Object domain) {
|
||||
return Intl.message(
|
||||
'$domain (available)',
|
||||
name: 'domain_available_token',
|
||||
desc: '',
|
||||
args: [domain],
|
||||
);
|
||||
}
|
||||
|
||||
/// `{domain} (unavailable)`
|
||||
String domain_unavailable_token(Object domain) {
|
||||
return Intl.message(
|
||||
'$domain (unavailable)',
|
||||
name: 'domain_unavailable_token',
|
||||
desc: '',
|
||||
args: [domain],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Place order now`
|
||||
String get place_order_now {
|
||||
return Intl.message(
|
||||
'Place order now',
|
||||
name: 'place_order_now',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `mobile`
|
||||
String get mobile {
|
||||
return Intl.message(
|
||||
'mobile',
|
||||
name: 'mobile',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Renew service now`
|
||||
String get renew_service_now {
|
||||
return Intl.message(
|
||||
'Renew service now',
|
||||
name: 'renew_service_now',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class AppLocalizationDelegate extends LocalizationsDelegate<S> {
|
||||
|
||||
@@ -339,7 +339,7 @@
|
||||
"confirmation": "Confirmation",
|
||||
"are_you_sure_to_remove_the_card": "Are you srue you want to remove the credit card?",
|
||||
"payment_verification": "Payment verification",
|
||||
"payment_verification_sent": "Payment verification code has been sent to your mobile phone {mobile}. Please enter the verification code below.",
|
||||
"payment_verification_sent": "Payment verification code has been sent to your {p1} {p2}. Please enter the verification code below.",
|
||||
"wrong_payment_verification_code": "Wrong payment verification code. Please check and enter again.",
|
||||
"pay_with": "Pay with",
|
||||
"pay_with_token": "Pay with {method}",
|
||||
@@ -392,5 +392,19 @@
|
||||
"your_group": "Your group",
|
||||
"current_plan": "Current plan",
|
||||
"select_a_plan": "Select a plan",
|
||||
"price": "Price"
|
||||
"price": "Price",
|
||||
"enter_keyword": "Enter keyword",
|
||||
"search": "Search",
|
||||
"create_a_online_store": "Open an online store",
|
||||
"open_online_store": "Open an online store",
|
||||
"select_a_store": "Select a store",
|
||||
"domain_name": "Domain name",
|
||||
"enter_desired_domain": "Your desired domain name",
|
||||
"check_domain_name": "Check availability",
|
||||
"domains_separated_comma": "Domains separated by comma",
|
||||
"domain_available_token": "{domain} (available)",
|
||||
"domain_unavailable_token": "{domain} (unavailable)",
|
||||
"place_order_now": "Place order now",
|
||||
"mobile": "mobile",
|
||||
"renew_service_now": "Renew service now"
|
||||
}
|
||||
@@ -334,7 +334,7 @@
|
||||
"confirmation": "请确定",
|
||||
"are_you_sure_to_remove_the_card": "您确定要移除该信用卡吗?",
|
||||
"payment_verification": "付款验证",
|
||||
"payment_verification_sent": "付款码已经发送到您的手机{mobile}。请在下面输入付款码。",
|
||||
"payment_verification_sent": "付款码已经发送到您的{p1}{p2}。请在下面输入付款码。",
|
||||
"wrong_payment_verification_code": "错误的付款码,请查证后再输入。",
|
||||
"pay_with": "使用",
|
||||
"pay_with_token": "使用{method}付款",
|
||||
@@ -388,5 +388,19 @@
|
||||
"current_plan": "当前计划",
|
||||
"select_a_plan": "选择一个计划",
|
||||
"price": "价格",
|
||||
"no_ticket_yet": "还没有支持票。 如果您有任何疑问/问题,请点击上方的加号图标以创建支持票。"
|
||||
"no_ticket_yet": "还没有支持票。 如果您有任何疑问/问题,请点击上方的加号图标以创建支持票。",
|
||||
"enter_keyword": "输入关键字",
|
||||
"search": "搜索",
|
||||
"create_a_online_store": "开网店",
|
||||
"open_online_store": "开网店",
|
||||
"select_a_store": "选择一个店子",
|
||||
"domain_name": "域名",
|
||||
"enter_desired_domain": "您想要的域名",
|
||||
"check_domain_name": "检查是否可用",
|
||||
"domains_separated_comma": "逗号分开多个域名",
|
||||
"domain_available_token": "{domain} (可用)",
|
||||
"domain_unavailable_token": "{domain} (不可用)",
|
||||
"place_order_now": "马上下单",
|
||||
"mobile": "手机",
|
||||
"renew_service_now": "马上续期"
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import 'package:flutter_wisetronic/pages/buy_service.dart';
|
||||
import 'package:geolocator/geolocator.dart' as geolocator;
|
||||
import 'package:url_strategy/url_strategy.dart';
|
||||
import 'models/located_address.dart';
|
||||
import 'pages/create_online_store_1.dart';
|
||||
import 'pages/me.dart';
|
||||
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
||||
import 'package:splashscreen/splashscreen.dart';
|
||||
@@ -28,6 +29,7 @@ import 'store/store.dart';
|
||||
import 'utils/configure_nonweb.dart' if (dart.library.html) 'utils/configure_web.dart';
|
||||
import 'utils/http_util.dart';
|
||||
import 'utils/util_io.dart' if (dart.library.html) 'utils/util_web.dart';
|
||||
import 'utils/utils.dart';
|
||||
|
||||
void main() {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
@@ -42,6 +44,7 @@ class MyApp extends StatelessWidget {
|
||||
|
||||
MyApp() {
|
||||
Routes.configure();
|
||||
Utils().init();
|
||||
Util().init();
|
||||
// getCurrentPosition();
|
||||
}
|
||||
@@ -142,16 +145,42 @@ class MyApp extends StatelessWidget {
|
||||
builder: (BuildContext context) => Me()
|
||||
);
|
||||
}
|
||||
if (pathElements[1] == 'service-policy') {
|
||||
return MaterialPageRoute(
|
||||
builder: (BuildContext context) =>
|
||||
PlainPage(
|
||||
'service-policy',
|
||||
businessId: 310,
|
||||
),
|
||||
);
|
||||
}
|
||||
if (pathElements[1] == 'privacy-policy') {
|
||||
return MaterialPageRoute(
|
||||
builder: (BuildContext context) =>
|
||||
PlainPage(
|
||||
'privacy-policy',
|
||||
// businessId: Constants.BUSINESS_ID,
|
||||
businessId: 310,
|
||||
),
|
||||
);
|
||||
}
|
||||
if (pathElements[1] == 'return-policy') {
|
||||
return MaterialPageRoute(
|
||||
builder: (BuildContext context) =>
|
||||
PlainPage(
|
||||
'return-policy',
|
||||
businessId: 310,
|
||||
),
|
||||
);
|
||||
}
|
||||
if (pathElements[1] == 'end-user-license-agreement') {
|
||||
return MaterialPageRoute(
|
||||
builder: (BuildContext context) =>
|
||||
PlainPage(
|
||||
'end-user-license-agreement',
|
||||
businessId: 310,
|
||||
),
|
||||
);
|
||||
}
|
||||
if (pathElements[1] == 'renew-minioffice') {
|
||||
return MaterialPageRoute(builder: (BuildContext context) =>
|
||||
RenewMiniOffice(int.parse(pathElements[2]))
|
||||
@@ -162,6 +191,11 @@ class MyApp extends StatelessWidget {
|
||||
BuyService(int.parse(pathElements[2]), pathElements[3])
|
||||
);
|
||||
}
|
||||
if (pathElements[1] == 'contact-stores') {
|
||||
return MaterialPageRoute(builder: (BuildContext context) =>
|
||||
CreateOnlineStore1()
|
||||
);
|
||||
}
|
||||
return MaterialPageRoute(
|
||||
builder: (BuildContext context) =>
|
||||
Home(title: Constants.APP_TITLE,),
|
||||
|
||||
22
lib/models/group.dart
Normal file
22
lib/models/group.dart
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
class Group {
|
||||
int id;
|
||||
String name;
|
||||
|
||||
Group.fromJson(Map<String, dynamic> json) :
|
||||
id = json['id'],
|
||||
name = json['name'];
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'id': id,
|
||||
'name': name
|
||||
};
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return json.encode(this);
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ class Product {
|
||||
String description;
|
||||
String detailDescription;
|
||||
String imagePath;
|
||||
String secondImagePath;
|
||||
double monthSales;
|
||||
int rate;
|
||||
double leftNum;
|
||||
@@ -30,26 +31,28 @@ class Product {
|
||||
this.price = price;
|
||||
this.description = description;
|
||||
this.imagePath = imagePath;
|
||||
this.secondImagePath = secondImagePath;
|
||||
this.productAttributes = productAttributes;
|
||||
}
|
||||
|
||||
Product.fromJson(Map<String, dynamic> json)
|
||||
: id = json['id'],
|
||||
businessId = json['business_id'],
|
||||
categoryId = json['category_id'],
|
||||
name = json['name'],
|
||||
price = double.parse(json['price'].toString()),
|
||||
regularPrice = double.parse(json['regular_price'].toString()),
|
||||
description = json['description'],
|
||||
detailDescription = json['detail_description'],
|
||||
imagePath = json['image_path'],
|
||||
monthSales = json['month_sales'] != null ? double.parse(json['month_sales'].toString()) : 0.0,
|
||||
rate = json['rate'],
|
||||
leftNum = json['left_num'] != null ? double.parse(json['left_num'].toString()) : 0.0,
|
||||
productAttributes = json['productattributes'] != null ? (json['productattributes'] as List).map((i) => ProductAttribute.fromJson(i)).toList() : [],
|
||||
nonInventory = json['non_inventory'],
|
||||
extraData = json['extra_data'],
|
||||
subproducts = json['subproducts'] != null ? (json['subproducts'] as List).map((e) => Subproduct.fromJson(e)).toList() : [];
|
||||
: id = json['id'],
|
||||
businessId = json['business_id'],
|
||||
categoryId = json['category_id'],
|
||||
name = json['name'],
|
||||
price = double.parse(json['price'].toString()),
|
||||
regularPrice = double.parse(json['regular_price'].toString()),
|
||||
description = json['description'],
|
||||
detailDescription = json['detail_description'],
|
||||
imagePath = json['image_path'],
|
||||
secondImagePath = json['second_image_path'],
|
||||
monthSales = json['month_sales'] != null ? double.parse(json['month_sales'].toString()) : 0.0,
|
||||
rate = json['rate'],
|
||||
leftNum = json['left_num'] != null ? double.parse(json['left_num'].toString()) : 0.0,
|
||||
productAttributes = json['productattributes'] != null ? (json['productattributes'] as List).map((i) => ProductAttribute.fromJson(i)).toList() : [],
|
||||
nonInventory = json['non_inventory'],
|
||||
extraData = json['extra_data'],
|
||||
subproducts = json['subproducts'] != null ? (json['subproducts'] as List).map((e) => Subproduct.fromJson(e)).toList() : [];
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'id': id,
|
||||
@@ -61,6 +64,7 @@ class Product {
|
||||
'description': description,
|
||||
'detail_description': detailDescription,
|
||||
'image_path': imagePath,
|
||||
'second_image_path': secondImagePath,
|
||||
'month_sales': monthSales,
|
||||
'rate': rate,
|
||||
'left_num': leftNum,
|
||||
|
||||
@@ -19,8 +19,10 @@ import '../widgets/mobile/mobile_renew_license.dart';
|
||||
class BuyService extends StatefulWidget {
|
||||
final int gid;
|
||||
final String serviceName;
|
||||
final String domain;
|
||||
final int sid;
|
||||
|
||||
const BuyService(this.gid, this.serviceName, {Key key}) :
|
||||
const BuyService(this.gid, this.serviceName, {Key key, this.domain, this.sid = 0}) :
|
||||
super(key: key);
|
||||
|
||||
@override
|
||||
@@ -66,8 +68,13 @@ class BuyServiceState extends State<BuyService> {
|
||||
HttpUtil.httpGet(
|
||||
'v1/get-buy-service-info/${widget.serviceName}/${widget.gid}',
|
||||
businessId: Constants.BUSINESS_ID,
|
||||
queryParameters: {
|
||||
'store_id': '${widget.sid}',
|
||||
}
|
||||
).then((value) {
|
||||
data = value;
|
||||
data['domain'] = widget.domain;
|
||||
print('data: $data');
|
||||
setState(() {});
|
||||
}).onError((error, stackTrace) {
|
||||
Utils.showMessageDialog(context, error);
|
||||
|
||||
@@ -22,7 +22,7 @@ class ChangeMobileOrEmail extends StatelessWidget {
|
||||
return ResponsiveBuilder(
|
||||
builder: (context, sizingInformation) =>
|
||||
Scaffold(
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: isMobile ? S.of(context).change_mobile : S.of(context).change_email,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -20,7 +20,7 @@ class ChangePassword extends StatelessWidget {
|
||||
builder: (context, sizingInformation) =>
|
||||
Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).change_password,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
48
lib/pages/create_online_store_1.dart
Normal file
48
lib/pages/create_online_store_1.dart
Normal file
@@ -0,0 +1,48 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/store/actions.dart';
|
||||
import 'package:flutter_wisetronic/store/store.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
|
||||
import '../constants.dart';
|
||||
import '../routes.dart';
|
||||
import '../widgets/desktop/create_online_store_1.dart' as desktop;
|
||||
import '../widgets/mobile/create_online_store_1.dart' as mobile;
|
||||
|
||||
class CreateOnlineStore1 extends StatefulWidget {
|
||||
|
||||
const CreateOnlineStore1({Key key}) :
|
||||
super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => CreateOnlineStore1State();
|
||||
}
|
||||
|
||||
class CreateOnlineStore1State extends State<CreateOnlineStore1> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
if (store.state.user == null) {
|
||||
store.dispatch(UpdateRedirectRoute('/contact-stores'));
|
||||
Routes.router.navigateTo(context, '/login', replace: true);
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
return ResponsiveBuilder(
|
||||
builder: (context, sizingInformation) =>
|
||||
ScreenTypeLayout(
|
||||
mobile: mobile.CreateOnlineStore1(Constants.BUSINESS_ID),
|
||||
tablet: desktop.CreateOnlineStore1(Constants.BUSINESS_ID),
|
||||
desktop: desktop.CreateOnlineStore1(Constants.BUSINESS_ID),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,7 @@ class DownloadState extends State<Download> {
|
||||
builder: (context, sizingInformation) =>
|
||||
Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).download,
|
||||
back: true,
|
||||
breadCrumbs: [BreadCrumb(S.of(context).downloads, null)],
|
||||
|
||||
@@ -19,7 +19,7 @@ class ForgotPassword extends StatelessWidget {
|
||||
return ResponsiveBuilder(
|
||||
builder: (context, sizingInformation) =>
|
||||
Scaffold(
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).forgot_password,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -70,7 +70,7 @@ class HomeState extends State<Home> {
|
||||
builder: (context, sizingInformation) =>
|
||||
Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: NavigationBar(),
|
||||
appBar: MiniNavigationBar(),
|
||||
drawer: sizingInformation.deviceScreenType == DeviceScreenType.mobile ? MobileNavigationDrawer() : null,
|
||||
body: DoubleBackToCloseAppWrapper(
|
||||
child: ScreenTypeLayout(
|
||||
|
||||
@@ -46,7 +46,7 @@ class IGoShowLearnMoreState extends State<IGoShowLearnMore> {
|
||||
builder: (context, sizingInformation) =>
|
||||
Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).igoshow,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -41,7 +41,7 @@ class LoginState extends State<Login> {
|
||||
builder: (context, sizingInformation) =>
|
||||
Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).login,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -42,7 +42,7 @@ class MeState extends State<Me> {
|
||||
builder: (context, sizingInformation) =>
|
||||
Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: sizingInformation.isMobile? null : NavigationBar(
|
||||
appBar: sizingInformation.isMobile? null : MiniNavigationBar(
|
||||
title: S.of(context).me,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -47,7 +47,7 @@ class MiniPosLearnMoreState extends State<MiniPosLearnMore> {
|
||||
builder: (context, sizingInformation) =>
|
||||
Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).minipos,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -43,7 +43,7 @@ class NewTicketState extends State<NewTicket> {
|
||||
builder: (context, sizingInformation) =>
|
||||
Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).new_ticket,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -19,7 +19,7 @@ class NewUser extends StatelessWidget {
|
||||
return ResponsiveBuilder(
|
||||
builder: (context, sizingInformation) =>
|
||||
Scaffold(
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).registration,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
26
lib/pages/product_search.dart
Normal file
26
lib/pages/product_search.dart
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/models/business.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
|
||||
import '../widgets/desktop/product_search.dart' as desktop;
|
||||
import '../widgets/mobile/product_search.dart' as mobile;
|
||||
|
||||
class ProductSearch extends StatelessWidget {
|
||||
final Business business;
|
||||
|
||||
const ProductSearch(this.business, {Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ResponsiveBuilder(
|
||||
builder: (context, sizingInformation) =>
|
||||
ScreenTypeLayout(
|
||||
mobile: mobile.ProductSearch(business),
|
||||
tablet: desktop.ProductSearch(business),
|
||||
desktop: desktop.ProductSearch(business),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,7 +21,7 @@ class ResetPassword extends StatelessWidget {
|
||||
return ResponsiveBuilder(
|
||||
builder: (context, sizingInformation) =>
|
||||
Scaffold(
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).reset_password,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -21,7 +21,7 @@ class SetPassword extends StatelessWidget {
|
||||
return ResponsiveBuilder(
|
||||
builder: (context, sizingInformation) =>
|
||||
Scaffold(
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).set_password,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -1,55 +1,44 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/events/eventbus.dart';
|
||||
import 'package:flutter_wisetronic/events/events.dart';
|
||||
import 'package:flutter_wisetronic/generated/l10n.dart';
|
||||
import 'package:flutter_wisetronic/models/cart_info.dart';
|
||||
import 'package:flutter_wisetronic/models/cart_line_item.dart';
|
||||
import 'package:flutter_wisetronic/models/product.dart';
|
||||
import 'package:flutter_wisetronic/utils/utils.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
|
||||
import '../constants.dart';
|
||||
import '../store/actions.dart';
|
||||
import '../store/store.dart';
|
||||
import '../widgets/desktop/desktop_shop.dart';
|
||||
import '../widgets/mobile/mobile_shop.dart';
|
||||
import '../../utils/utils.dart';
|
||||
import '../widgets/desktop/shop.dart' as desktop;
|
||||
import '../widgets/mobile/shop.dart' as mobile;
|
||||
|
||||
class Shop extends StatefulWidget {
|
||||
final int businessId;
|
||||
|
||||
const Shop({this.businessId = Constants.BUSINESS_ID, Key key}) :
|
||||
super(key: key);
|
||||
const Shop({this.businessId, Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => ShopState();
|
||||
}
|
||||
|
||||
class ShopState extends State<Shop> {
|
||||
StreamSubscription onProductWillAddToCartSubscription;
|
||||
StreamSubscription onProductWillRemoveFromCartSubscription;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
store.dispatch(UpdateContext(context));
|
||||
int _businessId =
|
||||
widget.businessId == null ? Utils.getBusinessId() : widget.businessId;
|
||||
|
||||
return ResponsiveBuilder(
|
||||
builder: (context, sizingInformation) =>
|
||||
ScreenTypeLayout(
|
||||
mobile: MobileShop(businessId: widget.businessId,),
|
||||
tablet: DesktopShop(businessId: widget.businessId,),
|
||||
desktop: DesktopShop(businessId: widget.businessId,),
|
||||
),
|
||||
builder: (context, sizingInformation) => ScreenTypeLayout(
|
||||
mobile: mobile.Shop(
|
||||
businessId: _businessId,
|
||||
),
|
||||
tablet: desktop.Shop(
|
||||
businessId: _businessId,
|
||||
),
|
||||
desktop: desktop.Shop(
|
||||
businessId: _businessId,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
onProductWillAddToCartSubscription?.cancel();
|
||||
onProductWillRemoveFromCartSubscription?.cancel();
|
||||
super.dispose();
|
||||
print("shop parent dispose");
|
||||
}
|
||||
@@ -57,137 +46,5 @@ class ShopState extends State<Shop> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
onProductWillAddToCartSubscription =
|
||||
eventBus.on<OnProductWillAddToCart>().listen((event) {
|
||||
if (mounted) {
|
||||
|
||||
CartInfo cartInfo =
|
||||
Utils.getCartInfoByBusiness(store.state.cartInfos, event.business);
|
||||
|
||||
if (cartInfo == null || cartInfo.productList.length == 0) {
|
||||
cartInfo = CartInfo();
|
||||
cartInfo.id = 0;
|
||||
cartInfo.amountPaid = 0.0;
|
||||
cartInfo.businessInfo = event.business;
|
||||
cartInfo.extraFeeList = [];
|
||||
cartInfo.discountList = [];
|
||||
CartLineItem lineItem = Utils.newCartLineItem(
|
||||
id: 0,
|
||||
price: event.price,
|
||||
product: event.product,
|
||||
name: event.product.name,
|
||||
description: event.description,
|
||||
quantity: 1.0);
|
||||
cartInfo.productList = [lineItem];
|
||||
Utils.addSubproductToCard(cartInfo, lineItem);
|
||||
store.dispatch(new UpdateCartInfo(Utils.addCartInfoToCartInfoList(
|
||||
store.state.cartInfos, cartInfo)));
|
||||
eventBus.fire(new OnCartInfoUpdated());
|
||||
} else {
|
||||
if (event.product.productAttributes.length > 0) {
|
||||
CartLineItem lineItem = Utils.newCartLineItem(
|
||||
id: 0,
|
||||
price: event.price,
|
||||
product: event.product,
|
||||
name: event.product.name,
|
||||
description: event.description,
|
||||
quantity: 1.0);
|
||||
cartInfo.productList.add(lineItem);
|
||||
Utils.addSubproductToCard(cartInfo, lineItem);
|
||||
store.dispatch(new UpdateCartInfo(Utils.addCartInfoToCartInfoList(
|
||||
store.state.cartInfos, cartInfo)));
|
||||
eventBus.fire(new OnCartInfoUpdated());
|
||||
} else {
|
||||
int found = -1;
|
||||
for (var i = 0; i < cartInfo.productList.length; i++) {
|
||||
if (event.product.id == cartInfo.productList[i].product.id) {
|
||||
found = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found == -1) {
|
||||
CartLineItem lineItem = Utils.newCartLineItem(
|
||||
id: 0,
|
||||
price: event.price,
|
||||
product: event.product,
|
||||
name: event.product.name,
|
||||
description: event.description,
|
||||
quantity: 1.0);
|
||||
cartInfo.productList.add(lineItem);
|
||||
Utils.addSubproductToCard(cartInfo, lineItem);
|
||||
store.dispatch(new UpdateCartInfo(Utils.addCartInfoToCartInfoList(
|
||||
store.state.cartInfos, cartInfo)));
|
||||
eventBus.fire(new OnCartInfoUpdated());
|
||||
} else {
|
||||
if (cartInfo.productList[found].quantity + 1.0 >
|
||||
event.product.leftNum) {
|
||||
Fluttertoast.showToast(
|
||||
msg: S.of(context).product_insufficient,
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
gravity: ToastGravity.CENTER,
|
||||
backgroundColor: Colors.red,
|
||||
textColor: Colors.white);
|
||||
} else {
|
||||
cartInfo.productList[found].quantity += 1;
|
||||
Utils.addSubproductQty(cartInfo, cartInfo.productList[found]);
|
||||
store.dispatch(new UpdateCartInfo(
|
||||
Utils.addCartInfoToCartInfoList(
|
||||
store.state.cartInfos, cartInfo)));
|
||||
eventBus.fire(new OnCartInfoUpdated());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
onProductWillRemoveFromCartSubscription =
|
||||
eventBus.on<OnProductWillRemoveFromCart>().listen((event) {
|
||||
if (mounted) {
|
||||
CartInfo cartInfo =
|
||||
Utils.getCartInfoByBusiness(store.state.cartInfos, event.business);
|
||||
if (cartInfo != null) {
|
||||
if (cartInfo.productList.length > 0) {
|
||||
if (event.productListIndex != -1) {
|
||||
if (cartInfo.productList[event.productListIndex].quantity <= 1) {
|
||||
String uuid = cartInfo.productList[event.productListIndex].uuid;
|
||||
cartInfo.productList.removeAt(event.productListIndex);
|
||||
Utils.removeSubproduct(cartInfo, uuid);
|
||||
} else {
|
||||
cartInfo.productList[event.productListIndex].quantity -= 1;
|
||||
Utils.addSubproductQty(cartInfo, cartInfo.productList[event.productListIndex], remove: true);
|
||||
}
|
||||
} else {
|
||||
int productListIndex = -1;
|
||||
for (var i = 0; i < cartInfo.productList.length; i++) {
|
||||
if (cartInfo.productList[i].product.id == event.product.id) {
|
||||
productListIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (productListIndex != -1) {
|
||||
if (cartInfo.productList[productListIndex].quantity <= 1) {
|
||||
String uuid = cartInfo.productList[productListIndex].uuid;
|
||||
cartInfo.productList.removeAt(productListIndex);
|
||||
Utils.removeSubproduct(cartInfo, uuid);
|
||||
} else {
|
||||
cartInfo.productList[productListIndex].quantity -= 1;
|
||||
Utils.addSubproductQty(cartInfo, cartInfo.productList[productListIndex], remove: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cartInfo.productList.length <= 0) {
|
||||
store.dispatch(UpdateCartInfo(Utils.removeCartInfoFromCartInfoList(
|
||||
store.state.cartInfos, cartInfo)));
|
||||
} else {
|
||||
store.dispatch(UpdateCartInfo(Utils.addCartInfoToCartInfoList(
|
||||
store.state.cartInfos, cartInfo)));
|
||||
}
|
||||
eventBus.fire(new OnCartInfoUpdated());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/widgets/desktop/desktop_store_product_search.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
|
||||
import '../constants.dart';
|
||||
import '../generated/l10n.dart';
|
||||
import '../models/business.dart';
|
||||
import '../widgets/desktop/desktop_store_product_search.dart';
|
||||
import '../widgets/general/bottom_nav.dart';
|
||||
import '../widgets/general/breadcrumbs.dart';
|
||||
import '../widgets/general/navigationbar.dart';
|
||||
@@ -22,7 +22,7 @@ class StoreProductSearch extends StatelessWidget {
|
||||
return ResponsiveBuilder(
|
||||
builder: (context, sizingInformation) =>
|
||||
Scaffold(
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).search_product,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
|
||||
import '../constants.dart';
|
||||
import '../events/eventbus.dart';
|
||||
import '../events/events.dart';
|
||||
import '../generated/l10n.dart';
|
||||
import '../widgets/desktop/desktop_tutorials.dart';
|
||||
import '../widgets/general/bottom_nav.dart';
|
||||
import '../widgets/general/breadcrumbs.dart';
|
||||
import '../widgets/general/navigationbar.dart';
|
||||
import '../widgets/mobile/MobileBottomNav.dart';
|
||||
import '../widgets/mobile/mobile_navigation_drawer.dart';
|
||||
import '../widgets/mobile/mobile_tutorials.dart';
|
||||
|
||||
class Tutorials extends StatefulWidget {
|
||||
const Tutorials({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return TutorialsState();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TutorialsState extends State<Tutorials> {
|
||||
final _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ResponsiveBuilder(
|
||||
builder: (context, sizingInformation) =>
|
||||
Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: NavigationBar(
|
||||
title: S.of(context).tutorials,
|
||||
back: true,
|
||||
breadCrumbs: [BreadCrumb(S.of(context).tutorials, null)],
|
||||
breadCrumbHeight: sizingInformation.deviceScreenType == DeviceScreenType.mobile ? null : Constants.BREADCRUMB_HEIGHT,
|
||||
),
|
||||
drawer: null,
|
||||
body: ScreenTypeLayout(
|
||||
mobile: MobileTutorials(),
|
||||
tablet: DesktopTutorials(),
|
||||
desktop: DesktopTutorials(),
|
||||
),
|
||||
bottomNavigationBar: ScreenTypeLayout(
|
||||
mobile: MobileBottomNav(currentIndex: 0,),
|
||||
tablet: BottomNav(),
|
||||
desktop: BottomNav(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
eventBus.on<OpenDrawer>().listen((event) {
|
||||
if (mounted) {
|
||||
_scaffoldKey.currentState.openDrawer();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ class UserProfile extends StatelessWidget {
|
||||
return ResponsiveBuilder(
|
||||
builder: (context, sizingInformation) =>
|
||||
Scaffold(
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).profile,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -42,7 +42,7 @@ class ViewBlogState extends State<ViewBlog> {
|
||||
builder: (context, sizingInformation) =>
|
||||
Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).view_blog,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -42,7 +42,7 @@ class ViewTicketState extends State<ViewTicket> {
|
||||
builder: (context, sizingInformation) =>
|
||||
Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).view_ticket,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
|
||||
import 'package:fluro/fluro.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/pages/buy_service.dart';
|
||||
import 'package:flutter_wisetronic/pages/contact_us.dart';
|
||||
import 'package:flutter_wisetronic/pages/plain_page.dart';
|
||||
import 'package:flutter_wisetronic/pages/renew_license.dart';
|
||||
import 'package:flutter_wisetronic/pages/renew_minioffice.dart';
|
||||
import 'package:flutter_wisetronic/store/store.dart';
|
||||
|
||||
import 'constants.dart';
|
||||
import 'pages/blog.dart';
|
||||
import 'pages/buy_service.dart';
|
||||
import 'pages/change_mobile_or_email.dart';
|
||||
import 'pages/change_password.dart';
|
||||
import 'pages/checkout.dart';
|
||||
import 'pages/contact_us.dart';
|
||||
import 'pages/coupons.dart';
|
||||
import 'pages/create_online_store_1.dart';
|
||||
import 'pages/download.dart';
|
||||
import 'pages/forgot_password.dart';
|
||||
import 'pages/home.dart';
|
||||
@@ -30,11 +27,13 @@ import 'pages/new_user.dart';
|
||||
import 'pages/order_detail.dart';
|
||||
import 'pages/orders.dart';
|
||||
import 'pages/pay_now.dart';
|
||||
import 'pages/plain_page.dart';
|
||||
import 'pages/renew_license.dart';
|
||||
import 'pages/renew_minioffice.dart';
|
||||
import 'pages/reset_password.dart';
|
||||
import 'pages/search_place.dart';
|
||||
import 'pages/set_password.dart';
|
||||
import 'pages/shop.dart';
|
||||
import 'pages/tutorials.dart';
|
||||
import 'pages/user_profile.dart';
|
||||
import 'pages/view_blog.dart';
|
||||
import 'pages/view_ticket.dart';
|
||||
@@ -68,12 +67,6 @@ class Routes {
|
||||
}),
|
||||
transitionType: TransitionType.inFromRight
|
||||
);
|
||||
router.define('/tutorials', handler: new Handler(
|
||||
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||
return Tutorials();
|
||||
}),
|
||||
transitionType: TransitionType.inFromRight
|
||||
);
|
||||
router.define('/login', handler: new Handler(
|
||||
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||
return Login();
|
||||
@@ -279,5 +272,10 @@ class Routes {
|
||||
return BuyService(int.parse(params['gid'][0]), params['servicename'][0]);
|
||||
}
|
||||
));
|
||||
router.define('/contact-stores', handler: new Handler(
|
||||
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||
return CreateOnlineStore1();
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,7 @@ class HttpUtil {
|
||||
localHeaders['Http-Signature'] = generateSignature(url);
|
||||
}
|
||||
|
||||
localHeaders['Http-Business-Id'] = businessId.toString();
|
||||
localHeaders['Http-Business-Id'] = businessId == 0 ? '${Constants.BUSINESS_ID}' : businessId.toString();
|
||||
Box box = await Utils.getBox();
|
||||
localHeaders['Http-Contact-Authorization'] = box.get(Constants.KEY_ACCESS_TOKEN, defaultValue: '');
|
||||
localHeaders['Http-App-Key'] = platformName;
|
||||
@@ -81,7 +81,7 @@ class HttpUtil {
|
||||
onReceiveProgress: receiveProgress,
|
||||
).timeout(const Duration(seconds: 30));
|
||||
|
||||
// print(response.data);
|
||||
// print('response data: ${response.data}');
|
||||
// Utils.jsonPrettyPrint(response.data);
|
||||
|
||||
int statusCode = response.statusCode;
|
||||
@@ -115,7 +115,7 @@ class HttpUtil {
|
||||
if (!url.startsWith('http')) {
|
||||
localHeaders['Http-Signature'] = generateSignature(url);
|
||||
}
|
||||
localHeaders['Http-Business-Id'] = businessId.toString();
|
||||
localHeaders['Http-Business-Id'] = businessId == 0 ? '${Constants.BUSINESS_ID}' : businessId.toString();
|
||||
Box box = await Utils.getBox();
|
||||
localHeaders['Http-Contact-Authorization'] = box.get(Constants.KEY_ACCESS_TOKEN, defaultValue: '');
|
||||
localHeaders['Http-App-Key'] = platformName;
|
||||
@@ -189,7 +189,7 @@ class HttpUtil {
|
||||
localHeaders['Http-Signature'] = generateSignature(url);
|
||||
}
|
||||
|
||||
localHeaders['Http-Business-Id'] = businessId.toString();
|
||||
localHeaders['Http-Business-Id'] = businessId == 0 ? '${Constants.BUSINESS_ID}' : businessId.toString();
|
||||
Box box = await Utils.getBox();
|
||||
localHeaders['Http-Contact-Authorization'] = box.get(Constants.KEY_ACCESS_TOKEN, defaultValue: '');
|
||||
localHeaders['Http-App-Key'] = platformName;
|
||||
@@ -254,7 +254,7 @@ class HttpUtil {
|
||||
localHeaders['Http-Signature'] = generateSignature(url);
|
||||
}
|
||||
|
||||
localHeaders['Http-Business-Id'] = businessId.toString();
|
||||
localHeaders['Http-Business-Id'] = businessId == 0 ? '${Constants.BUSINESS_ID}' : businessId.toString();
|
||||
Box box = await Utils.getBox();
|
||||
localHeaders['Http-Contact-Authorization'] = box.get(Constants.KEY_ACCESS_TOKEN, defaultValue: '');
|
||||
localHeaders['Http-App-Key'] = platformName;
|
||||
@@ -319,7 +319,7 @@ class HttpUtil {
|
||||
localHeaders['Http-Signature'] = generateSignature(url);
|
||||
}
|
||||
|
||||
localHeaders['Http-Business-Id'] = businessId.toString();
|
||||
localHeaders['Http-Business-Id'] = businessId == 0 ? '${Constants.BUSINESS_ID}' : businessId.toString();
|
||||
Box box = await Utils.getBox();
|
||||
localHeaders['Http-Contact-Authorization'] = box.get(Constants.KEY_ACCESS_TOKEN, defaultValue: '');
|
||||
localHeaders['Http-App-Key'] = platformName;
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
|
||||
import 'dart:html';
|
||||
|
||||
import 'dart:ui' as ui;
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class IFrameWeb extends StatefulWidget {
|
||||
final String width;
|
||||
final String height;
|
||||
final String src;
|
||||
|
||||
const IFrameWeb({this.width, this.height, this.src});
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return IFrameWebState();
|
||||
}
|
||||
}
|
||||
|
||||
class IFrameWebState extends State<IFrameWeb> {
|
||||
final IFrameElement _iframeElement = IFrameElement();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
_iframeElement.height = widget.height;
|
||||
_iframeElement.width = widget.width;
|
||||
_iframeElement.src = widget.src;
|
||||
_iframeElement.style.border = 'none';
|
||||
ui.platformViewRegistry.registerViewFactory(
|
||||
'iframeElement',
|
||||
(int viewId) => _iframeElement,
|
||||
);
|
||||
return HtmlElementView(
|
||||
key: UniqueKey(),
|
||||
viewType: 'iframeElement',
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -57,7 +57,7 @@ class Util {
|
||||
);
|
||||
},
|
||||
errorBuilder: (BuildContext context, Object object, StackTrace stackTrace) {
|
||||
print(stackTrace);
|
||||
print('StackTrace: $stackTrace');
|
||||
if (errorWidget != null) {
|
||||
return errorWidget(context, null, null);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
@@ -36,6 +37,142 @@ typedef void OnOk();
|
||||
typedef void OnLoadImageError();
|
||||
|
||||
class Utils {
|
||||
static StreamSubscription onProductWillAddToCartSubscription;
|
||||
static StreamSubscription onProductWillRemoveFromCartSubscription;
|
||||
|
||||
init() async {
|
||||
onProductWillAddToCartSubscription =
|
||||
eventBus.on<OnProductWillAddToCart>().listen((event) {
|
||||
CartInfo cartInfo =
|
||||
getCartInfoByBusiness(store.state.cartInfos, event.business);
|
||||
|
||||
if (cartInfo == null || cartInfo.productList.length == 0) {
|
||||
cartInfo = CartInfo();
|
||||
cartInfo.id = 0;
|
||||
cartInfo.amountPaid = 0.0;
|
||||
cartInfo.businessInfo = event.business;
|
||||
cartInfo.extraFeeList = [];
|
||||
cartInfo.discountList = [];
|
||||
CartLineItem lineItem = newCartLineItem(
|
||||
id: 0,
|
||||
price: event.price,
|
||||
product: event.product,
|
||||
name: event.product.name,
|
||||
description: event.description,
|
||||
quantity: 1.0);
|
||||
cartInfo.productList = [lineItem];
|
||||
addSubproductToCard(cartInfo, lineItem);
|
||||
store.dispatch(new UpdateCartInfo(addCartInfoToCartInfoList(
|
||||
store.state.cartInfos, cartInfo)));
|
||||
eventBus.fire(new OnCartInfoUpdated());
|
||||
print('#1');
|
||||
} else {
|
||||
if (event.product.productAttributes.length > 0) {
|
||||
CartLineItem lineItem = newCartLineItem(
|
||||
id: 0,
|
||||
price: event.price,
|
||||
product: event.product,
|
||||
name: event.product.name,
|
||||
description: event.description,
|
||||
quantity: 1.0);
|
||||
cartInfo.productList.add(lineItem);
|
||||
addSubproductToCard(cartInfo, lineItem);
|
||||
store.dispatch(new UpdateCartInfo(addCartInfoToCartInfoList(
|
||||
store.state.cartInfos, cartInfo)));
|
||||
print('#2');
|
||||
eventBus.fire(new OnCartInfoUpdated());
|
||||
} else {
|
||||
int found = -1;
|
||||
for (var i = 0; i < cartInfo.productList.length; i++) {
|
||||
if (event.product.id == cartInfo.productList[i].product.id) {
|
||||
found = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found == -1) {
|
||||
CartLineItem lineItem = newCartLineItem(
|
||||
id: 0,
|
||||
price: event.price,
|
||||
product: event.product,
|
||||
name: event.product.name,
|
||||
description: event.description,
|
||||
quantity: 1.0);
|
||||
cartInfo.productList.add(lineItem);
|
||||
addSubproductToCard(cartInfo, lineItem);
|
||||
store.dispatch(new UpdateCartInfo(addCartInfoToCartInfoList(
|
||||
store.state.cartInfos, cartInfo)));
|
||||
print('#3');
|
||||
eventBus.fire(new OnCartInfoUpdated());
|
||||
} else {
|
||||
if (cartInfo.productList[found].quantity + 1.0 >
|
||||
event.product.leftNum) {
|
||||
// Fluttertoast.showToast(
|
||||
// msg: S.of(context).product_insufficient,
|
||||
// toastLength: Toast.LENGTH_SHORT,
|
||||
// gravity: ToastGravity.CENTER,
|
||||
// backgroundColor: Colors.red,
|
||||
// textColor: Colors.white);
|
||||
} else {
|
||||
cartInfo.productList[found].quantity += 1;
|
||||
addSubproductQty(cartInfo, cartInfo.productList[found]);
|
||||
store.dispatch(new UpdateCartInfo(
|
||||
addCartInfoToCartInfoList(
|
||||
store.state.cartInfos, cartInfo)));
|
||||
print('#4');
|
||||
eventBus.fire(new OnCartInfoUpdated());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
onProductWillRemoveFromCartSubscription =
|
||||
eventBus.on<OnProductWillRemoveFromCart>().listen((event) {
|
||||
CartInfo cartInfo =
|
||||
getCartInfoByBusiness(store.state.cartInfos, event.business);
|
||||
if (cartInfo != null) {
|
||||
if (cartInfo.productList.length > 0) {
|
||||
if (event.productListIndex != -1) {
|
||||
if (cartInfo.productList[event.productListIndex].quantity <= 1) {
|
||||
String uuid = cartInfo.productList[event.productListIndex].uuid;
|
||||
cartInfo.productList.removeAt(event.productListIndex);
|
||||
removeSubproduct(cartInfo, uuid);
|
||||
} else {
|
||||
cartInfo.productList[event.productListIndex].quantity -= 1;
|
||||
addSubproductQty(cartInfo, cartInfo.productList[event.productListIndex], remove: true);
|
||||
}
|
||||
} else {
|
||||
int productListIndex = -1;
|
||||
for (var i = 0; i < cartInfo.productList.length; i++) {
|
||||
if (cartInfo.productList[i].product.id == event.product.id) {
|
||||
productListIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (productListIndex != -1) {
|
||||
if (cartInfo.productList[productListIndex].quantity <= 1) {
|
||||
String uuid = cartInfo.productList[productListIndex].uuid;
|
||||
cartInfo.productList.removeAt(productListIndex);
|
||||
removeSubproduct(cartInfo, uuid);
|
||||
} else {
|
||||
cartInfo.productList[productListIndex].quantity -= 1;
|
||||
addSubproductQty(cartInfo, cartInfo.productList[productListIndex], remove: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cartInfo.productList.length <= 0) {
|
||||
store.dispatch(UpdateCartInfo(removeCartInfoFromCartInfoList(
|
||||
store.state.cartInfos, cartInfo)));
|
||||
} else {
|
||||
store.dispatch(UpdateCartInfo(addCartInfoToCartInfoList(
|
||||
store.state.cartInfos, cartInfo)));
|
||||
}
|
||||
eventBus.fire(new OnCartInfoUpdated());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static bool equalsIgnoreCase(String a, String b) =>
|
||||
(a == null && b == null) ||
|
||||
(a != null && b != null && a.toLowerCase() == b.toLowerCase());
|
||||
@@ -373,6 +510,8 @@ class Utils {
|
||||
message = error.response.data.toString();
|
||||
}
|
||||
}
|
||||
} else if (error is String) {
|
||||
message = '$error';
|
||||
} else if (error.message != null) {
|
||||
message = error.message;
|
||||
} else {
|
||||
@@ -642,7 +781,8 @@ class Utils {
|
||||
}
|
||||
|
||||
static void loadProducts(int businessId, int categoryId, int page, bool more,
|
||||
OnComplete onComplete, OnError onError) {
|
||||
OnComplete onComplete, OnError onError, {int featuredCount=4, int hotSaleCount=4, String keyword=''}) {
|
||||
print('feature $featuredCount');
|
||||
HttpUtil.httpGet(
|
||||
more ? 'v1/service-category-products-more' : 'v1/service-category-products',
|
||||
businessId: businessId,
|
||||
@@ -650,9 +790,12 @@ class Utils {
|
||||
// 'lat': store.state.position.latitude.toString(),
|
||||
// 'lng': store.state.position.longitude.toString(),
|
||||
'category_id': categoryId,
|
||||
'preview': 'no',
|
||||
'preview': Constants.isPreview,
|
||||
'page': page,
|
||||
'num_per_page': Constants.ORDERS_PER_PAGE,
|
||||
'featured_count': featuredCount,
|
||||
'hot_sale_count': hotSaleCount,
|
||||
'keyword': Uri.encodeComponent(keyword),
|
||||
},
|
||||
).then((value) {
|
||||
if (onComplete != null) {
|
||||
@@ -667,6 +810,9 @@ class Utils {
|
||||
|
||||
static String timestampToString(BuildContext context, int timestamp, {bool withTime=false}) {
|
||||
DateTime date = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
|
||||
if (timestamp == 0) {
|
||||
return '';
|
||||
}
|
||||
return datetimeFormat(context, date, withTime: withTime);
|
||||
}
|
||||
|
||||
@@ -966,6 +1112,10 @@ class Utils {
|
||||
child: row,
|
||||
);
|
||||
}
|
||||
|
||||
static int getBusinessId() {
|
||||
return Constants.BUSINESS_ID;
|
||||
}
|
||||
}
|
||||
|
||||
class RuntimeError extends Error {
|
||||
|
||||
464
lib/widgets/desktop/create_online_store_1.dart
Normal file
464
lib/widgets/desktop/create_online_store_1.dart
Normal file
@@ -0,0 +1,464 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../constants.dart';
|
||||
import '../../generated/l10n.dart';
|
||||
import '../../models/group.dart';
|
||||
import '../../pages/buy_service.dart';
|
||||
import '../../routes.dart';
|
||||
import '../../utils/http_util.dart';
|
||||
import '../../utils/utils.dart';
|
||||
import '../../widgets/general/bottom_nav.dart';
|
||||
import '../../widgets/general/breadcrumbs.dart';
|
||||
import '../../widgets/general/navigationbar.dart';
|
||||
|
||||
class CreateOnlineStore1 extends StatefulWidget {
|
||||
final int businessId;
|
||||
|
||||
const CreateOnlineStore1(this.businessId, {Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return CreateOnlineStore1State();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class CreateOnlineStore1State extends State<CreateOnlineStore1> {
|
||||
double sideSpace = 0;
|
||||
double mainSpace = 1200;
|
||||
|
||||
TextEditingController groupNumberController = TextEditingController();
|
||||
|
||||
TextEditingController domainController = TextEditingController();
|
||||
|
||||
bool canSubmit = false;
|
||||
|
||||
List<dynamic> stores = [];
|
||||
Map<String, dynamic> service;
|
||||
dynamic selectedStore;
|
||||
|
||||
Group group;
|
||||
|
||||
String selectedDomain;
|
||||
List<dynamic> domainResult = [];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (MediaQuery
|
||||
.of(context)
|
||||
.size
|
||||
.width <= 1200) {
|
||||
mainSpace = MediaQuery
|
||||
.of(context)
|
||||
.size
|
||||
.width;
|
||||
sideSpace = 0;
|
||||
} else {
|
||||
mainSpace = 1200;
|
||||
sideSpace = (MediaQuery
|
||||
.of(context)
|
||||
.size
|
||||
.width - 1200) / 2;
|
||||
}
|
||||
|
||||
Row row = Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [],
|
||||
);
|
||||
|
||||
row.children.add(
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(
|
||||
left: 16.0, right: 16.0, top: 20, bottom: 20),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.only(bottom: 4.0),
|
||||
child: Text(
|
||||
S.of(context).open_online_store,
|
||||
style: TextStyle(
|
||||
fontSize: 28,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 4, bottom: 4),
|
||||
child: Text(
|
||||
S.of(context)
|
||||
.select_a_store,
|
||||
style: TextStyle(
|
||||
color: Colors.black45,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 4),
|
||||
child: DropdownButton<dynamic>(
|
||||
items: stores.map((e) => DropdownMenuItem<dynamic>(
|
||||
value: e,
|
||||
child: Text(e['name']),
|
||||
)).toList(),
|
||||
isExpanded: false,
|
||||
hint: Text(S.of(context).select_a_store),
|
||||
onChanged: (newValue) {
|
||||
print('newValue $newValue');
|
||||
setState(() {
|
||||
selectedStore = newValue;
|
||||
});
|
||||
},
|
||||
value: selectedStore,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
right: BorderSide(
|
||||
width: 1,
|
||||
color: Colors.black12,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
row.children.add(
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(
|
||||
left: 16.0, right: 16.0, top: 20, bottom: 20),
|
||||
child: Visibility(
|
||||
child: getSearchDomainWidget(),
|
||||
visible: selectedStore != null,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return Scaffold(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S
|
||||
.of(context)
|
||||
.blog,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
BreadCrumb(S
|
||||
.of(context)
|
||||
.open_online_store, null),
|
||||
],
|
||||
breadCrumbHeight: Constants.BREADCRUMB_HEIGHT,
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: sideSpace,
|
||||
),
|
||||
Expanded(child: row,),
|
||||
Container(
|
||||
width: sideSpace,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
bottomNavigationBar: BottomNav(),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getSearchDomainWidget() {
|
||||
if (selectedStore == null) {
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
Column col = Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [],
|
||||
);
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(bottom: 4,),
|
||||
child: Text(selectedStore == null ? '' : selectedStore['name'],
|
||||
style: TextStyle(
|
||||
fontSize: 28,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
Map<String, dynamic> existing_web_svc;
|
||||
if (selectedStore != null && (selectedStore['services'] as List).length > 0) {
|
||||
for (Map<String, dynamic>svc in (selectedStore['services'] as List)) {
|
||||
if (svc['code'] == Constants.WEB_MINISTORE_SERVICE) {
|
||||
existing_web_svc = svc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (existing_web_svc != null) {
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 8.0),
|
||||
child: Text(
|
||||
'${existing_web_svc['description']}',
|
||||
),
|
||||
),
|
||||
);
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 4.0),
|
||||
child: Text(
|
||||
S.of(context).expiration_date + ": "
|
||||
+ Utils.utcDatetimeStringToLocalDatetimeString(context, existing_web_svc['expiration_date']),
|
||||
),
|
||||
),
|
||||
);
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 4.0),
|
||||
child: Text(
|
||||
S.of(context).store + ": " + '${existing_web_svc['store']['name']}'
|
||||
),
|
||||
),
|
||||
);
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 4.0),
|
||||
child: Text(
|
||||
S.of(context).domain_name + ": " + '${existing_web_svc['domain']}'
|
||||
),
|
||||
),
|
||||
);
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 10.0),
|
||||
child: ElevatedButton(
|
||||
child: Text(S.of(context).renew_service_now),
|
||||
onPressed: () {
|
||||
Navigator.pushReplacement(context, MaterialPageRoute(
|
||||
builder: (BuildContext context) =>
|
||||
BuyService(group.id, Constants.WEB_MINISTORE_SERVICE,
|
||||
domain: existing_web_svc['domain'],
|
||||
sid: existing_web_svc['store']['id'],
|
||||
),
|
||||
));
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 8.0),
|
||||
child: Text(S.of(context).enter_desired_domain),
|
||||
),
|
||||
);
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 0,),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
controller: domainController,
|
||||
decoration: new InputDecoration(
|
||||
enabledBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Colors.black12,
|
||||
),
|
||||
),
|
||||
focusedBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Colors.blue,
|
||||
),
|
||||
),
|
||||
labelText: S.of(context).domains_separated_comma,
|
||||
),
|
||||
style: TextStyle(
|
||||
fontSize: 18.0
|
||||
),
|
||||
autofocus: true,
|
||||
validator: (String value) {
|
||||
if (value.trim().isEmpty) {
|
||||
return S.of(context).domains_separated_comma;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
onChanged: (string) {
|
||||
if (string.isNotEmpty) {
|
||||
canSubmit = true;
|
||||
} else {
|
||||
canSubmit = false;
|
||||
}
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 8.0),
|
||||
child: ElevatedButton(
|
||||
child: Text(
|
||||
S.of(context).check_domain_name,
|
||||
),
|
||||
onPressed: domainController.text.length > 0 ? checkDomainAvailability : null,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
);
|
||||
if (domainResult.length > 0) {
|
||||
for (dynamic dr in domainResult) {
|
||||
col.children.add(_getDomain(dr));
|
||||
}
|
||||
}
|
||||
if (selectedDomain != null && service != null) {
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 8.0),
|
||||
child: Text(
|
||||
service['description'],
|
||||
),
|
||||
),
|
||||
);
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 8.0),
|
||||
child: Text(
|
||||
service['options'][0]['name'],
|
||||
),
|
||||
),
|
||||
);
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 8.0),
|
||||
child: Text(
|
||||
'\$${service['options'][0]['price']}',
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.orange,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 10.0),
|
||||
child: ElevatedButton(
|
||||
child: Text(
|
||||
S.of(context).place_order_now,
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.pushReplacement(context, MaterialPageRoute(
|
||||
builder: (BuildContext context) =>
|
||||
BuyService(group.id, Constants.WEB_MINISTORE_SERVICE,
|
||||
domain: selectedDomain,
|
||||
sid: selectedStore['id'],
|
||||
),
|
||||
));
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
return Container(
|
||||
padding: EdgeInsets.only(bottom: 4,),
|
||||
child: col,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
HttpUtil.httpGet(
|
||||
'v1/get-contact-stores',
|
||||
queryParameters: {
|
||||
'service': Constants.WEB_MINISTORE_SERVICE
|
||||
}
|
||||
).then((value) {
|
||||
setState(() {
|
||||
stores = value['stores'];
|
||||
service = value['service'];
|
||||
group = Group.fromJson(value['group']);
|
||||
print('stores: ${value}');
|
||||
});
|
||||
}).onError((error, stackTrace) {
|
||||
Utils.showMessageDialog(context, error, onOk: () {
|
||||
Routes.router.navigateTo(context, '/');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> checkDomainAvailability() async {
|
||||
Utils.showLoadingDialog(context);
|
||||
selectedDomain = null;
|
||||
domainResult = [];
|
||||
setState(() {});
|
||||
HttpUtil.httpGet(
|
||||
'v1/check-domain-availability',
|
||||
queryParameters: {
|
||||
'domain': domainController.text,
|
||||
},
|
||||
).then((value) {
|
||||
Routes.router.pop(context);
|
||||
print('value: $value');
|
||||
if (value['status'] == 'OK') {
|
||||
domainResult = (value['domain_check_result'] as List);
|
||||
setState(() {});
|
||||
} else if (value['status'] == 'ERROR') {
|
||||
String errors = '';
|
||||
for (int i = 0; i < (value['errors'] as List).length; i++) {
|
||||
errors += value['errors'][i] + '\n';
|
||||
}
|
||||
Utils.showMessageDialog(context, errors);
|
||||
}
|
||||
}).onError((error, stackTrace) {
|
||||
Routes.router.pop(context);
|
||||
Utils.showMessageDialog(context, error);
|
||||
});
|
||||
}
|
||||
|
||||
Widget _getDomain(dynamic d) {
|
||||
if ((d['available'] as bool)) {
|
||||
return Container(
|
||||
child: ListTile(
|
||||
title: Text(
|
||||
d['domain'],
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
leading: Radio(
|
||||
value: d['domain'],
|
||||
groupValue: selectedDomain,
|
||||
onChanged: (val) {
|
||||
setState(() {
|
||||
selectedDomain = val;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(top: 1.0),
|
||||
child: ListTile(
|
||||
title: Text(
|
||||
d['domain'],
|
||||
style: TextStyle(
|
||||
color: Colors.black45,
|
||||
),
|
||||
),
|
||||
leading: Icon(Icons.clear, color: Colors.red,),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,8 @@ class DesktopAppBarMenu extends StatelessWidget {
|
||||
TextLink(
|
||||
S.of(context).home,
|
||||
'/',
|
||||
color: Colors.white,
|
||||
color: Colors.white60,
|
||||
hoverColor: Colors.white,
|
||||
selected: currentRoute == '/',
|
||||
clearStack: true,
|
||||
),
|
||||
@@ -47,14 +48,16 @@ class DesktopAppBarMenu extends StatelessWidget {
|
||||
TextLink(
|
||||
S.of(context).download,
|
||||
'/download',
|
||||
color: Colors.white,
|
||||
color: Colors.white60,
|
||||
hoverColor: Colors.white,
|
||||
selected: currentRoute == '/download',
|
||||
),
|
||||
SizedBox(width: 15.0,),
|
||||
TextLink(
|
||||
S.of(context).tutorials,
|
||||
Constants.TUTORIAL_URL,
|
||||
color: Colors.white,
|
||||
color: Colors.white60,
|
||||
hoverColor: Colors.white,
|
||||
selected: currentRoute == '/tutorials',
|
||||
isLink: true,
|
||||
),
|
||||
@@ -62,21 +65,24 @@ class DesktopAppBarMenu extends StatelessWidget {
|
||||
TextLink(
|
||||
S.of(context).support,
|
||||
'/my-support/${Constants.BUSINESS_ID}',
|
||||
color: Colors.white,
|
||||
color: Colors.white60,
|
||||
hoverColor: Colors.white,
|
||||
selected: currentRoute == '/my-support/${Constants.BUSINESS_ID}',
|
||||
),
|
||||
SizedBox(width: 15.0,),
|
||||
TextLink(
|
||||
S.of(context).shop,
|
||||
'/shop',
|
||||
color: Colors.white,
|
||||
color: Colors.white60,
|
||||
hoverColor: Colors.white,
|
||||
selected: currentRoute == '/shop',
|
||||
),
|
||||
SizedBox(width: 15.0,),
|
||||
TextLink(
|
||||
S.of(context).blog,
|
||||
'/blog/${Constants.BUSINESS_ID}',
|
||||
color: Colors.white,
|
||||
color: Colors.white60,
|
||||
hoverColor: Colors.white,
|
||||
selected: currentRoute == '/blog/${Constants.BUSINESS_ID}',
|
||||
),
|
||||
SizedBox(width: 15.0,),
|
||||
@@ -126,7 +132,8 @@ class DesktopAppBarMenu extends StatelessWidget {
|
||||
TextLink(
|
||||
S.of(context).login,
|
||||
'/login',
|
||||
color: Colors.white,
|
||||
color: Colors.white60,
|
||||
hoverColor: Colors.white,
|
||||
selected: currentRoute == '/login',
|
||||
),
|
||||
],
|
||||
|
||||
@@ -85,7 +85,7 @@ class DesktopBlogState extends State<DesktopBlog> {
|
||||
BuildContext mainContext = context;
|
||||
|
||||
return Scaffold(
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).blog,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
@@ -272,6 +272,7 @@ class DesktopBlogState extends State<DesktopBlog> {
|
||||
'size': Constants.BLOG_PER_PAGE_DESKTOP.toString()
|
||||
}
|
||||
).then((value) {
|
||||
print('value: $value');
|
||||
if (mounted) {
|
||||
if (isRefresh) {
|
||||
_refreshController.refreshCompleted();
|
||||
|
||||
@@ -72,6 +72,18 @@ class DesktopBuyServiceState extends State<DesktopBuyService> {
|
||||
Utils.buildLine(S.of(context).your_group, widget.data['group']['name'], valueSize: 16),
|
||||
);
|
||||
|
||||
if (widget.data['store']['id'] != null) {
|
||||
col1.children.add(
|
||||
Utils.buildLine(S.of(context).store, widget.data['store']['name'], valueSize: 16),
|
||||
);
|
||||
}
|
||||
|
||||
if (widget.data['domain'] != null) {
|
||||
col1.children.add(
|
||||
Utils.buildLine(S.of(context).domain_name, widget.data['domain'], valueSize: 16),
|
||||
);
|
||||
}
|
||||
|
||||
if (widget.data['exists_service'] == null) {
|
||||
col1.children.add(
|
||||
Utils.buildLine(S.of(context).current_plan, 'N/A', valueSize: 16),
|
||||
@@ -171,7 +183,7 @@ class DesktopBuyServiceState extends State<DesktopBuyService> {
|
||||
);
|
||||
|
||||
return Scaffold(
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).blog,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -178,7 +178,7 @@ class DesktopCheckoutState extends State<DesktopCheckout> with SingleTickerProvi
|
||||
|
||||
Scaffold scaffold = Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).blog,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
@@ -355,6 +355,7 @@ class DesktopCheckoutState extends State<DesktopCheckout> with SingleTickerProvi
|
||||
check();
|
||||
},
|
||||
initialLabelIndex: deliveryMethodIndex,
|
||||
totalSwitches: shippingMethodLabels.length,
|
||||
);
|
||||
switch (position) {
|
||||
case 0:
|
||||
|
||||
@@ -329,7 +329,7 @@ class DesktopContactUsState extends State<DesktopContactUs> {
|
||||
);
|
||||
}
|
||||
return Scaffold(
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).blog,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -78,7 +78,7 @@ class DesktopCouponsState extends State<DesktopCoupons> {
|
||||
);
|
||||
|
||||
return Scaffold(
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).blog,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -399,7 +399,7 @@ class DesktopEditAddressState extends State<DesktopEditAddress> {
|
||||
);
|
||||
|
||||
return Scaffold(
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).edit_address,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -101,7 +101,8 @@ class DesktopIndexMainContent3State extends State<DesktopIndexMainContent3> {
|
||||
TextLink(S.of(context).support_ticket, '/my-support/${Constants.BUSINESS_ID}', paddingVertical: 5.0, paddingHorizontal: 10.0,),
|
||||
TextLink(S.of(context).contact_us, '/contact-us', paddingVertical: 5.0, paddingHorizontal: 10.0,),
|
||||
TextLink(S.of(context).about_us, '/about-us', paddingVertical: 5.0, paddingHorizontal: 10.0,),
|
||||
TextLink(S.of(context).renew_license, '/renew-license', paddingVertical: 5.0, paddingHorizontal: 10.0,)
|
||||
TextLink(S.of(context).renew_license, '/renew-license', paddingVertical: 5.0, paddingHorizontal: 10.0,),
|
||||
TextLink(S.of(context).create_a_online_store, '/contact-stores', paddingVertical: 5.0, paddingHorizontal: 10.0,)
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -250,7 +251,8 @@ class DesktopIndexMainContent3State extends State<DesktopIndexMainContent3> {
|
||||
TextLink(S.of(context).support_ticket, '/my-support/${Constants.BUSINESS_ID}', paddingVertical: 5.0, paddingHorizontal: 0.0,),
|
||||
TextLink(S.of(context).contact_us, '/contact-us', paddingVertical: 5.0, paddingHorizontal: 0.0,),
|
||||
TextLink(S.of(context).about_us, '/about-us', paddingVertical: 5.0, paddingHorizontal: 0.0,),
|
||||
TextLink(S.of(context).renew_license, '/renew-license', paddingVertical: 5.0, paddingHorizontal: 0.0,)
|
||||
TextLink(S.of(context).renew_license, '/renew-license', paddingVertical: 5.0, paddingHorizontal: 0.0,),
|
||||
TextLink(S.of(context).create_a_online_store, '/contact-stores', paddingVertical: 5.0, paddingHorizontal: 0.0,)
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -63,7 +63,7 @@ class DesktopMyAddressesState extends State<DesktopMyAddresses> {
|
||||
BuildContext mainContext = context;
|
||||
|
||||
return Scaffold(
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).my_addresses,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -48,7 +48,7 @@ class MyCardsState extends State<DesktopMyCards> {
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).blog,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -88,7 +88,7 @@ class DesktopMySupportState extends State<DesktopMySupport> {
|
||||
BuildContext mainContext = context;
|
||||
|
||||
return Scaffold(
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).my_support,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -2,28 +2,25 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_wisetronic/widgets/desktop/desktop_appbar_menu.dart';
|
||||
import '../../widgets/general/breadcrumbs.dart';
|
||||
|
||||
import '../../constants.dart';
|
||||
import '../../dialog/logout_dialog.dart';
|
||||
import '../../events/eventbus.dart';
|
||||
import '../../events/events.dart';
|
||||
import '../../generated/l10n.dart';
|
||||
import '../../models/user.dart';
|
||||
import '../../routes.dart';
|
||||
import '../../store/store.dart';
|
||||
import '../../utils/utils.dart';
|
||||
import '../../widgets/general/navigationbar_logo.dart';
|
||||
import '../../widgets/general/text_link.dart';
|
||||
import '../../widgets/desktop/desktop_appbar_menu.dart';
|
||||
import '../../widgets/general/breadcrumbs.dart';
|
||||
import '../../widgets/general/navigationbar.dart';
|
||||
|
||||
class DesktopNavigationBar extends StatefulWidget {
|
||||
final bool hasBack;
|
||||
final List<BreadCrumb> breadCrumbs;
|
||||
final Widget shoppingCart;
|
||||
final OnBackPress onBackPress;
|
||||
|
||||
const DesktopNavigationBar({Key key, this.hasBack, this.breadCrumbs,
|
||||
this.shoppingCart}) : super(key: key);
|
||||
this.shoppingCart, this.onBackPress}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -37,132 +34,6 @@ class DesktopNavigationBarState extends State<DesktopNavigationBar> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// String currentRoute = ModalRoute.of(context).settings.name;
|
||||
// Stack stack = Stack(
|
||||
// children: [
|
||||
// Container(
|
||||
// color: Colors.blue,
|
||||
// height: 80.0,
|
||||
// ),
|
||||
// Container(
|
||||
// height: 80.0,
|
||||
// padding: EdgeInsets.only(left: 10.0, right: 10.0, top: 5.0, bottom: 5.0),
|
||||
// child: Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
// children: [
|
||||
// NavigationBarLogo(),
|
||||
// Expanded(
|
||||
// child: Container(
|
||||
// alignment: Alignment.centerRight,
|
||||
// padding: EdgeInsets.only(left: 8.0, right: 16.0),
|
||||
// child: SingleChildScrollView(
|
||||
// scrollDirection: Axis.horizontal,
|
||||
// child: Row(
|
||||
// mainAxisSize: MainAxisSize.min,
|
||||
// children: [
|
||||
// SizedBox(width: 20.0,),
|
||||
// TextLink(
|
||||
// S.of(context).home,
|
||||
// '/',
|
||||
// color: Colors.white,
|
||||
// selected: currentRoute == '/',
|
||||
// clearStack: true,
|
||||
// ),
|
||||
// SizedBox(width: 15.0,),
|
||||
// TextLink(
|
||||
// S.of(context).download,
|
||||
// '/download',
|
||||
// color: Colors.white,
|
||||
// selected: currentRoute == '/download',
|
||||
// ),
|
||||
// SizedBox(width: 15.0,),
|
||||
// TextLink(
|
||||
// S.of(context).tutorials,
|
||||
// '/tutorials',
|
||||
// color: Colors.white,
|
||||
// selected: currentRoute == '/tutorials',
|
||||
// ),
|
||||
// SizedBox(width: 15.0,),
|
||||
// TextLink(
|
||||
// S.of(context).support,
|
||||
// '/my-support/${Constants.BUSINESS_ID}',
|
||||
// color: Colors.white,
|
||||
// selected: currentRoute == '/my-support/${Constants.BUSINESS_ID}',
|
||||
// ),
|
||||
// SizedBox(width: 15.0,),
|
||||
// TextLink(
|
||||
// S.of(context).shop,
|
||||
// '/shop',
|
||||
// color: Colors.white,
|
||||
// selected: currentRoute == '/shop',
|
||||
// ),
|
||||
// SizedBox(width: 15.0,),
|
||||
// TextLink(
|
||||
// S.of(context).blog,
|
||||
// '/blog/${Constants.BUSINESS_ID}',
|
||||
// color: Colors.white,
|
||||
// selected: currentRoute == '/blog/${Constants.BUSINESS_ID}',
|
||||
// ),
|
||||
// SizedBox(width: 15.0,),
|
||||
// _user != null ?
|
||||
// (currentRoute == '/me') ?
|
||||
// MouseRegion(
|
||||
// cursor: SystemMouseCursors.click,
|
||||
// child: GestureDetector(
|
||||
// child: Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.start,
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// Container(
|
||||
// padding: EdgeInsets.only(right: 4.0),
|
||||
// child: Text(
|
||||
// S.of(context).logout,
|
||||
// style: TextStyle(
|
||||
// color: Colors.white,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// Icon(
|
||||
// Icons.logout,
|
||||
// color: Colors.white,
|
||||
// size: 16.0,
|
||||
// )
|
||||
// ],
|
||||
// ),
|
||||
// onTap: () {
|
||||
// showDialog(
|
||||
// context: context,
|
||||
// builder: (BuildContext context) {
|
||||
// return logoutDialog(context);
|
||||
// }
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// ) : IconButton(
|
||||
// icon: Icon(
|
||||
// Icons.account_circle,
|
||||
// color: Colors.white,
|
||||
// ),
|
||||
// onPressed: () {
|
||||
// Routes.router.navigateTo(context, '/me');
|
||||
// },
|
||||
// ) :
|
||||
// TextLink(
|
||||
// S.of(context).login,
|
||||
// '/login',
|
||||
// color: Colors.white,
|
||||
// selected: currentRoute == '/login',
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
Widget sc = SizedBox.shrink();
|
||||
if (widget.shoppingCart != null) {
|
||||
sc = widget.shoppingCart;
|
||||
@@ -171,8 +42,8 @@ class DesktopNavigationBarState extends State<DesktopNavigationBar> {
|
||||
if (widget.breadCrumbs != null && widget.breadCrumbs.length > 0) {
|
||||
breadCrumbBar = Container(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
height: 38.0,
|
||||
color: Color(0xFF4FB0C6),
|
||||
height: Constants.BREADCRUMB_HEIGHT,
|
||||
padding: EdgeInsets.only(top: 6.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -180,6 +51,7 @@ class DesktopNavigationBarState extends State<DesktopNavigationBar> {
|
||||
Expanded(
|
||||
child: BreadCrumbs(
|
||||
widget.hasBack ?? false,
|
||||
onBackPress: widget.onBackPress,
|
||||
breadCrumbs: widget.breadCrumbs,
|
||||
),
|
||||
),
|
||||
@@ -189,14 +61,18 @@ class DesktopNavigationBarState extends State<DesktopNavigationBar> {
|
||||
),
|
||||
],
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black12,
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
width: 1.0,
|
||||
color: Colors.black26,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
// stack.children.add(
|
||||
// Positioned(
|
||||
// top: 90.0,
|
||||
// child: breadCrumbBar,
|
||||
// ),
|
||||
// );
|
||||
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
|
||||
@@ -324,7 +324,7 @@ class DesktopNewAddressState extends State<DesktopNewAddress> {
|
||||
);
|
||||
|
||||
return Scaffold(
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).new_address,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -62,7 +62,7 @@ class DesktopNewCommentState extends State<DesktopNewComment> {
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).new_comment,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -958,7 +958,7 @@ class DesktopOrderDetailState extends State<DesktopOrderDetail> {
|
||||
);
|
||||
|
||||
return Scaffold(
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).blog,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -98,7 +98,7 @@ class DesktopOrdersState extends State<DesktopOrders> with SingleTickerProviderS
|
||||
|
||||
return Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).blog,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -345,7 +345,7 @@ class DesktopPayNowState extends State<DesktopPayNow> {
|
||||
);
|
||||
|
||||
return Scaffold(
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).blog,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -60,7 +60,7 @@ class DesktopPlainPageState extends State<DesktopPlainPage> {
|
||||
));
|
||||
|
||||
return Scaffold(
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).blog,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -79,7 +79,7 @@ class DesktopProductDetailPageState extends State<DesktopProductDetailPage>
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).shop,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -167,7 +167,7 @@ class DesktopRenewLicenseState extends State<DesktopRenewLicense> {
|
||||
);
|
||||
|
||||
return Scaffold(
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).blog,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -136,7 +136,7 @@ class DesktopRenewMiniOfficeState extends State<DesktopRenewMiniOffice> {
|
||||
);
|
||||
|
||||
return Scaffold(
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).blog,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -45,7 +45,7 @@ class DesktopSearchPlaceState extends State<DesktopSearchPlace> {
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).search_place,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -288,7 +288,7 @@ class DesktopSetPasswordState extends State<DesktopSetPassword> {
|
||||
);
|
||||
},
|
||||
queryParameters: {
|
||||
'action': 'reset_password',
|
||||
'action': 'create_user',
|
||||
},
|
||||
isFormData: true,
|
||||
body: {
|
||||
|
||||
@@ -109,7 +109,7 @@ class DesktopStripePayWebState extends State<DesktopStripePayWeb> {
|
||||
|
||||
return Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: NavigationBar(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).blog,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
|
||||
import '../../constants.dart';
|
||||
import '../../utils/iframe_web.dart' if (dart.library.io) '../../utils/fake_iframe_web.dart';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||
|
||||
class DesktopTutorials extends StatefulWidget {
|
||||
const DesktopTutorials({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return DesktopTutorialsState();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DesktopTutorialsState extends State<DesktopTutorials> {
|
||||
double sideSpace = 0;
|
||||
double mainSpace = 1200;
|
||||
|
||||
InAppWebViewController webView;
|
||||
String url = "";
|
||||
double progress = 0;
|
||||
bool isLoadStop = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (MediaQuery.of(context).size.width <= 1200) {
|
||||
mainSpace = MediaQuery.of(context).size.width;
|
||||
sideSpace = 0;
|
||||
} else {
|
||||
mainSpace = 1200;
|
||||
sideSpace = (MediaQuery.of(context).size.width - 1200) / 2;
|
||||
}
|
||||
|
||||
if (kIsWeb) {
|
||||
return Row(
|
||||
children: [
|
||||
Container(
|
||||
width: sideSpace,
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Expanded(
|
||||
child: IFrameWeb(
|
||||
width: double.maxFinite.toString(),
|
||||
height: double.maxFinite.toString(),
|
||||
src: Constants.TUTORIAL_URL,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: sideSpace,
|
||||
),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
print('progress: $progress');
|
||||
return Stack(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
width: sideSpace,
|
||||
),
|
||||
Expanded(
|
||||
child: InAppWebView(
|
||||
initialUrlRequest: URLRequest(url: Uri.parse(Constants.TUTORIAL_URL)),
|
||||
initialOptions: InAppWebViewGroupOptions(
|
||||
crossPlatform: InAppWebViewOptions(
|
||||
|
||||
),
|
||||
),
|
||||
onWebViewCreated: (InAppWebViewController controller) {
|
||||
webView = controller;
|
||||
},
|
||||
onLoadStart: (controller, url) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
this.url = url.toString();
|
||||
this.isLoadStop = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
onLoadStop: (controller, url) async {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
this.url = url.toString();
|
||||
this.isLoadStop = true;
|
||||
});
|
||||
}
|
||||
},
|
||||
onProgressChanged: (InAppWebViewController controller, int progress) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
if (this.progress < 1.0) {
|
||||
this.isLoadStop = false;
|
||||
} else {
|
||||
this.isLoadStop = true;
|
||||
}
|
||||
this.progress = progress / 100;
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: sideSpace,
|
||||
),
|
||||
],
|
||||
),
|
||||
isLoadStop ? Container() :
|
||||
Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,6 +13,8 @@ import '../../utils/http_util.dart';
|
||||
import '../../utils/utils.dart';
|
||||
import '../../widgets/general/breadcrumbs.dart';
|
||||
|
||||
import '../../utils/util_io.dart' if (dart.library.html) '../../utils/util_web.dart';
|
||||
|
||||
class DesktopViewBlog extends StatefulWidget {
|
||||
final Key key;
|
||||
final int bid;
|
||||
@@ -172,11 +174,7 @@ class DesktopViewBlogState extends State<DesktopViewBlog> {
|
||||
: Container(
|
||||
width: mainSpace / 2 - 100.0,
|
||||
height: mainSpace / 2 - 100.0,
|
||||
child: PhotoView(
|
||||
imageProvider: NetworkImage(
|
||||
'https:${blog.imageUrl}',
|
||||
),
|
||||
),
|
||||
child: Util.showImage('https:${blog.imageUrl}'),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
280
lib/widgets/desktop/product_item.dart
Normal file
280
lib/widgets/desktop/product_item.dart
Normal file
@@ -0,0 +1,280 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hovering/hovering.dart';
|
||||
|
||||
import '../../events/eventbus.dart';
|
||||
import '../../events/events.dart';
|
||||
import '../../generated/l10n.dart';
|
||||
import '../../models/business.dart';
|
||||
import '../../models/product.dart';
|
||||
import '../../pages/product_detail_page.dart';
|
||||
import '../../utils/util_io.dart' if (dart.library.html) '../../utils/util_web.dart';
|
||||
import '../../widgets/general/add_remove_button.dart';
|
||||
import '../../widgets/general/show_price.dart';
|
||||
|
||||
class ProductItem extends StatefulWidget {
|
||||
final Business business;
|
||||
final Product product;
|
||||
final bool horizontal;
|
||||
|
||||
const ProductItem(this.product, this.business, {Key key, this.horizontal = false}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => ProductItemState();
|
||||
|
||||
}
|
||||
|
||||
class ProductItemState extends State<ProductItem> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return HoverWidget(
|
||||
child: Container(
|
||||
width: 160.0,
|
||||
height: widget.horizontal ? 160 : 268.0,
|
||||
padding: new EdgeInsets.symmetric(horizontal: 10.0, vertical: 15.0).copyWith(bottom: 5.0),
|
||||
decoration: new BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: new Border(
|
||||
bottom: new BorderSide(
|
||||
color: new Color(0xFFEBEBEB),
|
||||
),
|
||||
),
|
||||
),
|
||||
child: new SizedBox.expand(
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(left: 10.0, right: 10.0, top: 10.0, bottom: 10.0),
|
||||
child: widget.horizontal ? getHorizontal(false) : getVertial(false),
|
||||
),
|
||||
),
|
||||
),
|
||||
hoverChild: Container(
|
||||
width: 160.0,
|
||||
height: widget.horizontal ? 160 : 268.0,
|
||||
padding: new EdgeInsets.symmetric(horizontal: 10.0, vertical: 15.0).copyWith(bottom: 5.0),
|
||||
decoration: new BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: new Border(
|
||||
top: new BorderSide(
|
||||
color: new Color(0xFFEBEBEB),
|
||||
),
|
||||
left: new BorderSide(
|
||||
color: new Color(0xFFEBEBEB),
|
||||
),
|
||||
right: new BorderSide(
|
||||
color: new Color(0xFFEBEBEB),
|
||||
),
|
||||
bottom: new BorderSide(
|
||||
color: new Color(0xFFBBBBBB),
|
||||
),
|
||||
),
|
||||
),
|
||||
child: new SizedBox.expand(
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(left: 10.0, right: 10.0, top: 10.0, bottom: 10.0),
|
||||
child: widget.horizontal ? getHorizontal(true) : getVertial(true),
|
||||
),
|
||||
),
|
||||
),
|
||||
onHover: (event) {
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Widget getHorizontal(bool onHover) {
|
||||
return Row(
|
||||
children: [
|
||||
Container(
|
||||
margin: new EdgeInsets.all(10.0),
|
||||
width: 110.0,
|
||||
height: 110.0,
|
||||
child: GestureDetector(
|
||||
child: onHover && widget.product.secondImagePath.isNotEmpty ?
|
||||
Util.showImage('${widget.product.secondImagePath}',
|
||||
fit: BoxFit.fill,
|
||||
) :
|
||||
Util.showImage('${widget.product.imagePath}',
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
onTap: (){
|
||||
_showProductDetail();
|
||||
},
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: GestureDetector(
|
||||
child: Text(
|
||||
'${widget.product.name}',
|
||||
// overflow: kIsWeb ? null : TextOverflow.ellipsis,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 2,
|
||||
softWrap: true,
|
||||
style: new TextStyle(
|
||||
fontSize: 15.0,
|
||||
),
|
||||
),
|
||||
onTap: (){
|
||||
_showProductDetail();
|
||||
},
|
||||
),
|
||||
),
|
||||
Text(
|
||||
widget.product.description,
|
||||
// overflow: kIsWeb ? null : TextOverflow.ellipsis,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 2,
|
||||
style: new TextStyle(
|
||||
fontSize: 12.0,
|
||||
color: new Color(0xFF999999),
|
||||
),
|
||||
),
|
||||
new Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
new Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
new Container(
|
||||
child: widget.business.showMonthlySold ?
|
||||
Text(
|
||||
S.of(context).sold_per_month_token(widget.product.monthSales.toStringAsFixed(0)),
|
||||
style: new TextStyle(
|
||||
fontSize: 9.0
|
||||
),
|
||||
) : SizedBox.shrink(),
|
||||
),
|
||||
ShowPrice(
|
||||
widget.product.price,
|
||||
regularPrice: widget.product.regularPrice,
|
||||
currencySign: '\$',
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
],
|
||||
),
|
||||
AddRemoveButton(product: widget.product, business: widget.business, addOnly: false, onHovor: onHover,),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget getVertial(bool onHover) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
new Container(
|
||||
margin: new EdgeInsets.all(10.0),
|
||||
width: 110.0,
|
||||
height: 110.0,
|
||||
child: GestureDetector(
|
||||
child: onHover && widget.product.secondImagePath.isNotEmpty ?
|
||||
Util.showImage('${widget.product.secondImagePath}',
|
||||
fit: BoxFit.fill,
|
||||
) :
|
||||
Util.showImage('${widget.product.imagePath}',
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
onTap: (){
|
||||
_showProductDetail();
|
||||
},
|
||||
),
|
||||
),
|
||||
new Expanded(
|
||||
child: new Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: GestureDetector(
|
||||
child: Text(
|
||||
'${widget.product.name}',
|
||||
// overflow: kIsWeb ? null : TextOverflow.ellipsis,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 2,
|
||||
softWrap: true,
|
||||
style: new TextStyle(
|
||||
fontSize: 15.0,
|
||||
),
|
||||
),
|
||||
onTap: (){
|
||||
_showProductDetail();
|
||||
},
|
||||
),
|
||||
),
|
||||
Container(
|
||||
child: Text(
|
||||
widget.product.description,
|
||||
// overflow: kIsWeb ? null : TextOverflow.ellipsis,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 2,
|
||||
style: new TextStyle(
|
||||
fontSize: 12.0,
|
||||
color: new Color(0xFF999999),
|
||||
),
|
||||
),
|
||||
),
|
||||
new Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
new Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
new Container(
|
||||
child: widget.business.showMonthlySold ?
|
||||
Text(
|
||||
S.of(context).sold_per_month_token(widget.product.monthSales.toStringAsFixed(0)),
|
||||
style: new TextStyle(
|
||||
fontSize: 9.0
|
||||
),
|
||||
) : SizedBox.shrink(),
|
||||
),
|
||||
ShowPrice(
|
||||
widget.product.price,
|
||||
regularPrice: widget.product.regularPrice,
|
||||
currencySign: '\$',
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
],
|
||||
),
|
||||
AddRemoveButton(product: widget.product, business: widget.business, addOnly: false, onHovor: onHover,),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
void _showProductDetail() {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ProductDetailPage(
|
||||
product: widget.product,
|
||||
business: widget.business,
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
eventBus.on<OnCartInfoUpdated>().listen((event) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
181
lib/widgets/desktop/product_search.dart
Normal file
181
lib/widgets/desktop/product_search.dart
Normal file
@@ -0,0 +1,181 @@
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flappy_search_bar/flappy_search_bar.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../constants.dart';
|
||||
import '../../events/eventbus.dart';
|
||||
import '../../events/events.dart';
|
||||
import '../../generated/l10n.dart';
|
||||
import '../../models/business.dart';
|
||||
import '../../models/product.dart';
|
||||
import '../../pages/product_detail_page.dart';
|
||||
import '../../utils/http_util.dart';
|
||||
import '../../utils/utils.dart';
|
||||
import '../../widgets/general/bottom_nav.dart';
|
||||
import '../../widgets/general/breadcrumbs.dart';
|
||||
import '../../widgets/general/navigationbar.dart';
|
||||
import 'product_item.dart';
|
||||
|
||||
class ProductSearch extends StatefulWidget {
|
||||
final Business business;
|
||||
|
||||
const ProductSearch(this.business, {Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => ProductSearchState();
|
||||
}
|
||||
|
||||
class ProductSearchState extends State<ProductSearch> {
|
||||
|
||||
double sideSpace = 0;
|
||||
double mainSpace = 1200;
|
||||
double rate = 1;
|
||||
|
||||
int page = 1;
|
||||
int numPerPage = 10;
|
||||
int lastResultSize = 0;
|
||||
double lastBottomPosition = 0;
|
||||
String lastKeyword = '';
|
||||
|
||||
SearchBarController _controller = SearchBarController<Product>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
if (MediaQuery.of(context).size.width <= 1200) {
|
||||
mainSpace = MediaQuery.of(context).size.width;
|
||||
sideSpace = 0;
|
||||
} else {
|
||||
mainSpace = 1200;
|
||||
sideSpace = (MediaQuery.of(context).size.width - 1200) / 2;
|
||||
}
|
||||
rate = mainSpace / 1200;
|
||||
|
||||
return Scaffold(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).search_product,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
BreadCrumb(S.of(context).search_product, null),
|
||||
],
|
||||
breadCrumbHeight: Constants.BREADCRUMB_HEIGHT,
|
||||
),
|
||||
drawer: null,
|
||||
body: SafeArea(
|
||||
child: Container(
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: sideSpace,
|
||||
),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: NotificationListener<ScrollNotification>(
|
||||
child: SearchBar(
|
||||
searchBarController: _controller,
|
||||
minimumChars: 2,
|
||||
hintText: S.of(context).enter_keyword,
|
||||
cancellationWidget: Text(
|
||||
S.of(context).cancel,
|
||||
),
|
||||
onSearch: search,
|
||||
onItemFound: (Product searchProduct, int index) {
|
||||
return ProductItem(
|
||||
searchProduct,
|
||||
widget.business,
|
||||
horizontal: true,
|
||||
);
|
||||
},
|
||||
onError: (error) {
|
||||
return Center(
|
||||
child: Text("$error"),
|
||||
);
|
||||
},
|
||||
emptyWidget: Center(
|
||||
child: Text(
|
||||
S.of(context).empty_result_change_keyword,
|
||||
),
|
||||
),
|
||||
),
|
||||
onNotification: (notification) {
|
||||
if (notification.metrics.atEdge) {
|
||||
print('fff: $page, $lastBottomPosition, ${notification.metrics.pixels}');
|
||||
if (page != 0 && lastResultSize >= numPerPage && notification.metrics.pixels != 0) {
|
||||
if (notification.metrics.pixels > lastBottomPosition) {
|
||||
lastBottomPosition = notification.metrics.pixels;
|
||||
page += 1;
|
||||
_controller.replayLastSearch();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: sideSpace,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
bottomNavigationBar: BottomNav(),
|
||||
);
|
||||
}
|
||||
|
||||
Future<List<Product>> search(String keyword) async {
|
||||
if (lastKeyword != keyword) {
|
||||
page = 1;
|
||||
}
|
||||
lastKeyword = keyword;
|
||||
var result = await HttpUtil.httpGet('v1/search-store-product2',
|
||||
queryParameters: {
|
||||
'store_id': widget.business.id,
|
||||
'keyword': keyword,
|
||||
'page': page,
|
||||
'num_per_page': numPerPage,
|
||||
},
|
||||
returnError: true,
|
||||
);
|
||||
if (result is DioError) {
|
||||
if (result.response != null) {
|
||||
throw RuntimeError(result.response.data);
|
||||
} else {
|
||||
throw RuntimeError(result.message);
|
||||
}
|
||||
} else if (result != null && result is List) {
|
||||
lastBottomPosition = 0;
|
||||
var r = result.map((e) => Product.fromJson(e)).toList();
|
||||
lastResultSize = r.length;
|
||||
if (lastResultSize < numPerPage) {
|
||||
page = 1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
eventBus.on<OnCartInfoUpdated>().listen((event) {
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _showProductDetail(Product p) {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ProductDetailPage(
|
||||
product: p,
|
||||
business: widget.business,
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
||||
297
lib/widgets/desktop/shop.dart
Normal file
297
lib/widgets/desktop/shop.dart
Normal file
@@ -0,0 +1,297 @@
|
||||
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import '../../utils/utils.dart';
|
||||
import '../../widgets/desktop/shop_products.dart';
|
||||
import '../../widgets/general/bottom_nav.dart';
|
||||
import '../../widgets/general/breadcrumbs.dart';
|
||||
import '../../widgets/general/navigationbar.dart';
|
||||
import '../../widgets/general/sliding_up_panel.dart';
|
||||
import '../../widgets/mobile/shopping_cart_bar.dart';
|
||||
import 'shop_bulletin.dart';
|
||||
|
||||
import '../../constants.dart';
|
||||
import '../../events/eventbus.dart';
|
||||
import '../../events/events.dart';
|
||||
import '../../generated/l10n.dart';
|
||||
import '../../models/business.dart';
|
||||
import '../../models/category_products.dart';
|
||||
import 'product_search.dart';
|
||||
import 'shop_promote.dart';
|
||||
import 'shopping_cart_widget.dart';
|
||||
|
||||
class Shop extends StatefulWidget {
|
||||
final int businessId;
|
||||
|
||||
const Shop({Key key, this.businessId}): super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => ShopState();
|
||||
|
||||
}
|
||||
|
||||
class ShopState extends State<Shop> {
|
||||
Business _business;
|
||||
|
||||
PanelController panelController = PanelController();
|
||||
SlidingUpPanel _slidUpShoppingCart;
|
||||
GlobalKey endKey = GlobalKey();
|
||||
|
||||
List<CategoryProducts> _categoryProducts;
|
||||
bool displayProductByCategoryClick = false;
|
||||
String displayProductByCategoryClickIndicator = '';
|
||||
int categoryId = 0;
|
||||
static int _productCurrentPage = 1;
|
||||
|
||||
int _categoryIndex = 0;
|
||||
bool _categoryIndexChange = false;
|
||||
bool _isLoading = false;
|
||||
|
||||
dynamic data;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (_business == null) {
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: SpinKitWave(
|
||||
color: Colors.lightBlueAccent,
|
||||
size: 40.0,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_slidUpShoppingCart = SlidingUpPanel(
|
||||
controller: panelController,
|
||||
minHeight: 0.0,
|
||||
maxHeight: 250.0,
|
||||
isDraggable: false,
|
||||
backdropEnabled: true,
|
||||
slideDirection: SlideDirection.DOWN,
|
||||
panel: ShoppingCartBar(
|
||||
business: _business,
|
||||
endKey: endKey,
|
||||
barAtBottom: true,
|
||||
hasPicture: true,
|
||||
onEmptyCartListener: () {
|
||||
Future.delayed(Duration(seconds: 1), () {
|
||||
panelController.close();
|
||||
});
|
||||
},
|
||||
onPanelOpenCloseRequest: () {
|
||||
if (panelController.isPanelOpen) {
|
||||
panelController.close();
|
||||
} else {
|
||||
panelController.open();
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
Scaffold scaffold = Scaffold(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).shop,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
BreadCrumb(S.of(context).shop, null),
|
||||
BreadCrumb(null, null,
|
||||
item: Container(
|
||||
margin: EdgeInsets.only(left: 20.0),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
child: Icon(
|
||||
Icons.search,
|
||||
size: 24,
|
||||
color: Colors.blue,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
child: Text(
|
||||
S.of(context).search_product,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.push(context,
|
||||
MaterialPageRoute(builder: (BuildContext context) {
|
||||
return ProductSearch(_business);
|
||||
}));
|
||||
},
|
||||
),
|
||||
],
|
||||
breadCrumbHeight: Constants.BREADCRUMB_HEIGHT,
|
||||
shoppingCart: ShoppingCartWidget(
|
||||
business: _business,
|
||||
onTap: () {
|
||||
if (panelController.isPanelClosed) {
|
||||
panelController.open();
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
body: Scrollbar(
|
||||
child: NotificationListener<ScrollNotification>(
|
||||
onNotification: (scrollNotification) {
|
||||
if (scrollNotification is ScrollEndNotification &&
|
||||
scrollNotification.metrics.pixels == scrollNotification.metrics.maxScrollExtent) {
|
||||
loadMoreProducts();
|
||||
}
|
||||
return false;
|
||||
},
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ShopPromote(data),
|
||||
ShopBulletin(_business),
|
||||
ShopProducts(data),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
bottomNavigationBar: BottomNav(),
|
||||
);
|
||||
return Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
child: scaffold,
|
||||
),
|
||||
_slidUpShoppingCart,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
eventBus.on<OnCartInfoUpdated>().listen((event) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
eventBus.on<CategoryChangeEvent>().listen((event) {
|
||||
if (mounted) {
|
||||
// setState(() {
|
||||
// categoryId = event.categoryId;
|
||||
// _productCurrentPage = 1;
|
||||
// });
|
||||
categoryId = event.categoryId;
|
||||
_productCurrentPage = 1;
|
||||
_isLoading = true;
|
||||
Utils.showLoadingDialog(context, message: S.of(context).loading);
|
||||
loadProducts();
|
||||
}
|
||||
});
|
||||
loadProducts();
|
||||
}
|
||||
|
||||
void loadProducts() {
|
||||
print('categoryId $categoryId');
|
||||
if (categoryId < 0) {
|
||||
return;
|
||||
}
|
||||
_productCurrentPage = 1;
|
||||
Utils.loadProducts(
|
||||
widget.businessId, categoryId, _productCurrentPage, false,
|
||||
(value) {
|
||||
if (_isLoading) {
|
||||
_isLoading = false;
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
if (mounted) {
|
||||
if (_business == null) {
|
||||
setState(() {
|
||||
displayProductByCategoryClick =
|
||||
value['display_product_by_category_click'];
|
||||
displayProductByCategoryClickIndicator = '';
|
||||
_business = Business.fromJson(value['business']);
|
||||
_categoryProducts = (value['category_products'] as List)
|
||||
.map((i) => CategoryProducts.fromJson(i))
|
||||
.toList();
|
||||
if (categoryId == 0 && displayProductByCategoryClick) {
|
||||
categoryId = _categoryProducts[0].id;
|
||||
}
|
||||
data = value;
|
||||
});
|
||||
} else {
|
||||
eventBus.fire(GetCategoryProducts(value));
|
||||
}
|
||||
}
|
||||
},
|
||||
(error) {
|
||||
print('error: $error');
|
||||
if (_isLoading) {
|
||||
_isLoading = false;
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
Utils.showMessageDialog(context, error);
|
||||
}, featuredCount: 6, hotSaleCount: 0, keyword: ''
|
||||
);
|
||||
}
|
||||
|
||||
void loadMoreProducts() {
|
||||
if (_productCurrentPage == 0 || categoryId <= 0) {
|
||||
return;
|
||||
}
|
||||
_productCurrentPage += 1;
|
||||
Utils.loadProducts(widget.businessId, categoryId, _productCurrentPage, true, (value) {
|
||||
if (_isLoading) {
|
||||
_isLoading = false;
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
if (mounted) {
|
||||
List<CategoryProducts> moreCategoryProducts = (value as List).map((i) => CategoryProducts.fromJson(i)).toList();
|
||||
if (moreCategoryProducts.isEmpty) {
|
||||
_productCurrentPage = 0;
|
||||
} else {
|
||||
if (moreCategoryProducts[0].products.length < Constants.ORDERS_PER_PAGE) {
|
||||
_productCurrentPage = 0;
|
||||
}
|
||||
}
|
||||
eventBus.fire(MoreCategoryProducts(moreCategoryProducts));
|
||||
}
|
||||
}, (error) {
|
||||
print('error: $error');
|
||||
if (_isLoading) {
|
||||
_isLoading = false;
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
Utils.showMessageDialog(context, error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
int nextCategoryId(int currentCategoryId) {
|
||||
if (_categoryProducts.length <= 0) {
|
||||
return 0;
|
||||
}
|
||||
for (int i = 0; i < _categoryProducts.length; i++) {
|
||||
if (_categoryProducts[i].id == currentCategoryId) {
|
||||
try {
|
||||
CategoryProducts cps = _categoryProducts[i + 1];
|
||||
return cps.id;
|
||||
} catch (error) {
|
||||
print('Error $error');
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,11 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:badges/badges.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import 'package:flutter_wisetronic/widgets/mobile/shopping_cart_bar.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
||||
import 'package:smooth_star_rating/smooth_star_rating.dart';
|
||||
|
||||
@@ -24,34 +21,31 @@ import '../../models/comment.dart';
|
||||
import '../../models/product.dart';
|
||||
import '../../models/product_image.dart';
|
||||
import '../../pages/product_detail_page.dart';
|
||||
import '../../pages/store_product_search.dart';
|
||||
import '../../store/actions.dart';
|
||||
import '../../store/store.dart';
|
||||
import '../../utils/http_util.dart';
|
||||
import '../../utils/shop_scroll_controller.dart';
|
||||
import '../../utils/shop_scroll_coordinator.dart';
|
||||
import '../../utils/util_web.dart'
|
||||
if (dart.library.io) '../../utils/util_io.dart';
|
||||
import '../../utils/util_io.dart' if (dart.library.html) '../../utils/util_web.dart';
|
||||
import '../../utils/utils.dart';
|
||||
import '../../widgets/general/add_remove_button.dart';
|
||||
import '../../widgets/general/bottom_nav.dart';
|
||||
import '../../widgets/general/breadcrumbs.dart';
|
||||
import '../../widgets/general/carousel.dart';
|
||||
import '../../widgets/general/navigationbar.dart';
|
||||
import '../../widgets/general/product_item.dart';
|
||||
import '../../widgets/general/read_more_text.dart';
|
||||
import '../../widgets/general/show_price.dart';
|
||||
import '../../widgets/general/sliding_up_panel.dart';
|
||||
import '../../widgets/general/style.dart';
|
||||
import 'desktop_shopping_cart_widget.dart';
|
||||
import '../../widgets/mobile/shopping_cart_bar.dart';
|
||||
import 'product_item.dart';
|
||||
import 'shopping_cart_widget.dart';
|
||||
|
||||
class DesktopShop extends StatefulWidget {
|
||||
class Shop extends StatefulWidget {
|
||||
final int businessId;
|
||||
|
||||
const DesktopShop({Key key, this.businessId}) : super(key: key);
|
||||
const Shop({Key key, this.businessId}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => DesktopShopState();
|
||||
State<StatefulWidget> createState() => ShopState();
|
||||
}
|
||||
|
||||
MediaQueryData mediaQuery;
|
||||
@@ -59,7 +53,7 @@ double statusBarHeight;
|
||||
double screenWidth;
|
||||
double screenHeight;
|
||||
|
||||
class DesktopShopState extends State<DesktopShop>
|
||||
class ShopState extends State<Shop>
|
||||
with TickerProviderStateMixin, AutomaticKeepAliveClientMixin {
|
||||
GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||
|
||||
@@ -109,7 +103,7 @@ class DesktopShopState extends State<DesktopShop>
|
||||
int _commentPageCount = 1;
|
||||
bool _commentLoadingFinish = false;
|
||||
RefreshController _commentRefreshController =
|
||||
RefreshController(initialRefresh: true);
|
||||
RefreshController(initialRefresh: true);
|
||||
|
||||
PanelController panelController = PanelController();
|
||||
SlidingUpPanel _slidUpShoppingCart;
|
||||
@@ -123,6 +117,44 @@ class DesktopShopState extends State<DesktopShop>
|
||||
|
||||
double lastProductListScrollPositionPixel = 0;
|
||||
|
||||
final TextEditingController _searchController = new TextEditingController();
|
||||
Widget searchFieldPlaceHolder;
|
||||
Icon searchIcon = new Icon(
|
||||
Icons.search,
|
||||
color: Colors.blue,
|
||||
);
|
||||
bool _isSearching = false;
|
||||
String _searchText = "";
|
||||
|
||||
dynamic responseData;
|
||||
|
||||
ShopState() {
|
||||
_searchController.addListener(() {
|
||||
if (_searchController.text.isEmpty) {
|
||||
setState(() {
|
||||
// _isSearching = false;
|
||||
_searchText = "";
|
||||
if (responseData != null) {
|
||||
_categoryProducts.clear();
|
||||
_categoryProducts = (responseData['category_products'] as List)
|
||||
.map((i) => CategoryProducts.fromJson(i))
|
||||
.toList();
|
||||
} else {
|
||||
categoryId = 0;
|
||||
loadProducts();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (!displayProductByCategoryClick) {
|
||||
setState(() {
|
||||
_isSearching = true;
|
||||
_searchText = _searchController.text;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _onCommentRefresh() {
|
||||
if (_commentPage - 1 > 1) {
|
||||
_commentPage -= 1;
|
||||
@@ -253,9 +285,33 @@ class DesktopShopState extends State<DesktopShop>
|
||||
left: 10.0,
|
||||
top: 10.0,
|
||||
bottom: 10.0,
|
||||
right: 10.0,
|
||||
),
|
||||
margin: EdgeInsets.symmetric(horizontal: 5.0, vertical: 5.0),
|
||||
width: 220.0,
|
||||
height: 220.0,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(5.0)),
|
||||
color: Colors.white,
|
||||
border: Border(
|
||||
top: BorderSide(
|
||||
width: 1.0,
|
||||
color: Colors.black12,
|
||||
),
|
||||
bottom: BorderSide(
|
||||
width: 1.0,
|
||||
color: Colors.black12,
|
||||
),
|
||||
left: BorderSide(
|
||||
width: 1.0,
|
||||
color: Colors.black12,
|
||||
),
|
||||
right: BorderSide(
|
||||
width: 1.0,
|
||||
color: Colors.black12,
|
||||
),
|
||||
),
|
||||
),
|
||||
width: 240.0,
|
||||
height: 320.0,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
@@ -263,6 +319,7 @@ class DesktopShopState extends State<DesktopShop>
|
||||
child: Container(
|
||||
child: Util.showImage(
|
||||
_business.promoProducts[i].imagePath,
|
||||
width: 120.0,
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
@@ -307,8 +364,8 @@ class DesktopShopState extends State<DesktopShop>
|
||||
pinned: false,
|
||||
floating: true,
|
||||
delegate: _SliverAppBarDelegate2(
|
||||
minHeight: 350.0,
|
||||
maxHeight: 350.0,
|
||||
minHeight: 260.0,
|
||||
maxHeight: 260.0,
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
@@ -413,10 +470,24 @@ class DesktopShopState extends State<DesktopShop>
|
||||
final newOffset = _pageScrollController.offset + ps.scrollDelta.dy;
|
||||
if (ps.scrollDelta.dy.isNegative) {
|
||||
_pageScrollController.jumpTo(max(0, newOffset));
|
||||
if (max(0, newOffset) == 0) {
|
||||
_listScrollController1.jumpTo(max(0, _listScrollController1.offset - 10));
|
||||
}
|
||||
} else {
|
||||
_pageScrollController
|
||||
.jumpTo(min(_pageScrollController.position.maxScrollExtent, newOffset));
|
||||
if (newOffset > _pageScrollController.position.maxScrollExtent) {
|
||||
_listScrollController1.jumpTo(min(_listScrollController1.position.maxScrollExtent, _listScrollController1.offset + 10));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// if (ps.scrollDelta.dy.isNegative) {
|
||||
// _listScrollController2.jumpTo(max(0, newOffset));
|
||||
// } else {
|
||||
// _listScrollController2
|
||||
// .jumpTo(min(_listScrollController2.position.maxScrollExtent, newOffset));
|
||||
// }
|
||||
}
|
||||
},
|
||||
child: CustomScrollView(
|
||||
@@ -427,45 +498,86 @@ class DesktopShopState extends State<DesktopShop>
|
||||
pinned: true,
|
||||
floating: true,
|
||||
delegate: _SliverAppBarDelegate2(
|
||||
minHeight: 94,
|
||||
maxHeight: 94,
|
||||
minHeight: 98,
|
||||
maxHeight: 98,
|
||||
child: Column(
|
||||
children: [
|
||||
NavigationBar(
|
||||
MiniNavigationBar(
|
||||
title: S.of(context).shop,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
BreadCrumb(S.of(context).shop, null),
|
||||
BreadCrumb(null, null,
|
||||
// BreadCrumb(null, null,
|
||||
// item: Container(
|
||||
// margin: EdgeInsets.only(left: 20.0),
|
||||
// child: Row(
|
||||
// children: [
|
||||
// Container(
|
||||
// child: Icon(
|
||||
// Icons.search,
|
||||
// size: 24,
|
||||
// color: Colors.blue,
|
||||
// ),
|
||||
// ),
|
||||
// Container(
|
||||
// child: Text(
|
||||
// S.of(context).search_product,
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// onTap: () {
|
||||
// // Navigator.push(context,
|
||||
// // MaterialPageRoute(builder: (BuildContext context) {
|
||||
// // return ProductSearch(_business);
|
||||
// // }));
|
||||
// },
|
||||
// ),
|
||||
BreadCrumb(
|
||||
null, null,
|
||||
item: Container(
|
||||
margin: EdgeInsets.only(left: 20.0),
|
||||
width: 280.0,
|
||||
padding: EdgeInsets.only(left: 20.0, right: 20.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
child: Icon(
|
||||
Icons.search,
|
||||
size: 24,
|
||||
color: Colors.blue,
|
||||
MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(right: 10.0),
|
||||
child: Icon(
|
||||
searchIcon.icon,
|
||||
size: 20.0,
|
||||
color: Colors.blue,
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
onSearchTap();
|
||||
},
|
||||
),
|
||||
),
|
||||
Container(
|
||||
child: Text(
|
||||
S.of(context).search_product,
|
||||
Expanded(child: searchFieldPlaceHolder == null ? MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
child: Text(
|
||||
S.of(context).search_products,
|
||||
style: new TextStyle(color: Colors.blue),
|
||||
),
|
||||
onTap: () {
|
||||
onSearchTap();
|
||||
},
|
||||
),
|
||||
),
|
||||
) : searchFieldPlaceHolder),
|
||||
],
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.push(context,
|
||||
MaterialPageRoute(builder: (BuildContext context) {
|
||||
return StoreProductSearch(_business);
|
||||
}));
|
||||
},
|
||||
),
|
||||
)
|
||||
],
|
||||
breadCrumbHeight: Constants.BREADCRUMB_HEIGHT,
|
||||
shoppingCart: DesktopShoppingCartWidget(
|
||||
shoppingCart: ShoppingCartWidget(
|
||||
business: _business,
|
||||
onTap: () {
|
||||
if (panelController.isPanelClosed) {
|
||||
@@ -573,21 +685,20 @@ class DesktopShopState extends State<DesktopShop>
|
||||
stack.children.addAll(children);
|
||||
|
||||
if (!_business.isPublic) {
|
||||
/* todo */
|
||||
// stack.children.add(
|
||||
// Positioned(
|
||||
// top: 0,
|
||||
// right: 0,
|
||||
// left: screenWidth - 100,
|
||||
// bottom: screenHeight - 100,
|
||||
// child: Image.asset(
|
||||
// 'assets/images/under_renovation.png',
|
||||
// width: 200.0,
|
||||
// height: 200.0,
|
||||
// fit: BoxFit.fill,
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
stack.children.add(
|
||||
Positioned(
|
||||
top: 0,
|
||||
right: 0,
|
||||
left: screenWidth - 100,
|
||||
bottom: screenHeight - 100,
|
||||
child: Image.asset(
|
||||
'assets/images/under_renovation.png',
|
||||
width: 200.0,
|
||||
height: 200.0,
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return stack;
|
||||
@@ -626,7 +737,7 @@ class DesktopShopState extends State<DesktopShop>
|
||||
cancelButton: CupertinoActionSheetAction(
|
||||
child: Text(S.of(context).close),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).maybePop();
|
||||
},
|
||||
),
|
||||
);
|
||||
@@ -872,8 +983,8 @@ class DesktopShopState extends State<DesktopShop>
|
||||
));
|
||||
var duration = Duration(
|
||||
seconds: (_business.distanceInfo.duration != null
|
||||
? _business.distanceInfo.duration.value
|
||||
: 30) +
|
||||
? _business.distanceInfo.duration.value
|
||||
: 30) +
|
||||
_business.shippingTime * 60);
|
||||
var hours = duration.inHours.remainder(60);
|
||||
var minutes = duration.inMinutes.remainder(60);
|
||||
@@ -1008,28 +1119,28 @@ class DesktopShopState extends State<DesktopShop>
|
||||
children: <Widget>[
|
||||
_business.bulletin.isNotEmpty ? Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
padding:
|
||||
EdgeInsets.only(left: 10.0, right: 5.0, bottom: 10.0),
|
||||
EdgeInsets.only(left: 10.0, right: 5.0, bottom: 10.0),
|
||||
child: Icon(
|
||||
Icons.announcement,
|
||||
size: 14.0,
|
||||
color: Colors.white,
|
||||
)),
|
||||
Container(
|
||||
width: mediaQuery.size.width - 30.0,
|
||||
padding: EdgeInsets.only(right: 10.0, bottom: 10.0),
|
||||
child: new Text(
|
||||
_business.bulletin.isEmpty ? '' : _business.bulletin,
|
||||
softWrap: true,
|
||||
style: new TextStyle(
|
||||
fontSize: 12.0, color: const Color(0xFFDDDDDD)),
|
||||
Container(
|
||||
width: mediaQuery.size.width - 30.0,
|
||||
padding: EdgeInsets.only(right: 10.0, bottom: 10.0),
|
||||
child: new Text(
|
||||
_business.bulletin.isEmpty ? '' : _business.bulletin,
|
||||
softWrap: true,
|
||||
style: new TextStyle(
|
||||
fontSize: 12.0, color: const Color(0xFFDDDDDD)),
|
||||
// overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
) : SizedBox.shrink(),
|
||||
),
|
||||
],
|
||||
) : SizedBox.shrink(),
|
||||
_business.description.isNotEmpty ? Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -1276,7 +1387,7 @@ class DesktopShopState extends State<DesktopShop>
|
||||
height: 70.0,
|
||||
padding: new EdgeInsets.symmetric(horizontal: 10.0),
|
||||
decoration: new BoxDecoration(
|
||||
color: _categoryIndex == i ? Style.backgroundColor : null,
|
||||
color: _categoryIndex == i ? Colors.white : null,
|
||||
border: new Border(
|
||||
bottom:
|
||||
new BorderSide(color: new Color(0xFFEBEBEB)))),
|
||||
@@ -1309,10 +1420,10 @@ class DesktopShopState extends State<DesktopShop>
|
||||
_categoryIndexChange = true;
|
||||
_listScrollController1
|
||||
.animateTo(height,
|
||||
duration: new Duration(
|
||||
microseconds: 200,
|
||||
),
|
||||
curve: Curves.linear)
|
||||
duration: new Duration(
|
||||
microseconds: 200,
|
||||
),
|
||||
curve: Curves.linear)
|
||||
.then((value) {
|
||||
_categoryIndexChange = false;
|
||||
});
|
||||
@@ -1522,10 +1633,11 @@ class DesktopShopState extends State<DesktopShop>
|
||||
if (it.moveNext()) {
|
||||
r1.children.add(
|
||||
Container(
|
||||
width: (mainSpace - 200) / c,
|
||||
width: (mainSpace - 200) / c - 4.0,
|
||||
margin: EdgeInsets.only(top: 2.0, bottom: 2.0, left: 2.0, right: 2.0),
|
||||
child: ProductItem(
|
||||
product: it.current,
|
||||
business: _business,
|
||||
it.current,
|
||||
_business,
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -1656,128 +1768,6 @@ class DesktopShopState extends State<DesktopShop>
|
||||
}
|
||||
});
|
||||
|
||||
// onProductWillAddToCartSubscription =
|
||||
// eventBus.on<OnProductWillAddToCart>().listen((event) {
|
||||
// if (mounted) {
|
||||
//
|
||||
// CartInfo cartInfo =
|
||||
// Utils.getCartInfoByBusiness(store.state.cartInfos, event.business);
|
||||
//
|
||||
// if (cartInfo == null || cartInfo.productList.length == 0) {
|
||||
// cartInfo = CartInfo();
|
||||
// cartInfo.id = 0;
|
||||
// cartInfo.amountPaid = 0.0;
|
||||
// cartInfo.businessInfo = event.business;
|
||||
// cartInfo.extraFeeList = [];
|
||||
// cartInfo.discountList = [];
|
||||
// CartLineItem lineItem = _newCartLineItem(
|
||||
// id: 0,
|
||||
// price: event.price,
|
||||
// product: event.product,
|
||||
// name: event.product.name,
|
||||
// description: event.description,
|
||||
// quantity: 1.0);
|
||||
// cartInfo.productList = [lineItem];
|
||||
// store.dispatch(new UpdateCartInfo(Utils.addCartInfoToCartInfoList(
|
||||
// store.state.cartInfos, cartInfo)));
|
||||
// eventBus.fire(new OnCartInfoUpdated());
|
||||
// } else {
|
||||
// if (event.product.productAttributes.length > 0) {
|
||||
// CartLineItem lineItem = _newCartLineItem(
|
||||
// id: 0,
|
||||
// price: event.price,
|
||||
// product: event.product,
|
||||
// name: event.product.name,
|
||||
// description: event.description,
|
||||
// quantity: 1.0);
|
||||
// cartInfo.productList.add(lineItem);
|
||||
// store.dispatch(new UpdateCartInfo(Utils.addCartInfoToCartInfoList(
|
||||
// store.state.cartInfos, cartInfo)));
|
||||
// eventBus.fire(new OnCartInfoUpdated());
|
||||
// } else {
|
||||
// int found = -1;
|
||||
// for (var i = 0; i < cartInfo.productList.length; i++) {
|
||||
// if (event.product.id == cartInfo.productList[i].product.id) {
|
||||
// found = i;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (found == -1) {
|
||||
// CartLineItem lineItem = _newCartLineItem(
|
||||
// id: 0,
|
||||
// price: event.price,
|
||||
// product: event.product,
|
||||
// name: event.product.name,
|
||||
// description: event.description,
|
||||
// quantity: 1.0);
|
||||
// cartInfo.productList.add(lineItem);
|
||||
// store.dispatch(new UpdateCartInfo(Utils.addCartInfoToCartInfoList(
|
||||
// store.state.cartInfos, cartInfo)));
|
||||
// eventBus.fire(new OnCartInfoUpdated());
|
||||
// } else {
|
||||
// if (cartInfo.productList[found].quantity + 1.0 >
|
||||
// event.product.leftNum) {
|
||||
// Fluttertoast.showToast(
|
||||
// msg: S.of(context).product_insufficient,
|
||||
// toastLength: Toast.LENGTH_SHORT,
|
||||
// gravity: ToastGravity.CENTER,
|
||||
// backgroundColor: Colors.red,
|
||||
// textColor: Colors.white);
|
||||
// } else {
|
||||
// cartInfo.productList[found].quantity += 1;
|
||||
// store.dispatch(new UpdateCartInfo(
|
||||
// Utils.addCartInfoToCartInfoList(
|
||||
// store.state.cartInfos, cartInfo)));
|
||||
// eventBus.fire(new OnCartInfoUpdated());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// onProductWillRemoveFromCartSubscription =
|
||||
// eventBus.on<OnProductWillRemoveFromCart>().listen((event) {
|
||||
// if (mounted) {
|
||||
// CartInfo cartInfo =
|
||||
// Utils.getCartInfoByBusiness(store.state.cartInfos, event.business);
|
||||
// if (cartInfo != null) {
|
||||
// if (cartInfo.productList.length > 0) {
|
||||
// if (event.productListIndex != -1) {
|
||||
// if (cartInfo.productList[event.productListIndex].quantity <= 1) {
|
||||
// cartInfo.productList.removeAt(event.productListIndex);
|
||||
// } else {
|
||||
// cartInfo.productList[event.productListIndex].quantity -= 1;
|
||||
// }
|
||||
// } else {
|
||||
// int productListIndex = -1;
|
||||
// for (var i = 0; i < cartInfo.productList.length; i++) {
|
||||
// if (cartInfo.productList[i].product.id == event.product.id) {
|
||||
// productListIndex = i;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (productListIndex != -1) {
|
||||
// if (cartInfo.productList[productListIndex].quantity <= 1) {
|
||||
// cartInfo.productList.removeAt(productListIndex);
|
||||
// } else {
|
||||
// cartInfo.productList[productListIndex].quantity -= 1;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (cartInfo.productList.length <= 0) {
|
||||
// store.dispatch(UpdateCartInfo(Utils.removeCartInfoFromCartInfoList(
|
||||
// store.state.cartInfos, cartInfo)));
|
||||
// } else {
|
||||
// store.dispatch(UpdateCartInfo(Utils.addCartInfoToCartInfoList(
|
||||
// store.state.cartInfos, cartInfo)));
|
||||
// }
|
||||
// eventBus.fire(new OnCartInfoUpdated());
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
|
||||
loadProducts();
|
||||
}
|
||||
|
||||
@@ -1792,68 +1782,80 @@ class DesktopShopState extends State<DesktopShop>
|
||||
lastProductListScrollPositionPixel = 0;
|
||||
_productCurrentPage = 1;
|
||||
Utils.loadProducts(
|
||||
widget.businessId, categoryId, _productCurrentPage, false,
|
||||
(value) {
|
||||
if (_isLoading) {
|
||||
_isLoading = false;
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
displayProductByCategoryClick =
|
||||
value['display_product_by_category_click'];
|
||||
displayProductByCategoryClickIndicator = '';
|
||||
_business = Business.fromJson(value['business']);
|
||||
_categoryProducts = (value['category_products'] as List)
|
||||
.map((i) => CategoryProducts.fromJson(i))
|
||||
.toList();
|
||||
widget.businessId, categoryId, _productCurrentPage, false,
|
||||
(value) {
|
||||
if (_isLoading) {
|
||||
_isLoading = false;
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
|
||||
_featuredProducts = (value['featured_products'] as List)
|
||||
.map((i) => Product.fromJson(i))
|
||||
.toList();
|
||||
_hotSaleProducts = (value['hot_sale_products'] as List)
|
||||
.map((i) => Product.fromJson(i))
|
||||
.toList();
|
||||
_prompts = value['prompt'] as List;
|
||||
_isSearching = false;
|
||||
|
||||
if (_hotSaleProducts.length > 0) {
|
||||
CategoryProducts hs = CategoryProducts(
|
||||
Constants.HOT_SALE_ID,
|
||||
widget.businessId,
|
||||
S.of(context).hot_sale,
|
||||
'',
|
||||
'',
|
||||
_hotSaleProducts);
|
||||
_categoryProducts.insert(0, hs);
|
||||
}
|
||||
if (_searchController.text.isEmpty) {
|
||||
responseData = value;
|
||||
}
|
||||
displayProductByCategoryClick =
|
||||
value['display_product_by_category_click'];
|
||||
displayProductByCategoryClickIndicator = '';
|
||||
_business = Business.fromJson(value['business']);
|
||||
_categoryProducts = (value['category_products'] as List)
|
||||
.map((i) => CategoryProducts.fromJson(i))
|
||||
.toList();
|
||||
|
||||
if (_featuredProducts.length > 0) {
|
||||
CategoryProducts fe = CategoryProducts(
|
||||
Constants.FEATURED_PRODUCT_ID,
|
||||
widget.businessId,
|
||||
S.of(context).featured_product,
|
||||
'',
|
||||
'',
|
||||
_featuredProducts);
|
||||
_categoryProducts.insert(0, fe);
|
||||
}
|
||||
// _featuredProducts = (value['featured_products'] as List)
|
||||
// .map((i) => Product.fromJson(i))
|
||||
// .toList();
|
||||
// _hotSaleProducts = (value['hot_sale_products'] as List)
|
||||
// .map((i) => Product.fromJson(i))
|
||||
// .toList();
|
||||
_featuredProducts = [];
|
||||
_hotSaleProducts = [];
|
||||
_prompts = value['prompt'] as List;
|
||||
|
||||
checkActionAndClose(context);
|
||||
if (_hotSaleProducts.length > 0) {
|
||||
CategoryProducts hs = CategoryProducts(
|
||||
Constants.HOT_SALE_ID,
|
||||
widget.businessId,
|
||||
S.of(context).hot_sale,
|
||||
'',
|
||||
'',
|
||||
_hotSaleProducts);
|
||||
_categoryProducts.insert(0, hs);
|
||||
}
|
||||
|
||||
if (displayProductByCategoryClick) {
|
||||
_resetProductListScroll();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
(error) {
|
||||
print('error: $error');
|
||||
if (_isLoading) {
|
||||
_isLoading = false;
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
Utils.showMessageDialog(context, error);
|
||||
}
|
||||
if (_featuredProducts.length > 0) {
|
||||
CategoryProducts fe = CategoryProducts(
|
||||
Constants.FEATURED_PRODUCT_ID,
|
||||
widget.businessId,
|
||||
S.of(context).featured_product,
|
||||
'',
|
||||
'',
|
||||
_featuredProducts);
|
||||
_categoryProducts.insert(0, fe);
|
||||
}
|
||||
|
||||
checkActionAndClose(context);
|
||||
|
||||
if (displayProductByCategoryClick) {
|
||||
_resetProductListScroll();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
(error) {
|
||||
print('error: $error');
|
||||
_isSearching = false;
|
||||
if (_isLoading) {
|
||||
_isLoading = false;
|
||||
Navigator.of(context).maybePop();
|
||||
}
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
Utils.showMessageDialog(context, error);
|
||||
}, featuredCount: 5, hotSaleCount: 0, keyword: _searchController.text
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1863,59 +1865,59 @@ class DesktopShopState extends State<DesktopShop>
|
||||
}
|
||||
_productCurrentPage += 1;
|
||||
Utils.loadProducts(widget.businessId, categoryId, _productCurrentPage, true,
|
||||
(value) {
|
||||
if (_isLoading) {
|
||||
_isLoading = false;
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
List<CategoryProducts> moreCategoryProducts =
|
||||
(value as List).map((i) => CategoryProducts.fromJson(i)).toList();
|
||||
if (moreCategoryProducts.isEmpty) {
|
||||
_productCurrentPage = 0;
|
||||
displayProductByCategoryClickIndicator =
|
||||
S.of(context).end_of_the_list;
|
||||
} else {
|
||||
if (moreCategoryProducts[0].products.length < Constants.ORDERS_PER_PAGE) {
|
||||
(value) {
|
||||
if (_isLoading) {
|
||||
_isLoading = false;
|
||||
Navigator.of(context).maybePop();
|
||||
}
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
List<CategoryProducts> moreCategoryProducts =
|
||||
(value as List).map((i) => CategoryProducts.fromJson(i)).toList();
|
||||
if (moreCategoryProducts.isEmpty) {
|
||||
_productCurrentPage = 0;
|
||||
displayProductByCategoryClickIndicator =
|
||||
S.of(context).end_of_the_list;
|
||||
} else {
|
||||
displayProductByCategoryClickIndicator =
|
||||
S.of(context).pull_up_to_load_more;
|
||||
if (moreCategoryProducts[0].products.length < Constants.ORDERS_PER_PAGE) {
|
||||
_productCurrentPage = 0;
|
||||
displayProductByCategoryClickIndicator =
|
||||
S.of(context).end_of_the_list;
|
||||
} else {
|
||||
displayProductByCategoryClickIndicator =
|
||||
S.of(context).pull_up_to_load_more;
|
||||
}
|
||||
CategoryProducts currentCp =
|
||||
getCategoryProductByCategoryId(categoryId);
|
||||
if (currentCp != null) {
|
||||
currentCp.products.addAll(moreCategoryProducts[0].products);
|
||||
} else {
|
||||
_productCurrentPage = 0;
|
||||
displayProductByCategoryClickIndicator =
|
||||
S.of(context).end_of_the_list;
|
||||
}
|
||||
}
|
||||
CategoryProducts currentCp =
|
||||
getCategoryProductByCategoryId(categoryId);
|
||||
if (currentCp != null) {
|
||||
currentCp.products.addAll(moreCategoryProducts[0].products);
|
||||
} else {
|
||||
_productCurrentPage = 0;
|
||||
displayProductByCategoryClickIndicator =
|
||||
S.of(context).end_of_the_list;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
(error) {
|
||||
print('error: $error');
|
||||
if (_isLoading) {
|
||||
_isLoading = false;
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
Utils.showMessageDialog(context, error);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
(error) {
|
||||
print('error: $error');
|
||||
if (_isLoading) {
|
||||
_isLoading = false;
|
||||
Navigator.of(context).maybePop();
|
||||
}
|
||||
Utils.showMessageDialog(context, error);
|
||||
}, keyword: _searchController.text
|
||||
);
|
||||
}
|
||||
|
||||
CartLineItem _newCartLineItem(
|
||||
{int id,
|
||||
double price,
|
||||
Product product,
|
||||
String name,
|
||||
String description,
|
||||
double quantity}) {
|
||||
double price,
|
||||
Product product,
|
||||
String name,
|
||||
String description,
|
||||
double quantity}) {
|
||||
CartLineItem lineItem = CartLineItem();
|
||||
lineItem.unitPrice = price;
|
||||
lineItem.product = product;
|
||||
@@ -2087,10 +2089,10 @@ class DesktopShopState extends State<DesktopShop>
|
||||
S.of(context).store_closed,
|
||||
),
|
||||
actions: <Widget>[
|
||||
FlatButton(
|
||||
TextButton(
|
||||
child: Text(S.of(context).ok),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).maybePop();
|
||||
showPrompt(0);
|
||||
},
|
||||
)
|
||||
@@ -2143,10 +2145,10 @@ class DesktopShopState extends State<DesktopShop>
|
||||
),
|
||||
),
|
||||
actions: <Widget>[
|
||||
FlatButton(
|
||||
TextButton(
|
||||
child: Text(S.of(context).ok),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).maybePop();
|
||||
showPrompt(0);
|
||||
},
|
||||
)
|
||||
@@ -2169,7 +2171,7 @@ class DesktopShopState extends State<DesktopShop>
|
||||
title: Text(_prompt['title']),
|
||||
content: Text(_prompt['message']),
|
||||
actions: [
|
||||
FlatButton(
|
||||
TextButton(
|
||||
child: Text(S.of(context).ok),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
@@ -2184,6 +2186,158 @@ class DesktopShopState extends State<DesktopShop>
|
||||
|
||||
@override
|
||||
bool get wantKeepAlive => true;
|
||||
|
||||
void onSearchTap() {
|
||||
setState(() {
|
||||
if (searchIcon.icon == Icons.search) {
|
||||
searchIcon = new Icon(
|
||||
Icons.close,
|
||||
color: Colors.white,
|
||||
);
|
||||
if (displayProductByCategoryClick) {
|
||||
searchFieldPlaceHolder = Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child:
|
||||
TextField(
|
||||
controller: _searchController,
|
||||
textInputAction: TextInputAction.search,
|
||||
onSubmitted: (value) {
|
||||
onSearchButtonTap();
|
||||
},
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
),
|
||||
decoration: new InputDecoration(
|
||||
hintText: S
|
||||
.of(context)
|
||||
.enter_keyword,
|
||||
hintStyle: TextStyle(color: Colors.black26)),
|
||||
onChanged: searchOperation,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 5,),
|
||||
ElevatedButton.icon(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.redAccent,
|
||||
onPrimary: Colors.white,
|
||||
padding: EdgeInsets.only(left: 5, right: 5, top: 5, bottom: 5),
|
||||
elevation: 2.0,
|
||||
shape: new RoundedRectangleBorder(
|
||||
borderRadius: new BorderRadius.circular(5.0),
|
||||
),
|
||||
),
|
||||
onPressed: onSearchButtonTap,
|
||||
icon: Icon(
|
||||
Icons.search,
|
||||
size: 16,
|
||||
color: Colors.green,
|
||||
),
|
||||
label: Text(
|
||||
S.of(context).search,
|
||||
style: TextStyle(
|
||||
color: Colors.green,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
searchFieldPlaceHolder = TextField(
|
||||
controller: _searchController,
|
||||
style: TextStyle(
|
||||
color: Colors.black87,
|
||||
),
|
||||
decoration: new InputDecoration(
|
||||
hintText: S
|
||||
.of(context)
|
||||
.enter_keyword,
|
||||
hintStyle: TextStyle(color: Colors.black26)),
|
||||
onChanged: searchOperation,
|
||||
);
|
||||
_handleSearchStart();
|
||||
}
|
||||
} else {
|
||||
_handleSearchEnd();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _handleSearchStart() {
|
||||
setState(() {
|
||||
_isSearching = true;
|
||||
});
|
||||
}
|
||||
|
||||
void _handleSearchEnd() {
|
||||
setState(() {
|
||||
searchIcon = new Icon(
|
||||
Icons.search,
|
||||
color: Colors.blue,
|
||||
);
|
||||
searchFieldPlaceHolder = MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
child: Text(
|
||||
S.of(context).search_products,
|
||||
style: new TextStyle(color: Colors.blue),
|
||||
),
|
||||
onTap: () {
|
||||
onSearchTap();
|
||||
},
|
||||
),
|
||||
);
|
||||
_isSearching = false;
|
||||
_searchController.clear();
|
||||
if (displayProductByCategoryClick) {
|
||||
categoryId = 0;
|
||||
loadProducts();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void searchOperation(String searchText) {
|
||||
if (displayProductByCategoryClick) {
|
||||
|
||||
} else {
|
||||
if (responseData != null) {
|
||||
_categoryProducts.clear();
|
||||
List<CategoryProducts> cps = (responseData['category_products'] as List)
|
||||
.map((i) {
|
||||
CategoryProducts cp = CategoryProducts.fromJson(i);
|
||||
List<Product> ps = [];
|
||||
for (Product p in cp.products) {
|
||||
if (p.name.toLowerCase().contains(searchText.toLowerCase()) ||
|
||||
p.description.toLowerCase().contains(searchText.toLowerCase()) ||
|
||||
(p.detailDescription != null && p.detailDescription.toLowerCase().contains(searchText.toLowerCase()))) {
|
||||
ps.add(p);
|
||||
}
|
||||
}
|
||||
if (ps.length > 0) {
|
||||
cp.products = ps;
|
||||
return cp;
|
||||
}
|
||||
}).toList();
|
||||
for (CategoryProducts cp in cps) {
|
||||
if (cp != null) {
|
||||
_categoryProducts.add(cp);
|
||||
}
|
||||
}
|
||||
print('$searchText, count: ${_categoryProducts.length}');
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void onSearchButtonTap() {
|
||||
String kw = _searchController.text;
|
||||
if (kw.isNotEmpty) {
|
||||
_handleSearchStart();
|
||||
loadProducts();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class _SliverAppBarDelegate2 extends SliverPersistentHeaderDelegate {
|
||||
70
lib/widgets/desktop/shop_bulletin.dart
Normal file
70
lib/widgets/desktop/shop_bulletin.dart
Normal file
@@ -0,0 +1,70 @@
|
||||
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../models/business.dart';
|
||||
|
||||
class ShopBulletin extends StatefulWidget {
|
||||
final Business business;
|
||||
|
||||
const ShopBulletin(this.business, {Key key}): super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => ShopBulletinState();
|
||||
|
||||
}
|
||||
|
||||
class ShopBulletinState extends State<ShopBulletin> {
|
||||
double sideSpace = 0;
|
||||
double mainSpace = 1200;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (MediaQuery.of(context).size.width <= 1200) {
|
||||
mainSpace = MediaQuery.of(context).size.width;
|
||||
sideSpace = 0;
|
||||
} else {
|
||||
mainSpace = 1200;
|
||||
sideSpace = (MediaQuery.of(context).size.width - 1200) / 2;
|
||||
}
|
||||
|
||||
if (widget.business.bulletin != null && widget.business.bulletin.isNotEmpty) {
|
||||
return Container(
|
||||
margin: EdgeInsets.only(bottom: 12),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: sideSpace,
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(top: 10, left: 16.0, right: 16.0, bottom: 10.0),
|
||||
child: Text(
|
||||
'${widget.business.bulletin}',
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 3,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.orangeAccent,
|
||||
border: Border.all(
|
||||
color: Colors.red[500],
|
||||
width: 1.0,
|
||||
),
|
||||
borderRadius: BorderRadius.all(Radius.circular(16)),
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: sideSpace,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
|
||||
}
|
||||
431
lib/widgets/desktop/shop_products.dart
Normal file
431
lib/widgets/desktop/shop_products.dart
Normal file
@@ -0,0 +1,431 @@
|
||||
|
||||
import 'package:badges/badges.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../constants.dart';
|
||||
import '../../events/eventbus.dart';
|
||||
import '../../events/events.dart';
|
||||
import '../../generated/l10n.dart';
|
||||
import '../../models/business.dart';
|
||||
import '../../models/cart_info.dart';
|
||||
import '../../models/category_products.dart';
|
||||
import '../../store/store.dart';
|
||||
import '../../utils/utils.dart';
|
||||
import '../../widgets/desktop/product_item.dart';
|
||||
|
||||
class ShopProducts extends StatefulWidget {
|
||||
final dynamic data;
|
||||
|
||||
const ShopProducts(this.data, {Key key}): super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => ShopProductsState();
|
||||
}
|
||||
|
||||
class ShopProductsState extends State<ShopProducts> {
|
||||
double sideSpace = 0;
|
||||
double mainSpace = 1200;
|
||||
|
||||
dynamic data;
|
||||
|
||||
static const num _categoryHeight = 50.0;
|
||||
static const num _categoryDescHeight = 50.0;
|
||||
static const num _productHeight = 266.0;
|
||||
|
||||
bool displayProductByCategoryClick = false;
|
||||
String displayProductByCategoryClickIndicator = '';
|
||||
int categoryId = 0;
|
||||
double leftSideMenuWidth = 0;
|
||||
|
||||
int _categoryIndex = 0;
|
||||
List<CategoryProducts> _categoryProducts = [];
|
||||
Business _business;
|
||||
|
||||
double menuPosition = 0;
|
||||
|
||||
ScrollController _menuScrollController = ScrollController();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (MediaQuery.of(context).size.width <= 1200) {
|
||||
mainSpace = MediaQuery.of(context).size.width;
|
||||
sideSpace = 0;
|
||||
} else {
|
||||
mainSpace = 1200;
|
||||
sideSpace = (MediaQuery.of(context).size.width - 1200) / 2;
|
||||
}
|
||||
|
||||
return Container(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
width: sideSpace,
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
child:
|
||||
// Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.start,
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// mainAxisSize: MainAxisSize.min,
|
||||
// children: [
|
||||
// _buildCategories(),
|
||||
// Expanded(
|
||||
// child: _buildProducts(),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
IntrinsicHeight(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
_buildCategories(),
|
||||
Expanded(
|
||||
child: _buildProducts(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: sideSpace,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildCategories() {
|
||||
return new Container(
|
||||
width: leftSideMenuWidth,
|
||||
height: 500,
|
||||
color: new Color(0xFFF5F5F5),
|
||||
child: new SizedBox.expand(
|
||||
child: ListView.builder(
|
||||
physics: ClampingScrollPhysics(),
|
||||
controller: _menuScrollController,
|
||||
itemCount: _categoryProducts == null ? 0 : _categoryProducts.length,
|
||||
itemBuilder: (BuildContext context, int i) {
|
||||
CategoryProducts cp = _categoryProducts[i];
|
||||
int qtyInCategory = 0;
|
||||
CartInfo cartInfo = Utils.getCartInfoByBusiness(store.state.cartInfos, _business);
|
||||
if (cartInfo != null &&
|
||||
cartInfo.businessInfo.id == _business.id &&
|
||||
cartInfo.productList != null) {
|
||||
for (var i = 0; i < cartInfo.productList.length; i++) {
|
||||
if (cartInfo.productList[i].product.categoryId == cp.id) {
|
||||
qtyInCategory += cartInfo.productList[i].quantity.ceil();
|
||||
}
|
||||
}
|
||||
}
|
||||
Row categoryRow = Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[],
|
||||
);
|
||||
categoryRow.children.add(
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Container(
|
||||
margin: EdgeInsets.only(top: 5.0, bottom: 5.0),
|
||||
child: Text(
|
||||
cp.name,
|
||||
style: TextStyle(
|
||||
fontSize: 13.0,
|
||||
fontWeight: (cp.id == Constants.FEATURED_PRODUCT_ID ||
|
||||
cp.id == Constants.HOT_SALE_ID)
|
||||
? FontWeight.bold
|
||||
: FontWeight.normal,
|
||||
color: (cp.id == Constants.HOT_SALE_ID)
|
||||
? Colors.redAccent
|
||||
: ((cp.id == Constants.FEATURED_PRODUCT_ID)
|
||||
? Colors.lightGreen
|
||||
: Colors.black87)),
|
||||
// overflow: kIsWeb ? null : TextOverflow.ellipsis,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true,
|
||||
maxLines: 2,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
if (qtyInCategory > 0) {
|
||||
categoryRow.children.add(
|
||||
Badge(
|
||||
badgeContent: Text(
|
||||
'$qtyInCategory',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 11.0,
|
||||
),
|
||||
),
|
||||
animationType: BadgeAnimationType.scale,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
categoryRow.children.add(SizedBox.shrink());
|
||||
}
|
||||
return GestureDetector(
|
||||
child: new Container(
|
||||
height: 70.0,
|
||||
padding: new EdgeInsets.symmetric(horizontal: 10.0),
|
||||
decoration: new BoxDecoration(
|
||||
color: cp.id == categoryId ? Colors.white : null,
|
||||
border: new Border(
|
||||
bottom:
|
||||
new BorderSide(color: new Color(0xFFEBEBEB)))),
|
||||
child: categoryRow,
|
||||
),
|
||||
onTap: () => _selectCategory(cp.id),
|
||||
);
|
||||
}
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _selectCategory(int i) {
|
||||
categoryId = i;
|
||||
eventBus.fire(CategoryChangeEvent(i));
|
||||
}
|
||||
|
||||
Widget _buildProducts() {
|
||||
if (_categoryProducts == null) {
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
Column col = new Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: <Widget>[],
|
||||
);
|
||||
for (int i = 0; i < _categoryProducts.length; i++) {
|
||||
CategoryProducts cp = _categoryProducts[i];
|
||||
if (cp.products.length > 0) {
|
||||
col.children.add(new Container(
|
||||
height: _categoryDescHeight,
|
||||
padding: new EdgeInsets.symmetric(horizontal: 10.0),
|
||||
color: new Color(0xFFF5F5F5),
|
||||
child: new Row(
|
||||
children: <Widget>[
|
||||
new Expanded(
|
||||
child: new Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
textBaseline: TextBaseline.alphabetic,
|
||||
children: <Widget>[
|
||||
new Padding(
|
||||
padding: new EdgeInsets.only(right: 5.0),
|
||||
child: new Text(
|
||||
cp.name,
|
||||
style: new TextStyle(
|
||||
fontSize: 16.0,
|
||||
fontWeight:
|
||||
(cp.id == Constants.FEATURED_PRODUCT_ID ||
|
||||
cp.id == Constants.HOT_SALE_ID)
|
||||
? FontWeight.bold
|
||||
: FontWeight.normal,
|
||||
color: (cp.id == Constants.HOT_SALE_ID)
|
||||
? Colors.redAccent
|
||||
: ((cp.id ==
|
||||
Constants.FEATURED_PRODUCT_ID)
|
||||
? Colors.lightGreen
|
||||
: Colors.black87)),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
new Visibility(
|
||||
visible: cp.description.isNotEmpty,
|
||||
child: new Text(
|
||||
cp.description,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: new TextStyle(
|
||||
fontSize: 10.0,
|
||||
color: new Color(0xFF999999)),
|
||||
),
|
||||
replacement: const SizedBox.shrink()),
|
||||
],
|
||||
))
|
||||
],
|
||||
)));
|
||||
|
||||
var it = cp.products.iterator;
|
||||
for (int i = 0; i < cp.products.length; i++) {
|
||||
var r1 = Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [],
|
||||
);
|
||||
double d = getProductCountInRow();
|
||||
int c = int.parse(d.toString());
|
||||
while (d > 0) {
|
||||
if (it.moveNext()) {
|
||||
r1.children.add(
|
||||
Container(
|
||||
width: (mainSpace - leftSideMenuWidth) / c - 4.0,
|
||||
margin: EdgeInsets.only(top: 2.0, bottom: 2.0, left: 2.0, right: 2.0),
|
||||
child: ProductItem(
|
||||
it.current,
|
||||
_business,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
d -= 1;
|
||||
}
|
||||
col.children.add(r1);
|
||||
}
|
||||
|
||||
if (displayProductByCategoryClick) {
|
||||
if (displayProductByCategoryClickIndicator.isNotEmpty) {
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.all(12.0),
|
||||
child: Center(
|
||||
child: Text(
|
||||
displayProductByCategoryClickIndicator,
|
||||
style: TextStyle(
|
||||
color: Colors.black54,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else if (categoryId > 0) {
|
||||
if (cp.products.length < Constants.ORDERS_PER_PAGE) {
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.all(12.0),
|
||||
child: Center(
|
||||
child: Text(
|
||||
S
|
||||
.of(context)
|
||||
.end_of_the_list,
|
||||
style: TextStyle(
|
||||
color: Colors.black54,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.all(12.0),
|
||||
child: Center(
|
||||
child: Text(
|
||||
S
|
||||
.of(context)
|
||||
.pull_up_to_load_more,
|
||||
style: TextStyle(
|
||||
color: Colors.black54,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return col;
|
||||
}
|
||||
|
||||
void loadData() {
|
||||
// _categoryProducts .clear();
|
||||
_categoryProducts = (data['category_products'] as List)
|
||||
.map((i) => CategoryProducts.fromJson(i))
|
||||
.toList();
|
||||
_business = Business.fromJson(data['business']);
|
||||
displayProductByCategoryClick = data['display_product_by_category_click'];
|
||||
if (displayProductByCategoryClick) {
|
||||
leftSideMenuWidth = 200;
|
||||
}
|
||||
displayProductByCategoryClickIndicator = '';
|
||||
if (categoryId == 0 && displayProductByCategoryClick) {
|
||||
categoryId = _categoryProducts[0].id;
|
||||
}
|
||||
setState(() {
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
data = widget.data;
|
||||
loadData();
|
||||
eventBus.on<GetCategoryProducts>().listen((event) {
|
||||
if (mounted) {
|
||||
data = event.data;
|
||||
loadData();
|
||||
}
|
||||
});
|
||||
eventBus.on<MoreCategoryProducts>().listen((event) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
List<CategoryProducts> moreCategoryProducts = event.data;
|
||||
if (moreCategoryProducts.isEmpty) {
|
||||
displayProductByCategoryClickIndicator = S
|
||||
.of(context)
|
||||
.end_of_the_list;
|
||||
} else {
|
||||
if (moreCategoryProducts[0].products.length <
|
||||
Constants.ORDERS_PER_PAGE) {
|
||||
displayProductByCategoryClickIndicator = S
|
||||
.of(context)
|
||||
.end_of_the_list;
|
||||
} else {
|
||||
displayProductByCategoryClickIndicator =
|
||||
S
|
||||
.of(context)
|
||||
.pull_up_to_load_more;
|
||||
}
|
||||
CategoryProducts currentCp =
|
||||
getCategoryProductByCategoryId(categoryId);
|
||||
if (currentCp != null) {
|
||||
currentCp.products.addAll(moreCategoryProducts[0].products);
|
||||
} else {
|
||||
displayProductByCategoryClickIndicator = S
|
||||
.of(context)
|
||||
.end_of_the_list;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
int numCategoriesHasProducts() {
|
||||
int num = 0;
|
||||
for (CategoryProducts cp in _categoryProducts) {
|
||||
if (cp.products.length > 0) {
|
||||
num += 1;
|
||||
}
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
CategoryProducts getCategoryProductByCategoryId(int cid) {
|
||||
for (CategoryProducts cp in _categoryProducts) {
|
||||
if (cp.id == cid) {
|
||||
return cp;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
double getProductCountInRow() {
|
||||
double d = 2;
|
||||
if (mainSpace >= 800 && mainSpace < 1000) {
|
||||
d = 3;
|
||||
} else if (mainSpace >= 1000) {
|
||||
d = 4;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
}
|
||||
185
lib/widgets/desktop/shop_promote.dart
Normal file
185
lib/widgets/desktop/shop_promote.dart
Normal file
@@ -0,0 +1,185 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../generated/l10n.dart';
|
||||
import '../../pages/product_detail_page.dart';
|
||||
import '../../widgets/general/add_remove_button.dart';
|
||||
import '../../widgets/general/show_price.dart';
|
||||
|
||||
import '../../models/business.dart';
|
||||
import '../../models/product.dart';
|
||||
import '../../utils/util_io.dart' if (dart.library.html) '../../utils/util_web.dart';
|
||||
|
||||
class ShopPromote extends StatefulWidget {
|
||||
final dynamic data;
|
||||
|
||||
const ShopPromote(this.data, {Key key}): super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => ShopPromoteState();
|
||||
}
|
||||
|
||||
class ShopPromoteState extends State<ShopPromote> {
|
||||
double sideSpace = 0;
|
||||
double mainSpace = 1200;
|
||||
|
||||
Business _business;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (MediaQuery.of(context).size.width <= 1200) {
|
||||
mainSpace = MediaQuery.of(context).size.width;
|
||||
sideSpace = 0;
|
||||
} else {
|
||||
mainSpace = 1200;
|
||||
sideSpace = (MediaQuery.of(context).size.width - 1200) / 2;
|
||||
}
|
||||
|
||||
Row promoteRow = getPromoteRow();
|
||||
if (promoteRow.children.length > 0) {
|
||||
return Container(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: sideSpace,
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 12, bottom: 6),
|
||||
child: Text(
|
||||
S.of(context).promotions,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.only(bottom: 10),
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: promoteRow,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: sideSpace,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_business = Business.fromJson(widget.data['business']);
|
||||
}
|
||||
|
||||
Row getPromoteRow() {
|
||||
Row promotRow = Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[],
|
||||
);
|
||||
for (var i = 0; i < _business.promoProducts.length; i++) {
|
||||
promotRow.children.add(Container(
|
||||
padding: EdgeInsets.only(
|
||||
left: 10.0,
|
||||
top: 10.0,
|
||||
bottom: 10.0,
|
||||
right: 10.0,
|
||||
),
|
||||
margin: EdgeInsets.symmetric(horizontal: 5.0, vertical: 5.0),
|
||||
width: 220.0,
|
||||
height: 220.0,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(5.0)),
|
||||
color: Colors.white,
|
||||
border: Border(
|
||||
top: BorderSide(
|
||||
width: 1.0,
|
||||
color: Colors.black12,
|
||||
),
|
||||
bottom: BorderSide(
|
||||
width: 1.0,
|
||||
color: Colors.black12,
|
||||
),
|
||||
left: BorderSide(
|
||||
width: 1.0,
|
||||
color: Colors.black12,
|
||||
),
|
||||
right: BorderSide(
|
||||
width: 1.0,
|
||||
color: Colors.black12,
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
GestureDetector(
|
||||
child: Container(
|
||||
child: Util.showImage(
|
||||
_business.promoProducts[i].imagePath,
|
||||
width: 120.0,
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
_showProductDetail(_business.promoProducts[i]);
|
||||
},
|
||||
),
|
||||
Container(
|
||||
child: Text(
|
||||
_business.promoProducts[i].name,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(fontSize: 14.0),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
ShowPrice(
|
||||
_business.promoProducts[i].price,
|
||||
currencySign: '\$',
|
||||
fontWeight: FontWeight.bold,
|
||||
smallFontSize: 15,
|
||||
largeFontSize: 24,
|
||||
regularPrice: _business.promoProducts[i].regularPrice,
|
||||
),
|
||||
Container(
|
||||
child: AddRemoveButton(
|
||||
product: _business.promoProducts[i],
|
||||
business: _business,
|
||||
addOnly: true,
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
));
|
||||
}
|
||||
return promotRow;
|
||||
}
|
||||
|
||||
void _showProductDetail(Product p) {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ProductDetailPage(
|
||||
product: p,
|
||||
business: _business,
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
||||
79
lib/widgets/desktop/shopping_cart_widget.dart
Normal file
79
lib/widgets/desktop/shopping_cart_widget.dart
Normal file
@@ -0,0 +1,79 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../events/eventbus.dart';
|
||||
import '../../events/events.dart';
|
||||
import '../../models/business.dart';
|
||||
import '../../models/cart_info.dart';
|
||||
import '../../store/store.dart';
|
||||
import '../../utils/utils.dart';
|
||||
|
||||
class ShoppingCartWidget extends StatefulWidget {
|
||||
final Business business;
|
||||
final Function onTap;
|
||||
|
||||
ShoppingCartWidget({@required this.business, this.onTap});
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => ShoppingCartWidgetState();
|
||||
}
|
||||
|
||||
class ShoppingCartWidgetState extends State<ShoppingCartWidget> {
|
||||
CartInfo cartInfo;
|
||||
double totalPrice = 0.0;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
totalPrice = 0.0;
|
||||
cartInfo = Utils.getCartInfoByBusiness(store.state.cartInfos, widget.business);
|
||||
if (cartInfo != null && cartInfo.businessInfo.id == widget.business.id) {
|
||||
totalPrice = cartInfo.getTotalPrice();
|
||||
}
|
||||
Row row = Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 16.0, right: 4.0, top: 8.0),
|
||||
child: Icon(
|
||||
Icons.shopping_basket_outlined,
|
||||
size: 24,
|
||||
color: Colors.blue,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 4.0, right: 16.0, top: 8.0),
|
||||
child: Text(
|
||||
'\$${totalPrice.toStringAsFixed(2)}',
|
||||
style: TextStyle(
|
||||
color: totalPrice > 0 ? Colors.red : Colors.black45,
|
||||
fontWeight: totalPrice > 0 ? FontWeight.bold : FontWeight.normal,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
return MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
child: Container(
|
||||
child: row,
|
||||
width: 160.0,
|
||||
),
|
||||
onTap: widget.onTap,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
eventBus.on<OnCartInfoUpdated>().listen((event) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -4,11 +4,13 @@ import 'package:flutter/rendering.dart';
|
||||
|
||||
import '../../generated/l10n.dart';
|
||||
import '../../routes.dart';
|
||||
import 'navigationbar.dart';
|
||||
|
||||
class BreadCrumbs extends StatelessWidget {
|
||||
final List<BreadCrumb> breadCrumbs;
|
||||
final bool hasBack;
|
||||
const BreadCrumbs(this.hasBack, {this.breadCrumbs, Key key}) : super(key: key);
|
||||
final OnBackPress onBackPress;
|
||||
const BreadCrumbs(this.hasBack, {this.breadCrumbs, Key key, this.onBackPress}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -39,8 +41,8 @@ class BreadCrumbs extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
onTap: () {
|
||||
Routes.router.pop(context);
|
||||
onTap: onBackPress != null ? onBackPress : () {
|
||||
Navigator.of(context).maybePop();
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -72,7 +74,7 @@ class BreadCrumbs extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 0.0),
|
||||
padding: EdgeInsets.only(top: 6.0, left: 4.0, right: 4.0),
|
||||
child: Icon(
|
||||
Icons.circle,
|
||||
size: 6.0,
|
||||
@@ -123,7 +125,7 @@ class BreadCrumbs extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 0.0),
|
||||
padding: EdgeInsets.only(top: 6.0, left: 4.0, right: 4.0),
|
||||
child: Icon(
|
||||
Icons.circle,
|
||||
size: 6.0,
|
||||
|
||||
@@ -6,7 +6,9 @@ import '../../widgets/desktop/desktop_navigationbar.dart';
|
||||
import '../../widgets/mobile/mobile_navigationbar.dart';
|
||||
import 'breadcrumbs.dart';
|
||||
|
||||
class NavigationBar extends StatefulWidget implements PreferredSizeWidget {
|
||||
typedef OnBackPress();
|
||||
|
||||
class MiniNavigationBar extends StatefulWidget implements PreferredSizeWidget {
|
||||
final Key key;
|
||||
final String title;
|
||||
final bool back;
|
||||
@@ -16,7 +18,7 @@ class NavigationBar extends StatefulWidget implements PreferredSizeWidget {
|
||||
final double breadCrumbHeight;
|
||||
final Widget shoppingCart;
|
||||
|
||||
NavigationBar({Key key, PreferredSizeWidget bottom, String title,
|
||||
MiniNavigationBar({Key key, PreferredSizeWidget bottom, String title,
|
||||
bool back, bool toHome, bool showMe, this.breadCrumbs,
|
||||
this.breadCrumbHeight, this.shoppingCart})
|
||||
: key = key,
|
||||
@@ -32,12 +34,12 @@ class NavigationBar extends StatefulWidget implements PreferredSizeWidget {
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return NavigationBarState();
|
||||
return MiniNavigationBarState();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class NavigationBarState extends State<NavigationBar> {
|
||||
class MiniNavigationBarState extends State<MiniNavigationBar> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
@@ -33,6 +33,9 @@ class PaymentVerificationCodeDialogState extends State<PaymentVerificationCodeDi
|
||||
String getCodeText = '';
|
||||
String paymentCodeEncrypt = '';
|
||||
|
||||
String verifyMethod;
|
||||
String verifyName;
|
||||
|
||||
final TextEditingController _pinPutController = TextEditingController();
|
||||
final FocusNode _pinPutFocusNode = FocusNode();
|
||||
BoxDecoration get _pinPutDecoration {
|
||||
@@ -53,12 +56,15 @@ class PaymentVerificationCodeDialogState extends State<PaymentVerificationCodeDi
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 0.0, bottom: 10.0, left: 0.0, right: 0.0),
|
||||
child: Text(
|
||||
S.of(context).payment_verification_sent(Utils.safePhoneNumber(widget.user.mobile)),
|
||||
(verifyMethod != null) ? S.of(context).payment_verification_sent(
|
||||
(verifyName == 'sms') ? S.of(context).mobile : S.of(context).email,
|
||||
Utils.safePhoneNumber(verifyName)
|
||||
) : '',
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 0.0, bottom: 10.0, left: 0.0, right: 0.0),
|
||||
child: FlatButton(
|
||||
child: TextButton(
|
||||
child: Text(getCodeText),
|
||||
onPressed: enableGetCode ? () {
|
||||
getPaymentCode();
|
||||
@@ -146,6 +152,8 @@ class PaymentVerificationCodeDialogState extends State<PaymentVerificationCodeDi
|
||||
},
|
||||
).then((data) {
|
||||
paymentCodeEncrypt = data['payment_code_encrypt'];
|
||||
verifyMethod = data['verify_method'];
|
||||
verifyName = data['verify_name'];
|
||||
print('data: $data');
|
||||
startCountDown();
|
||||
}).catchError((error) {
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/models/business.dart';
|
||||
import 'package:flutter_wisetronic/models/product.dart';
|
||||
import 'package:flutter_wisetronic/widgets/desktop/desktop_product_item.dart';
|
||||
import 'package:flutter_wisetronic/widgets/mobile/mobile_product_item.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
|
||||
class ProductItem extends StatelessWidget {
|
||||
final Product product;
|
||||
final Business business;
|
||||
|
||||
const ProductItem({Key key, this.product, this.business}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ResponsiveBuilder(
|
||||
builder: (context, sizingInformation) =>
|
||||
ScreenTypeLayout(
|
||||
mobile: MobileProductItem(product: product, business: business,),
|
||||
tablet: DesktopProductItem(product: product, business: business,),
|
||||
desktop: DesktopProductItem(product: product, business: business,),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import 'package:fluro/fluro.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_wisetronic/utils/utils.dart';
|
||||
import 'package:hovering/hovering.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
import '../../routes.dart';
|
||||
@@ -11,6 +12,7 @@ class TextLink extends StatelessWidget {
|
||||
final String title;
|
||||
final String url;
|
||||
final Color color;
|
||||
final Color hoverColor;
|
||||
final double paddingHorizontal;
|
||||
final double paddingVertical;
|
||||
final FontWeight fontWeight;
|
||||
@@ -24,8 +26,14 @@ class TextLink extends StatelessWidget {
|
||||
final bool closeDrawer;
|
||||
final bool isEmail;
|
||||
final bool isPhone;
|
||||
final double fontSize;
|
||||
final bool isAddress;
|
||||
final TextOverflow overflow;
|
||||
final int maxLines;
|
||||
|
||||
TextLink(this.title, this.url, {
|
||||
this.color,
|
||||
this.hoverColor,
|
||||
this.paddingHorizontal,
|
||||
this.paddingVertical,
|
||||
this.fontWeight,
|
||||
@@ -39,6 +47,10 @@ class TextLink extends StatelessWidget {
|
||||
bool closeDrawer,
|
||||
bool isEmail,
|
||||
bool isPhone,
|
||||
double fontSize,
|
||||
bool isAddress,
|
||||
TextOverflow overflow,
|
||||
int maxLines,
|
||||
}) :
|
||||
isLink = isLink ?? false,
|
||||
replace = replace ?? false,
|
||||
@@ -47,7 +59,11 @@ class TextLink extends StatelessWidget {
|
||||
rootNavigator = rootNavigator ?? false,
|
||||
closeDrawer = closeDrawer ?? false,
|
||||
isEmail = isEmail ?? false,
|
||||
isPhone = isPhone ?? false;
|
||||
isPhone = isPhone ?? false,
|
||||
fontSize = fontSize ?? null,
|
||||
isAddress = isAddress ?? false,
|
||||
overflow = overflow ?? TextOverflow.ellipsis,
|
||||
maxLines = maxLines ?? 1;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -59,19 +75,37 @@ class TextLink extends StatelessWidget {
|
||||
vertical: paddingVertical ?? 0.0,
|
||||
horizontal: paddingHorizontal ?? 0.0
|
||||
),
|
||||
child: Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
color: color ?? Colors.blue,
|
||||
fontWeight: fontWeight ?? FontWeight.normal,
|
||||
child: HoverWidget(
|
||||
child: Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
color: color ?? Colors.blue,
|
||||
fontWeight: fontWeight ?? FontWeight.normal,
|
||||
fontSize: fontSize,
|
||||
),
|
||||
overflow: overflow,
|
||||
maxLines: maxLines,
|
||||
),
|
||||
hoverChild: Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
color: hoverColor ?? Colors.grey,
|
||||
fontSize: fontSize,
|
||||
fontWeight: fontWeight ?? FontWeight.normal,
|
||||
),
|
||||
overflow: overflow,
|
||||
maxLines: maxLines,
|
||||
),
|
||||
onHover: (event) {
|
||||
|
||||
},
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
border: (selected != null && selected) ? Border(
|
||||
bottom: BorderSide(
|
||||
color: color ?? Colors.blue,
|
||||
width: 3.0,
|
||||
)
|
||||
bottom: BorderSide(
|
||||
color: color ?? Colors.blue,
|
||||
width: 3.0,
|
||||
)
|
||||
) : null,
|
||||
),
|
||||
),
|
||||
@@ -81,6 +115,8 @@ class TextLink extends StatelessWidget {
|
||||
Utils.openEmail(url);
|
||||
} else if (isPhone) {
|
||||
Utils.callPhone(url);
|
||||
} else if (isAddress) {
|
||||
await launch('https://maps.google.com/?q=${url}');
|
||||
} else if (!isLink) {
|
||||
if (closeDrawer) {
|
||||
Routes.router.pop(context);
|
||||
|
||||
411
lib/widgets/mobile/create_online_store_1.dart
Normal file
411
lib/widgets/mobile/create_online_store_1.dart
Normal file
@@ -0,0 +1,411 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '/models/group.dart';
|
||||
import '/pages/buy_service.dart';
|
||||
import '../../constants.dart';
|
||||
import '../../generated/l10n.dart';
|
||||
import '../../routes.dart';
|
||||
import '../../utils/http_util.dart';
|
||||
import '../../utils/utils.dart';
|
||||
|
||||
class CreateOnlineStore1 extends StatefulWidget {
|
||||
final int businessId;
|
||||
|
||||
const CreateOnlineStore1(this.businessId, {Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return CreateOnlineStore1State();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class CreateOnlineStore1State extends State<CreateOnlineStore1> {
|
||||
|
||||
TextEditingController groupNumberController = TextEditingController();
|
||||
|
||||
TextEditingController domainController = TextEditingController();
|
||||
|
||||
bool canSubmit = false;
|
||||
|
||||
List<dynamic> stores = [];
|
||||
Map<String, dynamic> service;
|
||||
dynamic selectedStore;
|
||||
|
||||
Group group;
|
||||
|
||||
String selectedDomain;
|
||||
List<dynamic> domainResult = [];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Column col = Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [],
|
||||
);
|
||||
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 20, left: 16, right: 16, bottom: 10,),
|
||||
child: Text(
|
||||
S.of(context).open_online_store,
|
||||
style: TextStyle(
|
||||
fontSize: 28,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 4, bottom: 4, left: 16.0, right: 16.0),
|
||||
child: Text(
|
||||
S.of(context)
|
||||
.select_a_store,
|
||||
style: TextStyle(
|
||||
color: Colors.black45,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 4, bottom: 4, left: 16.0, right: 16.0),
|
||||
child: DropdownButton<dynamic>(
|
||||
items: stores.map((e) => DropdownMenuItem<dynamic>(
|
||||
value: e,
|
||||
child: Text(e['name']),
|
||||
)).toList(),
|
||||
isExpanded: false,
|
||||
hint: Text(S.of(context).select_a_store),
|
||||
onChanged: (newValue) {
|
||||
print('newValue $newValue');
|
||||
setState(() {
|
||||
selectedStore = newValue;
|
||||
});
|
||||
},
|
||||
value: selectedStore,
|
||||
),
|
||||
),
|
||||
);
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(
|
||||
left: 16.0, right: 16.0, top: 20, bottom: 20),
|
||||
child: Visibility(
|
||||
child: getSearchDomainWidget(),
|
||||
visible: selectedStore != null,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: IconButton(
|
||||
icon: Icon(Icons.arrow_back_ios),
|
||||
onPressed: (){
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
title: Text(S.of(context).open_online_store),
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: col,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getSearchDomainWidget() {
|
||||
if (selectedStore == null) {
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
Column col = Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [],
|
||||
);
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(bottom: 4,),
|
||||
child: Text(selectedStore == null ? '' : selectedStore['name'],
|
||||
style: TextStyle(
|
||||
fontSize: 28,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
Map<String, dynamic> existing_web_svc;
|
||||
if (selectedStore != null && (selectedStore['services'] as List).length > 0) {
|
||||
for (Map<String, dynamic>svc in (selectedStore['services'] as List)) {
|
||||
if (svc['code'] == Constants.WEB_MINISTORE_SERVICE) {
|
||||
existing_web_svc = svc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (existing_web_svc != null) {
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 8.0),
|
||||
child: Text(
|
||||
'${existing_web_svc['description']}',
|
||||
),
|
||||
),
|
||||
);
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 4.0),
|
||||
child: Text(
|
||||
S.of(context).expiration_date + ": "
|
||||
+ Utils.utcDatetimeStringToLocalDatetimeString(context, existing_web_svc['expiration_date']),
|
||||
),
|
||||
),
|
||||
);
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 4.0),
|
||||
child: Text(
|
||||
S.of(context).store + ": " + '${existing_web_svc['store']['name']}'
|
||||
),
|
||||
),
|
||||
);
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 4.0),
|
||||
child: Text(
|
||||
S.of(context).domain_name + ": " + '${existing_web_svc['domain']}'
|
||||
),
|
||||
),
|
||||
);
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 10.0),
|
||||
child: ElevatedButton(
|
||||
child: Text(S.of(context).renew_service_now),
|
||||
onPressed: () {
|
||||
Navigator.pushReplacement(context, MaterialPageRoute(
|
||||
builder: (BuildContext context) =>
|
||||
BuyService(group.id, Constants.WEB_MINISTORE_SERVICE,
|
||||
domain: existing_web_svc['domain'],
|
||||
sid: existing_web_svc['store']['id'],
|
||||
),
|
||||
));
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 8.0),
|
||||
child: Text(S.of(context).enter_desired_domain),
|
||||
),
|
||||
);
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 0,),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
controller: domainController,
|
||||
decoration: new InputDecoration(
|
||||
enabledBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Colors.black12,
|
||||
),
|
||||
),
|
||||
focusedBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Colors.blue,
|
||||
),
|
||||
),
|
||||
labelText: S.of(context).domains_separated_comma,
|
||||
),
|
||||
style: TextStyle(
|
||||
fontSize: 18.0
|
||||
),
|
||||
autofocus: true,
|
||||
validator: (String value) {
|
||||
if (value.trim().isEmpty) {
|
||||
return S.of(context).domains_separated_comma;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
onChanged: (string) {
|
||||
if (string.isNotEmpty) {
|
||||
canSubmit = true;
|
||||
} else {
|
||||
canSubmit = false;
|
||||
}
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 8.0),
|
||||
child: ElevatedButton(
|
||||
child: Text(
|
||||
S.of(context).check_domain_name,
|
||||
),
|
||||
onPressed: domainController.text.length > 0 ? checkDomainAvailability : null,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
);
|
||||
if (domainResult.length > 0) {
|
||||
for (dynamic dr in domainResult) {
|
||||
col.children.add(_getDomain(dr));
|
||||
}
|
||||
}
|
||||
if (selectedDomain != null && service != null) {
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 8.0),
|
||||
child: Text(
|
||||
service['description'],
|
||||
),
|
||||
),
|
||||
);
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 8.0),
|
||||
child: Text(
|
||||
service['options'][0]['name'],
|
||||
),
|
||||
),
|
||||
);
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 8.0),
|
||||
child: Text(
|
||||
'\$${service['options'][0]['price']}',
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.orange,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 10.0),
|
||||
child: ElevatedButton(
|
||||
child: Text(
|
||||
S.of(context).place_order_now,
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.pushReplacement(context, MaterialPageRoute(
|
||||
builder: (BuildContext context) =>
|
||||
BuyService(group.id, Constants.WEB_MINISTORE_SERVICE,
|
||||
domain: selectedDomain,
|
||||
sid: selectedStore['id'],
|
||||
),
|
||||
));
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
return Container(
|
||||
padding: EdgeInsets.only(bottom: 4,),
|
||||
child: col,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
HttpUtil.httpGet(
|
||||
'v1/get-contact-stores',
|
||||
queryParameters: {
|
||||
'service': Constants.WEB_MINISTORE_SERVICE
|
||||
}
|
||||
).then((value) {
|
||||
setState(() {
|
||||
stores = value['stores'];
|
||||
service = value['service'];
|
||||
group = Group.fromJson(value['group']);
|
||||
print('stores: ${value}');
|
||||
});
|
||||
}).onError((error, stackTrace) {
|
||||
Utils.showMessageDialog(context, error, onOk: () {
|
||||
Routes.router.navigateTo(context, '/');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> checkDomainAvailability() async {
|
||||
Utils.showLoadingDialog(context);
|
||||
selectedDomain = null;
|
||||
domainResult = [];
|
||||
setState(() {});
|
||||
HttpUtil.httpGet(
|
||||
'v1/check-domain-availability',
|
||||
queryParameters: {
|
||||
'domain': domainController.text,
|
||||
},
|
||||
).then((value) {
|
||||
Routes.router.pop(context);
|
||||
print('value: $value');
|
||||
if (value['status'] == 'OK') {
|
||||
domainResult = (value['domain_check_result'] as List);
|
||||
setState(() {});
|
||||
} else if (value['status'] == 'ERROR') {
|
||||
String errors = '';
|
||||
for (int i = 0; i < (value['errors'] as List).length; i++) {
|
||||
errors += value['errors'][i] + '\n';
|
||||
}
|
||||
Utils.showMessageDialog(context, errors);
|
||||
}
|
||||
}).onError((error, stackTrace) {
|
||||
Routes.router.pop(context);
|
||||
Utils.showMessageDialog(context, error);
|
||||
});
|
||||
}
|
||||
|
||||
Widget _getDomain(dynamic d) {
|
||||
if ((d['available'] as bool)) {
|
||||
return Container(
|
||||
child: ListTile(
|
||||
title: Text(
|
||||
d['domain'],
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
leading: Radio(
|
||||
value: d['domain'],
|
||||
groupValue: selectedDomain,
|
||||
onChanged: (val) {
|
||||
setState(() {
|
||||
selectedDomain = val;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(top: 1.0),
|
||||
child: ListTile(
|
||||
title: Text(
|
||||
d['domain'],
|
||||
style: TextStyle(
|
||||
color: Colors.black45,
|
||||
),
|
||||
),
|
||||
leading: Icon(Icons.clear, color: Colors.red,),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,6 +52,18 @@ class MobileBuyServiceState extends State<MobileBuyService> {
|
||||
Utils.buildLine(S.of(context).your_group, widget.data['group']['name'], valueSize: 16),
|
||||
);
|
||||
|
||||
if (widget.data['store']['id'] != null) {
|
||||
col1.children.add(
|
||||
Utils.buildLine(S.of(context).store, widget.data['store']['name'], valueSize: 16),
|
||||
);
|
||||
}
|
||||
|
||||
if (widget.data['domain'] != null) {
|
||||
col1.children.add(
|
||||
Utils.buildLine(S.of(context).domain_name, widget.data['domain'], valueSize: 16),
|
||||
);
|
||||
}
|
||||
|
||||
if (widget.data['exists_service'] == null) {
|
||||
col1.children.add(
|
||||
Utils.buildLine(S.of(context).current_plan, 'N/A', valueSize: 16),
|
||||
|
||||
@@ -335,6 +335,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
check();
|
||||
},
|
||||
initialLabelIndex: deliveryMethodIndex,
|
||||
totalSwitches: shippingMethodLabels.length,
|
||||
);
|
||||
switch (position) {
|
||||
case 0:
|
||||
|
||||
@@ -189,6 +189,7 @@ class MobileNavigationDrawerState extends State<MobileNavigationDrawer> {
|
||||
TextLink(S.of(context).contact_us, '/contact-us', paddingVertical: 5.0, paddingHorizontal: 10.0, closeDrawer: true,),
|
||||
TextLink(S.of(context).about_us, '/about-us', paddingVertical: 5.0, paddingHorizontal: 10.0, closeDrawer: true,),
|
||||
TextLink(S.of(context).renew_license, '/renew-license', paddingVertical: 5.0, paddingHorizontal: 10.0, closeDrawer: true,),
|
||||
TextLink(S.of(context).create_a_online_store, '/contact-stores', paddingVertical: 5.0, paddingHorizontal: 10.0,),
|
||||
Container(
|
||||
margin: EdgeInsets.only(top: 20.0, bottom: 10.0),
|
||||
child: Text(
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
|
||||
import '../../constants.dart';
|
||||
import '../../utils/iframe_web.dart' if (dart.library.io) '../../utils/fake_iframe_web.dart';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||
|
||||
class MobileTutorials extends StatefulWidget {
|
||||
const MobileTutorials({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return MobileTutorialsState();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class MobileTutorialsState extends State<MobileTutorials> {
|
||||
InAppWebViewController webView;
|
||||
String url = "";
|
||||
double progress = 0;
|
||||
bool isLoadStop = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (kIsWeb) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Expanded(
|
||||
child: IFrameWeb(
|
||||
width: double.maxFinite.toString(),
|
||||
height: double.maxFinite.toString(),
|
||||
src: Constants.TUTORIAL_URL,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
print('progress: $progress');
|
||||
return Stack(
|
||||
children: [
|
||||
InAppWebView(
|
||||
initialUrlRequest: URLRequest(url: Uri.parse(Constants.TUTORIAL_URL)),
|
||||
initialOptions: InAppWebViewGroupOptions(
|
||||
crossPlatform: InAppWebViewOptions(
|
||||
|
||||
),
|
||||
),
|
||||
onWebViewCreated: (InAppWebViewController controller) {
|
||||
webView = controller;
|
||||
},
|
||||
onLoadStart: (controller, url) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
this.url = url.toString();
|
||||
this.isLoadStop = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
onLoadStop: (controller, url) async {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
this.url = url.toString();
|
||||
this.isLoadStop = true;
|
||||
});
|
||||
}
|
||||
},
|
||||
onProgressChanged: (InAppWebViewController controller, int progress) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
if (this.progress < 1.0) {
|
||||
this.isLoadStop = false;
|
||||
} else {
|
||||
this.isLoadStop = true;
|
||||
}
|
||||
this.progress = progress / 100;
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
isLoadStop ? Container() :
|
||||
Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,6 +13,8 @@ import '../../store/store.dart';
|
||||
import '../../utils/http_util.dart';
|
||||
import '../../utils/utils.dart';
|
||||
|
||||
import '../../utils/util_io.dart' if (dart.library.html) '../../utils/util_web.dart';
|
||||
|
||||
class MobileViewBlog extends StatefulWidget {
|
||||
final Key key;
|
||||
final int bid;
|
||||
@@ -126,11 +128,7 @@ class MobileViewBlogState extends State<MobileViewBlog> {
|
||||
Container(
|
||||
width: min(MediaQuery.of(context).size.width, MediaQuery.of(context).size.height) - 100.0,
|
||||
height: min(MediaQuery.of(context).size.width, MediaQuery.of(context).size.height) - 100.0,
|
||||
child: PhotoView(
|
||||
imageProvider: NetworkImage(
|
||||
'https:${blog.imageUrl}',
|
||||
),
|
||||
),
|
||||
child: Util.showImage('https:${blog.imageUrl}'),
|
||||
) : SizedBox.shrink(),
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
|
||||
261
lib/widgets/mobile/product_item.dart
Normal file
261
lib/widgets/mobile/product_item.dart
Normal file
@@ -0,0 +1,261 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../constants.dart';
|
||||
import '../../events/eventbus.dart';
|
||||
import '../../events/events.dart';
|
||||
import '../../generated/l10n.dart';
|
||||
import '../../models/business.dart';
|
||||
import '../../models/product.dart';
|
||||
import '../../pages/product_detail_page.dart';
|
||||
import '../../utils/util_io.dart' if (dart.library.html) '../../utils/util_web.dart';
|
||||
import '../../widgets/general/add_remove_button.dart';
|
||||
import '../../widgets/general/show_price.dart';
|
||||
|
||||
class ProductItem extends StatefulWidget {
|
||||
final Business business;
|
||||
final Product product;
|
||||
final bool horizontal;
|
||||
final double imageWidth;
|
||||
|
||||
const ProductItem(this.product, this.business, {
|
||||
Key key,
|
||||
this.horizontal = false,
|
||||
this.imageWidth = 110,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => ProductItemState();
|
||||
|
||||
}
|
||||
|
||||
class ProductItemState extends State<ProductItem> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
// width: 160.0,
|
||||
height: widget.horizontal ? Constants.PRODUCT_ITEM_HEIGHT_H : Constants.PRODUCT_ITEM_HEIGHT_V,
|
||||
padding: new EdgeInsets.symmetric(horizontal: 10.0, vertical: 15.0).copyWith(bottom: 5.0),
|
||||
decoration: new BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: new Border(
|
||||
bottom: new BorderSide(
|
||||
color: new Color(0xFFEBEBEB),
|
||||
),
|
||||
),
|
||||
),
|
||||
child: new SizedBox.expand(
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(left: 10.0, right: 10.0, top: 10.0, bottom: 10.0),
|
||||
child: widget.horizontal ? getHorizontal(true) : getVertial(true),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getHorizontal(bool onHover) {
|
||||
Row row1 = Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
margin: new EdgeInsets.all(10.0),
|
||||
width: widget.imageWidth,
|
||||
height: widget.imageWidth,
|
||||
child: GestureDetector(
|
||||
child: onHover && widget.product.secondImagePath.isNotEmpty ?
|
||||
Util.showImage('${widget.product.secondImagePath}',
|
||||
fit: BoxFit.fill,
|
||||
) :
|
||||
Util.showImage('${widget.product.imagePath}',
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
onTap: (){
|
||||
_showProductDetail();
|
||||
},
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: GestureDetector(
|
||||
child: Text(
|
||||
'${widget.product.name}',
|
||||
// overflow: kIsWeb ? null : TextOverflow.ellipsis,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 2,
|
||||
softWrap: true,
|
||||
style: new TextStyle(
|
||||
fontSize: 15.0,
|
||||
),
|
||||
),
|
||||
onTap: (){
|
||||
_showProductDetail();
|
||||
},
|
||||
),
|
||||
),
|
||||
Text(
|
||||
widget.product.description,
|
||||
// overflow: kIsWeb ? null : TextOverflow.ellipsis,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 2,
|
||||
style: new TextStyle(
|
||||
fontSize: 12.0,
|
||||
color: new Color(0xFF999999),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
row1,
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
new Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
new Container(
|
||||
child: widget.business.showMonthlySold ?
|
||||
Text(
|
||||
S.of(context).sold_per_month_token(widget.product.monthSales.toStringAsFixed(0)),
|
||||
style: new TextStyle(
|
||||
fontSize: 9.0
|
||||
),
|
||||
) : SizedBox.shrink(),
|
||||
),
|
||||
ShowPrice(
|
||||
widget.product.price,
|
||||
regularPrice: widget.product.regularPrice,
|
||||
currencySign: '\$',
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
],
|
||||
),
|
||||
AddRemoveButton(product: widget.product, business: widget.business, addOnly: false, onHovor: onHover,),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget getVertial(bool onHover) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
new Container(
|
||||
margin: new EdgeInsets.all(10.0),
|
||||
width: widget.imageWidth,
|
||||
height: widget.imageWidth,
|
||||
child: GestureDetector(
|
||||
child: onHover && widget.product.secondImagePath.isNotEmpty ?
|
||||
Util.showImage('${widget.product.secondImagePath}',
|
||||
fit: BoxFit.fill,
|
||||
) :
|
||||
Util.showImage('${widget.product.imagePath}',
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
onTap: (){
|
||||
_showProductDetail();
|
||||
},
|
||||
),
|
||||
),
|
||||
new Expanded(
|
||||
child: new Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: GestureDetector(
|
||||
child: Text(
|
||||
'${widget.product.name}',
|
||||
// overflow: kIsWeb ? null : TextOverflow.ellipsis,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 2,
|
||||
softWrap: true,
|
||||
style: new TextStyle(
|
||||
fontSize: 15.0,
|
||||
),
|
||||
),
|
||||
onTap: (){
|
||||
_showProductDetail();
|
||||
},
|
||||
),
|
||||
),
|
||||
Container(
|
||||
child: Text(
|
||||
widget.product.description,
|
||||
// overflow: kIsWeb ? null : TextOverflow.ellipsis,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 2,
|
||||
style: new TextStyle(
|
||||
fontSize: 12.0,
|
||||
color: new Color(0xFF999999),
|
||||
),
|
||||
),
|
||||
),
|
||||
new Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
new Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
new Container(
|
||||
child: widget.business.showMonthlySold ?
|
||||
Text(
|
||||
S.of(context).sold_per_month_token(widget.product.monthSales.toStringAsFixed(0)),
|
||||
style: new TextStyle(
|
||||
fontSize: 9.0
|
||||
),
|
||||
) : SizedBox.shrink(),
|
||||
),
|
||||
ShowPrice(
|
||||
widget.product.price,
|
||||
regularPrice: widget.product.regularPrice,
|
||||
currencySign: '\$',
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
],
|
||||
),
|
||||
AddRemoveButton(product: widget.product, business: widget.business, addOnly: false, onHovor: onHover,),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
void _showProductDetail() {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ProductDetailPage(
|
||||
product: widget.product,
|
||||
business: widget.business,
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
eventBus.on<OnCartInfoUpdated>().listen((event) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
152
lib/widgets/mobile/product_search.dart
Normal file
152
lib/widgets/mobile/product_search.dart
Normal file
@@ -0,0 +1,152 @@
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flappy_search_bar/flappy_search_bar.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../events/eventbus.dart';
|
||||
import '../../events/events.dart';
|
||||
import '../../generated/l10n.dart';
|
||||
import '../../models/business.dart';
|
||||
import '../../models/product.dart';
|
||||
import '../../pages/product_detail_page.dart';
|
||||
import '../../utils/http_util.dart';
|
||||
import '../../utils/utils.dart';
|
||||
import '../../widgets/general/breadcrumbs.dart';
|
||||
import '../../widgets/general/navigationbar.dart';
|
||||
import 'product_item.dart';
|
||||
|
||||
class ProductSearch extends StatefulWidget {
|
||||
final Business business;
|
||||
|
||||
const ProductSearch(this.business, {Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => ProductSearchState();
|
||||
}
|
||||
|
||||
class ProductSearchState extends State<ProductSearch> {
|
||||
|
||||
int page = 1;
|
||||
int numPerPage = 10;
|
||||
int lastResultSize = 0;
|
||||
double lastBottomPosition = 0;
|
||||
String lastKeyword = '';
|
||||
|
||||
SearchBarController _controller = SearchBarController<Product>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return Scaffold(
|
||||
appBar: MiniNavigationBar(
|
||||
title: S.of(context).search_product,
|
||||
back: true,
|
||||
breadCrumbs: [
|
||||
BreadCrumb(S.of(context).search_product, null),
|
||||
],
|
||||
),
|
||||
drawer: null,
|
||||
body: SafeArea(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: NotificationListener<ScrollNotification>(
|
||||
child: SearchBar(
|
||||
searchBarController: _controller,
|
||||
minimumChars: 2,
|
||||
hintText: S.of(context).enter_keyword,
|
||||
cancellationWidget: Text(
|
||||
S.of(context).cancel,
|
||||
),
|
||||
onSearch: search,
|
||||
onItemFound: (Product searchProduct, int index) {
|
||||
return ProductItem(
|
||||
searchProduct,
|
||||
widget.business,
|
||||
horizontal: true,
|
||||
imageWidth: 80.0,
|
||||
);
|
||||
},
|
||||
onError: (error) {
|
||||
return Center(
|
||||
child: Text("$error"),
|
||||
);
|
||||
},
|
||||
emptyWidget: Center(
|
||||
child: Text(
|
||||
S.of(context).empty_result_change_keyword,
|
||||
),
|
||||
),
|
||||
),
|
||||
onNotification: (notification) {
|
||||
if (notification.metrics.atEdge) {
|
||||
print('fff: $page, $lastBottomPosition, ${notification.metrics.pixels}');
|
||||
if (page != 0 && lastResultSize >= numPerPage && notification.metrics.pixels != 0) {
|
||||
if (notification.metrics.pixels > lastBottomPosition) {
|
||||
lastBottomPosition = notification.metrics.pixels;
|
||||
page += 1;
|
||||
_controller.replayLastSearch();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
bottomNavigationBar: null,
|
||||
);
|
||||
}
|
||||
|
||||
Future<List<Product>> search(String keyword) async {
|
||||
if (lastKeyword != keyword) {
|
||||
page = 1;
|
||||
}
|
||||
lastKeyword = keyword;
|
||||
var result = await HttpUtil.httpGet('v1/search-store-product2',
|
||||
queryParameters: {
|
||||
'store_id': widget.business.id,
|
||||
'keyword': keyword,
|
||||
'page': page,
|
||||
'num_per_page': numPerPage,
|
||||
},
|
||||
returnError: true,
|
||||
);
|
||||
if (result is DioError) {
|
||||
if (result.response != null) {
|
||||
throw RuntimeError(result.response.data);
|
||||
} else {
|
||||
throw RuntimeError(result.message);
|
||||
}
|
||||
} else if (result != null && result is List) {
|
||||
lastBottomPosition = 0;
|
||||
var r = result.map((e) => Product.fromJson(e)).toList();
|
||||
lastResultSize = r.length;
|
||||
if (lastResultSize < numPerPage) {
|
||||
page = 1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
eventBus.on<OnCartInfoUpdated>().listen((event) {
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _showProductDetail(Product p) {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ProductDetailPage(
|
||||
product: p,
|
||||
business: widget.business,
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,63 +1,59 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:badges/badges.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import 'package:flutter_wisetronic/events/eventbus.dart';
|
||||
import 'package:flutter_wisetronic/events/events.dart';
|
||||
import 'package:flutter_wisetronic/generated/l10n.dart';
|
||||
import 'package:flutter_wisetronic/models/business.dart';
|
||||
import 'package:flutter_wisetronic/models/cart_info.dart';
|
||||
import 'package:flutter_wisetronic/models/cart_line_item.dart';
|
||||
import 'package:flutter_wisetronic/models/category_products.dart';
|
||||
import 'package:flutter_wisetronic/models/comment.dart';
|
||||
import 'package:flutter_wisetronic/models/product.dart';
|
||||
import 'package:flutter_wisetronic/models/product_image.dart';
|
||||
import 'package:flutter_wisetronic/pages/product_detail_page.dart';
|
||||
import 'package:flutter_wisetronic/store/store.dart';
|
||||
import 'package:flutter_wisetronic/utils/http_util.dart';
|
||||
import 'package:flutter_wisetronic/utils/shop_scroll_controller.dart';
|
||||
import 'package:flutter_wisetronic/utils/shop_scroll_coordinator.dart';
|
||||
import 'package:flutter_wisetronic/utils/utils.dart';
|
||||
import 'package:flutter_wisetronic/widgets/general/add_remove_button.dart';
|
||||
import 'package:flutter_wisetronic/widgets/general/animation_point_manager.dart';
|
||||
import 'package:flutter_wisetronic/widgets/general/carousel.dart';
|
||||
import 'package:flutter_wisetronic/widgets/general/read_more_text.dart';
|
||||
import 'package:flutter_wisetronic/widgets/general/show_price.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:flutter_wisetronic/widgets/general/sliding_up_panel.dart';
|
||||
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
||||
import 'package:smooth_star_rating/smooth_star_rating.dart';
|
||||
|
||||
import '../../constants.dart';
|
||||
import '../../events/eventbus.dart';
|
||||
import '../../events/events.dart';
|
||||
import '../../generated/l10n.dart';
|
||||
import '../../models/business.dart';
|
||||
import '../../models/cart_info.dart';
|
||||
import '../../models/cart_line_item.dart';
|
||||
import '../../models/category_products.dart';
|
||||
import '../../models/comment.dart';
|
||||
import '../../models/product.dart';
|
||||
import '../../models/product_image.dart';
|
||||
import '../../pages/product_detail_page.dart';
|
||||
import '../../pages/store_product_search.dart';
|
||||
import '../../routes.dart';
|
||||
import '../../store/actions.dart';
|
||||
import '../../store/store.dart';
|
||||
import '../../utils/http_util.dart';
|
||||
import '../../utils/shop_scroll_controller.dart';
|
||||
import '../../utils/shop_scroll_coordinator.dart';
|
||||
import '../../utils/util_web.dart'
|
||||
if (dart.library.io) '../../utils/util_io.dart';
|
||||
import '../../utils/utils.dart';
|
||||
import '../../widgets/general/add_remove_button.dart';
|
||||
import '../../widgets/general/animation_point_manager.dart';
|
||||
import '../../widgets/general/carousel.dart';
|
||||
import '../../widgets/general/product_item.dart';
|
||||
import '../../widgets/general/read_more_text.dart';
|
||||
import '../../widgets/general/sliding_up_panel.dart';
|
||||
import '../../widgets/general/style.dart';
|
||||
|
||||
import '../../utils/util_io.dart' if (dart.library.html) '../../utils/util_web.dart';
|
||||
import 'product_item.dart';
|
||||
import 'product_search.dart';
|
||||
import 'shopping_cart_bar.dart';
|
||||
|
||||
class MobileShop extends StatefulWidget {
|
||||
final int businessId;
|
||||
|
||||
const MobileShop({Key key, this.businessId}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => MobileShopState();
|
||||
}
|
||||
|
||||
MediaQueryData mediaQuery;
|
||||
double statusBarHeight;
|
||||
double screenWidth;
|
||||
double screenHeight;
|
||||
|
||||
class MobileShopState extends State<MobileShop>
|
||||
class Shop extends StatefulWidget {
|
||||
final int businessId;
|
||||
|
||||
const Shop({Key key, this.businessId}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => ShopState();
|
||||
}
|
||||
|
||||
class ShopState extends State<Shop>
|
||||
with TickerProviderStateMixin, AutomaticKeepAliveClientMixin {
|
||||
|
||||
GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||
|
||||
Business _business;
|
||||
@@ -75,7 +71,7 @@ class MobileShopState extends State<MobileShop>
|
||||
|
||||
static const num _categoryHeight = 50.0;
|
||||
static const num _categoryDescHeight = 50.0;
|
||||
static const num _productHeight = 115.0;
|
||||
static const num _productHeight = Constants.PRODUCT_ITEM_HEIGHT_H;
|
||||
|
||||
int _categoryIndex = 0;
|
||||
bool _categoryIndexChange = false;
|
||||
@@ -103,7 +99,7 @@ class MobileShopState extends State<MobileShop>
|
||||
int _commentPageCount = 1;
|
||||
bool _commentLoadingFinish = false;
|
||||
RefreshController _commentRefreshController =
|
||||
RefreshController(initialRefresh: true);
|
||||
RefreshController(initialRefresh: true);
|
||||
|
||||
PanelController panelController = PanelController();
|
||||
SlidingUpPanel _slidUpShoppingCart;
|
||||
@@ -256,9 +252,33 @@ class MobileShopState extends State<MobileShop>
|
||||
padding: EdgeInsets.only(
|
||||
left: 10.0,
|
||||
top: 10.0,
|
||||
right: 10.0,
|
||||
bottom: 10.0,
|
||||
),
|
||||
width: 150.0,
|
||||
margin: EdgeInsets.symmetric(horizontal: 5.0, vertical: 5.0),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(5.0)),
|
||||
color: Colors.white,
|
||||
border: Border(
|
||||
top: BorderSide(
|
||||
width: 1.0,
|
||||
color: Colors.black12,
|
||||
),
|
||||
bottom: BorderSide(
|
||||
width: 1.0,
|
||||
color: Colors.black12,
|
||||
),
|
||||
left: BorderSide(
|
||||
width: 1.0,
|
||||
color: Colors.black12,
|
||||
),
|
||||
right: BorderSide(
|
||||
width: 1.0,
|
||||
color: Colors.black12,
|
||||
),
|
||||
),
|
||||
),
|
||||
width: 160.0,
|
||||
height: 220.0,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
@@ -267,6 +287,7 @@ class MobileShopState extends State<MobileShop>
|
||||
child: Container(
|
||||
child: Util.showImage(
|
||||
_business.promoProducts[i].imagePath,
|
||||
width: 110.0,
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
@@ -308,7 +329,7 @@ class MobileShopState extends State<MobileShop>
|
||||
pinned: false,
|
||||
floating: true,
|
||||
delegate: _SliverAppBarDelegate2(
|
||||
minHeight: 250.0,
|
||||
minHeight: 256.0,
|
||||
maxHeight: 260.0,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
@@ -359,7 +380,7 @@ class MobileShopState extends State<MobileShop>
|
||||
icon: Icon(Icons.arrow_back_ios),
|
||||
onPressed: () {
|
||||
if (_animationFinish) {
|
||||
Routes.router.pop(context);
|
||||
Navigator.of(context).maybePop();
|
||||
}
|
||||
}),
|
||||
titleSpacing: 0.0,
|
||||
@@ -371,8 +392,8 @@ class MobileShopState extends State<MobileShop>
|
||||
onTap: () {
|
||||
Navigator.push(context,
|
||||
MaterialPageRoute(builder: (BuildContext context) {
|
||||
return StoreProductSearch(_business);
|
||||
}));
|
||||
return ProductSearch(_business);
|
||||
}));
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -540,7 +561,7 @@ class MobileShopState extends State<MobileShop>
|
||||
cancelButton: CupertinoActionSheetAction(
|
||||
child: Text(S.of(context).close),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).maybePop();
|
||||
},
|
||||
),
|
||||
);
|
||||
@@ -786,8 +807,8 @@ class MobileShopState extends State<MobileShop>
|
||||
));
|
||||
var duration = Duration(
|
||||
seconds: (_business.distanceInfo.duration != null
|
||||
? _business.distanceInfo.duration.value
|
||||
: 30) +
|
||||
? _business.distanceInfo.duration.value
|
||||
: 30) +
|
||||
_business.shippingTime * 60);
|
||||
var hours = duration.inHours.remainder(60);
|
||||
var minutes = duration.inMinutes.remainder(60);
|
||||
@@ -922,28 +943,28 @@ class MobileShopState extends State<MobileShop>
|
||||
children: <Widget>[
|
||||
_business.bulletin.isNotEmpty ? Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
padding:
|
||||
EdgeInsets.only(left: 10.0, right: 5.0, bottom: 10.0),
|
||||
EdgeInsets.only(left: 10.0, right: 5.0, bottom: 10.0),
|
||||
child: Icon(
|
||||
Icons.announcement,
|
||||
size: 14.0,
|
||||
color: Colors.white,
|
||||
)),
|
||||
Container(
|
||||
width: mediaQuery.size.width - 30.0,
|
||||
padding: EdgeInsets.only(right: 10.0, bottom: 10.0),
|
||||
child: new Text(
|
||||
_business.bulletin.isEmpty ? '' : _business.bulletin,
|
||||
softWrap: true,
|
||||
style: new TextStyle(
|
||||
fontSize: 12.0, color: const Color(0xFFDDDDDD)),
|
||||
Container(
|
||||
width: mediaQuery.size.width - 30.0,
|
||||
padding: EdgeInsets.only(right: 10.0, bottom: 10.0),
|
||||
child: new Text(
|
||||
_business.bulletin.isEmpty ? '' : _business.bulletin,
|
||||
softWrap: true,
|
||||
style: new TextStyle(
|
||||
fontSize: 12.0, color: const Color(0xFFDDDDDD)),
|
||||
// overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
) : SizedBox.shrink(),
|
||||
),
|
||||
],
|
||||
) : SizedBox.shrink(),
|
||||
_business.description.isNotEmpty ? Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -1092,13 +1113,13 @@ class MobileShopState extends State<MobileShop>
|
||||
}
|
||||
|
||||
Widget _buildMainContent() {
|
||||
return new Row(
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: <Widget>[
|
||||
_buildCategories(),
|
||||
Expanded(
|
||||
child: _buildProducts(),
|
||||
)
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -1116,7 +1137,7 @@ class MobileShopState extends State<MobileShop>
|
||||
CategoryProducts cp = _categoryProducts[i];
|
||||
int qtyInCategory = 0;
|
||||
CartInfo cartInfo =
|
||||
Utils.getCartInfoByBusiness(store.state.cartInfos, _business);
|
||||
Utils.getCartInfoByBusiness(store.state.cartInfos, _business);
|
||||
if (cartInfo != null &&
|
||||
cartInfo.businessInfo.id == _business.id &&
|
||||
cartInfo.productList != null) {
|
||||
@@ -1141,14 +1162,14 @@ class MobileShopState extends State<MobileShop>
|
||||
style: TextStyle(
|
||||
fontSize: 13.0,
|
||||
fontWeight: (cp.id == Constants.FEATURED_PRODUCT_ID ||
|
||||
cp.id == Constants.HOT_SALE_ID)
|
||||
cp.id == Constants.HOT_SALE_ID)
|
||||
? FontWeight.bold
|
||||
: FontWeight.normal,
|
||||
color: (cp.id == Constants.HOT_SALE_ID)
|
||||
? Colors.redAccent
|
||||
: ((cp.id == Constants.FEATURED_PRODUCT_ID)
|
||||
? Colors.lightGreen
|
||||
: Colors.black87)),
|
||||
? Colors.lightGreen
|
||||
: Colors.black87)),
|
||||
// overflow: kIsWeb ? null : TextOverflow.ellipsis,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true,
|
||||
@@ -1178,10 +1199,10 @@ class MobileShopState extends State<MobileShop>
|
||||
height: 70.0,
|
||||
padding: new EdgeInsets.symmetric(horizontal: 10.0),
|
||||
decoration: new BoxDecoration(
|
||||
color: _categoryIndex == i ? Style.backgroundColor : null,
|
||||
color: _categoryIndex == i ? Colors.white : null,
|
||||
border: new Border(
|
||||
bottom:
|
||||
new BorderSide(color: new Color(0xFFEBEBEB)))),
|
||||
new BorderSide(color: new Color(0xFFEBEBEB)))),
|
||||
child: categoryRow,
|
||||
),
|
||||
onTap: () => _selectCategory(i),
|
||||
@@ -1208,10 +1229,10 @@ class MobileShopState extends State<MobileShop>
|
||||
_categoryIndexChange = true;
|
||||
_listScrollController1
|
||||
.animateTo(height,
|
||||
duration: new Duration(
|
||||
microseconds: 200,
|
||||
),
|
||||
curve: Curves.linear)
|
||||
duration: new Duration(
|
||||
microseconds: 200,
|
||||
),
|
||||
curve: Curves.linear)
|
||||
.then((value) {
|
||||
_categoryIndexChange = false;
|
||||
});
|
||||
@@ -1316,7 +1337,7 @@ class MobileShopState extends State<MobileShop>
|
||||
controller: _listScrollController1,
|
||||
// itemCount: displayProductByCategoryClick ? 1 : (_categoryProducts == null ? 0 : _categoryProducts.length),
|
||||
itemCount:
|
||||
_categoryProducts == null ? 0 : numCategoriesHasProducts(),
|
||||
_categoryProducts == null ? 0 : numCategoriesHasProducts(),
|
||||
itemBuilder: (BuildContext context, int i) {
|
||||
CategoryProducts cp;
|
||||
cp = _categoryProducts[i];
|
||||
@@ -1357,42 +1378,42 @@ class MobileShopState extends State<MobileShop>
|
||||
children: <Widget>[
|
||||
new Expanded(
|
||||
child: new Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
textBaseline: TextBaseline.alphabetic,
|
||||
children: <Widget>[
|
||||
new Padding(
|
||||
padding: new EdgeInsets.only(right: 5.0),
|
||||
child: new Text(
|
||||
cp.name,
|
||||
style: new TextStyle(
|
||||
fontSize: 16.0,
|
||||
fontWeight:
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
textBaseline: TextBaseline.alphabetic,
|
||||
children: <Widget>[
|
||||
new Padding(
|
||||
padding: new EdgeInsets.only(right: 5.0),
|
||||
child: new Text(
|
||||
cp.name,
|
||||
style: new TextStyle(
|
||||
fontSize: 16.0,
|
||||
fontWeight:
|
||||
(cp.id == Constants.FEATURED_PRODUCT_ID ||
|
||||
cp.id == Constants.HOT_SALE_ID)
|
||||
cp.id == Constants.HOT_SALE_ID)
|
||||
? FontWeight.bold
|
||||
: FontWeight.normal,
|
||||
color: (cp.id == Constants.HOT_SALE_ID)
|
||||
? Colors.redAccent
|
||||
: ((cp.id ==
|
||||
Constants.FEATURED_PRODUCT_ID)
|
||||
color: (cp.id == Constants.HOT_SALE_ID)
|
||||
? Colors.redAccent
|
||||
: ((cp.id ==
|
||||
Constants.FEATURED_PRODUCT_ID)
|
||||
? Colors.lightGreen
|
||||
: Colors.black87)),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
new Visibility(
|
||||
visible: cp.description.isNotEmpty,
|
||||
child: new Text(
|
||||
cp.description,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: new TextStyle(
|
||||
fontSize: 10.0,
|
||||
color: new Color(0xFF999999)),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
replacement: const SizedBox.shrink()),
|
||||
],
|
||||
))
|
||||
new Visibility(
|
||||
visible: cp.description.isNotEmpty,
|
||||
child: new Text(
|
||||
cp.description,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: new TextStyle(
|
||||
fontSize: 10.0,
|
||||
color: new Color(0xFF999999)),
|
||||
),
|
||||
replacement: const SizedBox.shrink()),
|
||||
],
|
||||
))
|
||||
],
|
||||
)));
|
||||
for (var p in cp.products) {
|
||||
@@ -1400,9 +1421,13 @@ class MobileShopState extends State<MobileShop>
|
||||
children: <Widget>[],
|
||||
);
|
||||
|
||||
pStack.children.add(new ProductItem(
|
||||
product: p,
|
||||
business: _business,
|
||||
pStack.children.add(Container(
|
||||
// width: MediaQuery.of(context).size.width - 100.0,
|
||||
child: ProductItem(
|
||||
p, _business,
|
||||
horizontal: true,
|
||||
imageWidth: 80.0,
|
||||
),
|
||||
));
|
||||
|
||||
col.children.add(pStack);
|
||||
@@ -1494,129 +1519,6 @@ class MobileShopState extends State<MobileShop>
|
||||
}
|
||||
});
|
||||
|
||||
// onProductWillAddToCartSubscription =
|
||||
// eventBus.on<OnProductWillAddToCart>().listen((event) {
|
||||
// if (mounted) {
|
||||
// itemAddToCart(event.buttonKey);
|
||||
//
|
||||
// CartInfo cartInfo =
|
||||
// Utils.getCartInfoByBusiness(store.state.cartInfos, event.business);
|
||||
//
|
||||
// if (cartInfo == null || cartInfo.productList.length == 0) {
|
||||
// cartInfo = CartInfo();
|
||||
// cartInfo.id = 0;
|
||||
// cartInfo.amountPaid = 0.0;
|
||||
// cartInfo.businessInfo = event.business;
|
||||
// cartInfo.extraFeeList = [];
|
||||
// cartInfo.discountList = [];
|
||||
// CartLineItem lineItem = _newCartLineItem(
|
||||
// id: 0,
|
||||
// price: event.price,
|
||||
// product: event.product,
|
||||
// name: event.product.name,
|
||||
// description: event.description,
|
||||
// quantity: 1.0);
|
||||
// cartInfo.productList = [lineItem];
|
||||
// store.dispatch(new UpdateCartInfo(Utils.addCartInfoToCartInfoList(
|
||||
// store.state.cartInfos, cartInfo)));
|
||||
// eventBus.fire(new OnCartInfoUpdated());
|
||||
// } else {
|
||||
// if (event.product.productAttributes.length > 0) {
|
||||
// CartLineItem lineItem = _newCartLineItem(
|
||||
// id: 0,
|
||||
// price: event.price,
|
||||
// product: event.product,
|
||||
// name: event.product.name,
|
||||
// description: event.description,
|
||||
// quantity: 1.0);
|
||||
// cartInfo.productList.add(lineItem);
|
||||
// store.dispatch(new UpdateCartInfo(Utils.addCartInfoToCartInfoList(
|
||||
// store.state.cartInfos, cartInfo)));
|
||||
// eventBus.fire(new OnCartInfoUpdated());
|
||||
// } else {
|
||||
// int found = -1;
|
||||
// for (var i = 0; i < cartInfo.productList.length; i++) {
|
||||
// if (event.product.id == cartInfo.productList[i].product.id) {
|
||||
// found = i;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (found == -1) {
|
||||
// CartLineItem lineItem = _newCartLineItem(
|
||||
// id: 0,
|
||||
// price: event.price,
|
||||
// product: event.product,
|
||||
// name: event.product.name,
|
||||
// description: event.description,
|
||||
// quantity: 1.0);
|
||||
// cartInfo.productList.add(lineItem);
|
||||
// store.dispatch(new UpdateCartInfo(Utils.addCartInfoToCartInfoList(
|
||||
// store.state.cartInfos, cartInfo)));
|
||||
// eventBus.fire(new OnCartInfoUpdated());
|
||||
// } else {
|
||||
// if (cartInfo.productList[found].quantity + 1.0 >
|
||||
// event.product.leftNum) {
|
||||
// Fluttertoast.showToast(
|
||||
// msg: S.of(context).product_insufficient,
|
||||
// toastLength: Toast.LENGTH_SHORT,
|
||||
// gravity: ToastGravity.CENTER,
|
||||
// backgroundColor: Colors.red,
|
||||
// textColor: Colors.white);
|
||||
// } else {
|
||||
// cartInfo.productList[found].quantity += 1;
|
||||
// store.dispatch(new UpdateCartInfo(
|
||||
// Utils.addCartInfoToCartInfoList(
|
||||
// store.state.cartInfos, cartInfo)));
|
||||
// eventBus.fire(new OnCartInfoUpdated());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// onProductWillRemoveFromCartSubscription =
|
||||
// eventBus.on<OnProductWillRemoveFromCart>().listen((event) {
|
||||
// if (mounted) {
|
||||
// CartInfo cartInfo =
|
||||
// Utils.getCartInfoByBusiness(store.state.cartInfos, event.business);
|
||||
// if (cartInfo != null) {
|
||||
// if (cartInfo.productList.length > 0) {
|
||||
// if (event.productListIndex != -1) {
|
||||
// if (cartInfo.productList[event.productListIndex].quantity <= 1) {
|
||||
// cartInfo.productList.removeAt(event.productListIndex);
|
||||
// } else {
|
||||
// cartInfo.productList[event.productListIndex].quantity -= 1;
|
||||
// }
|
||||
// } else {
|
||||
// int productListIndex = -1;
|
||||
// for (var i = 0; i < cartInfo.productList.length; i++) {
|
||||
// if (cartInfo.productList[i].product.id == event.product.id) {
|
||||
// productListIndex = i;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (productListIndex != -1) {
|
||||
// if (cartInfo.productList[productListIndex].quantity <= 1) {
|
||||
// cartInfo.productList.removeAt(productListIndex);
|
||||
// } else {
|
||||
// cartInfo.productList[productListIndex].quantity -= 1;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (cartInfo.productList.length <= 0) {
|
||||
// store.dispatch(UpdateCartInfo(Utils.removeCartInfoFromCartInfoList(
|
||||
// store.state.cartInfos, cartInfo)));
|
||||
// } else {
|
||||
// store.dispatch(UpdateCartInfo(Utils.addCartInfoToCartInfoList(
|
||||
// store.state.cartInfos, cartInfo)));
|
||||
// }
|
||||
// eventBus.fire(new OnCartInfoUpdated());
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
|
||||
loadProducts();
|
||||
}
|
||||
|
||||
@@ -1630,67 +1532,71 @@ class MobileShopState extends State<MobileShop>
|
||||
}
|
||||
_productCurrentPage = 1;
|
||||
Utils.loadProducts(
|
||||
widget.businessId, categoryId, _productCurrentPage, false,
|
||||
(value) {
|
||||
if (_isLoading) {
|
||||
_isLoading = false;
|
||||
Navigator.of(context).pop();
|
||||
widget.businessId, categoryId, _productCurrentPage, false,
|
||||
(value) {
|
||||
if (_isLoading) {
|
||||
_isLoading = false;
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
|
||||
displayProductByCategoryClick =
|
||||
value['display_product_by_category_click'];
|
||||
displayProductByCategoryClickIndicator = '';
|
||||
_business = Business.fromJson(value['business']);
|
||||
|
||||
_categoryProducts = (value['category_products'] as List)
|
||||
.map((i) => CategoryProducts.fromJson(i))
|
||||
.toList();
|
||||
// _featuredProducts = (value['featured_products'] as List)
|
||||
// .map((i) => Product.fromJson(i))
|
||||
// .toList();
|
||||
_featuredProducts = [];
|
||||
// _hotSaleProducts = (value['hot_sale_products'] as List)
|
||||
// .map((i) => Product.fromJson(i))
|
||||
// .toList();
|
||||
_hotSaleProducts = [];
|
||||
_prompts = value['prompt'] as List;
|
||||
|
||||
if (_hotSaleProducts.length > 0) {
|
||||
CategoryProducts hs = CategoryProducts(
|
||||
Constants.HOT_SALE_ID,
|
||||
widget.businessId,
|
||||
S.of(context).hot_sale,
|
||||
'',
|
||||
'',
|
||||
_hotSaleProducts);
|
||||
_categoryProducts.insert(0, hs);
|
||||
}
|
||||
|
||||
if (_featuredProducts.length > 0) {
|
||||
CategoryProducts fe = CategoryProducts(
|
||||
Constants.FEATURED_PRODUCT_ID,
|
||||
widget.businessId,
|
||||
S.of(context).featured_product,
|
||||
'',
|
||||
'',
|
||||
_featuredProducts);
|
||||
_categoryProducts.insert(0, fe);
|
||||
}
|
||||
|
||||
checkActionAndClose(context);
|
||||
|
||||
if (displayProductByCategoryClick) {
|
||||
_resetProductListScroll();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
(error) {
|
||||
print('error: $error');
|
||||
if (_isLoading) {
|
||||
_isLoading = false;
|
||||
Navigator.of(context).maybePop();
|
||||
}
|
||||
Utils.showMessageDialog(context, error);
|
||||
}
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
displayProductByCategoryClick =
|
||||
value['display_product_by_category_click'];
|
||||
displayProductByCategoryClickIndicator = '';
|
||||
_business = Business.fromJson(value['business']);
|
||||
_categoryProducts = (value['category_products'] as List)
|
||||
.map((i) => CategoryProducts.fromJson(i))
|
||||
.toList();
|
||||
_featuredProducts = (value['featured_products'] as List)
|
||||
.map((i) => Product.fromJson(i))
|
||||
.toList();
|
||||
_hotSaleProducts = (value['hot_sale_products'] as List)
|
||||
.map((i) => Product.fromJson(i))
|
||||
.toList();
|
||||
_prompts = value['prompt'] as List;
|
||||
|
||||
if (_hotSaleProducts.length > 0) {
|
||||
CategoryProducts hs = CategoryProducts(
|
||||
Constants.HOT_SALE_ID,
|
||||
widget.businessId,
|
||||
S.of(context).hot_sale,
|
||||
'',
|
||||
'',
|
||||
_hotSaleProducts);
|
||||
_categoryProducts.insert(0, hs);
|
||||
}
|
||||
|
||||
if (_featuredProducts.length > 0) {
|
||||
CategoryProducts fe = CategoryProducts(
|
||||
Constants.FEATURED_PRODUCT_ID,
|
||||
widget.businessId,
|
||||
S.of(context).featured_product,
|
||||
'',
|
||||
'',
|
||||
_featuredProducts);
|
||||
_categoryProducts.insert(0, fe);
|
||||
}
|
||||
|
||||
checkActionAndClose(context);
|
||||
|
||||
if (displayProductByCategoryClick) {
|
||||
_resetProductListScroll();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
(error) {
|
||||
print('error: $error');
|
||||
if (_isLoading) {
|
||||
_isLoading = false;
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
Utils.showMessageDialog(context, error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1700,59 +1606,59 @@ class MobileShopState extends State<MobileShop>
|
||||
}
|
||||
_productCurrentPage += 1;
|
||||
Utils.loadProducts(widget.businessId, categoryId, _productCurrentPage, true,
|
||||
(value) {
|
||||
if (_isLoading) {
|
||||
_isLoading = false;
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
List<CategoryProducts> moreCategoryProducts =
|
||||
(value as List).map((i) => CategoryProducts.fromJson(i)).toList();
|
||||
if (moreCategoryProducts.isEmpty) {
|
||||
_productCurrentPage = 0;
|
||||
displayProductByCategoryClickIndicator =
|
||||
S.of(context).end_of_the_list;
|
||||
} else {
|
||||
if (moreCategoryProducts[0].products.length < Constants.ORDERS_PER_PAGE) {
|
||||
(value) {
|
||||
if (_isLoading) {
|
||||
_isLoading = false;
|
||||
Navigator.of(context).maybePop();
|
||||
}
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
List<CategoryProducts> moreCategoryProducts =
|
||||
(value as List).map((i) => CategoryProducts.fromJson(i)).toList();
|
||||
if (moreCategoryProducts.isEmpty) {
|
||||
_productCurrentPage = 0;
|
||||
displayProductByCategoryClickIndicator =
|
||||
S.of(context).end_of_the_list;
|
||||
} else {
|
||||
displayProductByCategoryClickIndicator =
|
||||
S.of(context).pull_up_to_load_more;
|
||||
if (moreCategoryProducts[0].products.length < Constants.ORDERS_PER_PAGE) {
|
||||
_productCurrentPage = 0;
|
||||
displayProductByCategoryClickIndicator =
|
||||
S.of(context).end_of_the_list;
|
||||
} else {
|
||||
displayProductByCategoryClickIndicator =
|
||||
S.of(context).pull_up_to_load_more;
|
||||
}
|
||||
CategoryProducts currentCp =
|
||||
getCategoryProductByCategoryId(categoryId);
|
||||
if (currentCp != null) {
|
||||
currentCp.products.addAll(moreCategoryProducts[0].products);
|
||||
} else {
|
||||
_productCurrentPage = 0;
|
||||
displayProductByCategoryClickIndicator =
|
||||
S.of(context).end_of_the_list;
|
||||
}
|
||||
}
|
||||
CategoryProducts currentCp =
|
||||
getCategoryProductByCategoryId(categoryId);
|
||||
if (currentCp != null) {
|
||||
currentCp.products.addAll(moreCategoryProducts[0].products);
|
||||
} else {
|
||||
_productCurrentPage = 0;
|
||||
displayProductByCategoryClickIndicator =
|
||||
S.of(context).end_of_the_list;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
(error) {
|
||||
print('error: $error');
|
||||
if (_isLoading) {
|
||||
_isLoading = false;
|
||||
Navigator.of(context).maybePop();
|
||||
}
|
||||
Utils.showMessageDialog(context, error);
|
||||
}
|
||||
},
|
||||
(error) {
|
||||
print('error: $error');
|
||||
if (_isLoading) {
|
||||
_isLoading = false;
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
Utils.showMessageDialog(context, error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
CartLineItem _newCartLineItem(
|
||||
{int id,
|
||||
double price,
|
||||
Product product,
|
||||
String name,
|
||||
String description,
|
||||
double quantity}) {
|
||||
double price,
|
||||
Product product,
|
||||
String name,
|
||||
String description,
|
||||
double quantity}) {
|
||||
CartLineItem lineItem = CartLineItem();
|
||||
lineItem.unitPrice = price;
|
||||
lineItem.product = product;
|
||||
@@ -1787,9 +1693,9 @@ class MobileShopState extends State<MobileShop>
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ProductDetailPage(
|
||||
product: p,
|
||||
business: _business,
|
||||
)),
|
||||
product: p,
|
||||
business: _business,
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1925,10 +1831,10 @@ class MobileShopState extends State<MobileShop>
|
||||
S.of(context).store_closed,
|
||||
),
|
||||
actions: <Widget>[
|
||||
FlatButton(
|
||||
TextButton(
|
||||
child: Text(S.of(context).ok),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).maybePop();
|
||||
showPrompt(0);
|
||||
},
|
||||
)
|
||||
@@ -1981,10 +1887,10 @@ class MobileShopState extends State<MobileShop>
|
||||
),
|
||||
),
|
||||
actions: <Widget>[
|
||||
FlatButton(
|
||||
TextButton(
|
||||
child: Text(S.of(context).ok),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).maybePop();
|
||||
showPrompt(0);
|
||||
},
|
||||
)
|
||||
@@ -2007,10 +1913,10 @@ class MobileShopState extends State<MobileShop>
|
||||
title: Text(_prompt['title']),
|
||||
content: Text(_prompt['message']),
|
||||
actions: [
|
||||
FlatButton(
|
||||
TextButton(
|
||||
child: Text(S.of(context).ok),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).maybePop();
|
||||
showPrompt(idx + 1);
|
||||
},
|
||||
),
|
||||
@@ -2053,4 +1959,4 @@ class _SliverAppBarDelegate2 extends SliverPersistentHeaderDelegate {
|
||||
minHeight != oldDelegate.minHeight ||
|
||||
child != oldDelegate.child;
|
||||
}
|
||||
}
|
||||
}
|
||||
12
pubspec.lock
12
pubspec.lock
@@ -21,7 +21,7 @@ packages:
|
||||
name: async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.8.1"
|
||||
version: "2.8.2"
|
||||
awesome_card:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -84,7 +84,7 @@ packages:
|
||||
name: characters
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.2.0"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -601,7 +601,7 @@ packages:
|
||||
name: matcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.10"
|
||||
version: "0.12.11"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1000,7 +1000,7 @@ packages:
|
||||
name: test_api
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.2"
|
||||
version: "0.4.3"
|
||||
timezone:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1119,7 +1119,7 @@ packages:
|
||||
name: vector_math
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.1"
|
||||
video_player:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1219,5 +1219,5 @@ packages:
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
sdks:
|
||||
dart: ">=2.13.0 <3.0.0"
|
||||
dart: ">=2.14.0 <3.0.0"
|
||||
flutter: ">=2.2.0"
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<!-- iOS meta tags & icons -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<meta name="apple-mobile-web-app-title" content="flutter_wisetronic">
|
||||
<meta name="apple-mobile-web-app-title" content="Wisetronic">
|
||||
<link rel="apple-touch-icon" href="icons/Icon-192.png">
|
||||
|
||||
<!-- Favicon -->
|
||||
|
||||
Reference in New Issue
Block a user