dyn topic fold

Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
dom
2026-07-06 12:22:27 +08:00
parent 5e1c73abc1
commit aa03eed92d
13 changed files with 184 additions and 97 deletions

View File

@@ -87,13 +87,23 @@ class ActionPanel extends StatelessWidget {
Expanded(
child: Builder(
builder: (context) {
final IconData icon;
final Color color;
final String label;
if (like.status ?? false) {
icon = FontAwesomeIcons.solidThumbsUp;
color = primary;
label = '已赞';
} else {
icon = FontAwesomeIcons.thumbsUp;
color = outline;
label = '点赞';
}
final likeIcon = Icon(
like.status!
? FontAwesomeIcons.solidThumbsUp
: FontAwesomeIcons.thumbsUp,
icon,
size: 16,
color: like.status! ? primary : outline,
semanticLabel: like.status! ? "已赞" : "点赞",
color: color,
semanticLabel: label,
);
return TextButton.icon(
onPressed: () => RequestUtils.onLikeDynamic(

View File

@@ -76,36 +76,13 @@ class _DynamicsTabPageState extends State<DynamicsTabPage>
? SliverWaterfallFlow(
gridDelegate: dynGridDelegate,
delegate: SliverChildBuilderDelegate(
(_, index) {
if (index == response.length - 1) {
controller.onLoadMore();
}
final item = response[index];
return DynamicPanel(
item: item,
onRemove: (idStr) =>
controller.onRemove(index, idStr),
onBlock: () => controller.onBlock(index),
onUnfold: () => controller.onUnfold(item, index),
);
},
(_, index) => _itemBuilder(response, index),
childCount: response.length,
),
)
: SliverList.builder(
itemBuilder: (context, index) {
if (index == response.length - 1) {
controller.onLoadMore();
}
final item = response[index];
return DynamicPanel(
item: item,
onRemove: (idStr) =>
controller.onRemove(index, idStr),
onBlock: () => controller.onBlock(index),
onUnfold: () => controller.onUnfold(item, index),
);
},
itemBuilder: (context, index) =>
_itemBuilder(response, index),
itemCount: response.length,
)
: HttpError(onReload: controller.onReload),
@@ -115,4 +92,17 @@ class _DynamicsTabPageState extends State<DynamicsTabPage>
),
};
}
Widget _itemBuilder(List<DynamicItemModel> list, int index) {
if (index == list.length - 1) {
controller.onLoadMore();
}
final item = list[index];
return DynamicPanel(
item: item,
onRemove: (idStr) => controller.onRemove(index, idStr),
onBlock: () => controller.onBlock(index),
onUnfold: () => controller.onUnfold(item, index),
);
}
}

View File

@@ -130,4 +130,16 @@ class DynTopicController
res.toast();
}
}
Future<void> topicFold() async {
final res = await DynamicsHttp.topicFold(topicId: topicId, sortBy: sortBy);
if (res case Success(:final response)) {
if (response?.items case final items? when items.isNotEmpty) {
loadingState.value.data!
..removeLast()
..addAll(items);
loadingState.refresh();
}
}
}
}

View File

