Merge remote-tracking branch 'origin/dev_reason_v1.0' into dev_reason_v1.0
# Conflicts: # android/app/build.gradle # pubspec.lock
Showing
25 changed files
with
892 additions
and
86 deletions
... | @@ -32,8 +32,8 @@ if (keystorePropertiesFile.exists()) { | ... | @@ -32,8 +32,8 @@ if (keystorePropertiesFile.exists()) { |
32 | } | 32 | } |
33 | 33 | ||
34 | android { | 34 | android { |
35 | - compileSdkVersion 33 | 35 | + compileSdkVersion 32 |
36 | - buildToolsVersion "33" | 36 | + buildToolsVersion "32" |
37 | 37 | ||
38 | compileOptions { | 38 | compileOptions { |
39 | sourceCompatibility JavaVersion.VERSION_1_8 | 39 | sourceCompatibility JavaVersion.VERSION_1_8 | ... | ... |
... | @@ -21,6 +21,6 @@ | ... | @@ -21,6 +21,6 @@ |
21 | <key>CFBundleVersion</key> | 21 | <key>CFBundleVersion</key> |
22 | <string>1.0</string> | 22 | <string>1.0</string> |
23 | <key>MinimumOSVersion</key> | 23 | <key>MinimumOSVersion</key> |
24 | - <string>9.0</string> | 24 | + <string>11.0</string> |
25 | </dict> | 25 | </dict> |
26 | </plist> | 26 | </plist> | ... | ... |
1 | # Uncomment this line to define a global platform for your project | 1 | # Uncomment this line to define a global platform for your project |
2 | -# platform :ios, '9.0' | 2 | +platform :ios, '12.0' |
3 | -platform :ios, '10.0' | ||
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. | 3 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. |
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' | 4 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' |
6 | 5 | ... | ... |
This diff is collapsed. Click to expand it.
... | @@ -363,7 +363,7 @@ | ... | @@ -363,7 +363,7 @@ |
363 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | 363 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; |
364 | GCC_WARN_UNUSED_FUNCTION = YES; | 364 | GCC_WARN_UNUSED_FUNCTION = YES; |
365 | GCC_WARN_UNUSED_VARIABLE = YES; | 365 | GCC_WARN_UNUSED_VARIABLE = YES; |
366 | - IPHONEOS_DEPLOYMENT_TARGET = 9.0; | 366 | + IPHONEOS_DEPLOYMENT_TARGET = 11.0; |
367 | MTL_ENABLE_DEBUG_INFO = NO; | 367 | MTL_ENABLE_DEBUG_INFO = NO; |
368 | SDKROOT = iphoneos; | 368 | SDKROOT = iphoneos; |
369 | SUPPORTED_PLATFORMS = iphoneos; | 369 | SUPPORTED_PLATFORMS = iphoneos; |
... | @@ -380,14 +380,14 @@ | ... | @@ -380,14 +380,14 @@ |
380 | CLANG_ENABLE_MODULES = YES; | 380 | CLANG_ENABLE_MODULES = YES; |
381 | CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; | 381 | CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; |
382 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; | 382 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; |
383 | - DEVELOPMENT_TEAM = FLS6Y2LS7Z; | 383 | + DEVELOPMENT_TEAM = 5PX6JTCZ6G; |
384 | ENABLE_BITCODE = NO; | 384 | ENABLE_BITCODE = NO; |
385 | INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; | 385 | INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; |
386 | LD_RUNPATH_SEARCH_PATHS = ( | 386 | LD_RUNPATH_SEARCH_PATHS = ( |
387 | "$(inherited)", | 387 | "$(inherited)", |
388 | "@executable_path/Frameworks", | 388 | "@executable_path/Frameworks", |
389 | ); | 389 | ); |
390 | - PRODUCT_BUNDLE_IDENTIFIER = pub.yiyan.parlando.Parlando; | 390 | + PRODUCT_BUNDLE_IDENTIFIER = ink.parlando.parlando; |
391 | PRODUCT_NAME = "$(TARGET_NAME)"; | 391 | PRODUCT_NAME = "$(TARGET_NAME)"; |
392 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; | 392 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; |
393 | SWIFT_VERSION = 5.0; | 393 | SWIFT_VERSION = 5.0; |
... | @@ -442,7 +442,7 @@ | ... | @@ -442,7 +442,7 @@ |
442 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | 442 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; |
443 | GCC_WARN_UNUSED_FUNCTION = YES; | 443 | GCC_WARN_UNUSED_FUNCTION = YES; |
444 | GCC_WARN_UNUSED_VARIABLE = YES; | 444 | GCC_WARN_UNUSED_VARIABLE = YES; |
445 | - IPHONEOS_DEPLOYMENT_TARGET = 9.0; | 445 | + IPHONEOS_DEPLOYMENT_TARGET = 11.0; |
446 | MTL_ENABLE_DEBUG_INFO = YES; | 446 | MTL_ENABLE_DEBUG_INFO = YES; |
447 | ONLY_ACTIVE_ARCH = YES; | 447 | ONLY_ACTIVE_ARCH = YES; |
448 | SDKROOT = iphoneos; | 448 | SDKROOT = iphoneos; |
... | @@ -491,7 +491,7 @@ | ... | @@ -491,7 +491,7 @@ |
491 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | 491 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; |
492 | GCC_WARN_UNUSED_FUNCTION = YES; | 492 | GCC_WARN_UNUSED_FUNCTION = YES; |
493 | GCC_WARN_UNUSED_VARIABLE = YES; | 493 | GCC_WARN_UNUSED_VARIABLE = YES; |
494 | - IPHONEOS_DEPLOYMENT_TARGET = 9.0; | 494 | + IPHONEOS_DEPLOYMENT_TARGET = 11.0; |
495 | MTL_ENABLE_DEBUG_INFO = NO; | 495 | MTL_ENABLE_DEBUG_INFO = NO; |
496 | SDKROOT = iphoneos; | 496 | SDKROOT = iphoneos; |
497 | SUPPORTED_PLATFORMS = iphoneos; | 497 | SUPPORTED_PLATFORMS = iphoneos; |
... | @@ -509,14 +509,14 @@ | ... | @@ -509,14 +509,14 @@ |
509 | CLANG_ENABLE_MODULES = YES; | 509 | CLANG_ENABLE_MODULES = YES; |
510 | CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; | 510 | CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; |
511 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; | 511 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; |
512 | - DEVELOPMENT_TEAM = FLS6Y2LS7Z; | 512 | + DEVELOPMENT_TEAM = 5PX6JTCZ6G; |
513 | ENABLE_BITCODE = NO; | 513 | ENABLE_BITCODE = NO; |
514 | INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; | 514 | INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; |
515 | LD_RUNPATH_SEARCH_PATHS = ( | 515 | LD_RUNPATH_SEARCH_PATHS = ( |
516 | "$(inherited)", | 516 | "$(inherited)", |
517 | "@executable_path/Frameworks", | 517 | "@executable_path/Frameworks", |
518 | ); | 518 | ); |
519 | - PRODUCT_BUNDLE_IDENTIFIER = pub.yiyan.parlando.Parlando; | 519 | + PRODUCT_BUNDLE_IDENTIFIER = ink.parlando.parlando; |
520 | PRODUCT_NAME = "$(TARGET_NAME)"; | 520 | PRODUCT_NAME = "$(TARGET_NAME)"; |
521 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; | 521 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; |
522 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; | 522 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; |
... | @@ -533,14 +533,14 @@ | ... | @@ -533,14 +533,14 @@ |
533 | CLANG_ENABLE_MODULES = YES; | 533 | CLANG_ENABLE_MODULES = YES; |
534 | CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; | 534 | CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; |
535 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; | 535 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; |
536 | - DEVELOPMENT_TEAM = FLS6Y2LS7Z; | 536 | + DEVELOPMENT_TEAM = 5PX6JTCZ6G; |
537 | ENABLE_BITCODE = NO; | 537 | ENABLE_BITCODE = NO; |
538 | INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; | 538 | INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; |
539 | LD_RUNPATH_SEARCH_PATHS = ( | 539 | LD_RUNPATH_SEARCH_PATHS = ( |
540 | "$(inherited)", | 540 | "$(inherited)", |
541 | "@executable_path/Frameworks", | 541 | "@executable_path/Frameworks", |
542 | ); | 542 | ); |
543 | - PRODUCT_BUNDLE_IDENTIFIER = pub.yiyan.parlando.Parlando; | 543 | + PRODUCT_BUNDLE_IDENTIFIER = ink.parlando.parlando; |
544 | PRODUCT_NAME = "$(TARGET_NAME)"; | 544 | PRODUCT_NAME = "$(TARGET_NAME)"; |
545 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; | 545 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; |
546 | SWIFT_VERSION = 5.0; | 546 | SWIFT_VERSION = 5.0; | ... | ... |
... | @@ -2,12 +2,6 @@ | ... | @@ -2,12 +2,6 @@ |
2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
3 | <plist version="1.0"> | 3 | <plist version="1.0"> |
4 | <dict> | 4 | <dict> |
5 | - <key>NSLocalNetworkUsageDescription</key> | ||
6 | - <string>Allow flutter app</string> | ||
7 | - <key>NSBonjourServices</key> | ||
8 | - <array> | ||
9 | - <string>_dartobservatory._tcp</string> | ||
10 | - </array> | ||
11 | <key>CFBundleDevelopmentRegion</key> | 5 | <key>CFBundleDevelopmentRegion</key> |
12 | <string>$(DEVELOPMENT_LANGUAGE)</string> | 6 | <string>$(DEVELOPMENT_LANGUAGE)</string> |
13 | <key>CFBundleDisplayName</key> | 7 | <key>CFBundleDisplayName</key> |
... | @@ -35,6 +29,12 @@ | ... | @@ -35,6 +29,12 @@ |
35 | <key>NSAllowsArbitraryLoads</key> | 29 | <key>NSAllowsArbitraryLoads</key> |
36 | <true/> | 30 | <true/> |
37 | </dict> | 31 | </dict> |
32 | + <key>NSBonjourServices</key> | ||
33 | + <array> | ||
34 | + <string>_dartobservatory._tcp</string> | ||
35 | + </array> | ||
36 | + <key>NSLocalNetworkUsageDescription</key> | ||
37 | + <string>Allow flutter app</string> | ||
38 | <key>NSMicrophoneUsageDescription</key> | 38 | <key>NSMicrophoneUsageDescription</key> |
39 | <string>打开话筒</string> | 39 | <string>打开话筒</string> |
40 | <key>UILaunchStoryboardName</key> | 40 | <key>UILaunchStoryboardName</key> | ... | ... |
ios/Runner/Info-Profile.plist
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
3 | +<plist version="1.0"> | ||
4 | +<dict> | ||
5 | + <key>CFBundleDevelopmentRegion</key> | ||
6 | + <string>$(DEVELOPMENT_LANGUAGE)</string> | ||
7 | + <key>CFBundleDisplayName</key> | ||
8 | + <string>一言临境</string> | ||
9 | + <key>CFBundleExecutable</key> | ||
10 | + <string>$(EXECUTABLE_NAME)</string> | ||
11 | + <key>CFBundleIdentifier</key> | ||
12 | + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> | ||
13 | + <key>CFBundleInfoDictionaryVersion</key> | ||
14 | + <string>6.0</string> | ||
15 | + <key>CFBundleName</key> | ||
16 | + <string>Parlando</string> | ||
17 | + <key>CFBundlePackageType</key> | ||
18 | + <string>APPL</string> | ||
19 | + <key>CFBundleShortVersionString</key> | ||
20 | + <string>$(FLUTTER_BUILD_NAME)</string> | ||
21 | + <key>CFBundleSignature</key> | ||
22 | + <string>????</string> | ||
23 | + <key>CFBundleVersion</key> | ||
24 | + <string>$(FLUTTER_BUILD_NUMBER)</string> | ||
25 | + <key>LSRequiresIPhoneOS</key> | ||
26 | + <true/> | ||
27 | + <key>NSAppTransportSecurity</key> | ||
28 | + <dict> | ||
29 | + <key>NSAllowsArbitraryLoads</key> | ||
30 | + <true/> | ||
31 | + </dict> | ||
32 | + <key>NSMicrophoneUsageDescription</key> | ||
33 | + <string>打开话筒</string> | ||
34 | + <key>UILaunchStoryboardName</key> | ||
35 | + <string>LaunchScreen</string> | ||
36 | + <key>UIMainStoryboardFile</key> | ||
37 | + <string>Main</string> | ||
38 | + <key>UIStatusBarHidden</key> | ||
39 | + <false/> | ||
40 | + <key>UISupportedInterfaceOrientations</key> | ||
41 | + <array> | ||
42 | + <string>UIInterfaceOrientationPortrait</string> | ||
43 | + <string>UIInterfaceOrientationLandscapeLeft</string> | ||
44 | + <string>UIInterfaceOrientationLandscapeRight</string> | ||
45 | + </array> | ||
46 | + <key>UISupportedInterfaceOrientations~ipad</key> | ||
47 | + <array> | ||
48 | + <string>UIInterfaceOrientationPortrait</string> | ||
49 | + <string>UIInterfaceOrientationPortraitUpsideDown</string> | ||
50 | + <string>UIInterfaceOrientationLandscapeLeft</string> | ||
51 | + <string>UIInterfaceOrientationLandscapeRight</string> | ||
52 | + </array> | ||
53 | + <key>UIViewControllerBasedStatusBarAppearance</key> | ||
54 | + <false/> | ||
55 | +</dict> | ||
56 | +</plist> |
lib/apis/api_base.dart
0 → 100644
1 | +import 'dart:convert'; | ||
2 | + | ||
3 | +import 'package:Parlando/apis/api_response.dart'; | ||
4 | +import 'package:Parlando/net/dio_utils.dart'; | ||
5 | +import 'package:common_utils/common_utils.dart'; | ||
6 | +import 'package:dio/dio.dart'; | ||
7 | +import 'package:flutter/material.dart'; | ||
8 | + | ||
9 | +class BaseApi { | ||
10 | + Future<Response<T>> post<T>( | ||
11 | + String path, { | ||
12 | + data, | ||
13 | + Map<String, dynamic>? queryParameters, | ||
14 | + Options? options, | ||
15 | + CancelToken? cancelToken, | ||
16 | + ProgressCallback? onSendProgress, | ||
17 | + ProgressCallback? onReceiveProgress, | ||
18 | + }) { | ||
19 | + return _getDio().post<T>( | ||
20 | + path, | ||
21 | + data: data, | ||
22 | + queryParameters: queryParameters, | ||
23 | + options: options, | ||
24 | + cancelToken: cancelToken, | ||
25 | + onSendProgress: onSendProgress, | ||
26 | + onReceiveProgress: onReceiveProgress, | ||
27 | + ); | ||
28 | + } | ||
29 | + | ||
30 | + Dio _getDio() { | ||
31 | + return DioUtils.instance.dio; | ||
32 | + } | ||
33 | +} |
lib/apis/api_order.dart
0 → 100644
1 | +import 'dart:convert'; | ||
2 | + | ||
3 | +import 'package:Parlando/apis/api_base.dart'; | ||
4 | +import 'package:Parlando/apis/api_response.dart'; | ||
5 | +import 'package:common_utils/common_utils.dart'; | ||
6 | +import 'package:dio/dio.dart'; | ||
7 | +import 'package:flutter/material.dart'; | ||
8 | + | ||
9 | +class OrderApi extends BaseApi { | ||
10 | + OrderApi._privateConstructor(); | ||
11 | + | ||
12 | + static final OrderApi _instance = OrderApi._privateConstructor(); | ||
13 | + | ||
14 | + static OrderApi get request { | ||
15 | + return _instance; | ||
16 | + } | ||
17 | + | ||
18 | + Future<dynamic> createOrder(String productId) { | ||
19 | + var data = {"goods_id": productId}; | ||
20 | + return post("order", data: data).then((value) { | ||
21 | + if (TextUtil.isEmpty(value.data)) { | ||
22 | + return {}; | ||
23 | + } | ||
24 | + return json.decode(value.data); | ||
25 | + }); | ||
26 | + } | ||
27 | + | ||
28 | + Future<dynamic> verifyOrder(String orderId, String type, String token, {Map<String, dynamic>? others}) { | ||
29 | + var data = { | ||
30 | + "order_sn": orderId, | ||
31 | + "pay_type": type, | ||
32 | + "token": token, | ||
33 | + "others": others ?? {}, | ||
34 | + }; | ||
35 | + return post("pay", data: data).then((value) { | ||
36 | + if (TextUtil.isEmpty(value.data)) { | ||
37 | + return {}; | ||
38 | + } | ||
39 | + return value.data; | ||
40 | + }); | ||
41 | + } | ||
42 | +} |
lib/base/base_state.dart
0 → 100644
1 | +import 'dart:async'; | ||
2 | + | ||
3 | +import 'package:flutter/material.dart'; | ||
4 | +import 'package:flutter_easyloading/flutter_easyloading.dart'; | ||
5 | + | ||
6 | +abstract class BaseState<T extends StatefulWidget> extends State<T> { | ||
7 | + bool _isFirstBuild = true; | ||
8 | + List<Timer> delayTimers = []; | ||
9 | + | ||
10 | + @override | ||
11 | + Widget build(BuildContext context) { | ||
12 | + if (_isFirstBuild) { | ||
13 | + onFirstBuildBody(context); | ||
14 | + _isFirstBuild = false; | ||
15 | + } | ||
16 | + return buildBody(context); | ||
17 | + } | ||
18 | + | ||
19 | + postDelay(VoidCallback fn, int delayTime) { | ||
20 | + var delayTimer = Timer(Duration(milliseconds: delayTime), fn); | ||
21 | + delayTimers.add(delayTimer); | ||
22 | + } | ||
23 | + | ||
24 | + Widget buildBody(BuildContext context); | ||
25 | + | ||
26 | + void onFirstBuildBody(BuildContext context) {} | ||
27 | + | ||
28 | + showLoading({String text = 'Loading...'}) { | ||
29 | + EasyLoading.show(status: text); | ||
30 | + } | ||
31 | + | ||
32 | + hideLoading() { | ||
33 | + EasyLoading.dismiss(); | ||
34 | + } | ||
35 | + | ||
36 | + toast(String text) { | ||
37 | + EasyLoading.showToast(text); | ||
38 | + } | ||
39 | + | ||
40 | + Widget buildLoading() { | ||
41 | + return const Center(child: CircularProgressIndicator()); | ||
42 | + } | ||
43 | + | ||
44 | + @override | ||
45 | + void dispose() { | ||
46 | + super.dispose(); | ||
47 | + for (var element in delayTimers) { | ||
48 | + element.cancel(); | ||
49 | + } | ||
50 | + hideLoading(); | ||
51 | + } | ||
52 | +} |
lib/extension/widget_ext.dart
0 → 100644
1 | +import 'package:flutter/material.dart'; | ||
2 | + | ||
3 | +extension WidgetExt on Widget { | ||
4 | + Expanded expanded({int flex = 1}) { | ||
5 | + return Expanded(flex: flex, child: this); | ||
6 | + } | ||
7 | + | ||
8 | + SafeArea safe() { | ||
9 | + return SafeArea(child: this); | ||
10 | + } | ||
11 | + | ||
12 | + ClipRRect round({double? radius, BorderRadius? borderRadius}) { | ||
13 | + return ClipRRect( | ||
14 | + borderRadius: borderRadius ?? BorderRadius.all(Radius.circular(radius ?? 5)), | ||
15 | + child: this, | ||
16 | + ); | ||
17 | + } | ||
18 | + | ||
19 | + Container height(double height, {Alignment? alignment}) { | ||
20 | + return Container(height: height, alignment: alignment, child: this); | ||
21 | + } | ||
22 | + | ||
23 | + Container height48({Alignment? alignment}) { | ||
24 | + return Container(height: 48, alignment: alignment, child: this); | ||
25 | + } | ||
26 | + | ||
27 | + Container paddingALL(double padding) { | ||
28 | + return Container(child: this, padding: EdgeInsets.all(padding)); | ||
29 | + } | ||
30 | + | ||
31 | + Container paddingTopBottom(double padding) { | ||
32 | + return Container(child: this, padding: EdgeInsets.only(bottom: padding, top: padding)); | ||
33 | + } | ||
34 | + | ||
35 | + Container paddingBottom(double padding) { | ||
36 | + return Container(child: this, padding: EdgeInsets.only(bottom: padding)); | ||
37 | + } | ||
38 | + | ||
39 | + Container paddingTop(double padding) { | ||
40 | + return Container(child: this, padding: EdgeInsets.only(top: padding)); | ||
41 | + } | ||
42 | + | ||
43 | + Widget paddingLeftRight(double padding) { | ||
44 | + return Container(child: this, padding: EdgeInsets.only(left: padding, right: padding)); | ||
45 | + } | ||
46 | + | ||
47 | + Container paddingLeft(double padding) { | ||
48 | + return Container(child: this, padding: EdgeInsets.only(left: padding)); | ||
49 | + } | ||
50 | + | ||
51 | + Container paddingRight(double padding) { | ||
52 | + return Container(child: this, padding: EdgeInsets.only(right: padding)); | ||
53 | + } | ||
54 | + | ||
55 | + Row rowRight() { | ||
56 | + return Row(mainAxisAlignment: MainAxisAlignment.end, children: [this]); | ||
57 | + } | ||
58 | + | ||
59 | + Row rowLeft() { | ||
60 | + return Row(mainAxisAlignment: MainAxisAlignment.start, children: [this]); | ||
61 | + } | ||
62 | + | ||
63 | + Row rowCenter() { | ||
64 | + return Row(mainAxisAlignment: MainAxisAlignment.center, children: [this]); | ||
65 | + } | ||
66 | + | ||
67 | + Widget click( | ||
68 | + GestureTapCallback? onTap, { | ||
69 | + Color? color, | ||
70 | + double? radius, | ||
71 | + BorderRadius? borderRadius, | ||
72 | + Color? bgColor, | ||
73 | + }) { | ||
74 | + if (color != null) { | ||
75 | + var border = radius == null ? null : BorderRadius.all(Radius.circular(radius)); | ||
76 | + return getMaterialInkWell( | ||
77 | + this, | ||
78 | + onTap, | ||
79 | + color, | ||
80 | + borderRadius: borderRadius ?? border, | ||
81 | + bgColor: bgColor, | ||
82 | + ); | ||
83 | + } | ||
84 | + return getWhiteInkWell(this, onTap); | ||
85 | + } | ||
86 | + | ||
87 | + ///当InkWell效果失效时,使用这个套件 | ||
88 | + Widget getMaterialInkWell( | ||
89 | + Widget widget, | ||
90 | + GestureTapCallback? onTap, | ||
91 | + Color? color, { | ||
92 | + BorderRadius? borderRadius, | ||
93 | + Color? splashColor, | ||
94 | + Color? bgColor = Colors.white, | ||
95 | + }) { | ||
96 | + return Material( | ||
97 | + color: bgColor, | ||
98 | + child: Ink( | ||
99 | + decoration: BoxDecoration( | ||
100 | + color: color, | ||
101 | + borderRadius: borderRadius, | ||
102 | + ), | ||
103 | + child: InkWell( | ||
104 | + onTap: onTap, | ||
105 | + splashColor: splashColor, | ||
106 | + borderRadius: borderRadius, | ||
107 | + child: widget, | ||
108 | + ), | ||
109 | + ), | ||
110 | + ); | ||
111 | + } | ||
112 | + | ||
113 | + ///当InkWell效果失效时,使用这个套件 | ||
114 | + Widget getWhiteInkWell(Widget widget, GestureTapCallback? onTap, {BorderRadius? borderRadius}) { | ||
115 | + return Material( | ||
116 | + child: Ink( | ||
117 | + color: Colors.white, | ||
118 | + child: InkWell(onTap: onTap, child: widget), | ||
119 | + ), | ||
120 | + ); | ||
121 | + } | ||
122 | +} |
... | @@ -68,6 +68,10 @@ MembershipData $MembershipDataFromJson(Map<String, dynamic> json) { | ... | @@ -68,6 +68,10 @@ MembershipData $MembershipDataFromJson(Map<String, dynamic> json) { |
68 | if (videoCover != null) { | 68 | if (videoCover != null) { |
69 | membershipData.videoCover = videoCover; | 69 | membershipData.videoCover = videoCover; |
70 | } | 70 | } |
71 | + final String? expireVipAt = jsonConvert.convert<String>(json['expire_vip_time']); | ||
72 | + if (videoCover != null) { | ||
73 | + membershipData.expireVipAt = expireVipAt; | ||
74 | + } | ||
71 | final String? terminal = jsonConvert.convert<String>(json['terminal']); | 75 | final String? terminal = jsonConvert.convert<String>(json['terminal']); |
72 | if (terminal != null) { | 76 | if (terminal != null) { |
73 | membershipData.terminal = terminal; | 77 | membershipData.terminal = terminal; |
... | @@ -105,6 +109,7 @@ Map<String, dynamic> $MembershipDataToJson(MembershipData entity) { | ... | @@ -105,6 +109,7 @@ Map<String, dynamic> $MembershipDataToJson(MembershipData entity) { |
105 | data['bg_images'] = entity.bgImages; | 109 | data['bg_images'] = entity.bgImages; |
106 | data['video_url'] = entity.videoUrl; | 110 | data['video_url'] = entity.videoUrl; |
107 | data['video_cover'] = entity.videoCover; | 111 | data['video_cover'] = entity.videoCover; |
112 | + data['expire_vip_time'] = entity.expireVipAt; | ||
108 | data['terminal'] = entity.terminal; | 113 | data['terminal'] = entity.terminal; |
109 | data['state'] = entity.state; | 114 | data['state'] = entity.state; |
110 | data['created_at'] = entity.createdAt; | 115 | data['created_at'] = entity.createdAt; |
... | @@ -116,17 +121,19 @@ Map<String, dynamic> $MembershipDataToJson(MembershipData entity) { | ... | @@ -116,17 +121,19 @@ Map<String, dynamic> $MembershipDataToJson(MembershipData entity) { |
116 | 121 | ||
117 | MembershipDataGoodsList $MembershipDataGoodsListFromJson( | 122 | MembershipDataGoodsList $MembershipDataGoodsListFromJson( |
118 | Map<String, dynamic> json) { | 123 | Map<String, dynamic> json) { |
119 | - final MembershipDataGoodsList membershipDataGoodsList = | 124 | + final MembershipDataGoodsList membershipDataGoodsList = MembershipDataGoodsList(); |
120 | - MembershipDataGoodsList(); | ||
121 | final int? id = jsonConvert.convert<int>(json['id']); | 125 | final int? id = jsonConvert.convert<int>(json['id']); |
122 | if (id != null) { | 126 | if (id != null) { |
123 | membershipDataGoodsList.id = id; | 127 | membershipDataGoodsList.id = id; |
124 | } | 128 | } |
125 | - final String? membershipId = | 129 | + final String? membershipId = jsonConvert.convert<String>(json['membership_id']); |
126 | - jsonConvert.convert<String>(json['membership_id']); | ||
127 | if (membershipId != null) { | 130 | if (membershipId != null) { |
128 | membershipDataGoodsList.membershipId = membershipId; | 131 | membershipDataGoodsList.membershipId = membershipId; |
129 | } | 132 | } |
133 | + final String? iapId = jsonConvert.convert<String>(json['iap_id']); | ||
134 | + if (iapId != null) { | ||
135 | + membershipDataGoodsList.iapId = iapId; | ||
136 | + } | ||
130 | final String? name = jsonConvert.convert<String>(json['name']); | 137 | final String? name = jsonConvert.convert<String>(json['name']); |
131 | if (name != null) { | 138 | if (name != null) { |
132 | membershipDataGoodsList.name = name; | 139 | membershipDataGoodsList.name = name; |
... | @@ -192,6 +199,7 @@ Map<String, dynamic> $MembershipDataGoodsListToJson( | ... | @@ -192,6 +199,7 @@ Map<String, dynamic> $MembershipDataGoodsListToJson( |
192 | final Map<String, dynamic> data = <String, dynamic>{}; | 199 | final Map<String, dynamic> data = <String, dynamic>{}; |
193 | data['id'] = entity.id; | 200 | data['id'] = entity.id; |
194 | data['membership_id'] = entity.membershipId; | 201 | data['membership_id'] = entity.membershipId; |
202 | + data['iap_id'] = entity.iapId; | ||
195 | data['name'] = entity.name; | 203 | data['name'] = entity.name; |
196 | data['price'] = entity.price; | 204 | data['price'] = entity.price; |
197 | data['line_price'] = entity.linePrice; | 205 | data['line_price'] = entity.linePrice; | ... | ... |
... | @@ -10,6 +10,10 @@ import 'package:Parlando/widgets/my_button.dart'; | ... | @@ -10,6 +10,10 @@ import 'package:Parlando/widgets/my_button.dart'; |
10 | import 'package:Parlando/widgets/my_scroll_view.dart'; | 10 | import 'package:Parlando/widgets/my_scroll_view.dart'; |
11 | 11 | ||
12 | import 'package:Parlando/extension/int_extension.dart'; | 12 | import 'package:Parlando/extension/int_extension.dart'; |
13 | +import 'package:getwidget/components/loader/gf_loader.dart'; | ||
14 | + | ||
15 | +import '../../net/dio_utils.dart'; | ||
16 | +import '../../net/http_api.dart'; | ||
13 | 17 | ||
14 | class UpdatePasswordPage extends StatefulWidget { | 18 | class UpdatePasswordPage extends StatefulWidget { |
15 | const UpdatePasswordPage({Key? key}) : super(key: key); | 19 | const UpdatePasswordPage({Key? key}) : super(key: key); |
... | @@ -26,6 +30,7 @@ class _UpdatePasswordPageState extends State<UpdatePasswordPage> | ... | @@ -26,6 +30,7 @@ class _UpdatePasswordPageState extends State<UpdatePasswordPage> |
26 | final FocusNode _nodeText1 = FocusNode(); | 30 | final FocusNode _nodeText1 = FocusNode(); |
27 | final FocusNode _nodeText2 = FocusNode(); | 31 | final FocusNode _nodeText2 = FocusNode(); |
28 | bool _clickable = false; | 32 | bool _clickable = false; |
33 | + bool _isLoading = false; | ||
29 | 34 | ||
30 | @override | 35 | @override |
31 | Map<ChangeNotifier, List<VoidCallback>?>? changeNotifier() { | 36 | Map<ChangeNotifier, List<VoidCallback>?>? changeNotifier() { |
... | @@ -56,8 +61,25 @@ class _UpdatePasswordPageState extends State<UpdatePasswordPage> | ... | @@ -56,8 +61,25 @@ class _UpdatePasswordPageState extends State<UpdatePasswordPage> |
56 | } | 61 | } |
57 | 62 | ||
58 | void _confirm() { | 63 | void _confirm() { |
59 | - Toast.show('修改成功!'); | 64 | + _isLoading = true; |
60 | - NavigatorUtils.goBack(context); | 65 | + Map<String, String> params = <String, String>{ |
66 | + "password": _newPwdController.text, | ||
67 | + "password_confirmation": _newPwdController.text, | ||
68 | + }; | ||
69 | + DioUtils.instance.asyncRequestNetwork( | ||
70 | + Method.post, | ||
71 | + HttpApi.changePassword, | ||
72 | + params: params, | ||
73 | + onSuccess: (data) { | ||
74 | + _isLoading = false; | ||
75 | + NavigatorUtils.goBack(context); | ||
76 | + }, | ||
77 | + onError: (code, msg) { | ||
78 | + _isLoading = false; | ||
79 | + Toast.show(msg.toString()); | ||
80 | + setState(() {}); | ||
81 | + }, | ||
82 | + ); | ||
61 | } | 83 | } |
62 | 84 | ||
63 | @override | 85 | @override |
... | @@ -76,7 +98,7 @@ class _UpdatePasswordPageState extends State<UpdatePasswordPage> | ... | @@ -76,7 +98,7 @@ class _UpdatePasswordPageState extends State<UpdatePasswordPage> |
76 | ), | 98 | ), |
77 | Gaps.vGap8, | 99 | Gaps.vGap8, |
78 | Text( | 100 | Text( |
79 | - '设置账号 15000000000', | 101 | + ' ', |
80 | style: Theme.of(context) | 102 | style: Theme.of(context) |
81 | .textTheme | 103 | .textTheme |
82 | .subtitle2 | 104 | .subtitle2 |
... | @@ -102,7 +124,10 @@ class _UpdatePasswordPageState extends State<UpdatePasswordPage> | ... | @@ -102,7 +124,10 @@ class _UpdatePasswordPageState extends State<UpdatePasswordPage> |
102 | MyButton( | 124 | MyButton( |
103 | onPressed: _clickable ? _confirm : null, | 125 | onPressed: _clickable ? _confirm : null, |
104 | text: '确认', | 126 | text: '确认', |
105 | - ) | 127 | + ), |
128 | + Container( | ||
129 | + child: _isLoading ? const GFLoader() : null, | ||
130 | + ), | ||
106 | ], | 131 | ], |
107 | ), | 132 | ), |
108 | ); | 133 | ); | ... | ... |
... | @@ -6,6 +6,7 @@ import 'package:dio/dio.dart'; | ... | @@ -6,6 +6,7 @@ import 'package:dio/dio.dart'; |
6 | import 'package:flustars/flustars.dart'; | 6 | import 'package:flustars/flustars.dart'; |
7 | import 'package:flutter/material.dart'; | 7 | import 'package:flutter/material.dart'; |
8 | import 'package:flutter/services.dart'; | 8 | import 'package:flutter/services.dart'; |
9 | +import 'package:flutter_easyloading/flutter_easyloading.dart'; | ||
9 | import 'package:oktoast/oktoast.dart'; | 10 | import 'package:oktoast/oktoast.dart'; |
10 | import 'package:provider/provider.dart'; | 11 | import 'package:provider/provider.dart'; |
11 | import 'package:quick_actions/quick_actions.dart'; | 12 | import 'package:quick_actions/quick_actions.dart'; |
... | @@ -60,8 +61,7 @@ Future<void> main() async { | ... | @@ -60,8 +61,7 @@ Future<void> main() async { |
60 | await SpUtil.getInstance(); | 61 | await SpUtil.getInstance(); |
61 | 62 | ||
62 | WidgetsFlutterBinding.ensureInitialized(); | 63 | WidgetsFlutterBinding.ensureInitialized(); |
63 | - SystemChrome.setPreferredOrientations( | 64 | + SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]); |
64 | - [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]); | ||
65 | 65 | ||
66 | /// 1.22 预览功能: 在输入频率与显示刷新率不匹配情况下提供平滑的滚动效果 | 66 | /// 1.22 预览功能: 在输入频率与显示刷新率不匹配情况下提供平滑的滚动效果 |
67 | // GestureBinding.instance?.resamplingEnabled = true; | 67 | // GestureBinding.instance?.resamplingEnabled = true; |
... | @@ -69,8 +69,7 @@ Future<void> main() async { | ... | @@ -69,8 +69,7 @@ Future<void> main() async { |
69 | handleError(() => runApp(MyApp())); | 69 | handleError(() => runApp(MyApp())); |
70 | 70 | ||
71 | /// 隐藏状态栏。为启动页、引导页设置。完成后修改回显示状态栏。 | 71 | /// 隐藏状态栏。为启动页、引导页设置。完成后修改回显示状态栏。 |
72 | - SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, | 72 | + SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.bottom]); |
73 | - overlays: [SystemUiOverlay.bottom]); | ||
74 | // TODO(weilu): 启动体验不佳。状态栏、导航栏在冷启动开始的一瞬间为黑色,且无法通过隐藏、修改颜色等方式进行处理。。。 | 73 | // TODO(weilu): 启动体验不佳。状态栏、导航栏在冷启动开始的一瞬间为黑色,且无法通过隐藏、修改颜色等方式进行处理。。。 |
75 | // 相关问题跟踪:https://github.com/flutter/flutter/issues/73351 | 74 | // 相关问题跟踪:https://github.com/flutter/flutter/issues/73351 |
76 | if (Platform.isAndroid) { | 75 | if (Platform.isAndroid) { |
... | @@ -133,8 +132,7 @@ class MyApp extends StatelessWidget { | ... | @@ -133,8 +132,7 @@ class MyApp extends StatelessWidget { |
133 | } | 132 | } |
134 | 133 | ||
135 | quickActions.setShortcutItems(<ShortcutItem>[ | 134 | quickActions.setShortcutItems(<ShortcutItem>[ |
136 | - const ShortcutItem( | 135 | + const ShortcutItem(type: 'demo', localizedTitle: '发一言', icon: 'flutter_dash_black'), |
137 | - type: 'demo', localizedTitle: '发一言', icon: 'flutter_dash_black'), | ||
138 | ]); | 136 | ]); |
139 | } | 137 | } |
140 | } | 138 | } |
... | @@ -149,8 +147,7 @@ class MyApp extends StatelessWidget { | ... | @@ -149,8 +147,7 @@ class MyApp extends StatelessWidget { |
149 | ChangeNotifierProvider(create: (_) => MembershipViewProvider()) | 147 | ChangeNotifierProvider(create: (_) => MembershipViewProvider()) |
150 | ], | 148 | ], |
151 | child: Consumer2<ThemeProvider, LocaleProvider>( | 149 | child: Consumer2<ThemeProvider, LocaleProvider>( |
152 | - builder: | 150 | + builder: (_, ThemeProvider provider, LocaleProvider localeProvider, __) { |
153 | - (_, ThemeProvider provider, LocaleProvider localeProvider, __) { | ||
154 | return _buildMaterialApp(provider, localeProvider); | 151 | return _buildMaterialApp(provider, localeProvider); |
155 | }, | 152 | }, |
156 | ), | 153 | ), |
... | @@ -159,15 +156,13 @@ class MyApp extends StatelessWidget { | ... | @@ -159,15 +156,13 @@ class MyApp extends StatelessWidget { |
159 | /// Toast 配置 | 156 | /// Toast 配置 |
160 | return OKToast( | 157 | return OKToast( |
161 | backgroundColor: Colors.black54, | 158 | backgroundColor: Colors.black54, |
162 | - textPadding: | 159 | + textPadding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 10.0), |
163 | - const EdgeInsets.symmetric(horizontal: 16.0, vertical: 10.0), | ||
164 | radius: 20.0, | 160 | radius: 20.0, |
165 | position: ToastPosition.bottom, | 161 | position: ToastPosition.bottom, |
166 | child: app); | 162 | child: app); |
167 | } | 163 | } |
168 | 164 | ||
169 | - Widget _buildMaterialApp( | 165 | + Widget _buildMaterialApp(ThemeProvider provider, LocaleProvider localeProvider) { |
170 | - ThemeProvider provider, LocaleProvider localeProvider) { | ||
171 | return MaterialApp( | 166 | return MaterialApp( |
172 | title: '一言', | 167 | title: '一言', |
173 | // showPerformanceOverlay: true, //显示性能标签 | 168 | // showPerformanceOverlay: true, //显示性能标签 |
... | @@ -185,7 +180,7 @@ class MyApp extends StatelessWidget { | ... | @@ -185,7 +180,7 @@ class MyApp extends StatelessWidget { |
185 | supportedLocales: ParlandoLocalizations.supportedLocales, | 180 | supportedLocales: ParlandoLocalizations.supportedLocales, |
186 | locale: localeProvider.locale, | 181 | locale: localeProvider.locale, |
187 | navigatorKey: navigatorKey, | 182 | navigatorKey: navigatorKey, |
188 | - builder: (BuildContext context, Widget? child) { | 183 | + builder: EasyLoading.init(builder: (context, child) { |
189 | /// 仅针对安卓 | 184 | /// 仅针对安卓 |
190 | if (Device.isAndroid) { | 185 | if (Device.isAndroid) { |
191 | /// 切换深色模式会触发此方法,这里设置导航栏颜色 | 186 | /// 切换深色模式会触发此方法,这里设置导航栏颜色 |
... | @@ -197,7 +192,7 @@ class MyApp extends StatelessWidget { | ... | @@ -197,7 +192,7 @@ class MyApp extends StatelessWidget { |
197 | data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0), | 192 | data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0), |
198 | child: child!, | 193 | child: child!, |
199 | ); | 194 | ); |
200 | - }, | 195 | + }), |
201 | 196 | ||
202 | /// 因为使用了fluro,这里设置主要针对Web | 197 | /// 因为使用了fluro,这里设置主要针对Web |
203 | onUnknownRoute: (_) { | 198 | onUnknownRoute: (_) { |
... | @@ -236,4 +231,4 @@ Future<bool> requestLocationPermission() async { | ... | @@ -236,4 +231,4 @@ Future<bool> requestLocationPermission() async { |
236 | return false; | 231 | return false; |
237 | } | 232 | } |
238 | } | 233 | } |
239 | -} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
234 | +} | ... | ... |
... | @@ -42,6 +42,8 @@ class MembershipData { | ... | @@ -42,6 +42,8 @@ class MembershipData { |
42 | String? createdAt; | 42 | String? createdAt; |
43 | @JSONField(name: "updated_at") | 43 | @JSONField(name: "updated_at") |
44 | String? updatedAt; | 44 | String? updatedAt; |
45 | + @JSONField(name: "expire_vip_time") | ||
46 | + String? expireVipAt; | ||
45 | @JSONField(name: "is_vip") | 47 | @JSONField(name: "is_vip") |
46 | int? isVip; | 48 | int? isVip; |
47 | @JSONField(name: "goods_list") | 49 | @JSONField(name: "goods_list") |
... | @@ -65,6 +67,8 @@ class MembershipDataGoodsList { | ... | @@ -65,6 +67,8 @@ class MembershipDataGoodsList { |
65 | int? id; | 67 | int? id; |
66 | @JSONField(name: "membership_id") | 68 | @JSONField(name: "membership_id") |
67 | String? membershipId; | 69 | String? membershipId; |
70 | + @JSONField(name: "iap_id") | ||
71 | + String? iapId; | ||
68 | String? name; | 72 | String? name; |
69 | String? price; | 73 | String? price; |
70 | @JSONField(name: "line_price") | 74 | @JSONField(name: "line_price") | ... | ... |
This diff is collapsed. Click to expand it.
lib/models/nearby_response.dart
0 → 100644
1 | +class NearbyPlacesResponse { | ||
2 | + List<Results>? results; | ||
3 | + String? status; | ||
4 | + | ||
5 | + NearbyPlacesResponse({this.results, this.status}); | ||
6 | + | ||
7 | + NearbyPlacesResponse.fromJson(Map<String, dynamic> json) { | ||
8 | + if (json['results'] != null) { | ||
9 | + results = <Results>[]; | ||
10 | + json['results'].forEach((v) { | ||
11 | + results!.add(Results.fromJson(v)); | ||
12 | + }); | ||
13 | + } | ||
14 | + status = json['status']; | ||
15 | + } | ||
16 | + | ||
17 | + Map<String, dynamic> toJson() { | ||
18 | + final Map<String, dynamic> data = Map<String, dynamic>(); | ||
19 | + if (this.results != null) { | ||
20 | + data['results'] = this.results!.map((v) => v.toJson()).toList(); | ||
21 | + } | ||
22 | + data['status'] = this.status; | ||
23 | + return data; | ||
24 | + } | ||
25 | +} | ||
26 | + | ||
27 | +class Results { | ||
28 | + Geometry? geometry; | ||
29 | + String? icon; | ||
30 | + String? iconBackgroundColor; | ||
31 | + String? iconMaskBaseUri; | ||
32 | + String? name; | ||
33 | + List<Photos>? photos; | ||
34 | + String? placeId; | ||
35 | + String? reference; | ||
36 | + String? scope; | ||
37 | + List<String>? types; | ||
38 | + String? vicinity; | ||
39 | + String? businessStatus; | ||
40 | + OpeningHours? openingHours; | ||
41 | + PlusCode? plusCode; | ||
42 | + dynamic rating; | ||
43 | + int? userRatingsTotal; | ||
44 | + bool isSelect = false; | ||
45 | + | ||
46 | + Results( | ||
47 | + {this.geometry, | ||
48 | + this.icon, | ||
49 | + this.iconBackgroundColor, | ||
50 | + this.iconMaskBaseUri, | ||
51 | + this.name, | ||
52 | + this.photos, | ||
53 | + this.placeId, | ||
54 | + this.reference, | ||
55 | + this.scope, | ||
56 | + this.types, | ||
57 | + this.vicinity, | ||
58 | + this.businessStatus, | ||
59 | + this.openingHours, | ||
60 | + this.plusCode, | ||
61 | + this.rating, | ||
62 | + this.userRatingsTotal, | ||
63 | + this.isSelect = false}); | ||
64 | + | ||
65 | + Results.fromJson(Map<String, dynamic> json) { | ||
66 | + geometry = json['geometry'] != null ? Geometry.fromJson(json['geometry']) : null; | ||
67 | + icon = json['icon']; | ||
68 | + iconBackgroundColor = json['icon_background_color']; | ||
69 | + iconMaskBaseUri = json['icon_mask_base_uri']; | ||
70 | + name = json['name']; | ||
71 | + if (json['photos'] != null) { | ||
72 | + photos = <Photos>[]; | ||
73 | + json['photos'].forEach((v) { | ||
74 | + photos!.add(Photos.fromJson(v)); | ||
75 | + }); | ||
76 | + } | ||
77 | + placeId = json['place_id']; | ||
78 | + reference = json['reference']; | ||
79 | + scope = json['scope']; | ||
80 | + types = json['types'].cast<String>(); | ||
81 | + vicinity = json['vicinity']; | ||
82 | + businessStatus = json['business_status']; | ||
83 | + openingHours = json['opening_hours'] != null ? OpeningHours.fromJson(json['opening_hours']) : null; | ||
84 | + plusCode = json['plus_code'] != null ? PlusCode.fromJson(json['plus_code']) : null; | ||
85 | + rating = json['rating']; | ||
86 | + userRatingsTotal = json['user_ratings_total']; | ||
87 | + } | ||
88 | + | ||
89 | + Map<String, dynamic> toJson() { | ||
90 | + final Map<String, dynamic> data = Map<String, dynamic>(); | ||
91 | + if (this.geometry != null) { | ||
92 | + data['geometry'] = this.geometry!.toJson(); | ||
93 | + } | ||
94 | + data['icon'] = this.icon; | ||
95 | + data['icon_background_color'] = this.iconBackgroundColor; | ||
96 | + data['icon_mask_base_uri'] = this.iconMaskBaseUri; | ||
97 | + data['name'] = this.name; | ||
98 | + if (this.photos != null) { | ||
99 | + data['photos'] = this.photos!.map((v) => v.toJson()).toList(); | ||
100 | + } | ||
101 | + data['place_id'] = this.placeId; | ||
102 | + data['reference'] = this.reference; | ||
103 | + data['scope'] = this.scope; | ||
104 | + data['types'] = this.types; | ||
105 | + data['vicinity'] = this.vicinity; | ||
106 | + data['business_status'] = this.businessStatus; | ||
107 | + if (this.openingHours != null) { | ||
108 | + data['opening_hours'] = this.openingHours!.toJson(); | ||
109 | + } | ||
110 | + if (this.plusCode != null) { | ||
111 | + data['plus_code'] = this.plusCode!.toJson(); | ||
112 | + } | ||
113 | + data['rating'] = this.rating; | ||
114 | + data['user_ratings_total'] = this.userRatingsTotal; | ||
115 | + return data; | ||
116 | + } | ||
117 | +} | ||
118 | + | ||
119 | +class Geometry { | ||
120 | + Location? location; | ||
121 | + Viewport? viewport; | ||
122 | + | ||
123 | + Geometry({this.location, this.viewport}); | ||
124 | + | ||
125 | + Geometry.fromJson(Map<String, dynamic> json) { | ||
126 | + location = json['location'] != null ? Location.fromJson(json['location']) : null; | ||
127 | + viewport = json['viewport'] != null ? Viewport.fromJson(json['viewport']) : null; | ||
128 | + } | ||
129 | + | ||
130 | + Map<String, dynamic> toJson() { | ||
131 | + final Map<String, dynamic> data = Map<String, dynamic>(); | ||
132 | + if (this.location != null) { | ||
133 | + data['location'] = this.location!.toJson(); | ||
134 | + } | ||
135 | + if (this.viewport != null) { | ||
136 | + data['viewport'] = this.viewport!.toJson(); | ||
137 | + } | ||
138 | + return data; | ||
139 | + } | ||
140 | +} | ||
141 | + | ||
142 | +class Location { | ||
143 | + double? lat; | ||
144 | + double? lng; | ||
145 | + | ||
146 | + Location({this.lat, this.lng}); | ||
147 | + | ||
148 | + Location.fromJson(Map<String, dynamic> json) { | ||
149 | + lat = json['lat']; | ||
150 | + lng = json['lng']; | ||
151 | + } | ||
152 | + | ||
153 | + Map<String, dynamic> toJson() { | ||
154 | + final Map<String, dynamic> data = Map<String, dynamic>(); | ||
155 | + data['lat'] = this.lat; | ||
156 | + data['lng'] = this.lng; | ||
157 | + return data; | ||
158 | + } | ||
159 | +} | ||
160 | + | ||
161 | +class Viewport { | ||
162 | + Location? northeast; | ||
163 | + Location? southwest; | ||
164 | + | ||
165 | + Viewport({this.northeast, this.southwest}); | ||
166 | + | ||
167 | + Viewport.fromJson(Map<String, dynamic> json) { | ||
168 | + northeast = json['northeast'] != null ? Location.fromJson(json['northeast']) : null; | ||
169 | + southwest = json['southwest'] != null ? Location.fromJson(json['southwest']) : null; | ||
170 | + } | ||
171 | + | ||
172 | + Map<String, dynamic> toJson() { | ||
173 | + final Map<String, dynamic> data = Map<String, dynamic>(); | ||
174 | + if (this.northeast != null) { | ||
175 | + data['northeast'] = this.northeast!.toJson(); | ||
176 | + } | ||
177 | + if (this.southwest != null) { | ||
178 | + data['southwest'] = this.southwest!.toJson(); | ||
179 | + } | ||
180 | + return data; | ||
181 | + } | ||
182 | +} | ||
183 | + | ||
184 | +class Photos { | ||
185 | + int? height; | ||
186 | + List<String>? htmlAttributions; | ||
187 | + String? photoReference; | ||
188 | + int? width; | ||
189 | + | ||
190 | + Photos({this.height, this.htmlAttributions, this.photoReference, this.width}); | ||
191 | + | ||
192 | + Photos.fromJson(Map<String, dynamic> json) { | ||
193 | + height = json['height']; | ||
194 | + htmlAttributions = json['html_attributions'].cast<String>(); | ||
195 | + photoReference = json['photo_reference']; | ||
196 | + width = json['width']; | ||
197 | + } | ||
198 | + | ||
199 | + Map<String, dynamic> toJson() { | ||
200 | + final Map<String, dynamic> data = Map<String, dynamic>(); | ||
201 | + data['height'] = this.height; | ||
202 | + data['html_attributions'] = this.htmlAttributions; | ||
203 | + data['photo_reference'] = this.photoReference; | ||
204 | + data['width'] = this.width; | ||
205 | + return data; | ||
206 | + } | ||
207 | +} | ||
208 | + | ||
209 | +class OpeningHours { | ||
210 | + bool? openNow; | ||
211 | + | ||
212 | + OpeningHours({this.openNow}); | ||
213 | + | ||
214 | + OpeningHours.fromJson(Map<String, dynamic> json) { | ||
215 | + openNow = json['open_now']; | ||
216 | + } | ||
217 | + | ||
218 | + Map<String, dynamic> toJson() { | ||
219 | + final Map<String, dynamic> data = Map<String, dynamic>(); | ||
220 | + data['open_now'] = this.openNow; | ||
221 | + return data; | ||
222 | + } | ||
223 | +} | ||
224 | + | ||
225 | +class PlusCode { | ||
226 | + String? compoundCode; | ||
227 | + String? globalCode; | ||
228 | + | ||
229 | + PlusCode({this.compoundCode, this.globalCode}); | ||
230 | + | ||
231 | + PlusCode.fromJson(Map<String, dynamic> json) { | ||
232 | + compoundCode = json['compound_code']; | ||
233 | + globalCode = json['global_code']; | ||
234 | + } | ||
235 | + | ||
236 | + Map<String, dynamic> toJson() { | ||
237 | + final Map<String, dynamic> data = Map<String, dynamic>(); | ||
238 | + data['compound_code'] = this.compoundCode; | ||
239 | + data['global_code'] = this.globalCode; | ||
240 | + return data; | ||
241 | + } | ||
242 | +} |
lib/models/poisearch_model.dart
0 → 100644
1 | +class PoiSearch { | ||
2 | + PoiSearch({ | ||
3 | + required this.cityCode, | ||
4 | + required this.cityName, | ||
5 | + required this.provinceName, | ||
6 | + required this.title, | ||
7 | + required this.adName, | ||
8 | + required this.provinceCode, | ||
9 | + required this.latitude, | ||
10 | + required this.longitude, | ||
11 | + }); | ||
12 | + | ||
13 | + PoiSearch.fromJsonMap(Map<String, dynamic> map) | ||
14 | + : cityCode = map['cityCode'] as String, | ||
15 | + cityName = map['cityName'] as String, | ||
16 | + provinceName = map['provinceName'] as String, | ||
17 | + title = map['title'] as String, | ||
18 | + adName = map['adName'] as String, | ||
19 | + provinceCode = map['provinceCode'] as String, | ||
20 | + latitude = map['latitude'] as String, | ||
21 | + longitude = map['longitude'] as String; | ||
22 | + | ||
23 | + String cityCode; | ||
24 | + String cityName; | ||
25 | + String provinceName; | ||
26 | + String title; | ||
27 | + String adName; | ||
28 | + String provinceCode; | ||
29 | + String latitude; | ||
30 | + String longitude; | ||
31 | + | ||
32 | + Map<String, dynamic> toJson() { | ||
33 | + final Map<String, dynamic> data = <String, dynamic>{}; | ||
34 | + data['cityCode'] = cityCode; | ||
35 | + data['cityName'] = cityName; | ||
36 | + data['provinceName'] = provinceName; | ||
37 | + data['title'] = title; | ||
38 | + data['adName'] = adName; | ||
39 | + data['provinceCode'] = provinceCode; | ||
40 | + data['latitude'] = latitude; | ||
41 | + data['longitude'] = longitude; | ||
42 | + return data; | ||
43 | + } | ||
44 | +} |
... | @@ -7,6 +7,7 @@ class HttpApi { | ... | @@ -7,6 +7,7 @@ class HttpApi { |
7 | static const String uploadVideo = 'upload/video'; | 7 | static const String uploadVideo = 'upload/video'; |
8 | static const String uploadImage = 'upload/image'; | 8 | static const String uploadImage = 'upload/image'; |
9 | static const String immersive = 'immersive'; | 9 | static const String immersive = 'immersive'; |
10 | + static const String changePassword = 'user/changePassword'; | ||
10 | static const String avatar = 'avatar'; | 11 | static const String avatar = 'avatar'; |
11 | static const String user = 'user'; | 12 | static const String user = 'user'; |
12 | static const String membership = 'membership'; | 13 | static const String membership = 'membership'; | ... | ... |
lib/payment/payment_sdk.dart
0 → 100644
1 | +import 'dart:async'; | ||
2 | + | ||
3 | +import 'package:Parlando/apis/api_order.dart'; | ||
4 | +import 'package:Parlando/membership/models/membership_entity.dart'; | ||
5 | +import 'package:common_utils/common_utils.dart'; | ||
6 | +import 'package:in_app_purchase/in_app_purchase.dart'; | ||
7 | +import 'package:in_app_purchase_android/in_app_purchase_android.dart'; | ||
8 | +import 'package:in_app_purchase_storekit/in_app_purchase_storekit.dart'; | ||
9 | + | ||
10 | +class PaymentSdk { | ||
11 | + var currentOrder; | ||
12 | + | ||
13 | + PaymentSdk._privateConstructor(); | ||
14 | + | ||
15 | + static final PaymentSdk _instance = PaymentSdk._privateConstructor(); | ||
16 | + | ||
17 | + static PaymentSdk get instance { | ||
18 | + return _instance; | ||
19 | + } | ||
20 | + | ||
21 | + static const Set<String> _kIds = <String>{'yearly_yiyan_vip', 'monthly_yiyan_vip'}; | ||
22 | + | ||
23 | + StreamSubscription<List<PurchaseDetails>>? _subscription; | ||
24 | + List<ProductDetails> products = []; | ||
25 | + Function? onPaySuccess; | ||
26 | + Function? onPending; | ||
27 | + Function? onFailed; | ||
28 | + Function? onCancel; | ||
29 | + | ||
30 | + initState({ | ||
31 | + Function? onPaySuccess, | ||
32 | + Function? onPending, | ||
33 | + Function? onFailed, | ||
34 | + Function? onCancel, | ||
35 | + }) { | ||
36 | + this.onPaySuccess = onPaySuccess; | ||
37 | + this.onPending = onPending; | ||
38 | + this.onFailed = onFailed; | ||
39 | + this.onCancel = onCancel; | ||
40 | + final Stream<List<PurchaseDetails>> purchaseUpdated = InAppPurchase.instance.purchaseStream; | ||
41 | + _subscription = purchaseUpdated.listen((purchaseDetailsList) { | ||
42 | + _listenToPurchaseUpdated(purchaseDetailsList); | ||
43 | + }, onDone: () { | ||
44 | + _subscription?.cancel(); | ||
45 | + }, onError: (error) { | ||
46 | + // handle error here. | ||
47 | + }); | ||
48 | + } | ||
49 | + | ||
50 | + Future<List<ProductDetails>> queryProducts() async { | ||
51 | + final bool available = await InAppPurchase.instance.isAvailable(); | ||
52 | + if (!available) { | ||
53 | + return []; | ||
54 | + } | ||
55 | + final ProductDetailsResponse response = await InAppPurchase.instance.queryProductDetails(_kIds); | ||
56 | + return products = response.productDetails; | ||
57 | + } | ||
58 | + | ||
59 | + buy(ProductDetails details, MembershipDataGoodsList e) { | ||
60 | + OrderApi.request.createOrder(e.id.toString()).then((value) { | ||
61 | + var orderId = value?['data']?['data']?['order_sn']; | ||
62 | + if (TextUtil.isEmpty(orderId)) { | ||
63 | + onFailed?.call(); | ||
64 | + return; | ||
65 | + } | ||
66 | + currentOrder = orderId; | ||
67 | + final PurchaseParam purchaseParam = PurchaseParam(productDetails: details, applicationUserName: orderId); | ||
68 | + if (_isConsumable(details)) { | ||
69 | + InAppPurchase.instance.buyConsumable(purchaseParam: purchaseParam); | ||
70 | + } else { | ||
71 | + InAppPurchase.instance.buyNonConsumable(purchaseParam: purchaseParam); | ||
72 | + } | ||
73 | + }); | ||
74 | + } | ||
75 | + | ||
76 | + void _listenToPurchaseUpdated(List<PurchaseDetails> purchaseDetailsList) async { | ||
77 | + for (var purchaseDetails in purchaseDetailsList) { | ||
78 | + if (purchaseDetails.status == PurchaseStatus.pending) { | ||
79 | + onPending?.call(); | ||
80 | + } else { | ||
81 | + if (purchaseDetails.status == PurchaseStatus.error) { | ||
82 | + _handleError(purchaseDetails.error!); | ||
83 | + } else if (purchaseDetails.status == PurchaseStatus.purchased || purchaseDetails.status == PurchaseStatus.restored) { | ||
84 | + bool valid = await _verifyPurchase(purchaseDetails); | ||
85 | + if (valid) { | ||
86 | + _deliverProduct(purchaseDetails); | ||
87 | + } else { | ||
88 | + _handleInvalidPurchase(purchaseDetails); | ||
89 | + } | ||
90 | + } else { | ||
91 | + onCancel?.call(); | ||
92 | + } | ||
93 | + if (purchaseDetails.pendingCompletePurchase) { | ||
94 | + await InAppPurchase.instance.completePurchase(purchaseDetails); | ||
95 | + } | ||
96 | + } | ||
97 | + } | ||
98 | + } | ||
99 | + | ||
100 | + _verifyPurchase(PurchaseDetails purchaseDetails) async { | ||
101 | + return true; | ||
102 | + } | ||
103 | + | ||
104 | + void _deliverProduct(PurchaseDetails purchaseDetails) { | ||
105 | + String type = ""; | ||
106 | + Map<String, dynamic> otherField = {}; | ||
107 | + if (purchaseDetails is GooglePlayPurchaseDetails) { | ||
108 | + currentOrder = purchaseDetails.billingClientPurchase.obfuscatedAccountId; | ||
109 | + type = "google"; | ||
110 | + otherField["google"] = { | ||
111 | + "originalJson": purchaseDetails.billingClientPurchase.originalJson, | ||
112 | + }; | ||
113 | + } | ||
114 | + if (purchaseDetails is AppStorePurchaseDetails) { | ||
115 | + type = "apple"; | ||
116 | + otherField["apple"] = { | ||
117 | + "transactionIdentifier": purchaseDetails.skPaymentTransaction.transactionIdentifier, | ||
118 | + "originalTransactionIdentifier": | ||
119 | + purchaseDetails.skPaymentTransaction.originalTransaction?.transactionIdentifier ?? "", | ||
120 | + }; | ||
121 | + } | ||
122 | + var serverVerifyStr = purchaseDetails.verificationData.serverVerificationData; | ||
123 | + var verifySource = purchaseDetails.verificationData.source; | ||
124 | + otherField["source"] = verifySource; | ||
125 | + OrderApi.request.verifyOrder(currentOrder, type, serverVerifyStr, others: otherField).then((value) { | ||
126 | + if (value != null) {} | ||
127 | + onPaySuccess?.call(); | ||
128 | + }); | ||
129 | + } | ||
130 | + | ||
131 | + void _handleInvalidPurchase(PurchaseDetails purchaseDetails) { | ||
132 | + onFailed?.call(); | ||
133 | + } | ||
134 | + | ||
135 | + void _handleError(IAPError iapError) { | ||
136 | + onFailed?.call(); | ||
137 | + } | ||
138 | + | ||
139 | + bool _isConsumable(ProductDetails details) { | ||
140 | + return false; | ||
141 | + } | ||
142 | + | ||
143 | + void restore() { | ||
144 | + InAppPurchase.instance.restorePurchases(); | ||
145 | + } | ||
146 | + | ||
147 | + void dispose() { | ||
148 | + onPaySuccess = null; | ||
149 | + onPending = null; | ||
150 | + onFailed = null; | ||
151 | + onCancel = null; | ||
152 | + _subscription?.cancel(); | ||
153 | + } | ||
154 | +} |
... | @@ -26,7 +26,7 @@ class PaymentService { | ... | @@ -26,7 +26,7 @@ class PaymentService { |
26 | late StreamSubscription<PurchaseResult?> _purchaseErrorSubscription; | 26 | late StreamSubscription<PurchaseResult?> _purchaseErrorSubscription; |
27 | 27 | ||
28 | /// List of product ids you want to fetch | 28 | /// List of product ids you want to fetch |
29 | - final List<String> _productIds = ['test.yiyan.vip.1.month']; | 29 | + final List<String> _productIds = ['yearly_yiyan_vip', 'monthly_yiyan_vip']; |
30 | 30 | ||
31 | /// All available products will be store in this list | 31 | /// All available products will be store in this list |
32 | late List<IAPItem> _products; | 32 | late List<IAPItem> _products; |
... | @@ -36,12 +36,12 @@ class PaymentService { | ... | @@ -36,12 +36,12 @@ class PaymentService { |
36 | 36 | ||
37 | /// view of the app will subscribe to this to get notified | 37 | /// view of the app will subscribe to this to get notified |
38 | /// when premium status of the user changes | 38 | /// when premium status of the user changes |
39 | - final ObserverList<Function> _proStatusChangedListeners = | 39 | + final ObserverList<Function> _proStatusChangedListeners = ObserverList<Function>(); |
40 | - ObserverList<Function>(); | ||
41 | 40 | ||
42 | /// view of the app will subscribe to this to get errors of the purchase | 41 | /// view of the app will subscribe to this to get errors of the purchase |
43 | - final ObserverList<Function(String)> _errorListeners = | 42 | + final ObserverList<Function(String)> _errorListeners = ObserverList<Function(String)>(); |
44 | - ObserverList<Function(String)>(); | 43 | + |
44 | + final ObserverList<Function> _connectListeners = ObserverList<Function>(); | ||
45 | 45 | ||
46 | /// logged in user's premium status | 46 | /// logged in user's premium status |
47 | bool _isProUser = false; | 47 | bool _isProUser = false; |
... | @@ -68,6 +68,20 @@ class PaymentService { | ... | @@ -68,6 +68,20 @@ class PaymentService { |
68 | _errorListeners.remove(callback); | 68 | _errorListeners.remove(callback); |
69 | } | 69 | } |
70 | 70 | ||
71 | + addConnectListener(Function? callback) { | ||
72 | + if (callback == null) { | ||
73 | + return; | ||
74 | + } | ||
75 | + _connectListeners.add(callback); | ||
76 | + } | ||
77 | + | ||
78 | + removeConnectListener(Function? callback) { | ||
79 | + if (callback == null) { | ||
80 | + return; | ||
81 | + } | ||
82 | + _connectListeners.remove(callback); | ||
83 | + } | ||
84 | + | ||
71 | /// Call this method to notify all the subsctibers of _proStatusChangedListeners | 85 | /// Call this method to notify all the subsctibers of _proStatusChangedListeners |
72 | void _callProStatusChangedListeners() { | 86 | void _callProStatusChangedListeners() { |
73 | for (var callback in _proStatusChangedListeners) { | 87 | for (var callback in _proStatusChangedListeners) { |
... | @@ -84,18 +98,19 @@ class PaymentService { | ... | @@ -84,18 +98,19 @@ class PaymentService { |
84 | 98 | ||
85 | /// Call this method at the startup of you app to initialize connection | 99 | /// Call this method at the startup of you app to initialize connection |
86 | /// with billing server and get all the necessary data | 100 | /// with billing server and get all the necessary data |
87 | - void initConnection() { | 101 | + void initConnection() async { |
88 | - var result = FlutterInappPurchase.instance.initialize(); | 102 | + var result = await FlutterInappPurchase.instance.initialize(); |
89 | print("___________________________"); | 103 | print("___________________________"); |
90 | print("result:$result"); | 104 | print("result:$result"); |
91 | - _connectionSubscription = | 105 | + _connectionSubscription = FlutterInappPurchase.connectionUpdated.listen((connected) { |
92 | - FlutterInappPurchase.connectionUpdated.listen((connected) {}); | 106 | + for (var value in _connectListeners) { |
107 | + value.call(); | ||
108 | + } | ||
109 | + }); | ||
93 | 110 | ||
94 | - _purchaseUpdatedSubscription = | 111 | + _purchaseUpdatedSubscription = FlutterInappPurchase.purchaseUpdated.listen(_handlePurchaseUpdate); |
95 | - FlutterInappPurchase.purchaseUpdated.listen(_handlePurchaseUpdate); | ||
96 | 112 | ||
97 | - _purchaseErrorSubscription = | 113 | + _purchaseErrorSubscription = FlutterInappPurchase.purchaseError.listen(_handlePurchaseError); |
98 | - FlutterInappPurchase.purchaseError.listen(_handlePurchaseError); | ||
99 | 114 | ||
100 | _getItems(); | 115 | _getItems(); |
101 | _getPastPurchases(); | 116 | _getPastPurchases(); |
... | @@ -191,14 +206,14 @@ class PaymentService { | ... | @@ -191,14 +206,14 @@ class PaymentService { |
191 | } | 206 | } |
192 | 207 | ||
193 | Future<void> _getItems() async { | 208 | Future<void> _getItems() async { |
194 | - List<IAPItem> items = | 209 | + List<IAPItem> items = await FlutterInappPurchase.instance.getSubscriptions(_productIds); |
195 | - await FlutterInappPurchase.instance.getSubscriptions(_productIds); | 210 | + print("############${items.length}"); |
196 | _products = []; | 211 | _products = []; |
197 | for (var item in items) { | 212 | for (var item in items) { |
198 | _products.add(item); | 213 | _products.add(item); |
199 | } | 214 | } |
200 | print("############"); | 215 | print("############"); |
201 | - print(_products); | 216 | + print("############${_products}"); |
202 | } | 217 | } |
203 | 218 | ||
204 | void _getPastPurchases() async { | 219 | void _getPastPurchases() async { |
... | @@ -206,8 +221,7 @@ class PaymentService { | ... | @@ -206,8 +221,7 @@ class PaymentService { |
206 | if (Platform.isIOS) { | 221 | if (Platform.isIOS) { |
207 | return; | 222 | return; |
208 | } | 223 | } |
209 | - List<PurchasedItem>? purchasedItems = | 224 | + List<PurchasedItem>? purchasedItems = await FlutterInappPurchase.instance.getAvailablePurchases(); |
210 | - await FlutterInappPurchase.instance.getAvailablePurchases(); | ||
211 | 225 | ||
212 | for (var purchasedItem in purchasedItems!) { | 226 | for (var purchasedItem in purchasedItems!) { |
213 | bool isValid = false; | 227 | bool isValid = false; |
... | @@ -236,8 +250,7 @@ class PaymentService { | ... | @@ -236,8 +250,7 @@ class PaymentService { |
236 | 250 | ||
237 | Future<void> buyProduct(IAPItem item) async { | 251 | Future<void> buyProduct(IAPItem item) async { |
238 | try { | 252 | try { |
239 | - await FlutterInappPurchase.instance | 253 | + await FlutterInappPurchase.instance.requestSubscription(item.productId.toString()); |
240 | - .requestSubscription(item.productId.toString()); | ||
241 | } catch (error) { | 254 | } catch (error) { |
242 | Toast.show("购买失败!"); | 255 | Toast.show("购买失败!"); |
243 | } | 256 | } | ... | ... |
1 | +import 'package:Parlando/models/nearby_response.dart'; | ||
1 | import 'package:Parlando/models/upload_entity.dart'; | 2 | import 'package:Parlando/models/upload_entity.dart'; |
2 | import 'package:Parlando/net/dio_utils.dart'; | 3 | import 'package:Parlando/net/dio_utils.dart'; |
3 | import 'package:Parlando/net/http_api.dart'; | 4 | import 'package:Parlando/net/http_api.dart'; |
... | @@ -109,12 +110,10 @@ class PoemPublishState extends State<PoemPublish> { | ... | @@ -109,12 +110,10 @@ class PoemPublishState extends State<PoemPublish> { |
109 | NavigatorUtils.pushResult( | 110 | NavigatorUtils.pushResult( |
110 | context, PoemRouter.addressSelectPage, (result) { | 111 | context, PoemRouter.addressSelectPage, (result) { |
111 | setState(() { | 112 | setState(() { |
112 | - // final BMFSuggestionInfo model = | 113 | + final Results model = result as Results; |
113 | - // result as BMFSuggestionInfo; | 114 | + _longitude = model.geometry!.location!.lng.toString(); |
114 | - // _longitude = model.location!.longitude.toString(); | 115 | + _latitude = model.geometry!.location!.lat.toString(); |
115 | - // _latitude = model.location!.latitude.toString(); | 116 | + _address = '${model.name} ${model.vicinity}'; |
116 | - // _address = | ||
117 | - // '${model.city!} ${model.district!} ${model.address!}'; | ||
118 | }); | 117 | }); |
119 | }); | 118 | }); |
120 | }, | 119 | }, |
... | @@ -130,10 +129,20 @@ class PoemPublishState extends State<PoemPublish> { | ... | @@ -130,10 +129,20 @@ class PoemPublishState extends State<PoemPublish> { |
130 | size: 15.px, | 129 | size: 15.px, |
131 | ), | 130 | ), |
132 | Gaps.hGap5, | 131 | Gaps.hGap5, |
133 | - Text( | 132 | + Container( |
134 | - _address, | 133 | + padding: const EdgeInsets.fromLTRB(0, 0, 10, 10), |
135 | - style: const TextStyle(color: Colors.black45), | 134 | + width: MediaQuery.of(context).size.width * 0.8, |
136 | - ), | 135 | + alignment: Alignment.centerLeft, |
136 | + child: Column( | ||
137 | + children: <Widget>[ | ||
138 | + Text( | ||
139 | + _address, | ||
140 | + style: const TextStyle(color: Colors.black45), | ||
141 | + textAlign: TextAlign.left, | ||
142 | + ), | ||
143 | + ], | ||
144 | + ), | ||
145 | + ) | ||
137 | ], | 146 | ], |
138 | ), | 147 | ), |
139 | ), | 148 | ), |
... | @@ -209,12 +218,12 @@ class PoemPublishState extends State<PoemPublish> { | ... | @@ -209,12 +218,12 @@ class PoemPublishState extends State<PoemPublish> { |
209 | Gaps.vGap10, | 218 | Gaps.vGap10, |
210 | isUploading | 219 | isUploading |
211 | ? Padding( | 220 | ? Padding( |
212 | - padding: const EdgeInsets.all(20), | 221 | + padding: const EdgeInsets.all(20), |
213 | - child: ValueListenableBuilder<double>( | 222 | + child: ValueListenableBuilder<double>( |
214 | - builder: _buildWithValue, | 223 | + builder: _buildWithValue, |
215 | - valueListenable: _counter, | 224 | + valueListenable: _counter, |
216 | - ), | 225 | + ), |
217 | - ) | 226 | + ) |
218 | : Container(), | 227 | : Container(), |
219 | ], | 228 | ], |
220 | ), | 229 | ), |
... | @@ -224,10 +233,10 @@ class PoemPublishState extends State<PoemPublish> { | ... | @@ -224,10 +233,10 @@ class PoemPublishState extends State<PoemPublish> { |
224 | ), | 233 | ), |
225 | isPublishing | 234 | isPublishing |
226 | ? const Center( | 235 | ? const Center( |
227 | - child: CupertinoActivityIndicator( | 236 | + child: CupertinoActivityIndicator( |
228 | - radius: 16.0, | 237 | + radius: 16.0, |
229 | - ), | 238 | + ), |
230 | - ) | 239 | + ) |
231 | : Container(), | 240 | : Container(), |
232 | ], | 241 | ], |
233 | ), | 242 | ), | ... | ... |
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
... | @@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev | ... | @@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev |
15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. | 15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. |
16 | # Read more about iOS versioning at | 16 | # Read more about iOS versioning at |
17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html | 17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html |
18 | -version: 1.0.0+12 | 18 | +version: 1.0.0+16 |
19 | 19 | ||
20 | environment: | 20 | environment: |
21 | sdk: ">=2.16.2 <3.0.0" | 21 | sdk: ">=2.16.2 <3.0.0" |
... | @@ -101,11 +101,13 @@ dependencies: | ... | @@ -101,11 +101,13 @@ dependencies: |
101 | 101 | ||
102 | # A Dart timer that can be paused, resumed and reset. | 102 | # A Dart timer that can be paused, resumed and reset. |
103 | pausable_timer: ^1.0.0+3 | 103 | pausable_timer: ^1.0.0+3 |
104 | + | ||
105 | + flutter_easyloading: ^3.0.0 | ||
104 | email_validator: ^2.0.1 | 106 | email_validator: ^2.0.1 |
105 | 107 | ||
106 | getwidget: ^2.0.5 | 108 | getwidget: ^2.0.5 |
107 | sign_in_with_apple: ^4.0.0 | 109 | sign_in_with_apple: ^4.0.0 |
108 | - flutter_facebook_auth: ^4.3.4+2 | 110 | + flutter_facebook_auth: ^5.0.6 |
109 | flutter_signin_button: ^2.0.0 | 111 | flutter_signin_button: ^2.0.0 |
110 | twitter_login: ^4.2.3 | 112 | twitter_login: ^4.2.3 |
111 | 113 | ||
... | @@ -114,7 +116,10 @@ dependencies: | ... | @@ -114,7 +116,10 @@ dependencies: |
114 | animated_radial_menu: | 116 | animated_radial_menu: |
115 | path: plugins/animated_radial | 117 | path: plugins/animated_radial |
116 | 118 | ||
119 | + # 非官方库 暂时不删 | ||
117 | flutter_inapp_purchase: ^5.3.0 | 120 | flutter_inapp_purchase: ^5.3.0 |
121 | + # Flutter官方支付支持库 | ||
122 | + in_app_purchase: ^3.0.8 | ||
118 | 123 | ||
119 | jpush_flutter: ^2.2.9 | 124 | jpush_flutter: ^2.2.9 |
120 | share_plus: ^4.0.10 | 125 | share_plus: ^4.0.10 |
... | @@ -125,7 +130,9 @@ dependencies: | ... | @@ -125,7 +130,9 @@ dependencies: |
125 | google_fonts: ^3.0.1 | 130 | google_fonts: ^3.0.1 |
126 | wakelock: ^0.6.1+2 | 131 | wakelock: ^0.6.1+2 |
127 | location: ^4.4.0 | 132 | location: ^4.4.0 |
128 | - google_maps_flutter: ^2.1.10 | 133 | + # GoogleMap支持库 |
134 | + google_maps_flutter: ^2.2.1 | ||
135 | + http: ^0.13.5 | ||
129 | 136 | ||
130 | dependency_overrides: | 137 | dependency_overrides: |
131 | decimal: 1.5.0 | 138 | decimal: 1.5.0 | ... | ... |
-
Please register or login to post a comment