mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-05-31 16:18:22 +08:00
opt: member page
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -67,6 +67,7 @@ class StatView extends _StatItemBase {
|
|||||||
IconData get iconData => switch (goto) {
|
IconData get iconData => switch (goto) {
|
||||||
'picture' => Icons.remove_red_eye_outlined,
|
'picture' => Icons.remove_red_eye_outlined,
|
||||||
'like' => Icons.thumb_up_outlined,
|
'like' => Icons.thumb_up_outlined,
|
||||||
|
'reply' => Icons.comment_outlined,
|
||||||
_ => Icons.play_circle_outlined,
|
_ => Icons.play_circle_outlined,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import 'package:PiliPlus/common/widgets/image_save.dart';
|
import 'package:PiliPlus/common/widgets/image_save.dart';
|
||||||
|
import 'package:PiliPlus/http/search.dart';
|
||||||
import 'package:PiliPlus/models/space/item.dart';
|
import 'package:PiliPlus/models/space/item.dart';
|
||||||
|
import 'package:PiliPlus/utils/id_utils.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||||
import '../../utils/utils.dart';
|
import '../../utils/utils.dart';
|
||||||
@@ -28,9 +30,15 @@ class VideoCardVMemberHome extends StatelessWidget {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String bvid = videoItem.bvid ?? '';
|
String? aid = videoItem.param;
|
||||||
|
String? bvid = videoItem.bvid;
|
||||||
|
if (aid == null && bvid == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int? cid = videoItem.firstCid;
|
||||||
|
cid ??= await SearchHttp.ab2c(aid: aid, bvid: bvid);
|
||||||
Utils.toViewPage(
|
Utils.toViewPage(
|
||||||
'bvid=$bvid&cid=${videoItem.firstCid}',
|
'bvid=${bvid ?? IdUtils.av2bv(int.parse(aid!))}&cid=$cid',
|
||||||
arguments: {
|
arguments: {
|
||||||
// 'videoItem': videoItem,
|
// 'videoItem': videoItem,
|
||||||
'pic': videoItem.cover,
|
'pic': videoItem.cover,
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
|
import 'package:PiliPlus/models/space/item.dart';
|
||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
part 'coin_archive.g.dart';
|
part 'coin_archive.g.dart';
|
||||||
|
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class CoinArchive {
|
class CoinArchive {
|
||||||
int? count;
|
int? count;
|
||||||
List<dynamic>? item;
|
List<Item>? item;
|
||||||
|
|
||||||
CoinArchive({this.count, this.item});
|
CoinArchive({this.count, this.item});
|
||||||
|
|
||||||
factory CoinArchive.fromJson(Map<String, dynamic> json) {
|
factory CoinArchive.fromJson(Map<String, dynamic> json) {
|
||||||
return _$CoinArchiveFromJson(json);
|
return _$CoinArchiveFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => _$CoinArchiveToJson(this);
|
Map<String, dynamic> toJson() => _$CoinArchiveToJson(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ part of 'coin_archive.dart';
|
|||||||
|
|
||||||
CoinArchive _$CoinArchiveFromJson(Map<String, dynamic> json) => CoinArchive(
|
CoinArchive _$CoinArchiveFromJson(Map<String, dynamic> json) => CoinArchive(
|
||||||
count: (json['count'] as num?)?.toInt(),
|
count: (json['count'] as num?)?.toInt(),
|
||||||
item: json['item'] as List<dynamic>?,
|
item: (json['item'] as List<dynamic>?)
|
||||||
|
?.map((json) => Item.fromJson(json))
|
||||||
|
.toList(),
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$CoinArchiveToJson(CoinArchive instance) =>
|
Map<String, dynamic> _$CoinArchiveToJson(CoinArchive instance) =>
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ part 'favourite2.g.dart';
|
|||||||
|
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class Favourite2 {
|
class Favourite2 {
|
||||||
int? count;
|
int? count;
|
||||||
List<dynamic>? item;
|
List<dynamic>? item;
|
||||||
|
|
||||||
Favourite2({this.count, this.item});
|
Favourite2({this.count, this.item});
|
||||||
|
|
||||||
factory Favourite2.fromJson(Map<String, dynamic> json) {
|
factory Favourite2.fromJson(Map<String, dynamic> json) {
|
||||||
return _$Favourite2FromJson(json);
|
return _$Favourite2FromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => _$Favourite2ToJson(this);
|
Map<String, dynamic> toJson() => _$Favourite2ToJson(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
|
import 'package:PiliPlus/models/space/item.dart';
|
||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
part 'like_archive.g.dart';
|
part 'like_archive.g.dart';
|
||||||
|
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class LikeArchive {
|
class LikeArchive {
|
||||||
int? count;
|
int? count;
|
||||||
List<dynamic>? item;
|
List<Item>? item;
|
||||||
|
|
||||||
LikeArchive({this.count, this.item});
|
LikeArchive({this.count, this.item});
|
||||||
|
|
||||||
factory LikeArchive.fromJson(Map<String, dynamic> json) {
|
factory LikeArchive.fromJson(Map<String, dynamic> json) {
|
||||||
return _$LikeArchiveFromJson(json);
|
return _$LikeArchiveFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => _$LikeArchiveToJson(this);
|
Map<String, dynamic> toJson() => _$LikeArchiveToJson(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ part of 'like_archive.dart';
|
|||||||
|
|
||||||
LikeArchive _$LikeArchiveFromJson(Map<String, dynamic> json) => LikeArchive(
|
LikeArchive _$LikeArchiveFromJson(Map<String, dynamic> json) => LikeArchive(
|
||||||
count: (json['count'] as num?)?.toInt(),
|
count: (json['count'] as num?)?.toInt(),
|
||||||
item: json['item'] as List<dynamic>?,
|
item: (json['item'] as List<dynamic>?)
|
||||||
|
?.map((json) => Item.fromJson(json))
|
||||||
|
.toList(),
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$LikeArchiveToJson(LikeArchive instance) =>
|
Map<String, dynamic> _$LikeArchiveToJson(LikeArchive instance) =>
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ Widget bangumiContent(Item bangumiItem) {
|
|||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
letterSpacing: 0.3,
|
letterSpacing: 0.3,
|
||||||
),
|
),
|
||||||
maxLines: 1,
|
maxLines: 2,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import 'package:PiliPlus/common/constants.dart';
|
import 'package:PiliPlus/common/constants.dart';
|
||||||
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/common/widgets/network_img_layer.dart';
|
|
||||||
import 'package:PiliPlus/http/loading_state.dart';
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
import 'package:PiliPlus/models/space_article/item.dart';
|
|
||||||
import 'package:PiliPlus/pages/member/new/content/member_contribute/content/article/member_article_ctr.dart';
|
import 'package:PiliPlus/pages/member/new/content/member_contribute/content/article/member_article_ctr.dart';
|
||||||
import 'package:PiliPlus/utils/app_scheme.dart';
|
import 'package:PiliPlus/pages/member/new/content/member_contribute/content/article/widget/item.dart';
|
||||||
|
import 'package:PiliPlus/utils/grid.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
@@ -43,62 +42,31 @@ class _MemberArticleState extends State<MemberArticle>
|
|||||||
return switch (loadingState) {
|
return switch (loadingState) {
|
||||||
Loading() => loadingWidget,
|
Loading() => loadingWidget,
|
||||||
Success() => (loadingState.response as List?)?.isNotEmpty == true
|
Success() => (loadingState.response as List?)?.isNotEmpty == true
|
||||||
? MediaQuery.removePadding(
|
? refreshIndicator(
|
||||||
context: context,
|
onRefresh: () async {
|
||||||
removeTop: true,
|
await _controller.onRefresh();
|
||||||
child: refreshIndicator(
|
},
|
||||||
onRefresh: () async {
|
child: CustomScrollView(
|
||||||
await _controller.onRefresh();
|
slivers: [
|
||||||
},
|
SliverGrid(
|
||||||
child: ListView.separated(
|
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
|
||||||
itemCount: loadingState.response.length,
|
mainAxisSpacing: 2,
|
||||||
itemBuilder: (context, index) {
|
maxCrossAxisExtent: Grid.mediumCardWidth * 2,
|
||||||
if (index == loadingState.response.length - 1) {
|
childAspectRatio: StyleString.aspectRatio * 2.2,
|
||||||
_controller.onLoadMore();
|
),
|
||||||
}
|
delegate: SliverChildBuilderDelegate(
|
||||||
Item item = loadingState.response[index];
|
(context, index) {
|
||||||
return ListTile(
|
if (index == loadingState.response.length - 1) {
|
||||||
dense: true,
|
_controller.onLoadMore();
|
||||||
onTap: () {
|
}
|
||||||
PiliScheme.routePushFromUrl(item.uri ?? '');
|
return MemberArticleItem(
|
||||||
|
item: loadingState.response[index],
|
||||||
|
);
|
||||||
},
|
},
|
||||||
leading: item.originImageUrls?.isNotEmpty == true
|
childCount: loadingState.response.length,
|
||||||
? Container(
|
),
|
||||||
margin: const EdgeInsets.symmetric(vertical: 6),
|
),
|
||||||
child: LayoutBuilder(
|
],
|
||||||
builder: (context, constraints) {
|
|
||||||
return NetworkImgLayer(
|
|
||||||
radius: 6,
|
|
||||||
src: item.originImageUrls!.first,
|
|
||||||
width: constraints.maxHeight *
|
|
||||||
StyleString.aspectRatio,
|
|
||||||
height: constraints.maxHeight,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
title: Text(
|
|
||||||
item.title ?? '',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 15,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
subtitle: item.summary?.isNotEmpty == true
|
|
||||||
? Text(
|
|
||||||
item.summary!,
|
|
||||||
maxLines: 2,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 13,
|
|
||||||
color: Theme.of(context).colorScheme.outline,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
separatorBuilder: (context, index) => Divider(height: 1),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: scrollErrorWidget(
|
: scrollErrorWidget(
|
||||||
|
|||||||
@@ -0,0 +1,105 @@
|
|||||||
|
import 'package:PiliPlus/common/constants.dart';
|
||||||
|
import 'package:PiliPlus/common/widgets/image_save.dart';
|
||||||
|
import 'package:PiliPlus/common/widgets/network_img_layer.dart';
|
||||||
|
import 'package:PiliPlus/common/widgets/stat/stat.dart';
|
||||||
|
import 'package:PiliPlus/models/space_article/item.dart';
|
||||||
|
import 'package:PiliPlus/utils/app_scheme.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class MemberArticleItem extends StatelessWidget {
|
||||||
|
const MemberArticleItem({super.key, required this.item});
|
||||||
|
|
||||||
|
final Item item;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
if (item.uri?.isNotEmpty == true) {
|
||||||
|
PiliScheme.routePushFromUrl(item.uri!);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onLongPress: () {
|
||||||
|
imageSaveDialog(
|
||||||
|
context: context,
|
||||||
|
title: item.title,
|
||||||
|
cover: item.originImageUrls?.firstOrNull,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: StyleString.safeSpace,
|
||||||
|
vertical: 5,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
if (item.originImageUrls?.firstOrNull?.isNotEmpty == true) ...[
|
||||||
|
AspectRatio(
|
||||||
|
aspectRatio: StyleString.aspectRatio,
|
||||||
|
child: LayoutBuilder(
|
||||||
|
builder:
|
||||||
|
(BuildContext context, BoxConstraints boxConstraints) {
|
||||||
|
return NetworkImgLayer(
|
||||||
|
src: item.originImageUrls!.first,
|
||||||
|
width: boxConstraints.maxWidth,
|
||||||
|
height: boxConstraints.maxHeight,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
],
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
if (item.title?.isNotEmpty == true) ...[
|
||||||
|
Text(
|
||||||
|
item.title!,
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
],
|
||||||
|
Text(
|
||||||
|
'${item.publishTimeText}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: Theme.of(context).colorScheme.outline,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
StatView(
|
||||||
|
context: context,
|
||||||
|
value: item.stats?.view ?? 0,
|
||||||
|
size: 'medium',
|
||||||
|
goto: 'picture',
|
||||||
|
textColor: Theme.of(context).colorScheme.outline,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 16),
|
||||||
|
StatView(
|
||||||
|
context: context,
|
||||||
|
goto: 'reply',
|
||||||
|
size: 'medium',
|
||||||
|
value: item.stats?.reply ?? 0,
|
||||||
|
textColor: Theme.of(context).colorScheme.outline,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -66,7 +66,7 @@ class _MemberBangumiState extends State<MemberBangumi>
|
|||||||
maxCrossAxisExtent: Grid.smallCardWidth / 3 * 2,
|
maxCrossAxisExtent: Grid.smallCardWidth / 3 * 2,
|
||||||
childAspectRatio: 0.75,
|
childAspectRatio: 0.75,
|
||||||
mainAxisExtent:
|
mainAxisExtent:
|
||||||
MediaQuery.textScalerOf(context).scale(30),
|
MediaQuery.textScalerOf(context).scale(52),
|
||||||
),
|
),
|
||||||
delegate: SliverChildBuilderDelegate(
|
delegate: SliverChildBuilderDelegate(
|
||||||
(context, index) {
|
(context, index) {
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
import 'package:PiliPlus/common/constants.dart';
|
import 'package:PiliPlus/common/constants.dart';
|
||||||
import 'package:PiliPlus/common/widgets/badge.dart';
|
|
||||||
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/common/widgets/network_img_layer.dart';
|
|
||||||
import 'package:PiliPlus/http/loading_state.dart';
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
import 'package:PiliPlus/models/space_fav/datum.dart';
|
import 'package:PiliPlus/models/space_fav/datum.dart';
|
||||||
import 'package:PiliPlus/models/space_fav/list.dart';
|
import 'package:PiliPlus/models/space_fav/list.dart';
|
||||||
import 'package:PiliPlus/models/user/sub_folder.dart';
|
|
||||||
import 'package:PiliPlus/pages/member/new/content/member_contribute/content/favorite/member_favorite_ctr.dart';
|
import 'package:PiliPlus/pages/member/new/content/member_contribute/content/favorite/member_favorite_ctr.dart';
|
||||||
import 'package:PiliPlus/utils/utils.dart';
|
import 'package:PiliPlus/pages/member/new/content/member_contribute/content/favorite/widget/item.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
@@ -64,7 +61,7 @@ class _MemberFavoriteState extends State<MemberFavorite>
|
|||||||
),
|
),
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 12 + MediaQuery.of(context).padding.bottom,
|
height: 80 + MediaQuery.of(context).padding.bottom,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
@@ -82,6 +79,7 @@ class _MemberFavoriteState extends State<MemberFavorite>
|
|||||||
}
|
}
|
||||||
|
|
||||||
_buildItem(Datum data, bool isFirst) {
|
_buildItem(Datum data, bool isFirst) {
|
||||||
|
final height = 120 / StyleString.aspectRatio + 10;
|
||||||
return Theme(
|
return Theme(
|
||||||
data: Theme.of(context).copyWith(
|
data: Theme.of(context).copyWith(
|
||||||
dividerColor: Colors.transparent,
|
dividerColor: Colors.transparent,
|
||||||
@@ -109,113 +107,21 @@ class _MemberFavoriteState extends State<MemberFavorite>
|
|||||||
controlAffinity: ListTileControlAffinity.leading,
|
controlAffinity: ListTileControlAffinity.leading,
|
||||||
children: [
|
children: [
|
||||||
...(data.mediaListResponse?.list as List<FavList>).map(
|
...(data.mediaListResponse?.list as List<FavList>).map(
|
||||||
(item1) => ListTile(
|
(item) => SizedBox(
|
||||||
onTap: () async {
|
height: height,
|
||||||
if (item1.state == 1) {
|
child: MemberFavItem(
|
||||||
// invalid
|
item: item,
|
||||||
return;
|
callback: (res) {
|
||||||
}
|
|
||||||
|
|
||||||
if (item1.type == 0) {
|
|
||||||
dynamic res = await Get.toNamed(
|
|
||||||
'/favDetail',
|
|
||||||
parameters: {
|
|
||||||
'mediaId': item1.id.toString(),
|
|
||||||
'heroTag': widget.heroTag ?? '',
|
|
||||||
},
|
|
||||||
);
|
|
||||||
if (res == true) {
|
if (res == true) {
|
||||||
_controller.first.value.mediaListResponse?.list
|
_controller.first.value.mediaListResponse?.list
|
||||||
?.remove(item1);
|
?.remove(item);
|
||||||
_controller.first.refresh();
|
_controller.first.refresh();
|
||||||
} else {
|
} else {
|
||||||
Future.delayed(const Duration(milliseconds: 100), () {
|
Future.delayed(const Duration(milliseconds: 100), () {
|
||||||
_controller.onRefresh();
|
_controller.onRefresh();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
},
|
||||||
Get.toNamed(
|
|
||||||
'/subDetail',
|
|
||||||
arguments: SubFolderItemData(
|
|
||||||
type: item1.type,
|
|
||||||
title: item1.title,
|
|
||||||
cover: item1.cover,
|
|
||||||
upper: Upper(
|
|
||||||
mid: item1.upper?.mid,
|
|
||||||
name: item1.upper?.name,
|
|
||||||
face: item1.upper?.face,
|
|
||||||
),
|
|
||||||
mediaCount: item1.mediaCount,
|
|
||||||
viewCount: item1.viewCount,
|
|
||||||
),
|
|
||||||
parameters: {
|
|
||||||
'heroTag': widget.heroTag ?? '',
|
|
||||||
'id': item1.id.toString(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
leading: Container(
|
|
||||||
margin: const EdgeInsets.symmetric(vertical: 6),
|
|
||||||
child: LayoutBuilder(
|
|
||||||
builder: (context, constraints) {
|
|
||||||
return Stack(
|
|
||||||
children: [
|
|
||||||
NetworkImgLayer(
|
|
||||||
radius: 6,
|
|
||||||
src: item1.cover,
|
|
||||||
width:
|
|
||||||
constraints.maxHeight * StyleString.aspectRatio,
|
|
||||||
height: constraints.maxHeight,
|
|
||||||
),
|
|
||||||
if (item1.type == 21)
|
|
||||||
PBadge(
|
|
||||||
right: 3,
|
|
||||||
bottom: 3,
|
|
||||||
text: '合集',
|
|
||||||
bold: false,
|
|
||||||
size: 'small',
|
|
||||||
)
|
|
||||||
else if (item1.type == 0 || item1.type == 11)
|
|
||||||
Positioned(
|
|
||||||
right: 3,
|
|
||||||
bottom: 3,
|
|
||||||
child: Container(
|
|
||||||
padding: const EdgeInsets.all(5),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
color: Theme.of(context).colorScheme.primary,
|
|
||||||
),
|
|
||||||
child: Icon(
|
|
||||||
Icons.video_library_outlined,
|
|
||||||
size: 12,
|
|
||||||
color: Theme.of(context).colorScheme.onPrimary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
title: Text(
|
|
||||||
item1.title ?? '',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
subtitle: Text(
|
|
||||||
item1.type == 0
|
|
||||||
? '${item1.mediaCount}个内容 · ${Utils.isPublicText(item1.attr ?? 0)}'
|
|
||||||
: item1.type == 11
|
|
||||||
? '${item1.mediaCount}个内容 · ${item1.upper?.name}'
|
|
||||||
: item1.type == 21
|
|
||||||
? '创建者: ${item1.upper?.name}\n${item1.mediaCount}个视频 · ${Utils.numFormat(item1.viewCount)}播放'
|
|
||||||
: '${item1.mediaCount}个内容',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 13,
|
|
||||||
color: Theme.of(context).colorScheme.outline,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -0,0 +1,151 @@
|
|||||||
|
import 'package:PiliPlus/common/constants.dart';
|
||||||
|
import 'package:PiliPlus/common/widgets/badge.dart';
|
||||||
|
import 'package:PiliPlus/common/widgets/image_save.dart';
|
||||||
|
import 'package:PiliPlus/common/widgets/network_img_layer.dart';
|
||||||
|
import 'package:PiliPlus/models/space_fav/list.dart';
|
||||||
|
import 'package:PiliPlus/models/user/sub_folder.dart';
|
||||||
|
import 'package:PiliPlus/utils/utils.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
class MemberFavItem extends StatelessWidget {
|
||||||
|
const MemberFavItem({super.key, required this.item, this.callback});
|
||||||
|
|
||||||
|
final FavList item;
|
||||||
|
final ValueChanged<bool?>? callback;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () async {
|
||||||
|
if (item.state == 1) {
|
||||||
|
// invalid
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.type == 0) {
|
||||||
|
dynamic res = await Get.toNamed(
|
||||||
|
'/favDetail',
|
||||||
|
parameters: {
|
||||||
|
'mediaId': item.id.toString(),
|
||||||
|
'heroTag': Utils.makeHeroTag(item.id),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
callback?.call(res);
|
||||||
|
} else {
|
||||||
|
Get.toNamed(
|
||||||
|
'/subDetail',
|
||||||
|
arguments: SubFolderItemData(
|
||||||
|
type: item.type,
|
||||||
|
title: item.title,
|
||||||
|
cover: item.cover,
|
||||||
|
upper: Upper(
|
||||||
|
mid: item.upper?.mid,
|
||||||
|
name: item.upper?.name,
|
||||||
|
face: item.upper?.face,
|
||||||
|
),
|
||||||
|
mediaCount: item.mediaCount,
|
||||||
|
viewCount: item.viewCount,
|
||||||
|
),
|
||||||
|
parameters: {
|
||||||
|
'id': item.id.toString(),
|
||||||
|
'heroTag': Utils.makeHeroTag(item.id),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onLongPress: () {
|
||||||
|
imageSaveDialog(
|
||||||
|
context: context,
|
||||||
|
title: item.title,
|
||||||
|
cover: item.cover,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: StyleString.safeSpace,
|
||||||
|
vertical: 5,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
AspectRatio(
|
||||||
|
aspectRatio: StyleString.aspectRatio,
|
||||||
|
child: LayoutBuilder(
|
||||||
|
builder: (context, boxConstraints) {
|
||||||
|
return Stack(
|
||||||
|
clipBehavior: Clip.none,
|
||||||
|
children: [
|
||||||
|
NetworkImgLayer(
|
||||||
|
src: item.cover,
|
||||||
|
width: boxConstraints.maxWidth,
|
||||||
|
height: boxConstraints.maxHeight,
|
||||||
|
),
|
||||||
|
if (item.type == 21)
|
||||||
|
PBadge(
|
||||||
|
right: 3,
|
||||||
|
bottom: 3,
|
||||||
|
text: '合集',
|
||||||
|
bold: false,
|
||||||
|
size: 'small',
|
||||||
|
)
|
||||||
|
else if (item.type == 0 || item.type == 11)
|
||||||
|
Positioned(
|
||||||
|
right: 3,
|
||||||
|
bottom: 3,
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.all(5),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
child: Icon(
|
||||||
|
Icons.video_library_outlined,
|
||||||
|
size: 12,
|
||||||
|
color: Theme.of(context).colorScheme.onPrimary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
item.title ?? '',
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
Text(
|
||||||
|
item.type == 0
|
||||||
|
? '${item.mediaCount}个内容 · ${Utils.isPublicText(item.attr ?? 0)}'
|
||||||
|
: item.type == 11
|
||||||
|
? '${item.mediaCount}个内容 · ${item.upper?.name}'
|
||||||
|
: item.type == 21
|
||||||
|
? '创建者: ${item.upper?.name}\n${item.mediaCount}个视频 · ${Utils.numFormat(item.viewCount)}播放'
|
||||||
|
: '${item.mediaCount}个内容',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: Theme.of(context).colorScheme.outline,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,13 +2,14 @@ import 'dart:math';
|
|||||||
|
|
||||||
import 'package:PiliPlus/common/constants.dart';
|
import 'package:PiliPlus/common/constants.dart';
|
||||||
import 'package:PiliPlus/common/widgets/loading_widget.dart';
|
import 'package:PiliPlus/common/widgets/loading_widget.dart';
|
||||||
import 'package:PiliPlus/common/widgets/network_img_layer.dart';
|
|
||||||
import 'package:PiliPlus/common/widgets/video_card_v_member_home.dart';
|
import 'package:PiliPlus/common/widgets/video_card_v_member_home.dart';
|
||||||
import 'package:PiliPlus/http/loading_state.dart';
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
import 'package:PiliPlus/models/space/data.dart';
|
import 'package:PiliPlus/models/space/data.dart';
|
||||||
import 'package:PiliPlus/models/space/item.dart';
|
import 'package:PiliPlus/models/space/item.dart';
|
||||||
import 'package:PiliPlus/pages/bangumi/widgets/bangumi_card_v_member_home.dart';
|
import 'package:PiliPlus/pages/bangumi/widgets/bangumi_card_v_member_home.dart';
|
||||||
|
import 'package:PiliPlus/pages/member/new/content/member_contribute/content/article/widget/item.dart';
|
||||||
import 'package:PiliPlus/pages/member/new/content/member_contribute/member_contribute_ctr.dart';
|
import 'package:PiliPlus/pages/member/new/content/member_contribute/member_contribute_ctr.dart';
|
||||||
|
import 'package:PiliPlus/pages/member/new/content/member_home/widget/fav_item.dart';
|
||||||
import 'package:PiliPlus/pages/member/new/controller.dart';
|
import 'package:PiliPlus/pages/member/new/controller.dart';
|
||||||
import 'package:PiliPlus/pages/member_coin/index.dart';
|
import 'package:PiliPlus/pages/member_coin/index.dart';
|
||||||
import 'package:PiliPlus/pages/member_like/index.dart';
|
import 'package:PiliPlus/pages/member_like/index.dart';
|
||||||
@@ -17,8 +18,6 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
import '../../../../../utils/app_scheme.dart';
|
|
||||||
|
|
||||||
class MemberHome extends StatefulWidget {
|
class MemberHome extends StatefulWidget {
|
||||||
const MemberHome({super.key, this.heroTag});
|
const MemberHome({super.key, this.heroTag});
|
||||||
|
|
||||||
@@ -42,6 +41,7 @@ class _MemberHomeState extends State<MemberHome>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBody(LoadingState loadingState) {
|
Widget _buildBody(LoadingState loadingState) {
|
||||||
|
final isVertical = context.orientation == Orientation.portrait;
|
||||||
return switch (loadingState) {
|
return switch (loadingState) {
|
||||||
Loading() => loadingWidget,
|
Loading() => loadingWidget,
|
||||||
Success() => loadingState.response is Data
|
Success() => loadingState.response is Data
|
||||||
@@ -75,8 +75,8 @@ class _MemberHomeState extends State<MemberHome>
|
|||||||
loadingState.response.archive.item[index],
|
loadingState.response.archive.item[index],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
childCount:
|
childCount: min(isVertical ? 4 : 8,
|
||||||
min(4, loadingState.response.archive.item.length),
|
loadingState.response.archive.item.length),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -88,7 +88,14 @@ class _MemberHomeState extends State<MemberHome>
|
|||||||
param: 'favorite',
|
param: 'favorite',
|
||||||
count: loadingState.response.favourite2.count,
|
count: loadingState.response.favourite2.count,
|
||||||
),
|
),
|
||||||
// TODO
|
SliverToBoxAdapter(
|
||||||
|
child: SizedBox(
|
||||||
|
height: 120 / StyleString.aspectRatio + 10,
|
||||||
|
child: MemberFavItem(
|
||||||
|
item: loadingState.response.favourite2.item.first,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
if (loadingState.response?.coinArchive?.item?.isNotEmpty ==
|
if (loadingState.response?.coinArchive?.item?.isNotEmpty ==
|
||||||
true) ...[
|
true) ...[
|
||||||
@@ -97,7 +104,31 @@ class _MemberHomeState extends State<MemberHome>
|
|||||||
param: 'coinArchive',
|
param: 'coinArchive',
|
||||||
count: loadingState.response.coinArchive.count,
|
count: loadingState.response.coinArchive.count,
|
||||||
),
|
),
|
||||||
// TODO
|
SliverPadding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: StyleString.safeSpace,
|
||||||
|
),
|
||||||
|
sliver: SliverGrid(
|
||||||
|
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
||||||
|
mainAxisSpacing: StyleString.cardSpace,
|
||||||
|
crossAxisSpacing: StyleString.cardSpace,
|
||||||
|
maxCrossAxisExtent: Grid.smallCardWidth,
|
||||||
|
childAspectRatio: StyleString.aspectRatio,
|
||||||
|
mainAxisExtent:
|
||||||
|
MediaQuery.textScalerOf(context).scale(55),
|
||||||
|
),
|
||||||
|
delegate: SliverChildBuilderDelegate(
|
||||||
|
(context, index) {
|
||||||
|
return VideoCardVMemberHome(
|
||||||
|
videoItem:
|
||||||
|
loadingState.response.coinArchive.item[index],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
childCount: min(isVertical ? 2 : 4,
|
||||||
|
loadingState.response.coinArchive.item.length),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
if (loadingState.response?.likeArchive?.item?.isNotEmpty ==
|
if (loadingState.response?.likeArchive?.item?.isNotEmpty ==
|
||||||
true) ...[
|
true) ...[
|
||||||
@@ -106,7 +137,31 @@ class _MemberHomeState extends State<MemberHome>
|
|||||||
param: 'likeArchive',
|
param: 'likeArchive',
|
||||||
count: loadingState.response.likeArchive.count,
|
count: loadingState.response.likeArchive.count,
|
||||||
),
|
),
|
||||||
// TODO
|
SliverPadding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: StyleString.safeSpace,
|
||||||
|
),
|
||||||
|
sliver: SliverGrid(
|
||||||
|
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
||||||
|
mainAxisSpacing: StyleString.cardSpace,
|
||||||
|
crossAxisSpacing: StyleString.cardSpace,
|
||||||
|
maxCrossAxisExtent: Grid.smallCardWidth,
|
||||||
|
childAspectRatio: StyleString.aspectRatio,
|
||||||
|
mainAxisExtent:
|
||||||
|
MediaQuery.textScalerOf(context).scale(55),
|
||||||
|
),
|
||||||
|
delegate: SliverChildBuilderDelegate(
|
||||||
|
(context, index) {
|
||||||
|
return VideoCardVMemberHome(
|
||||||
|
videoItem:
|
||||||
|
loadingState.response.likeArchive.item[index],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
childCount: min(isVertical ? 2 : 4,
|
||||||
|
loadingState.response.likeArchive.item.length),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
if (loadingState.response?.article?.item?.isNotEmpty ==
|
if (loadingState.response?.article?.item?.isNotEmpty ==
|
||||||
true) ...[
|
true) ...[
|
||||||
@@ -116,52 +171,21 @@ class _MemberHomeState extends State<MemberHome>
|
|||||||
param1: 'article',
|
param1: 'article',
|
||||||
count: loadingState.response.article.count,
|
count: loadingState.response.article.count,
|
||||||
),
|
),
|
||||||
SliverToBoxAdapter(
|
SliverGrid(
|
||||||
child: ListTile(
|
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
|
||||||
dense: true,
|
mainAxisSpacing: 2,
|
||||||
onTap: () {
|
maxCrossAxisExtent: Grid.mediumCardWidth * 2,
|
||||||
PiliScheme.routePushFromUrl(
|
childAspectRatio: StyleString.aspectRatio * 2.2,
|
||||||
loadingState.response.article.item.first.uri ?? '',
|
),
|
||||||
|
delegate: SliverChildBuilderDelegate(
|
||||||
|
(context, index) {
|
||||||
|
return MemberArticleItem(
|
||||||
|
item: loadingState.response.article.item[index],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
leading: loadingState.response.article.item.first
|
childCount: isVertical
|
||||||
.originImageUrls?.isNotEmpty ==
|
? 1
|
||||||
true
|
: loadingState.response.article.item.length,
|
||||||
? Container(
|
|
||||||
margin: const EdgeInsets.symmetric(vertical: 6),
|
|
||||||
child: LayoutBuilder(
|
|
||||||
builder: (context, constraints) {
|
|
||||||
return NetworkImgLayer(
|
|
||||||
radius: 6,
|
|
||||||
src: loadingState.response.article.item
|
|
||||||
.first.originImageUrls!.first,
|
|
||||||
width: constraints.maxHeight *
|
|
||||||
StyleString.aspectRatio,
|
|
||||||
height: constraints.maxHeight,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
title: Text(
|
|
||||||
loadingState.response.article.item.first.title ?? '',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 15,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
subtitle: loadingState.response.article.item.first.summary
|
|
||||||
?.isNotEmpty ==
|
|
||||||
true
|
|
||||||
? Text(
|
|
||||||
loadingState.response.article.item.first.summary!,
|
|
||||||
maxLines: 2,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 13,
|
|
||||||
color: Theme.of(context).colorScheme.outline,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -193,7 +217,7 @@ class _MemberHomeState extends State<MemberHome>
|
|||||||
maxCrossAxisExtent: Grid.smallCardWidth / 3 * 2,
|
maxCrossAxisExtent: Grid.smallCardWidth / 3 * 2,
|
||||||
childAspectRatio: 0.75,
|
childAspectRatio: 0.75,
|
||||||
mainAxisExtent:
|
mainAxisExtent:
|
||||||
MediaQuery.textScalerOf(context).scale(30),
|
MediaQuery.textScalerOf(context).scale(52),
|
||||||
),
|
),
|
||||||
delegate: SliverChildBuilderDelegate(
|
delegate: SliverChildBuilderDelegate(
|
||||||
(context, index) {
|
(context, index) {
|
||||||
@@ -202,15 +226,15 @@ class _MemberHomeState extends State<MemberHome>
|
|||||||
loadingState.response.season.item[index],
|
loadingState.response.season.item[index],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
childCount:
|
childCount: min(isVertical ? 3 : 6,
|
||||||
min(3, loadingState.response.season.item.length),
|
loadingState.response.season.item.length),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 12 + MediaQuery.of(context).padding.bottom,
|
height: 80 + MediaQuery.of(context).padding.bottom,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -288,7 +312,8 @@ class _MemberHomeState extends State<MemberHome>
|
|||||||
));
|
));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO
|
|
||||||
|
// else TODO
|
||||||
SmartDialog.showToast('view $param');
|
SmartDialog.showToast('view $param');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
import 'package:PiliPlus/common/constants.dart';
|
||||||
|
import 'package:PiliPlus/common/widgets/image_save.dart';
|
||||||
|
import 'package:PiliPlus/common/widgets/network_img_layer.dart';
|
||||||
|
import 'package:PiliPlus/utils/utils.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
class MemberFavItem extends StatelessWidget {
|
||||||
|
const MemberFavItem({super.key, required this.item});
|
||||||
|
|
||||||
|
final dynamic item;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
if (item['type'] == 2) {
|
||||||
|
Get.toNamed(
|
||||||
|
'/favDetail',
|
||||||
|
parameters: {
|
||||||
|
'mediaId': item['media_id'].toString(),
|
||||||
|
'heroTag': Utils.makeHeroTag(item['media_id']),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onLongPress: () {
|
||||||
|
imageSaveDialog(
|
||||||
|
context: context,
|
||||||
|
title: item['title'],
|
||||||
|
cover: item['cover'],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: StyleString.safeSpace,
|
||||||
|
vertical: 5,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
AspectRatio(
|
||||||
|
aspectRatio: StyleString.aspectRatio,
|
||||||
|
child: LayoutBuilder(
|
||||||
|
builder: (context, boxConstraints) {
|
||||||
|
return Stack(
|
||||||
|
clipBehavior: Clip.none,
|
||||||
|
children: [
|
||||||
|
NetworkImgLayer(
|
||||||
|
src: item['cover'],
|
||||||
|
width: boxConstraints.maxWidth,
|
||||||
|
height: boxConstraints.maxHeight,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
item['title'] ?? '',
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
Text(
|
||||||
|
'${item['count']}个内容 · ${item['is_public'] == 1 ? '私密' : '公开'}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: Theme.of(context).colorScheme.outline,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user