Compare commits

..

1 Commits

Author SHA1 Message Date
c1008e0162 fix: 垂直布局视频卡片样式 2024-02-17 22:07:48 +08:00
19 changed files with 143 additions and 343 deletions

View File

@ -229,9 +229,7 @@ class VideoContent extends StatelessWidget {
),
if (crossAxisCount > 1) ...[
const SizedBox(height: 2),
VideoStat(
videoItem: videoItem,
),
VideoStat(videoItem: videoItem, crossAxisCount: crossAxisCount),
],
if (crossAxisCount == 1) const SizedBox(height: 4),
Row(
@ -292,10 +290,14 @@ class VideoContent extends StatelessWidget {
color: Theme.of(context).colorScheme.outline,
),
),
VideoStat(
videoItem: videoItem,
Expanded(
flex: 1,
child: VideoStat(
videoItem: videoItem,
crossAxisCount: crossAxisCount,
),
),
const Spacer(),
// const Spacer(),
],
if (videoItem.goto == 'av' && crossAxisCount != 1) ...[
VideoPopupMenu(
@ -317,10 +319,12 @@ class VideoContent extends StatelessWidget {
class VideoStat extends StatelessWidget {
final dynamic videoItem;
final int crossAxisCount;
const VideoStat({
Key? key,
required this.videoItem,
required this.crossAxisCount,
}) : super(key: key);
@override
@ -337,7 +341,7 @@ class VideoStat extends StatelessWidget {
danmu: videoItem.stat.danmu,
),
if (videoItem is RecVideoItemModel) ...<Widget>[
const Spacer(),
crossAxisCount > 1 ? const Spacer() : const SizedBox(width: 8),
RichText(
maxLines: 1,
text: TextSpan(

View File

@ -101,13 +101,10 @@ class MemberHttp {
'data': MemberArchiveDataModel.fromJson(res.data['data'])
};
} else {
Map errMap = {
-352: '风控校验失败,请检查登录状态',
};
return {
'status': false,
'data': [],
'msg': errMap[res.data['code']] ?? res.data['message'],
'msg': res.data['message'],
};
}
}
@ -126,13 +123,10 @@ class MemberHttp {
'data': DynamicsDataModel.fromJson(res.data['data']),
};
} else {
Map errMap = {
-352: '风控校验失败,请检查登录状态',
};
return {
'status': false,
'data': [],
'msg': errMap[res.data['code']] ?? res.data['message'],
'msg': res.data['message'],
};
}
}

View File

@ -142,7 +142,7 @@ class Stat {
Stat.fromJson(Map<String, dynamic> json) {
view = json["play"];
danmaku = json['video_review'];
danmaku = json['comment'];
}
}

View File

@ -34,7 +34,6 @@ class PlayUrlModel {
String? seekParam;
String? seekType;
Dash? dash;
List<Durl>? durl;
List<FormatItem>? supportFormats;
// String? highFormat;
int? lastPlayTime;
@ -53,8 +52,7 @@ class PlayUrlModel {
videoCodecid = json['video_codecid'];
seekParam = json['seek_param'];
seekType = json['seek_type'];
dash = json['dash'] != null ? Dash.fromJson(json['dash']) : null;
durl = json['durl']?.map<Durl>((e) => Durl.fromJson(e)).toList();
dash = Dash.fromJson(json['dash']);
supportFormats = json['support_formats'] != null
? json['support_formats']
.map<FormatItem>((e) => FormatItem.fromJson(e))
@ -252,30 +250,3 @@ class Flac {
audio = json['audio'] != null ? AudioItem.fromJson(json['audio']) : null;
}
}
class Durl {
Durl({
this.order,
this.length,
this.size,
this.ahead,
this.vhead,
this.url,
});
int? order;
int? length;
int? size;
String? ahead;
String? vhead;
String? url;
Durl.fromJson(Map<String, dynamic> json) {
order = json['order'];
length = json['length'];
size = json['size'];
ahead = json['ahead'];
vhead = json['vhead'];
url = json['url'];
}
}

View File

@ -53,54 +53,29 @@ class _AboutPageState extends State<AboutPage> {
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 6),
Text(
'使用Flutter开发的哔哩哔哩第三方客户端',
style: TextStyle(color: Theme.of(context).colorScheme.outline),
),
const SizedBox(height: 20),
Obx(
() => Badge(
isLabelVisible: _aboutController.isLoading.value
? false
: _aboutController.isUpdate.value,
label: const Text('New'),
child: Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 30),
child: FilledButton.tonal(
onPressed: () {
showModalBottomSheet(
context: context,
builder: (context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
onTap: () => _aboutController.githubRelease(),
title: const Text('Github下载'),
),
ListTile(
onTap: () => _aboutController.panDownload(),
title: const Text('网盘下载'),
),
ListTile(
onTap: () => _aboutController.webSiteUrl(),
title: const Text('官网下载'),
),
ListTile(
onTap: () => _aboutController.qimiao(),
title: const Text('奇妙应用'),
),
SizedBox(
height:
MediaQuery.of(context).padding.bottom +
20)
],
);
},
);
},
child: Text(
'V${_aboutController.currentVersion.value}',
style: subTitleStyle.copyWith(
color: Theme.of(context).primaryColor,
),
),
),
() => ListTile(
title: const Text('当前版本'),
trailing: Text(_aboutController.currentVersion.value,
style: subTitleStyle),
),
),
Obx(
() => ListTile(
onTap: () => _aboutController.onUpdate(),
title: const Text('最新版本'),
trailing: Text(
_aboutController.isLoading.value
? '正在获取'
: _aboutController.isUpdate.value
? '有新版本 ❤️${_aboutController.remoteVersion.value}'
: '当前已是最新版',
style: subTitleStyle,
),
),
),
@ -112,9 +87,14 @@ class _AboutPageState extends State<AboutPage> {
// size: 16,
// ),
// ),
Divider(
thickness: 1,
height: 30,
color: Theme.of(context).colorScheme.outlineVariant,
),
ListTile(
onTap: () => _aboutController.githubUrl(),
title: const Text('开源地址'),
title: const Text('Github'),
trailing: Text(
'github.com/guozhigq/pilipala',
style: subTitleStyle,
@ -149,43 +129,19 @@ class _AboutPageState extends State<AboutPage> {
),
),
ListTile(
onTap: () {
showModalBottomSheet(
context: context,
builder: (context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
onTap: () => _aboutController.qqChanel(),
title: const Text('QQ群'),
trailing: Text(
'616150809',
style: subTitleStyle,
),
),
ListTile(
onTap: () => _aboutController.tgChanel(),
title: const Text('TG频道'),
trailing: Text(
'https://t.me/+lm_oOVmF0RJiODk1',
style: subTitleStyle,
),
),
SizedBox(
height: MediaQuery.of(context).padding.bottom + 20)
],
);
},
);
},
title: const Text('交流社区'),
onTap: () => _aboutController.qqChanel(),
title: const Text('QQ群'),
trailing: Icon(
Icons.arrow_forward_ios,
size: 16,
color: outline,
),
),
ListTile(
onTap: () => _aboutController.tgChanel(),
title: const Text('TG频道'),
trailing: Icon(Icons.arrow_forward_ios, size: 16, color: outline),
),
ListTile(
onTap: () => _aboutController.aPay(),
title: const Text('赞助'),
@ -207,7 +163,6 @@ class _AboutPageState extends State<AboutPage> {
subtitle: Text('图片及网络缓存 $cacheSize', style: subTitleStyle),
trailing: Icon(Icons.arrow_forward_ios, size: 16, color: outline),
),
SizedBox(height: MediaQuery.of(context).padding.bottom + 20)
],
),
),
@ -275,26 +230,11 @@ class AboutController extends GetxController {
);
}
githubRelease() {
launchUrl(
Uri.parse('https://github.com/guozhigq/pilipala/release'),
mode: LaunchMode.externalApplication,
);
}
// 从网盘下载
panDownload() {
Clipboard.setData(
const ClipboardData(text: 'pili'),
);
SmartDialog.showToast(
'已复制提取码pili',
displayTime: const Duration(milliseconds: 500),
).then(
(value) => launchUrl(
Uri.parse('https://www.123pan.com/s/9sVqVv-flu0A.html'),
mode: LaunchMode.externalApplication,
),
launchUrl(
Uri.parse('https://www.123pan.com/s/9sVqVv-flu0A.html'),
mode: LaunchMode.externalApplication,
);
}
@ -310,7 +250,7 @@ class AboutController extends GetxController {
// qq频道
qqChanel() {
Clipboard.setData(
const ClipboardData(text: '616150809'),
const ClipboardData(text: '489981949'),
);
SmartDialog.showToast('已复制QQ群号');
}
@ -351,13 +291,6 @@ class AboutController extends GetxController {
);
}
qimiao() {
launchUrl(
Uri.parse('https://www.magicalapk.com/home'),
mode: LaunchMode.externalApplication,
);
}
// 日志
logs() {
Get.toNamed('/logs');

View File

@ -218,12 +218,14 @@ class BangumiIntroController extends GetxController {
addIds: addMediaIdsNew.join(','),
delIds: delMediaIdsNew.join(','));
if (result['status']) {
addMediaIdsNew = [];
delMediaIdsNew = [];
// 重新获取收藏状态
queryHasFavVideo();
SmartDialog.showToast('✅ 操作成功');
Get.back();
if (result['data']['prompt']) {
addMediaIdsNew = [];
delMediaIdsNew = [];
Get.back();
// 重新获取收藏状态
queryHasFavVideo();
SmartDialog.showToast('✅ 操作成功');
}
}
}

View File

@ -60,14 +60,16 @@ class FavDetailController extends GetxController {
var result = await VideoHttp.favVideo(
aid: id, addIds: '', delIds: mediaId.toString());
if (result['status']) {
List dataList = favList;
for (var i in dataList) {
if (i.id == id) {
dataList.remove(i);
break;
if (result['data']['prompt']) {
List dataList = favList;
for (var i in dataList) {
if (i.id == id) {
dataList.remove(i);
break;
}
}
SmartDialog.showToast('取消收藏');
}
SmartDialog.showToast('取消收藏');
}
}

View File

@ -29,7 +29,6 @@ class _FavDetailPageState extends State<FavDetailPage> {
@override
void initState() {
super.initState();
mediaId = Get.parameters['mediaId']!;
_futureBuilderFuture = _favDetailController.queryUserFavFolderDetail();
mediaId = Get.parameters['mediaId']!;
titleStreamC = StreamController<bool>();

View File

@ -80,14 +80,16 @@ class FavSearchController extends GetxController {
var result = await VideoHttp.favVideo(
aid: id, addIds: '', delIds: mediaId.toString());
if (result['status']) {
List dataList = favList;
for (var i in dataList) {
if (i.id == id) {
dataList.remove(i);
break;
if (result['data']['prompt']) {
List dataList = favList;
for (var i in dataList) {
if (i.id == id) {
dataList.remove(i);
break;
}
}
SmartDialog.showToast('取消收藏');
}
SmartDialog.showToast('取消收藏');
}
}
}

View File

@ -26,7 +26,6 @@ class HomeController extends GetxController with GetTickerProviderStateMixin {
late List defaultTabs;
late List<String> tabbarSort;
RxString defaultSearch = ''.obs;
late bool enableGradientBg;
@override
void onInit() {
@ -41,8 +40,6 @@ class HomeController extends GetxController with GetTickerProviderStateMixin {
if (setting.get(SettingBoxKey.enableSearchWord, defaultValue: true)) {
searchDefault();
}
enableGradientBg =
setting.get(SettingBoxKey.enableGradientBg, defaultValue: true);
}
void onRefresh() {

View File

@ -48,48 +48,38 @@ class _HomePageState extends State<HomePage>
super.build(context);
Brightness currentBrightness = MediaQuery.of(context).platformBrightness;
// 设置状态栏图标的亮度
if (_homeController.enableGradientBg) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarIconBrightness: currentBrightness == Brightness.light
? Brightness.dark
: Brightness.light,
));
}
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarIconBrightness: currentBrightness == Brightness.light
? Brightness.dark
: Brightness.light,
));
return Scaffold(
extendBody: true,
extendBodyBehindAppBar: true,
body: Stack(
children: [
// gradient background
if (_homeController.enableGradientBg) ...[
Align(
alignment: Alignment.topLeft,
child: Opacity(
opacity: 0.6,
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Theme.of(context)
.colorScheme
.primary
.withOpacity(0.9),
Theme.of(context)
.colorScheme
.primary
.withOpacity(0.5),
Theme.of(context).colorScheme.surface
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
stops: const [0, 0.0034, 0.34]),
),
Align(
alignment: Alignment.topLeft,
child: Opacity(
opacity: 0.6,
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Theme.of(context).colorScheme.primary.withOpacity(0.9),
Theme.of(context).colorScheme.primary.withOpacity(0.5),
Theme.of(context).colorScheme.surface
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
stops: const [0, 0.0034, 0.34]),
),
),
),
],
),
Column(
children: [
CustomAppBar(
@ -100,37 +90,7 @@ class _HomePageState extends State<HomePage>
callback: showUserBottomSheet,
),
if (_homeController.tabs.length > 1) ...[
if (_homeController.enableGradientBg) ...[
const CustomTabs(),
] else ...[
const SizedBox(height: 4),
SizedBox(
width: double.infinity,
height: 42,
child: Align(
alignment: Alignment.center,
child: TabBar(
controller: _homeController.tabController,
tabs: [
for (var i in _homeController.tabs)
Tab(text: i['label'])
],
isScrollable: true,
dividerColor: Colors.transparent,
enableFeedback: true,
splashBorderRadius: BorderRadius.circular(10),
tabAlignment: TabAlignment.center,
onTap: (value) {
feedBack();
if (_homeController.initialIndex.value == value) {
_homeController.tabsCtrList[value]().animateToTop();
}
_homeController.initialIndex.value = value;
},
),
),
),
],
const CustomTabs(),
] else ...[
const SizedBox(height: 6),
],

View File

@ -3,7 +3,6 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:pilipala/common/widgets/video_card_h.dart';
import 'package:pilipala/utils/utils.dart';
import '../../common/widgets/http_error.dart';
import 'controller.dart';
class MemberArchivePage extends StatefulWidget {
@ -87,16 +86,10 @@ class _MemberArchivePageState extends State<MemberArchivePage> {
: const SliverToBoxAdapter(),
);
} else {
return HttpError(
errMsg: snapshot.data['msg'],
fn: () {},
);
return const SliverToBoxAdapter();
}
} else {
return HttpError(
errMsg: snapshot.data['msg'],
fn: () {},
);
return const SliverToBoxAdapter();
}
} else {
return const SliverToBoxAdapter();

View File

@ -4,7 +4,6 @@ import 'package:get/get.dart';
import 'package:pilipala/pages/member_dynamics/index.dart';
import 'package:pilipala/utils/utils.dart';
import '../../common/widgets/http_error.dart';
import '../dynamics/widgets/dynamic_panel.dart';
class MemberDynamicsPage extends StatefulWidget {
@ -81,16 +80,10 @@ class _MemberDynamicsPageState extends State<MemberDynamicsPage> {
: const SliverToBoxAdapter(),
);
} else {
return HttpError(
errMsg: snapshot.data['msg'],
fn: () {},
);
return const SliverToBoxAdapter();
}
} else {
return HttpError(
errMsg: snapshot.data['msg'],
fn: () {},
);
return const SliverToBoxAdapter();
}
} else {
return const SliverToBoxAdapter();

View File

@ -102,12 +102,6 @@ class _StyleSettingState extends State<StyleSetting> {
defaultVal: true,
needReboot: true,
),
const SetSwitchItem(
title: '首页底栏背景渐变',
setKey: SettingBoxKey.enableGradientBg,
defaultVal: true,
needReboot: true,
),
ListTile(
onTap: () async {
int? result = await showDialog(

View File

@ -90,8 +90,6 @@ class VideoDetailController extends GetxController
late String cacheDecode;
late int cacheAudioQa;
PersistentBottomSheetController? replyReplyBottomSheetCtr;
@override
void onInit() {
super.onInit();
@ -142,7 +140,7 @@ class VideoDetailController extends GetxController
}
showReplyReplyPanel() {
replyReplyBottomSheetCtr =
PersistentBottomSheetController? ctr =
scaffoldKey.currentState?.showBottomSheet((BuildContext context) {
return VideoReplyReplyPanel(
oid: oid.value,
@ -155,7 +153,7 @@ class VideoDetailController extends GetxController
source: 'videoDetail',
);
});
replyReplyBottomSheetCtr?.closed.then((value) {
ctr?.closed.then((value) {
fRpid = 0;
});
}
@ -231,11 +229,9 @@ class VideoDetailController extends GetxController
seekTo: seekToTime ?? defaultST,
duration: duration ?? Duration(milliseconds: data.timeLength ?? 0),
// 宽>高 水平 否则 垂直
direction: firstVideo.width != null && firstVideo.height != null
? ((firstVideo.width! - firstVideo.height!) > 0
? 'horizontal'
: 'vertical')
: null,
direction: (firstVideo.width! - firstVideo.height!) > 0
? 'horizontal'
: 'vertical',
bvid: bvid,
cid: cid.value,
enableHeart: enableHeart,
@ -252,21 +248,6 @@ class VideoDetailController extends GetxController
var result = await VideoHttp.videoUrl(cid: cid.value, bvid: bvid);
if (result['status']) {
data = result['data'];
if (data.acceptDesc!.isNotEmpty && data.acceptDesc!.contains('试看')) {
SmartDialog.showToast(
'该视频为专属视频,仅提供试看',
displayTime: const Duration(seconds: 3),
);
videoUrl = data.durl!.first.url!;
audioUrl = '';
defaultST = Duration.zero;
firstVideo = VideoItem();
if (autoPlay.value) {
await playerInit();
isShowCover.value = false;
}
return result;
}
final List<VideoItem> allVideosList = data.dash!.video!;
try {
// 当前可播放的最高质量视频
@ -374,11 +355,4 @@ class VideoDetailController extends GetxController
}
return result;
}
// mob端全屏状态关闭二级回复
hiddenReplyReplyPanel() {
replyReplyBottomSheetCtr != null
? replyReplyBottomSheetCtr!.close()
: print('replyReplyBottomSheetCtr is null');
}
}

View File

@ -305,9 +305,11 @@ class VideoIntroController extends GetxController {
delIds: favStatus == 1 ? '$defaultFolderId' : '',
);
if (result['status']) {
// 重新获取收藏状态
await queryHasFavVideo();
SmartDialog.showToast('✅ 操作成功');
if (result['data']['prompt']) {
// 重新获取收藏状态
await queryHasFavVideo();
SmartDialog.showToast('✅ 操作成功');
}
} else {
SmartDialog.showToast(result['msg']);
}
@ -332,12 +334,14 @@ class VideoIntroController extends GetxController {
delIds: delMediaIdsNew.join(','));
SmartDialog.dismiss();
if (result['status']) {
addMediaIdsNew = [];
delMediaIdsNew = [];
Get.back();
// 重新获取收藏状态
await queryHasFavVideo();
SmartDialog.showToast('✅ 操作成功');
if (result['data']['prompt']) {
addMediaIdsNew = [];
delMediaIdsNew = [];
Get.back();
// 重新获取收藏状态
await queryHasFavVideo();
SmartDialog.showToast('✅ 操作成功');
}
} else {
SmartDialog.showToast(result['msg']);
}
@ -478,7 +482,7 @@ class VideoIntroController extends GetxController {
final ReleatedController releatedCtr =
Get.find<ReleatedController>(tag: heroTag);
videoDetailCtr.bvid = bvid;
videoDetailCtr.oid.value = aid ?? IdUtils.bv2av(bvid);
videoDetailCtr.oid.value = aid;
videoDetailCtr.cid.value = cid;
videoDetailCtr.danmakuCid.value = cid;
videoDetailCtr.queryVideoUrl();

View File

@ -12,7 +12,6 @@ import 'package:pilipala/pages/preview/index.dart';
import 'package:pilipala/pages/video/detail/index.dart';
import 'package:pilipala/pages/video/detail/reply_new/index.dart';
import 'package:pilipala/utils/feed_back.dart';
import 'package:pilipala/utils/id_utils.dart';
import 'package:pilipala/utils/storage.dart';
import 'package:pilipala/utils/url_utils.dart';
import 'package:pilipala/utils/utils.dart';
@ -621,34 +620,26 @@ InlineSpan buildContent(
..onTap = () async {
final String title = content.jumpUrl[matchStr]['title'];
if (appUrlSchema == '') {
if (matchStr.startsWith('BV')) {
final String redirectUrl =
await UrlUtils.parseRedirectUrl(matchStr);
final String pathSegment = Uri.parse(redirectUrl).path;
final String lastPathSegment =
pathSegment.split('/').last;
if (lastPathSegment.startsWith('BV')) {
UrlUtils.matchUrlPush(
matchStr,
lastPathSegment,
title,
'',
redirectUrl,
);
} else {
final String redirectUrl =
await UrlUtils.parseRedirectUrl(matchStr);
final String pathSegment = Uri.parse(redirectUrl).path;
final String lastPathSegment =
pathSegment.split('/').last;
if (lastPathSegment.startsWith('BV')) {
UrlUtils.matchUrlPush(
lastPathSegment,
title,
redirectUrl,
);
} else {
Get.toNamed(
'/webview',
parameters: {
'url': redirectUrl,
'type': 'url',
'pageTitle': title
},
);
}
Get.toNamed(
'/webview',
parameters: {
'url': redirectUrl,
'type': 'url',
'pageTitle': title
},
);
}
} else {
if (appUrlSchema.startsWith('bilibili://search')) {

View File

@ -92,7 +92,6 @@ class _VideoDetailPageState extends State<VideoDetailPage>
videoSourceInit();
appbarStreamListen();
lifecycleListener();
fullScreenStatusListener();
}
// 获取视频资源,初始化播放器
@ -189,14 +188,6 @@ class _VideoDetailPageState extends State<VideoDetailPage>
);
}
void fullScreenStatusListener() {
plPlayerController?.isFullScreen.listen((bool isFullScreen) {
if (isFullScreen) {
videoDetailController.hiddenReplyReplyPanel();
}
});
}
@override
void dispose() {
shutdownTimerService.handleWaitingFinished();
@ -234,10 +225,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
@override
// 返回当前页面时
void didPopNext() async {
if (plPlayerController != null &&
plPlayerController!.videoPlayerController != null) {
setState(() => isShowing = true);
}
setState(() => isShowing = true);
videoDetailController.isFirstTime = false;
final bool autoplay = autoPlayEnable;
videoDetailController.playerInit(autoplay: autoplay);

View File

@ -135,8 +135,7 @@ class SettingBoxKey {
hideSearchBar = 'hideSearchBar', // 收起顶栏
hideTabBar = 'hideTabBar', // 收起底栏
tabbarSort = 'tabbarSort', // 首页tabbar
dynamicBadgeMode = 'dynamicBadgeMode',
enableGradientBg = 'enableGradientBg';
dynamicBadgeMode = 'dynamicBadgeMode';
}
class LocalCacheKey {