feat: fold dyn

Closes #1153

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-08-28 16:07:32 +08:00
parent 7a5662c6ca
commit ac26022da1
4 changed files with 82 additions and 3 deletions

View File

@@ -5,6 +5,7 @@ import 'package:PiliPlus/models/common/dynamic/dynamics_type.dart';
import 'package:PiliPlus/models/dynamics/article_content_model.dart';
import 'package:PiliPlus/models/model_avatar.dart';
import 'package:PiliPlus/models_new/live/live_feed_index/watched_show.dart';
import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/storage_pref.dart';
class DynamicsDataModel {
@@ -162,6 +163,7 @@ class ItemModulesModel {
List<ModuleTag>? moduleExtend; // opus的tag
List<ArticleContentModel>? moduleContent;
ModuleBlocked? moduleBlocked;
ModuleFold? moduleFold;
// moduleBottom
@@ -179,6 +181,9 @@ class ItemModulesModel {
moduleTag = json['module_tag'] != null
? ModuleTag.fromJson(json['module_tag'])
: null;
moduleFold = json['module_fold'] != null
? ModuleFold.fromJson(json['module_fold'])
: null;
}
ItemModulesModel.fromOpusJson(List json) {
@@ -233,6 +238,18 @@ class ItemModulesModel {
}
}
class ModuleFold {
List<String>? ids;
String? statement;
int? type;
ModuleFold.fromJson(Map<String, dynamic> json) {
ids = (json['ids'] as List?)?.fromCast();
statement = json['statement'];
type = json['type'];
}
}
class ModuleCollection {
String? count;
int? id;

View File

@@ -20,6 +20,7 @@ class DynamicPanel extends StatelessWidget {
final bool isSave;
final Function(bool isTop, dynamic dynId)? onSetTop;
final VoidCallback? onBlock;
final VoidCallback? onUnfold;
const DynamicPanel({
super.key,
@@ -31,10 +32,14 @@ class DynamicPanel extends StatelessWidget {
this.isSave = false,
this.onSetTop,
this.onBlock,
this.onUnfold,
});
@override
Widget build(BuildContext context) {
if (item.visible == false) {
return const SizedBox.shrink();
}
final theme = Theme.of(context);
final authorWidget = AuthorPanel(
item: item,
@@ -98,8 +103,49 @@ class DynamicPanel extends StatelessWidget {
maxWidth: maxWidth,
),
const SizedBox(height: 2),
if (!isDetail) ActionPanel(item: item),
if (isDetail && !isSave) const SizedBox(height: 12),
if (!isDetail) ...[
ActionPanel(item: item),
if (item.modules.moduleFold case ModuleFold moduleFold) ...[
Divider(
height: 1,
color: theme.dividerColor.withValues(alpha: 0.1),
),
InkWell(
onTap: onUnfold,
child: Container(
alignment: Alignment.center,
padding: const EdgeInsets.symmetric(vertical: 10),
child: Text.rich(
textAlign: TextAlign.center,
style: TextStyle(
height: 1,
fontSize: 13,
color: theme.colorScheme.outline,
),
strutStyle: const StrutStyle(
height: 1,
leading: 0,
fontSize: 13,
),
TextSpan(
children: [
TextSpan(text: moduleFold.statement ?? '展开'),
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Icon(
size: 19,
Icons.keyboard_arrow_down,
color: theme.colorScheme.outline,
),
),
],
),
),
),
),
],
] else if (!isSave)
const SizedBox(height: 12),
],
),
),

View File

@@ -74,4 +74,17 @@ class DynamicsTabController
..refresh();
}
}
void onUnfold(DynamicItemModel item, int index) {
try {
final list = loadingState.value.data!;
final ids = item.modules.moduleFold!.ids!;
final flag = index + ids.length + 1;
for (int i = index + 1; i < flag; i++) {
list[i].visible = true;
}
item.modules.moduleFold = null;
loadingState.refresh();
} catch (_) {}
}
}

View File

@@ -112,12 +112,14 @@ class _DynamicsTabPageState
if (index == response.length - 1) {
controller.onLoadMore();
}
final item = response[index];
return DynamicPanel(
item: response[index],
item: item,
onRemove: (idStr) =>
controller.onRemove(index, idStr),
onBlock: () => controller.onBlock(index),
maxWidth: maxWidth,
onUnfold: () => controller.onUnfold(item, index),
);
},
childCount: response!.length,
@@ -135,6 +137,7 @@ class _DynamicsTabPageState
controller.onRemove(index, idStr),
onBlock: () => controller.onBlock(index),
maxWidth: maxWidth,
onUnfold: () => controller.onUnfold(item, index),
);
},
itemCount: response!.length,