mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
feat: pgc timeline
Closes #653 Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:PiliPlus/utils/extension.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class PBadge extends StatelessWidget {
|
class PBadge extends StatelessWidget {
|
||||||
@@ -17,7 +18,7 @@ class PBadge extends StatelessWidget {
|
|||||||
|
|
||||||
const PBadge({
|
const PBadge({
|
||||||
super.key,
|
super.key,
|
||||||
this.text,
|
required this.text,
|
||||||
this.top,
|
this.top,
|
||||||
this.right,
|
this.right,
|
||||||
this.bottom,
|
this.bottom,
|
||||||
@@ -34,15 +35,19 @@ class PBadge extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
if (text.isNullOrEmpty) {
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
|
||||||
ColorScheme t = Theme.of(context).colorScheme;
|
ColorScheme t = Theme.of(context).colorScheme;
|
||||||
// 背景色
|
// 背景色
|
||||||
Color bgColor = t.primary;
|
Color bgColor = t.primary;
|
||||||
// 前景色
|
// 前景色
|
||||||
Color color = t.onPrimary;
|
Color color = t.onPrimary;
|
||||||
// 边框色
|
// 边框色
|
||||||
Color borderColor = Colors.transparent;
|
Color? borderColor;
|
||||||
if (type == 'gray') {
|
if (type == 'gray') {
|
||||||
bgColor = Colors.black54.withOpacity(0.45);
|
bgColor = Colors.black45;
|
||||||
color = Colors.white;
|
color = Colors.white;
|
||||||
} else if (type == 'color') {
|
} else if (type == 'color') {
|
||||||
bgColor = t.secondaryContainer.withOpacity(0.5);
|
bgColor = t.secondaryContainer.withOpacity(0.5);
|
||||||
@@ -72,10 +77,10 @@ class PBadge extends StatelessWidget {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: br,
|
borderRadius: br,
|
||||||
color: bgColor,
|
color: bgColor,
|
||||||
border: Border.all(color: borderColor),
|
border: borderColor != null ? Border.all(color: borderColor) : null,
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
text ?? "",
|
text!,
|
||||||
textScaler: textScaleFactor != null
|
textScaler: textScaleFactor != null
|
||||||
? TextScaler.linear(textScaleFactor!)
|
? TextScaler.linear(textScaleFactor!)
|
||||||
: null,
|
: null,
|
||||||
|
|||||||
@@ -141,11 +141,7 @@ class VideoCardH extends StatelessWidget {
|
|||||||
width: maxWidth,
|
width: maxWidth,
|
||||||
height: maxHeight,
|
height: maxHeight,
|
||||||
),
|
),
|
||||||
if (videoItem is HotVideoItemModel &&
|
if (videoItem is HotVideoItemModel)
|
||||||
(videoItem as HotVideoItemModel)
|
|
||||||
.pgcLabel
|
|
||||||
?.isNotEmpty ==
|
|
||||||
true)
|
|
||||||
PBadge(
|
PBadge(
|
||||||
text:
|
text:
|
||||||
(videoItem as HotVideoItemModel).pgcLabel,
|
(videoItem as HotVideoItemModel).pgcLabel,
|
||||||
|
|||||||
@@ -760,4 +760,6 @@ class Api {
|
|||||||
|
|
||||||
static const String getLiveEmoticons =
|
static const String getLiveEmoticons =
|
||||||
'${HttpString.liveBaseUrl}/xlive/web-ucenter/v2/emoticon/GetEmoticons';
|
'${HttpString.liveBaseUrl}/xlive/web-ucenter/v2/emoticon/GetEmoticons';
|
||||||
|
|
||||||
|
static const String pgcTimeline = '/pgc/web/timeline';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import 'package:PiliPlus/http/loading_state.dart';
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
|
import 'package:PiliPlus/models/bangumi/pgc_timeline/pgc_timeline.dart';
|
||||||
|
import 'package:PiliPlus/models/bangumi/pgc_timeline/result.dart';
|
||||||
|
|
||||||
import '../models/bangumi/list.dart';
|
import '../models/bangumi/list.dart';
|
||||||
import '../models/bangumi/pgc_index/condition.dart';
|
import '../models/bangumi/pgc_index/condition.dart';
|
||||||
@@ -86,4 +88,24 @@ class BangumiHttp {
|
|||||||
return LoadingState.error(res.data['message']);
|
return LoadingState.error(res.data['message']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future<LoadingState<List<Result>?>> pgcTimeline({
|
||||||
|
int types = 1, // 1:`番剧`<br />3:`电影`<br />4:`国创` |
|
||||||
|
required int before,
|
||||||
|
required int after,
|
||||||
|
}) async {
|
||||||
|
var res = await Request().get(
|
||||||
|
Api.pgcTimeline,
|
||||||
|
queryParameters: {
|
||||||
|
'types': types,
|
||||||
|
'before': before,
|
||||||
|
'after': after,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (res.data['code'] == 0) {
|
||||||
|
return LoadingState.success(PgcTimeline.fromJson(res.data).result);
|
||||||
|
} else {
|
||||||
|
return LoadingState.error(res.data['message']);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
91
lib/models/bangumi/pgc_timeline/episode.dart
Normal file
91
lib/models/bangumi/pgc_timeline/episode.dart
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
import 'icon_font.dart';
|
||||||
|
|
||||||
|
class Episode {
|
||||||
|
String? cover;
|
||||||
|
int? delay;
|
||||||
|
int? delayId;
|
||||||
|
String? delayIndex;
|
||||||
|
String? delayReason;
|
||||||
|
bool? enableVt;
|
||||||
|
String? epCover;
|
||||||
|
int? episodeId;
|
||||||
|
int? follow;
|
||||||
|
String? follows;
|
||||||
|
IconFont? iconFont;
|
||||||
|
String? plays;
|
||||||
|
String? pubIndex;
|
||||||
|
String? pubTime;
|
||||||
|
int? pubTs;
|
||||||
|
int? published;
|
||||||
|
int? seasonId;
|
||||||
|
String? squareCover;
|
||||||
|
String? title;
|
||||||
|
|
||||||
|
Episode({
|
||||||
|
this.cover,
|
||||||
|
this.delay,
|
||||||
|
this.delayId,
|
||||||
|
this.delayIndex,
|
||||||
|
this.delayReason,
|
||||||
|
this.enableVt,
|
||||||
|
this.epCover,
|
||||||
|
this.episodeId,
|
||||||
|
this.follow,
|
||||||
|
this.follows,
|
||||||
|
this.iconFont,
|
||||||
|
this.plays,
|
||||||
|
this.pubIndex,
|
||||||
|
this.pubTime,
|
||||||
|
this.pubTs,
|
||||||
|
this.published,
|
||||||
|
this.seasonId,
|
||||||
|
this.squareCover,
|
||||||
|
this.title,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory Episode.fromJson(Map<String, dynamic> json) => Episode(
|
||||||
|
cover: json['cover'] as String?,
|
||||||
|
delay: json['delay'] as int?,
|
||||||
|
delayId: json['delay_id'] as int?,
|
||||||
|
delayIndex: json['delay_index'] as String?,
|
||||||
|
delayReason: json['delay_reason'] as String?,
|
||||||
|
enableVt: json['enable_vt'] as bool?,
|
||||||
|
epCover: json['ep_cover'] as String?,
|
||||||
|
episodeId: json['episode_id'] as int?,
|
||||||
|
follow: json['follow'] as int?,
|
||||||
|
follows: json['follows'] as String?,
|
||||||
|
iconFont: json['icon_font'] == null
|
||||||
|
? null
|
||||||
|
: IconFont.fromJson(json['icon_font'] as Map<String, dynamic>),
|
||||||
|
plays: json['plays'] as String?,
|
||||||
|
pubIndex: json['pub_index'] as String?,
|
||||||
|
pubTime: json['pub_time'] as String?,
|
||||||
|
pubTs: json['pub_ts'] as int?,
|
||||||
|
published: json['published'] as int?,
|
||||||
|
seasonId: json['season_id'] as int?,
|
||||||
|
squareCover: json['square_cover'] as String?,
|
||||||
|
title: json['title'] as String?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
'cover': cover,
|
||||||
|
'delay': delay,
|
||||||
|
'delay_id': delayId,
|
||||||
|
'delay_index': delayIndex,
|
||||||
|
'delay_reason': delayReason,
|
||||||
|
'enable_vt': enableVt,
|
||||||
|
'ep_cover': epCover,
|
||||||
|
'episode_id': episodeId,
|
||||||
|
'follow': follow,
|
||||||
|
'follows': follows,
|
||||||
|
'icon_font': iconFont?.toJson(),
|
||||||
|
'plays': plays,
|
||||||
|
'pub_index': pubIndex,
|
||||||
|
'pub_time': pubTime,
|
||||||
|
'pub_ts': pubTs,
|
||||||
|
'published': published,
|
||||||
|
'season_id': seasonId,
|
||||||
|
'square_cover': squareCover,
|
||||||
|
'title': title,
|
||||||
|
};
|
||||||
|
}
|
||||||
16
lib/models/bangumi/pgc_timeline/icon_font.dart
Normal file
16
lib/models/bangumi/pgc_timeline/icon_font.dart
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
class IconFont {
|
||||||
|
String? name;
|
||||||
|
String? text;
|
||||||
|
|
||||||
|
IconFont({this.name, this.text});
|
||||||
|
|
||||||
|
factory IconFont.fromJson(Map<String, dynamic> json) => IconFont(
|
||||||
|
name: json['name'] as String?,
|
||||||
|
text: json['text'] as String?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
'name': name,
|
||||||
|
'text': text,
|
||||||
|
};
|
||||||
|
}
|
||||||
23
lib/models/bangumi/pgc_timeline/pgc_timeline.dart
Normal file
23
lib/models/bangumi/pgc_timeline/pgc_timeline.dart
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import 'result.dart';
|
||||||
|
|
||||||
|
class PgcTimeline {
|
||||||
|
int? code;
|
||||||
|
String? message;
|
||||||
|
List<Result>? result;
|
||||||
|
|
||||||
|
PgcTimeline({this.code, this.message, this.result});
|
||||||
|
|
||||||
|
factory PgcTimeline.fromJson(Map<String, dynamic> json) => PgcTimeline(
|
||||||
|
code: json['code'] as int?,
|
||||||
|
message: json['message'] as String?,
|
||||||
|
result: (json['result'] as List<dynamic>?)
|
||||||
|
?.map((e) => Result.fromJson(e as Map<String, dynamic>))
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
'code': code,
|
||||||
|
'message': message,
|
||||||
|
'result': result?.map((e) => e.toJson()).toList(),
|
||||||
|
};
|
||||||
|
}
|
||||||
35
lib/models/bangumi/pgc_timeline/result.dart
Normal file
35
lib/models/bangumi/pgc_timeline/result.dart
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import 'episode.dart';
|
||||||
|
|
||||||
|
class Result {
|
||||||
|
String? date;
|
||||||
|
int? dateTs;
|
||||||
|
int? dayOfWeek;
|
||||||
|
List<Episode>? episodes;
|
||||||
|
int? isToday;
|
||||||
|
|
||||||
|
Result({
|
||||||
|
this.date,
|
||||||
|
this.dateTs,
|
||||||
|
this.dayOfWeek,
|
||||||
|
this.episodes,
|
||||||
|
this.isToday,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory Result.fromJson(Map<String, dynamic> json) => Result(
|
||||||
|
date: json['date'] as String?,
|
||||||
|
dateTs: json['date_ts'] as int?,
|
||||||
|
dayOfWeek: json['day_of_week'] as int?,
|
||||||
|
episodes: (json['episodes'] as List<dynamic>?)
|
||||||
|
?.map((e) => Episode.fromJson(e as Map<String, dynamic>))
|
||||||
|
.toList(),
|
||||||
|
isToday: json['is_today'] as int?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
'date': date,
|
||||||
|
'date_ts': dateTs,
|
||||||
|
'day_of_week': dayOfWeek,
|
||||||
|
'episodes': episodes?.map((e) => e.toJson()).toList(),
|
||||||
|
'is_today': isToday,
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'package:PiliPlus/http/loading_state.dart';
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
import 'package:PiliPlus/models/bangumi/list.dart';
|
import 'package:PiliPlus/models/bangumi/list.dart';
|
||||||
|
import 'package:PiliPlus/models/bangumi/pgc_timeline/result.dart';
|
||||||
import 'package:PiliPlus/models/common/tab_type.dart';
|
import 'package:PiliPlus/models/common/tab_type.dart';
|
||||||
import 'package:PiliPlus/pages/common/common_list_controller.dart';
|
import 'package:PiliPlus/pages/common/common_list_controller.dart';
|
||||||
import 'package:PiliPlus/utils/extension.dart';
|
import 'package:PiliPlus/utils/extension.dart';
|
||||||
@@ -24,6 +25,9 @@ class BangumiController extends CommonListController<
|
|||||||
|
|
||||||
queryData();
|
queryData();
|
||||||
queryBangumiFollow();
|
queryBangumiFollow();
|
||||||
|
if (tabType == TabType.bangumi) {
|
||||||
|
queryPgcTimeline();
|
||||||
|
}
|
||||||
if (isLogin.value) {
|
if (isLogin.value) {
|
||||||
followController = ScrollController();
|
followController = ScrollController();
|
||||||
}
|
}
|
||||||
@@ -36,16 +40,30 @@ class BangumiController extends CommonListController<
|
|||||||
followEnd = false;
|
followEnd = false;
|
||||||
}
|
}
|
||||||
queryBangumiFollow();
|
queryBangumiFollow();
|
||||||
|
if (tabType == TabType.bangumi) {
|
||||||
|
queryPgcTimeline();
|
||||||
|
}
|
||||||
return super.onRefresh();
|
return super.onRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// follow
|
||||||
late int followPage = 1;
|
late int followPage = 1;
|
||||||
late RxInt followCount = (-1).obs;
|
late RxInt followCount = (-1).obs;
|
||||||
late bool followLoading = false;
|
late bool followLoading = false;
|
||||||
late bool followEnd = false;
|
late bool followEnd = false;
|
||||||
late Rx<LoadingState> followState = LoadingState.loading().obs;
|
late Rx<LoadingState<List<BangumiListItemModel>?>> followState =
|
||||||
|
LoadingState<List<BangumiListItemModel>?>.loading().obs;
|
||||||
ScrollController? followController;
|
ScrollController? followController;
|
||||||
|
|
||||||
|
// timeline
|
||||||
|
late Rx<LoadingState<List<Result>?>> timelineState =
|
||||||
|
LoadingState<List<Result>?>.loading().obs;
|
||||||
|
|
||||||
|
Future queryPgcTimeline() async {
|
||||||
|
final res = await BangumiHttp.pgcTimeline(types: 1, before: 6, after: 6);
|
||||||
|
timelineState.value = res;
|
||||||
|
}
|
||||||
|
|
||||||
// 我的订阅
|
// 我的订阅
|
||||||
Future queryBangumiFollow([bool isRefresh = true]) async {
|
Future queryBangumiFollow([bool isRefresh = true]) async {
|
||||||
if (isLogin.value.not || followLoading || (isRefresh.not && followEnd)) {
|
if (isLogin.value.not || followLoading || (isRefresh.not && followEnd)) {
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
import 'dart:async';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:PiliPlus/common/widgets/loading_widget.dart';
|
import 'package:PiliPlus/common/widgets/loading_widget.dart';
|
||||||
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
|
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
|
||||||
import 'package:PiliPlus/http/loading_state.dart';
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
import 'package:PiliPlus/models/bangumi/list.dart';
|
import 'package:PiliPlus/models/bangumi/list.dart';
|
||||||
|
import 'package:PiliPlus/models/bangumi/pgc_timeline/result.dart';
|
||||||
import 'package:PiliPlus/models/common/tab_type.dart';
|
import 'package:PiliPlus/models/common/tab_type.dart';
|
||||||
import 'package:PiliPlus/pages/bangumi/pgc_index/pgc_index_page.dart';
|
import 'package:PiliPlus/pages/bangumi/pgc_index/pgc_index_page.dart';
|
||||||
|
import 'package:PiliPlus/pages/bangumi/widgets/bangumi_card_v_timeline.dart';
|
||||||
import 'package:PiliPlus/pages/common/common_page.dart';
|
import 'package:PiliPlus/pages/common/common_page.dart';
|
||||||
|
import 'package:PiliPlus/utils/extension.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:PiliPlus/common/constants.dart';
|
import 'package:PiliPlus/common/constants.dart';
|
||||||
@@ -45,108 +48,148 @@ class _BangumiPageState extends CommonPageState<BangumiPage, BangumiController>
|
|||||||
super.build(context);
|
super.build(context);
|
||||||
return refreshIndicator(
|
return refreshIndicator(
|
||||||
onRefresh: () async {
|
onRefresh: () async {
|
||||||
await Future.wait([
|
await controller.onRefresh();
|
||||||
controller.onRefresh(),
|
|
||||||
controller.queryBangumiFollow(),
|
|
||||||
]);
|
|
||||||
},
|
},
|
||||||
child: CustomScrollView(
|
child: CustomScrollView(
|
||||||
controller: controller.scrollController,
|
controller: controller.scrollController,
|
||||||
physics: const AlwaysScrollableScrollPhysics(),
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
slivers: [
|
slivers: [
|
||||||
|
_buildFollow,
|
||||||
|
if (widget.tabType == TabType.bangumi)
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
child: Obx(
|
child: Container(
|
||||||
() => controller.isLogin.value
|
margin: const EdgeInsets.only(top: 10),
|
||||||
? Column(
|
height: Grid.smallCardWidth / 2 / 0.75 +
|
||||||
|
MediaQuery.textScalerOf(context).scale(110),
|
||||||
|
child:
|
||||||
|
Obx(() => _buildTimeline(controller.timelineState.value)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
..._buildRcmd,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
late final List<String> weekList = [
|
||||||
|
'一',
|
||||||
|
'二',
|
||||||
|
'三',
|
||||||
|
'四',
|
||||||
|
'五',
|
||||||
|
'六',
|
||||||
|
'日',
|
||||||
|
];
|
||||||
|
|
||||||
|
Widget _buildTimeline(LoadingState<List<Result>?> loadingState) =>
|
||||||
|
switch (loadingState) {
|
||||||
|
Loading() => loadingWidget,
|
||||||
|
Success() => loadingState.response?.isNotEmpty == true
|
||||||
|
? Builder(builder: (context) {
|
||||||
|
final initialIndex = max(
|
||||||
|
0,
|
||||||
|
loadingState.response!
|
||||||
|
.indexWhere((item) => item.isToday == 1));
|
||||||
|
return DefaultTabController(
|
||||||
|
initialIndex: initialIndex,
|
||||||
|
length: loadingState.response!.length,
|
||||||
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Row(
|
||||||
padding: const EdgeInsets.only(left: 16),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
children: [
|
||||||
Obx(
|
const SizedBox(width: 16),
|
||||||
() => Text(
|
Text(
|
||||||
'最近${widget.tabType == TabType.bangumi ? '追番' : '追剧'}${controller.followCount.value == -1 ? '' : ' ${controller.followCount.value}'}',
|
'追番时间表',
|
||||||
style:
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
Theme.of(context).textTheme.titleMedium,
|
),
|
||||||
|
const SizedBox(width: 16),
|
||||||
|
Expanded(
|
||||||
|
child: Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: TabBar(
|
||||||
|
isScrollable: true,
|
||||||
|
tabAlignment: TabAlignment.start,
|
||||||
|
tabs: loadingState.response!
|
||||||
|
.map(
|
||||||
|
(item) => Tab(
|
||||||
|
text:
|
||||||
|
'${item.date} ${item.isToday == 1 ? '今天' : '周${weekList[item.dayOfWeek! - 1]}'}',
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
|
||||||
IconButton(
|
|
||||||
tooltip: '刷新',
|
|
||||||
onPressed: () {
|
|
||||||
controller
|
|
||||||
..followPage = 1
|
|
||||||
..followEnd = false
|
|
||||||
..queryBangumiFollow();
|
|
||||||
},
|
|
||||||
icon: const Icon(
|
|
||||||
Icons.refresh,
|
|
||||||
size: 20,
|
|
||||||
),
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Expanded(
|
||||||
|
child: TabBarView(
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
children: loadingState.response!.map((item) {
|
||||||
|
if (item.episodes!.isNullOrEmpty) {
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
return MediaQuery.removePadding(
|
||||||
|
context: context,
|
||||||
|
removeLeft: context.orientation ==
|
||||||
|
Orientation.landscape,
|
||||||
|
child: ListView.builder(
|
||||||
|
physics:
|
||||||
|
const AlwaysScrollableScrollPhysics(),
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
itemCount: item.episodes!.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Container(
|
||||||
|
width: Grid.smallCardWidth / 2,
|
||||||
|
margin: EdgeInsets.only(
|
||||||
|
left: StyleString.safeSpace,
|
||||||
|
right:
|
||||||
|
index == item.episodes!.length - 1
|
||||||
|
? StyleString.safeSpace
|
||||||
|
: 0,
|
||||||
|
),
|
||||||
|
child: BangumiCardVTimeline(
|
||||||
|
item: item.episodes![index],
|
||||||
),
|
),
|
||||||
Obx(
|
|
||||||
() => controller.isLogin.value
|
|
||||||
? Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 10),
|
|
||||||
child: GestureDetector(
|
|
||||||
behavior: HitTestBehavior.opaque,
|
|
||||||
onTap: () {
|
|
||||||
Get.toNamed(
|
|
||||||
'/fav',
|
|
||||||
arguments: widget.tabType ==
|
|
||||||
TabType.bangumi
|
|
||||||
? 1
|
|
||||||
: 2,
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
vertical: 8),
|
|
||||||
child: Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'查看全部',
|
|
||||||
strutStyle: StrutStyle(
|
|
||||||
leading: 0, height: 1),
|
|
||||||
style: TextStyle(
|
|
||||||
height: 1,
|
|
||||||
color: Theme.of(context)
|
|
||||||
.colorScheme
|
|
||||||
.secondary,
|
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
Icon(
|
}).toList()),
|
||||||
Icons.chevron_right,
|
|
||||||
color: Theme.of(context)
|
|
||||||
.colorScheme
|
|
||||||
.secondary,
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
),
|
})
|
||||||
)
|
|
||||||
: const SizedBox.shrink(),
|
: const SizedBox.shrink(),
|
||||||
),
|
Error() => GestureDetector(
|
||||||
],
|
behavior: HitTestBehavior.opaque,
|
||||||
|
onTap: controller.queryPgcTimeline,
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Text(
|
||||||
|
loadingState.errMsg,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(
|
),
|
||||||
height: Grid.smallCardWidth / 2 / 0.75 +
|
LoadingState() => throw UnimplementedError(),
|
||||||
MediaQuery.textScalerOf(context).scale(50),
|
};
|
||||||
child: Obx(
|
|
||||||
() =>
|
List<Widget> get _buildRcmd => [
|
||||||
_buildFollowBody(controller.followState.value),
|
_buildRcmdTitle,
|
||||||
|
SliverPadding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(
|
||||||
|
StyleString.safeSpace, 0, StyleString.safeSpace, 0),
|
||||||
|
sliver: Obx(
|
||||||
|
() => _buildRcmdBody(controller.loadingState.value),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
];
|
||||||
)
|
|
||||||
: const SizedBox.shrink(),
|
Widget get _buildRcmdTitle => SliverToBoxAdapter(
|
||||||
),
|
|
||||||
),
|
|
||||||
SliverToBoxAdapter(
|
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
top: 10,
|
top: 10,
|
||||||
@@ -224,20 +267,10 @@ class _BangumiPageState extends CommonPageState<BangumiPage, BangumiController>
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
SliverPadding(
|
|
||||||
padding: const EdgeInsets.fromLTRB(
|
|
||||||
StyleString.safeSpace, 0, StyleString.safeSpace, 0),
|
|
||||||
sliver: Obx(
|
|
||||||
() => _buildBody(controller.loadingState.value),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildBody(LoadingState<List<BangumiListItemModel>?> loadingState) {
|
Widget _buildRcmdBody(
|
||||||
|
LoadingState<List<BangumiListItemModel>?> loadingState) {
|
||||||
return switch (loadingState) {
|
return switch (loadingState) {
|
||||||
Loading() => const SliverToBoxAdapter(),
|
Loading() => const SliverToBoxAdapter(),
|
||||||
Success() => loadingState.response?.isNotEmpty == true
|
Success() => loadingState.response?.isNotEmpty == true
|
||||||
@@ -274,36 +307,122 @@ class _BangumiPageState extends CommonPageState<BangumiPage, BangumiController>
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildFollowList(Success loadingState) {
|
Widget get _buildFollow => SliverToBoxAdapter(
|
||||||
return ListView.builder(
|
child: Obx(
|
||||||
|
() => controller.isLogin.value
|
||||||
|
? Column(
|
||||||
|
children: [
|
||||||
|
_buildFollowTitle,
|
||||||
|
SizedBox(
|
||||||
|
height: Grid.smallCardWidth / 2 / 0.75 +
|
||||||
|
MediaQuery.textScalerOf(context).scale(50),
|
||||||
|
child: Obx(
|
||||||
|
() => _buildFollowBody(controller.followState.value),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: const SizedBox.shrink(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget get _buildFollowTitle => Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 16),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Obx(
|
||||||
|
() => Text(
|
||||||
|
'最近${widget.tabType == TabType.bangumi ? '追番' : '追剧'}${controller.followCount.value == -1 ? '' : ' ${controller.followCount.value}'}',
|
||||||
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
IconButton(
|
||||||
|
tooltip: '刷新',
|
||||||
|
onPressed: () {
|
||||||
|
controller
|
||||||
|
..followPage = 1
|
||||||
|
..followEnd = false
|
||||||
|
..queryBangumiFollow();
|
||||||
|
},
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.refresh,
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Obx(
|
||||||
|
() => controller.isLogin.value
|
||||||
|
? Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||||
|
child: GestureDetector(
|
||||||
|
behavior: HitTestBehavior.opaque,
|
||||||
|
onTap: () {
|
||||||
|
Get.toNamed(
|
||||||
|
'/fav',
|
||||||
|
arguments:
|
||||||
|
widget.tabType == TabType.bangumi ? 1 : 2,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'查看全部',
|
||||||
|
strutStyle: StrutStyle(leading: 0, height: 1),
|
||||||
|
style: TextStyle(
|
||||||
|
height: 1,
|
||||||
|
color:
|
||||||
|
Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Icon(
|
||||||
|
Icons.chevron_right,
|
||||||
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: const SizedBox.shrink(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget _buildFollowBody(
|
||||||
|
LoadingState<List<BangumiListItemModel>?> loadingState) {
|
||||||
|
return switch (loadingState) {
|
||||||
|
Loading() => loadingWidget,
|
||||||
|
Success() => loadingState.response?.isNotEmpty == true
|
||||||
|
? MediaQuery.removePadding(
|
||||||
|
context: context,
|
||||||
|
removeLeft: context.orientation == Orientation.landscape,
|
||||||
|
child: ListView.builder(
|
||||||
controller: controller.followController,
|
controller: controller.followController,
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
itemCount: loadingState.response.length,
|
itemCount: loadingState.response!.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
if (index == loadingState.response.length - 1) {
|
if (index == loadingState.response!.length - 1) {
|
||||||
controller.queryBangumiFollow(false);
|
controller.queryBangumiFollow(false);
|
||||||
}
|
}
|
||||||
return Container(
|
return Container(
|
||||||
width: Grid.smallCardWidth / 2,
|
width: Grid.smallCardWidth / 2,
|
||||||
margin: EdgeInsets.only(
|
margin: EdgeInsets.only(
|
||||||
left: StyleString.safeSpace,
|
left: StyleString.safeSpace,
|
||||||
right: index == loadingState.response.length - 1
|
right: index == loadingState.response!.length - 1
|
||||||
? StyleString.safeSpace
|
? StyleString.safeSpace
|
||||||
: 0,
|
: 0,
|
||||||
),
|
),
|
||||||
child: BangumiCardV(
|
child: BangumiCardV(
|
||||||
bangumiItem: loadingState.response[index],
|
bangumiItem: loadingState.response![index],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
),
|
||||||
}
|
)
|
||||||
|
|
||||||
Widget _buildFollowBody(LoadingState loadingState) {
|
|
||||||
return switch (loadingState) {
|
|
||||||
Loading() => loadingWidget,
|
|
||||||
Success() => (loadingState.response as List?)?.isNotEmpty == true
|
|
||||||
? _buildFollowList(loadingState)
|
|
||||||
: Center(
|
: Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
'还没有${widget.tabType == TabType.bangumi ? '追番' : '追剧'}')),
|
'还没有${widget.tabType == TabType.bangumi ? '追番' : '追剧'}')),
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ class BangumiCardV extends StatelessWidget {
|
|||||||
Utils.viewBangumi(seasonId: seasonId);
|
Utils.viewBangumi(seasonId: seasonId);
|
||||||
},
|
},
|
||||||
child: Column(
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
ClipRRect(
|
ClipRRect(
|
||||||
borderRadius: StyleString.mdRadius,
|
borderRadius: StyleString.mdRadius,
|
||||||
@@ -49,7 +50,6 @@ class BangumiCardV extends StatelessWidget {
|
|||||||
height: maxHeight,
|
height: maxHeight,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (bangumiItem.badge != null)
|
|
||||||
PBadge(
|
PBadge(
|
||||||
text: bangumiItem.badge,
|
text: bangumiItem.badge,
|
||||||
top: 6,
|
top: 6,
|
||||||
@@ -97,10 +97,7 @@ class BangumiCardV extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Text(
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
bangumiItem.title,
|
bangumiItem.title,
|
||||||
textAlign: TextAlign.start,
|
textAlign: TextAlign.start,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
@@ -108,8 +105,6 @@ class BangumiCardV extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
)),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
const SizedBox(height: 1),
|
const SizedBox(height: 1),
|
||||||
if (bangumiItem.indexShow != null)
|
if (bangumiItem.indexShow != null)
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ class BangumiCardVMemberHome extends StatelessWidget {
|
|||||||
cover: bangumiItem.cover,
|
cover: bangumiItem.cover,
|
||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
ClipRRect(
|
ClipRRect(
|
||||||
borderRadius: const BorderRadius.only(
|
borderRadius: const BorderRadius.only(
|
||||||
@@ -94,10 +95,7 @@ Widget bangumiContent(Item bangumiItem) {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Text(
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
bangumiItem.title,
|
bangumiItem.title,
|
||||||
textAlign: TextAlign.start,
|
textAlign: TextAlign.start,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
@@ -105,8 +103,6 @@ Widget bangumiContent(Item bangumiItem) {
|
|||||||
),
|
),
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
)),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
const SizedBox(height: 1),
|
const SizedBox(height: 1),
|
||||||
// if (bangumiItem.indexShow != null)
|
// if (bangumiItem.indexShow != null)
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ class BangumiCardVPgcIndex extends StatelessWidget {
|
|||||||
Utils.viewBangumi(seasonId: bangumiItem['season_id']);
|
Utils.viewBangumi(seasonId: bangumiItem['season_id']);
|
||||||
},
|
},
|
||||||
child: Column(
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
ClipRRect(
|
ClipRRect(
|
||||||
borderRadius: StyleString.mdRadius,
|
borderRadius: StyleString.mdRadius,
|
||||||
@@ -44,8 +45,6 @@ class BangumiCardVPgcIndex extends StatelessWidget {
|
|||||||
width: maxWidth,
|
width: maxWidth,
|
||||||
height: maxHeight,
|
height: maxHeight,
|
||||||
),
|
),
|
||||||
if (bangumiItem['badge'] != null &&
|
|
||||||
bangumiItem['badge'] != '')
|
|
||||||
PBadge(
|
PBadge(
|
||||||
text: bangumiItem['badge'],
|
text: bangumiItem['badge'],
|
||||||
top: 6,
|
top: 6,
|
||||||
@@ -53,8 +52,6 @@ class BangumiCardVPgcIndex extends StatelessWidget {
|
|||||||
bottom: null,
|
bottom: null,
|
||||||
left: null,
|
left: null,
|
||||||
),
|
),
|
||||||
if (bangumiItem['order'] != null &&
|
|
||||||
bangumiItem['order'] != '')
|
|
||||||
PBadge(
|
PBadge(
|
||||||
text: bangumiItem['order'],
|
text: bangumiItem['order'],
|
||||||
top: null,
|
top: null,
|
||||||
@@ -86,10 +83,7 @@ class BangumiCardVPgcIndex extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Text(
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
bangumiItem['title'],
|
bangumiItem['title'],
|
||||||
textAlign: TextAlign.start,
|
textAlign: TextAlign.start,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
@@ -97,8 +91,6 @@ class BangumiCardVPgcIndex extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
)),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
const SizedBox(height: 1),
|
const SizedBox(height: 1),
|
||||||
if (bangumiItem['index_show'] != null)
|
if (bangumiItem['index_show'] != null)
|
||||||
|
|||||||
105
lib/pages/bangumi/widgets/bangumi_card_v_timeline.dart
Normal file
105
lib/pages/bangumi/widgets/bangumi_card_v_timeline.dart
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
import 'package:PiliPlus/common/widgets/image_save.dart';
|
||||||
|
import 'package:PiliPlus/models/bangumi/pgc_timeline/episode.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:PiliPlus/common/constants.dart';
|
||||||
|
import 'package:PiliPlus/common/widgets/badge.dart';
|
||||||
|
import 'package:PiliPlus/utils/utils.dart';
|
||||||
|
import 'package:PiliPlus/common/widgets/network_img_layer.dart';
|
||||||
|
|
||||||
|
// 视频卡片 - 垂直布局
|
||||||
|
class BangumiCardVTimeline extends StatelessWidget {
|
||||||
|
const BangumiCardVTimeline({
|
||||||
|
super.key,
|
||||||
|
required this.item,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Episode item;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Card(
|
||||||
|
clipBehavior: Clip.hardEdge,
|
||||||
|
margin: EdgeInsets.zero,
|
||||||
|
child: InkWell(
|
||||||
|
onLongPress: () => imageSaveDialog(
|
||||||
|
context: context,
|
||||||
|
title: item.title,
|
||||||
|
cover: item.cover,
|
||||||
|
),
|
||||||
|
onTap: () async {
|
||||||
|
Utils.viewBangumi(
|
||||||
|
seasonId: item.seasonId,
|
||||||
|
epId: item.episodeId,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
ClipRRect(
|
||||||
|
borderRadius: StyleString.mdRadius,
|
||||||
|
child: AspectRatio(
|
||||||
|
aspectRatio: 0.75,
|
||||||
|
child: LayoutBuilder(builder: (context, boxConstraints) {
|
||||||
|
final double maxWidth = boxConstraints.maxWidth;
|
||||||
|
final double maxHeight = boxConstraints.maxHeight;
|
||||||
|
return Stack(
|
||||||
|
children: [
|
||||||
|
NetworkImgLayer(
|
||||||
|
src: item.cover,
|
||||||
|
width: maxWidth,
|
||||||
|
height: maxHeight,
|
||||||
|
),
|
||||||
|
if (item.follow == 1)
|
||||||
|
PBadge(
|
||||||
|
text: '已追番',
|
||||||
|
right: 6,
|
||||||
|
top: 6,
|
||||||
|
),
|
||||||
|
PBadge(
|
||||||
|
text: '${item.pubTime}',
|
||||||
|
left: 6,
|
||||||
|
bottom: 6,
|
||||||
|
type: 'gray',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
bagumiContent(context)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget bagumiContent(context) {
|
||||||
|
return Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(4, 5, 0, 3),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
item.title ?? '',
|
||||||
|
textAlign: TextAlign.start,
|
||||||
|
style: const TextStyle(
|
||||||
|
letterSpacing: 0.3,
|
||||||
|
),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
item.pubIndex ?? '',
|
||||||
|
maxLines: 1,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: Theme.of(context).textTheme.labelMedium!.fontSize,
|
||||||
|
color: Theme.of(context).colorScheme.outline,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -516,14 +516,11 @@ Widget forWard(bool isSave, item, BuildContext context, source, callback,
|
|||||||
src: item.modules.moduleDynamic.major.medialist['cover'],
|
src: item.modules.moduleDynamic.major.medialist['cover'],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (item.modules.moduleDynamic.major.medialist['badge']
|
|
||||||
?['text'] !=
|
|
||||||
null)
|
|
||||||
PBadge(
|
PBadge(
|
||||||
right: 6,
|
right: 6,
|
||||||
top: 6,
|
top: 6,
|
||||||
text: item.modules.moduleDynamic.major.medialist['badge']
|
text: item.modules.moduleDynamic.major.medialist['badge']
|
||||||
['text'],
|
?['text'],
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -65,7 +65,6 @@ class FavPgcItem extends StatelessWidget {
|
|||||||
width: boxConstraints.maxWidth,
|
width: boxConstraints.maxWidth,
|
||||||
height: boxConstraints.maxHeight,
|
height: boxConstraints.maxHeight,
|
||||||
),
|
),
|
||||||
if (item.badge?.isNotEmpty == true)
|
|
||||||
PBadge(
|
PBadge(
|
||||||
right: 4,
|
right: 4,
|
||||||
top: 4,
|
top: 4,
|
||||||
|
|||||||
@@ -123,9 +123,8 @@ class FavVideoCardH extends StatelessWidget {
|
|||||||
bottom: 6.0,
|
bottom: 6.0,
|
||||||
type: 'gray',
|
type: 'gray',
|
||||||
),
|
),
|
||||||
if (videoItem.ogv != null)
|
|
||||||
PBadge(
|
PBadge(
|
||||||
text: videoItem.ogv!['type_name'],
|
text: videoItem.ogv?['type_name'],
|
||||||
top: 6.0,
|
top: 6.0,
|
||||||
right: 6.0,
|
right: 6.0,
|
||||||
bottom: null,
|
bottom: null,
|
||||||
|
|||||||
@@ -186,7 +186,10 @@ class _LivePageState extends CommonPageState<LivePage, LiveController>
|
|||||||
child: loadingWidget,
|
child: loadingWidget,
|
||||||
),
|
),
|
||||||
Success() => (loadingState.response as List?)?.isNotEmpty == true
|
Success() => (loadingState.response as List?)?.isNotEmpty == true
|
||||||
? SelfSizedHorizontalList(
|
? MediaQuery.removePadding(
|
||||||
|
context: context,
|
||||||
|
removeLeft: context.orientation == Orientation.landscape,
|
||||||
|
child: SelfSizedHorizontalList(
|
||||||
gapSize: 5,
|
gapSize: 5,
|
||||||
childBuilder: (index) {
|
childBuilder: (index) {
|
||||||
if (index == loadingState.response.length - 1) {
|
if (index == loadingState.response.length - 1) {
|
||||||
@@ -233,12 +236,12 @@ class _LivePageState extends CommonPageState<LivePage, LiveController>
|
|||||||
src: loadingState.response[index].face,
|
src: loadingState.response[index].face,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 2),
|
const SizedBox(height: 4),
|
||||||
Text(
|
Text(
|
||||||
loadingState.response[index].uname,
|
loadingState.response[index].uname,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
style: TextStyle(fontSize: 11),
|
style: TextStyle(fontSize: 12),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -247,6 +250,7 @@ class _LivePageState extends CommonPageState<LivePage, LiveController>
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
itemCount: loadingState.response.length,
|
itemCount: loadingState.response.length,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
: const SizedBox.shrink(),
|
: const SizedBox.shrink(),
|
||||||
Error() => GestureDetector(
|
Error() => GestureDetector(
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ Widget searchBangumiPanel(
|
|||||||
height: 148,
|
height: 148,
|
||||||
src: i.cover,
|
src: i.cover,
|
||||||
),
|
),
|
||||||
if (i.seasonTypeName?.isNotEmpty == true)
|
|
||||||
PBadge(
|
PBadge(
|
||||||
text: i.seasonTypeName,
|
text: i.seasonTypeName,
|
||||||
top: 6.0,
|
top: 6.0,
|
||||||
|
|||||||
Reference in New Issue
Block a user