opt: article list page

opt: fav/sub detail

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-05-10 15:44:58 +08:00
parent 91af974bd4
commit 3b6fd8019b
37 changed files with 401 additions and 447 deletions

View File

@@ -1,4 +1,5 @@
import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:cached_network_image/cached_network_image.dart';
@@ -10,7 +11,7 @@ class NetworkImgLayer extends StatelessWidget {
this.src,
required this.width,
this.height,
this.type,
this.type = ImageType.def,
this.fadeOutDuration,
this.fadeInDuration,
// 图片质量 默认1%
@@ -27,7 +28,7 @@ class NetworkImgLayer extends StatelessWidget {
final String? src;
final double width;
final double? height;
final String? type;
final ImageType type;
final Duration? fadeOutDuration;
final Duration? fadeInDuration;
final int? quality;
@@ -42,9 +43,9 @@ class NetworkImgLayer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return src.isNullOrEmpty.not
? type == 'avatar'
? type == ImageType.avatar
? ClipOval(child: _buildImage(context))
: radius == 0 || type == 'emote'
: radius == 0 || type == ImageType.emote
? _buildImage(context)
: ClipRRect(
borderRadius: radius != null
@@ -86,9 +87,10 @@ class NetworkImgLayer extends StatelessWidget {
height: height,
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
shape: type == 'avatar' ? BoxShape.circle : BoxShape.rectangle,
shape: type == ImageType.avatar ? BoxShape.circle : BoxShape.rectangle,
color: Theme.of(context).colorScheme.onInverseSurface.withOpacity(0.4),
borderRadius: type == 'avatar' || type == 'emote' || radius == 0
borderRadius:
type == ImageType.avatar || type == ImageType.emote || radius == 0
? null
: radius != null
? BorderRadius.circular(radius!)
@@ -98,7 +100,7 @@ class NetworkImgLayer extends StatelessWidget {
? const SizedBox.shrink()
: Center(
child: Image.asset(
type == 'avatar'
type == ImageType.avatar
? 'assets/images/noface.jpeg'
: 'assets/images/loading.png',
width: width,

View File

@@ -1,5 +1,6 @@
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models/common/avatar_badge_type.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/storage.dart';
import 'package:PiliPlus/utils/utils.dart';
@@ -120,7 +121,7 @@ class PendantAvatar extends StatelessWidget {
src: avatar,
width: size,
height: size,
type: 'avatar',
type: ImageType.avatar,
),
),
)
@@ -128,7 +129,7 @@ class PendantAvatar extends StatelessWidget {
src: avatar,
width: size,
height: size,
type: 'avatar',
type: ImageType.avatar,
);
Widget _buildBadge(ColorScheme colorScheme) {

View File

@@ -0,0 +1 @@
enum ImageType { avatar, emote, def }

View File

@@ -10,6 +10,7 @@ import 'package:PiliPlus/grpc/bilibili/main/community/reply/v1.pb.dart'
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/common/badge_type.dart';
import 'package:PiliPlus/models/common/image_preview_type.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/common/reply/reply_sort_type.dart';
import 'package:PiliPlus/models/common/reply/reply_type.dart';
import 'package:PiliPlus/models/dynamics/result.dart' show DynamicStat;
@@ -486,7 +487,7 @@ class _ArticlePageState extends State<ArticlePage>
// TODO Avatar
width: 40,
height: 40,
type: 'avatar',
type: ImageType.avatar,
src: _articleCtr.summary.author?.face,
),
const SizedBox(width: 10),

View File

@@ -17,12 +17,12 @@ class ArticleListController
queryData();
}
ArticleList? list;
Rx<ArticleList?> list = Rx<ArticleList?>(null);
Author? author;
@override
List<Article>? getDataList(ArticleListData response) {
list = response.list;
list.value = response.list;
author = response.author;
return response.articles;
}

View File

@@ -4,6 +4,7 @@ import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/dynamics/article_list/article.dart';
import 'package:PiliPlus/models/dynamics/article_list/list.dart';
import 'package:PiliPlus/pages/article_list/controller.dart';
@@ -35,6 +36,7 @@ class _ArticleListPageState extends State<ArticleListPage> {
onRefresh: _controller.onRefresh,
child: CustomScrollView(
slivers: [
Obx(() => _buildHeader(theme, _controller.list.value)),
SliverPadding(
padding: EdgeInsets.only(
bottom: MediaQuery.paddingOf(context).bottom + 80),
@@ -64,12 +66,8 @@ class _ArticleListPageState extends State<ArticleListPage> {
),
),
),
Success() => SliverMainAxisGroup(
slivers: [
if (_controller.list != null)
_buildHeader(theme, _controller.list!),
if (loadingState.response?.isNotEmpty == true)
SliverGrid(
Success() => loadingState.response?.isNotEmpty == true
? SliverGrid(
gridDelegate: SliverGridDelegateWithExtentAndRatio(
mainAxisSpacing: 2,
maxCrossAxisExtent: Grid.smallCardWidth * 2,
@@ -85,10 +83,7 @@ class _ArticleListPageState extends State<ArticleListPage> {
childCount: loadingState.response!.length,
),
)
else
HttpError(onReload: _controller.onReload),
],
),
: HttpError(onReload: _controller.onReload),
Error() => HttpError(
errMsg: loadingState.errMsg,
onReload: _controller.onReload,
@@ -96,7 +91,10 @@ class _ArticleListPageState extends State<ArticleListPage> {
};
}
Widget _buildHeader(ThemeData theme, ArticleList item) {
Widget _buildHeader(ThemeData theme, ArticleList? item) {
if (item == null) {
return const SliverToBoxAdapter();
}
late final style = TextStyle(color: theme.colorScheme.onSurfaceVariant);
late final divider = TextSpan(
text: ' | ',
@@ -105,6 +103,7 @@ class _ArticleListPageState extends State<ArticleListPage> {
final padding = MediaQuery.paddingOf(context).top + kToolbarHeight;
return SliverAppBar.medium(
title: Text(item.name!),
pinned: true,
expandedHeight: kToolbarHeight + 130,
flexibleSpace: FlexibleSpaceBar(
background: Container(
@@ -117,7 +116,7 @@ class _ArticleListPageState extends State<ArticleListPage> {
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (item.imageUrl?.isNotEmpty == true)
if (item.imageUrl?.isNotEmpty == true) ...[
NetworkImgLayer(
width: 91,
height: 120,
@@ -125,6 +124,7 @@ class _ArticleListPageState extends State<ArticleListPage> {
radius: 6,
),
const SizedBox(width: 10),
],
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@@ -149,6 +149,7 @@ class _ArticleListPageState extends State<ArticleListPage> {
width: 30,
height: 30,
src: _controller.author!.face,
type: ImageType.avatar,
),
const SizedBox(width: 10),
Text(_controller.author!.name!),
@@ -162,9 +163,9 @@ class _ArticleListPageState extends State<ArticleListPage> {
children: [
TextSpan(text: '${item.articlesCount}篇专栏'),
divider,
TextSpan(text: '${item.words}个字'),
TextSpan(text: '${Utils.numFormat(item.words)}个字'),
divider,
TextSpan(text: '${item.read}次阅读'),
TextSpan(text: '${Utils.numFormat(item.read)}次阅读'),
],
style: style,
),

View File

@@ -3,6 +3,7 @@ import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/user/black.dart';
import 'package:PiliPlus/pages/blacklist/controller.dart';
import 'package:PiliPlus/utils/storage.dart';
@@ -75,7 +76,7 @@ class _BlackListPageState extends State<BlackListPage> {
leading: NetworkImgLayer(
width: 45,
height: 45,
type: 'avatar',
type: ImageType.avatar,
src: item.face,
),
title: Text(

View File

@@ -3,6 +3,7 @@ import 'package:PiliPlus/common/widgets/badge.dart';
import 'package:PiliPlus/common/widgets/image/image_save.dart';
import 'package:PiliPlus/common/widgets/image/image_view.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/dynamics/result.dart';
import 'package:PiliPlus/pages/article/widgets/opus_content.dart';
import 'package:PiliPlus/pages/dynamics/widgets/additional_panel.dart';
@@ -332,7 +333,6 @@ Widget forWard(
child: Row(
children: [
NetworkImgLayer(
type: 'cover',
radius: 8,
width: 45,
height: 45,
@@ -382,7 +382,6 @@ Widget forWard(
child: Row(
children: [
NetworkImgLayer(
type: 'cover',
radius: 8,
width: 45,
height: 45,
@@ -432,7 +431,7 @@ Widget forWard(
NetworkImgLayer(
width: 28,
height: 28,
type: 'avatar',
type: ImageType.avatar,
src: item.modules.moduleAuthor!.face,
),
const SizedBox(width: 10),

View File

@@ -1,6 +1,7 @@
import 'package:PiliPlus/common/widgets/image/image_view.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/http/search.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/dynamics/result.dart';
import 'package:PiliPlus/pages/dynamics/widgets/vote.dart';
import 'package:PiliPlus/utils/app_scheme.dart';
@@ -136,7 +137,7 @@ TextSpan? richNode(
WidgetSpan(
child: NetworkImgLayer(
src: i.emoji!.webpUrl ?? i.emoji!.gifUrl ?? i.emoji!.iconUrl,
type: 'emote',
type: ImageType.emote,
width: (i.emoji!.size ?? 1) * 20,
height: (i.emoji!.size ?? 1) * 20,
),

View File

@@ -1,4 +1,5 @@
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/dynamics/up.dart';
import 'package:PiliPlus/pages/dynamics/controller.dart';
import 'package:PiliPlus/utils/extension.dart';
@@ -150,7 +151,7 @@ class _UpPanelState extends State<UpPanel> {
width: 38,
height: 38,
src: data.face,
type: 'avatar',
type: ImageType.avatar,
)
: const CircleAvatar(
backgroundColor: Color(0xFF5CB67B),

View File

@@ -2,6 +2,7 @@ import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/loading_widget/loading_widget.dart';
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/video/reply/emote.dart';
import 'package:PiliPlus/pages/emote/controller.dart';
import 'package:flutter/material.dart';
@@ -78,7 +79,7 @@ class _EmotePanelState extends State<EmotePanel>
width: size * 38,
height: size * 38,
semanticsLabel: e.emote![index].text!,
type: 'emote',
type: ImageType.emote,
boxFit: BoxFit.contain,
),
),
@@ -107,7 +108,7 @@ class _EmotePanelState extends State<EmotePanel>
child: NetworkImgLayer(
width: 24,
height: 24,
type: 'emote',
type: ImageType.emote,
src: e.url,
),
),

View File

@@ -4,6 +4,7 @@ import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/fans/result.dart';
import 'package:PiliPlus/pages/fan/controller.dart';
import 'package:PiliPlus/pages/share/view.dart' show UserModel;
@@ -132,7 +133,7 @@ class _FansPageState extends State<FansPage> {
child: NetworkImgLayer(
width: 45,
height: 45,
type: 'avatar',
type: ImageType.avatar,
src: item.face,
),
),

View File

@@ -18,7 +18,6 @@ class FavDetailController
late int mediaId;
late String heroTag;
RxBool isOwner = false.obs;
RxBool titleCtr = false.obs;
dynamic mid;

View File

@@ -36,18 +36,6 @@ class _FavDetailPageState extends State<FavDetailPage> {
void initState() {
super.initState();
mediaId = Get.parameters['mediaId']!;
_favDetailController.scrollController.addListener(listener);
}
void listener() {
_favDetailController.titleCtr.value =
_favDetailController.scrollController.offset >= 130;
}
@override
void dispose() {
_favDetailController.scrollController.removeListener(listener);
super.dispose();
}
@override
@@ -81,7 +69,20 @@ class _FavDetailPageState extends State<FavDetailPage> {
physics: const AlwaysScrollableScrollPhysics(),
controller: _favDetailController.scrollController,
slivers: [
SliverAppBar(
_buildHeader(theme),
Obx(() => _buildBody(
theme, _favDetailController.loadingState.value)),
],
),
),
),
),
),
);
}
Widget _buildHeader(ThemeData theme) {
return SliverAppBar.medium(
leading: _favDetailController.enableMultiSelect.value
? IconButton(
tooltip: '取消',
@@ -92,16 +93,8 @@ class _FavDetailPageState extends State<FavDetailPage> {
expandedHeight: kToolbarHeight + 130,
pinned: true,
title: _favDetailController.enableMultiSelect.value
? Text(
'已选: ${_favDetailController.checkedCount.value}',
)
: Obx(
() => AnimatedOpacity(
opacity:
_favDetailController.titleCtr.value ? 1 : 0,
curve: Curves.easeOut,
duration: const Duration(milliseconds: 500),
child: Column(
? Text('已选: ${_favDetailController.checkedCount.value}')
: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
@@ -114,16 +107,13 @@ class _FavDetailPageState extends State<FavDetailPage> {
)
],
),
),
),
actions: _favDetailController.enableMultiSelect.value
? [
TextButton(
style: TextButton.styleFrom(
visualDensity: VisualDensity.compact,
),
onPressed: () =>
_favDetailController.handleSelect(true),
onPressed: () => _favDetailController.handleSelect(true),
child: const Text('全选'),
),
TextButton(
@@ -131,8 +121,7 @@ class _FavDetailPageState extends State<FavDetailPage> {
visualDensity: VisualDensity.compact,
),
onPressed: () {
RequestUtils.onCopyOrMove<FavDetailData,
FavDetailItemData>(
RequestUtils.onCopyOrMove<FavDetailData, FavDetailItemData>(
context: context,
isCopy: true,
ctr: _favDetailController,
@@ -152,8 +141,7 @@ class _FavDetailPageState extends State<FavDetailPage> {
visualDensity: VisualDensity.compact,
),
onPressed: () {
RequestUtils.onCopyOrMove<FavDetailData,
FavDetailItemData>(
RequestUtils.onCopyOrMove<FavDetailData, FavDetailItemData>(
context: context,
isCopy: false,
ctr: _favDetailController,
@@ -172,12 +160,10 @@ class _FavDetailPageState extends State<FavDetailPage> {
style: TextButton.styleFrom(
visualDensity: VisualDensity.compact,
),
onPressed: () =>
_favDetailController.onDelChecked(context),
onPressed: () => _favDetailController.onDelChecked(context),
child: Text(
'删除',
style:
TextStyle(color: theme.colorScheme.error),
style: TextStyle(color: theme.colorScheme.error),
),
),
const SizedBox(width: 6),
@@ -190,10 +176,8 @@ class _FavDetailPageState extends State<FavDetailPage> {
arguments: {
'type': 0,
'mediaId': int.parse(mediaId),
'title':
_favDetailController.item.value.title,
'count': _favDetailController
.item.value.mediaCount,
'title': _favDetailController.item.value.title,
'count': _favDetailController.item.value.mediaCount,
'isOwner': _favDetailController.isOwner.value,
},
),
@@ -211,8 +195,7 @@ class _FavDetailPageState extends State<FavDetailPage> {
parameters: {'mediaId': mediaId},
)?.then((res) {
if (res is FavFolderItemData) {
_favDetailController
.item.value = res;
_favDetailController.item.value = res;
}
});
},
@@ -220,19 +203,15 @@ class _FavDetailPageState extends State<FavDetailPage> {
),
PopupMenuItem(
onTap: () {
UserHttp.cleanFav(mediaId: mediaId)
.then((data) {
UserHttp.cleanFav(mediaId: mediaId).then((data) {
if (data['status']) {
SmartDialog.showToast('清除成功');
Future.delayed(
const Duration(
milliseconds: 200), () {
_favDetailController
.onReload();
const Duration(milliseconds: 200), () {
_favDetailController.onReload();
});
} else {
SmartDialog.showToast(
data['msg']);
SmartDialog.showToast(data['msg']);
}
});
},
@@ -240,22 +219,18 @@ class _FavDetailPageState extends State<FavDetailPage> {
),
PopupMenuItem(
onTap: () {
if (_favDetailController
.loadingState
.value is Success &&
((_favDetailController
.loadingState
.value
if (_favDetailController.loadingState.value
is Success &&
((_favDetailController.loadingState.value
as Success)
.response as List?)
?.isNotEmpty ==
true) {
if ((_favDetailController.item
.value.mediaCount ??
if ((_favDetailController
.item.value.mediaCount ??
0) >
1000) {
SmartDialog.showToast(
'内容太多啦超过1000不支持排序');
SmartDialog.showToast('内容太多啦超过1000不支持排序');
return;
}
Get.to(
@@ -268,25 +243,20 @@ class _FavDetailPageState extends State<FavDetailPage> {
child: const Text('排序'),
),
if (!Utils.isDefaultFav(
_favDetailController
.item.value.attr ??
0))
_favDetailController.item.value.attr ?? 0))
PopupMenuItem(
onTap: () {
showConfirmDialog(
context: context,
title: '确定删除该收藏夹?',
onConfirm: () {
UserHttp.deleteFolder(
mediaIds: [mediaId])
UserHttp.deleteFolder(mediaIds: [mediaId])
.then((data) {
if (data['status']) {
SmartDialog.showToast(
'删除成功');
SmartDialog.showToast('删除成功');
Get.back(result: true);
} else {
SmartDialog.showToast(
data['msg']);
SmartDialog.showToast(data['msg']);
}
});
},
@@ -308,9 +278,7 @@ class _FavDetailPageState extends State<FavDetailPage> {
flexibleSpace: FlexibleSpaceBar(
background: Padding(
padding: EdgeInsets.only(
top: kToolbarHeight +
MediaQuery.of(context).padding.top +
10,
top: kToolbarHeight + MediaQuery.of(context).padding.top + 10,
left: 14,
right: 20,
bottom: 10,
@@ -335,55 +303,41 @@ class _FavDetailPageState extends State<FavDetailPage> {
height: 110,
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 4),
Text(
_favDetailController
.item.value.title ??
'',
_favDetailController.item.value.title ?? '',
style: TextStyle(
fontSize: theme.textTheme
.titleMedium!.fontSize,
fontSize: theme.textTheme.titleMedium!.fontSize,
fontWeight: FontWeight.bold),
),
if (_favDetailController
.item.value.intro?.isNotEmpty ==
true)
Text(
_favDetailController
.item.value.intro ??
'',
_favDetailController.item.value.intro ?? '',
style: TextStyle(
fontSize: theme.textTheme
.labelSmall!.fontSize,
color:
theme.colorScheme.outline),
fontSize:
theme.textTheme.labelSmall!.fontSize,
color: theme.colorScheme.outline),
),
const SizedBox(height: 4),
Text(
_favDetailController
.item.value.upper?.name ??
'',
_favDetailController.item.value.upper?.name ?? '',
style: TextStyle(
fontSize: theme.textTheme
.labelSmall!.fontSize,
fontSize: theme.textTheme.labelSmall!.fontSize,
color: theme.colorScheme.outline),
),
const Spacer(),
if (_favDetailController
.item.value.attr !=
null)
if (_favDetailController.item.value.attr != null)
Text(
'${_favDetailController.item.value.mediaCount}条视频 · ${Utils.isPublicFavText(_favDetailController.item.value.attr ?? 0)}',
style: TextStyle(
fontSize: theme.textTheme
.labelSmall!.fontSize,
color:
theme.colorScheme.outline),
fontSize:
theme.textTheme.labelSmall!.fontSize,
color: theme.colorScheme.outline),
),
],
),
@@ -395,15 +349,6 @@ class _FavDetailPageState extends State<FavDetailPage> {
),
),
),
),
Obx(() => _buildBody(
theme, _favDetailController.loadingState.value)),
],
),
),
),
),
),
);
}

View File

@@ -1,4 +1,5 @@
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/follow/result.dart';
import 'package:PiliPlus/pages/share/view.dart' show UserModel;
import 'package:PiliPlus/utils/feed_back.dart';
@@ -49,7 +50,7 @@ class FollowItem extends StatelessWidget {
child: NetworkImgLayer(
width: 45,
height: 45,
type: 'avatar',
type: ImageType.avatar,
src: item.face,
),
),

View File

@@ -2,6 +2,7 @@ import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
import 'package:PiliPlus/models/common/dynamic/dynamic_badge_mode.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/pages/home/controller.dart';
import 'package:PiliPlus/pages/main/controller.dart';
import 'package:PiliPlus/pages/mine/controller.dart';
@@ -98,7 +99,7 @@ class _HomePageState extends State<HomePage>
clipBehavior: Clip.none,
children: [
NetworkImgLayer(
type: 'avatar',
type: ImageType.avatar,
width: 34,
height: 34,
src: _homeController.userFace.value,

View File

@@ -7,6 +7,7 @@ import 'package:PiliPlus/common/widgets/pair.dart';
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
import 'package:PiliPlus/common/widgets/self_sized_horizontal_list.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/live/live_feed_index/card_data_list_item.dart';
import 'package:PiliPlus/models/live/live_feed_index/card_list.dart';
import 'package:PiliPlus/pages/common/common_page.dart';
@@ -311,7 +312,7 @@ class _LivePageState extends CommonPageState<LivePage, LiveController>
shape: BoxShape.circle,
),
child: NetworkImgLayer(
type: 'avatar',
type: ImageType.avatar,
width: 45,
height: 45,
src: item.face,

View File

@@ -4,6 +4,7 @@ import 'package:PiliPlus/common/widgets/keep_alive_wrapper.dart';
import 'package:PiliPlus/common/widgets/loading_widget/loading_widget.dart';
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/live/live_area_list/area_item.dart';
import 'package:PiliPlus/models/live/live_area_list/area_list.dart';
import 'package:PiliPlus/pages/live_area/controller.dart';
@@ -258,7 +259,7 @@ class _LiveAreaPageState extends State<LiveAreaPage> {
width: 45,
height: 45,
src: item.pic,
type: 'emote',
type: ImageType.emote,
),
const SizedBox(height: 4),
Text(

View File

@@ -2,6 +2,7 @@ import 'package:PiliPlus/common/widgets/button/icon_button.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/live/live_area_list/area_item.dart';
import 'package:PiliPlus/pages/live_area_detail/child/view.dart';
import 'package:PiliPlus/pages/live_area_detail/controller.dart';
@@ -131,7 +132,7 @@ class _LiveAreaDetailPageState extends State<LiveAreaDetailPage> {
width: 45,
height: 45,
src: item.pic,
type: 'emote',
type: ImageType.emote,
),
const SizedBox(height: 4),
Text(

View File

@@ -4,6 +4,7 @@ import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/loading_widget/loading_widget.dart';
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/live/live_emoticons/datum.dart';
import 'package:PiliPlus/models/live/live_emoticons/emoticon.dart';
import 'package:PiliPlus/pages/live_emote/controller.dart';
@@ -93,7 +94,7 @@ class _LiveEmotePanelState extends State<LiveEmotePanel>
src: item.emoticons![index].url!,
width: widthFac * 38,
height: heightFac * 38,
type: 'emote',
type: ImageType.emote,
quality: item.pkgType == 3 ? null : 80,
),
),
@@ -122,7 +123,7 @@ class _LiveEmotePanelState extends State<LiveEmotePanel>
child: NetworkImgLayer(
width: 24,
height: 24,
type: 'emote',
type: ImageType.emote,
src: item.currentCover,
),
),

View File

@@ -3,6 +3,7 @@ import 'dart:io';
import 'dart:ui';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/live/live_room/room_info_h5.dart';
import 'package:PiliPlus/pages/live_room/controller.dart';
import 'package:PiliPlus/pages/live_room/send_danmaku/view.dart';
@@ -386,7 +387,7 @@ class _LiveRoomPageState extends State<LiveRoomPage>
child: NetworkImgLayer(
width: 34,
height: 34,
type: 'avatar',
type: ImageType.avatar,
src: _liveRoomController
.roomInfoH5.value!.anchorInfo!.baseInfo!.face,
),

View File

@@ -1,4 +1,5 @@
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/pages/live_room/controller.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/gestures.dart';
@@ -126,7 +127,7 @@ class LiveRoomChat extends StatelessWidget {
child: ExcludeSemantics(
child: NetworkImgLayer(
src: emote['url'],
type: 'emote',
type: ImageType.emote,
width: emote['width'].toDouble(),
height: emote['height'].toDouble(),
semanticsLabel: key,

View File

@@ -1,4 +1,5 @@
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/live/live_search/user_item.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
@@ -30,7 +31,7 @@ class LiveSearchUserItem extends StatelessWidget {
src: item.face,
width: 42,
height: 42,
type: 'avatar',
type: ImageType.avatar,
),
const SizedBox(width: 10),
Column(

View File

@@ -3,6 +3,7 @@ import 'dart:io';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/tabs.dart';
import 'package:PiliPlus/models/common/dynamic/dynamic_badge_mode.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/pages/dynamics/controller.dart';
import 'package:PiliPlus/pages/dynamics/view.dart';
import 'package:PiliPlus/pages/home/controller.dart';
@@ -435,7 +436,7 @@ class _MainAppState extends State<MainApp>
clipBehavior: Clip.none,
children: [
NetworkImgLayer(
type: 'avatar',
type: ImageType.avatar,
width: 34,
height: 34,
src: _homeController.userFace.value,

View File

@@ -1,5 +1,6 @@
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/stat/stat.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/space_opus/item.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:flutter/material.dart';
@@ -38,7 +39,7 @@ class SpaceOpusItem extends StatelessWidget {
width: constraints.maxWidth,
height: constraints.maxWidth * item.cover!.ratio,
src: item.cover!.url,
type: 'emote',
type: ImageType.emote,
quality: 60,
);
},

View File

@@ -6,6 +6,7 @@ import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
import 'package:PiliPlus/grpc/bilibili/app/im/v1.pbenum.dart'
show IMSettingType;
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/msg/msgfeed_at_me.dart';
import 'package:PiliPlus/pages/msg_feed_top/at_me/controller.dart';
import 'package:PiliPlus/pages/whisper_settings/view.dart';
@@ -100,7 +101,7 @@ class _AtMePageState extends State<AtMePage> {
child: NetworkImgLayer(
width: 45,
height: 45,
type: 'avatar',
type: ImageType.avatar,
src: item.user?.avatar,
),
),
@@ -147,7 +148,6 @@ class _AtMePageState extends State<AtMePage> {
? NetworkImgLayer(
width: 45,
height: 45,
type: 'cover',
src: item.item?.image,
)
: null,

View File

@@ -7,6 +7,7 @@ import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
import 'package:PiliPlus/grpc/bilibili/app/im/v1.pbenum.dart'
show IMSettingType;
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/msg/msgfeed_like_me.dart';
import 'package:PiliPlus/pages/msg_feed_top/like_me/controller.dart';
import 'package:PiliPlus/pages/whisper_settings/view.dart';
@@ -255,7 +256,7 @@ class _LikeMePageState extends State<LikeMePage> {
child: NetworkImgLayer(
width: item.users!.length > 1 ? 30 : 45,
height: item.users!.length > 1 ? 30 : 45,
type: 'avatar',
type: ImageType.avatar,
src: item.users![j].avatar,
)),
]
@@ -319,7 +320,6 @@ class _LikeMePageState extends State<LikeMePage> {
NetworkImgLayer(
width: 45,
height: 45,
type: 'cover',
src: item.item!.image,
),
if (item.noticeState == 1)

View File

@@ -6,6 +6,7 @@ import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
import 'package:PiliPlus/grpc/bilibili/app/im/v1.pbenum.dart'
show IMSettingType;
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/msg/msgfeed_reply_me.dart';
import 'package:PiliPlus/pages/msg_feed_top/reply_me/controller.dart';
import 'package:PiliPlus/pages/whisper_settings/view.dart';
@@ -105,7 +106,7 @@ class _ReplyMePageState extends State<ReplyMePage> {
child: NetworkImgLayer(
width: 45,
height: 45,
type: 'avatar',
type: ImageType.avatar,
src: item.user?.avatar,
),
),

View File

@@ -1,6 +1,7 @@
import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/widgets/image/image_save.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/search/result.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
@@ -37,7 +38,7 @@ class LiveItem extends StatelessWidget {
children: [
NetworkImgLayer(
src: liveItem.cover,
type: 'emote',
type: ImageType.emote,
width: maxWidth,
height: maxHeight,
),

View File

@@ -1,6 +1,7 @@
import 'package:PiliPlus/common/widgets/button/icon_button.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/self_sized_horizontal_list.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/pages/contact/view.dart';
import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/request_utils.dart';
@@ -130,7 +131,7 @@ class _SharePanelState extends State<SharePanel> {
width: 40,
height: 40,
src: _userList[index].avatar,
type: 'avatar',
type: ImageType.avatar,
),
),
const SizedBox(height: 2),

View File

@@ -1,6 +1,7 @@
import 'package:PiliPlus/common/skeleton/video_card_h.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/user/sub_detail.dart';
import 'package:PiliPlus/models/user/sub_folder.dart';
@@ -23,23 +24,6 @@ class _SubDetailPageState extends State<SubDetailPage> {
SubDetailController(),
tag: Utils.makeHeroTag(Get.parameters['id']),
);
final RxBool showTitle = false.obs;
@override
void initState() {
super.initState();
_subDetailController.scrollController.addListener(listener);
}
void listener() {
showTitle.value = _subDetailController.scrollController.offset > 132;
}
@override
void dispose() {
_subDetailController.scrollController.removeListener(listener);
super.dispose();
}
@override
Widget build(BuildContext context) {
@@ -48,6 +32,8 @@ class _SubDetailPageState extends State<SubDetailPage> {
body: SafeArea(
top: false,
bottom: false,
child: refreshIndicator(
onRefresh: _subDetailController.onRefresh,
child: CustomScrollView(
controller: _subDetailController.scrollController,
physics: const AlwaysScrollableScrollPhysics(),
@@ -58,6 +44,7 @@ class _SubDetailPageState extends State<SubDetailPage> {
],
),
),
),
);
}
@@ -105,7 +92,7 @@ class _SubDetailPageState extends State<SubDetailPage> {
padding: const EdgeInsets.only(top: 12, bottom: 8, left: 14),
child: Obx(
() => Text(
'${_subDetailController.mediaCount}条视频',
'${_subDetailController.mediaCount.value}条视频',
style: TextStyle(
fontSize: theme.textTheme.labelMedium!.fontSize,
color: theme.colorScheme.outline,
@@ -116,16 +103,10 @@ class _SubDetailPageState extends State<SubDetailPage> {
),
);
Widget _buildAppBar(ThemeData theme) => SliverAppBar(
Widget _buildAppBar(ThemeData theme) => SliverAppBar.medium(
expandedHeight: kToolbarHeight + 132,
pinned: true,
title: Obx(
() {
return AnimatedOpacity(
opacity: showTitle.value ? 1 : 0,
curve: Curves.easeOut,
duration: const Duration(milliseconds: 500),
child: Column(
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
@@ -134,14 +115,13 @@ class _SubDetailPageState extends State<SubDetailPage> {
overflow: TextOverflow.ellipsis,
style: theme.textTheme.titleMedium,
),
Text(
Obx(
() => Text(
'${_subDetailController.mediaCount.value}条视频',
style: theme.textTheme.labelMedium,
)
],
),
);
},
),
],
),
flexibleSpace: FlexibleSpaceBar(
background: Container(

View File

@@ -5,6 +5,7 @@ import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/pendant_avatar.dart';
import 'package:PiliPlus/common/widgets/self_sized_horizontal_list.dart';
import 'package:PiliPlus/common/widgets/stat/stat.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/video_detail_res.dart';
import 'package:PiliPlus/pages/mine/controller.dart';
import 'package:PiliPlus/pages/search/widgets/search_text.dart';
@@ -389,7 +390,7 @@ class _VideoInfoState extends State<VideoInfo> {
clipBehavior: Clip.none,
children: [
NetworkImgLayer(
type: 'avatar',
type: ImageType.avatar,
src: videoItem['staff'][index].face,
width: 35,
height: 35,

View File

@@ -6,6 +6,7 @@ import 'package:PiliPlus/common/widgets/scroll_physics.dart';
import 'package:PiliPlus/common/widgets/video_card/video_card_h_member_video.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/common/image_preview_type.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/member/info.dart';
import 'package:PiliPlus/models/space_archive/item.dart';
import 'package:PiliPlus/pages/video/controller.dart';
@@ -417,7 +418,7 @@ class _HorizontalMemberPageState extends State<HorizontalMemberPage> {
},
child: NetworkImgLayer(
src: face,
type: 'avatar',
type: ImageType.avatar,
width: 70,
height: 70,
),

View File

@@ -4,6 +4,7 @@ import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/pages/common/common_slide_page.dart';
import 'package:PiliPlus/pages/video/note/controller.dart';
import 'package:PiliPlus/pages/webview/view.dart';
@@ -212,7 +213,7 @@ Widget _itemWidget(BuildContext context, ThemeData theme, dynamic item) {
height: 34,
width: 34,
src: item['author']['face'],
type: 'avatar',
type: ImageType.avatar,
),
),
const SizedBox(width: 12),

View File

@@ -11,6 +11,7 @@ import 'package:PiliPlus/grpc/bilibili/main/community/reply/v1.pb.dart'
import 'package:PiliPlus/http/init.dart';
import 'package:PiliPlus/http/video.dart';
import 'package:PiliPlus/models/common/badge_type.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/pages/dynamics/widgets/vote.dart';
import 'package:PiliPlus/pages/save_panel/view.dart';
import 'package:PiliPlus/pages/video/controller.dart';
@@ -656,7 +657,7 @@ class ReplyItemGrpc extends StatelessWidget {
src: content.emotes[matchStr]?.hasGifUrl() == true
? content.emotes[matchStr]?.gifUrl
: content.emotes[matchStr]?.url,
type: 'emote',
type: ImageType.emote,
width: size * 20,
height: size * 20,
semanticsLabel: matchStr,

View File

@@ -6,6 +6,7 @@ import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
import 'package:PiliPlus/grpc/bilibili/im/type.pb.dart' show Msg;
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/http/msg.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/common/publish_panel_type.dart';
import 'package:PiliPlus/pages/common/common_publish_page.dart';
import 'package:PiliPlus/pages/emote/view.dart';
@@ -79,7 +80,7 @@ class _WhisperDetailPageState
NetworkImgLayer(
width: 34,
height: 34,
type: 'avatar',
type: ImageType.avatar,
src: _whisperDetailController.face,
),
const SizedBox(width: 6),

View File

@@ -6,6 +6,7 @@ import 'package:PiliPlus/grpc/bilibili/im/interfaces/v1.pb.dart'
import 'package:PiliPlus/grpc/bilibili/im/type.pb.dart' show Msg, MsgType;
import 'package:PiliPlus/http/search.dart';
import 'package:PiliPlus/models/common/image_preview_type.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/id_utils.dart';
import 'package:PiliPlus/utils/page_utils.dart';
@@ -598,7 +599,7 @@ class ChatItem extends StatelessWidget {
width: emojiMap[emojiKey]!['size'],
height: emojiMap[emojiKey]!['size'],
src: emojiMap[emojiKey]!['url'],
type: 'emote',
type: ImageType.emote,
),
),
);