mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
wip
This commit is contained in:
@@ -300,6 +300,8 @@ class Api {
|
||||
static const String spaceBangumi =
|
||||
'${HttpString.appBaseUrl}/x/v2/space/bangumi';
|
||||
|
||||
static const String spaceFav = '/x/v3/fav/folder/space';
|
||||
|
||||
// 用户名片信息
|
||||
static const String memberCardInfo = '/x/web-interface/card';
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:PiliPalaX/grpc/grpc_repo.dart';
|
||||
import 'package:PiliPalaX/http/constants.dart';
|
||||
import 'package:PiliPalaX/http/loading_state.dart';
|
||||
import 'package:PiliPalaX/models/space/data.dart';
|
||||
import 'package:PiliPalaX/models/space_fav/space_fav.dart';
|
||||
import 'package:PiliPalaX/pages/member/new/content/member_contribute/member_contribute.dart'
|
||||
show ContributeType;
|
||||
import 'package:PiliPalaX/utils/storage.dart';
|
||||
@@ -57,6 +58,51 @@ class MemberHttp {
|
||||
}
|
||||
}
|
||||
|
||||
static Future<LoadingState> spaceFav({
|
||||
required int mid,
|
||||
}) async {
|
||||
String? accessKey = GStorage.localCache
|
||||
.get(LocalCacheKey.accessKey, defaultValue: {})['value'];
|
||||
Map<String, String> data = {
|
||||
if (accessKey != null) 'access_key': accessKey,
|
||||
'appkey': Constants.appKey,
|
||||
'build': '1462100',
|
||||
'c_locale': 'zh_CN',
|
||||
'channel': 'yingyongbao',
|
||||
'mobi_app': 'android_hd',
|
||||
'platform': 'android',
|
||||
's_locale': 'zh_CN',
|
||||
'statistics': Constants.statistics,
|
||||
'ts': (DateTime.now().millisecondsSinceEpoch ~/ 1000).toString(),
|
||||
'up_mid': mid.toString(),
|
||||
};
|
||||
String sign = Utils.appSign(
|
||||
data,
|
||||
Constants.appKey,
|
||||
Constants.appSec,
|
||||
);
|
||||
data['sign'] = sign;
|
||||
int? _mid = GStorage.userInfo.get('userInfoCache')?.mid;
|
||||
dynamic res = await Request().get(
|
||||
Api.spaceFav,
|
||||
data: data,
|
||||
options: Options(
|
||||
headers: {
|
||||
'env': 'prod',
|
||||
'app-key': 'android_hd',
|
||||
'x-bili-mid': _mid,
|
||||
'bili-http-engine': 'cronet',
|
||||
'user-agent': Constants.userAgent,
|
||||
},
|
||||
),
|
||||
);
|
||||
if (res.data['code'] == 0) {
|
||||
return LoadingState.success(SpaceFav.fromJson(res.data).data);
|
||||
} else {
|
||||
return LoadingState.error(res.data['message']);
|
||||
}
|
||||
}
|
||||
|
||||
static Future<LoadingState> spaceArchive({
|
||||
required ContributeType type,
|
||||
required int? mid,
|
||||
|
||||
19
lib/models/space_fav/datum.dart
Normal file
19
lib/models/space_fav/datum.dart
Normal file
@@ -0,0 +1,19 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'media_list_response.dart';
|
||||
|
||||
part 'datum.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class Datum {
|
||||
int? id;
|
||||
String? name;
|
||||
MediaListResponse? mediaListResponse;
|
||||
String? uri;
|
||||
|
||||
Datum({this.id, this.name, this.mediaListResponse, this.uri});
|
||||
|
||||
factory Datum.fromJson(Map<String, dynamic> json) => _$DatumFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$DatumToJson(this);
|
||||
}
|
||||
24
lib/models/space_fav/datum.g.dart
Normal file
24
lib/models/space_fav/datum.g.dart
Normal file
@@ -0,0 +1,24 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'datum.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
Datum _$DatumFromJson(Map<String, dynamic> json) => Datum(
|
||||
id: (json['id'] as num?)?.toInt(),
|
||||
name: json['name'] as String?,
|
||||
mediaListResponse: json['mediaListResponse'] == null
|
||||
? null
|
||||
: MediaListResponse.fromJson(
|
||||
json['mediaListResponse'] as Map<String, dynamic>),
|
||||
uri: json['uri'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$DatumToJson(Datum instance) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'name': instance.name,
|
||||
'mediaListResponse': instance.mediaListResponse,
|
||||
'uri': instance.uri,
|
||||
};
|
||||
70
lib/models/space_fav/list.dart
Normal file
70
lib/models/space_fav/list.dart
Normal file
@@ -0,0 +1,70 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'upper.dart';
|
||||
|
||||
part 'list.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class FavList {
|
||||
int? id;
|
||||
int? fid;
|
||||
int? mid;
|
||||
int? attr;
|
||||
@JsonKey(name: 'attr_desc')
|
||||
String? attrDesc;
|
||||
String? title;
|
||||
String? cover;
|
||||
Upper? upper;
|
||||
@JsonKey(name: 'cover_type')
|
||||
int? coverType;
|
||||
String? intro;
|
||||
int? ctime;
|
||||
int? mtime;
|
||||
int? state;
|
||||
@JsonKey(name: 'fav_state')
|
||||
int? favState;
|
||||
@JsonKey(name: 'media_count')
|
||||
int? mediaCount;
|
||||
@JsonKey(name: 'view_count')
|
||||
int? viewCount;
|
||||
int? vt;
|
||||
@JsonKey(name: 'is_top')
|
||||
bool? isTop;
|
||||
@JsonKey(name: 'recent_fav')
|
||||
dynamic recentFav;
|
||||
@JsonKey(name: 'play_switch')
|
||||
int? playSwitch;
|
||||
int? type;
|
||||
String? link;
|
||||
String? bvid;
|
||||
|
||||
FavList({
|
||||
this.id,
|
||||
this.fid,
|
||||
this.mid,
|
||||
this.attr,
|
||||
this.attrDesc,
|
||||
this.title,
|
||||
this.cover,
|
||||
this.upper,
|
||||
this.coverType,
|
||||
this.intro,
|
||||
this.ctime,
|
||||
this.mtime,
|
||||
this.state,
|
||||
this.favState,
|
||||
this.mediaCount,
|
||||
this.viewCount,
|
||||
this.vt,
|
||||
this.isTop,
|
||||
this.recentFav,
|
||||
this.playSwitch,
|
||||
this.type,
|
||||
this.link,
|
||||
this.bvid,
|
||||
});
|
||||
|
||||
factory FavList.fromJson(Map<String, dynamic> json) => _$ListFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$ListToJson(this);
|
||||
}
|
||||
61
lib/models/space_fav/list.g.dart
Normal file
61
lib/models/space_fav/list.g.dart
Normal file
@@ -0,0 +1,61 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'list.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
FavList _$ListFromJson(Map<String, dynamic> json) => FavList(
|
||||
id: (json['id'] as num?)?.toInt(),
|
||||
fid: (json['fid'] as num?)?.toInt(),
|
||||
mid: (json['mid'] as num?)?.toInt(),
|
||||
attr: (json['attr'] as num?)?.toInt(),
|
||||
attrDesc: json['attr_desc'] as String?,
|
||||
title: json['title'] as String?,
|
||||
cover: json['cover'] as String?,
|
||||
upper: json['upper'] == null
|
||||
? null
|
||||
: Upper.fromJson(json['upper'] as Map<String, dynamic>),
|
||||
coverType: (json['cover_type'] as num?)?.toInt(),
|
||||
intro: json['intro'] as String?,
|
||||
ctime: (json['ctime'] as num?)?.toInt(),
|
||||
mtime: (json['mtime'] as num?)?.toInt(),
|
||||
state: (json['state'] as num?)?.toInt(),
|
||||
favState: (json['fav_state'] as num?)?.toInt(),
|
||||
mediaCount: (json['media_count'] as num?)?.toInt(),
|
||||
viewCount: (json['view_count'] as num?)?.toInt(),
|
||||
vt: (json['vt'] as num?)?.toInt(),
|
||||
isTop: json['is_top'] as bool?,
|
||||
recentFav: json['recent_fav'],
|
||||
playSwitch: (json['play_switch'] as num?)?.toInt(),
|
||||
type: (json['type'] as num?)?.toInt(),
|
||||
link: json['link'] as String?,
|
||||
bvid: json['bvid'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$ListToJson(FavList instance) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'fid': instance.fid,
|
||||
'mid': instance.mid,
|
||||
'attr': instance.attr,
|
||||
'attr_desc': instance.attrDesc,
|
||||
'title': instance.title,
|
||||
'cover': instance.cover,
|
||||
'upper': instance.upper,
|
||||
'cover_type': instance.coverType,
|
||||
'intro': instance.intro,
|
||||
'ctime': instance.ctime,
|
||||
'mtime': instance.mtime,
|
||||
'state': instance.state,
|
||||
'fav_state': instance.favState,
|
||||
'media_count': instance.mediaCount,
|
||||
'view_count': instance.viewCount,
|
||||
'vt': instance.vt,
|
||||
'is_top': instance.isTop,
|
||||
'recent_fav': instance.recentFav,
|
||||
'play_switch': instance.playSwitch,
|
||||
'type': instance.type,
|
||||
'link': instance.link,
|
||||
'bvid': instance.bvid,
|
||||
};
|
||||
21
lib/models/space_fav/media_list_response.dart
Normal file
21
lib/models/space_fav/media_list_response.dart
Normal file
@@ -0,0 +1,21 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'list.dart';
|
||||
|
||||
part 'media_list_response.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class MediaListResponse {
|
||||
int? count;
|
||||
List<FavList>? list;
|
||||
@JsonKey(name: 'has_more')
|
||||
bool? hasMore;
|
||||
|
||||
MediaListResponse({this.count, this.list, this.hasMore});
|
||||
|
||||
factory MediaListResponse.fromJson(Map<String, dynamic> json) {
|
||||
return _$MediaListResponseFromJson(json);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => _$MediaListResponseToJson(this);
|
||||
}
|
||||
23
lib/models/space_fav/media_list_response.g.dart
Normal file
23
lib/models/space_fav/media_list_response.g.dart
Normal file
@@ -0,0 +1,23 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'media_list_response.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
MediaListResponse _$MediaListResponseFromJson(Map<String, dynamic> json) =>
|
||||
MediaListResponse(
|
||||
count: (json['count'] as num?)?.toInt(),
|
||||
list: (json['list'] as List<dynamic>?)
|
||||
?.map((item) => FavList.fromJson(item))
|
||||
.toList(),
|
||||
hasMore: json['has_more'] as bool?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$MediaListResponseToJson(MediaListResponse instance) =>
|
||||
<String, dynamic>{
|
||||
'count': instance.count,
|
||||
'list': instance.list,
|
||||
'has_more': instance.hasMore,
|
||||
};
|
||||
21
lib/models/space_fav/space_fav.dart
Normal file
21
lib/models/space_fav/space_fav.dart
Normal file
@@ -0,0 +1,21 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'datum.dart';
|
||||
|
||||
part 'space_fav.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class SpaceFav {
|
||||
int? code;
|
||||
String? message;
|
||||
int? ttl;
|
||||
List<Datum>? data;
|
||||
|
||||
SpaceFav({this.code, this.message, this.ttl, this.data});
|
||||
|
||||
factory SpaceFav.fromJson(Map<String, dynamic> json) {
|
||||
return _$SpaceFavFromJson(json);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => _$SpaceFavToJson(this);
|
||||
}
|
||||
23
lib/models/space_fav/space_fav.g.dart
Normal file
23
lib/models/space_fav/space_fav.g.dart
Normal file
@@ -0,0 +1,23 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'space_fav.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
SpaceFav _$SpaceFavFromJson(Map<String, dynamic> json) => SpaceFav(
|
||||
code: (json['code'] as num?)?.toInt(),
|
||||
message: json['message'] as String?,
|
||||
ttl: (json['ttl'] as num?)?.toInt(),
|
||||
data: (json['data'] as List<dynamic>?)
|
||||
?.map((e) => Datum.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$SpaceFavToJson(SpaceFav instance) => <String, dynamic>{
|
||||
'code': instance.code,
|
||||
'message': instance.message,
|
||||
'ttl': instance.ttl,
|
||||
'data': instance.data,
|
||||
};
|
||||
16
lib/models/space_fav/upper.dart
Normal file
16
lib/models/space_fav/upper.dart
Normal file
@@ -0,0 +1,16 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'upper.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class Upper {
|
||||
int? mid;
|
||||
String? name;
|
||||
String? face;
|
||||
|
||||
Upper({this.mid, this.name, this.face});
|
||||
|
||||
factory Upper.fromJson(Map<String, dynamic> json) => _$UpperFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$UpperToJson(this);
|
||||
}
|
||||
19
lib/models/space_fav/upper.g.dart
Normal file
19
lib/models/space_fav/upper.g.dart
Normal file
@@ -0,0 +1,19 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'upper.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
Upper _$UpperFromJson(Map<String, dynamic> json) => Upper(
|
||||
mid: (json['mid'] as num?)?.toInt(),
|
||||
name: json['name'] as String?,
|
||||
face: json['face'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$UpperToJson(Upper instance) => <String, dynamic>{
|
||||
'mid': instance.mid,
|
||||
'name': instance.name,
|
||||
'face': instance.face,
|
||||
};
|
||||
@@ -7,15 +7,18 @@ import 'package:PiliPalaX/http/video.dart';
|
||||
import 'package:PiliPalaX/models/user/fav_folder.dart';
|
||||
|
||||
class FavDetailController extends CommonController {
|
||||
FavFolderItemData? item;
|
||||
// FavFolderItemData? item;
|
||||
int? mediaId;
|
||||
late String heroTag;
|
||||
RxString loadingText = '加载中...'.obs;
|
||||
int mediaCount = 0;
|
||||
RxString title = ''.obs;
|
||||
RxString cover = ''.obs;
|
||||
RxString name = ''.obs;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
item = Get.arguments;
|
||||
// item = Get.arguments;
|
||||
if (Get.parameters.keys.isNotEmpty) {
|
||||
mediaId = int.parse(Get.parameters['mediaId']!);
|
||||
heroTag = Get.parameters['heroTag']!;
|
||||
@@ -42,6 +45,9 @@ class FavDetailController extends CommonController {
|
||||
@override
|
||||
bool customHandleResponse(Success response) {
|
||||
if (currentPage == 1) {
|
||||
title.value = response.response.info['title'];
|
||||
cover.value = response.response.info['cover'];
|
||||
name.value = response.response.info['upper']['name'];
|
||||
mediaCount = response.response.info['media_count'];
|
||||
}
|
||||
List currentList = loadingState.value is Success
|
||||
|
||||
@@ -79,19 +79,21 @@ class _FavDetailPageState extends State<FavDetailPage> {
|
||||
duration: const Duration(milliseconds: 500),
|
||||
child: Row(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
_favDetailController.item!.title!,
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
Text(
|
||||
'共${_favDetailController.item!.mediaCount!}条视频',
|
||||
style: Theme.of(context).textTheme.labelMedium,
|
||||
)
|
||||
],
|
||||
)
|
||||
Obx(
|
||||
() => Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
_favDetailController.title.value,
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
Text(
|
||||
'共${_favDetailController.mediaCount}条视频',
|
||||
style: Theme.of(context).textTheme.labelMedium,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -134,52 +136,58 @@ class _FavDetailPageState extends State<FavDetailPage> {
|
||||
// mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Hero(
|
||||
tag: _favDetailController.heroTag,
|
||||
child: NetworkImgLayer(
|
||||
width: 180,
|
||||
height: 110,
|
||||
src: _favDetailController.item!.cover,
|
||||
Obx(
|
||||
() => Hero(
|
||||
tag: _favDetailController.heroTag,
|
||||
child: NetworkImgLayer(
|
||||
width: 180,
|
||||
height: 110,
|
||||
src: _favDetailController.cover.value,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 14),
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
_favDetailController.item!.title!,
|
||||
style: TextStyle(
|
||||
fontSize: Theme.of(context)
|
||||
.textTheme
|
||||
.titleMedium!
|
||||
.fontSize,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
_favDetailController.item!.upper!.name!,
|
||||
style: TextStyle(
|
||||
fontSize: Theme.of(context)
|
||||
.textTheme
|
||||
.labelSmall!
|
||||
.fontSize,
|
||||
color: Theme.of(context).colorScheme.outline),
|
||||
),
|
||||
const Spacer(),
|
||||
Text(
|
||||
'共${_favDetailController.item!.mediaCount!}条视频',
|
||||
style: TextStyle(
|
||||
fontSize: Theme.of(context)
|
||||
.textTheme
|
||||
.labelSmall!
|
||||
.fontSize,
|
||||
color: Theme.of(context).colorScheme.outline),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
],
|
||||
Obx(
|
||||
() => Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
_favDetailController.title.value,
|
||||
style: TextStyle(
|
||||
fontSize: Theme.of(context)
|
||||
.textTheme
|
||||
.titleMedium!
|
||||
.fontSize,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
_favDetailController.name.value,
|
||||
style: TextStyle(
|
||||
fontSize: Theme.of(context)
|
||||
.textTheme
|
||||
.labelSmall!
|
||||
.fontSize,
|
||||
color:
|
||||
Theme.of(context).colorScheme.outline),
|
||||
),
|
||||
const Spacer(),
|
||||
Text(
|
||||
'共${_favDetailController.mediaCount}条视频',
|
||||
style: TextStyle(
|
||||
fontSize: Theme.of(context)
|
||||
.textTheme
|
||||
.labelSmall!
|
||||
.fontSize,
|
||||
color:
|
||||
Theme.of(context).colorScheme.outline),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
import 'package:PiliPalaX/common/constants.dart';
|
||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
||||
import 'package:PiliPalaX/common/widgets/network_img_layer.dart';
|
||||
import 'package:PiliPalaX/http/loading_state.dart';
|
||||
import 'package:PiliPalaX/pages/member/new/content/member_contribute/content/favorite/member_favorite_ctr.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class MemberFavorite extends StatefulWidget {
|
||||
const MemberFavorite({
|
||||
super.key,
|
||||
required this.heroTag,
|
||||
required this.mid,
|
||||
});
|
||||
|
||||
final String? heroTag;
|
||||
final int mid;
|
||||
|
||||
@override
|
||||
State<MemberFavorite> createState() => _MemberFavoriteState();
|
||||
}
|
||||
|
||||
class _MemberFavoriteState extends State<MemberFavorite>
|
||||
with AutomaticKeepAliveClientMixin {
|
||||
@override
|
||||
bool get wantKeepAlive => true;
|
||||
|
||||
late final _controller = Get.put(
|
||||
MemberFavoriteCtr(mid: widget.mid),
|
||||
tag: widget.heroTag,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
return Obx(() => _buildBody(_controller.loadingState.value));
|
||||
}
|
||||
|
||||
_buildBody(LoadingState loadingState) {
|
||||
return loadingState is Success
|
||||
? RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
await _controller.onRefresh();
|
||||
},
|
||||
child: ListView.builder(
|
||||
itemCount: loadingState.response.length,
|
||||
itemBuilder: (_, index) {
|
||||
dynamic item = loadingState.response[index];
|
||||
return item.mediaListResponse.list is List
|
||||
? ExpansionTile(
|
||||
dense: true,
|
||||
title: Text.rich(
|
||||
TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: item.name,
|
||||
style: TextStyle(fontSize: 14),
|
||||
),
|
||||
TextSpan(
|
||||
text: ' ${item.mediaListResponse.count}',
|
||||
style: TextStyle(fontSize: 13),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
controlAffinity: ListTileControlAffinity.leading,
|
||||
children: (item.mediaListResponse.list as List)
|
||||
.map(
|
||||
(item1) => ListTile(
|
||||
onTap: () {
|
||||
if (item1.state == 1) {
|
||||
return;
|
||||
}
|
||||
if (item.id == 1) {
|
||||
Get.toNamed(
|
||||
'/favDetail',
|
||||
parameters: {
|
||||
'mediaId': item1.id.toString(),
|
||||
'heroTag': widget.heroTag ?? '',
|
||||
},
|
||||
);
|
||||
} else {
|
||||
// TODO
|
||||
}
|
||||
},
|
||||
leading: Container(
|
||||
margin:
|
||||
const EdgeInsets.symmetric(vertical: 6),
|
||||
child: LayoutBuilder(
|
||||
builder: (_, constraints) =>
|
||||
NetworkImgLayer(
|
||||
radius: 6,
|
||||
src: item1.cover,
|
||||
width: constraints.maxHeight *
|
||||
StyleString.aspectRatio,
|
||||
height: constraints.maxHeight,
|
||||
),
|
||||
),
|
||||
),
|
||||
title: Text(item1.title),
|
||||
subtitle: Text(
|
||||
'${item1.mediaCount}个内容 · ${item1.mid == widget.mid ? [
|
||||
0,
|
||||
22
|
||||
].contains(item1.attr) ? '公开' : '私密' : item1.upper.name}',
|
||||
style: TextStyle(
|
||||
color:
|
||||
Theme.of(context).colorScheme.outline,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
)
|
||||
: const SizedBox.shrink();
|
||||
},
|
||||
),
|
||||
)
|
||||
: loadingState is Error
|
||||
? Center(
|
||||
child: CustomScrollView(
|
||||
shrinkWrap: true,
|
||||
slivers: [
|
||||
HttpError(
|
||||
errMsg: loadingState.errMsg,
|
||||
fn: _controller.onReload,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import 'package:PiliPalaX/http/loading_state.dart';
|
||||
import 'package:PiliPalaX/http/member.dart';
|
||||
import 'package:PiliPalaX/pages/common/common_controller.dart';
|
||||
|
||||
class MemberFavoriteCtr extends CommonController {
|
||||
MemberFavoriteCtr({
|
||||
required this.mid,
|
||||
});
|
||||
|
||||
final int mid;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
queryData();
|
||||
}
|
||||
|
||||
@override
|
||||
bool customHandleResponse(Success response) {
|
||||
loadingState.value = response;
|
||||
return true;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<LoadingState> customGetData() => MemberHttp.spaceFav(mid: mid);
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import 'package:PiliPalaX/common/widgets/dynamic_sliver_appbar.dart';
|
||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
||||
import 'package:PiliPalaX/http/loading_state.dart';
|
||||
import 'package:PiliPalaX/pages/member/new/content/member_contribute/content/bangumi/member_bangumi.dart';
|
||||
import 'package:PiliPalaX/pages/member/new/content/member_contribute/content/favorite/member_favorite.dart';
|
||||
import 'package:PiliPalaX/pages/member/new/content/member_contribute/member_contribute.dart';
|
||||
import 'package:PiliPalaX/pages/member/new/content/member_dynamic/member_dynamic.dart';
|
||||
import 'package:PiliPalaX/pages/member/new/content/member_home/member_home.dart';
|
||||
@@ -225,6 +226,10 @@ class _MemberPageNewState extends State<MemberPageNew>
|
||||
heroTag: _heroTag,
|
||||
mid: _mid ?? -1,
|
||||
),
|
||||
'favorite' => MemberFavorite(
|
||||
heroTag: _heroTag,
|
||||
mid: _mid ?? -1,
|
||||
),
|
||||
_ => Center(child: Text(item.title ?? '')),
|
||||
};
|
||||
}).toList(),
|
||||
|
||||
Reference in New Issue
Block a user