diff --git a/android/app/build.gradle b/android/app/build.gradle index 262f823b6..5b25c505c 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -47,11 +47,11 @@ android { applicationId "com.example.pilipala" // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. - minSdkVersion flutter.minSdkVersion + // minSdkVersion flutter.minSdkVersion targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName - minSdkVersion 17 + minSdkVersion 19 } buildTypes { diff --git a/android/app/src/main/res/drawable-hdpi-v26/ic_launcher_monochrome.png b/android/app/src/main/res/drawable-hdpi-v26/ic_launcher_monochrome.png new file mode 100644 index 000000000..df13b1283 Binary files /dev/null and b/android/app/src/main/res/drawable-hdpi-v26/ic_launcher_monochrome.png differ diff --git a/android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png b/android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..df13b1283 Binary files /dev/null and b/android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/drawable-mdpi-v26/ic_launcher_monochrome.png b/android/app/src/main/res/drawable-mdpi-v26/ic_launcher_monochrome.png new file mode 100644 index 000000000..8cdf48518 Binary files /dev/null and b/android/app/src/main/res/drawable-mdpi-v26/ic_launcher_monochrome.png differ diff --git a/android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png b/android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..8cdf48518 Binary files /dev/null and b/android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/drawable-xhdpi-v26/ic_launcher_monochrome.png b/android/app/src/main/res/drawable-xhdpi-v26/ic_launcher_monochrome.png new file mode 100644 index 000000000..1bdb8bb32 Binary files /dev/null and b/android/app/src/main/res/drawable-xhdpi-v26/ic_launcher_monochrome.png differ diff --git a/android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png b/android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..1bdb8bb32 Binary files /dev/null and b/android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/drawable-xxhdpi-v26/ic_launcher_monochrome.png b/android/app/src/main/res/drawable-xxhdpi-v26/ic_launcher_monochrome.png new file mode 100644 index 000000000..140baca63 Binary files /dev/null and b/android/app/src/main/res/drawable-xxhdpi-v26/ic_launcher_monochrome.png differ diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..140baca63 Binary files /dev/null and b/android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/drawable-xxxhdpi-v26/ic_launcher_monochrome.png b/android/app/src/main/res/drawable-xxxhdpi-v26/ic_launcher_monochrome.png new file mode 100644 index 000000000..b1b583954 Binary files /dev/null and b/android/app/src/main/res/drawable-xxxhdpi-v26/ic_launcher_monochrome.png differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..b1b583954 Binary files /dev/null and b/android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 000000000..f606c4d83 --- /dev/null +++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png index db77bb4b7..1cb4b0c49 100644 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png index 17987b79b..9eaf93928 100644 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png index 09d439148..6bf71b8f1 100644 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index d5f1c8d34..9c4d6c7ab 100644 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index 4d6372eeb..59f64433e 100644 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml new file mode 100644 index 000000000..ab9832824 --- /dev/null +++ b/android/app/src/main/res/values/colors.xml @@ -0,0 +1,4 @@ + + + #ffffff + \ No newline at end of file diff --git a/assets/images/logo/logo_android.png b/assets/images/logo/logo_android.png new file mode 100644 index 000000000..5e220fb45 Binary files /dev/null and b/assets/images/logo/logo_android.png differ diff --git a/assets/images/logo/logo_ios.png b/assets/images/logo/logo_ios.png new file mode 100644 index 000000000..a9992b4a5 Binary files /dev/null and b/assets/images/logo/logo_ios.png differ diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 8576a625c..c6b5ee31a 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -31,6 +31,10 @@ PODS: - FMDB (>= 2.7.5) - url_launcher_ios (0.0.1): - Flutter + - webview_cookie_manager (0.0.1): + - Flutter + - webview_flutter_wkwebview (0.0.1): + - Flutter DEPENDENCIES: - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) @@ -43,6 +47,8 @@ DEPENDENCIES: - share_plus (from `.symlinks/plugins/share_plus/ios`) - sqflite (from `.symlinks/plugins/sqflite/ios`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) + - webview_cookie_manager (from `.symlinks/plugins/webview_cookie_manager/ios`) + - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`) SPEC REPOS: trunk: @@ -71,6 +77,10 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/sqflite/ios" url_launcher_ios: :path: ".symlinks/plugins/url_launcher_ios/ios" + webview_cookie_manager: + :path: ".symlinks/plugins/webview_cookie_manager/ios" + webview_flutter_wkwebview: + :path: ".symlinks/plugins/webview_flutter_wkwebview/ios" SPEC CHECKSUMS: connectivity_plus: 413a8857dd5d9f1c399a39130850d02fe0feaf7e @@ -86,6 +96,8 @@ SPEC CHECKSUMS: share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68 sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4 + webview_cookie_manager: eaf920722b493bd0f7611b5484771ca53fed03f7 + webview_flutter_wkwebview: 2e2d318f21a5e036e2c3f26171342e95908bd60a PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png index dc9ada472..7f19eb8f9 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png index 7353c41ec..4b8fadf7c 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png index 797d452e4..bf7de64d7 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png index 6ed2d933e..59305c75b 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png index 4cd7b0099..b22a87060 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png index fe730945a..4eb2bd8da 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png index 321773cd8..8cfd292f3 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png index 797d452e4..bf7de64d7 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png index 502f463a9..fd0c7eab9 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png index 0ec303439..c2d7c2526 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png new file mode 100644 index 000000000..e1f6fde24 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png new file mode 100644 index 000000000..48ce80ad4 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png new file mode 100644 index 000000000..0b3f7b667 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png new file mode 100644 index 000000000..ebc40996b Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png index 0ec303439..c2d7c2526 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png index e9f5fea27..41f9638c5 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png new file mode 100644 index 000000000..5ba23fa61 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png new file mode 100644 index 000000000..ccfaddf50 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png index 84ac32ae7..59436734d 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png index 8953cba09..371d47633 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png index 0467bf12a..04d363004 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/lib/http/api.dart b/lib/http/api.dart index 068d7d24d..62e7047c3 100644 --- a/lib/http/api.dart +++ b/lib/http/api.dart @@ -5,18 +5,22 @@ class Api { static const String hotList = '/x/web-interface/popular'; // 视频详情 // 竖屏 https://api.bilibili.com/x/web-interface/view?aid=527403921 + // https://api.bilibili.com/x/web-interface/view/detail 获取视频超详细信息(web端) static const String videoIntro = '/x/web-interface/view'; // 视频详情页 相关视频 static const String relatedList = '/x/web-interface/archive/related'; - // 用户(被)关注数、投稿数 - // https://api.bilibili.com/x/relation/stat?vmid=697166795 - static const String userStat = '/x/relation/stat'; - // 评论列表 static const String replyList = '/x/v2/reply'; // 楼中楼 static const String replyReplyList = '/x/v2/reply/reply'; + + // 用户(被)关注数、投稿数 + // https://api.bilibili.com/x/relation/stat?vmid=697166795 + static const String userStat = '/x/relation/stat'; + + // 获取用户信息 + static const String userInfo = '/x/web-interface/nav'; } diff --git a/lib/http/user.dart b/lib/http/user.dart index ce3d4c431..f7f19a552 100644 --- a/lib/http/user.dart +++ b/lib/http/user.dart @@ -10,4 +10,13 @@ class UserHttp { return {'status': false}; } } + + static Future userInfo() async { + var res = await Request().get(Api.userInfo); + if (res.data['code'] == 0) { + return {'status': true, 'data': res.data['data']}; + } else { + return {'status': false}; + } + } } diff --git a/lib/main.dart b/lib/main.dart index 08059adf4..f572a7a77 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,3 +1,4 @@ +import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; import 'package:flutter/material.dart'; import 'package:dynamic_color/dynamic_color.dart'; @@ -23,18 +24,24 @@ class MyApp extends StatelessWidget { return GetMaterialApp( title: 'PiLiPaLa', theme: ThemeData( - colorScheme: lightDynamic ?? - ColorScheme.fromSeed( - seedColor: Colors.green, brightness: Brightness.light), - useMaterial3: true), + colorScheme: lightDynamic ?? + ColorScheme.fromSeed( + seedColor: Colors.green, + brightness: Brightness.light, + ), + useMaterial3: true, + ), darkTheme: ThemeData( - colorScheme: darkDynamic ?? - ColorScheme.fromSeed( - seedColor: Colors.green, brightness: Brightness.dark), - useMaterial3: true), + colorScheme: darkDynamic ?? + ColorScheme.fromSeed( + seedColor: Colors.green, + brightness: Brightness.dark, + ), + useMaterial3: true, + ), getPages: Routes.getPages, home: const MainApp(), - // home: const Scaffold(), + builder: FlutterSmartDialog.init(), ); }), ); diff --git a/lib/models/user/info.dart b/lib/models/user/info.dart new file mode 100644 index 000000000..9fa34bb78 --- /dev/null +++ b/lib/models/user/info.dart @@ -0,0 +1,7 @@ +class UserInfoData { + UserInfoData({ + this.isLogin, + }); + + bool? isLogin; +} diff --git a/lib/pages/home/widgets/app_bar.dart b/lib/pages/home/widgets/app_bar.dart index eb62ece2b..cd070d1d4 100644 --- a/lib/pages/home/widgets/app_bar.dart +++ b/lib/pages/home/widgets/app_bar.dart @@ -30,7 +30,7 @@ class HomeAppBar extends StatelessWidget { title: const Text( 'PiLiPaLa', style: TextStyle( - fontSize: 19, + fontSize: 20, fontWeight: FontWeight.bold, letterSpacing: 1, fontFamily: 'ArchivoNarrow', diff --git a/lib/pages/mine/controller.dart b/lib/pages/mine/controller.dart index e69de29bb..9e867c789 100644 --- a/lib/pages/mine/controller.dart +++ b/lib/pages/mine/controller.dart @@ -0,0 +1,14 @@ +import 'package:get/get.dart'; +import 'package:pilipala/http/user.dart'; + +class MineController extends GetxController { + @override + void onInit() { + super.onInit(); + // queryUserInfo(); + } + + Future queryUserInfo() async { + var res = await UserHttp.userInfo(); + } +} diff --git a/lib/pages/mine/view.dart b/lib/pages/mine/view.dart index c2ae65329..10c7ab36e 100644 --- a/lib/pages/mine/view.dart +++ b/lib/pages/mine/view.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:get/get.dart'; import 'package:pilipala/common/constants.dart'; +import 'controller.dart'; class MinePage extends StatefulWidget { const MinePage({super.key}); @@ -10,6 +12,8 @@ class MinePage extends StatefulWidget { } class _MinePageState extends State { + final MineController _mineController = Get.put(MineController()); + @override Widget build(BuildContext context) { return Scaffold( @@ -30,136 +34,161 @@ class _MinePageState extends State { const SizedBox(width: 10), ], ), - body: Padding( - padding: const EdgeInsets.only(left: 12, right: 12), + body: RefreshIndicator( + onRefresh: () async { + await Future.delayed(Duration(seconds: 2)); + }, child: Column( children: [ - Row( - children: [ - const SizedBox(width: 20), - ClipOval( - child: Container( - width: 75, - height: 75, - color: Theme.of(context).colorScheme.onInverseSurface, - child: Center( - child: Image.asset('assets/images/loading.png'), + InkWell( + onTap: () { + Get.toNamed( + '/webview', + parameters: { + 'url': + 'https://passport.bilibili.com/h5-app/passport/login', + 'type': 'login', + 'pageTitle': '登录bilibili', + }, + ); + }, + child: Padding( + padding: const EdgeInsets.only(top: 10, bottom: 10), + child: Row( + children: [ + const SizedBox(width: 20), + ClipOval( + child: Container( + width: 75, + height: 75, + color: Theme.of(context).colorScheme.onInverseSurface, + child: Center( + child: Image.asset('assets/images/loading.png'), + ), + ), ), - ), + const SizedBox(width: 14), + Text( + '点击登录', + style: Theme.of(context).textTheme.titleMedium, + ), + ], ), - const SizedBox(width: 14), - Text( - '点击登录', - style: Theme.of(context).textTheme.titleMedium, - ), - ], + ), + ), + const SizedBox(height: 10), + Padding( + padding: const EdgeInsets.only(left: 12, right: 12), + child: LayoutBuilder( + builder: (context, constraints) { + TextStyle style = TextStyle( + fontSize: + Theme.of(context).textTheme.titleMedium!.fontSize, + color: Theme.of(context).colorScheme.primary, + fontWeight: FontWeight.bold); + return SizedBox( + height: constraints.maxWidth / 3 * 0.6, + child: GridView.count( + primary: false, + padding: const EdgeInsets.all(0), + crossAxisCount: 3, + childAspectRatio: 1.67, + children: [ + InkWell( + onTap: () {}, + borderRadius: StyleString.mdRadius, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text('-', style: style), + const SizedBox(height: 8), + Text( + '动态', + style: Theme.of(context).textTheme.labelMedium, + ), + ], + ), + ), + InkWell( + onTap: () {}, + borderRadius: StyleString.mdRadius, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + '50', + style: style, + ), + const SizedBox(height: 8), + Text( + '关注', + style: Theme.of(context).textTheme.labelMedium, + ), + ], + ), + ), + InkWell( + onTap: () {}, + borderRadius: StyleString.mdRadius, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + '-', + style: style, + ), + const SizedBox(height: 8), + Text( + '粉丝', + style: Theme.of(context).textTheme.labelMedium, + ), + ], + ), + ), + ], + ), + ); + }, + ), ), const SizedBox(height: 20), - LayoutBuilder( - builder: (context, constraints) { - TextStyle style = TextStyle( - fontSize: Theme.of(context).textTheme.titleMedium!.fontSize, - color: Theme.of(context).colorScheme.primary, - fontWeight: FontWeight.bold); - return SizedBox( - height: constraints.maxWidth / 3 * 0.6, - child: GridView.count( - primary: false, - padding: const EdgeInsets.all(0), - crossAxisCount: 3, - childAspectRatio: 1.67, - children: [ - InkWell( - onTap: () {}, - borderRadius: StyleString.mdRadius, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text('-', style: style), - const SizedBox(height: 8), - Text( - '动态', - style: Theme.of(context).textTheme.labelMedium, - ), - ], + Padding( + padding: const EdgeInsets.only(left: 12, right: 12), + child: LayoutBuilder( + builder: (context, constraints) { + return SizedBox( + height: constraints.maxWidth / 4 * 0.8, + child: GridView.count( + primary: false, + padding: const EdgeInsets.all(0), + crossAxisCount: 4, + childAspectRatio: 1.25, + children: [ + ActionItem( + icon: const Icon(FontAwesomeIcons.download), + onTap: () => {}, + text: '离线缓存', ), - ), - InkWell( - onTap: () {}, - borderRadius: StyleString.mdRadius, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - '50', - style: style, - ), - const SizedBox(height: 8), - Text( - '关注', - style: Theme.of(context).textTheme.labelMedium, - ), - ], + ActionItem( + icon: const Icon(FontAwesomeIcons.clockRotateLeft), + onTap: () => {}, + text: '历史记录', ), - ), - InkWell( - onTap: () {}, - borderRadius: StyleString.mdRadius, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - '-', - style: style, - ), - const SizedBox(height: 8), - Text( - '粉丝', - style: Theme.of(context).textTheme.labelMedium, - ), - ], + ActionItem( + icon: const Icon(FontAwesomeIcons.star), + onTap: () => {}, + text: '我的收藏', ), - ), - ], - ), - ); - }, - ), - const SizedBox(height: 20), - LayoutBuilder( - builder: (context, constraints) { - return SizedBox( - height: constraints.maxWidth / 4 * 0.8, - child: GridView.count( - primary: false, - padding: const EdgeInsets.all(0), - crossAxisCount: 4, - childAspectRatio: 1.25, - children: [ - ActionItem( - icon: const Icon(FontAwesomeIcons.download), - onTap: () => {}, - text: '离线缓存', - ), - ActionItem( - icon: const Icon(FontAwesomeIcons.clockRotateLeft), - onTap: () => {}, - text: '历史记录', - ), - ActionItem( - icon: const Icon(FontAwesomeIcons.star), - onTap: () => {}, - text: '我的收藏', - ), - ActionItem( - icon: const Icon(FontAwesomeIcons.film), - onTap: () => {}, - text: '稍后再看', - ), - ], - ), - ); - }, + ActionItem( + icon: const Icon(FontAwesomeIcons.film), + onTap: () => {}, + text: '稍后再看', + ), + ], + ), + ); + }, + ), ), ], ), @@ -188,7 +217,10 @@ class ActionItem extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon(icon!.icon!), + Icon( + icon!.icon!, + color: Theme.of(context).colorScheme.outline, + ), const SizedBox(height: 8), Text( text!, diff --git a/lib/pages/video/detail/introduction/view.dart b/lib/pages/video/detail/introduction/view.dart index 8aa0d570a..623a26847 100644 --- a/lib/pages/video/detail/introduction/view.dart +++ b/lib/pages/video/detail/introduction/view.dart @@ -247,7 +247,7 @@ class _VideoInfoState extends State with TickerProviderStateMixin { children: const [ Icon( FontAwesomeIcons.lemon, - size: 17, + size: 15, ), SizedBox(width: 4), Text('关注'), @@ -334,10 +334,7 @@ class _VideoInfoState extends State with TickerProviderStateMixin { ? widget.videoDetail!.stat!.coin!.toString() : '-'), ActionItem( - icon: const Icon( - FontAwesomeIcons.heart, - size: 17, - ), + icon: const Icon(FontAwesomeIcons.star), onTap: () => {}, selectStatus: false, loadingStatus: widget.loadingStatus, @@ -386,10 +383,11 @@ class ActionItem extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(icon!.icon!, + size: 20, color: selectStatus ? Theme.of(context).primaryColor : Theme.of(context).colorScheme.outline), - const SizedBox(height: 2), + const SizedBox(height: 4), AnimatedOpacity( opacity: loadingStatus! ? 0 : 1, duration: const Duration(milliseconds: 200), diff --git a/lib/pages/video/detail/reply/widgets/reply_item.dart b/lib/pages/video/detail/reply/widgets/reply_item.dart index 3885d8f1d..8f0e3cb69 100644 --- a/lib/pages/video/detail/reply/widgets/reply_item.dart +++ b/lib/pages/video/detail/reply/widgets/reply_item.dart @@ -164,7 +164,7 @@ class ReplyItem extends StatelessWidget { TextSpan( children: [ if (replyItem!.isTop!) - WidgetSpan(child: UpTag(tagText: '置顶')), + WidgetSpan(child: UpTag(tagText: 'TOP')), buildContent(context, replyItem!.content!), ], ), @@ -200,6 +200,15 @@ class ReplyItem extends StatelessWidget { .labelMedium! .copyWith(color: Theme.of(context).colorScheme.outline), ), + if (replyItem!.replyControl != null && + replyItem!.replyControl!.location != null) + Text( + ' • ${replyItem!.replyControl!.location!}', + style: Theme.of(context) + .textTheme + .labelMedium! + .copyWith(color: Theme.of(context).colorScheme.outline), + ), const Spacer(), if (replyControl!.isUpTop!) Icon(Icons.favorite, color: Colors.red[400], size: 18), @@ -209,7 +218,7 @@ class ReplyItem extends StatelessWidget { child: Row( children: [ Icon( - Icons.thumb_up_alt_outlined, + FontAwesomeIcons.thumbsUp, size: 16, color: color, ), diff --git a/lib/pages/video/detail/view.dart b/lib/pages/video/detail/view.dart index 6747ea699..030ccc8e1 100644 --- a/lib/pages/video/detail/view.dart +++ b/lib/pages/video/detail/view.dart @@ -74,7 +74,7 @@ class _VideoDetailPageState extends State { body: Column( children: [ Container( - height: 50, + height: 45, decoration: BoxDecoration( border: Border( bottom: BorderSide( @@ -91,7 +91,6 @@ class _VideoDetailPageState extends State { margin: const EdgeInsets.only(left: 20), child: Obx( () => TabBar( - splashBorderRadius: BorderRadius.circular(6), dividerColor: Colors.transparent, tabs: videoDetailController.tabs .map((String name) => Tab(text: name)) diff --git a/lib/pages/webview/controller.dart b/lib/pages/webview/controller.dart new file mode 100644 index 000000000..593dd53f5 --- /dev/null +++ b/lib/pages/webview/controller.dart @@ -0,0 +1,69 @@ +import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; +import 'package:get/get.dart'; +import 'package:pilipala/http/constants.dart'; +import 'package:pilipala/http/user.dart'; +import 'package:pilipala/utils/cookie.dart'; +import 'package:webview_cookie_manager/webview_cookie_manager.dart'; +import 'package:webview_flutter/webview_flutter.dart'; + +class WebviewController extends GetxController { + String url = ''; + String type = ''; + String pageTitle = ''; + final WebViewController controller = WebViewController(); + + @override + void onInit() { + super.onInit(); + url = Get.parameters['url']!; + type = Get.parameters['type']!; + pageTitle = Get.parameters['pageTitle']!; + + webviewInit(); + } + + webviewInit() { + controller + ..setJavaScriptMode(JavaScriptMode.unrestricted) + ..setNavigationDelegate( + NavigationDelegate( + // 页面加载 + onProgress: (int progress) { + // Update loading bar. + }, + onPageStarted: (String url) {}, + // 加载完成 + onPageFinished: (String url) async { + if (url.startsWith( + 'https://passport.bilibili.com/web/sso/exchange_cookie') || + url.startsWith('https://m.bilibili.com/')) { + try { + var cookies = + await WebviewCookieManager().getCookies(HttpString.baseUrl); + var apiCookies = + await WebviewCookieManager().getCookies(HttpString.baseUrl); + await SetCookie.onSet(cookies, HttpString.baseUrl); + await SetCookie.onSet(apiCookies, HttpString.baseApiUrl); + var result = await UserHttp.userInfo(); + bool isLogin = result['data']['isLogin']; + if (isLogin) { + SmartDialog.showToast('登录成功'); + Get.back(); + } + } catch (e) { + print(e); + } + } + }, + onWebResourceError: (WebResourceError error) {}, + onNavigationRequest: (NavigationRequest request) { + if (request.url.startsWith('https://www.youtube.com/')) { + return NavigationDecision.prevent; + } + return NavigationDecision.navigate; + }, + ), + ) + ..loadRequest(Uri.parse(url)); + } +} diff --git a/lib/pages/webview/index.dart b/lib/pages/webview/index.dart new file mode 100644 index 000000000..17efad94a --- /dev/null +++ b/lib/pages/webview/index.dart @@ -0,0 +1,4 @@ +library webview; + +export './controller.dart'; +export './view.dart'; diff --git a/lib/pages/webview/view.dart b/lib/pages/webview/view.dart new file mode 100644 index 000000000..bee73de54 --- /dev/null +++ b/lib/pages/webview/view.dart @@ -0,0 +1,29 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'controller.dart'; +import 'package:webview_flutter/webview_flutter.dart'; + +class WebviewPage extends StatefulWidget { + const WebviewPage({super.key}); + + @override + State createState() => _WebviewPageState(); +} + +class _WebviewPageState extends State { + final WebviewController _webviewController = Get.put(WebviewController()); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + centerTitle: false, + title: Text( + _webviewController.pageTitle, + style: Theme.of(context).textTheme.titleMedium, + ), + ), + body: WebViewWidget(controller: _webviewController.controller), + ); + } +} diff --git a/lib/router/app_pages.dart b/lib/router/app_pages.dart index 0a0bd88bc..47cd8bbe5 100644 --- a/lib/router/app_pages.dart +++ b/lib/router/app_pages.dart @@ -3,6 +3,7 @@ import 'package:pilipala/pages/home/index.dart'; import 'package:pilipala/pages/hot/index.dart'; import 'package:pilipala/pages/preview/index.dart'; import 'package:pilipala/pages/video/detail/index.dart'; +import 'package:pilipala/pages/webview/index.dart'; class Routes { static final List getPages = [ @@ -13,6 +14,8 @@ class Routes { // 视频详情 GetPage(name: '/video', page: () => const VideoDetailPage()), // 图片预览 - GetPage(name: '/preview', page: () => const ImagePreview()) + GetPage(name: '/preview', page: () => const ImagePreview()), + // + GetPage(name: '/webview', page: () => const WebviewPage()) ]; } diff --git a/lib/utils/cookie.dart b/lib/utils/cookie.dart new file mode 100644 index 000000000..42a2cb5d2 --- /dev/null +++ b/lib/utils/cookie.dart @@ -0,0 +1,27 @@ +import 'dart:io'; +import 'package:cookie_jar/cookie_jar.dart'; +import 'package:pilipala/http/init.dart'; +import 'package:pilipala/utils/utils.dart'; +import 'package:dio_cookie_manager/dio_cookie_manager.dart'; + +class SetCookie { + static onSet(List cookiesList, String url) async { + // domain url + List jarCookies = []; + if (cookiesList.isNotEmpty) { + for (var i in cookiesList) { + Cookie jarCookie = Cookie(i.name, i.value); + jarCookies.add(jarCookie); + } + } + String cookiePath = await Utils.getCookiePath(); + PersistCookieJar cookieJar = PersistCookieJar( + ignoreExpires: true, + storage: FileStorage(cookiePath), + ); + await cookieJar.saveFromResponse(Uri.parse(url), jarCookies); + // 重新设置 cookie + Request.setCookie(); + return true; + } +} diff --git a/pubspec.lock b/pubspec.lock index 36af3acfc..78a4654c1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -262,6 +262,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.1" + flutter_smart_dialog: + dependency: "direct main" + description: + name: flutter_smart_dialog + sha256: da7ed8fe78e301e3c2cdaa533d13ed3edcf1853c1ba1a7383b481739569f7b2a + url: "https://pub.dev" + source: hosted + version: "4.9.0+6" flutter_test: dependency: "direct dev" description: flutter @@ -725,6 +733,46 @@ packages: url: "https://pub.dev" source: hosted version: "0.3.3" + webview_cookie_manager: + dependency: "direct main" + description: + name: webview_cookie_manager + sha256: "425a9feac5cd2cb62a71da3dda5ac2eaf9ece5481ee8d79f3868dc5ba8223ad3" + url: "https://pub.dev" + source: hosted + version: "2.0.6" + webview_flutter: + dependency: "direct main" + description: + name: webview_flutter + sha256: "1a37bdbaaf5fbe09ad8579ab09ecfd473284ce482f900b5aea27cf834386a567" + url: "https://pub.dev" + source: hosted + version: "4.2.0" + webview_flutter_android: + dependency: transitive + description: + name: webview_flutter_android + sha256: "1acea8def62592123e2fbbca164ed8681a98a890bdcbb88f916d5b4a22687759" + url: "https://pub.dev" + source: hosted + version: "3.7.0" + webview_flutter_platform_interface: + dependency: transitive + description: + name: webview_flutter_platform_interface + sha256: "78715dc442b7849dbde74e92bb67de1cecf5addf95531c5fb474e72f5fe9a507" + url: "https://pub.dev" + source: hosted + version: "2.3.0" + webview_flutter_wkwebview: + dependency: transitive + description: + name: webview_flutter_wkwebview + sha256: "61f33512810bf1ee9ac89761a4b02663ff64e8227b7dc80654642acd660fd49d" + url: "https://pub.dev" + source: hosted + version: "3.4.2" win32: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 8251e5789..7374bbf5a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -63,9 +63,13 @@ dependencies: # webView url_launcher: ^6.1.9 flutter_inappwebview: 5.4.4 + webview_cookie_manager: ^2.0.6 + webview_flutter: ^4.2.0 extended_nested_scroll_view: ^6.0.0 font_awesome_flutter: ^10.4.0 + # toast + flutter_smart_dialog: ^4.9.0+6 dev_dependencies: flutter_test: @@ -77,6 +81,21 @@ dev_dependencies: # package. See that file for information about deactivating specific lint # rules and activating additional ones. flutter_lints: ^2.0.0 + # flutter_launcher_icons: + # git: + # url: https://github.com/nvi9/flutter_launcher_icons.git + # ref: e045d40 + +flutter_icons: + android: true + ios: true + remove_alpha_ios: false + image_path: assets/images/logo/logo_android.png + image_path_android: assets/images/logo/logo_android.png + image_path_ios: assets/images/logo/logo_ios.png + adaptive_icon_background: "#ffffff" + adaptive_icon_foreground: assets/images/logo/logo_android.png + adaptive_icon_monochrome: assets/images/logo/logo_android.png # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec