Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-05-17 18:08:55 +08:00
parent 906c21e252
commit 1d4eabb770
58 changed files with 875 additions and 684 deletions

View File

@@ -0,0 +1,9 @@
class Attributes {
String? clazz;
Attributes({this.clazz});
factory Attributes.fromJson(Map<String, dynamic> json) => Attributes(
clazz: json['class'] as String?,
);
}

View File

@@ -0,0 +1,92 @@
import 'package:PiliPlus/models/dynamics/article_opus/attributes.dart';
class ReadOpusModel {
dynamic insert;
Attributes? attributes;
ReadOpusModel({this.insert, this.attributes});
ReadOpusModel.fromJson(Map<String, dynamic> json) {
if (json['insert'] is Map) {
insert = Insert.fromJson(json['insert']);
} else {
insert = json['insert'];
}
attributes = json['attributes'] == null
? null
: Attributes.fromJson(json['attributes'] as Map<String, dynamic>);
}
}
class Insert {
InsertCard? card;
Insert({
this.card,
});
Insert.fromJson(Map<String, dynamic> json) {
if (json['article-card'] != null) {
card = InsertCard.fromJson(json['article-card']);
return;
}
if (json['live-card'] != null) {
card = InsertCard.fromJson(json['live-card']);
return;
}
if (json['goods-card'] != null) {
card = InsertCard.fromJson(json['goods-card']);
return;
}
if (json['video-card'] != null) {
card = InsertCard.fromJson(json['video-card']);
return;
}
if (json['mall-card'] != null) {
card = InsertCard.fromJson(json['mall-card']);
return;
}
if (json['vote-card'] != null) {
card = InsertCard.fromJson(json['vote-card']);
return;
}
}
}
class InsertCard {
dynamic tid;
String? id;
dynamic alt;
String? url;
num? width;
num? height;
num? size;
String? status;
InsertCard({
this.tid,
this.id,
this.alt,
this.url,
this.width,
this.height,
this.size,
this.status,
});
InsertCard.fromJson(Map<String, dynamic> json) {
tid = json['tid'];
id = json['id'] == '' ? null : json['id'];
alt = json['alt'];
url = json['url'];
width = json['width'];
height = json['height'];
size = json['size'];
status = json['status'];
}
}

View File

@@ -1,5 +1,7 @@
import 'package:PiliPlus/models/dynamics/article_content_model.dart';
import 'dart:convert';
import 'package:PiliPlus/models/dynamics/article_content_model.dart';
import 'package:PiliPlus/models/dynamics/article_opus/opus.dart';
import 'package:PiliPlus/models/space_article/author.dart';
import 'package:PiliPlus/models/space_article/category.dart';
import 'package:PiliPlus/models/space_article/media.dart';
@@ -55,6 +57,7 @@ class SpaceArticleItem {
int? versionId;
String? dynIdStr;
int? totalArtNum;
List<ReadOpusModel>? ops;
SpaceArticleItem.fromJson(Map<String, dynamic> json) {
id = json["id"];
@@ -105,8 +108,13 @@ class SpaceArticleItem {
keywords = json["keywords"];
if (json['opus'] != null) opus = Opus.fromJson(json['opus']);
versionId = json["version_id"];
dynIdStr = json["dyn_id_str"];
dynIdStr = json["dyn_id_str"] == '' ? null : json["dyn_id_str"];
totalArtNum = json["total_art_num"];
if (type == 3 && content != null) {
ops = (jsonDecode(content!)['ops'] as List?)
?.map((e) => ReadOpusModel.fromJson(e))
.toList();
}
}
}

View File

@@ -17,6 +17,7 @@ import 'package:PiliPlus/models/dynamics/result.dart' show DynamicStat;
import 'package:PiliPlus/pages/article/controller.dart';
import 'package:PiliPlus/pages/article/widgets/html_render.dart';
import 'package:PiliPlus/pages/article/widgets/opus_content.dart';
import 'package:PiliPlus/pages/article/widgets/read_opus.dart';
import 'package:PiliPlus/pages/dynamics_repost/view.dart';
import 'package:PiliPlus/pages/video/reply/widgets/reply_item_grpc.dart';
import 'package:PiliPlus/pages/video/reply_reply/view.dart';
@@ -360,6 +361,10 @@ class _ArticlePageState extends State<ArticlePage>
child: moduleBlockedItem(theme, moduleBlocked, maxWidth),
);
} else if (_articleCtr.articleData?.content != null) {
if (_articleCtr.articleData?.type == 3) {
// json
return ReadOpus(ops: _articleCtr.articleData?.ops);
}
debugPrint('html page');
final res = parser.parse(_articleCtr.articleData!.content!);
if (res.body!.children.isEmpty) {

View File

@@ -0,0 +1,77 @@
import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/models/dynamics/article_opus/opus.dart';
import 'package:PiliPlus/pages/dynamics/widgets/vote.dart';
import 'package:PiliPlus/utils/app_scheme.dart';
import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class ReadOpus extends StatelessWidget {
const ReadOpus({super.key, required this.ops});
final List<ReadOpusModel>? ops;
@override
Widget build(BuildContext context) {
if (ops.isNullOrEmpty) {
return const SliverToBoxAdapter();
}
return SliverList.separated(
itemCount: ops!.length,
itemBuilder: (context, index) {
try {
final item = ops![index];
if (item.insert is String) {
return SelectableText(item.insert);
}
if (item.insert is Insert) {
InsertCard card = item.insert.card;
if (card.url?.isNotEmpty == true) {
return GestureDetector(
onTap: () {
switch (item.attributes?.clazz) {
case 'article-card card':
if (card.id != null) {
Get.toNamed(
'/articlePage',
parameters: {
'id': card.id!.substring(2),
'type': 'read',
},
);
}
case 'video-card card':
if (card.id != null) {
PiliScheme.videoPush(null, card.id);
}
case 'vote-card card':
if (card.id != null) {
showVoteDialog(context, card.id);
}
}
},
child: ClipRRect(
borderRadius: StyleString.mdRadius,
child: CachedNetworkImage(
imageUrl: Utils.thumbnailImgUrl(card.url, 60),
),
),
);
}
}
return Text('${item.attributes}');
} catch (e) {
return Text(e.toString());
}
},
separatorBuilder: (context, index) {
return const SizedBox(height: 10);
},
);
}
}

View File

@@ -171,7 +171,7 @@ class _DynamicsPageState extends State<DynamicsPage>
children: [
if (upPanelPosition == UpPanelPosition.top) upPanelPart(theme),
Expanded(
child: tabBarView(
child: videoTabBarView(
controller: _dynamicsController.tabController,
children: _dynamicsController.tabsPageList,
),