@@ -9,6 +9,7 @@ import 'package:PiliPlus/common/widgets/sliver/sliver_pinned_header.dart';
import 'package:PiliPlus/http/constants.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models_new/dynamic/dyn_topic_feed/fold_card_item.dart';
import 'package:PiliPlus/models_new/dynamic/dyn_topic_feed/item.dart';
import 'package:PiliPlus/models_new/dynamic/dyn_topic_top/top_details.dart';
import 'package:PiliPlus/pages/common/fab_mixin.dart';
@@ -41,15 +42,22 @@ class DynTopicPage extends StatefulWidget {
class _DynTopicPageState extends State<DynTopicPage>
with DynMixin, SingleTickerProviderStateMixin, BaseFabMixin, FabMixin {
late EdgeInsets padding;
late ColorScheme colorScheme;
final DynTopicController _controller = Get.put(
DynTopicController(),
tag: Utils.generateRandomString(8),
);
@override
void didChangeDependencies() {
super.didChangeDependencies();
colorScheme = ColorScheme.of(context);
padding = MediaQuery.viewPaddingOf(context);
}
@override
Widget build(BuildContext context) {
final colorScheme = ColorScheme.of(context);
final padding = MediaQuery.viewPaddingOf(context);
return Material(
child: Stack(
clipBehavior: .none,
@@ -372,33 +380,13 @@ class _DynTopicPageState extends State<DynTopicPage>
? SliverWaterfallFlow(
gridDelegate: dynGridDelegate,
delegate: SliverChildBuilderDelegate(
(_, index) {
if (index == response.length - 1) {
_controller.onLoadMore();
}
final item = response[index];
if (item.dynamicCardItem != null) {
return DynamicPanel(item: item.dynamicCardItem!);
}
return Text(item.topicType ?? 'err');
},
(_, index) => _itemBuilder(response, index),
childCount: response.length,
),
)
: SliverList.builder(
itemBuilder: (context, index) {
if (index == response.length - 1) {
_controller.onLoadMore();
}
final item = response[index];
if (item.dynamicCardItem != null) {
return DynamicPanel(item: item.dynamicCardItem!);
} else {
return Text(item.topicType ?? 'err');
}
},
itemBuilder: (context, index) =>
_itemBuilder(response, index),
itemCount: response.length,
)
: HttpError(onReload: _controller.onReload),
@@ -408,4 +396,44 @@ class _DynTopicPageState extends State<DynTopicPage>
),
};
}
Widget _itemBuilder(List<TopicCardItem> list, int index) {
if (index == list.length - 1) {
_controller.onLoadMore();
}
final item = list[index];
if (item.dynamicCardItem case final dynamicCardItem?) {
return DynamicPanel(item: dynamicCardItem);
}
if (item.foldCardItem case final foldCardItem?) {
return _buildFoldItem(foldCardItem);
}
return Text(item.topicType ?? 'err');
}
Widget _buildFoldItem(FoldCardItem item) {
return Padding(
padding: const .only(top: 12),
child: InkWell(
onTap: _controller.topicFold,
child: Ink(
padding: const .symmetric(vertical: 10),
color: colorScheme.outline.withValues(alpha: .05),
child: Center(
child: Row(
mainAxisSize: .min,
children: [
Text(item.foldDesc!),
const Icon(Icons.keyboard_arrow_right, size: 22),
],
),
),
),
),
);
}
}

View File

@@ -85,30 +85,13 @@ class _MemberDynamicsPageState extends State<MemberDynamicsPage>
? SliverWaterfallFlow(
gridDelegate: dynGridDelegate,
delegate: SliverChildBuilderDelegate(
(_, index) {
if (index == response.length - 1) {
_memberDynamicController.onLoadMore();
}
return DynamicPanel(
item: response[index],
onRemove: _memberDynamicController.onRemove,
onSetTop: _memberDynamicController.onSetTop,
);
},
(_, index) => _itemBuilder(response, index),
childCount: response.length,
),
)
: SliverList.builder(
itemBuilder: (context, index) {
if (index == response.length - 1) {
_memberDynamicController.onLoadMore();
}
return DynamicPanel(
item: response[index],
onRemove: _memberDynamicController.onRemove,
onSetTop: _memberDynamicController.onSetTop,
);
},
itemBuilder: (context, index) =>
_itemBuilder(response, index),
itemCount: response.length,
)
: HttpError(onReload: _memberDynamicController.onReload),
@@ -118,4 +101,15 @@ class _MemberDynamicsPageState extends State<MemberDynamicsPage>
),
};
}
Widget _itemBuilder(List<DynamicItemModel> list, int index) {
if (index == list.length - 1) {
_memberDynamicController.onLoadMore();
}
return DynamicPanel(
item: list[index],
onRemove: _memberDynamicController.onRemove,
onSetTop: _memberDynamicController.onSetTop,
);
}
}

View File

@@ -87,22 +87,13 @@ class _MemberSearchChildPageState extends State<MemberSearchChildPage>
? SliverWaterfallFlow(
gridDelegate: dynGridDelegate,
delegate: SliverChildBuilderDelegate(
(_, index) {
if (index == response.length - 1) {
_controller.onLoadMore();
}
return DynamicPanel(item: response[index]);
},
(_, index) => _itemBuilder(response, index),
childCount: response.length,
),
)
: SliverList.builder(
itemBuilder: (context, index) {
if (index == response.length - 1) {
_controller.onLoadMore();
}
return DynamicPanel(item: response[index]);
},
itemBuilder: (context, index) =>
_itemBuilder(response, index),
itemCount: response.length,
),
}
@@ -114,6 +105,13 @@ class _MemberSearchChildPageState extends State<MemberSearchChildPage>
};
}
Widget _itemBuilder(List list, int index) {
if (index == list.length - 1) {
_controller.onLoadMore();
}
return DynamicPanel(item: list[index]);
}
@override
bool get wantKeepAlive => true;
}