diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index c948bc8f..46b34c20 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -12,7 +12,6 @@
-
@@ -20,7 +19,6 @@
"android.support.customtabs.action.CustomTabsService" />
-
@@ -34,7 +32,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
\ No newline at end of file
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index 86cb7071..27baf9e5 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -1,8 +1,6 @@
PODS:
- app_links (0.0.2):
- Flutter
- - appscheme (1.0.4):
- - Flutter
- audio_service (0.0.1):
- Flutter
- audio_session (0.0.1):
@@ -71,7 +69,6 @@ PODS:
DEPENDENCIES:
- app_links (from `.symlinks/plugins/app_links/ios`)
- - appscheme (from `.symlinks/plugins/appscheme/ios`)
- audio_service (from `.symlinks/plugins/audio_service/ios`)
- audio_session (from `.symlinks/plugins/audio_session/ios`)
- auto_orientation (from `.symlinks/plugins/auto_orientation/ios`)
@@ -110,8 +107,6 @@ SPEC REPOS:
EXTERNAL SOURCES:
app_links:
:path: ".symlinks/plugins/app_links/ios"
- appscheme:
- :path: ".symlinks/plugins/appscheme/ios"
audio_service:
:path: ".symlinks/plugins/audio_service/ios"
audio_session:
@@ -171,7 +166,6 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
app_links: e7a6750a915a9e161c58d91bc610e8cd1d4d0ad0
- appscheme: b1c3f8862331cb20430cf9e0e4af85dbc1572ad8
audio_service: f509d65da41b9521a61f1c404dd58651f265a567
audio_session: 4f3e461722055d21515cf3261b64c973c062f345
auto_orientation: 102ed811a5938d52c86520ddd7ecd3a126b5d39d
diff --git a/lib/common/pages_bottom_sheet.dart b/lib/common/pages_bottom_sheet.dart
index 1e88e863..e4f23608 100644
--- a/lib/common/pages_bottom_sheet.dart
+++ b/lib/common/pages_bottom_sheet.dart
@@ -105,7 +105,8 @@ class _PagesBottomSheetState extends State
List? _listScrollControllerList;
final String heroTag = Get.arguments['heroTag'];
VideoDetailController? _videoDetailController;
- late RxInt isSubscribe = (-1).obs;
+ RxInt isSubscribe = (-1).obs;
+ bool isVisible = false;
@override
void initState() {
@@ -224,6 +225,13 @@ class _PagesBottomSheetState extends State
}
}
+ // 更改展开状态
+ void _changeVisible() {
+ setState(() {
+ isVisible = !isVisible;
+ });
+ }
+
@override
void dispose() {
try {
@@ -255,7 +263,9 @@ class _PagesBottomSheetState extends State
UgcSeasonBuild(
ugcSeason: widget.ugcSeason!,
isSubscribe: isSubscribe,
+ isVisible: isVisible,
changeFucCall: _changeSubscribeStatus,
+ changeVisible: _changeVisible,
),
],
Expanded(
@@ -325,19 +335,23 @@ class _PagesBottomSheetState extends State
Widget buildTabBar() {
return Column(
children: [
- TabBar(
- controller: tabController,
- isScrollable: true,
- indicatorSize: TabBarIndicatorSize.label,
- tabAlignment: TabAlignment.start,
- splashBorderRadius: BorderRadius.circular(4),
- tabs: [
- ...widget.ugcSeason!.sections!.map((SectionItem section) {
- return Tab(
- text: section.title,
- );
- }).toList()
- ],
+ // 背景色
+ Container(
+ color: Theme.of(context).colorScheme.surface,
+ child: TabBar(
+ controller: tabController,
+ isScrollable: true,
+ indicatorSize: TabBarIndicatorSize.label,
+ tabAlignment: TabAlignment.start,
+ splashBorderRadius: BorderRadius.circular(4),
+ tabs: [
+ ...widget.ugcSeason!.sections!.map((SectionItem section) {
+ return Tab(
+ text: section.title,
+ );
+ }).toList()
+ ],
+ ),
),
Expanded(
child: TabBarView(
@@ -394,17 +408,29 @@ class TitleBar extends StatelessWidget {
toolbarHeight: 45,
automaticallyImplyLeading: false,
centerTitle: false,
- title: Text(
- title,
- style: Theme.of(context).textTheme.titleMedium,
+ elevation: 1,
+ scrolledUnderElevation: 1,
+ title: Padding(
+ padding: const EdgeInsets.only(left: 12),
+ child: Text(
+ title,
+ style: Theme.of(context).textTheme.titleMedium,
+ ),
),
actions: !isFullScreen
? [
- IconButton(
- icon: const Icon(Icons.close, size: 20),
- onPressed: () => Navigator.pop(context),
+ SizedBox(
+ width: 35,
+ height: 35,
+ child: IconButton(
+ icon: const Icon(Icons.close, size: 20),
+ style: ButtonStyle(
+ padding: MaterialStateProperty.all(EdgeInsets.zero),
+ ),
+ onPressed: () => Navigator.pop(context),
+ ),
),
- const SizedBox(width: 14),
+ const SizedBox(width: 8),
]
: null,
);
@@ -465,7 +491,7 @@ class EpisodeListItem extends StatelessWidget {
dense: false,
leading: isCurrentIndex
? Image.asset(
- 'assets/images/live.gif',
+ 'assets/images/live.png',
color: primary,
height: 12,
)
@@ -678,95 +704,133 @@ class EpisodeGridItem extends StatelessWidget {
class UgcSeasonBuild extends StatelessWidget {
final UgcSeason ugcSeason;
final RxInt isSubscribe;
+ final bool isVisible;
final Function changeFucCall;
+ final Function changeVisible;
const UgcSeasonBuild({
Key? key,
required this.ugcSeason,
required this.isSubscribe,
+ required this.isVisible,
required this.changeFucCall,
+ required this.changeVisible,
}) : super(key: key);
@override
Widget build(BuildContext context) {
- final ThemeData t = Theme.of(context);
- final Color outline = t.colorScheme.outline;
- return Container(
- padding: const EdgeInsets.fromLTRB(12, 0, 12, 0),
- color: Theme.of(context).colorScheme.surface,
- child: Column(
- mainAxisAlignment: MainAxisAlignment.start,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Divider(
- height: 1,
- thickness: 1,
- color: Theme.of(context).dividerColor.withOpacity(0.1),
- ),
- const SizedBox(height: 10),
- Text(
- '合集:${ugcSeason.title}',
- style: Theme.of(context).textTheme.titleMedium,
- overflow: TextOverflow.ellipsis,
- ),
- if (ugcSeason.intro != null && ugcSeason.intro != '') ...[
- const SizedBox(height: 4),
- Row(
+ final ThemeData theme = Theme.of(context);
+ final Color outline = theme.colorScheme.outline;
+ final Color surface = theme.colorScheme.surface;
+ final Color primary = theme.colorScheme.primary;
+ final Color onPrimary = theme.colorScheme.onPrimary;
+ final Color onInverseSurface = theme.colorScheme.onInverseSurface;
+ final TextStyle titleMedium = theme.textTheme.titleMedium!;
+ final TextStyle labelMedium = theme.textTheme.labelMedium!;
+ final Color dividerColor = theme.dividerColor.withOpacity(0.1);
+
+ return isVisible
+ ? Container(
+ padding: const EdgeInsets.fromLTRB(12, 0, 12, 0),
+ color: surface,
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.start,
children: [
- Expanded(
- child: Text(ugcSeason.intro ?? '',
- style: TextStyle(
- color: Theme.of(context).colorScheme.outline)),
- ),
- Obx(
- () => isSubscribe.value == -1
- ? const SizedBox(height: 32)
- : SizedBox(
- height: 32,
- child: FilledButton.tonal(
- onPressed: () => changeFucCall.call(),
- style: TextButton.styleFrom(
- padding: const EdgeInsets.only(
- left: 8,
- right: 8,
+ Divider(height: 1, thickness: 1, color: dividerColor),
+ const SizedBox(height: 10),
+ Row(
+ children: [
+ Expanded(
+ child: Text(
+ '合集:${ugcSeason.title}',
+ style: titleMedium,
+ maxLines: 2,
+ overflow: TextOverflow.ellipsis,
+ ),
+ ),
+ const SizedBox(width: 10),
+ Obx(
+ () => isSubscribe.value == -1
+ ? const SizedBox(height: 32)
+ : SizedBox(
+ height: 32,
+ child: FilledButton.tonal(
+ onPressed: () => changeFucCall.call(),
+ style: TextButton.styleFrom(
+ padding:
+ const EdgeInsets.only(left: 8, right: 8),
+ foregroundColor: isSubscribe.value == 1
+ ? outline
+ : onPrimary,
+ backgroundColor: isSubscribe.value == 1
+ ? onInverseSurface
+ : primary,
+ ),
+ child:
+ Text(isSubscribe.value == 1 ? '已订阅' : '订阅'),
),
- foregroundColor: isSubscribe.value == 1
- ? outline
- : t.colorScheme.onPrimary,
- backgroundColor: isSubscribe.value == 1
- ? t.colorScheme.onInverseSurface
- : t.colorScheme.primary, // 设置按钮背景色
),
- child: Text(isSubscribe.value == 1 ? '已订阅' : '订阅'),
- ),
- ),
+ ),
+ ],
),
- const SizedBox(width: 6),
+ if (ugcSeason.intro != null && ugcSeason.intro != '') ...[
+ const SizedBox(height: 4),
+ Text(
+ ugcSeason.intro!,
+ style: TextStyle(color: outline, fontSize: 12),
+ ),
+ ],
+ const SizedBox(height: 4),
+ Text.rich(
+ TextSpan(
+ style: TextStyle(
+ fontSize: labelMedium.fontSize, color: outline),
+ children: [
+ TextSpan(
+ text: '${Utils.numFormat(ugcSeason.stat!.view)}播放'),
+ const TextSpan(text: ' · '),
+ TextSpan(
+ text:
+ '${Utils.numFormat(ugcSeason.stat!.danmaku)}弹幕'),
+ ],
+ ),
+ ),
+ const SizedBox(height: 14),
+ Align(
+ alignment: Alignment.center,
+ child: Material(
+ color: surface,
+ child: InkWell(
+ onTap: () => changeVisible.call(),
+ child: Padding(
+ padding: const EdgeInsets.symmetric(
+ vertical: 10, horizontal: 0),
+ child: Text(
+ '收起简介',
+ style: TextStyle(color: primary, fontSize: 12),
+ ),
+ ),
+ ),
+ ),
+ ),
+ Divider(height: 1, thickness: 1, color: dividerColor),
],
),
- ],
- const SizedBox(height: 4),
- Text.rich(
- TextSpan(
- style: TextStyle(
- fontSize: Theme.of(context).textTheme.labelMedium!.fontSize,
- color: Theme.of(context).colorScheme.outline,
+ )
+ : Align(
+ alignment: Alignment.center,
+ child: InkWell(
+ onTap: () => changeVisible.call(),
+ child: Padding(
+ padding:
+ const EdgeInsets.symmetric(vertical: 10, horizontal: 0),
+ child: Text(
+ '展开简介',
+ style: TextStyle(color: primary, fontSize: 12),
+ ),
),
- children: [
- TextSpan(text: '${Utils.numFormat(ugcSeason.stat!.view)}播放'),
- const TextSpan(text: ' · '),
- TextSpan(text: '${Utils.numFormat(ugcSeason.stat!.danmaku)}弹幕'),
- ],
),
- ),
- const SizedBox(height: 14),
- Divider(
- height: 1,
- thickness: 1,
- color: Theme.of(context).dividerColor.withOpacity(0.1),
- ),
- ],
- ),
- );
+ );
}
}
diff --git a/lib/common/widgets/custom_toast.dart b/lib/common/widgets/custom_toast.dart
index f732fd85..93695e0d 100644
--- a/lib/common/widgets/custom_toast.dart
+++ b/lib/common/widgets/custom_toast.dart
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:pilipala/utils/storage.dart';
-Box setting = GStrorage.setting;
+Box setting = GStorage.setting;
class CustomToast extends StatelessWidget {
const CustomToast({super.key, required this.msg});
diff --git a/lib/common/widgets/network_img_layer.dart b/lib/common/widgets/network_img_layer.dart
index d5903b71..b7b5de7e 100644
--- a/lib/common/widgets/network_img_layer.dart
+++ b/lib/common/widgets/network_img_layer.dart
@@ -6,7 +6,7 @@ import 'package:pilipala/utils/global_data_cache.dart';
import '../../utils/storage.dart';
import '../constants.dart';
-Box setting = GStrorage.setting;
+Box setting = GStorage.setting;
class NetworkImgLayer extends StatelessWidget {
const NetworkImgLayer({
@@ -48,7 +48,7 @@ class NetworkImgLayer extends StatelessWidget {
Widget build(BuildContext context) {
int defaultImgQuality = 10;
try {
- defaultImgQuality = GlobalDataCache().imgQuality;
+ defaultImgQuality = GlobalDataCache.imgQuality;
} catch (_) {}
if (src == '' || src == null) {
diff --git a/lib/http/api.dart b/lib/http/api.dart
index 40b4fd5d..5b2cdf58 100644
--- a/lib/http/api.dart
+++ b/lib/http/api.dart
@@ -619,4 +619,7 @@ class Api {
/// 获取空降区间
static const String getSkipSegments =
'${HttpString.sponsorBlockBaseUrl}/api/skipSegments';
+
+ /// 视频标签
+ static const String videoTag = '/x/tag/archive/tags';
}
diff --git a/lib/http/danmaku.dart b/lib/http/danmaku.dart
index 2ed2a415..7b4283ae 100644
--- a/lib/http/danmaku.dart
+++ b/lib/http/danmaku.dart
@@ -17,7 +17,9 @@ class DanmakaHttp {
var response = await Request().get(
Api.webDanmaku,
data: params,
- extra: {'resType': ResponseType.bytes},
+ options: Options(
+ responseType: ResponseType.bytes,
+ ),
);
return DmSegMobileReply.fromBuffer(response.data);
}
diff --git a/lib/http/dynamics.dart b/lib/http/dynamics.dart
index 5ba5675e..53ba6fc1 100644
--- a/lib/http/dynamics.dart
+++ b/lib/http/dynamics.dart
@@ -92,7 +92,7 @@ class DynamicsHttp {
//
static Future dynamicDetail({
- String? id,
+ required String id,
}) async {
var res = await Request().get(Api.dynamicDetail, data: {
'timezone_offset': -480,
diff --git a/lib/http/init.dart b/lib/http/init.dart
index 3117666e..8a11034c 100644
--- a/lib/http/init.dart
+++ b/lib/http/init.dart
@@ -9,6 +9,7 @@ import 'package:dio/dio.dart';
import 'package:dio/io.dart';
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
import 'package:hive/hive.dart';
+import 'package:pilipala/models/user/info.dart';
import 'package:pilipala/utils/id_utils.dart';
import '../utils/storage.dart';
import '../utils/utils.dart';
@@ -21,8 +22,8 @@ class Request {
static late CookieManager cookieManager;
static late final Dio dio;
factory Request() => _instance;
- Box setting = GStrorage.setting;
- static Box localCache = GStrorage.localCache;
+ Box setting = GStorage.setting;
+ static Box localCache = GStorage.localCache;
late bool enableSystemProxy;
late String systemProxyHost;
late String systemProxyPort;
@@ -32,8 +33,8 @@ class Request {
/// 设置cookie
static setCookie() async {
- Box userInfoCache = GStrorage.userInfo;
- Box setting = GStrorage.setting;
+ Box userInfoCache = GStorage.userInfo;
+ Box setting = GStorage.setting;
final String cookiePath = await Utils.getCookiePath();
final PersistCookieJar cookieJar = PersistCookieJar(
ignoreExpires: true,
@@ -43,7 +44,7 @@ class Request {
dio.interceptors.add(cookieManager);
final List cookie = await cookieManager.cookieJar
.loadForRequest(Uri.parse(HttpString.baseUrl));
- final userInfo = userInfoCache.get('userInfoCache');
+ final UserInfoData? userInfo = userInfoCache.get('userInfoCache');
if (userInfo != null && userInfo.mid != null) {
final List cookie2 = await cookieManager.cookieJar
.loadForRequest(Uri.parse(HttpString.tUrl));
@@ -209,17 +210,13 @@ class Request {
*/
get(url, {data, Options? options, cancelToken, extra}) async {
Response response;
- options ??= Options(); // 如果 options 为 null,则初始化一个新的 Options 对象
- ResponseType resType = ResponseType.json;
-
if (extra != null) {
- resType = extra['resType'] ?? ResponseType.json;
if (extra['ua'] != null) {
- options.headers = {'user-agent': headerUa(type: extra['ua'])};
+ options ??= Options();
+ options.headers ??= {};
+ options.headers?['user-agent'] = headerUa(type: extra['ua']);
}
}
- options.responseType = resType;
-
try {
response = await dio.get(
url,
diff --git a/lib/http/member.dart b/lib/http/member.dart
index fc99c987..107a9379 100644
--- a/lib/http/member.dart
+++ b/lib/http/member.dart
@@ -4,6 +4,7 @@ import 'package:hive/hive.dart';
import 'package:html/parser.dart';
import 'package:pilipala/models/member/article.dart';
import 'package:pilipala/models/member/like.dart';
+import 'package:pilipala/models/user/info.dart';
import 'package:pilipala/utils/global_data_cache.dart';
import '../common/constants.dart';
import '../models/dynamics/result.dart';
@@ -25,7 +26,7 @@ class MemberHttp {
}) async {
String? wWebid;
if ((await getWWebid(mid: mid))['status']) {
- wWebid = GlobalDataCache().wWebid;
+ wWebid = GlobalDataCache.wWebid;
}
Map params = await WbiSign().makSign({
@@ -470,11 +471,11 @@ class MemberHttp {
SmartDialog.dismiss();
if (res.data['code'] == 0) {
String accessKey = res.data['data']['access_token'];
- Box localCache = GStrorage.localCache;
- Box userInfoCache = GStrorage.userInfo;
- var userInfo = userInfoCache.get('userInfoCache');
+ Box localCache = GStorage.localCache;
+ Box userInfoCache = GStorage.userInfo;
+ final UserInfoData? userInfo = userInfoCache.get('userInfoCache');
localCache.put(
- LocalCacheKey.accessKey, {'mid': userInfo.mid, 'value': accessKey});
+ LocalCacheKey.accessKey, {'mid': userInfo!.mid, 'value': accessKey});
return {'status': true, 'data': [], 'msg': '操作成功'};
} else {
return {
@@ -573,7 +574,7 @@ class MemberHttp {
}
static Future getWWebid({required int mid}) async {
- String? wWebid = GlobalDataCache().wWebid;
+ String? wWebid = GlobalDataCache.wWebid;
if (wWebid != null) {
return {'status': true, 'data': wWebid};
}
@@ -587,7 +588,7 @@ class MemberHttp {
final content = match.group(1);
String decodedString = Uri.decodeComponent(content!);
Map map = jsonDecode(decodedString);
- GlobalDataCache().wWebid = map['access_id'];
+ GlobalDataCache.wWebid = map['access_id'];
return {'status': true, 'data': map['access_id']};
} else {
return {'status': false, 'data': '请检查登录状态'};
@@ -604,7 +605,7 @@ class MemberHttp {
}) async {
String? wWebid;
if ((await getWWebid(mid: mid))['status']) {
- wWebid = GlobalDataCache().wWebid;
+ wWebid = GlobalDataCache.wWebid;
}
Map params = await WbiSign().makSign({
'host_mid': mid,
diff --git a/lib/http/read.dart b/lib/http/read.dart
index 68e72e59..f2542936 100644
--- a/lib/http/read.dart
+++ b/lib/http/read.dart
@@ -1,4 +1,5 @@
import 'dart:convert';
+import 'package:dio/dio.dart';
import 'package:html/parser.dart';
import 'package:pilipala/models/read/opus.dart';
import 'package:pilipala/models/read/read.dart';
@@ -65,6 +66,11 @@ class ReadHttp {
var res = await Request().get(
'https://www.bilibili.com/read/cv$id',
extra: {'ua': 'pc'},
+ options: Options(
+ headers: {
+ 'cookie': 'opus-goback=1',
+ },
+ ),
);
String scriptContent =
extractScriptContents(parse(res.data).body!.outerHtml)[0];
diff --git a/lib/http/search.dart b/lib/http/search.dart
index 00e51497..a61ff406 100644
--- a/lib/http/search.dart
+++ b/lib/http/search.dart
@@ -11,7 +11,7 @@ import '../utils/storage.dart';
import 'index.dart';
class SearchHttp {
- static Box setting = GStrorage.setting;
+ static Box setting = GStorage.setting;
static Future hotSearchList() async {
var res = await Request().get(Api.hotSearchList);
if (res.data is String) {
diff --git a/lib/http/video.dart b/lib/http/video.dart
index cb84e676..6237abcb 100644
--- a/lib/http/video.dart
+++ b/lib/http/video.dart
@@ -3,6 +3,7 @@ import 'dart:developer';
import 'package:dio/dio.dart';
import 'package:hive/hive.dart';
import 'package:pilipala/utils/id_utils.dart';
+import 'package:pilipala/models/video/tags.dart';
import '../common/constants.dart';
import '../models/common/reply_type.dart';
import '../models/home/rcmd/result.dart';
@@ -25,11 +26,11 @@ import 'init.dart';
/// 返回{'status': bool, 'data': List}
/// view层根据 status 判断渲染逻辑
class VideoHttp {
- static Box localCache = GStrorage.localCache;
- static Box setting = GStrorage.setting;
+ static Box localCache = GStorage.localCache;
+ static Box setting = GStorage.setting;
static bool enableRcmdDynamic =
setting.get(SettingBoxKey.enableRcmdDynamic, defaultValue: true);
- static Box userInfoCache = GStrorage.userInfo;
+ static Box userInfoCache = GStorage.userInfo;
// 首页推荐视频
static Future rcmdVideoList({required int ps, required int freshIdx}) async {
@@ -607,4 +608,19 @@ class VideoHttp {
};
}
}
+
+ // 获取视频标签
+ static Future getVideoTag({required String bvid}) async {
+ var res = await Request().get(Api.videoTag, data: {'bvid': bvid});
+ if (res.data['code'] == 0) {
+ return {
+ 'status': true,
+ 'data': res.data['data'].map((e) {
+ return VideoTagItem.fromJson(e);
+ }).toList()
+ };
+ } else {
+ return {'status': false, 'data': [], 'msg': res.data['message']};
+ }
+ }
}
diff --git a/lib/main.dart b/lib/main.dart
index 3ac97b25..5a163f49 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -32,7 +32,7 @@ void main() async {
MediaKit.ensureInitialized();
await SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
- await GStrorage.init();
+ await GStorage.init();
clearLogs();
Request();
await Request.setCookie();
@@ -65,7 +65,7 @@ void main() async {
}
PiliSchame.init();
- await GlobalDataCache().initialize();
+ await GlobalDataCache.initialize();
}
class MyApp extends StatelessWidget {
@@ -73,7 +73,7 @@ class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
- Box setting = GStrorage.setting;
+ Box setting = GStorage.setting;
// 主题色
Color defaultColor =
colorThemeTypes[setting.get(SettingBoxKey.customColor, defaultValue: 0)]
@@ -222,13 +222,23 @@ class BuildMainApp extends StatelessWidget {
elevation: 20,
);
- return GetMaterialApp(
- title: 'PiliPala',
- theme: ThemeData(
- colorScheme: currentThemeValue == ThemeType.dark
- ? darkColorScheme
- : lightColorScheme,
+ AppBarTheme appBarTheme(ColorScheme colorScheme) {
+ return AppBarTheme(
+ backgroundColor: colorScheme.surface,
+ foregroundColor: colorScheme.onSurface,
+ elevation: 0,
+ titleSpacing: 0,
+ scrolledUnderElevation: 0,
+ // titleTextStyle: TextStyle(
+ // fontSize: Theme.of(context).textTheme.titleLarge!.fontSize),
+ );
+ }
+
+ ThemeData buildThemeData(ColorScheme colorScheme) {
+ return ThemeData(
+ colorScheme: colorScheme,
snackBarTheme: snackBarTheme,
+ appBarTheme: appBarTheme(colorScheme),
pageTransitionsTheme: const PageTransitionsTheme(
builders: {
TargetPlatform.android: ZoomPageTransitionsBuilder(
@@ -236,12 +246,20 @@ class BuildMainApp extends StatelessWidget {
),
},
),
+ );
+ }
+
+ return GetMaterialApp(
+ title: 'PiliPala',
+ theme: buildThemeData(
+ currentThemeValue == ThemeType.dark
+ ? darkColorScheme
+ : lightColorScheme,
),
- darkTheme: ThemeData(
- colorScheme: currentThemeValue == ThemeType.light
+ darkTheme: buildThemeData(
+ currentThemeValue == ThemeType.light
? lightColorScheme
: darkColorScheme,
- snackBarTheme: snackBarTheme,
),
localizationsDelegates: const [
GlobalCupertinoLocalizations.delegate,
diff --git a/lib/models/video/reply/item.dart b/lib/models/video/reply/item.dart
index 1fa05bec..44a87af9 100644
--- a/lib/models/video/reply/item.dart
+++ b/lib/models/video/reply/item.dart
@@ -125,6 +125,7 @@ class ReplyControl {
this.upLike,
this.isShow,
this.entryText,
+ this.entryTextNum,
this.titleText,
this.time,
this.location,
@@ -135,6 +136,7 @@ class ReplyControl {
bool? upLike;
bool? isShow;
String? entryText;
+ int? entryTextNum;
String? titleText;
String? time;
String? location;
@@ -155,6 +157,10 @@ class ReplyControl {
}
entryText = json['sub_reply_entry_text'];
+ // 正则匹配
+ entryTextNum = json['sub_reply_entry_text'] != null
+ ? int.parse(RegExp(r"\d+").stringMatch(json['sub_reply_entry_text']!)!)
+ : 0;
titleText = json['sub_reply_title_text'];
time = json['time_desc'];
location = json['location'] != null ? json['location'].split(':')[1] : '';
diff --git a/lib/models/video/reply/member.dart b/lib/models/video/reply/member.dart
index 0801d110..ad10c143 100644
--- a/lib/models/video/reply/member.dart
+++ b/lib/models/video/reply/member.dart
@@ -29,7 +29,7 @@ class ReplyMember {
avatar = json['avatar'];
level = json['level_info']['current_level'];
pendant = Pendant.fromJson(json['pendant']);
- officialVerify = json['officia_verify'];
+ officialVerify = json['official_verify'];
vip = json['vip'];
fansDetail = json['fans_detail'];
userSailing = json['user_sailing'] != null
diff --git a/lib/models/video/tags.dart b/lib/models/video/tags.dart
new file mode 100644
index 00000000..f01f85ba
--- /dev/null
+++ b/lib/models/video/tags.dart
@@ -0,0 +1,17 @@
+class VideoTagItem {
+ String? tagName;
+ int? tagId;
+ int? tagType;
+
+ VideoTagItem({
+ this.tagName,
+ this.tagId,
+ this.tagType,
+ });
+
+ VideoTagItem.fromJson(Map json) {
+ tagName = json['tag_name'];
+ tagId = json['tag_id'];
+ tagType = json['type'];
+ }
+}
diff --git a/lib/pages/about/index.dart b/lib/pages/about/index.dart
index 3a8e5a0a..c7cc2c59 100644
--- a/lib/pages/about/index.dart
+++ b/lib/pages/about/index.dart
@@ -39,9 +39,7 @@ class _AboutPageState extends State {
TextStyle subTitleStyle =
TextStyle(fontSize: 13, color: Theme.of(context).colorScheme.outline);
return Scaffold(
- appBar: AppBar(
- title: Text('关于', style: Theme.of(context).textTheme.titleMedium),
- ),
+ appBar: AppBar(title: const Text('关于')),
body: SingleChildScrollView(
child: Column(
children: [
diff --git a/lib/pages/bangumi/controller.dart b/lib/pages/bangumi/controller.dart
index 29dd15d1..e7582cfc 100644
--- a/lib/pages/bangumi/controller.dart
+++ b/lib/pages/bangumi/controller.dart
@@ -3,6 +3,7 @@ import 'package:get/get.dart';
import 'package:hive/hive.dart';
import 'package:pilipala/http/bangumi.dart';
import 'package:pilipala/models/bangumi/list.dart';
+import 'package:pilipala/models/user/info.dart';
import 'package:pilipala/utils/storage.dart';
class BangumiController extends GetxController {
@@ -12,17 +13,17 @@ class BangumiController extends GetxController {
RxInt total = 0.obs;
int _currentPage = 1;
bool isLoadingMore = true;
- Box userInfoCache = GStrorage.userInfo;
+ Box userInfoCache = GStorage.userInfo;
RxBool userLogin = false.obs;
late int mid;
- var userInfo;
+ UserInfoData? userInfo;
@override
void onInit() {
super.onInit();
userInfo = userInfoCache.get('userInfoCache');
if (userInfo != null) {
- mid = userInfo.mid;
+ mid = userInfo!.mid!;
}
userLogin.value = userInfo != null;
}
@@ -55,7 +56,7 @@ class BangumiController extends GetxController {
if (userInfo == null) {
return;
}
- var result = await BangumiHttp.getRecentBangumi(mid: userInfo.mid);
+ var result = await BangumiHttp.getRecentBangumi(mid: userInfo!.mid!);
if (result['status']) {
bangumiFollowList.value = result['data'].list;
total.value = result['data'].total;
diff --git a/lib/pages/bangumi/introduction/controller.dart b/lib/pages/bangumi/introduction/controller.dart
index d79eef79..f06e6ee8 100644
--- a/lib/pages/bangumi/introduction/controller.dart
+++ b/lib/pages/bangumi/introduction/controller.dart
@@ -8,6 +8,7 @@ import 'package:pilipala/http/search.dart';
import 'package:pilipala/http/video.dart';
import 'package:pilipala/models/bangumi/info.dart';
import 'package:pilipala/models/user/fav_folder.dart';
+import 'package:pilipala/models/user/info.dart';
import 'package:pilipala/pages/video/detail/index.dart';
import 'package:pilipala/pages/video/detail/reply/index.dart';
import 'package:pilipala/plugin/pl_player/models/play_repeat.dart';
@@ -48,7 +49,7 @@ class BangumiIntroController extends GetxController {
RxBool hasCoin = false.obs;
// 是否收藏
RxBool hasFav = false.obs;
- Box userInfoCache = GStrorage.userInfo;
+ Box userInfoCache = GStorage.userInfo;
bool userLogin = false;
Rx favFolderData = FavFolderData().obs;
List addMediaIdsNew = [];
@@ -57,7 +58,7 @@ class BangumiIntroController extends GetxController {
RxBool isFollowed = false.obs;
RxInt followStatus = 1.obs;
int _tempThemeValue = -1;
- var userInfo;
+ UserInfoData? userInfo;
PersistentBottomSheetController? bottomSheetController;
List