Showing
6 changed files
with
78 additions
and
138 deletions
... | @@ -41,18 +41,6 @@ | ... | @@ -41,18 +41,6 @@ |
41 | android:name="com.yalantis.ucrop.UCropActivity" | 41 | android:name="com.yalantis.ucrop.UCropActivity" |
42 | android:screenOrientation="portrait" | 42 | android:screenOrientation="portrait" |
43 | android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> | 43 | android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> |
44 | - <activity | ||
45 | - android:name="com.braintreepayments.api.BraintreeBrowserSwitchActivity" | ||
46 | - android:exported="true" | ||
47 | - android:launchMode="singleTask"> | ||
48 | - <intent-filter> | ||
49 | - <action android:name="android.intent.action.VIEW" /> | ||
50 | - | ||
51 | - <category android:name="android.intent.category.DEFAULT" /> | ||
52 | - <category android:name="android.intent.category.BROWSABLE" /> | ||
53 | - | ||
54 | - </intent-filter> | ||
55 | - </activity> | ||
56 | 44 | ||
57 | <meta-data | 45 | <meta-data |
58 | android:name="flutterEmbedding" | 46 | android:name="flutterEmbedding" |
... | @@ -63,17 +51,6 @@ | ... | @@ -63,17 +51,6 @@ |
63 | <meta-data | 51 | <meta-data |
64 | android:name="com.facebook.sdk.ClientToken" | 52 | android:name="com.facebook.sdk.ClientToken" |
65 | android:value="@string/facebook_client_token" /> | 53 | android:value="@string/facebook_client_token" /> |
66 | - | ||
67 | - <provider | ||
68 | - android:name="androidx.core.content.FileProvider" | ||
69 | - android:authorities="${applicationId}.com.shekarmudaliyar.social_share" | ||
70 | - android:exported="false" | ||
71 | - android:grantUriPermissions="true" | ||
72 | - tools:replace="android:authorities"> | ||
73 | - <meta-data | ||
74 | - android:name="android.support.FILE_PROVIDER_PATHS" | ||
75 | - android:resource="@xml/filepaths" /> | ||
76 | - </provider> | ||
77 | </application> | 54 | </application> |
78 | 55 | ||
79 | <queries> | 56 | <queries> |
... | @@ -87,4 +64,8 @@ | ... | @@ -87,4 +64,8 @@ |
87 | 64 | ||
88 | <uses-permission android:name="com.android.vending.BILLING" /> | 65 | <uses-permission android:name="com.android.vending.BILLING" /> |
89 | <uses-permission android:name="android.permission.INTERNET" /> | 66 | <uses-permission android:name="android.permission.INTERNET" /> |
67 | + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> | ||
68 | + <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> | ||
69 | + <uses-permission android:name="android.permission.CAMERA" /> | ||
70 | + <uses-permission android:name="android.permission.RECORD_AUDIO" /> | ||
90 | </manifest> | 71 | </manifest> | ... | ... |
1 | import 'dart:async'; | 1 | import 'dart:async'; |
2 | -import 'dart:io'; | ||
3 | -import 'dart:typed_data'; | ||
4 | - | ||
5 | import 'package:Parlando/account/account_router.dart'; | 2 | import 'package:Parlando/account/account_router.dart'; |
6 | import 'package:Parlando/events/trans_event.dart'; | 3 | import 'package:Parlando/events/trans_event.dart'; |
7 | import 'package:Parlando/home/models/home_entity.dart'; | 4 | import 'package:Parlando/home/models/home_entity.dart'; |
... | @@ -10,6 +7,7 @@ import 'package:Parlando/net/dio_utils.dart'; | ... | @@ -10,6 +7,7 @@ import 'package:Parlando/net/dio_utils.dart'; |
10 | import 'package:Parlando/net/http_api.dart'; | 7 | import 'package:Parlando/net/http_api.dart'; |
11 | import 'package:Parlando/util/toast_utils.dart'; | 8 | import 'package:Parlando/util/toast_utils.dart'; |
12 | import 'package:animated_radial_menu/animated_radial_menu.dart'; | 9 | import 'package:animated_radial_menu/animated_radial_menu.dart'; |
10 | +import 'package:dio/dio.dart'; | ||
13 | import 'package:flutter/material.dart'; | 11 | import 'package:flutter/material.dart'; |
14 | import 'package:Parlando/category/category_router.dart'; | 12 | import 'package:Parlando/category/category_router.dart'; |
15 | import 'package:Parlando/poem/poem_router.dart'; | 13 | import 'package:Parlando/poem/poem_router.dart'; |
... | @@ -25,12 +23,12 @@ import 'package:Parlando/tiktok/widgets/tiktok_video_button_column.dart'; | ... | @@ -25,12 +23,12 @@ import 'package:Parlando/tiktok/widgets/tiktok_video_button_column.dart'; |
25 | import 'package:Parlando/tiktok/widgets/tiktok_video_poem.dart'; | 23 | import 'package:Parlando/tiktok/widgets/tiktok_video_poem.dart'; |
26 | import 'package:Parlando/widgets/bars/home_types_bar.dart'; | 24 | import 'package:Parlando/widgets/bars/home_types_bar.dart'; |
27 | import 'package:Parlando/widgets/my_app_bar.dart'; | 25 | import 'package:Parlando/widgets/my_app_bar.dart'; |
28 | -import 'package:flutter/services.dart'; | 26 | +import 'package:flutter_easy_permission/easy_permissions.dart'; |
29 | import 'package:getwidget/getwidget.dart'; | 27 | import 'package:getwidget/getwidget.dart'; |
28 | +import 'package:image_gallery_saver/image_gallery_saver.dart'; | ||
30 | import 'package:path_provider/path_provider.dart'; | 29 | import 'package:path_provider/path_provider.dart'; |
31 | import 'package:provider/provider.dart'; | 30 | import 'package:provider/provider.dart'; |
32 | -import 'package:screenshot/screenshot.dart'; | 31 | +import 'package:share_plus/share_plus.dart'; |
33 | -import 'package:social_share/social_share.dart'; | ||
34 | import 'package:video_player/video_player.dart'; | 32 | import 'package:video_player/video_player.dart'; |
35 | 33 | ||
36 | import 'poem_detail.dart'; | 34 | import 'poem_detail.dart'; |
... | @@ -60,6 +58,22 @@ class PoemPageState extends State<PoemPage> with WidgetsBindingObserver { | ... | @@ -60,6 +58,22 @@ class PoemPageState extends State<PoemPage> with WidgetsBindingObserver { |
60 | 58 | ||
61 | bool isFav = false; | 59 | bool isFav = false; |
62 | bool isPraise = false; | 60 | bool isPraise = false; |
61 | + bool isSharing = false; | ||
62 | + | ||
63 | + static const permissions = [ | ||
64 | + Permissions.CAMERA, | ||
65 | + Permissions.READ_EXTERNAL_STORAGE, | ||
66 | + Permissions.RECORD_AUDIO, | ||
67 | + Permissions.WRITE_EXTERNAL_STORAGE | ||
68 | + ]; | ||
69 | + | ||
70 | + static const permissionGroup = [ | ||
71 | + PermissionGroup.Camera, | ||
72 | + PermissionGroup.Camera, | ||
73 | + PermissionGroup.Microphone | ||
74 | + ]; | ||
75 | + | ||
76 | + late FlutterEasyPermission _easyPermission; | ||
63 | 77 | ||
64 | @override | 78 | @override |
65 | void didChangeAppLifecycleState(AppLifecycleState state) async { | 79 | void didChangeAppLifecycleState(AppLifecycleState state) async { |
... | @@ -73,12 +87,41 @@ class PoemPageState extends State<PoemPage> with WidgetsBindingObserver { | ... | @@ -73,12 +87,41 @@ class PoemPageState extends State<PoemPage> with WidgetsBindingObserver { |
73 | WidgetsBinding.instance.removeObserver(this); | 87 | WidgetsBinding.instance.removeObserver(this); |
74 | _videoListController.currentPlayer.pause(); | 88 | _videoListController.currentPlayer.pause(); |
75 | bus.cancel(); | 89 | bus.cancel(); |
90 | + _easyPermission.dispose(); | ||
76 | super.dispose(); | 91 | super.dispose(); |
77 | } | 92 | } |
78 | 93 | ||
79 | @override | 94 | @override |
80 | void initState() { | 95 | void initState() { |
81 | WidgetsBinding.instance.addObserver(this); | 96 | WidgetsBinding.instance.addObserver(this); |
97 | + | ||
98 | + FlutterEasyPermission.has(perms: permissions, permsGroup: permissionGroup) | ||
99 | + .then((value) { | ||
100 | + if (value) { | ||
101 | + FlutterEasyPermission.request( | ||
102 | + perms: permissions, | ||
103 | + permsGroup: permissionGroup, | ||
104 | + rationale: "需要使用如下权限"); | ||
105 | + } | ||
106 | + }); | ||
107 | + _easyPermission = FlutterEasyPermission() | ||
108 | + ..addPermissionCallback(onGranted: (requestCode, perms, perm) { | ||
109 | + debugPrint("android获得授权:$perms"); | ||
110 | + debugPrint("iOS获得授权:$perm"); | ||
111 | + }, onDenied: (requestCode, perms, perm, isPermanent) { | ||
112 | + if (isPermanent) { | ||
113 | + FlutterEasyPermission.showAppSettingsDialog(title: "Camera"); | ||
114 | + } else { | ||
115 | + debugPrint("android授权失败:$perms"); | ||
116 | + debugPrint("iOS授权失败:$perm"); | ||
117 | + } | ||
118 | + }, onSettingsReturned: () { | ||
119 | + FlutterEasyPermission.has(perms: permissions, permsGroup: []).then( | ||
120 | + (value) => value | ||
121 | + ? debugPrint("已获得授权:$permissions") | ||
122 | + : debugPrint("未获得授权:$permissions")); | ||
123 | + }); | ||
124 | + | ||
82 | isLoading = true; | 125 | isLoading = true; |
83 | DioUtils.instance.asyncRequestNetwork<HomeEntity>( | 126 | DioUtils.instance.asyncRequestNetwork<HomeEntity>( |
84 | Method.get, | 127 | Method.get, |
... | @@ -165,7 +208,6 @@ class PoemPageState extends State<PoemPage> with WidgetsBindingObserver { | ... | @@ -165,7 +208,6 @@ class PoemPageState extends State<PoemPage> with WidgetsBindingObserver { |
165 | Widget? currentPage; | 208 | Widget? currentPage; |
166 | double a = MediaQuery.of(context).size.aspectRatio; | 209 | double a = MediaQuery.of(context).size.aspectRatio; |
167 | bool hasBottomPadding = a < 0.55; | 210 | bool hasBottomPadding = a < 0.55; |
168 | - ScreenshotController screenshotController = ScreenshotController(); | ||
169 | var detailPage = PoemDetailPage( | 211 | var detailPage = PoemDetailPage( |
170 | onPop: () { | 212 | onPop: () { |
171 | tkController.animateToMiddle(); | 213 | tkController.animateToMiddle(); |
... | @@ -270,7 +312,21 @@ class PoemPageState extends State<PoemPage> with WidgetsBindingObserver { | ... | @@ -270,7 +312,21 @@ class PoemPageState extends State<PoemPage> with WidgetsBindingObserver { |
270 | ); | 312 | ); |
271 | }, | 313 | }, |
272 | onShare: () async { | 314 | onShare: () async { |
273 | - showShareView(context); | 315 | + isSharing = true; |
316 | + setState(() {}); | ||
317 | + var appDocDir = await getTemporaryDirectory(); | ||
318 | + String savePath = "${appDocDir.path}/temp.mp4"; | ||
319 | + await Dio().download( | ||
320 | + "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4", | ||
321 | + savePath); | ||
322 | + final result = | ||
323 | + await ImageGallerySaver.saveFile(savePath); | ||
324 | + print(result); | ||
325 | + isSharing = false; | ||
326 | + setState(() {}); | ||
327 | + await Share.shareFiles( | ||
328 | + ["/media/external/video/media/79"], | ||
329 | + text: '一言一世界 临境不蹉跎'); | ||
274 | }, | 330 | }, |
275 | ); | 331 | ); |
276 | Widget poem = TikTokVidePoem( | 332 | Widget poem = TikTokVidePoem( |
... | @@ -400,106 +456,6 @@ class PoemPageState extends State<PoemPage> with WidgetsBindingObserver { | ... | @@ -400,106 +456,6 @@ class PoemPageState extends State<PoemPage> with WidgetsBindingObserver { |
400 | ); | 456 | ); |
401 | } | 457 | } |
402 | 458 | ||
403 | - static showShareView(BuildContext context) { | ||
404 | - final List buttonTitles = [ | ||
405 | - "Twitter", | ||
406 | - "Facebook", | ||
407 | - ]; | ||
408 | - final List buttonImages = [ | ||
409 | - "jiguang_socialize_twitter.png", | ||
410 | - "jiguang_socialize_facebook.png", | ||
411 | - ]; | ||
412 | - showModalBottomSheet( | ||
413 | - context: context, | ||
414 | - backgroundColor: Colors.white.withAlpha(0), | ||
415 | - elevation: 2, | ||
416 | - builder: (BuildContext context) { | ||
417 | - return ClipRRect( | ||
418 | - borderRadius: const BorderRadius.only( | ||
419 | - topLeft: Radius.circular(10), topRight: Radius.circular(10)), | ||
420 | - child: Container( | ||
421 | - width: double.infinity, | ||
422 | - height: 180, | ||
423 | - color: const Color.fromRGBO(255, 255, 255, 1), | ||
424 | - child: Stack( | ||
425 | - children: [ | ||
426 | - Padding( | ||
427 | - padding: | ||
428 | - const EdgeInsets.only(top: 14, left: 15, right: 15), | ||
429 | - child: Row( | ||
430 | - mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||
431 | - children: const [ | ||
432 | - Text( | ||
433 | - "分享到", | ||
434 | - style: TextStyle( | ||
435 | - fontSize: 20, | ||
436 | - fontWeight: FontWeight.bold, | ||
437 | - color: Color.fromRGBO(51, 51, 51, 1)), | ||
438 | - ), | ||
439 | - ], | ||
440 | - )), | ||
441 | - Padding( | ||
442 | - padding: const EdgeInsets.only(left: 0, right: 0, top: 0), | ||
443 | - child: Row( | ||
444 | - mainAxisAlignment: MainAxisAlignment.spaceEvenly, | ||
445 | - children: List.generate(buttonTitles.length, (index) { | ||
446 | - return Container( | ||
447 | - child: buttonWidget(context, buttonTitles[index], | ||
448 | - buttonImages[index], index), | ||
449 | - ); | ||
450 | - }).toList(), | ||
451 | - ), | ||
452 | - ) | ||
453 | - ], | ||
454 | - ), | ||
455 | - ), | ||
456 | - ); | ||
457 | - }); | ||
458 | - } | ||
459 | - | ||
460 | - static buttonWidget( | ||
461 | - BuildContext context, String title, String imageName, int index) { | ||
462 | - return GestureDetector( | ||
463 | - onTap: () { | ||
464 | - switch (index) { | ||
465 | - case 0: | ||
466 | - dismiss(context); | ||
467 | - SocialShare.shareTwitter( | ||
468 | - "This is Social Share twitter example", | ||
469 | - hashtags: ["hello", "world", "foo", "bar"], | ||
470 | - url: "https://google.com/#/hello", | ||
471 | - trailingText: "\nhello", | ||
472 | - ).then((data) { | ||
473 | - print(data); | ||
474 | - }); | ||
475 | - break; | ||
476 | - case 1: //Facebook | ||
477 | - print("朋友圈"); | ||
478 | - dismiss(context); | ||
479 | - break; | ||
480 | - default: | ||
481 | - break; | ||
482 | - } | ||
483 | - }, | ||
484 | - child: Column( | ||
485 | - mainAxisAlignment: MainAxisAlignment.center, | ||
486 | - children: [ | ||
487 | - Image.asset( | ||
488 | - "assets/images/share/$imageName", | ||
489 | - height: 64, | ||
490 | - width: 64, | ||
491 | - ), | ||
492 | - Padding( | ||
493 | - padding: const EdgeInsets.only(top: 5), | ||
494 | - child: Text(title, | ||
495 | - style: const TextStyle( | ||
496 | - fontSize: 12, color: Color.fromRGBO(51, 51, 51, 1))), | ||
497 | - ) | ||
498 | - ], | ||
499 | - ), | ||
500 | - ); | ||
501 | - } | ||
502 | - | ||
503 | static dismiss(BuildContext context) { | 459 | static dismiss(BuildContext context) { |
504 | Navigator.pop(context); | 460 | Navigator.pop(context); |
505 | } | 461 | } | ... | ... |
1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
2 | import 'package:Parlando/tiktok/style/style.dart'; | 2 | import 'package:Parlando/tiktok/style/style.dart'; |
3 | +import 'package:getwidget/getwidget.dart'; | ||
3 | import 'package:tapped/tapped.dart'; | 4 | import 'package:tapped/tapped.dart'; |
4 | 5 | ||
5 | import 'package:Parlando/extension/int_extension.dart'; | 6 | import 'package:Parlando/extension/int_extension.dart'; |
... | @@ -8,6 +9,7 @@ class TikTokButtonColumn extends StatelessWidget { | ... | @@ -8,6 +9,7 @@ class TikTokButtonColumn extends StatelessWidget { |
8 | final double? bottomPadding; | 9 | final double? bottomPadding; |
9 | final bool isPraise; | 10 | final bool isPraise; |
10 | final bool isCollect; | 11 | final bool isCollect; |
12 | + final bool isSharing; | ||
11 | final Function? onPraise; | 13 | final Function? onPraise; |
12 | final Function? onCollect; | 14 | final Function? onCollect; |
13 | final Function? onShare; | 15 | final Function? onShare; |
... | @@ -22,6 +24,7 @@ class TikTokButtonColumn extends StatelessWidget { | ... | @@ -22,6 +24,7 @@ class TikTokButtonColumn extends StatelessWidget { |
22 | this.isPraise = false, | 24 | this.isPraise = false, |
23 | this.isCollect = false, | 25 | this.isCollect = false, |
24 | this.onAvatar, | 26 | this.onAvatar, |
27 | + this.isSharing = false, | ||
25 | }) : super(key: key); | 28 | }) : super(key: key); |
26 | 29 | ||
27 | @override | 30 | @override |
... | @@ -44,7 +47,9 @@ class TikTokButtonColumn extends StatelessWidget { | ... | @@ -44,7 +47,9 @@ class TikTokButtonColumn extends StatelessWidget { |
44 | onCollect: onCollect, | 47 | onCollect: onCollect, |
45 | isCollect: isCollect, | 48 | isCollect: isCollect, |
46 | ), | 49 | ), |
47 | - _IconButton( | 50 | + isSharing |
51 | + ? const GFLoader() | ||
52 | + : _IconButton( | ||
48 | icon: IconToText(Icons.share, size: 20.px), | 53 | icon: IconToText(Icons.share, size: 20.px), |
49 | text: '分享', | 54 | text: '分享', |
50 | onTap: onShare, | 55 | onTap: onShare, | ... | ... |
... | @@ -28,9 +28,7 @@ class HomeTypesHeader extends StatelessWidget { | ... | @@ -28,9 +28,7 @@ class HomeTypesHeader extends StatelessWidget { |
28 | //交叉轴的布局方式,对于column来说就是水平方向的布局方式 | 28 | //交叉轴的布局方式,对于column来说就是水平方向的布局方式 |
29 | crossAxisAlignment: CrossAxisAlignment.center, | 29 | crossAxisAlignment: CrossAxisAlignment.center, |
30 | children: <Widget>[ | 30 | children: <Widget>[ |
31 | - SizedBox( | 31 | + TextButton( |
32 | - width: 60.0, | ||
33 | - child: TextButton( | ||
34 | onPressed: () => funcLeft!(), | 32 | onPressed: () => funcLeft!(), |
35 | child: Text( | 33 | child: Text( |
36 | "临境", | 34 | "临境", |
... | @@ -40,7 +38,6 @@ class HomeTypesHeader extends StatelessWidget { | ... | @@ -40,7 +38,6 @@ class HomeTypesHeader extends StatelessWidget { |
40 | ), | 38 | ), |
41 | ), | 39 | ), |
42 | ), | 40 | ), |
43 | - ), | ||
44 | VerticalDivider( | 41 | VerticalDivider( |
45 | color: color ?? Colors.white, | 42 | color: color ?? Colors.white, |
46 | width: 1.0, | 43 | width: 1.0, | ... | ... |
This diff is collapsed. Click to expand it.
... | @@ -119,9 +119,10 @@ dependencies: | ... | @@ -119,9 +119,10 @@ dependencies: |
119 | flutter_inapp_purchase: ^5.3.0 | 119 | flutter_inapp_purchase: ^5.3.0 |
120 | 120 | ||
121 | jpush_flutter: ^2.2.9 | 121 | jpush_flutter: ^2.2.9 |
122 | - social_share: ^2.2.1 | 122 | + share_plus: ^4.0.10 |
123 | - screenshot: ^1.2.3 | 123 | + image_gallery_saver: ^1.7.1 |
124 | 124 | ||
125 | + flutter_easy_permission: ^1.1.2 | ||
125 | dependency_overrides: | 126 | dependency_overrides: |
126 | decimal: 1.5.0 | 127 | decimal: 1.5.0 |
127 | 128 | ... | ... |
-
Please register or login to post a comment