mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
refa: opus (#762)
* feat: opus * fix * fix * fix * fix * . * fix * remove * wbi sign * fix * opus content null check Co-authored-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
committed by
GitHub
parent
3722ff1f33
commit
bd3c76ef43
@@ -105,7 +105,7 @@ class _SavePanelState extends State<SavePanel> {
|
|||||||
} else if (currentRoute.startsWith('/dynamicDetail')) {
|
} else if (currentRoute.startsWith('/dynamicDetail')) {
|
||||||
try {
|
try {
|
||||||
DynamicItemModel dynItem = Get.arguments['item'];
|
DynamicItemModel dynItem = Get.arguments['item'];
|
||||||
uname = dynItem.modules?.moduleAuthor?.name;
|
uname = dynItem.modules.moduleAuthor?.name;
|
||||||
final type = _item.type.toInt();
|
final type = _item.type.toInt();
|
||||||
late final oid = dynItem.idStr;
|
late final oid = dynItem.idStr;
|
||||||
late final rootId = hasRoot ? _item.root : _item.id;
|
late final rootId = hasRoot ? _item.root : _item.id;
|
||||||
@@ -117,7 +117,7 @@ class _SavePanelState extends State<SavePanel> {
|
|||||||
1 ||
|
1 ||
|
||||||
11 ||
|
11 ||
|
||||||
12 =>
|
12 =>
|
||||||
'bilibili://comment/detail/$type/${dynItem.basic!['rid_str']}/$rootId/?${anchor}enterUri=$enterUri',
|
'bilibili://comment/detail/$type/${dynItem.basic!.ridStr}/$rootId/?${anchor}enterUri=$enterUri',
|
||||||
_ =>
|
_ =>
|
||||||
'bilibili://comment/detail/$type/$oid/$rootId/?${anchor}enterUri=$enterUri',
|
'bilibili://comment/detail/$type/$oid/$rootId/?${anchor}enterUri=$enterUri',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import 'package:PiliPlus/http/loading_state.dart';
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
import 'package:PiliPlus/models/dynamics/article_view/data.dart';
|
|
||||||
import 'package:PiliPlus/models/dynamics/opus_detail/data.dart';
|
|
||||||
import 'package:PiliPlus/utils/accounts/account.dart';
|
import 'package:PiliPlus/utils/accounts/account.dart';
|
||||||
import 'package:PiliPlus/utils/storage.dart';
|
import 'package:PiliPlus/utils/storage.dart';
|
||||||
import 'package:PiliPlus/utils/wbi_sign.dart';
|
import 'package:PiliPlus/utils/wbi_sign.dart';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
|
|
||||||
|
import '../models/space_article/item.dart';
|
||||||
import '../models/dynamics/result.dart';
|
import '../models/dynamics/result.dart';
|
||||||
import '../models/dynamics/up.dart';
|
import '../models/dynamics/up.dart';
|
||||||
import 'index.dart';
|
import 'index.dart';
|
||||||
@@ -33,9 +32,9 @@ class DynamicsHttp {
|
|||||||
if (GStorage.antiGoodsDyn) {
|
if (GStorage.antiGoodsDyn) {
|
||||||
data.items?.removeWhere(
|
data.items?.removeWhere(
|
||||||
(item) =>
|
(item) =>
|
||||||
item.orig?.modules?.moduleDynamic?.additional?.type ==
|
item.orig?.modules.moduleDynamic?.additional?.type ==
|
||||||
'ADDITIONAL_TYPE_GOODS' ||
|
'ADDITIONAL_TYPE_GOODS' ||
|
||||||
item.modules?.moduleDynamic?.additional?.type ==
|
item.modules.moduleDynamic?.additional?.type ==
|
||||||
'ADDITIONAL_TYPE_GOODS',
|
'ADDITIONAL_TYPE_GOODS',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -160,37 +159,34 @@ class DynamicsHttp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future articleView({
|
static Future<LoadingState<Item>> articleView({required dynamic cvId}) async {
|
||||||
required dynamic cvId,
|
final res = await Request().get(
|
||||||
}) async {
|
|
||||||
var res = await Request().get(
|
|
||||||
Api.articleView,
|
Api.articleView,
|
||||||
queryParameters: await WbiSign.makSign({
|
queryParameters: await WbiSign.makSign({
|
||||||
'id': cvId,
|
'id': cvId,
|
||||||
'gaia_source': 'main_web',
|
'gaia_source': 'main_web',
|
||||||
|
'web_location': '333.976',
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
if (res.data['code'] == 0) {
|
|
||||||
return {'status': true, 'data': ArticleData.fromJson(res.data['data'])};
|
return res.data['code'] == 0
|
||||||
} else {
|
? LoadingState.success(Item.fromJson(res.data['data']))
|
||||||
return {'status': false, 'msg': res.data['message']};
|
: LoadingState.error(res.data['message']);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future opusDetail({
|
static Future<LoadingState<DynamicItemModel>> opusDetail(
|
||||||
required dynamic opusId,
|
{required dynamic opusId}) async {
|
||||||
}) async {
|
final res = await Request().get(
|
||||||
var res = await Request().get(
|
|
||||||
Api.opusDetail,
|
Api.opusDetail,
|
||||||
queryParameters: await WbiSign.makSign({
|
queryParameters: await WbiSign.makSign({
|
||||||
'id': opusId,
|
'timezone_offset': '-480',
|
||||||
'features': 'htmlNewStyle',
|
'features': 'htmlNewStyle',
|
||||||
|
'id': opusId,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
if (res.data['code'] == 0) {
|
|
||||||
return {'status': true, 'data': OpusData.fromJson(res.data['data'])};
|
return res.data['code'] == 0
|
||||||
} else {
|
? LoadingState.success(DynamicItemModel.fromOpusJson(res.data['data']))
|
||||||
return {'status': false, 'msg': res.data['message']};
|
: LoadingState.error(res.data['message']);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -414,9 +414,9 @@ class MemberHttp {
|
|||||||
DynamicsDataModel data = DynamicsDataModel.fromJson(res.data['data']);
|
DynamicsDataModel data = DynamicsDataModel.fromJson(res.data['data']);
|
||||||
if (GStorage.antiGoodsDyn) {
|
if (GStorage.antiGoodsDyn) {
|
||||||
data.items?.removeWhere((item) =>
|
data.items?.removeWhere((item) =>
|
||||||
item.orig?.modules?.moduleDynamic?.additional?.type ==
|
item.orig?.modules.moduleDynamic?.additional?.type ==
|
||||||
'ADDITIONAL_TYPE_GOODS' ||
|
'ADDITIONAL_TYPE_GOODS' ||
|
||||||
item.modules?.moduleDynamic?.additional?.type ==
|
item.modules.moduleDynamic?.additional?.type ==
|
||||||
'ADDITIONAL_TYPE_GOODS');
|
'ADDITIONAL_TYPE_GOODS');
|
||||||
}
|
}
|
||||||
return LoadingState.success(data);
|
return LoadingState.success(data);
|
||||||
|
|||||||
308
lib/models/dynamics/article_content_model.dart
Normal file
308
lib/models/dynamics/article_content_model.dart
Normal file
@@ -0,0 +1,308 @@
|
|||||||
|
class ArticleContentModel {
|
||||||
|
int? align;
|
||||||
|
int? paraType;
|
||||||
|
Text? text;
|
||||||
|
Format? format;
|
||||||
|
Line? line;
|
||||||
|
Pic? pic;
|
||||||
|
LinkCard? linkCard;
|
||||||
|
Code? code;
|
||||||
|
L1st? list;
|
||||||
|
|
||||||
|
ArticleContentModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
align = json['align'];
|
||||||
|
paraType = json['para_type'];
|
||||||
|
text = json['text'] == null ? null : Text.fromJson(json['text']);
|
||||||
|
format = json['format'] == null ? null : Format.fromJson(json['format']);
|
||||||
|
line = json['line'] == null ? null : Line.fromJson(json['line']);
|
||||||
|
pic = json['pic'] == null ? null : Pic.fromJson(json['pic']);
|
||||||
|
linkCard =
|
||||||
|
json['link_card'] == null ? null : LinkCard.fromJson(json['link_card']);
|
||||||
|
code = json['code'] == null ? null : Code.fromJson(json['code']);
|
||||||
|
list = json['list'] == null ? null : L1st.fromJson(json['list']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Pic {
|
||||||
|
List<Pic>? pics;
|
||||||
|
int? style;
|
||||||
|
String? url;
|
||||||
|
num? width;
|
||||||
|
num? height;
|
||||||
|
num? size;
|
||||||
|
String? liveUrl;
|
||||||
|
|
||||||
|
double? calHeight;
|
||||||
|
|
||||||
|
Pic.fromJson(Map<String, dynamic> json) {
|
||||||
|
url = json['url'];
|
||||||
|
width = json['width'];
|
||||||
|
height = json['height'];
|
||||||
|
size = json['size'];
|
||||||
|
pics = (json['pics'] as List?)?.map((item) => Pic.fromJson(item)).toList();
|
||||||
|
style = json['style'];
|
||||||
|
liveUrl = json['live_url'];
|
||||||
|
}
|
||||||
|
|
||||||
|
void onCalHeight(double maxWidth) {
|
||||||
|
if (calHeight == null && height != null && width != null) {
|
||||||
|
calHeight = maxWidth * height! / width!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Line {
|
||||||
|
Line({
|
||||||
|
this.pic,
|
||||||
|
});
|
||||||
|
Pic? pic;
|
||||||
|
|
||||||
|
Line.fromJson(Map<String, dynamic> json) {
|
||||||
|
pic = json['pic'] == null ? null : Pic.fromJson(json['pic']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Format {
|
||||||
|
Format({
|
||||||
|
this.align,
|
||||||
|
});
|
||||||
|
int? align;
|
||||||
|
|
||||||
|
Format.fromJson(Map<String, dynamic> json) {
|
||||||
|
align = json['align'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Text {
|
||||||
|
Text({
|
||||||
|
this.nodes,
|
||||||
|
});
|
||||||
|
List<Nodes>? nodes;
|
||||||
|
|
||||||
|
Text.fromJson(Map<String, dynamic> json) {
|
||||||
|
nodes =
|
||||||
|
(json['nodes'] as List?)?.map((item) => Nodes.fromJson(item)).toList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Nodes {
|
||||||
|
int? nodeType;
|
||||||
|
Word? word;
|
||||||
|
Rich? rich;
|
||||||
|
|
||||||
|
Nodes.fromJson(Map<String, dynamic> json) {
|
||||||
|
nodeType = json['node_type'];
|
||||||
|
word = json['word'] == null ? null : Word.fromJson(json['word']);
|
||||||
|
rich = json['rich'] == null ? null : Rich.fromJson(json['rich']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Word {
|
||||||
|
String? words;
|
||||||
|
double? fontSize;
|
||||||
|
Style? style;
|
||||||
|
int? color;
|
||||||
|
String? fontLevel;
|
||||||
|
|
||||||
|
Word.fromJson(Map<String, dynamic> json) {
|
||||||
|
words = json['words'];
|
||||||
|
fontSize = (json['font_size'] as num?)?.toDouble();
|
||||||
|
style = json['style'] == null ? null : Style.fromJson(json['style']);
|
||||||
|
color = json['color'] == null
|
||||||
|
? null
|
||||||
|
: int.tryParse('FF${(json['color'] as String).substring(1)}',
|
||||||
|
radix: 16);
|
||||||
|
fontLevel = json['font_level'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Style {
|
||||||
|
Style({
|
||||||
|
this.bold,
|
||||||
|
this.italic,
|
||||||
|
this.strikethrough,
|
||||||
|
});
|
||||||
|
bool? bold;
|
||||||
|
bool? italic;
|
||||||
|
bool? strikethrough;
|
||||||
|
|
||||||
|
Style.fromJson(Map<String, dynamic> json) {
|
||||||
|
bold = json['bold'];
|
||||||
|
italic = json['italic'];
|
||||||
|
strikethrough = json['strikethrough'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Rich {
|
||||||
|
Style? style;
|
||||||
|
String? jumpUrl;
|
||||||
|
String? origText;
|
||||||
|
String? text;
|
||||||
|
|
||||||
|
Rich.fromJson(Map<String, dynamic> json) {
|
||||||
|
style = json['style'] == null ? null : Style.fromJson(json['style']);
|
||||||
|
jumpUrl = json['jump_url'];
|
||||||
|
origText = json['orig_text'];
|
||||||
|
text = json['text'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Ugc {
|
||||||
|
String? cover;
|
||||||
|
String? descSecond;
|
||||||
|
String? duration;
|
||||||
|
String? headText;
|
||||||
|
String? idStr;
|
||||||
|
String? jumpUrl;
|
||||||
|
bool? multiLine;
|
||||||
|
String? title;
|
||||||
|
|
||||||
|
Ugc.fromJson(Map<String, dynamic> json) {
|
||||||
|
cover = json['cover'];
|
||||||
|
descSecond = json['desc_second'];
|
||||||
|
duration = json['duration'];
|
||||||
|
headText = json['head_text'];
|
||||||
|
idStr = json['id_str'];
|
||||||
|
jumpUrl = json['jump_url'];
|
||||||
|
multiLine = json['multi_line'];
|
||||||
|
title = json['title'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Card {
|
||||||
|
String? oid;
|
||||||
|
String? type;
|
||||||
|
Ugc? ugc;
|
||||||
|
|
||||||
|
Card.fromJson(Map<String, dynamic> json) {
|
||||||
|
oid = json['oid'];
|
||||||
|
type = json['type'];
|
||||||
|
ugc = json['ugc'] == null ? null : Ugc.fromJson(json['ugc']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LinkCard {
|
||||||
|
LinkCard({
|
||||||
|
this.card,
|
||||||
|
});
|
||||||
|
Card? card;
|
||||||
|
|
||||||
|
LinkCard.fromJson(Map<String, dynamic> json) {
|
||||||
|
card = json['card'] == null ? null : Card.fromJson(json['card']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class L1st {
|
||||||
|
List<Item>? items;
|
||||||
|
int? style;
|
||||||
|
|
||||||
|
L1st.fromJson(Map<String, dynamic> json) {
|
||||||
|
items = (json['items'] as List?)?.map((e) => Item.fromJson(e)).toList();
|
||||||
|
style = json['style'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Item {
|
||||||
|
int? level;
|
||||||
|
int? order;
|
||||||
|
List<Nodes>? nodes;
|
||||||
|
|
||||||
|
Item.fromJson(Map<String, dynamic> json) {
|
||||||
|
level = json['level'];
|
||||||
|
order = json['order'];
|
||||||
|
nodes = (json['nodes'] as List?)?.map((e) => Nodes.fromJson(e)).toList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Code {
|
||||||
|
String? content;
|
||||||
|
String? lang;
|
||||||
|
|
||||||
|
Code.fromJson(Map<String, dynamic> json) {
|
||||||
|
content = json['content'];
|
||||||
|
lang = json['lang'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// class ArticleContentModel {
|
||||||
|
// ArticleContentModel({
|
||||||
|
// this.attributes,
|
||||||
|
// this.insert,
|
||||||
|
// });
|
||||||
|
// Attributes? attributes;
|
||||||
|
// dynamic insert;
|
||||||
|
|
||||||
|
// ArticleContentModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
// attributes = json['attributes'] == null
|
||||||
|
// ? null
|
||||||
|
// : Attributes.fromJson(json['attributes']);
|
||||||
|
// insert = json['insert'] == null
|
||||||
|
// ? null
|
||||||
|
// : json['attributes']?['class'] == 'normal-img'
|
||||||
|
// ? Insert.fromJson(json['insert'])
|
||||||
|
// : json['insert'];
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// class Insert {
|
||||||
|
// Insert({
|
||||||
|
// this.nativeImage,
|
||||||
|
// });
|
||||||
|
// NativeImage? nativeImage;
|
||||||
|
|
||||||
|
// Insert.fromJson(Map<String, dynamic> json) {
|
||||||
|
// nativeImage = json['native-image'] == null
|
||||||
|
// ? null
|
||||||
|
// : NativeImage.fromJson(json['native-image']);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// class NativeImage {
|
||||||
|
// NativeImage({
|
||||||
|
// this.alt,
|
||||||
|
// this.url,
|
||||||
|
// this.width,
|
||||||
|
// this.height,
|
||||||
|
// this.size,
|
||||||
|
// this.status,
|
||||||
|
// });
|
||||||
|
|
||||||
|
// dynamic alt;
|
||||||
|
// dynamic url;
|
||||||
|
// dynamic width;
|
||||||
|
// dynamic height;
|
||||||
|
// dynamic size;
|
||||||
|
// dynamic status;
|
||||||
|
|
||||||
|
// NativeImage.fromJson(Map<String, dynamic> json) {
|
||||||
|
// alt = json['alt'];
|
||||||
|
// url = json['url'];
|
||||||
|
// width = json['width'];
|
||||||
|
// height = json['height'];
|
||||||
|
// size = json['size'];
|
||||||
|
// status = json['status'];
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// class Attributes {
|
||||||
|
// Attributes({
|
||||||
|
// this.clazz,
|
||||||
|
// this.bold,
|
||||||
|
// this.color,
|
||||||
|
// this.italic,
|
||||||
|
// this.strike,
|
||||||
|
// });
|
||||||
|
// String? clazz;
|
||||||
|
// bool? bold;
|
||||||
|
// String? color;
|
||||||
|
// bool? italic;
|
||||||
|
// bool? strike;
|
||||||
|
|
||||||
|
// Attributes.fromJson(Map<String, dynamic> json) {
|
||||||
|
// clazz = json['class'];
|
||||||
|
// bold = json['bold'];
|
||||||
|
// color = json['color'];
|
||||||
|
// italic = json['italic'];
|
||||||
|
// strike = json['strike'];
|
||||||
|
// }
|
||||||
|
// }
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
import 'data.dart';
|
|
||||||
|
|
||||||
class ArticleView {
|
|
||||||
int? code;
|
|
||||||
String? message;
|
|
||||||
int? ttl;
|
|
||||||
ArticleData? data;
|
|
||||||
|
|
||||||
ArticleView({this.code, this.message, this.ttl, this.data});
|
|
||||||
|
|
||||||
factory ArticleView.fromJson(Map<String, dynamic> json) => ArticleView(
|
|
||||||
code: json['code'] as int?,
|
|
||||||
message: json['message'] as String?,
|
|
||||||
ttl: json['ttl'] as int?,
|
|
||||||
data: json['data'] == null
|
|
||||||
? null
|
|
||||||
: ArticleData.fromJson(json['data'] as Map<String, dynamic>),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'code': code,
|
|
||||||
'message': message,
|
|
||||||
'ttl': ttl,
|
|
||||||
'data': data?.toJson(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
import 'nameplate.dart';
|
|
||||||
import 'official_verify.dart';
|
|
||||||
import 'pendant.dart';
|
|
||||||
import 'vip.dart';
|
|
||||||
|
|
||||||
class Author {
|
|
||||||
int? mid;
|
|
||||||
String? name;
|
|
||||||
String? face;
|
|
||||||
Pendant? pendant;
|
|
||||||
OfficialVerify? officialVerify;
|
|
||||||
Nameplate? nameplate;
|
|
||||||
Vip? vip;
|
|
||||||
int? fans;
|
|
||||||
int? level;
|
|
||||||
|
|
||||||
Author({
|
|
||||||
this.mid,
|
|
||||||
this.name,
|
|
||||||
this.face,
|
|
||||||
this.pendant,
|
|
||||||
this.officialVerify,
|
|
||||||
this.nameplate,
|
|
||||||
this.vip,
|
|
||||||
this.fans,
|
|
||||||
this.level,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory Author.fromJson(Map<String, dynamic> json) => Author(
|
|
||||||
mid: json['mid'] as int?,
|
|
||||||
name: json['name'] as String?,
|
|
||||||
face: json['face'] as String?,
|
|
||||||
pendant: json['pendant'] == null
|
|
||||||
? null
|
|
||||||
: Pendant.fromJson(json['pendant'] as Map<String, dynamic>),
|
|
||||||
officialVerify: json['official_verify'] == null
|
|
||||||
? null
|
|
||||||
: OfficialVerify.fromJson(json['official_verify'] as Map<String, dynamic>),
|
|
||||||
nameplate: json['nameplate'] == null
|
|
||||||
? null
|
|
||||||
: Nameplate.fromJson(json['nameplate'] as Map<String, dynamic>),
|
|
||||||
vip: json['vip'] == null
|
|
||||||
? null
|
|
||||||
: Vip.fromJson(json['vip'] as Map<String, dynamic>),
|
|
||||||
fans: json['fans'] as int?,
|
|
||||||
level: json['level'] as int?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'mid': mid,
|
|
||||||
'name': name,
|
|
||||||
'face': face,
|
|
||||||
'pendant': pendant?.toJson(),
|
|
||||||
'official_verify': officialVerify?.toJson(),
|
|
||||||
'nameplate': nameplate?.toJson(),
|
|
||||||
'vip': vip?.toJson(),
|
|
||||||
'fans': fans,
|
|
||||||
'level': level,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
class Category {
|
|
||||||
int? id;
|
|
||||||
int? parentId;
|
|
||||||
String? name;
|
|
||||||
|
|
||||||
Category({this.id, this.parentId, this.name});
|
|
||||||
|
|
||||||
factory Category.fromJson(Map<String, dynamic> json) => Category(
|
|
||||||
id: json['id'] as int?,
|
|
||||||
parentId: json['parent_id'] as int?,
|
|
||||||
name: json['name'] as String?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'id': id,
|
|
||||||
'parent_id': parentId,
|
|
||||||
'name': name,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,206 +0,0 @@
|
|||||||
import 'package:PiliPlus/models/dynamics/opus_detail/module.dart';
|
|
||||||
import 'package:PiliPlus/models/dynamics/opus_detail/module_content.dart';
|
|
||||||
import 'package:PiliPlus/models/dynamics/opus_detail/paragraph.dart';
|
|
||||||
|
|
||||||
import 'author.dart';
|
|
||||||
import 'category.dart';
|
|
||||||
import 'media.dart';
|
|
||||||
import 'stats.dart';
|
|
||||||
import 'tag.dart';
|
|
||||||
|
|
||||||
class ArticleData {
|
|
||||||
int? id;
|
|
||||||
Category? category;
|
|
||||||
List<Category>? categories;
|
|
||||||
String? title;
|
|
||||||
String? summary;
|
|
||||||
String? bannerUrl;
|
|
||||||
int? templateId;
|
|
||||||
int? state;
|
|
||||||
Author? author;
|
|
||||||
int? reprint;
|
|
||||||
List? imageUrls;
|
|
||||||
int? publishTime;
|
|
||||||
int? ctime;
|
|
||||||
int? mtime;
|
|
||||||
Stats? stats;
|
|
||||||
List<Tag>? tags;
|
|
||||||
int? words;
|
|
||||||
List? originImageUrls;
|
|
||||||
dynamic list;
|
|
||||||
bool? isLike;
|
|
||||||
Media? media;
|
|
||||||
String? applyTime;
|
|
||||||
String? checkTime;
|
|
||||||
int? original;
|
|
||||||
int? actId;
|
|
||||||
dynamic dispute;
|
|
||||||
dynamic authenMark;
|
|
||||||
int? coverAvid;
|
|
||||||
dynamic topVideoInfo;
|
|
||||||
int? type;
|
|
||||||
int? checkState;
|
|
||||||
int? originTemplateId;
|
|
||||||
int? privatePub;
|
|
||||||
dynamic contentPicList;
|
|
||||||
String? content;
|
|
||||||
String? keywords;
|
|
||||||
int? versionId;
|
|
||||||
String? dynIdStr;
|
|
||||||
int? totalArtNum;
|
|
||||||
List<OpusModule>? modules;
|
|
||||||
|
|
||||||
ArticleData({
|
|
||||||
this.id,
|
|
||||||
this.category,
|
|
||||||
this.categories,
|
|
||||||
this.title,
|
|
||||||
this.summary,
|
|
||||||
this.bannerUrl,
|
|
||||||
this.templateId,
|
|
||||||
this.state,
|
|
||||||
this.author,
|
|
||||||
this.reprint,
|
|
||||||
this.imageUrls,
|
|
||||||
this.publishTime,
|
|
||||||
this.ctime,
|
|
||||||
this.mtime,
|
|
||||||
this.stats,
|
|
||||||
this.tags,
|
|
||||||
this.words,
|
|
||||||
this.originImageUrls,
|
|
||||||
this.list,
|
|
||||||
this.isLike,
|
|
||||||
this.media,
|
|
||||||
this.applyTime,
|
|
||||||
this.checkTime,
|
|
||||||
this.original,
|
|
||||||
this.actId,
|
|
||||||
this.dispute,
|
|
||||||
this.authenMark,
|
|
||||||
this.coverAvid,
|
|
||||||
this.topVideoInfo,
|
|
||||||
this.type,
|
|
||||||
this.checkState,
|
|
||||||
this.originTemplateId,
|
|
||||||
this.privatePub,
|
|
||||||
this.contentPicList,
|
|
||||||
this.content,
|
|
||||||
this.keywords,
|
|
||||||
this.versionId,
|
|
||||||
this.dynIdStr,
|
|
||||||
this.totalArtNum,
|
|
||||||
this.modules,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory ArticleData.fromJson(Map<String, dynamic> json) {
|
|
||||||
final data = ArticleData(
|
|
||||||
id: json['id'] as int?,
|
|
||||||
category: json['category'] == null
|
|
||||||
? null
|
|
||||||
: Category.fromJson(json['category'] as Map<String, dynamic>),
|
|
||||||
categories: (json['categories'] as List<dynamic>?)
|
|
||||||
?.map((e) => Category.fromJson(e as Map<String, dynamic>))
|
|
||||||
.toList(),
|
|
||||||
title: json['title'] as String?,
|
|
||||||
summary: json['summary'] as String?,
|
|
||||||
bannerUrl: json['banner_url'] as String?,
|
|
||||||
templateId: json['template_id'] as int?,
|
|
||||||
state: json['state'] as int?,
|
|
||||||
author: json['author'] == null
|
|
||||||
? null
|
|
||||||
: Author.fromJson(json['author'] as Map<String, dynamic>),
|
|
||||||
reprint: json['reprint'] as int?,
|
|
||||||
imageUrls: json['image_urls'],
|
|
||||||
publishTime: json['publish_time'] as int?,
|
|
||||||
ctime: json['ctime'] as int?,
|
|
||||||
mtime: json['mtime'] as int?,
|
|
||||||
stats: json['stats'] == null
|
|
||||||
? null
|
|
||||||
: Stats.fromJson(json['stats'] as Map<String, dynamic>),
|
|
||||||
tags: (json['tags'] as List<dynamic>?)
|
|
||||||
?.map((e) => Tag.fromJson(e as Map<String, dynamic>))
|
|
||||||
.toList(),
|
|
||||||
words: json['words'] as int?,
|
|
||||||
originImageUrls: json['origin_image_urls'],
|
|
||||||
list: json['list'] as dynamic,
|
|
||||||
isLike: json['is_like'] as bool?,
|
|
||||||
media: json['media'] == null
|
|
||||||
? null
|
|
||||||
: Media.fromJson(json['media'] as Map<String, dynamic>),
|
|
||||||
applyTime: json['apply_time'] as String?,
|
|
||||||
checkTime: json['check_time'] as String?,
|
|
||||||
original: json['original'] as int?,
|
|
||||||
actId: json['act_id'] as int?,
|
|
||||||
dispute: json['dispute'] as dynamic,
|
|
||||||
authenMark: json['authenMark'] as dynamic,
|
|
||||||
coverAvid: json['cover_avid'] as int?,
|
|
||||||
topVideoInfo: json['top_video_info'] as dynamic,
|
|
||||||
type: json['type'] as int?,
|
|
||||||
checkState: json['check_state'] as int?,
|
|
||||||
originTemplateId: json['origin_template_id'] as int?,
|
|
||||||
privatePub: json['private_pub'] as int?,
|
|
||||||
contentPicList: json['content_pic_list'] as dynamic,
|
|
||||||
content: json['content'] as String?,
|
|
||||||
keywords: json['keywords'] as String?,
|
|
||||||
versionId: json['version_id'] as int?,
|
|
||||||
dynIdStr: json['dyn_id_str'] as String?,
|
|
||||||
totalArtNum: json['total_art_num'] as int?,
|
|
||||||
);
|
|
||||||
if (data.type == 3 && json['opus'] != null) {
|
|
||||||
data.modules = [
|
|
||||||
OpusModule(
|
|
||||||
moduleType: 'MODULE_TYPE_CONTENT',
|
|
||||||
moduleContent: ModuleContent(
|
|
||||||
paragraphs: (json['opus']?['content']?['paragraphs'] as List?)
|
|
||||||
?.map((e) => Paragraph.fromJson(e))
|
|
||||||
.toList(),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
];
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'id': id,
|
|
||||||
'category': category?.toJson(),
|
|
||||||
'categories': categories?.map((e) => e.toJson()).toList(),
|
|
||||||
'title': title,
|
|
||||||
'summary': summary,
|
|
||||||
'banner_url': bannerUrl,
|
|
||||||
'template_id': templateId,
|
|
||||||
'state': state,
|
|
||||||
'author': author?.toJson(),
|
|
||||||
'reprint': reprint,
|
|
||||||
'image_urls': imageUrls,
|
|
||||||
'publish_time': publishTime,
|
|
||||||
'ctime': ctime,
|
|
||||||
'mtime': mtime,
|
|
||||||
'stats': stats?.toJson(),
|
|
||||||
'tags': tags?.map((e) => e.toJson()).toList(),
|
|
||||||
'words': words,
|
|
||||||
'origin_image_urls': originImageUrls,
|
|
||||||
'list': list,
|
|
||||||
'is_like': isLike,
|
|
||||||
'media': media?.toJson(),
|
|
||||||
'apply_time': applyTime,
|
|
||||||
'check_time': checkTime,
|
|
||||||
'original': original,
|
|
||||||
'act_id': actId,
|
|
||||||
'dispute': dispute,
|
|
||||||
'authenMark': authenMark,
|
|
||||||
'cover_avid': coverAvid,
|
|
||||||
'top_video_info': topVideoInfo,
|
|
||||||
'type': type,
|
|
||||||
'check_state': checkState,
|
|
||||||
'origin_template_id': originTemplateId,
|
|
||||||
'private_pub': privatePub,
|
|
||||||
'content_pic_list': contentPicList,
|
|
||||||
'content': content,
|
|
||||||
'keywords': keywords,
|
|
||||||
'version_id': versionId,
|
|
||||||
'dyn_id_str': dynIdStr,
|
|
||||||
'total_art_num': totalArtNum,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
class Label {
|
|
||||||
String? path;
|
|
||||||
String? text;
|
|
||||||
String? labelTheme;
|
|
||||||
|
|
||||||
Label({this.path, this.text, this.labelTheme});
|
|
||||||
|
|
||||||
factory Label.fromJson(Map<String, dynamic> json) => Label(
|
|
||||||
path: json['path'] as String?,
|
|
||||||
text: json['text'] as String?,
|
|
||||||
labelTheme: json['label_theme'] as String?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'path': path,
|
|
||||||
'text': text,
|
|
||||||
'label_theme': labelTheme,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
class Media {
|
|
||||||
int? score;
|
|
||||||
int? mediaId;
|
|
||||||
String? title;
|
|
||||||
String? cover;
|
|
||||||
String? area;
|
|
||||||
int? typeId;
|
|
||||||
String? typeName;
|
|
||||||
int? spoiler;
|
|
||||||
int? seasonId;
|
|
||||||
|
|
||||||
Media({
|
|
||||||
this.score,
|
|
||||||
this.mediaId,
|
|
||||||
this.title,
|
|
||||||
this.cover,
|
|
||||||
this.area,
|
|
||||||
this.typeId,
|
|
||||||
this.typeName,
|
|
||||||
this.spoiler,
|
|
||||||
this.seasonId,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory Media.fromJson(Map<String, dynamic> json) => Media(
|
|
||||||
score: json['score'] as int?,
|
|
||||||
mediaId: json['media_id'] as int?,
|
|
||||||
title: json['title'] as String?,
|
|
||||||
cover: json['cover'] as String?,
|
|
||||||
area: json['area'] as String?,
|
|
||||||
typeId: json['type_id'] as int?,
|
|
||||||
typeName: json['type_name'] as String?,
|
|
||||||
spoiler: json['spoiler'] as int?,
|
|
||||||
seasonId: json['season_id'] as int?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'score': score,
|
|
||||||
'media_id': mediaId,
|
|
||||||
'title': title,
|
|
||||||
'cover': cover,
|
|
||||||
'area': area,
|
|
||||||
'type_id': typeId,
|
|
||||||
'type_name': typeName,
|
|
||||||
'spoiler': spoiler,
|
|
||||||
'season_id': seasonId,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
class Nameplate {
|
|
||||||
int? nid;
|
|
||||||
String? name;
|
|
||||||
String? image;
|
|
||||||
String? imageSmall;
|
|
||||||
String? level;
|
|
||||||
String? condition;
|
|
||||||
|
|
||||||
Nameplate({
|
|
||||||
this.nid,
|
|
||||||
this.name,
|
|
||||||
this.image,
|
|
||||||
this.imageSmall,
|
|
||||||
this.level,
|
|
||||||
this.condition,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory Nameplate.fromJson(Map<String, dynamic> json) => Nameplate(
|
|
||||||
nid: json['nid'] as int?,
|
|
||||||
name: json['name'] as String?,
|
|
||||||
image: json['image'] as String?,
|
|
||||||
imageSmall: json['image_small'] as String?,
|
|
||||||
level: json['level'] as String?,
|
|
||||||
condition: json['condition'] as String?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'nid': nid,
|
|
||||||
'name': name,
|
|
||||||
'image': image,
|
|
||||||
'image_small': imageSmall,
|
|
||||||
'level': level,
|
|
||||||
'condition': condition,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
class OfficialVerify {
|
|
||||||
int? type;
|
|
||||||
String? desc;
|
|
||||||
|
|
||||||
OfficialVerify({this.type, this.desc});
|
|
||||||
|
|
||||||
factory OfficialVerify.fromJson(Map<String, dynamic> json) {
|
|
||||||
return OfficialVerify(
|
|
||||||
type: json['type'] as int?,
|
|
||||||
desc: json['desc'] as String?,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'type': type,
|
|
||||||
'desc': desc,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
class Pendant {
|
|
||||||
int? pid;
|
|
||||||
String? name;
|
|
||||||
String? image;
|
|
||||||
int? expire;
|
|
||||||
|
|
||||||
Pendant({this.pid, this.name, this.image, this.expire});
|
|
||||||
|
|
||||||
factory Pendant.fromJson(Map<String, dynamic> json) => Pendant(
|
|
||||||
pid: json['pid'] as int?,
|
|
||||||
name: json['name'] as String?,
|
|
||||||
image: json['image'] as String?,
|
|
||||||
expire: json['expire'] as int?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'pid': pid,
|
|
||||||
'name': name,
|
|
||||||
'image': image,
|
|
||||||
'expire': expire,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
class Stats {
|
|
||||||
int? view;
|
|
||||||
int? favorite;
|
|
||||||
int? like;
|
|
||||||
int? dislike;
|
|
||||||
int? reply;
|
|
||||||
int? share;
|
|
||||||
int? coin;
|
|
||||||
int? dynam1c;
|
|
||||||
|
|
||||||
Stats({
|
|
||||||
this.view,
|
|
||||||
this.favorite,
|
|
||||||
this.like,
|
|
||||||
this.dislike,
|
|
||||||
this.reply,
|
|
||||||
this.share,
|
|
||||||
this.coin,
|
|
||||||
this.dynam1c,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory Stats.fromJson(Map<String, dynamic> json) => Stats(
|
|
||||||
view: json['view'] as int?,
|
|
||||||
favorite: json['favorite'] as int?,
|
|
||||||
like: json['like'] as int?,
|
|
||||||
dislike: json['dislike'] as int?,
|
|
||||||
reply: json['reply'] as int?,
|
|
||||||
share: json['share'] as int?,
|
|
||||||
coin: json['coin'] as int?,
|
|
||||||
dynam1c: json['dynamic'] as int?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'view': view,
|
|
||||||
'favorite': favorite,
|
|
||||||
'like': like,
|
|
||||||
'dislike': dislike,
|
|
||||||
'reply': reply,
|
|
||||||
'share': share,
|
|
||||||
'coin': coin,
|
|
||||||
'dynamic': dynam1c,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
class Tag {
|
|
||||||
int? tid;
|
|
||||||
String? name;
|
|
||||||
|
|
||||||
Tag({this.tid, this.name});
|
|
||||||
|
|
||||||
factory Tag.fromJson(Map<String, dynamic> json) => Tag(
|
|
||||||
tid: json['tid'] as int?,
|
|
||||||
name: json['name'] as String?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'tid': tid,
|
|
||||||
'name': name,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
import 'label.dart';
|
|
||||||
|
|
||||||
class Vip {
|
|
||||||
int? type;
|
|
||||||
int? status;
|
|
||||||
int? dueDate;
|
|
||||||
int? vipPayType;
|
|
||||||
int? themeType;
|
|
||||||
Label? label;
|
|
||||||
int? avatarSubscript;
|
|
||||||
String? nicknameColor;
|
|
||||||
|
|
||||||
Vip({
|
|
||||||
this.type,
|
|
||||||
this.status,
|
|
||||||
this.dueDate,
|
|
||||||
this.vipPayType,
|
|
||||||
this.themeType,
|
|
||||||
this.label,
|
|
||||||
this.avatarSubscript,
|
|
||||||
this.nicknameColor,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory Vip.fromJson(Map<String, dynamic> json) => Vip(
|
|
||||||
type: json['type'] as int?,
|
|
||||||
status: json['status'] as int?,
|
|
||||||
dueDate: json['due_date'] as int?,
|
|
||||||
vipPayType: json['vip_pay_type'] as int?,
|
|
||||||
themeType: json['theme_type'] as int?,
|
|
||||||
label: json['label'] == null
|
|
||||||
? null
|
|
||||||
: Label.fromJson(json['label'] as Map<String, dynamic>),
|
|
||||||
avatarSubscript: json['avatar_subscript'] as int?,
|
|
||||||
nicknameColor: json['nickname_color'] as String?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'type': type,
|
|
||||||
'status': status,
|
|
||||||
'due_date': dueDate,
|
|
||||||
'vip_pay_type': vipPayType,
|
|
||||||
'theme_type': themeType,
|
|
||||||
'label': label?.toJson(),
|
|
||||||
'avatar_subscript': avatarSubscript,
|
|
||||||
'nickname_color': nicknameColor,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
import 'container_size.dart';
|
|
||||||
import 'fallback_layers.dart';
|
|
||||||
|
|
||||||
class Avatar {
|
|
||||||
ContainerSize? containerSize;
|
|
||||||
FallbackLayers? fallbackLayers;
|
|
||||||
String? mid;
|
|
||||||
|
|
||||||
Avatar({this.containerSize, this.fallbackLayers, this.mid});
|
|
||||||
|
|
||||||
factory Avatar.fromJson(Map<String, dynamic> json) => Avatar(
|
|
||||||
containerSize: json['container_size'] == null
|
|
||||||
? null
|
|
||||||
: ContainerSize.fromJson(json['container_size'] as Map<String, dynamic>),
|
|
||||||
fallbackLayers: json['fallback_layers'] == null
|
|
||||||
? null
|
|
||||||
: FallbackLayers.fromJson(json['fallback_layers'] as Map<String, dynamic>),
|
|
||||||
mid: json['mid'] as String?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'container_size': containerSize?.toJson(),
|
|
||||||
'fallback_layers': fallbackLayers?.toJson(),
|
|
||||||
'mid': mid,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import 'icon_resource.dart';
|
|
||||||
|
|
||||||
class AvatarIcon {
|
|
||||||
IconResource? iconResource;
|
|
||||||
|
|
||||||
AvatarIcon({this.iconResource});
|
|
||||||
|
|
||||||
factory AvatarIcon.fromJson(Map<String, dynamic> json) => AvatarIcon(
|
|
||||||
iconResource: json['icon_resource'] == null
|
|
||||||
? null
|
|
||||||
: IconResource.fromJson(json['icon_resource'] as Map<String, dynamic>),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'icon_resource': iconResource?.toJson(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
|
|
||||||
class AvatarLayer {
|
|
||||||
AvatarLayer();
|
|
||||||
|
|
||||||
factory AvatarLayer.fromJson(Map<String, dynamic> json) {
|
|
||||||
// TODO: implement fromJson
|
|
||||||
throw UnimplementedError('AvatarLayer.fromJson($json) is not implemented');
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
|
||||||
// TODO: implement toJson
|
|
||||||
throw UnimplementedError();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
import 'like_icon.dart';
|
|
||||||
|
|
||||||
class Basic {
|
|
||||||
String? commentIdStr;
|
|
||||||
int? commentType;
|
|
||||||
LikeIcon? likeIcon;
|
|
||||||
String? ridStr;
|
|
||||||
String? title;
|
|
||||||
int? uid;
|
|
||||||
|
|
||||||
Basic({
|
|
||||||
this.commentIdStr,
|
|
||||||
this.commentType,
|
|
||||||
this.likeIcon,
|
|
||||||
this.ridStr,
|
|
||||||
this.title,
|
|
||||||
this.uid,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory Basic.fromJson(Map<String, dynamic> json) => Basic(
|
|
||||||
commentIdStr: json['comment_id_str'] as String?,
|
|
||||||
commentType: json['comment_type'] as int?,
|
|
||||||
likeIcon: json['like_icon'] == null
|
|
||||||
? null
|
|
||||||
: LikeIcon.fromJson(json['like_icon'] as Map<String, dynamic>),
|
|
||||||
ridStr: json['rid_str'] as String?,
|
|
||||||
title: json['title'] as String?,
|
|
||||||
uid: json['uid'] as int?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'comment_id_str': commentIdStr,
|
|
||||||
'comment_type': commentType,
|
|
||||||
'like_icon': likeIcon?.toJson(),
|
|
||||||
'rid_str': ridStr,
|
|
||||||
'title': title,
|
|
||||||
'uid': uid,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
class Coin {
|
|
||||||
int? count;
|
|
||||||
bool? forbidden;
|
|
||||||
bool? status;
|
|
||||||
|
|
||||||
Coin({this.count, this.forbidden, this.status});
|
|
||||||
|
|
||||||
factory Coin.fromJson(Map<String, dynamic> json) => Coin(
|
|
||||||
count: json['count'] as int?,
|
|
||||||
forbidden: json['forbidden'] as bool?,
|
|
||||||
status: json['status'] as bool?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'count': count,
|
|
||||||
'forbidden': forbidden,
|
|
||||||
'status': status,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
class Comment {
|
|
||||||
int? count;
|
|
||||||
bool? forbidden;
|
|
||||||
|
|
||||||
Comment({this.count, this.forbidden});
|
|
||||||
|
|
||||||
factory Comment.fromJson(Map<String, dynamic> json) => Comment(
|
|
||||||
count: json['count'] as int?,
|
|
||||||
forbidden: json['forbidden'] as bool?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'count': count,
|
|
||||||
'forbidden': forbidden,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
class ContainerSize {
|
|
||||||
double? height;
|
|
||||||
double? width;
|
|
||||||
|
|
||||||
ContainerSize({this.height, this.width});
|
|
||||||
|
|
||||||
factory ContainerSize.fromJson(Map<String, dynamic> json) => ContainerSize(
|
|
||||||
height: (json['height'] as num?)?.toDouble(),
|
|
||||||
width: (json['width'] as num?)?.toDouble(),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'height': height,
|
|
||||||
'width': width,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
import 'fallback.dart';
|
|
||||||
import 'item.dart';
|
|
||||||
|
|
||||||
class OpusData {
|
|
||||||
Item? item;
|
|
||||||
Fallback? fallback;
|
|
||||||
|
|
||||||
OpusData({
|
|
||||||
this.item,
|
|
||||||
this.fallback,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory OpusData.fromJson(Map<String, dynamic> json) => OpusData(
|
|
||||||
item: json['item'] == null
|
|
||||||
? null
|
|
||||||
: Item.fromJson(json['item'] as Map<String, dynamic>),
|
|
||||||
fallback: json['fallback'] == null
|
|
||||||
? null
|
|
||||||
: Fallback.fromJson(json['fallback']),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'item': item?.toJson(),
|
|
||||||
'fallback': fallback?.toJson(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
class Fallback {
|
|
||||||
String? id;
|
|
||||||
int? type;
|
|
||||||
|
|
||||||
Fallback({
|
|
||||||
this.id,
|
|
||||||
this.type,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory Fallback.fromJson(Map<String, dynamic> json) => Fallback(
|
|
||||||
id: json['id'],
|
|
||||||
type: json['type'],
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'id': id,
|
|
||||||
'type': type,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
import 'layer.dart';
|
|
||||||
|
|
||||||
class FallbackLayers {
|
|
||||||
bool? isCriticalGroup;
|
|
||||||
List<Layer>? layers;
|
|
||||||
|
|
||||||
FallbackLayers({this.isCriticalGroup, this.layers});
|
|
||||||
|
|
||||||
factory FallbackLayers.fromJson(Map<String, dynamic> json) {
|
|
||||||
return FallbackLayers(
|
|
||||||
isCriticalGroup: json['is_critical_group'] as bool?,
|
|
||||||
layers: (json['layers'] as List<dynamic>?)
|
|
||||||
?.map((e) => Layer.fromJson(e as Map<String, dynamic>))
|
|
||||||
.toList(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'is_critical_group': isCriticalGroup,
|
|
||||||
'layers': layers?.map((e) => e.toJson()).toList(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
class Favorite {
|
|
||||||
int? count;
|
|
||||||
bool? forbidden;
|
|
||||||
bool? status;
|
|
||||||
|
|
||||||
Favorite({this.count, this.forbidden, this.status});
|
|
||||||
|
|
||||||
factory Favorite.fromJson(Map<String, dynamic> json) => Favorite(
|
|
||||||
count: json['count'] as int?,
|
|
||||||
forbidden: json['forbidden'] as bool?,
|
|
||||||
status: json['status'] as bool?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'count': count,
|
|
||||||
'forbidden': forbidden,
|
|
||||||
'status': status,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
class Forward {
|
|
||||||
int? count;
|
|
||||||
bool? forbidden;
|
|
||||||
|
|
||||||
Forward({this.count, this.forbidden});
|
|
||||||
|
|
||||||
factory Forward.fromJson(Map<String, dynamic> json) => Forward(
|
|
||||||
count: json['count'] as int?,
|
|
||||||
forbidden: json['forbidden'] as bool?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'count': count,
|
|
||||||
'forbidden': forbidden,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
import 'general_config.dart';
|
|
||||||
|
|
||||||
class GeneralCfg {
|
|
||||||
int? configType;
|
|
||||||
GeneralConfig? generalConfig;
|
|
||||||
|
|
||||||
GeneralCfg({this.configType, this.generalConfig});
|
|
||||||
|
|
||||||
factory GeneralCfg.fromJson(Map<String, dynamic> json) => GeneralCfg(
|
|
||||||
configType: json['config_type'] as int?,
|
|
||||||
generalConfig: json['general_config'] == null
|
|
||||||
? null
|
|
||||||
: GeneralConfig.fromJson(json['general_config'] as Map<String, dynamic>),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'config_type': configType,
|
|
||||||
'general_config': generalConfig?.toJson(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import 'web_css_style.dart';
|
|
||||||
|
|
||||||
class GeneralConfig {
|
|
||||||
WebCssStyle? webCssStyle;
|
|
||||||
|
|
||||||
GeneralConfig({this.webCssStyle});
|
|
||||||
|
|
||||||
factory GeneralConfig.fromJson(Map<String, dynamic> json) => GeneralConfig(
|
|
||||||
webCssStyle: json['web_css_style'] == null
|
|
||||||
? null
|
|
||||||
: WebCssStyle.fromJson(json['web_css_style'] as Map<String, dynamic>),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'web_css_style': webCssStyle?.toJson(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
import 'pos_spec.dart';
|
|
||||||
import 'render_spec.dart';
|
|
||||||
import 'size_spec.dart';
|
|
||||||
|
|
||||||
class GeneralSpec {
|
|
||||||
PosSpec? posSpec;
|
|
||||||
RenderSpec? renderSpec;
|
|
||||||
SizeSpec? sizeSpec;
|
|
||||||
|
|
||||||
GeneralSpec({this.posSpec, this.renderSpec, this.sizeSpec});
|
|
||||||
|
|
||||||
factory GeneralSpec.fromJson(Map<String, dynamic> json) => GeneralSpec(
|
|
||||||
posSpec: json['pos_spec'] == null
|
|
||||||
? null
|
|
||||||
: PosSpec.fromJson(json['pos_spec'] as Map<String, dynamic>),
|
|
||||||
renderSpec: json['render_spec'] == null
|
|
||||||
? null
|
|
||||||
: RenderSpec.fromJson(json['render_spec'] as Map<String, dynamic>),
|
|
||||||
sizeSpec: json['size_spec'] == null
|
|
||||||
? null
|
|
||||||
: SizeSpec.fromJson(json['size_spec'] as Map<String, dynamic>),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'pos_spec': posSpec?.toJson(),
|
|
||||||
'render_spec': renderSpec?.toJson(),
|
|
||||||
'size_spec': sizeSpec?.toJson(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
|
|
||||||
class IconResource {
|
|
||||||
IconResource();
|
|
||||||
|
|
||||||
factory IconResource.fromJson(Map<String, dynamic> json) {
|
|
||||||
// TODO: implement fromJson
|
|
||||||
throw UnimplementedError('IconResource.fromJson($json) is not implemented');
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
|
||||||
// TODO: implement toJson
|
|
||||||
throw UnimplementedError();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import 'remote.dart';
|
|
||||||
|
|
||||||
class ImageSrc {
|
|
||||||
int? placeholder;
|
|
||||||
Remote? remote;
|
|
||||||
int? srcType;
|
|
||||||
|
|
||||||
ImageSrc({this.placeholder, this.remote, this.srcType});
|
|
||||||
|
|
||||||
factory ImageSrc.fromJson(Map<String, dynamic> json) => ImageSrc(
|
|
||||||
placeholder: json['placeholder'] as int?,
|
|
||||||
remote: json['remote'] == null
|
|
||||||
? null
|
|
||||||
: Remote.fromJson(json['remote'] as Map<String, dynamic>),
|
|
||||||
srcType: json['src_type'] as int?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'placeholder': placeholder,
|
|
||||||
'remote': remote?.toJson(),
|
|
||||||
'src_type': srcType,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
import 'basic.dart';
|
|
||||||
import 'module.dart';
|
|
||||||
|
|
||||||
class Item {
|
|
||||||
Basic? basic;
|
|
||||||
String? idStr;
|
|
||||||
List<OpusModule>? modules;
|
|
||||||
int? type;
|
|
||||||
|
|
||||||
Item({this.basic, this.idStr, this.modules, this.type});
|
|
||||||
|
|
||||||
factory Item.fromJson(Map<String, dynamic> json) => Item(
|
|
||||||
basic: json['basic'] == null
|
|
||||||
? null
|
|
||||||
: Basic.fromJson(json['basic'] as Map<String, dynamic>),
|
|
||||||
idStr: json['id_str'] as String?,
|
|
||||||
modules: (json['modules'] as List<dynamic>?)
|
|
||||||
?.map((e) => OpusModule.fromJson(e as Map<String, dynamic>))
|
|
||||||
.toList(),
|
|
||||||
type: json['type'] as int?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'basic': basic?.toJson(),
|
|
||||||
'id_str': idStr,
|
|
||||||
'modules': modules?.map((e) => e.toJson()).toList(),
|
|
||||||
'type': type,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
class Label {
|
|
||||||
String? bgColor;
|
|
||||||
int? bgStyle;
|
|
||||||
String? borderColor;
|
|
||||||
String? imgLabelUriHans;
|
|
||||||
String? imgLabelUriHansStatic;
|
|
||||||
String? imgLabelUriHant;
|
|
||||||
String? imgLabelUriHantStatic;
|
|
||||||
String? labelTheme;
|
|
||||||
String? path;
|
|
||||||
String? text;
|
|
||||||
String? textColor;
|
|
||||||
bool? useImgLabel;
|
|
||||||
|
|
||||||
Label({
|
|
||||||
this.bgColor,
|
|
||||||
this.bgStyle,
|
|
||||||
this.borderColor,
|
|
||||||
this.imgLabelUriHans,
|
|
||||||
this.imgLabelUriHansStatic,
|
|
||||||
this.imgLabelUriHant,
|
|
||||||
this.imgLabelUriHantStatic,
|
|
||||||
this.labelTheme,
|
|
||||||
this.path,
|
|
||||||
this.text,
|
|
||||||
this.textColor,
|
|
||||||
this.useImgLabel,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory Label.fromJson(Map<String, dynamic> json) => Label(
|
|
||||||
bgColor: json['bg_color'] as String?,
|
|
||||||
bgStyle: json['bg_style'] as int?,
|
|
||||||
borderColor: json['border_color'] as String?,
|
|
||||||
imgLabelUriHans: json['img_label_uri_hans'] as String?,
|
|
||||||
imgLabelUriHansStatic: json['img_label_uri_hans_static'] as String?,
|
|
||||||
imgLabelUriHant: json['img_label_uri_hant'] as String?,
|
|
||||||
imgLabelUriHantStatic: json['img_label_uri_hant_static'] as String?,
|
|
||||||
labelTheme: json['label_theme'] as String?,
|
|
||||||
path: json['path'] as String?,
|
|
||||||
text: json['text'] as String?,
|
|
||||||
textColor: json['text_color'] as String?,
|
|
||||||
useImgLabel: json['use_img_label'] as bool?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'bg_color': bgColor,
|
|
||||||
'bg_style': bgStyle,
|
|
||||||
'border_color': borderColor,
|
|
||||||
'img_label_uri_hans': imgLabelUriHans,
|
|
||||||
'img_label_uri_hans_static': imgLabelUriHansStatic,
|
|
||||||
'img_label_uri_hant': imgLabelUriHant,
|
|
||||||
'img_label_uri_hant_static': imgLabelUriHantStatic,
|
|
||||||
'label_theme': labelTheme,
|
|
||||||
'path': path,
|
|
||||||
'text': text,
|
|
||||||
'text_color': textColor,
|
|
||||||
'use_img_label': useImgLabel,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
import 'general_spec.dart';
|
|
||||||
import 'layer_config.dart';
|
|
||||||
import 'resource.dart';
|
|
||||||
|
|
||||||
class Layer {
|
|
||||||
GeneralSpec? generalSpec;
|
|
||||||
LayerConfig? layerConfig;
|
|
||||||
Resource? resource;
|
|
||||||
bool? visible;
|
|
||||||
|
|
||||||
Layer({this.generalSpec, this.layerConfig, this.resource, this.visible});
|
|
||||||
|
|
||||||
factory Layer.fromJson(Map<String, dynamic> json) => Layer(
|
|
||||||
generalSpec: json['general_spec'] == null
|
|
||||||
? null
|
|
||||||
: GeneralSpec.fromJson(json['general_spec'] as Map<String, dynamic>),
|
|
||||||
layerConfig: json['layer_config'] == null
|
|
||||||
? null
|
|
||||||
: LayerConfig.fromJson(json['layer_config'] as Map<String, dynamic>),
|
|
||||||
resource: json['resource'] == null
|
|
||||||
? null
|
|
||||||
: Resource.fromJson(json['resource'] as Map<String, dynamic>),
|
|
||||||
visible: json['visible'] as bool?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'general_spec': generalSpec?.toJson(),
|
|
||||||
'layer_config': layerConfig?.toJson(),
|
|
||||||
'resource': resource?.toJson(),
|
|
||||||
'visible': visible,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
import 'tags.dart';
|
|
||||||
|
|
||||||
class LayerConfig {
|
|
||||||
bool? isCritical;
|
|
||||||
Tags? tags;
|
|
||||||
|
|
||||||
LayerConfig({this.isCritical, this.tags});
|
|
||||||
|
|
||||||
factory LayerConfig.fromJson(Map<String, dynamic> json) => LayerConfig(
|
|
||||||
isCritical: json['is_critical'] as bool?,
|
|
||||||
tags: json['tags'] == null
|
|
||||||
? null
|
|
||||||
: Tags.fromJson(json['tags'] as Map<String, dynamic>),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'is_critical': isCritical,
|
|
||||||
'tags': tags?.toJson(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
class Like {
|
|
||||||
int? count;
|
|
||||||
bool? forbidden;
|
|
||||||
bool? status;
|
|
||||||
|
|
||||||
Like({this.count, this.forbidden, this.status});
|
|
||||||
|
|
||||||
factory Like.fromJson(Map<String, dynamic> json) => Like(
|
|
||||||
count: json['count'] as int?,
|
|
||||||
forbidden: json['forbidden'] as bool?,
|
|
||||||
status: json['status'] as bool?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'count': count,
|
|
||||||
'forbidden': forbidden,
|
|
||||||
'status': status,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
class LikeIcon {
|
|
||||||
String? actionUrl;
|
|
||||||
String? endUrl;
|
|
||||||
int? id;
|
|
||||||
String? startUrl;
|
|
||||||
|
|
||||||
LikeIcon({this.actionUrl, this.endUrl, this.id, this.startUrl});
|
|
||||||
|
|
||||||
factory LikeIcon.fromJson(Map<String, dynamic> json) => LikeIcon(
|
|
||||||
actionUrl: json['action_url'] as String?,
|
|
||||||
endUrl: json['end_url'] as String?,
|
|
||||||
id: json['id'] as int?,
|
|
||||||
startUrl: json['start_url'] as String?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'action_url': actionUrl,
|
|
||||||
'end_url': endUrl,
|
|
||||||
'id': id,
|
|
||||||
'start_url': startUrl,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
import 'module_author.dart';
|
|
||||||
import 'module_bottom.dart';
|
|
||||||
import 'module_content.dart';
|
|
||||||
import 'module_extend.dart';
|
|
||||||
import 'module_stat.dart';
|
|
||||||
import 'module_title.dart';
|
|
||||||
|
|
||||||
class OpusModule {
|
|
||||||
ModuleTitle? moduleTitle;
|
|
||||||
String? moduleType;
|
|
||||||
ModuleAuthor? moduleAuthor;
|
|
||||||
ModuleContent? moduleContent;
|
|
||||||
ModuleExtend? moduleExtend;
|
|
||||||
ModuleBottom? moduleBottom;
|
|
||||||
ModuleStat? moduleStat;
|
|
||||||
|
|
||||||
OpusModule({
|
|
||||||
this.moduleTitle,
|
|
||||||
this.moduleType,
|
|
||||||
this.moduleAuthor,
|
|
||||||
this.moduleContent,
|
|
||||||
this.moduleExtend,
|
|
||||||
this.moduleBottom,
|
|
||||||
this.moduleStat,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory OpusModule.fromJson(Map<String, dynamic> json) => OpusModule(
|
|
||||||
moduleTitle: json['module_title'] == null
|
|
||||||
? null
|
|
||||||
: ModuleTitle.fromJson(
|
|
||||||
json['module_title'] as Map<String, dynamic>),
|
|
||||||
moduleType: json['module_type'] as String?,
|
|
||||||
moduleAuthor: json['module_author'] == null
|
|
||||||
? null
|
|
||||||
: ModuleAuthor.fromJson(
|
|
||||||
json['module_author'] as Map<String, dynamic>),
|
|
||||||
moduleContent: json['module_content'] == null
|
|
||||||
? null
|
|
||||||
: ModuleContent.fromJson(
|
|
||||||
json['module_content'] as Map<String, dynamic>),
|
|
||||||
moduleExtend: json['module_extend'] == null
|
|
||||||
? null
|
|
||||||
: ModuleExtend.fromJson(
|
|
||||||
json['module_extend'] as Map<String, dynamic>),
|
|
||||||
moduleBottom: json['module_bottom'] == null
|
|
||||||
? null
|
|
||||||
: ModuleBottom.fromJson(
|
|
||||||
json['module_bottom'] as Map<String, dynamic>),
|
|
||||||
moduleStat: json['module_stat'] == null
|
|
||||||
? null
|
|
||||||
: ModuleStat.fromJson(json['module_stat'] as Map<String, dynamic>),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'module_title': moduleTitle?.toJson(),
|
|
||||||
'module_type': moduleType,
|
|
||||||
'module_author': moduleAuthor?.toJson(),
|
|
||||||
'module_content': moduleContent?.toJson(),
|
|
||||||
'module_extend': moduleExtend?.toJson(),
|
|
||||||
'module_bottom': moduleBottom?.toJson(),
|
|
||||||
'module_stat': moduleStat?.toJson(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
import 'avatar.dart';
|
|
||||||
import 'official.dart';
|
|
||||||
import 'pendant.dart';
|
|
||||||
import 'vip.dart';
|
|
||||||
|
|
||||||
class ModuleAuthor {
|
|
||||||
Avatar? avatar;
|
|
||||||
String? face;
|
|
||||||
bool? faceNft;
|
|
||||||
dynamic following;
|
|
||||||
String? jumpUrl;
|
|
||||||
String? label;
|
|
||||||
int? mid;
|
|
||||||
String? name;
|
|
||||||
Official? official;
|
|
||||||
Pendant? pendant;
|
|
||||||
String? pubLocationText;
|
|
||||||
String? pubTime;
|
|
||||||
int? pubTs;
|
|
||||||
String? viewsText;
|
|
||||||
Vip? vip;
|
|
||||||
|
|
||||||
ModuleAuthor({
|
|
||||||
this.avatar,
|
|
||||||
this.face,
|
|
||||||
this.faceNft,
|
|
||||||
this.following,
|
|
||||||
this.jumpUrl,
|
|
||||||
this.label,
|
|
||||||
this.mid,
|
|
||||||
this.name,
|
|
||||||
this.official,
|
|
||||||
this.pendant,
|
|
||||||
this.pubLocationText,
|
|
||||||
this.pubTime,
|
|
||||||
this.pubTs,
|
|
||||||
this.viewsText,
|
|
||||||
this.vip,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory ModuleAuthor.fromJson(Map<String, dynamic> json) => ModuleAuthor(
|
|
||||||
avatar: json['avatar'] == null
|
|
||||||
? null
|
|
||||||
: Avatar.fromJson(json['avatar'] as Map<String, dynamic>),
|
|
||||||
face: json['face'] as String?,
|
|
||||||
faceNft: json['face_nft'] as bool?,
|
|
||||||
following: json['following'] as dynamic,
|
|
||||||
jumpUrl: json['jump_url'] as String?,
|
|
||||||
label: json['label'] as String?,
|
|
||||||
mid: json['mid'] as int?,
|
|
||||||
name: json['name'] as String?,
|
|
||||||
official: json['official'] == null
|
|
||||||
? null
|
|
||||||
: Official.fromJson(json['official'] as Map<String, dynamic>),
|
|
||||||
pendant: json['pendant'] == null
|
|
||||||
? null
|
|
||||||
: Pendant.fromJson(json['pendant'] as Map<String, dynamic>),
|
|
||||||
pubLocationText: json['pub_location_text'] as String?,
|
|
||||||
pubTime: json['pub_time'] as String?,
|
|
||||||
pubTs: json['pub_ts'] as int?,
|
|
||||||
viewsText: json['views_text'] as String?,
|
|
||||||
vip: json['vip'] == null
|
|
||||||
? null
|
|
||||||
: Vip.fromJson(json['vip'] as Map<String, dynamic>),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'avatar': avatar?.toJson(),
|
|
||||||
'face': face,
|
|
||||||
'face_nft': faceNft,
|
|
||||||
'following': following,
|
|
||||||
'jump_url': jumpUrl,
|
|
||||||
'label': label,
|
|
||||||
'mid': mid,
|
|
||||||
'name': name,
|
|
||||||
'official': official?.toJson(),
|
|
||||||
'pendant': pendant?.toJson(),
|
|
||||||
'pub_location_text': pubLocationText,
|
|
||||||
'pub_time': pubTime,
|
|
||||||
'pub_ts': pubTs,
|
|
||||||
'views_text': viewsText,
|
|
||||||
'vip': vip?.toJson(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import 'share_info.dart';
|
|
||||||
|
|
||||||
class ModuleBottom {
|
|
||||||
ShareInfo? shareInfo;
|
|
||||||
|
|
||||||
ModuleBottom({this.shareInfo});
|
|
||||||
|
|
||||||
factory ModuleBottom.fromJson(Map<String, dynamic> json) => ModuleBottom(
|
|
||||||
shareInfo: json['share_info'] == null
|
|
||||||
? null
|
|
||||||
: ShareInfo.fromJson(json['share_info'] as Map<String, dynamic>),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'share_info': shareInfo?.toJson(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import 'paragraph.dart';
|
|
||||||
|
|
||||||
class ModuleContent {
|
|
||||||
List<Paragraph>? paragraphs;
|
|
||||||
|
|
||||||
ModuleContent({this.paragraphs});
|
|
||||||
|
|
||||||
factory ModuleContent.fromJson(Map<String, dynamic> json) => ModuleContent(
|
|
||||||
paragraphs: (json['paragraphs'] as List<dynamic>?)
|
|
||||||
?.map((e) => Paragraph.fromJson(e as Map<String, dynamic>))
|
|
||||||
.toList(),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'paragraphs': paragraphs?.map((e) => e.toJson()).toList(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import 'item.dart';
|
|
||||||
|
|
||||||
class ModuleExtend {
|
|
||||||
List<Item>? items;
|
|
||||||
|
|
||||||
ModuleExtend({this.items});
|
|
||||||
|
|
||||||
factory ModuleExtend.fromJson(Map<String, dynamic> json) => ModuleExtend(
|
|
||||||
items: (json['items'] as List<dynamic>?)
|
|
||||||
?.map((e) => Item.fromJson(e as Map<String, dynamic>))
|
|
||||||
.toList(),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'items': items?.map((e) => e.toJson()).toList(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
import 'coin.dart';
|
|
||||||
import 'comment.dart';
|
|
||||||
import 'favorite.dart';
|
|
||||||
import 'forward.dart';
|
|
||||||
import 'like.dart';
|
|
||||||
|
|
||||||
class ModuleStat {
|
|
||||||
Coin? coin;
|
|
||||||
Comment? comment;
|
|
||||||
Favorite? favorite;
|
|
||||||
Forward? forward;
|
|
||||||
Like? like;
|
|
||||||
|
|
||||||
ModuleStat({
|
|
||||||
this.coin,
|
|
||||||
this.comment,
|
|
||||||
this.favorite,
|
|
||||||
this.forward,
|
|
||||||
this.like,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory ModuleStat.fromJson(Map<String, dynamic> json) => ModuleStat(
|
|
||||||
coin: json['coin'] == null
|
|
||||||
? null
|
|
||||||
: Coin.fromJson(json['coin'] as Map<String, dynamic>),
|
|
||||||
comment: json['comment'] == null
|
|
||||||
? null
|
|
||||||
: Comment.fromJson(json['comment'] as Map<String, dynamic>),
|
|
||||||
favorite: json['favorite'] == null
|
|
||||||
? null
|
|
||||||
: Favorite.fromJson(json['favorite'] as Map<String, dynamic>),
|
|
||||||
forward: json['forward'] == null
|
|
||||||
? null
|
|
||||||
: Forward.fromJson(json['forward'] as Map<String, dynamic>),
|
|
||||||
like: json['like'] == null
|
|
||||||
? null
|
|
||||||
: Like.fromJson(json['like'] as Map<String, dynamic>),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'coin': coin?.toJson(),
|
|
||||||
'comment': comment?.toJson(),
|
|
||||||
'favorite': favorite?.toJson(),
|
|
||||||
'forward': forward?.toJson(),
|
|
||||||
'like': like?.toJson(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
class ModuleTitle {
|
|
||||||
String? text;
|
|
||||||
|
|
||||||
ModuleTitle({this.text});
|
|
||||||
|
|
||||||
factory ModuleTitle.fromJson(Map<String, dynamic> json) => ModuleTitle(
|
|
||||||
text: json['text'] as String?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'text': text,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
import 'rich.dart';
|
|
||||||
import 'word.dart';
|
|
||||||
|
|
||||||
class Node {
|
|
||||||
String? type;
|
|
||||||
Word? word;
|
|
||||||
Rich? rich;
|
|
||||||
|
|
||||||
Node({
|
|
||||||
this.type,
|
|
||||||
this.word,
|
|
||||||
this.rich,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory Node.fromJson(Map<String, dynamic> json) => Node(
|
|
||||||
type: json['type'] as String?,
|
|
||||||
word: json['word'] == null
|
|
||||||
? null
|
|
||||||
: Word.fromJson(json['word'] as Map<String, dynamic>),
|
|
||||||
rich: json['rich'] == null
|
|
||||||
? null
|
|
||||||
: Rich.fromJson(json['rich'] as Map<String, dynamic>),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'type': type,
|
|
||||||
'word': word?.toJson(),
|
|
||||||
'rich': rich?.toJson(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
class Official {
|
|
||||||
String? desc;
|
|
||||||
int? role;
|
|
||||||
String? title;
|
|
||||||
int? type;
|
|
||||||
|
|
||||||
Official({this.desc, this.role, this.title, this.type});
|
|
||||||
|
|
||||||
factory Official.fromJson(Map<String, dynamic> json) => Official(
|
|
||||||
desc: json['desc'] as String?,
|
|
||||||
role: json['role'] as int?,
|
|
||||||
title: json['title'] as String?,
|
|
||||||
type: json['type'] as int?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'desc': desc,
|
|
||||||
'role': role,
|
|
||||||
'title': title,
|
|
||||||
'type': type,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
import 'data.dart';
|
|
||||||
|
|
||||||
class OpusDetail {
|
|
||||||
int? code;
|
|
||||||
String? message;
|
|
||||||
int? ttl;
|
|
||||||
OpusData? data;
|
|
||||||
|
|
||||||
OpusDetail({this.code, this.message, this.ttl, this.data});
|
|
||||||
|
|
||||||
factory OpusDetail.fromJson(Map<String, dynamic> json) => OpusDetail(
|
|
||||||
code: json['code'] as int?,
|
|
||||||
message: json['message'] as String?,
|
|
||||||
ttl: json['ttl'] as int?,
|
|
||||||
data: json['data'] == null
|
|
||||||
? null
|
|
||||||
: OpusData.fromJson(json['data'] as Map<String, dynamic>),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'code': code,
|
|
||||||
'message': message,
|
|
||||||
'ttl': ttl,
|
|
||||||
'data': data?.toJson(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,142 +0,0 @@
|
|||||||
import 'node.dart';
|
|
||||||
import 'pic.dart';
|
|
||||||
import 'text.dart';
|
|
||||||
|
|
||||||
class Paragraph {
|
|
||||||
int? align;
|
|
||||||
int? paraType;
|
|
||||||
ParagraphText? text;
|
|
||||||
Pic? pic;
|
|
||||||
Line? line;
|
|
||||||
LinkCard? linkCard;
|
|
||||||
Code? code;
|
|
||||||
L1st? list;
|
|
||||||
|
|
||||||
Paragraph({
|
|
||||||
this.align,
|
|
||||||
this.paraType,
|
|
||||||
this.text,
|
|
||||||
this.pic,
|
|
||||||
this.line,
|
|
||||||
this.linkCard,
|
|
||||||
this.code,
|
|
||||||
this.list,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory Paragraph.fromJson(Map<String, dynamic> json) => Paragraph(
|
|
||||||
align: json['align'] as int?,
|
|
||||||
paraType: json['para_type'] as int?,
|
|
||||||
text: json['text'] == null
|
|
||||||
? null
|
|
||||||
: ParagraphText.fromJson(json['text'] as Map<String, dynamic>),
|
|
||||||
pic: json['pic'] == null
|
|
||||||
? null
|
|
||||||
: Pic.fromJson(json['pic'] as Map<String, dynamic>),
|
|
||||||
line: json['line'] == null ? null : Line.fromJson(json['line']),
|
|
||||||
linkCard: json['link_card'] == null
|
|
||||||
? null
|
|
||||||
: LinkCard.fromJson(json['link_card']),
|
|
||||||
code: json['code'] == null ? null : Code.fromJson(json['code']),
|
|
||||||
list: json['list'] == null ? null : L1st.fromJson(json['list']),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'align': align,
|
|
||||||
'para_type': paraType,
|
|
||||||
'text': text?.toJson(),
|
|
||||||
'pic': pic?.toJson(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
class L1st {
|
|
||||||
List<Item>? items;
|
|
||||||
int? style;
|
|
||||||
|
|
||||||
L1st.fromJson(Map<String, dynamic> json) {
|
|
||||||
items = (json['items'] as List?)?.map((e) => Item.fromJson(e)).toList();
|
|
||||||
style = json['style'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Item {
|
|
||||||
int? level;
|
|
||||||
int? order;
|
|
||||||
List<Node>? nodes;
|
|
||||||
|
|
||||||
Item.fromJson(Map<String, dynamic> json) {
|
|
||||||
level = json['level'];
|
|
||||||
order = json['order'];
|
|
||||||
nodes = (json['nodes'] as List?)?.map((e) => Node.fromJson(e)).toList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Code {
|
|
||||||
String? content;
|
|
||||||
String? lang;
|
|
||||||
|
|
||||||
Code.fromJson(Map<String, dynamic> json) {
|
|
||||||
content = json['content'];
|
|
||||||
lang = json['lang'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Ugc {
|
|
||||||
String? cover;
|
|
||||||
String? descSecond;
|
|
||||||
String? duration;
|
|
||||||
String? headText;
|
|
||||||
String? idStr;
|
|
||||||
String? jumpUrl;
|
|
||||||
bool? multiLine;
|
|
||||||
String? title;
|
|
||||||
|
|
||||||
Ugc.fromJson(Map<String, dynamic> json) {
|
|
||||||
cover = json['cover'];
|
|
||||||
descSecond = json['desc_second'];
|
|
||||||
duration = json['duration'];
|
|
||||||
headText = json['head_text'];
|
|
||||||
idStr = json['id_str'];
|
|
||||||
jumpUrl = json['jump_url'];
|
|
||||||
multiLine = json['multi_line'];
|
|
||||||
title = json['title'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Card {
|
|
||||||
Card({
|
|
||||||
this.oid,
|
|
||||||
this.type,
|
|
||||||
this.ugc,
|
|
||||||
});
|
|
||||||
String? oid;
|
|
||||||
String? type;
|
|
||||||
Ugc? ugc;
|
|
||||||
|
|
||||||
Card.fromJson(Map<String, dynamic> json) {
|
|
||||||
oid = json['oid'];
|
|
||||||
type = json['type'];
|
|
||||||
ugc = json['ugc'] == null ? null : Ugc.fromJson(json['ugc']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class LinkCard {
|
|
||||||
LinkCard({
|
|
||||||
this.card,
|
|
||||||
});
|
|
||||||
Card? card;
|
|
||||||
|
|
||||||
LinkCard.fromJson(Map<String, dynamic> json) {
|
|
||||||
card = json['card'] == null ? null : Card.fromJson(json['card']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Line {
|
|
||||||
Line({
|
|
||||||
this.pic,
|
|
||||||
});
|
|
||||||
Pic? pic;
|
|
||||||
|
|
||||||
Line.fromJson(Map<String, dynamic> json) {
|
|
||||||
pic = json['pic'] == null ? null : Pic.fromJson(json['pic']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
class Pendant {
|
|
||||||
int? expire;
|
|
||||||
String? image;
|
|
||||||
String? imageEnhance;
|
|
||||||
String? imageEnhanceFrame;
|
|
||||||
int? nPid;
|
|
||||||
String? name;
|
|
||||||
int? pid;
|
|
||||||
|
|
||||||
Pendant({
|
|
||||||
this.expire,
|
|
||||||
this.image,
|
|
||||||
this.imageEnhance,
|
|
||||||
this.imageEnhanceFrame,
|
|
||||||
this.nPid,
|
|
||||||
this.name,
|
|
||||||
this.pid,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory Pendant.fromJson(Map<String, dynamic> json) => Pendant(
|
|
||||||
expire: json['expire'] as int?,
|
|
||||||
image: json['image'] as String?,
|
|
||||||
imageEnhance: json['image_enhance'] as String?,
|
|
||||||
imageEnhanceFrame: json['image_enhance_frame'] as String?,
|
|
||||||
nPid: json['n_pid'] as int?,
|
|
||||||
name: json['name'] as String?,
|
|
||||||
pid: json['pid'] as int?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'expire': expire,
|
|
||||||
'image': image,
|
|
||||||
'image_enhance': imageEnhance,
|
|
||||||
'image_enhance_frame': imageEnhanceFrame,
|
|
||||||
'n_pid': nPid,
|
|
||||||
'name': name,
|
|
||||||
'pid': pid,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
class Pic {
|
|
||||||
List<PicItem>? pics;
|
|
||||||
int? style;
|
|
||||||
String? url;
|
|
||||||
num? width;
|
|
||||||
double? height;
|
|
||||||
num? size;
|
|
||||||
|
|
||||||
Pic({
|
|
||||||
this.pics,
|
|
||||||
this.style,
|
|
||||||
this.url,
|
|
||||||
this.height,
|
|
||||||
this.width,
|
|
||||||
this.size,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory Pic.fromJson(Map<String, dynamic> json) => Pic(
|
|
||||||
pics: (json['pics'] as List<dynamic>?)
|
|
||||||
?.map((e) => PicItem.fromJson(e as Map<String, dynamic>))
|
|
||||||
.toList(),
|
|
||||||
style: json['style'] as int?,
|
|
||||||
url: json['url'],
|
|
||||||
height: (json['height'] as num?)?.toDouble(),
|
|
||||||
width: json['width'] as num?,
|
|
||||||
size: json['size'] as num?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'pics': pics?.map((e) => e.toJson()).toList(),
|
|
||||||
'style': style,
|
|
||||||
'height': height,
|
|
||||||
'width': width,
|
|
||||||
'size': size,
|
|
||||||
'url': url,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
class PicItem {
|
|
||||||
num? height;
|
|
||||||
num? width;
|
|
||||||
num? size;
|
|
||||||
String? url;
|
|
||||||
String? liveUrl;
|
|
||||||
double? calHeight;
|
|
||||||
|
|
||||||
void onCalHeight(maxWidth) {
|
|
||||||
if (calHeight == null && height != null && width != null) {
|
|
||||||
calHeight = maxWidth * height! / width!;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PicItem({
|
|
||||||
this.height,
|
|
||||||
this.width,
|
|
||||||
this.size,
|
|
||||||
this.url,
|
|
||||||
this.liveUrl,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory PicItem.fromJson(Map<String, dynamic> json) => PicItem(
|
|
||||||
height: json['height'] as num?,
|
|
||||||
width: json['width'] as num?,
|
|
||||||
size: json['size'] as num?,
|
|
||||||
url: json['url'] as String?,
|
|
||||||
liveUrl: json['live_url'] as String?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'height': height,
|
|
||||||
'width': width,
|
|
||||||
'size': size,
|
|
||||||
'url': url,
|
|
||||||
'live_url': liveUrl,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
class PosSpec {
|
|
||||||
double? axisX;
|
|
||||||
double? axisY;
|
|
||||||
int? coordinatePos;
|
|
||||||
|
|
||||||
PosSpec({this.axisX, this.axisY, this.coordinatePos});
|
|
||||||
|
|
||||||
factory PosSpec.fromJson(Map<String, dynamic> json) => PosSpec(
|
|
||||||
axisX: (json['axis_x'] as num?)?.toDouble(),
|
|
||||||
axisY: (json['axis_y'] as num?)?.toDouble(),
|
|
||||||
coordinatePos: json['coordinate_pos'] as int?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'axis_x': axisX,
|
|
||||||
'axis_y': axisY,
|
|
||||||
'coordinate_pos': coordinatePos,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
class Remote {
|
|
||||||
String? bfsStyle;
|
|
||||||
String? url;
|
|
||||||
|
|
||||||
Remote({this.bfsStyle, this.url});
|
|
||||||
|
|
||||||
factory Remote.fromJson(Map<String, dynamic> json) => Remote(
|
|
||||||
bfsStyle: json['bfs_style'] as String?,
|
|
||||||
url: json['url'] as String?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'bfs_style': bfsStyle,
|
|
||||||
'url': url,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
class RenderSpec {
|
|
||||||
int? opacity;
|
|
||||||
|
|
||||||
RenderSpec({this.opacity});
|
|
||||||
|
|
||||||
factory RenderSpec.fromJson(Map<String, dynamic> json) => RenderSpec(
|
|
||||||
opacity: json['opacity'] as int?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'opacity': opacity,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import 'image_src.dart';
|
|
||||||
|
|
||||||
class ResImage {
|
|
||||||
ImageSrc? imageSrc;
|
|
||||||
|
|
||||||
ResImage({this.imageSrc});
|
|
||||||
|
|
||||||
factory ResImage.fromJson(Map<String, dynamic> json) => ResImage(
|
|
||||||
imageSrc: json['image_src'] == null
|
|
||||||
? null
|
|
||||||
: ImageSrc.fromJson(json['image_src'] as Map<String, dynamic>),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'image_src': imageSrc?.toJson(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
import 'res_image.dart';
|
|
||||||
|
|
||||||
class Resource {
|
|
||||||
ResImage? resImage;
|
|
||||||
int? resType;
|
|
||||||
|
|
||||||
Resource({this.resImage, this.resType});
|
|
||||||
|
|
||||||
factory Resource.fromJson(Map<String, dynamic> json) => Resource(
|
|
||||||
resImage: json['res_image'] == null
|
|
||||||
? null
|
|
||||||
: ResImage.fromJson(json['res_image'] as Map<String, dynamic>),
|
|
||||||
resType: json['res_type'] as int?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'res_image': resImage?.toJson(),
|
|
||||||
'res_type': resType,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
import 'style.dart';
|
|
||||||
|
|
||||||
class Rich {
|
|
||||||
Style? style;
|
|
||||||
String? jumpUrl;
|
|
||||||
String? origText;
|
|
||||||
String? text;
|
|
||||||
|
|
||||||
Rich({
|
|
||||||
this.style,
|
|
||||||
this.jumpUrl,
|
|
||||||
this.origText,
|
|
||||||
this.text,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory Rich.fromJson(Map<String, dynamic> json) => Rich(
|
|
||||||
style: json['style'] == null
|
|
||||||
? null
|
|
||||||
: Style.fromJson(json['style'] as Map<String, dynamic>),
|
|
||||||
jumpUrl: json['jump_url'] as String?,
|
|
||||||
origText: json['orig_text'] as String?,
|
|
||||||
text: json['text'] as String?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'style': style?.toJson(),
|
|
||||||
'jump_url': jumpUrl,
|
|
||||||
'orig_text': origText,
|
|
||||||
'text': text,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
class ShareInfo {
|
|
||||||
String? pic;
|
|
||||||
String? summary;
|
|
||||||
String? title;
|
|
||||||
|
|
||||||
ShareInfo({this.pic, this.summary, this.title});
|
|
||||||
|
|
||||||
factory ShareInfo.fromJson(Map<String, dynamic> json) => ShareInfo(
|
|
||||||
pic: json['pic'] as String?,
|
|
||||||
summary: json['summary'] as String?,
|
|
||||||
title: json['title'] as String?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'pic': pic,
|
|
||||||
'summary': summary,
|
|
||||||
'title': title,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
class SizeSpec {
|
|
||||||
num? height;
|
|
||||||
num? width;
|
|
||||||
|
|
||||||
SizeSpec({this.height, this.width});
|
|
||||||
|
|
||||||
factory SizeSpec.fromJson(Map<String, dynamic> json) => SizeSpec(
|
|
||||||
height: json['height'],
|
|
||||||
width: json['width'],
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'height': height,
|
|
||||||
'width': width,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
class Style {
|
|
||||||
Style({
|
|
||||||
this.bold,
|
|
||||||
this.italic,
|
|
||||||
this.strikethrough,
|
|
||||||
});
|
|
||||||
bool? bold;
|
|
||||||
bool? italic;
|
|
||||||
bool? strikethrough;
|
|
||||||
|
|
||||||
factory Style.fromJson(Map<String, dynamic> json) => Style(
|
|
||||||
bold: json['bold'],
|
|
||||||
italic: json['italic'],
|
|
||||||
strikethrough: json['strikethrough'],
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'bold': bold,
|
|
||||||
'italic': italic,
|
|
||||||
'strikethrough': strikethrough,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
import 'general_cfg.dart';
|
|
||||||
|
|
||||||
class Tags {
|
|
||||||
// AvatarLayer? avatarLayer;
|
|
||||||
GeneralCfg? generalCfg;
|
|
||||||
|
|
||||||
Tags({
|
|
||||||
// this.avatarLayer,
|
|
||||||
this.generalCfg,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory Tags.fromJson(Map<String, dynamic> json) => Tags(
|
|
||||||
// avatarLayer: json['AVATAR_LAYER'] == null
|
|
||||||
// ? null
|
|
||||||
// : AvatarLayer.fromJson(
|
|
||||||
// json['AVATAR_LAYER'] as Map<String, dynamic>),
|
|
||||||
generalCfg: json['GENERAL_CFG'] == null
|
|
||||||
? null
|
|
||||||
: GeneralCfg.fromJson(json['GENERAL_CFG'] as Map<String, dynamic>),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
// 'AVATAR_LAYER': avatarLayer?.toJson(),
|
|
||||||
'GENERAL_CFG': generalCfg?.toJson(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import 'node.dart';
|
|
||||||
|
|
||||||
class ParagraphText {
|
|
||||||
List<Node>? nodes;
|
|
||||||
|
|
||||||
ParagraphText({this.nodes});
|
|
||||||
|
|
||||||
factory ParagraphText.fromJson(Map<String, dynamic> json) => ParagraphText(
|
|
||||||
nodes: (json['nodes'] as List<dynamic>?)
|
|
||||||
?.map((e) => Node.fromJson(e as Map<String, dynamic>))
|
|
||||||
.toList(),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'nodes': nodes?.map((e) => e.toJson()).toList(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
import 'label.dart';
|
|
||||||
|
|
||||||
class Vip {
|
|
||||||
// AvatarIcon? avatarIcon;
|
|
||||||
int? avatarSubscript;
|
|
||||||
String? avatarSubscriptUrl;
|
|
||||||
int? dueDate;
|
|
||||||
Label? label;
|
|
||||||
String? nicknameColor;
|
|
||||||
int? role;
|
|
||||||
int? status;
|
|
||||||
int? themeType;
|
|
||||||
int? tvDueDate;
|
|
||||||
int? tvVipPayType;
|
|
||||||
int? tvVipStatus;
|
|
||||||
int? type;
|
|
||||||
int? vipPayType;
|
|
||||||
|
|
||||||
Vip({
|
|
||||||
// this.avatarIcon,
|
|
||||||
this.avatarSubscript,
|
|
||||||
this.avatarSubscriptUrl,
|
|
||||||
this.dueDate,
|
|
||||||
this.label,
|
|
||||||
this.nicknameColor,
|
|
||||||
this.role,
|
|
||||||
this.status,
|
|
||||||
this.themeType,
|
|
||||||
this.tvDueDate,
|
|
||||||
this.tvVipPayType,
|
|
||||||
this.tvVipStatus,
|
|
||||||
this.type,
|
|
||||||
this.vipPayType,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory Vip.fromJson(Map<String, dynamic> json) => Vip(
|
|
||||||
// avatarIcon: json['avatar_icon'] == null
|
|
||||||
// ? null
|
|
||||||
// : AvatarIcon.fromJson(json['avatar_icon'] as Map<String, dynamic>),
|
|
||||||
avatarSubscript: json['avatar_subscript'] as int?,
|
|
||||||
avatarSubscriptUrl: json['avatar_subscript_url'] as String?,
|
|
||||||
dueDate: json['due_date'] as int?,
|
|
||||||
label: json['label'] == null
|
|
||||||
? null
|
|
||||||
: Label.fromJson(json['label'] as Map<String, dynamic>),
|
|
||||||
nicknameColor: json['nickname_color'] as String?,
|
|
||||||
role: json['role'] as int?,
|
|
||||||
status: json['status'] as int?,
|
|
||||||
themeType: json['theme_type'] as int?,
|
|
||||||
tvDueDate: json['tv_due_date'] as int?,
|
|
||||||
tvVipPayType: json['tv_vip_pay_type'] as int?,
|
|
||||||
tvVipStatus: json['tv_vip_status'] as int?,
|
|
||||||
type: json['type'] as int?,
|
|
||||||
vipPayType: json['vip_pay_type'] as int?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
// 'avatar_icon': avatarIcon?.toJson(),
|
|
||||||
'avatar_subscript': avatarSubscript,
|
|
||||||
'avatar_subscript_url': avatarSubscriptUrl,
|
|
||||||
'due_date': dueDate,
|
|
||||||
'label': label?.toJson(),
|
|
||||||
'nickname_color': nicknameColor,
|
|
||||||
'role': role,
|
|
||||||
'status': status,
|
|
||||||
'theme_type': themeType,
|
|
||||||
'tv_due_date': tvDueDate,
|
|
||||||
'tv_vip_pay_type': tvVipPayType,
|
|
||||||
'tv_vip_status': tvVipStatus,
|
|
||||||
'type': type,
|
|
||||||
'vip_pay_type': vipPayType,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
class WebCssStyle {
|
|
||||||
String? borderRadius;
|
|
||||||
|
|
||||||
WebCssStyle({this.borderRadius});
|
|
||||||
|
|
||||||
factory WebCssStyle.fromJson(Map<String, dynamic> json) => WebCssStyle(
|
|
||||||
borderRadius: json['borderRadius'] as String?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'borderRadius': borderRadius,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
import 'style.dart';
|
|
||||||
|
|
||||||
class Word {
|
|
||||||
int? color;
|
|
||||||
double? fontSize;
|
|
||||||
Style? style;
|
|
||||||
String? words;
|
|
||||||
String? fontLevel;
|
|
||||||
|
|
||||||
Word({
|
|
||||||
this.color,
|
|
||||||
this.fontSize,
|
|
||||||
this.style,
|
|
||||||
this.words,
|
|
||||||
this.fontLevel,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory Word.fromJson(Map<String, dynamic> json) => Word(
|
|
||||||
color: json['color'] == null
|
|
||||||
? null
|
|
||||||
: int.tryParse('0xFF${(json['color'] as String).substring(1)}'),
|
|
||||||
fontSize: (json['font_size'] as num?)?.toDouble(),
|
|
||||||
style: json['style'] == null
|
|
||||||
? null
|
|
||||||
: Style.fromJson(json['style'] as Map<String, dynamic>),
|
|
||||||
words: json['words'] as String?,
|
|
||||||
fontLevel: json['font_level'] as String?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'color': color,
|
|
||||||
'font_size': fontSize,
|
|
||||||
'style': style?.toJson(),
|
|
||||||
'words': words,
|
|
||||||
'font_level': fontLevel,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,14 +1,11 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:PiliPlus/common/widgets/avatar.dart';
|
import 'package:PiliPlus/common/widgets/avatar.dart';
|
||||||
|
import 'package:PiliPlus/models/model_owner.dart';
|
||||||
|
|
||||||
|
import 'article_content_model.dart';
|
||||||
|
|
||||||
class DynamicsDataModel {
|
class DynamicsDataModel {
|
||||||
DynamicsDataModel({
|
|
||||||
this.hasMore,
|
|
||||||
this.items,
|
|
||||||
this.offset,
|
|
||||||
this.total,
|
|
||||||
});
|
|
||||||
bool? hasMore;
|
bool? hasMore;
|
||||||
List<DynamicItemModel>? items;
|
List<DynamicItemModel>? items;
|
||||||
String? offset;
|
String? offset;
|
||||||
@@ -26,50 +23,85 @@ class DynamicsDataModel {
|
|||||||
|
|
||||||
// 单个动态
|
// 单个动态
|
||||||
class DynamicItemModel {
|
class DynamicItemModel {
|
||||||
DynamicItemModel({
|
Basic? basic;
|
||||||
this.basic,
|
|
||||||
this.idStr,
|
|
||||||
this.modules,
|
|
||||||
this.orig,
|
|
||||||
this.type,
|
|
||||||
this.visible,
|
|
||||||
});
|
|
||||||
|
|
||||||
Map? basic;
|
|
||||||
dynamic idStr;
|
dynamic idStr;
|
||||||
ItemModulesModel? modules;
|
late ItemModulesModel modules;
|
||||||
|
|
||||||
DynamicItemModel? orig;
|
DynamicItemModel? orig;
|
||||||
String? type;
|
String? type;
|
||||||
bool? visible;
|
bool? visible;
|
||||||
bool? isForwarded;
|
bool? isForwarded;
|
||||||
|
|
||||||
|
// opus
|
||||||
|
Fallback? fallback;
|
||||||
|
|
||||||
DynamicItemModel.fromJson(Map<String, dynamic> json) {
|
DynamicItemModel.fromJson(Map<String, dynamic> json) {
|
||||||
basic = json['basic'];
|
if (json['basic'] != null) basic = Basic.fromJson(json['basic']);
|
||||||
idStr = json['id_str'];
|
idStr = json['id_str'];
|
||||||
modules = ItemModulesModel.fromJson(json['modules']);
|
modules = json['modules'] == null
|
||||||
orig =
|
? ItemModulesModel()
|
||||||
json['orig'] != null ? DynamicItemModel.fromJson(json['orig']) : null;
|
: ItemModulesModel.fromJson(json['modules']);
|
||||||
orig?.isForwarded = true;
|
if (json['orig'] != null) {
|
||||||
|
orig = DynamicItemModel.fromJson(json['orig'])..isForwarded = true;
|
||||||
|
}
|
||||||
type = json['type'];
|
type = json['type'];
|
||||||
visible = json['visible'];
|
visible = json['visible'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DynamicItemModel.fromOpusJson(Map<String, dynamic> json) {
|
||||||
|
if (json['item']?['basic'] != null) {
|
||||||
|
basic = Basic.fromJson(json['item']['basic']);
|
||||||
|
}
|
||||||
|
idStr = json['item']?['id_str'];
|
||||||
|
// type = json['type']; // int
|
||||||
|
modules = json['item']?['modules'] == null
|
||||||
|
? ItemModulesModel()
|
||||||
|
: ItemModulesModel.fromOpusJson(
|
||||||
|
(json['item']?['modules'] as List).cast());
|
||||||
|
|
||||||
|
if (json['fallback'] != null) {
|
||||||
|
fallback = Fallback.fromJson(json['fallback']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Fallback {
|
||||||
|
String? id;
|
||||||
|
int? type;
|
||||||
|
|
||||||
|
Fallback({
|
||||||
|
this.id,
|
||||||
|
this.type,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory Fallback.fromJson(Map<String, dynamic> json) => Fallback(
|
||||||
|
id: json['id'],
|
||||||
|
type: json['type'],
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
'id': id,
|
||||||
|
'type': type,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 单个动态详情
|
// 单个动态详情
|
||||||
class ItemModulesModel {
|
class ItemModulesModel {
|
||||||
ItemModulesModel({
|
ItemModulesModel();
|
||||||
this.moduleAuthor,
|
|
||||||
this.moduleDynamic,
|
|
||||||
// this.moduleInter,
|
|
||||||
this.moduleStat,
|
|
||||||
this.moduleTag,
|
|
||||||
});
|
|
||||||
|
|
||||||
ModuleAuthorModel? moduleAuthor;
|
ModuleAuthorModel? moduleAuthor;
|
||||||
|
ModuleStatModel? moduleStat;
|
||||||
|
ModuleTag? moduleTag; // 也做opus的title用
|
||||||
|
|
||||||
|
// 动态
|
||||||
ModuleDynamicModel? moduleDynamic;
|
ModuleDynamicModel? moduleDynamic;
|
||||||
// ModuleInterModel? moduleInter;
|
// ModuleInterModel? moduleInter;
|
||||||
ModuleStatModel? moduleStat;
|
|
||||||
ModuleTag? moduleTag;
|
// 专栏
|
||||||
|
List<ModuleTag>? moduleExtend; // opus的tag
|
||||||
|
List<ArticleContentModel>? moduleContent;
|
||||||
|
|
||||||
|
// moduleBottom
|
||||||
|
|
||||||
ItemModulesModel.fromJson(Map<String, dynamic> json) {
|
ItemModulesModel.fromJson(Map<String, dynamic> json) {
|
||||||
moduleAuthor = json['module_author'] != null
|
moduleAuthor = json['module_author'] != null
|
||||||
@@ -86,37 +118,63 @@ class ItemModulesModel {
|
|||||||
? ModuleTag.fromJson(json['module_tag'])
|
? ModuleTag.fromJson(json['module_tag'])
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ItemModulesModel.fromOpusJson(List<Map<String, dynamic>> json) {
|
||||||
|
for (var i in json) {
|
||||||
|
switch (i['module_type']) {
|
||||||
|
case 'MODULE_TYPE_TITLE':
|
||||||
|
moduleTag = i['module_title'] == null
|
||||||
|
? null
|
||||||
|
: ModuleTag.fromJson(i['module_title']);
|
||||||
|
break;
|
||||||
|
case 'MODULE_TYPE_AUTHOR':
|
||||||
|
moduleAuthor = i['module_author'] == null
|
||||||
|
? null
|
||||||
|
: ModuleAuthorModel.fromJson(i['module_author']);
|
||||||
|
break;
|
||||||
|
case 'MODULE_TYPE_CONTENT':
|
||||||
|
moduleContent = (i['module_content']?['paragraphs'] as List?)
|
||||||
|
?.map((i) => ArticleContentModel.fromJson(i))
|
||||||
|
.toList();
|
||||||
|
break;
|
||||||
|
case 'MODULE_TYPE_EXTEND':
|
||||||
|
moduleExtend = (i['module_extend']['items'] as List?)
|
||||||
|
?.map((i) => ModuleTag.fromJson(i))
|
||||||
|
.toList();
|
||||||
|
break;
|
||||||
|
case 'MODULE_TYPE_STAT':
|
||||||
|
moduleStat = i['module_stat'] == null
|
||||||
|
? null
|
||||||
|
: ModuleStatModel.fromJson(i['module_stat']);
|
||||||
|
break;
|
||||||
|
// case 'MODULE_TYPE_BOTTOM':
|
||||||
|
// break;
|
||||||
|
// default:
|
||||||
|
// debugPrint('unknown type: ${i}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Basic {
|
||||||
|
String? commentIdStr;
|
||||||
|
int? commentType;
|
||||||
|
Map<String, dynamic>? likeIcon;
|
||||||
|
String? ridStr;
|
||||||
|
|
||||||
|
Basic.fromJson(Map<String, dynamic> json) {
|
||||||
|
commentIdStr = json['comment_id_str'];
|
||||||
|
commentType = json['comment_type'];
|
||||||
|
likeIcon = json['like_icon'];
|
||||||
|
ridStr = json['rid_str'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 单个动态详情 - 作者信息
|
// 单个动态详情 - 作者信息
|
||||||
class ModuleAuthorModel {
|
class ModuleAuthorModel extends Owner {
|
||||||
ModuleAuthorModel({
|
|
||||||
// this.avatar,
|
|
||||||
// this.decorate,
|
|
||||||
this.face,
|
|
||||||
this.following,
|
|
||||||
this.jumpUrl,
|
|
||||||
this.label,
|
|
||||||
this.mid,
|
|
||||||
this.name,
|
|
||||||
// this.officialVerify,
|
|
||||||
// this.pandant,
|
|
||||||
this.pubAction,
|
|
||||||
// this.pubLocationText,
|
|
||||||
this.pubTime,
|
|
||||||
this.pubTs,
|
|
||||||
this.type,
|
|
||||||
this.vip,
|
|
||||||
this.decorate,
|
|
||||||
this.pendant,
|
|
||||||
});
|
|
||||||
|
|
||||||
String? face;
|
|
||||||
bool? following;
|
bool? following;
|
||||||
String? jumpUrl;
|
String? jumpUrl;
|
||||||
String? label;
|
String? label;
|
||||||
int? mid;
|
|
||||||
String? name;
|
|
||||||
String? pubAction;
|
String? pubAction;
|
||||||
String? pubTime;
|
String? pubTime;
|
||||||
int? pubTs;
|
int? pubTs;
|
||||||
@@ -790,63 +848,49 @@ class ModuleStatModel {
|
|||||||
this.comment,
|
this.comment,
|
||||||
this.forward,
|
this.forward,
|
||||||
this.like,
|
this.like,
|
||||||
|
this.favorite,
|
||||||
});
|
});
|
||||||
|
|
||||||
Comment? comment;
|
DynamicStat? comment;
|
||||||
ForWard? forward;
|
DynamicStat? forward;
|
||||||
Like? like;
|
DynamicStat? like;
|
||||||
|
DynamicStat? favorite;
|
||||||
|
// DynamicStat? coin;
|
||||||
|
|
||||||
ModuleStatModel.fromJson(Map<String, dynamic> json) {
|
ModuleStatModel.fromJson(Map<String, dynamic> json) {
|
||||||
comment = Comment.fromJson(json['comment']);
|
comment = DynamicStat.fromJson(json['comment']);
|
||||||
forward = ForWard.fromJson(json['forward']);
|
forward = DynamicStat.fromJson(json['forward']);
|
||||||
like = Like.fromJson(json['like']);
|
like = DynamicStat.fromJson(json['like']);
|
||||||
|
if (json['favorite'] != null) {
|
||||||
|
favorite = DynamicStat.fromJson(json['favorite']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 动态状态 评论
|
// 动态状态
|
||||||
class Comment {
|
class DynamicStat {
|
||||||
Comment({
|
DynamicStat({
|
||||||
this.count,
|
|
||||||
this.forbidden,
|
|
||||||
});
|
|
||||||
|
|
||||||
String? count;
|
|
||||||
bool? forbidden;
|
|
||||||
|
|
||||||
Comment.fromJson(Map<String, dynamic> json) {
|
|
||||||
count = json['count'] == 0 ? null : json['count'].toString();
|
|
||||||
forbidden = json['forbidden'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ForWard {
|
|
||||||
ForWard({this.count, this.forbidden});
|
|
||||||
String? count;
|
|
||||||
bool? forbidden;
|
|
||||||
|
|
||||||
ForWard.fromJson(Map<String, dynamic> json) {
|
|
||||||
count = json['count'] == 0 ? null : json['count'].toString();
|
|
||||||
forbidden = json['forbidden'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 动态状态 点赞
|
|
||||||
class Like {
|
|
||||||
Like({
|
|
||||||
this.count,
|
this.count,
|
||||||
this.forbidden,
|
this.forbidden,
|
||||||
this.status,
|
this.status,
|
||||||
});
|
});
|
||||||
|
|
||||||
String? count;
|
int? count;
|
||||||
bool? forbidden;
|
bool? forbidden;
|
||||||
bool? status;
|
bool? status;
|
||||||
|
|
||||||
Like.fromJson(Map<String, dynamic> json) {
|
DynamicStat.fromJson(Map<String, dynamic> json) {
|
||||||
count = json['count'] == 0 ? null : json['count'].toString();
|
count = json['count'] == 0 ? null : _parseInt(json['count']);
|
||||||
forbidden = json['forbidden'];
|
forbidden = json['forbidden'];
|
||||||
status = json['status'];
|
status = json['status'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int? _parseInt(dynamic x) => switch (x) {
|
||||||
|
int() => x,
|
||||||
|
String() => int.tryParse(x),
|
||||||
|
double() => x.toInt(),
|
||||||
|
_ => null
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class Stat {
|
class Stat {
|
||||||
|
|||||||
@@ -1,36 +1,27 @@
|
|||||||
import 'package:json_annotation/json_annotation.dart';
|
import '../model_owner.dart';
|
||||||
|
|
||||||
import 'nameplate.dart';
|
import 'nameplate.dart';
|
||||||
import 'official_verify.dart';
|
import 'official_verify.dart';
|
||||||
import 'pendant.dart';
|
import 'pendant.dart';
|
||||||
import 'vip.dart';
|
import 'vip.dart';
|
||||||
|
|
||||||
part 'author.g.dart';
|
class Author extends Owner {
|
||||||
|
Pendant? pendant;
|
||||||
|
OfficialVerify? officialVerify;
|
||||||
|
Nameplate? nameplate;
|
||||||
|
Vip? vip;
|
||||||
|
|
||||||
@JsonSerializable()
|
Author.fromJson(Map<String, dynamic> json) {
|
||||||
class Author {
|
mid = json['mid'];
|
||||||
int? mid;
|
name = json['name'] as String?;
|
||||||
String? name;
|
face = json['face'] as String?;
|
||||||
String? face;
|
pendant =
|
||||||
Pendant? pendant;
|
json['pendant'] == null ? null : Pendant.fromJson(json['pendant']);
|
||||||
@JsonKey(name: 'official_verify')
|
officialVerify = json['official_verify'] == null
|
||||||
OfficialVerify? officialVerify;
|
? null
|
||||||
Nameplate? nameplate;
|
: OfficialVerify.fromJson(json['official_verify']);
|
||||||
Vip? vip;
|
nameplate = json['nameplate'] == null
|
||||||
|
? null
|
||||||
Author({
|
: Nameplate.fromJson(json['nameplate']);
|
||||||
this.mid,
|
vip = json['vip'] == null ? null : Vip.fromJson(json['vip']);
|
||||||
this.name,
|
}
|
||||||
this.face,
|
|
||||||
this.pendant,
|
|
||||||
this.officialVerify,
|
|
||||||
this.nameplate,
|
|
||||||
this.vip,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory Author.fromJson(Map<String, dynamic> json) {
|
|
||||||
return _$AuthorFromJson(json);
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => _$AuthorToJson(this);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,36 +1 @@
|
|||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
|
||||||
|
|
||||||
part of 'author.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// JsonSerializableGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
Author _$AuthorFromJson(Map<String, dynamic> json) => Author(
|
|
||||||
mid: (json['mid'] as num?)?.toInt(),
|
|
||||||
name: json['name'] as String?,
|
|
||||||
face: json['face'] as String?,
|
|
||||||
pendant: json['pendant'] == null
|
|
||||||
? null
|
|
||||||
: Pendant.fromJson(json['pendant'] as Map<String, dynamic>),
|
|
||||||
officialVerify: json['official_verify'] == null
|
|
||||||
? null
|
|
||||||
: OfficialVerify.fromJson(
|
|
||||||
json['official_verify'] as Map<String, dynamic>),
|
|
||||||
nameplate: json['nameplate'] == null
|
|
||||||
? null
|
|
||||||
: Nameplate.fromJson(json['nameplate'] as Map<String, dynamic>),
|
|
||||||
vip: json['vip'] == null
|
|
||||||
? null
|
|
||||||
: Vip.fromJson(json['vip'] as Map<String, dynamic>),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> _$AuthorToJson(Author instance) => <String, dynamic>{
|
|
||||||
'mid': instance.mid,
|
|
||||||
'name': instance.name,
|
|
||||||
'face': instance.face,
|
|
||||||
'pendant': instance.pendant,
|
|
||||||
'official_verify': instance.officialVerify,
|
|
||||||
'nameplate': instance.nameplate,
|
|
||||||
'vip': instance.vip,
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,107 +1,142 @@
|
|||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:PiliPlus/models/dynamics/article_content_model.dart';
|
||||||
|
|
||||||
import 'author.dart';
|
import 'author.dart';
|
||||||
import 'category.dart';
|
import 'category.dart';
|
||||||
import 'media.dart';
|
import 'media.dart';
|
||||||
import 'stats.dart';
|
import 'stats.dart';
|
||||||
|
|
||||||
part 'item.g.dart';
|
|
||||||
|
|
||||||
@JsonSerializable()
|
|
||||||
class Item {
|
class Item {
|
||||||
int? id;
|
int? id;
|
||||||
Category? category;
|
Category? category;
|
||||||
List<Category>? categories;
|
List<Category>? categories;
|
||||||
String? title;
|
String? title;
|
||||||
String? summary;
|
String? summary;
|
||||||
@JsonKey(name: 'banner_url')
|
|
||||||
String? bannerUrl;
|
String? bannerUrl;
|
||||||
@JsonKey(name: 'template_id')
|
|
||||||
int? templateId;
|
int? templateId;
|
||||||
int? state;
|
int? state;
|
||||||
Author? author;
|
Author? author;
|
||||||
int? reprint;
|
int? reprint;
|
||||||
@JsonKey(name: 'image_urls')
|
|
||||||
List<String>? imageUrls;
|
List<String>? imageUrls;
|
||||||
@JsonKey(name: 'publish_time')
|
|
||||||
int? publishTime;
|
int? publishTime;
|
||||||
int? ctime;
|
int? ctime;
|
||||||
int? mtime;
|
int? mtime;
|
||||||
Stats? stats;
|
Stats? stats;
|
||||||
int? attributes;
|
|
||||||
int? words;
|
int? words;
|
||||||
@JsonKey(name: 'origin_image_urls')
|
|
||||||
List<String>? originImageUrls;
|
List<String>? originImageUrls;
|
||||||
dynamic list;
|
dynamic list;
|
||||||
@JsonKey(name: 'is_like')
|
|
||||||
bool? isLike;
|
bool? isLike;
|
||||||
Media? media;
|
Media? media;
|
||||||
@JsonKey(name: 'apply_time')
|
|
||||||
String? applyTime;
|
String? applyTime;
|
||||||
@JsonKey(name: 'check_time')
|
|
||||||
String? checkTime;
|
String? checkTime;
|
||||||
int? original;
|
int? original;
|
||||||
@JsonKey(name: 'act_id')
|
|
||||||
int? actId;
|
int? actId;
|
||||||
dynamic dispute;
|
dynamic dispute;
|
||||||
dynamic authenMark;
|
dynamic authenMark;
|
||||||
@JsonKey(name: 'cover_avid')
|
|
||||||
int? coverAvid;
|
int? coverAvid;
|
||||||
@JsonKey(name: 'top_video_info')
|
|
||||||
dynamic topVideoInfo;
|
dynamic topVideoInfo;
|
||||||
int? type;
|
int? type;
|
||||||
@JsonKey(name: 'check_state')
|
|
||||||
int? checkState;
|
int? checkState;
|
||||||
@JsonKey(name: 'origin_template_id')
|
|
||||||
int? originTemplateId;
|
int? originTemplateId;
|
||||||
|
|
||||||
|
// 动态
|
||||||
String? uri;
|
String? uri;
|
||||||
String? param;
|
String? param;
|
||||||
String? goto;
|
String? goto;
|
||||||
@JsonKey(name: 'publish_time_text')
|
|
||||||
String? publishTimeText;
|
String? publishTimeText;
|
||||||
String? dyn;
|
String? dyn;
|
||||||
|
|
||||||
Item({
|
// 专栏
|
||||||
this.id,
|
List<Tag>? tags;
|
||||||
this.category,
|
int? privatePub;
|
||||||
this.categories,
|
dynamic contentPicList;
|
||||||
this.title,
|
String? content;
|
||||||
this.summary,
|
String? keywords;
|
||||||
this.bannerUrl,
|
Opus? opus;
|
||||||
this.templateId,
|
int? versionId;
|
||||||
this.state,
|
String? dynIdStr;
|
||||||
this.author,
|
int? totalArtNum;
|
||||||
this.reprint,
|
|
||||||
this.imageUrls,
|
|
||||||
this.publishTime,
|
|
||||||
this.ctime,
|
|
||||||
this.mtime,
|
|
||||||
this.stats,
|
|
||||||
this.attributes,
|
|
||||||
this.words,
|
|
||||||
this.originImageUrls,
|
|
||||||
this.list,
|
|
||||||
this.isLike,
|
|
||||||
this.media,
|
|
||||||
this.applyTime,
|
|
||||||
this.checkTime,
|
|
||||||
this.original,
|
|
||||||
this.actId,
|
|
||||||
this.dispute,
|
|
||||||
this.authenMark,
|
|
||||||
this.coverAvid,
|
|
||||||
this.topVideoInfo,
|
|
||||||
this.type,
|
|
||||||
this.checkState,
|
|
||||||
this.originTemplateId,
|
|
||||||
this.uri,
|
|
||||||
this.param,
|
|
||||||
this.goto,
|
|
||||||
this.publishTimeText,
|
|
||||||
this.dyn,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory Item.fromJson(Map<String, dynamic> json) => _$ItemFromJson(json);
|
Item.fromJson(Map<String, dynamic> json) {
|
||||||
|
id = json["id"];
|
||||||
|
category =
|
||||||
|
json["category"] == null ? null : Category.fromJson(json["category"]);
|
||||||
|
categories = (json["categories"] as List?)
|
||||||
|
?.map((x) => Category.fromJson(x))
|
||||||
|
.toList();
|
||||||
|
title = json["title"];
|
||||||
|
summary = json["summary"];
|
||||||
|
bannerUrl = json["banner_url"];
|
||||||
|
templateId = json["template_id"];
|
||||||
|
state = json["state"];
|
||||||
|
author = json["author"] == null ? null : Author.fromJson(json["author"]);
|
||||||
|
reprint = json["reprint"];
|
||||||
|
imageUrls = (json["image_urls"] as List?)?.cast<String>();
|
||||||
|
publishTime = json["publish_time"];
|
||||||
|
ctime = json["ctime"];
|
||||||
|
mtime = json["mtime"];
|
||||||
|
stats = json["stats"] == null ? null : Stats.fromJson(json["stats"]);
|
||||||
|
words = json["words"];
|
||||||
|
originImageUrls = (json["origin_image_urls"] as List?)?.cast<String>();
|
||||||
|
list = json["list"];
|
||||||
|
isLike = json["is_like"];
|
||||||
|
media = json["media"] == null ? null : Media.fromJson(json["media"]);
|
||||||
|
applyTime = json["apply_time"];
|
||||||
|
checkTime = json["check_time"];
|
||||||
|
original = json["original"];
|
||||||
|
actId = json["act_id"];
|
||||||
|
dispute = json["dispute"];
|
||||||
|
authenMark = json["authenMark"];
|
||||||
|
coverAvid = json["cover_avid"];
|
||||||
|
topVideoInfo = json["top_video_info"];
|
||||||
|
type = json["type"];
|
||||||
|
checkState = json["check_state"];
|
||||||
|
originTemplateId = json["origin_template_id"];
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => _$ItemToJson(this);
|
uri = json['uri'];
|
||||||
|
param = json['param'];
|
||||||
|
goto = json['goto'];
|
||||||
|
publishTimeText = json['publish_time_text'];
|
||||||
|
dyn = json['dynamic'];
|
||||||
|
|
||||||
|
tags = (json["tags"] as List?)?.map((x) => Tag.fromJson(x)).toList();
|
||||||
|
privatePub = json["private_pub"];
|
||||||
|
contentPicList = json["content_pic_list"];
|
||||||
|
content = json["content"];
|
||||||
|
keywords = json["keywords"];
|
||||||
|
if (json['opus'] != null) opus = Opus.fromJson(json['opus']);
|
||||||
|
versionId = json["version_id"];
|
||||||
|
dynIdStr = json["dyn_id_str"];
|
||||||
|
totalArtNum = json["total_art_num"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Tag {
|
||||||
|
int? tid;
|
||||||
|
String? name;
|
||||||
|
|
||||||
|
Tag.fromJson(Map<String, dynamic> json) {
|
||||||
|
tid = json["tid"];
|
||||||
|
name = json["name"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Opus {
|
||||||
|
int? opusid;
|
||||||
|
int? opussource;
|
||||||
|
String? title;
|
||||||
|
List<ArticleContentModel>? content;
|
||||||
|
// PubInfo? pubinfo;
|
||||||
|
// Article? article;
|
||||||
|
// Version? version;
|
||||||
|
|
||||||
|
Opus.fromJson(Map<String, dynamic> json) {
|
||||||
|
opusid = json['opus_id'];
|
||||||
|
opussource = json['opus_source'];
|
||||||
|
title = json['title'];
|
||||||
|
if (json['content']?['paragraphs'] is List) {
|
||||||
|
content = (json['content']['paragraphs'] as List)
|
||||||
|
.map((i) => ArticleContentModel.fromJson(i))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,101 +0,0 @@
|
|||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
|
||||||
|
|
||||||
part of 'item.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// JsonSerializableGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
Item _$ItemFromJson(Map<String, dynamic> json) => Item(
|
|
||||||
id: (json['id'] as num?)?.toInt(),
|
|
||||||
category: json['category'] == null
|
|
||||||
? null
|
|
||||||
: Category.fromJson(json['category'] as Map<String, dynamic>),
|
|
||||||
categories: (json['categories'] as List<dynamic>?)
|
|
||||||
?.map((e) => Category.fromJson(e as Map<String, dynamic>))
|
|
||||||
.toList(),
|
|
||||||
title: json['title'] as String?,
|
|
||||||
summary: json['summary'] as String?,
|
|
||||||
bannerUrl: json['banner_url'] as String?,
|
|
||||||
templateId: (json['template_id'] as num?)?.toInt(),
|
|
||||||
state: (json['state'] as num?)?.toInt(),
|
|
||||||
author: json['author'] == null
|
|
||||||
? null
|
|
||||||
: Author.fromJson(json['author'] as Map<String, dynamic>),
|
|
||||||
reprint: (json['reprint'] as num?)?.toInt(),
|
|
||||||
imageUrls: (json['image_urls'] as List<dynamic>?)
|
|
||||||
?.map((e) => e as String)
|
|
||||||
.toList(),
|
|
||||||
publishTime: (json['publish_time'] as num?)?.toInt(),
|
|
||||||
ctime: (json['ctime'] as num?)?.toInt(),
|
|
||||||
mtime: (json['mtime'] as num?)?.toInt(),
|
|
||||||
stats: json['stats'] == null
|
|
||||||
? null
|
|
||||||
: Stats.fromJson(json['stats'] as Map<String, dynamic>),
|
|
||||||
attributes: (json['attributes'] as num?)?.toInt(),
|
|
||||||
words: (json['words'] as num?)?.toInt(),
|
|
||||||
originImageUrls: (json['origin_image_urls'] as List<dynamic>?)
|
|
||||||
?.map((e) => e as String)
|
|
||||||
.toList(),
|
|
||||||
list: json['list'],
|
|
||||||
isLike: json['is_like'] as bool?,
|
|
||||||
media: json['media'] == null
|
|
||||||
? null
|
|
||||||
: Media.fromJson(json['media'] as Map<String, dynamic>),
|
|
||||||
applyTime: json['apply_time'] as String?,
|
|
||||||
checkTime: json['check_time'] as String?,
|
|
||||||
original: (json['original'] as num?)?.toInt(),
|
|
||||||
actId: (json['act_id'] as num?)?.toInt(),
|
|
||||||
dispute: json['dispute'],
|
|
||||||
authenMark: json['authenMark'],
|
|
||||||
coverAvid: (json['cover_avid'] as num?)?.toInt(),
|
|
||||||
topVideoInfo: json['top_video_info'],
|
|
||||||
type: (json['type'] as num?)?.toInt(),
|
|
||||||
checkState: (json['check_state'] as num?)?.toInt(),
|
|
||||||
originTemplateId: (json['origin_template_id'] as num?)?.toInt(),
|
|
||||||
uri: json['uri'] as String?,
|
|
||||||
param: json['param'] as String?,
|
|
||||||
goto: json['goto'] as String?,
|
|
||||||
publishTimeText: json['publish_time_text'] as String?,
|
|
||||||
dyn: json['dynamic'] as String?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> _$ItemToJson(Item instance) => <String, dynamic>{
|
|
||||||
'id': instance.id,
|
|
||||||
'category': instance.category,
|
|
||||||
'categories': instance.categories,
|
|
||||||
'title': instance.title,
|
|
||||||
'summary': instance.summary,
|
|
||||||
'banner_url': instance.bannerUrl,
|
|
||||||
'template_id': instance.templateId,
|
|
||||||
'state': instance.state,
|
|
||||||
'author': instance.author,
|
|
||||||
'reprint': instance.reprint,
|
|
||||||
'image_urls': instance.imageUrls,
|
|
||||||
'publish_time': instance.publishTime,
|
|
||||||
'ctime': instance.ctime,
|
|
||||||
'mtime': instance.mtime,
|
|
||||||
'stats': instance.stats,
|
|
||||||
'attributes': instance.attributes,
|
|
||||||
'words': instance.words,
|
|
||||||
'origin_image_urls': instance.originImageUrls,
|
|
||||||
'list': instance.list,
|
|
||||||
'is_like': instance.isLike,
|
|
||||||
'media': instance.media,
|
|
||||||
'apply_time': instance.applyTime,
|
|
||||||
'check_time': instance.checkTime,
|
|
||||||
'original': instance.original,
|
|
||||||
'act_id': instance.actId,
|
|
||||||
'dispute': instance.dispute,
|
|
||||||
'authenMark': instance.authenMark,
|
|
||||||
'cover_avid': instance.coverAvid,
|
|
||||||
'top_video_info': instance.topVideoInfo,
|
|
||||||
'type': instance.type,
|
|
||||||
'check_state': instance.checkState,
|
|
||||||
'origin_template_id': instance.originTemplateId,
|
|
||||||
'uri': instance.uri,
|
|
||||||
'param': instance.param,
|
|
||||||
'goto': instance.goto,
|
|
||||||
'publish_time_text': instance.publishTimeText,
|
|
||||||
'dynamic': instance.dyn,
|
|
||||||
};
|
|
||||||
@@ -3,14 +3,17 @@ import 'package:PiliPlus/http/dynamics.dart';
|
|||||||
import 'package:PiliPlus/http/loading_state.dart';
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
import 'package:PiliPlus/http/user.dart';
|
import 'package:PiliPlus/http/user.dart';
|
||||||
import 'package:PiliPlus/http/video.dart';
|
import 'package:PiliPlus/http/video.dart';
|
||||||
import 'package:PiliPlus/models/dynamics/article_view/data.dart';
|
import 'package:PiliPlus/models/dynamics/article_content_model.dart'
|
||||||
import 'package:PiliPlus/models/dynamics/opus_detail/data.dart';
|
show ArticleContentModel;
|
||||||
import 'package:PiliPlus/models/dynamics/opus_detail/favorite.dart';
|
|
||||||
import 'package:PiliPlus/models/dynamics/result.dart';
|
import 'package:PiliPlus/models/dynamics/result.dart';
|
||||||
|
import 'package:PiliPlus/models/model_owner.dart';
|
||||||
|
import 'package:PiliPlus/models/space_article/item.dart';
|
||||||
|
import 'package:PiliPlus/models/space_article/stats.dart';
|
||||||
import 'package:PiliPlus/pages/common/reply_controller.dart';
|
import 'package:PiliPlus/pages/common/reply_controller.dart';
|
||||||
import 'package:PiliPlus/pages/mine/controller.dart';
|
import 'package:PiliPlus/pages/mine/controller.dart';
|
||||||
import 'package:PiliPlus/utils/storage.dart';
|
import 'package:PiliPlus/utils/storage.dart';
|
||||||
import 'package:PiliPlus/utils/url_utils.dart';
|
import 'package:PiliPlus/utils/url_utils.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 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:PiliPlus/http/reply.dart';
|
import 'package:PiliPlus/http/reply.dart';
|
||||||
@@ -20,9 +23,10 @@ class ArticleController extends ReplyController<MainListReply> {
|
|||||||
late String id;
|
late String id;
|
||||||
late String type;
|
late String type;
|
||||||
|
|
||||||
late final String url;
|
late String url;
|
||||||
late int commentType;
|
late int commentType;
|
||||||
dynamic commentId;
|
late int commentId;
|
||||||
|
final summary = Summary();
|
||||||
|
|
||||||
RxBool showTitle = false.obs;
|
RxBool showTitle = false.obs;
|
||||||
|
|
||||||
@@ -30,14 +34,15 @@ class ArticleController extends ReplyController<MainListReply> {
|
|||||||
late final showDynActionBar = GStorage.showDynActionBar;
|
late final showDynActionBar = GStorage.showDynActionBar;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
dynamic get sourceId => id;
|
dynamic get sourceId => commentType == 12 ? 'cv$commentId' : id;
|
||||||
|
|
||||||
RxBool isLoaded = false.obs;
|
final RxBool isLoaded = false.obs;
|
||||||
late ArticleData articleData;
|
DynamicItemModel? opusData; // 采用opus信息作为动态信息, 标题信息从summary获取
|
||||||
late OpusData opusData;
|
Item? articleData;
|
||||||
|
final Rx<ModuleStatModel?> stats = Rx<ModuleStatModel?>(null);
|
||||||
|
|
||||||
late final Rx<DynamicItemModel> item = DynamicItemModel().obs;
|
List<ArticleContentModel>? get opus =>
|
||||||
late final RxMap favStat = <dynamic, dynamic>{'status': false}.obs;
|
opusData?.modules.moduleContent ?? articleData?.opus?.content;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
@@ -45,6 +50,13 @@ class ArticleController extends ReplyController<MainListReply> {
|
|||||||
id = Get.parameters['id']!;
|
id = Get.parameters['id']!;
|
||||||
type = Get.parameters['type']!;
|
type = Get.parameters['type']!;
|
||||||
|
|
||||||
|
if (Get.arguments?['item'] is DynamicItemModel) {
|
||||||
|
opusData = Get.arguments['item'];
|
||||||
|
if (opusData!.modules.moduleStat != null) {
|
||||||
|
stats.value = opusData!.modules.moduleStat!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// to opus
|
// to opus
|
||||||
if (type == 'read') {
|
if (type == 'read') {
|
||||||
UrlUtils.parseRedirectUrl('https://www.bilibili.com/read/cv$id/')
|
UrlUtils.parseRedirectUrl('https://www.bilibili.com/read/cv$id/')
|
||||||
@@ -60,101 +72,92 @@ class ArticleController extends ReplyController<MainListReply> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
setUrl() {
|
||||||
url = type == 'read'
|
url = type == 'read'
|
||||||
? 'https://www.bilibili.com/read/cv$id'
|
? 'https://www.bilibili.com/read/cv$id'
|
||||||
: 'https://www.bilibili.com/opus/$id';
|
: 'https://www.bilibili.com/opus/$id';
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
setUrl();
|
||||||
commentType = type == 'picture' ? 11 : 12;
|
commentType = type == 'picture' ? 11 : 12;
|
||||||
|
|
||||||
if (Get.arguments?['item'] is DynamicItemModel) {
|
|
||||||
item.value = Get.arguments['item'];
|
|
||||||
}
|
|
||||||
|
|
||||||
_queryDynItem();
|
|
||||||
_queryContent();
|
_queryContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
_queryDynItem() async {
|
Future<bool> queryOpus(opusId) async {
|
||||||
if (showDynActionBar) {
|
final res = await DynamicsHttp.opusDetail(opusId: opusId);
|
||||||
if (type == 'read') {
|
if (res is Success) {
|
||||||
if (item.value.idStr == null) {
|
opusData = (res as Success<DynamicItemModel>).response;
|
||||||
UrlUtils.parseRedirectUrl('https://www.bilibili.com/read/cv$id/')
|
//fallback
|
||||||
.then((url) {
|
if (opusData?.fallback?.id != null) {
|
||||||
if (url != null) {
|
id = opusData!.fallback!.id!;
|
||||||
_queryDyn(url.split('/').last);
|
type = 'read';
|
||||||
}
|
setUrl();
|
||||||
});
|
_queryContent();
|
||||||
}
|
return false;
|
||||||
_queryInfo();
|
|
||||||
} else {
|
|
||||||
_queryDyn(id);
|
|
||||||
}
|
}
|
||||||
|
commentType = opusData!.basic!.commentType!;
|
||||||
|
commentId = int.parse(opusData!.basic!.commentIdStr!);
|
||||||
|
if (showDynActionBar && opusData!.modules.moduleStat != null) {
|
||||||
|
stats.value = opusData!.modules.moduleStat!;
|
||||||
|
}
|
||||||
|
summary
|
||||||
|
..author ??= opusData!.modules.moduleAuthor
|
||||||
|
..title ??= opusData!.modules.moduleTag?.text;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_queryInfo() {
|
Future<bool> queryRead(cvid) async {
|
||||||
DynamicsHttp.articleInfo(cvId: id).then((res) {
|
final res = await DynamicsHttp.articleView(cvId: cvid);
|
||||||
if (res['status']) {
|
if (res is Success) {
|
||||||
favStat.addAll({
|
articleData = (res as Success<Item>).response;
|
||||||
'status': true,
|
summary
|
||||||
'isFav': res['data']?['favorite'] ?? false,
|
..author ??= articleData!.author
|
||||||
'favNum': res['data']?['stats']?['favorite'] ?? 0,
|
..title ??= articleData!.title
|
||||||
'data': res['data'],
|
..cover ??= articleData!.originImageUrls?.firstOrNull;
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_queryDyn(id) {
|
if (showDynActionBar && opusData?.modules.moduleStat == null) {
|
||||||
if (item.value.idStr != null) {
|
final dynId = articleData!.dynIdStr;
|
||||||
return;
|
if (dynId != null) {
|
||||||
}
|
_queryReadAsDyn(dynId);
|
||||||
DynamicsHttp.dynamicDetail(id: id).then((res) {
|
|
||||||
if (res['status']) {
|
|
||||||
item.value = res['data'];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Future _queryContent() async {
|
|
||||||
final res = type == 'read'
|
|
||||||
? await DynamicsHttp.articleView(cvId: id)
|
|
||||||
: await DynamicsHttp.opusDetail(opusId: id);
|
|
||||||
if (res['status']) {
|
|
||||||
if (type == 'read') {
|
|
||||||
articleData = res['data'];
|
|
||||||
commentId = int.parse(id);
|
|
||||||
} else {
|
|
||||||
opusData = res['data'];
|
|
||||||
// fallback
|
|
||||||
if (opusData.fallback?.id != null) {
|
|
||||||
id = opusData.fallback!.id!;
|
|
||||||
type = 'read';
|
|
||||||
commentType = 12;
|
|
||||||
_queryInfo();
|
|
||||||
_queryContent();
|
|
||||||
return;
|
|
||||||
} else {
|
} else {
|
||||||
commentType = opusData.item?.basic?.commentType ??
|
debugPrint('cvid2opus failed: $id');
|
||||||
(type == 'picture' ? 11 : 12);
|
|
||||||
commentId = int.parse(opusData.item!.basic!.commentIdStr!);
|
|
||||||
Favorite? favorite =
|
|
||||||
opusData.item?.modules?.lastOrNull?.moduleStat?.favorite;
|
|
||||||
favStat.addAll({
|
|
||||||
'status': true,
|
|
||||||
'isFav': favorite?.status ?? false,
|
|
||||||
'favNum': favorite?.count ?? 0,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
_statsToModuleStat(articleData!.stats!);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
isLoaded.value = true;
|
_queryReadAsDyn(id) async {
|
||||||
|
// 仅用于获取moduleStat
|
||||||
|
final res = await DynamicsHttp.dynamicDetail(id: id);
|
||||||
|
if (res['status']) {
|
||||||
|
opusData = res['data'] as DynamicItemModel;
|
||||||
|
if (opusData!.modules.moduleStat != null) {
|
||||||
|
stats.value = opusData!.modules.moduleStat!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 请求动态内容
|
||||||
|
Future _queryContent() async {
|
||||||
|
if (type != 'read') {
|
||||||
|
isLoaded.value = await queryOpus(id);
|
||||||
|
} else {
|
||||||
|
commentId = int.parse(id);
|
||||||
|
commentType = 12;
|
||||||
|
isLoaded.value = await queryRead(commentId);
|
||||||
|
}
|
||||||
|
if (isLoaded.value) {
|
||||||
|
queryData();
|
||||||
if (isLogin && !MineController.anonymity.value) {
|
if (isLogin && !MineController.anonymity.value) {
|
||||||
VideoHttp.historyReport(aid: commentId, type: 5);
|
VideoHttp.historyReport(aid: commentId, type: 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
queryData();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,22 +180,48 @@ class ArticleController extends ReplyController<MainListReply> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future onFav() async {
|
Future onFav() async {
|
||||||
bool isFav = favStat['isFav'] == true;
|
bool isFav = stats.value?.favorite?.status == true;
|
||||||
final res = type == 'read'
|
final res = type == 'read'
|
||||||
? isFav
|
? isFav
|
||||||
? await UserHttp.delFavArticle(id: id)
|
? await UserHttp.delFavArticle(id: commentId)
|
||||||
: await UserHttp.addFavArticle(id: id)
|
: await UserHttp.addFavArticle(id: commentId)
|
||||||
: await UserHttp.communityAction(opusId: id, action: isFav ? 4 : 3);
|
: await UserHttp.communityAction(opusId: id, action: isFav ? 4 : 3);
|
||||||
if (res['status']) {
|
if (res['status']) {
|
||||||
favStat['isFav'] = !isFav;
|
stats.value?.favorite?.status = !isFav;
|
||||||
|
var count = stats.value?.favorite?.count ?? 0;
|
||||||
if (isFav) {
|
if (isFav) {
|
||||||
favStat['favNum'] -= 1;
|
stats.value?.favorite?.count = count - 1;
|
||||||
} else {
|
} else {
|
||||||
favStat['favNum'] += 1;
|
stats.value?.favorite?.count = count + 1;
|
||||||
}
|
}
|
||||||
|
stats.refresh();
|
||||||
SmartDialog.showToast('${isFav ? '取消' : ''}收藏成功');
|
SmartDialog.showToast('${isFav ? '取消' : ''}收藏成功');
|
||||||
} else {
|
} else {
|
||||||
SmartDialog.showToast(res['msg']);
|
SmartDialog.showToast(res['msg']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _statsToModuleStat(Stats dynStats) {
|
||||||
|
if (stats.value == null) {
|
||||||
|
stats.value = ModuleStatModel(
|
||||||
|
comment: _setCount(dynStats.reply),
|
||||||
|
forward: _setCount(dynStats.dyn),
|
||||||
|
like: _setCount(dynStats.like),
|
||||||
|
favorite: _setCount(dynStats.favorite),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// 动态类无收藏数据
|
||||||
|
stats.value!.favorite ??= _setCount(dynStats.favorite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicStat _setCount(int? count) => DynamicStat(count: count);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Summary {
|
||||||
|
Owner? author;
|
||||||
|
String? title;
|
||||||
|
String? cover;
|
||||||
|
|
||||||
|
Summary({this.author, this.title, this.cover});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:PiliPlus/common/widgets/network_img_layer.dart';
|
import 'package:PiliPlus/common/widgets/network_img_layer.dart';
|
||||||
|
import 'package:PiliPlus/models/dynamics/result.dart' show DynamicStat;
|
||||||
import 'package:PiliPlus/pages/article/widgets/opus_content.dart';
|
import 'package:PiliPlus/pages/article/widgets/opus_content.dart';
|
||||||
import 'package:PiliPlus/pages/article/widgets/html_render.dart';
|
import 'package:PiliPlus/pages/article/widgets/html_render.dart';
|
||||||
import 'package:PiliPlus/common/widgets/http_error.dart';
|
import 'package:PiliPlus/common/widgets/http_error.dart';
|
||||||
@@ -338,101 +339,98 @@ class _ArticlePageState extends State<ArticlePage>
|
|||||||
sliver: Obx(
|
sliver: Obx(
|
||||||
() {
|
() {
|
||||||
if (_articleCtr.isLoaded.value) {
|
if (_articleCtr.isLoaded.value) {
|
||||||
if (_articleCtr.type == 'read') {
|
late Widget content;
|
||||||
late final res = parser.parse(_articleCtr.articleData.content);
|
if (_articleCtr.opus == null) {
|
||||||
return SliverMainAxisGroup(
|
debugPrint('html page');
|
||||||
slivers: [
|
final res = parser.parse(_articleCtr.articleData!.content!);
|
||||||
if (_articleCtr.articleData.title != null)
|
content = SliverList.separated(
|
||||||
SliverToBoxAdapter(
|
itemCount: res.body!.children.length,
|
||||||
child: Text(
|
itemBuilder: (context, index) {
|
||||||
_articleCtr.articleData.title!,
|
return htmlRender(
|
||||||
style: TextStyle(
|
context: context,
|
||||||
fontSize: 17,
|
element: res.body!.children[index],
|
||||||
fontWeight: FontWeight.bold,
|
maxWidth: maxWidth,
|
||||||
),
|
callback: _getImageCallback,
|
||||||
),
|
);
|
||||||
),
|
},
|
||||||
SliverToBoxAdapter(
|
separatorBuilder: (context, index) =>
|
||||||
child: Padding(
|
const SizedBox(height: 10),
|
||||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
|
||||||
child: GestureDetector(
|
|
||||||
onTap: () {
|
|
||||||
Get.toNamed(
|
|
||||||
'/member?mid=${_articleCtr.articleData.author?.mid}');
|
|
||||||
},
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
NetworkImgLayer(
|
|
||||||
width: 40,
|
|
||||||
height: 40,
|
|
||||||
type: 'avatar',
|
|
||||||
src: _articleCtr.articleData.author?.face,
|
|
||||||
),
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
_articleCtr.articleData.author?.name ?? "",
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: Theme.of(context)
|
|
||||||
.textTheme
|
|
||||||
.titleSmall!
|
|
||||||
.fontSize,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (_articleCtr.articleData.publishTime !=
|
|
||||||
null)
|
|
||||||
Text(
|
|
||||||
Utils.dateFormat(
|
|
||||||
_articleCtr.articleData.publishTime),
|
|
||||||
style: TextStyle(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.colorScheme
|
|
||||||
.outline,
|
|
||||||
fontSize: Theme.of(context)
|
|
||||||
.textTheme
|
|
||||||
.labelSmall!
|
|
||||||
.fontSize,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
_articleCtr.articleData.modules?.isNotEmpty == true
|
|
||||||
? opusContent(
|
|
||||||
context: context,
|
|
||||||
modules: _articleCtr.articleData.modules,
|
|
||||||
callback: _getImageCallback,
|
|
||||||
maxWidth: maxWidth,
|
|
||||||
)
|
|
||||||
: SliverList.separated(
|
|
||||||
itemCount: res.body!.children.length,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
return htmlRender(
|
|
||||||
context: context,
|
|
||||||
element: res.body!.children[index],
|
|
||||||
maxWidth: maxWidth,
|
|
||||||
callback: _getImageCallback,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
separatorBuilder: (context, index) =>
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return opusContent(
|
debugPrint('json page');
|
||||||
|
content = opusContent(
|
||||||
context: context,
|
context: context,
|
||||||
modules: _articleCtr.opusData.item?.modules,
|
opus: _articleCtr.opus!,
|
||||||
callback: _getImageCallback,
|
callback: _getImageCallback,
|
||||||
maxWidth: maxWidth,
|
maxWidth: maxWidth,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int? pubTime =
|
||||||
|
_articleCtr.opusData?.modules.moduleAuthor?.pubTs ??
|
||||||
|
_articleCtr.articleData?.publishTime;
|
||||||
|
return SliverMainAxisGroup(
|
||||||
|
slivers: [
|
||||||
|
if (_articleCtr.summary.title != null)
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: Text(
|
||||||
|
_articleCtr.summary.title!,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 17,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () => Get.toNamed(
|
||||||
|
'/member?mid=${_articleCtr.summary.author?.mid}'),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
NetworkImgLayer(
|
||||||
|
// TODO Avatar
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
type: 'avatar',
|
||||||
|
src: _articleCtr.summary.author?.face,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
_articleCtr.summary.author?.name ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.titleSmall!
|
||||||
|
.fontSize,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (pubTime != null)
|
||||||
|
Text(
|
||||||
|
Utils.dateFormat(pubTime),
|
||||||
|
style: TextStyle(
|
||||||
|
color:
|
||||||
|
Theme.of(context).colorScheme.outline,
|
||||||
|
fontSize: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.labelSmall!
|
||||||
|
.fontSize,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
content,
|
||||||
|
],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return const SliverToBoxAdapter();
|
return const SliverToBoxAdapter();
|
||||||
@@ -543,11 +541,7 @@ class _ArticlePageState extends State<ArticlePage>
|
|||||||
PreferredSizeWidget get _buildAppBar => AppBar(
|
PreferredSizeWidget get _buildAppBar => AppBar(
|
||||||
title: Obx(() {
|
title: Obx(() {
|
||||||
if (_articleCtr.isLoaded.value && _articleCtr.showTitle.value) {
|
if (_articleCtr.isLoaded.value && _articleCtr.showTitle.value) {
|
||||||
return Text(_articleCtr.type == 'read'
|
return Text(_articleCtr.summary.title ?? '');
|
||||||
? _articleCtr.articleData.title ?? ''
|
|
||||||
: _articleCtr.opusData.item?.modules?.firstOrNull?.moduleTitle
|
|
||||||
?.text ??
|
|
||||||
'');
|
|
||||||
}
|
}
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}),
|
}),
|
||||||
@@ -628,23 +622,21 @@ class _ArticlePageState extends State<ArticlePage>
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (_articleCtr.type == 'read' && _articleCtr.favStat['status'])
|
if (_articleCtr.commentType == 12 &&
|
||||||
|
_articleCtr.stats.value != null)
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
try {
|
try {
|
||||||
PageUtils.pmShare(
|
PageUtils.pmShare(
|
||||||
content: {
|
content: {
|
||||||
"id": _articleCtr.id,
|
"id": _articleCtr.commentId,
|
||||||
"title": "- 哔哩哔哩专栏",
|
"title": "- 哔哩哔哩专栏",
|
||||||
"headline": _articleCtr.favStat['data']['title'],
|
"headline": _articleCtr.summary.title!, // throw
|
||||||
"source": 6,
|
"source": 6,
|
||||||
"thumb": (_articleCtr.favStat['data']
|
"thumb": _articleCtr.summary.cover!,
|
||||||
['origin_image_urls'] as List?)
|
"author": _articleCtr.summary.author!.name,
|
||||||
?.firstOrNull ??
|
|
||||||
'',
|
|
||||||
"author": _articleCtr.favStat['data']['author_name'],
|
|
||||||
"author_id":
|
"author_id":
|
||||||
_articleCtr.favStat['data']['mid'].toString(),
|
_articleCtr.summary.author!.mid.toString(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -704,8 +696,38 @@ class _ArticlePageState extends State<ArticlePage>
|
|||||||
child: button(),
|
child: button(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: Obx(
|
: Obx(() {
|
||||||
() => Column(
|
Widget textIconButton({
|
||||||
|
required IconData icon,
|
||||||
|
required String text,
|
||||||
|
required DynamicStat? stat,
|
||||||
|
required VoidCallback callback,
|
||||||
|
IconData? activitedIcon,
|
||||||
|
}) {
|
||||||
|
final show = stat?.status == true;
|
||||||
|
final color = show
|
||||||
|
? Theme.of(context).colorScheme.primary
|
||||||
|
: Theme.of(context).colorScheme.outline;
|
||||||
|
return TextButton.icon(
|
||||||
|
onPressed: callback,
|
||||||
|
icon: Icon(
|
||||||
|
stat?.status == true ? activitedIcon : icon,
|
||||||
|
size: 16,
|
||||||
|
color: color,
|
||||||
|
semanticLabel: text,
|
||||||
|
),
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||||
|
foregroundColor:
|
||||||
|
Theme.of(context).colorScheme.outline,
|
||||||
|
),
|
||||||
|
label: Text(stat?.count != null
|
||||||
|
? Utils.numFormat(stat!.count)
|
||||||
|
: text),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
@@ -713,13 +735,13 @@ class _ArticlePageState extends State<ArticlePage>
|
|||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
right: 14,
|
right: 14,
|
||||||
bottom: 14 +
|
bottom: 14 +
|
||||||
(_articleCtr.favStat['status']
|
(_articleCtr.stats.value != null
|
||||||
? 0
|
? 0
|
||||||
: MediaQuery.of(context).padding.bottom),
|
: MediaQuery.of(context).padding.bottom),
|
||||||
),
|
),
|
||||||
child: button(),
|
child: button(),
|
||||||
),
|
),
|
||||||
_articleCtr.favStat['status']
|
_articleCtr.stats.value != null
|
||||||
? Container(
|
? Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color:
|
color:
|
||||||
@@ -743,34 +765,36 @@ class _ArticlePageState extends State<ArticlePage>
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: Builder(
|
child: Builder(
|
||||||
builder: (btnContext) =>
|
builder: (btnContext) =>
|
||||||
TextButton.icon(
|
textIconButton(
|
||||||
onPressed: () {
|
text: '转发',
|
||||||
|
icon: FontAwesomeIcons
|
||||||
|
.shareFromSquare,
|
||||||
|
stat: _articleCtr
|
||||||
|
.stats.value?.forward,
|
||||||
|
callback: () {
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
isScrollControlled: true,
|
isScrollControlled: true,
|
||||||
useSafeArea: true,
|
useSafeArea: true,
|
||||||
builder: (context) =>
|
builder: (context) =>
|
||||||
RepostPanel(
|
RepostPanel(
|
||||||
item: _articleCtr.item.value,
|
item: _articleCtr.opusData,
|
||||||
|
pic:
|
||||||
|
_articleCtr.summary.cover,
|
||||||
|
title:
|
||||||
|
_articleCtr.summary.title,
|
||||||
callback: () {
|
callback: () {
|
||||||
int count = int.tryParse(
|
int count = _articleCtr
|
||||||
_articleCtr
|
.stats
|
||||||
.item
|
.value
|
||||||
.value
|
?.forward
|
||||||
.modules
|
?.count ??
|
||||||
?.moduleStat
|
|
||||||
?.forward
|
|
||||||
?.count ??
|
|
||||||
'0') ??
|
|
||||||
0;
|
0;
|
||||||
_articleCtr
|
_articleCtr
|
||||||
.item
|
.stats
|
||||||
.value
|
.value
|
||||||
.modules
|
?.forward
|
||||||
?.moduleStat
|
?.count = count + 1;
|
||||||
?.forward!
|
|
||||||
.count =
|
|
||||||
(count + 1).toString();
|
|
||||||
if (btnContext.mounted) {
|
if (btnContext.mounted) {
|
||||||
(btnContext as Element?)
|
(btnContext as Element?)
|
||||||
?.markNeedsBuild();
|
?.markNeedsBuild();
|
||||||
@@ -779,108 +803,34 @@ class _ArticlePageState extends State<ArticlePage>
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
icon: Icon(
|
|
||||||
FontAwesomeIcons.shareFromSquare,
|
|
||||||
size: 16,
|
|
||||||
color: Theme.of(context)
|
|
||||||
.colorScheme
|
|
||||||
.outline,
|
|
||||||
semanticLabel: "转发",
|
|
||||||
),
|
|
||||||
style: TextButton.styleFrom(
|
|
||||||
padding:
|
|
||||||
const EdgeInsets.fromLTRB(
|
|
||||||
15, 0, 15, 0),
|
|
||||||
foregroundColor: Theme.of(context)
|
|
||||||
.colorScheme
|
|
||||||
.outline,
|
|
||||||
),
|
|
||||||
label: Text(
|
|
||||||
_articleCtr
|
|
||||||
.item
|
|
||||||
.value
|
|
||||||
.modules
|
|
||||||
?.moduleStat
|
|
||||||
?.forward!
|
|
||||||
.count !=
|
|
||||||
null
|
|
||||||
? Utils.numFormat(_articleCtr
|
|
||||||
.item
|
|
||||||
.value
|
|
||||||
.modules
|
|
||||||
?.moduleStat
|
|
||||||
?.forward!
|
|
||||||
.count)
|
|
||||||
: '转发',
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TextButton.icon(
|
child: textIconButton(
|
||||||
onPressed: () {
|
text: '分享',
|
||||||
Utils.shareText(_articleCtr.url);
|
icon: FontAwesomeIcons.shareNodes,
|
||||||
},
|
stat: null,
|
||||||
icon: Icon(
|
callback: () =>
|
||||||
FontAwesomeIcons.shareNodes,
|
Utils.shareText(_articleCtr.url),
|
||||||
size: 16,
|
)),
|
||||||
color: Theme.of(context)
|
if (_articleCtr.stats.value != null)
|
||||||
.colorScheme
|
|
||||||
.outline,
|
|
||||||
semanticLabel: "分享",
|
|
||||||
),
|
|
||||||
style: TextButton.styleFrom(
|
|
||||||
padding: const EdgeInsets.fromLTRB(
|
|
||||||
15, 0, 15, 0),
|
|
||||||
foregroundColor: Theme.of(context)
|
|
||||||
.colorScheme
|
|
||||||
.outline,
|
|
||||||
),
|
|
||||||
label: const Text('分享'),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (_articleCtr.favStat['status'])
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TextButton.icon(
|
child: textIconButton(
|
||||||
onPressed: () {
|
icon: FontAwesomeIcons.star,
|
||||||
_articleCtr.onFav();
|
activitedIcon:
|
||||||
},
|
FontAwesomeIcons.solidStar,
|
||||||
icon: Icon(
|
text: '收藏',
|
||||||
_articleCtr.favStat['isFav'] ==
|
stat:
|
||||||
true
|
_articleCtr.stats.value!.favorite,
|
||||||
? FontAwesomeIcons.solidStar
|
callback: _articleCtr.onFav,
|
||||||
: FontAwesomeIcons.star,
|
)),
|
||||||
size: 16,
|
|
||||||
color: _articleCtr
|
|
||||||
.favStat['isFav'] ==
|
|
||||||
true
|
|
||||||
? Theme.of(context)
|
|
||||||
.colorScheme
|
|
||||||
.primary
|
|
||||||
: Theme.of(context)
|
|
||||||
.colorScheme
|
|
||||||
.outline,
|
|
||||||
semanticLabel: "收藏",
|
|
||||||
),
|
|
||||||
style: TextButton.styleFrom(
|
|
||||||
padding:
|
|
||||||
const EdgeInsets.fromLTRB(
|
|
||||||
15, 0, 15, 0),
|
|
||||||
foregroundColor: Theme.of(context)
|
|
||||||
.colorScheme
|
|
||||||
.outline,
|
|
||||||
),
|
|
||||||
label: Text(_articleCtr
|
|
||||||
.favStat['favNum']
|
|
||||||
.toString()),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Builder(
|
child: Builder(
|
||||||
builder: (context) => TextButton.icon(
|
builder: (context) => TextButton.icon(
|
||||||
onPressed: () =>
|
onPressed: () =>
|
||||||
RequestUtils.onLikeDynamic(
|
RequestUtils.onLikeDynamic(
|
||||||
_articleCtr.item.value,
|
_articleCtr.opusData!,
|
||||||
() {
|
() {
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
(context as Element?)
|
(context as Element?)
|
||||||
@@ -889,25 +839,15 @@ class _ArticlePageState extends State<ArticlePage>
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
_articleCtr
|
_articleCtr.stats.value?.like
|
||||||
.item
|
|
||||||
.value
|
|
||||||
.modules
|
|
||||||
?.moduleStat
|
|
||||||
?.like
|
|
||||||
?.status ==
|
?.status ==
|
||||||
true
|
true
|
||||||
? FontAwesomeIcons
|
? FontAwesomeIcons
|
||||||
.solidThumbsUp
|
.solidThumbsUp
|
||||||
: FontAwesomeIcons.thumbsUp,
|
: FontAwesomeIcons.thumbsUp,
|
||||||
size: 16,
|
size: 16,
|
||||||
color: _articleCtr
|
color: _articleCtr.stats.value
|
||||||
.item
|
?.like?.status ==
|
||||||
.value
|
|
||||||
.modules
|
|
||||||
?.moduleStat
|
|
||||||
?.like
|
|
||||||
?.status ==
|
|
||||||
true
|
true
|
||||||
? Theme.of(context)
|
? Theme.of(context)
|
||||||
.colorScheme
|
.colorScheme
|
||||||
@@ -916,10 +856,8 @@ class _ArticlePageState extends State<ArticlePage>
|
|||||||
.colorScheme
|
.colorScheme
|
||||||
.outline,
|
.outline,
|
||||||
semanticLabel: _articleCtr
|
semanticLabel: _articleCtr
|
||||||
.item
|
.stats
|
||||||
.value
|
.value
|
||||||
.modules
|
|
||||||
?.moduleStat
|
|
||||||
?.like
|
?.like
|
||||||
?.status ==
|
?.status ==
|
||||||
true
|
true
|
||||||
@@ -928,8 +866,8 @@ class _ArticlePageState extends State<ArticlePage>
|
|||||||
),
|
),
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
padding:
|
padding:
|
||||||
const EdgeInsets.fromLTRB(
|
const EdgeInsets.symmetric(
|
||||||
15, 0, 15, 0),
|
horizontal: 15),
|
||||||
foregroundColor: Theme.of(context)
|
foregroundColor: Theme.of(context)
|
||||||
.colorScheme
|
.colorScheme
|
||||||
.outline,
|
.outline,
|
||||||
@@ -944,31 +882,16 @@ class _ArticlePageState extends State<ArticlePage>
|
|||||||
child: child);
|
child: child);
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
_articleCtr
|
_articleCtr.stats.value?.like
|
||||||
.item
|
|
||||||
.value
|
|
||||||
.modules
|
|
||||||
?.moduleStat
|
|
||||||
?.like
|
|
||||||
?.count !=
|
?.count !=
|
||||||
null
|
null
|
||||||
? Utils.numFormat(
|
? Utils.numFormat(
|
||||||
_articleCtr
|
_articleCtr.stats.value!
|
||||||
.item
|
.like!.count)
|
||||||
.value
|
|
||||||
.modules!
|
|
||||||
.moduleStat!
|
|
||||||
.like!
|
|
||||||
.count)
|
|
||||||
: '点赞',
|
: '点赞',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: _articleCtr
|
color: _articleCtr.stats.value
|
||||||
.item
|
?.like?.status ==
|
||||||
.value
|
|
||||||
.modules
|
|
||||||
?.moduleStat
|
|
||||||
?.like
|
|
||||||
?.status ==
|
|
||||||
true
|
true
|
||||||
? Theme.of(context)
|
? Theme.of(context)
|
||||||
.colorScheme
|
.colorScheme
|
||||||
@@ -987,8 +910,8 @@ class _ArticlePageState extends State<ArticlePage>
|
|||||||
)
|
)
|
||||||
: const SizedBox.shrink(),
|
: const SizedBox.shrink(),
|
||||||
],
|
],
|
||||||
),
|
);
|
||||||
);
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ Widget htmlRender({
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
debugPrint('错误的HTML: $element');
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,14 +2,14 @@ import 'package:PiliPlus/common/constants.dart';
|
|||||||
import 'package:PiliPlus/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart'
|
import 'package:PiliPlus/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart'
|
||||||
show SourceModel;
|
show SourceModel;
|
||||||
import 'package:PiliPlus/common/widgets/network_img_layer.dart';
|
import 'package:PiliPlus/common/widgets/network_img_layer.dart';
|
||||||
import 'package:PiliPlus/models/dynamics/opus_detail/module.dart';
|
import 'package:PiliPlus/models/dynamics/article_content_model.dart'
|
||||||
|
show ArticleContentModel;
|
||||||
import 'package:PiliPlus/utils/app_scheme.dart';
|
import 'package:PiliPlus/utils/app_scheme.dart';
|
||||||
import 'package:PiliPlus/utils/extension.dart';
|
import 'package:PiliPlus/utils/extension.dart';
|
||||||
import 'package:PiliPlus/utils/utils.dart';
|
import 'package:PiliPlus/utils/utils.dart';
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||||
import 'package:re_highlight/languages/all.dart';
|
import 'package:re_highlight/languages/all.dart';
|
||||||
import 'package:re_highlight/re_highlight.dart';
|
import 'package:re_highlight/re_highlight.dart';
|
||||||
@@ -17,339 +17,257 @@ import 'package:re_highlight/styles/all.dart';
|
|||||||
|
|
||||||
Widget opusContent({
|
Widget opusContent({
|
||||||
required BuildContext context,
|
required BuildContext context,
|
||||||
required List<OpusModule>? modules,
|
required List<ArticleContentModel> opus,
|
||||||
Function(List<String>, int)? callback,
|
Function(List<String>, int)? callback,
|
||||||
required double maxWidth,
|
required double maxWidth,
|
||||||
}) {
|
}) {
|
||||||
debugPrint('opusContent');
|
debugPrint('opusContent');
|
||||||
|
|
||||||
if (modules.isNullOrEmpty) {
|
if (opus.isEmpty) {
|
||||||
return const SliverToBoxAdapter();
|
return const SliverToBoxAdapter();
|
||||||
}
|
}
|
||||||
|
final colorScheme = Theme.of(context).colorScheme;
|
||||||
return SliverMainAxisGroup(
|
return SliverList.separated(
|
||||||
slivers: modules!.map<Widget>((item) {
|
itemCount: opus.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final element = opus[index];
|
||||||
try {
|
try {
|
||||||
return switch (item.moduleType) {
|
switch (element.paraType) {
|
||||||
//
|
case 1 || 4:
|
||||||
'MODULE_TYPE_TITLE' => SliverToBoxAdapter(
|
return SelectableText.rich(
|
||||||
child: Text(
|
textAlign: element.align == 1 ? TextAlign.center : null,
|
||||||
item.moduleTitle!.text!,
|
TextSpan(
|
||||||
style: TextStyle(
|
children: element.text?.nodes?.map<TextSpan>((item) {
|
||||||
fontSize: 17,
|
if (item.rich != null) {
|
||||||
fontWeight: FontWeight.bold,
|
return TextSpan(
|
||||||
|
text: '\u{1F517}${item.rich?.text}',
|
||||||
|
style: TextStyle(
|
||||||
|
decoration: item.rich?.style?.strikethrough == true
|
||||||
|
? TextDecoration.lineThrough
|
||||||
|
: null,
|
||||||
|
fontStyle: item.rich?.style?.italic == true
|
||||||
|
? FontStyle.italic
|
||||||
|
: null,
|
||||||
|
fontWeight: item.rich?.style?.bold == true
|
||||||
|
? FontWeight.bold
|
||||||
|
: null,
|
||||||
|
color: colorScheme.primary,
|
||||||
|
),
|
||||||
|
recognizer: TapGestureRecognizer()
|
||||||
|
..onTap = () {
|
||||||
|
if (item.rich?.jumpUrl != null) {
|
||||||
|
PiliScheme.routePushFromUrl(item.rich!.jumpUrl!);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return TextSpan(
|
||||||
|
text: item.word?.words,
|
||||||
|
style: TextStyle(
|
||||||
|
decoration: item.word?.style?.strikethrough == true
|
||||||
|
? TextDecoration.lineThrough
|
||||||
|
: null,
|
||||||
|
fontStyle: item.word?.style?.italic == true
|
||||||
|
? FontStyle.italic
|
||||||
|
: null,
|
||||||
|
fontWeight:
|
||||||
|
item.word?.style?.bold == true ? FontWeight.bold : null,
|
||||||
|
color: item.word?.color != null
|
||||||
|
? Color(item.word!.color!)
|
||||||
|
: null,
|
||||||
|
fontSize: item.word?.fontSize,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList()),
|
||||||
|
);
|
||||||
|
case 2 when (element.pic != null):
|
||||||
|
element.pic!.pics!.first.onCalHeight(maxWidth);
|
||||||
|
return Hero(
|
||||||
|
tag: element.pic!.pics!.first.url!,
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
if (callback != null) {
|
||||||
|
callback([element.pic!.pics!.first.url!], 0);
|
||||||
|
} else {
|
||||||
|
context.imageView(
|
||||||
|
initialPage: 0,
|
||||||
|
imgList: [
|
||||||
|
SourceModel(url: element.pic!.pics!.first.url!)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: NetworkImgLayer(
|
||||||
|
width: maxWidth,
|
||||||
|
height: element.pic!.pics!.first.calHeight,
|
||||||
|
src: element.pic!.pics!.first.url!,
|
||||||
|
quality: 60,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
|
case 3 when (element.line != null):
|
||||||
//
|
return CachedNetworkImage(
|
||||||
'MODULE_TYPE_AUTHOR' => SliverToBoxAdapter(
|
width: maxWidth,
|
||||||
child: Padding(
|
fit: BoxFit.contain,
|
||||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
height: element.line?.pic?.height?.toDouble(),
|
||||||
child: GestureDetector(
|
imageUrl: Utils.thumbnailImgUrl(element.line!.pic!.url!),
|
||||||
onTap: () {
|
);
|
||||||
Get.toNamed('/member?mid=${item.moduleAuthor?.mid}');
|
case 5 when (element.list != null):
|
||||||
},
|
return SelectableText.rich(
|
||||||
|
TextSpan(
|
||||||
|
children: element.list!.items?.asMap().entries.map((entry) {
|
||||||
|
return TextSpan(
|
||||||
|
children: [
|
||||||
|
WidgetSpan(
|
||||||
|
child: Icon(MdiIcons.circleMedium),
|
||||||
|
alignment: PlaceholderAlignment.middle,
|
||||||
|
),
|
||||||
|
...entry.value.nodes!.map((item) {
|
||||||
|
return TextSpan(
|
||||||
|
children: [
|
||||||
|
TextSpan(
|
||||||
|
text: item.word?.words,
|
||||||
|
style: TextStyle(
|
||||||
|
decoration:
|
||||||
|
item.word?.style?.strikethrough == true
|
||||||
|
? TextDecoration.lineThrough
|
||||||
|
: null,
|
||||||
|
fontStyle: item.word?.style?.italic == true
|
||||||
|
? FontStyle.italic
|
||||||
|
: null,
|
||||||
|
fontWeight: item.word?.style?.bold == true
|
||||||
|
? FontWeight.bold
|
||||||
|
: null,
|
||||||
|
color: item.word?.color != null
|
||||||
|
? Color(item.word!.color!)
|
||||||
|
: null,
|
||||||
|
fontSize: item.word?.fontSize,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
if (entry.key < element.list!.items!.length - 1)
|
||||||
|
const TextSpan(text: '\n'),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
case 6 when (element.linkCard?.card?.ugc != null):
|
||||||
|
return Material(
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(8)),
|
||||||
|
),
|
||||||
|
color: colorScheme.onInverseSurface,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
try {
|
||||||
|
PiliScheme.videoPush(
|
||||||
|
int.parse(element.linkCard!.card!.oid!),
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
} catch (_) {}
|
||||||
|
},
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
NetworkImgLayer(
|
NetworkImgLayer(
|
||||||
width: 40,
|
radius: 6,
|
||||||
height: 40,
|
width: 65 * StyleString.aspectRatio,
|
||||||
type: 'avatar',
|
height: 65,
|
||||||
src: item.moduleAuthor?.face,
|
src: element.linkCard!.card!.ugc!.cover,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
Column(
|
Expanded(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
child: Column(
|
||||||
children: [
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
Text(
|
children: [
|
||||||
item.moduleAuthor!.name!,
|
Text(element.linkCard!.card!.ugc!.title!),
|
||||||
style: TextStyle(
|
|
||||||
fontSize: Theme.of(context)
|
|
||||||
.textTheme
|
|
||||||
.titleSmall!
|
|
||||||
.fontSize,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (item.moduleAuthor?.pubTime != null)
|
|
||||||
Text(
|
Text(
|
||||||
item.moduleAuthor!.pubTime!,
|
element.linkCard!.card!.ugc!.descSecond!,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context).colorScheme.outline,
|
fontSize: 13,
|
||||||
fontSize: Theme.of(context)
|
color: colorScheme.outline,
|
||||||
.textTheme
|
|
||||||
.labelSmall!
|
|
||||||
.fontSize,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
|
case 7 when (element.code != null):
|
||||||
//
|
final Highlight highlight = Highlight()
|
||||||
'MODULE_TYPE_CONTENT' => SliverList.separated(
|
..registerLanguages(builtinAllLanguages);
|
||||||
itemCount: item.moduleContent!.paragraphs!.length,
|
final HighlightResult result = highlight.highlightAuto(
|
||||||
itemBuilder: (context, index) {
|
element.code!.content!,
|
||||||
final element = item.moduleContent!.paragraphs![index];
|
element.code!.lang == 'language-clike'
|
||||||
|
? const ['c', 'java']
|
||||||
if (element.paraType == 1 || element.paraType == 4) {
|
: [
|
||||||
return SelectableText.rich(
|
element.code!.lang!
|
||||||
textAlign: element.align == 1 ? TextAlign.center : null,
|
.replaceAll('language-', '')
|
||||||
TextSpan(
|
.replaceAll('like', ''),
|
||||||
children: element.text?.nodes?.map<TextSpan>((item) {
|
]);
|
||||||
if (item.rich != null) {
|
final TextSpanRenderer renderer = TextSpanRenderer(
|
||||||
return TextSpan(
|
const TextStyle(), builtinAllThemes['github']!);
|
||||||
text: '\u{1F517}${item.rich?.text}',
|
result.render(renderer);
|
||||||
style: TextStyle(
|
return Container(
|
||||||
decoration: item.rich?.style?.strikethrough == true
|
padding: const EdgeInsets.all(12),
|
||||||
? TextDecoration.lineThrough
|
decoration: BoxDecoration(
|
||||||
: null,
|
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||||
fontStyle: item.rich?.style?.italic == true
|
color: colorScheme.onInverseSurface,
|
||||||
? FontStyle.italic
|
),
|
||||||
: null,
|
width: double.infinity,
|
||||||
fontWeight: item.rich?.style?.bold == true
|
child: SelectableText.rich(renderer.span!),
|
||||||
? FontWeight.bold
|
);
|
||||||
: null,
|
default:
|
||||||
color: Theme.of(context).colorScheme.primary,
|
debugPrint('unknown type ${element.paraType}');
|
||||||
),
|
if (element.text?.nodes?.isNotEmpty == true) {
|
||||||
recognizer: TapGestureRecognizer()
|
return SelectableText.rich(
|
||||||
..onTap = () {
|
textAlign: element.align == 1 ? TextAlign.center : null,
|
||||||
if (item.rich?.jumpUrl != null) {
|
TextSpan(
|
||||||
PiliScheme.routePushFromUrl(
|
children: element.text!.nodes!.map<TextSpan>((item) {
|
||||||
item.rich!.jumpUrl!);
|
return TextSpan(
|
||||||
}
|
text: item.word?.words,
|
||||||
},
|
style: TextStyle(
|
||||||
);
|
decoration: item.word?.style?.strikethrough == true
|
||||||
}
|
? TextDecoration.lineThrough
|
||||||
return TextSpan(
|
: null,
|
||||||
text: item.word?.words,
|
fontStyle: item.word?.style?.italic == true
|
||||||
style: TextStyle(
|
? FontStyle.italic
|
||||||
decoration: item.word?.style?.strikethrough == true
|
: null,
|
||||||
? TextDecoration.lineThrough
|
fontWeight: item.word?.style?.bold == true
|
||||||
: null,
|
? FontWeight.bold
|
||||||
fontStyle: item.word?.style?.italic == true
|
: null,
|
||||||
? FontStyle.italic
|
color: item.word?.color != null
|
||||||
: null,
|
? Color(item.word!.color!)
|
||||||
fontWeight: item.word?.style?.bold == true
|
: null,
|
||||||
? FontWeight.bold
|
fontSize: item.word?.fontSize,
|
||||||
: null,
|
|
||||||
color: item.word?.color != null
|
|
||||||
? Color(item.word!.color!)
|
|
||||||
: null,
|
|
||||||
fontSize: item.word?.fontSize,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}).toList()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element.paraType == 2) {
|
|
||||||
element.pic!.pics!.first.onCalHeight(maxWidth);
|
|
||||||
return Hero(
|
|
||||||
tag: element.pic!.pics!.first.url!,
|
|
||||||
child: GestureDetector(
|
|
||||||
onTap: () {
|
|
||||||
if (callback != null) {
|
|
||||||
callback([element.pic!.pics!.first.url!], 0);
|
|
||||||
} else {
|
|
||||||
context.imageView(
|
|
||||||
initialPage: 0,
|
|
||||||
imgList: [
|
|
||||||
SourceModel(url: element.pic!.pics!.first.url!)
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: NetworkImgLayer(
|
|
||||||
width: maxWidth,
|
|
||||||
height: element.pic!.pics!.first.calHeight,
|
|
||||||
src: element.pic!.pics!.first.url!,
|
|
||||||
quality: 60,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}).toList()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (element.paraType == 3) {
|
return SelectableText('不支持的类型 (${element.paraType})',
|
||||||
return CachedNetworkImage(
|
style: const TextStyle(
|
||||||
width: maxWidth,
|
fontWeight: FontWeight.bold,
|
||||||
fit: BoxFit.contain,
|
color: Colors.red,
|
||||||
height: element.line?.pic?.height,
|
));
|
||||||
imageUrl: Utils.thumbnailImgUrl(element.line!.pic!.url!),
|
}
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element.paraType == 5) {
|
|
||||||
return SelectableText.rich(
|
|
||||||
TextSpan(
|
|
||||||
children:
|
|
||||||
element.list?.items?.asMap().entries.map((entry) {
|
|
||||||
return TextSpan(
|
|
||||||
children: [
|
|
||||||
WidgetSpan(
|
|
||||||
child: Icon(MdiIcons.circleMedium),
|
|
||||||
alignment: PlaceholderAlignment.middle,
|
|
||||||
),
|
|
||||||
...entry.value.nodes!.map((item) {
|
|
||||||
return TextSpan(
|
|
||||||
children: [
|
|
||||||
TextSpan(
|
|
||||||
text: item.word?.words,
|
|
||||||
style: TextStyle(
|
|
||||||
decoration:
|
|
||||||
item.word?.style?.strikethrough ==
|
|
||||||
true
|
|
||||||
? TextDecoration.lineThrough
|
|
||||||
: null,
|
|
||||||
fontStyle:
|
|
||||||
item.word?.style?.italic == true
|
|
||||||
? FontStyle.italic
|
|
||||||
: null,
|
|
||||||
fontWeight: item.word?.style?.bold == true
|
|
||||||
? FontWeight.bold
|
|
||||||
: null,
|
|
||||||
color: item.word?.color != null
|
|
||||||
? Color(item.word!.color!)
|
|
||||||
: null,
|
|
||||||
fontSize: item.word?.fontSize,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
if (entry.key < element.list!.items!.length - 1)
|
|
||||||
TextSpan(text: '\n'),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}).toList(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element.paraType == 6) {
|
|
||||||
if (element.linkCard?.card?.ugc != null) {
|
|
||||||
return Material(
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius:
|
|
||||||
const BorderRadius.all(Radius.circular(8)),
|
|
||||||
),
|
|
||||||
color: Theme.of(context).colorScheme.onInverseSurface,
|
|
||||||
child: InkWell(
|
|
||||||
onTap: () {
|
|
||||||
try {
|
|
||||||
PiliScheme.videoPush(
|
|
||||||
int.parse(element.linkCard!.card!.oid!),
|
|
||||||
null,
|
|
||||||
);
|
|
||||||
} catch (_) {}
|
|
||||||
},
|
|
||||||
borderRadius:
|
|
||||||
const BorderRadius.all(Radius.circular(8)),
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(8),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
NetworkImgLayer(
|
|
||||||
radius: 6,
|
|
||||||
width: 65 * StyleString.aspectRatio,
|
|
||||||
height: 65,
|
|
||||||
src: element.linkCard!.card!.ugc!.cover,
|
|
||||||
),
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(element.linkCard!.card!.ugc!.title!),
|
|
||||||
Text(
|
|
||||||
element.linkCard!.card!.ugc!.descSecond!,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 13,
|
|
||||||
color: Theme.of(context)
|
|
||||||
.colorScheme
|
|
||||||
.outline,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element.paraType == 7) {
|
|
||||||
final Highlight highlight = Highlight()
|
|
||||||
..registerLanguages(builtinAllLanguages);
|
|
||||||
final HighlightResult result = highlight.highlightAuto(
|
|
||||||
element.code!.content!,
|
|
||||||
element.code!.lang == 'language-clike'
|
|
||||||
? ['c', 'java']
|
|
||||||
: [
|
|
||||||
element.code!.lang!
|
|
||||||
.replaceAll('language-', '')
|
|
||||||
.replaceAll('like', ''),
|
|
||||||
]);
|
|
||||||
final TextSpanRenderer renderer = TextSpanRenderer(
|
|
||||||
const TextStyle(), builtinAllThemes['github']!);
|
|
||||||
result.render(renderer);
|
|
||||||
return Container(
|
|
||||||
padding: const EdgeInsets.all(12),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
|
||||||
color: Theme.of(context).colorScheme.onInverseSurface,
|
|
||||||
),
|
|
||||||
width: double.infinity,
|
|
||||||
child: SelectableText.rich(renderer.span!),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element.text?.nodes?.isNotEmpty == true) {
|
|
||||||
return SelectableText.rich(
|
|
||||||
textAlign: element.align == 1 ? TextAlign.center : null,
|
|
||||||
TextSpan(
|
|
||||||
children: element.text!.nodes!.map<TextSpan>((item) {
|
|
||||||
return TextSpan(
|
|
||||||
text: item.word?.words,
|
|
||||||
style: TextStyle(
|
|
||||||
decoration: item.word?.style?.strikethrough == true
|
|
||||||
? TextDecoration.lineThrough
|
|
||||||
: null,
|
|
||||||
fontStyle: item.word?.style?.italic == true
|
|
||||||
? FontStyle.italic
|
|
||||||
: null,
|
|
||||||
fontWeight: item.word?.style?.bold == true
|
|
||||||
? FontWeight.bold
|
|
||||||
: null,
|
|
||||||
color: item.word?.color != null
|
|
||||||
? Color(item.word!.color!)
|
|
||||||
: null,
|
|
||||||
fontSize: item.word?.fontSize,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}).toList()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return const SizedBox.shrink();
|
|
||||||
},
|
|
||||||
separatorBuilder: (BuildContext context, int index) =>
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
),
|
|
||||||
|
|
||||||
//
|
|
||||||
_ => const SliverToBoxAdapter(),
|
|
||||||
};
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return SliverToBoxAdapter(child: Text(e.toString()));
|
return SelectableText('错误的类型 $e',
|
||||||
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.red,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}).toList(),
|
},
|
||||||
|
separatorBuilder: (context, index) => const SizedBox(height: 10),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import 'package:PiliPlus/grpc/app/main/community/reply/v1/reply.pb.dart';
|
|||||||
import 'package:PiliPlus/http/dynamics.dart';
|
import 'package:PiliPlus/http/dynamics.dart';
|
||||||
import 'package:PiliPlus/http/loading_state.dart';
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
import 'package:PiliPlus/models/common/reply_type.dart';
|
import 'package:PiliPlus/models/common/reply_type.dart';
|
||||||
import 'package:PiliPlus/models/dynamics/opus_detail/data.dart';
|
|
||||||
import 'package:PiliPlus/models/dynamics/result.dart';
|
import 'package:PiliPlus/models/dynamics/result.dart';
|
||||||
import 'package:PiliPlus/pages/common/reply_controller.dart';
|
import 'package:PiliPlus/pages/common/reply_controller.dart';
|
||||||
import 'package:PiliPlus/utils/id_utils.dart';
|
import 'package:PiliPlus/utils/id_utils.dart';
|
||||||
@@ -31,7 +30,7 @@ class DynamicDetailController extends ReplyController<MainListReply> {
|
|||||||
item = Get.arguments['item'];
|
item = Get.arguments['item'];
|
||||||
floor = Get.arguments['floor'];
|
floor = Get.arguments['floor'];
|
||||||
if (floor == 1) {
|
if (floor == 1) {
|
||||||
count.value = int.parse(item.modules!.moduleStat!.comment!.count ?? '0');
|
count.value = item.modules.moduleStat?.comment?.count ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oid != 0) {
|
if (oid != 0) {
|
||||||
@@ -41,10 +40,10 @@ class DynamicDetailController extends ReplyController<MainListReply> {
|
|||||||
|
|
||||||
getCommentParams(int id) async {
|
getCommentParams(int id) async {
|
||||||
var res = await DynamicsHttp.opusDetail(opusId: id);
|
var res = await DynamicsHttp.opusDetail(opusId: id);
|
||||||
if (res['status']) {
|
if (res is Success) {
|
||||||
OpusData data = res['data'];
|
final data = (res as Success<DynamicItemModel>).response;
|
||||||
type = data.item!.basic!.commentType!;
|
type = data.basic!.commentType!;
|
||||||
oid = int.parse(data.item!.basic!.commentIdStr!);
|
oid = int.parse(data.basic!.commentIdStr!);
|
||||||
queryData();
|
queryData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,14 +118,15 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
|||||||
// 楼层
|
// 楼层
|
||||||
int floor = args['floor'];
|
int floor = args['floor'];
|
||||||
// 评论类型
|
// 评论类型
|
||||||
int commentType = args['item'].basic!['comment_type'] ?? 11;
|
final item = args['item'] as DynamicItemModel;
|
||||||
|
int commentType = item.basic?.commentType ?? 11;
|
||||||
replyType = (commentType == 0) ? 11 : commentType;
|
replyType = (commentType == 0) ? 11 : commentType;
|
||||||
|
|
||||||
if (floor == 1) {
|
if (floor == 1) {
|
||||||
oid = int.parse(args['item'].basic!['comment_id_str']);
|
oid = int.parse(item.basic!.commentIdStr!);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
ModuleDynamicModel moduleDynamic = args['item'].modules.moduleDynamic;
|
final moduleDynamic = item.modules.moduleDynamic!;
|
||||||
String majorType = moduleDynamic.major!.type!;
|
String majorType = moduleDynamic.major!.type!;
|
||||||
|
|
||||||
if (majorType == 'MAJOR_TYPE_OPUS') {
|
if (majorType == 'MAJOR_TYPE_OPUS') {
|
||||||
@@ -528,32 +529,31 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
|||||||
item: _dynamicDetailController
|
item: _dynamicDetailController
|
||||||
.item,
|
.item,
|
||||||
callback: () {
|
callback: () {
|
||||||
int count = int.tryParse(
|
int count =
|
||||||
_dynamicDetailController
|
_dynamicDetailController
|
||||||
.item
|
.item
|
||||||
.modules
|
.modules
|
||||||
?.moduleStat
|
.moduleStat
|
||||||
?.forward
|
?.forward
|
||||||
?.count ??
|
?.count ??
|
||||||
'0') ??
|
0;
|
||||||
0;
|
|
||||||
_dynamicDetailController
|
_dynamicDetailController
|
||||||
.item
|
.item
|
||||||
.modules
|
.modules
|
||||||
?.moduleStat ??=
|
.moduleStat ??=
|
||||||
ModuleStatModel();
|
ModuleStatModel();
|
||||||
_dynamicDetailController
|
|
||||||
.item
|
|
||||||
.modules!
|
|
||||||
.moduleStat
|
|
||||||
?.forward ??= ForWard();
|
|
||||||
_dynamicDetailController
|
_dynamicDetailController
|
||||||
.item
|
.item
|
||||||
.modules!
|
.modules
|
||||||
.moduleStat!
|
.moduleStat
|
||||||
.forward!
|
?.forward ??=
|
||||||
.count =
|
DynamicStat();
|
||||||
(count + 1).toString();
|
_dynamicDetailController
|
||||||
|
.item
|
||||||
|
.modules
|
||||||
|
.moduleStat!
|
||||||
|
.forward!
|
||||||
|
.count = count + 1;
|
||||||
if (btnContext.mounted) {
|
if (btnContext.mounted) {
|
||||||
(btnContext as Element?)
|
(btnContext as Element?)
|
||||||
?.markNeedsBuild();
|
?.markNeedsBuild();
|
||||||
@@ -581,14 +581,14 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
|||||||
_dynamicDetailController
|
_dynamicDetailController
|
||||||
.item
|
.item
|
||||||
.modules
|
.modules
|
||||||
?.moduleStat
|
.moduleStat
|
||||||
?.forward
|
?.forward
|
||||||
?.count !=
|
?.count !=
|
||||||
null
|
null
|
||||||
? Utils.numFormat(
|
? Utils.numFormat(
|
||||||
_dynamicDetailController
|
_dynamicDetailController
|
||||||
.item
|
.item
|
||||||
.modules!
|
.modules
|
||||||
.moduleStat!
|
.moduleStat!
|
||||||
.forward!
|
.forward!
|
||||||
.count)
|
.count)
|
||||||
@@ -638,7 +638,7 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
|||||||
_dynamicDetailController
|
_dynamicDetailController
|
||||||
.item
|
.item
|
||||||
.modules
|
.modules
|
||||||
?.moduleStat
|
.moduleStat
|
||||||
?.like
|
?.like
|
||||||
?.status ==
|
?.status ==
|
||||||
true
|
true
|
||||||
@@ -648,7 +648,7 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
|||||||
color: _dynamicDetailController
|
color: _dynamicDetailController
|
||||||
.item
|
.item
|
||||||
.modules
|
.modules
|
||||||
?.moduleStat
|
.moduleStat
|
||||||
?.like
|
?.like
|
||||||
?.status ==
|
?.status ==
|
||||||
true
|
true
|
||||||
@@ -662,7 +662,7 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
|||||||
_dynamicDetailController
|
_dynamicDetailController
|
||||||
.item
|
.item
|
||||||
.modules
|
.modules
|
||||||
?.moduleStat
|
.moduleStat
|
||||||
?.like
|
?.like
|
||||||
?.status ==
|
?.status ==
|
||||||
true
|
true
|
||||||
@@ -689,14 +689,14 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
|||||||
_dynamicDetailController
|
_dynamicDetailController
|
||||||
.item
|
.item
|
||||||
.modules
|
.modules
|
||||||
?.moduleStat
|
.moduleStat
|
||||||
?.like
|
?.like
|
||||||
?.count !=
|
?.count !=
|
||||||
null
|
null
|
||||||
? Utils.numFormat(
|
? Utils.numFormat(
|
||||||
_dynamicDetailController
|
_dynamicDetailController
|
||||||
.item
|
.item
|
||||||
.modules!
|
.modules
|
||||||
.moduleStat!
|
.moduleStat!
|
||||||
.like!
|
.like!
|
||||||
.count)
|
.count)
|
||||||
@@ -705,7 +705,7 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
|||||||
color: _dynamicDetailController
|
color: _dynamicDetailController
|
||||||
.item
|
.item
|
||||||
.modules
|
.modules
|
||||||
?.moduleStat
|
.moduleStat
|
||||||
?.like
|
?.like
|
||||||
?.status ==
|
?.status ==
|
||||||
true
|
true
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class RepostPanel extends CommonPublishPage {
|
|||||||
final String? uname;
|
final String? uname;
|
||||||
final bool? isMax;
|
final bool? isMax;
|
||||||
|
|
||||||
final dynamic item;
|
final DynamicItemModel? item;
|
||||||
final VoidCallback? callback;
|
final VoidCallback? callback;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -44,53 +44,19 @@ class RepostPanel extends CommonPublishPage {
|
|||||||
class _RepostPanelState extends CommonPublishPageState<RepostPanel> {
|
class _RepostPanelState extends CommonPublishPageState<RepostPanel> {
|
||||||
late bool _isMax = widget.isMax ?? false;
|
late bool _isMax = widget.isMax ?? false;
|
||||||
|
|
||||||
late final dynamic _pic = widget.pic ??
|
late final _pic = widget.pic ??
|
||||||
(widget.item as DynamicItemModel?)
|
widget.item?.modules.moduleDynamic?.major?.archive?.cover ??
|
||||||
?.modules
|
widget.item?.modules.moduleDynamic?.major?.pgc?.cover ??
|
||||||
?.moduleDynamic
|
widget.item?.modules.moduleDynamic?.major?.opus?.pics?.firstOrNull?.url;
|
||||||
?.major
|
|
||||||
?.archive
|
|
||||||
?.cover ??
|
|
||||||
(widget.item as DynamicItemModel?)
|
|
||||||
?.modules
|
|
||||||
?.moduleDynamic
|
|
||||||
?.major
|
|
||||||
?.pgc
|
|
||||||
?.cover ??
|
|
||||||
(widget.item as DynamicItemModel?)
|
|
||||||
?.modules
|
|
||||||
?.moduleDynamic
|
|
||||||
?.major
|
|
||||||
?.opus
|
|
||||||
?.pics
|
|
||||||
?.firstOrNull
|
|
||||||
?.url;
|
|
||||||
|
|
||||||
late final _text = widget.title ??
|
late final _text = widget.title ??
|
||||||
(widget.item as DynamicItemModel?)
|
widget.item?.modules.moduleDynamic?.major?.opus?.summary?.text ??
|
||||||
?.modules
|
widget.item?.modules.moduleDynamic?.desc?.text ??
|
||||||
?.moduleDynamic
|
widget.item?.modules.moduleDynamic?.major?.archive?.title ??
|
||||||
?.major
|
widget.item?.modules.moduleDynamic?.major?.pgc?.title ??
|
||||||
?.opus
|
|
||||||
?.summary
|
|
||||||
?.text ??
|
|
||||||
(widget.item as DynamicItemModel?)?.modules?.moduleDynamic?.desc?.text ??
|
|
||||||
(widget.item as DynamicItemModel?)
|
|
||||||
?.modules
|
|
||||||
?.moduleDynamic
|
|
||||||
?.major
|
|
||||||
?.archive
|
|
||||||
?.title ??
|
|
||||||
(widget.item as DynamicItemModel?)
|
|
||||||
?.modules
|
|
||||||
?.moduleDynamic
|
|
||||||
?.major
|
|
||||||
?.pgc
|
|
||||||
?.title ??
|
|
||||||
'';
|
'';
|
||||||
|
|
||||||
late final _uname = widget.uname ??
|
late final _uname = widget.uname ?? widget.item?.modules.moduleAuthor?.name;
|
||||||
(widget.item as DynamicItemModel?)?.modules?.moduleAuthor?.name;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ class _DynamicsTabPageState
|
|||||||
] else ...[
|
] else ...[
|
||||||
for (var i in loadingState.response!)
|
for (var i in loadingState.response!)
|
||||||
if (!dynamicsController.tempBannedList
|
if (!dynamicsController.tempBannedList
|
||||||
.contains(i.modules?.moduleAuthor?.mid))
|
.contains(i.modules.moduleAuthor?.mid))
|
||||||
DynamicPanel(
|
DynamicPanel(
|
||||||
item: i,
|
item: i,
|
||||||
onRemove: controller.onRemove,
|
onRemove: controller.onRemove,
|
||||||
@@ -185,7 +185,7 @@ class _DynamicsTabPageState
|
|||||||
4 &&
|
4 &&
|
||||||
dynamicsController.mid.value != -1) ||
|
dynamicsController.mid.value != -1) ||
|
||||||
!dynamicsController.tempBannedList.contains(
|
!dynamicsController.tempBannedList.contains(
|
||||||
item.modules?.moduleAuthor?.mid)) {
|
item.modules.moduleAuthor?.mid)) {
|
||||||
return DynamicPanel(
|
return DynamicPanel(
|
||||||
item: item,
|
item: item,
|
||||||
onRemove: controller.onRemove,
|
onRemove: controller.onRemove,
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ import 'package:PiliPlus/utils/feed_back.dart';
|
|||||||
class ActionPanel extends StatefulWidget {
|
class ActionPanel extends StatefulWidget {
|
||||||
const ActionPanel({
|
const ActionPanel({
|
||||||
super.key,
|
super.key,
|
||||||
this.item,
|
required this.item,
|
||||||
});
|
});
|
||||||
final dynamic item;
|
final DynamicItemModel item;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<ActionPanel> createState() => _ActionPanelState();
|
State<ActionPanel> createState() => _ActionPanelState();
|
||||||
@@ -33,26 +33,22 @@ class _ActionPanelState extends State<ActionPanel> {
|
|||||||
// 动态点赞
|
// 动态点赞
|
||||||
Future onLikeDynamic() async {
|
Future onLikeDynamic() async {
|
||||||
feedBack();
|
feedBack();
|
||||||
var item = widget.item!;
|
final item = widget.item;
|
||||||
String dynamicId = item.idStr!;
|
String dynamicId = item.idStr!;
|
||||||
// 1 已点赞 2 不喜欢 0 未操作
|
// 1 已点赞 2 不喜欢 0 未操作
|
||||||
Like like = item.modules.moduleStat.like;
|
DynamicStat? like = item.modules.moduleStat?.like;
|
||||||
int count = like.count == '点赞' ? 0 : int.parse(like.count ?? '0');
|
int count = like?.count ?? 0;
|
||||||
bool status = like.status!;
|
bool status = like?.status == true;
|
||||||
int up = status ? 2 : 1;
|
int up = status ? 2 : 1;
|
||||||
var res = await DynamicsHttp.likeDynamic(dynamicId: dynamicId, up: up);
|
var res = await DynamicsHttp.likeDynamic(dynamicId: dynamicId, up: up);
|
||||||
if (res['status']) {
|
if (res['status']) {
|
||||||
SmartDialog.showToast(!status ? '点赞成功' : '取消赞');
|
SmartDialog.showToast(!status ? '点赞成功' : '取消赞');
|
||||||
if (up == 1) {
|
if (up == 1) {
|
||||||
item.modules.moduleStat.like.count = (count + 1).toString();
|
item.modules.moduleStat?.like?.count = count + 1;
|
||||||
item.modules.moduleStat.like.status = true;
|
item.modules.moduleStat?.like?.status = true;
|
||||||
} else {
|
} else {
|
||||||
if (count == 1) {
|
item.modules.moduleStat?.like?.count = count - 1;
|
||||||
item.modules.moduleStat.like.count = '点赞';
|
item.modules.moduleStat?.like?.status = false;
|
||||||
} else {
|
|
||||||
item.modules.moduleStat.like.count = (count - 1).toString();
|
|
||||||
}
|
|
||||||
item.modules.moduleStat.like.status = false;
|
|
||||||
}
|
}
|
||||||
setState(() {});
|
setState(() {});
|
||||||
} else {
|
} else {
|
||||||
@@ -78,12 +74,9 @@ class _ActionPanelState extends State<ActionPanel> {
|
|||||||
builder: (context) => RepostPanel(
|
builder: (context) => RepostPanel(
|
||||||
item: widget.item,
|
item: widget.item,
|
||||||
callback: () {
|
callback: () {
|
||||||
int count = int.tryParse(
|
int count =
|
||||||
widget.item!.modules.moduleStat.forward?.count ??
|
widget.item.modules.moduleStat?.forward?.count ?? 0;
|
||||||
'0') ??
|
widget.item.modules.moduleStat!.forward!.count = count + 1;
|
||||||
0;
|
|
||||||
widget.item!.modules.moduleStat.forward!.count =
|
|
||||||
(count + 1).toString();
|
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -100,9 +93,9 @@ class _ActionPanelState extends State<ActionPanel> {
|
|||||||
foregroundColor: Theme.of(context).colorScheme.outline,
|
foregroundColor: Theme.of(context).colorScheme.outline,
|
||||||
),
|
),
|
||||||
label: Text(
|
label: Text(
|
||||||
widget.item!.modules.moduleStat.forward!.count != null
|
widget.item.modules.moduleStat!.forward!.count != null
|
||||||
? Utils.numFormat(
|
? Utils.numFormat(
|
||||||
widget.item!.modules.moduleStat.forward!.count)
|
widget.item.modules.moduleStat!.forward!.count)
|
||||||
: '转发',
|
: '转发',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -123,9 +116,9 @@ class _ActionPanelState extends State<ActionPanel> {
|
|||||||
foregroundColor: Theme.of(context).colorScheme.outline,
|
foregroundColor: Theme.of(context).colorScheme.outline,
|
||||||
),
|
),
|
||||||
label: Text(
|
label: Text(
|
||||||
widget.item!.modules.moduleStat.comment!.count != null
|
widget.item.modules.moduleStat!.comment!.count != null
|
||||||
? Utils.numFormat(
|
? Utils.numFormat(
|
||||||
widget.item!.modules.moduleStat.comment!.count)
|
widget.item.modules.moduleStat!.comment!.count)
|
||||||
: '评论',
|
: '评论',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -135,15 +128,15 @@ class _ActionPanelState extends State<ActionPanel> {
|
|||||||
child: TextButton.icon(
|
child: TextButton.icon(
|
||||||
onPressed: () => handleState(onLikeDynamic),
|
onPressed: () => handleState(onLikeDynamic),
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
widget.item!.modules.moduleStat.like!.status!
|
widget.item.modules.moduleStat!.like!.status!
|
||||||
? FontAwesomeIcons.solidThumbsUp
|
? FontAwesomeIcons.solidThumbsUp
|
||||||
: FontAwesomeIcons.thumbsUp,
|
: FontAwesomeIcons.thumbsUp,
|
||||||
size: 16,
|
size: 16,
|
||||||
color: widget.item!.modules.moduleStat.like!.status!
|
color: widget.item.modules.moduleStat!.like!.status!
|
||||||
? primary
|
? primary
|
||||||
: color,
|
: color,
|
||||||
semanticLabel:
|
semanticLabel:
|
||||||
widget.item!.modules.moduleStat.like!.status! ? "已赞" : "点赞",
|
widget.item.modules.moduleStat!.like!.status! ? "已赞" : "点赞",
|
||||||
),
|
),
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
padding: const EdgeInsets.fromLTRB(15, 0, 15, 0),
|
padding: const EdgeInsets.fromLTRB(15, 0, 15, 0),
|
||||||
@@ -155,14 +148,15 @@ class _ActionPanelState extends State<ActionPanel> {
|
|||||||
return ScaleTransition(scale: animation, child: child);
|
return ScaleTransition(scale: animation, child: child);
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
widget.item!.modules.moduleStat.like!.count != null
|
widget.item.modules.moduleStat!.like!.count != null
|
||||||
? Utils.numFormat(
|
? Utils.numFormat(
|
||||||
widget.item!.modules.moduleStat.like!.count)
|
widget.item.modules.moduleStat!.like!.count)
|
||||||
: '点赞',
|
: '点赞',
|
||||||
key: ValueKey<String>(
|
key: ValueKey<String>(
|
||||||
widget.item!.modules.moduleStat.like!.count ?? '点赞'),
|
widget.item.modules.moduleStat!.like!.count?.toString() ??
|
||||||
|
'点赞'),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: widget.item!.modules.moduleStat.like!.status!
|
color: widget.item.modules.moduleStat!.like!.status!
|
||||||
? primary
|
? primary
|
||||||
: color,
|
: color,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import 'package:PiliPlus/common/widgets/avatar.dart';
|
|||||||
import 'package:PiliPlus/common/widgets/report.dart';
|
import 'package:PiliPlus/common/widgets/report.dart';
|
||||||
import 'package:PiliPlus/common/widgets/save_panel.dart';
|
import 'package:PiliPlus/common/widgets/save_panel.dart';
|
||||||
import 'package:PiliPlus/http/video.dart';
|
import 'package:PiliPlus/http/video.dart';
|
||||||
|
import 'package:PiliPlus/models/dynamics/result.dart';
|
||||||
import 'package:PiliPlus/utils/extension.dart';
|
import 'package:PiliPlus/utils/extension.dart';
|
||||||
import 'package:PiliPlus/utils/page_utils.dart';
|
import 'package:PiliPlus/utils/page_utils.dart';
|
||||||
import 'package:PiliPlus/utils/request_utils.dart';
|
import 'package:PiliPlus/utils/request_utils.dart';
|
||||||
@@ -20,7 +21,7 @@ import '../../../http/constants.dart';
|
|||||||
import '../controller.dart';
|
import '../controller.dart';
|
||||||
|
|
||||||
class AuthorPanel extends StatelessWidget {
|
class AuthorPanel extends StatelessWidget {
|
||||||
final dynamic item;
|
final DynamicItemModel item;
|
||||||
final Function? addBannedList;
|
final Function? addBannedList;
|
||||||
final String? source;
|
final String? source;
|
||||||
final Function? onRemove;
|
final Function? onRemove;
|
||||||
@@ -40,7 +41,7 @@ class AuthorPanel extends StatelessWidget {
|
|||||||
Widget _buildAvatar() {
|
Widget _buildAvatar() {
|
||||||
String? pendant = item.modules.moduleAuthor?.pendant?['image'];
|
String? pendant = item.modules.moduleAuthor?.pendant?['image'];
|
||||||
Widget avatar = Avatar(
|
Widget avatar = Avatar(
|
||||||
avatar: item.modules.moduleAuthor.face,
|
avatar: item.modules.moduleAuthor?.face ?? '',
|
||||||
size: pendant.isNullOrEmpty ? 40 : 34,
|
size: pendant.isNullOrEmpty ? 40 : 34,
|
||||||
isVip: null, // item.modules.moduleAuthor!.vip['status'] > 0
|
isVip: null, // item.modules.moduleAuthor!.vip['status'] > 0
|
||||||
officialType: null, // 已被注释
|
officialType: null, // 已被注释
|
||||||
@@ -55,14 +56,14 @@ class AuthorPanel extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
String? pubTime = item.modules.moduleAuthor.pubTs != null
|
final pubTime = item.modules.moduleAuthor?.pubTs != null
|
||||||
? isSave
|
? isSave
|
||||||
? DateTime.fromMillisecondsSinceEpoch(
|
? DateTime.fromMillisecondsSinceEpoch(
|
||||||
item.modules.moduleAuthor.pubTs * 1000)
|
item.modules.moduleAuthor!.pubTs! * 1000)
|
||||||
.toString()
|
.toString()
|
||||||
.substring(0, 19)
|
.substring(0, 19)
|
||||||
: Utils.dateFormat(item.modules.moduleAuthor.pubTs)
|
: Utils.dateFormat(item.modules.moduleAuthor!.pubTs)
|
||||||
: item.modules.moduleAuthor.pubTime;
|
: item.modules.moduleAuthor?.pubTime;
|
||||||
return Stack(
|
return Stack(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
children: [
|
children: [
|
||||||
@@ -71,17 +72,17 @@ class AuthorPanel extends StatelessWidget {
|
|||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
(item.modules.moduleAuthor.type == 'AUTHOR_TYPE_PGC' ||
|
(item.modules.moduleAuthor!.type == 'AUTHOR_TYPE_PGC' ||
|
||||||
item.modules.moduleAuthor.type ==
|
item.modules.moduleAuthor!.type ==
|
||||||
'AUTHOR_TYPE_UGC_SEASON')
|
'AUTHOR_TYPE_UGC_SEASON')
|
||||||
? _buildAvatar() // 番剧
|
? _buildAvatar() // 番剧
|
||||||
: GestureDetector(
|
: GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
feedBack();
|
feedBack();
|
||||||
Get.toNamed(
|
Get.toNamed(
|
||||||
'/member?mid=${item.modules.moduleAuthor.mid}',
|
'/member?mid=${item.modules.moduleAuthor!.mid}',
|
||||||
arguments: {
|
arguments: {
|
||||||
'face': item.modules.moduleAuthor.face,
|
'face': item.modules.moduleAuthor!.face,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@@ -92,11 +93,11 @@ class AuthorPanel extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
item.modules.moduleAuthor.name,
|
item.modules.moduleAuthor?.name ?? '',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: item.modules.moduleAuthor!.vip != null &&
|
color: item.modules.moduleAuthor!.vip != null &&
|
||||||
item.modules.moduleAuthor!.vip['status'] > 0 &&
|
item.modules.moduleAuthor!.vip!['status'] > 0 &&
|
||||||
item.modules.moduleAuthor!.vip['type'] == 2
|
item.modules.moduleAuthor!.vip!['type'] == 2
|
||||||
? context.vipColor
|
? context.vipColor
|
||||||
: theme.colorScheme.onSurface,
|
: theme.colorScheme.onSurface,
|
||||||
fontSize: theme.textTheme.titleSmall!.fontSize,
|
fontSize: theme.textTheme.titleSmall!.fontSize,
|
||||||
@@ -104,7 +105,7 @@ class AuthorPanel extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
if (pubTime != null)
|
if (pubTime != null)
|
||||||
Text(
|
Text(
|
||||||
'$pubTime${item.modules.moduleAuthor.pubAction != null ? ' ${item.modules.moduleAuthor.pubAction}' : ''}',
|
'$pubTime${item.modules.moduleAuthor?.pubAction != null ? ' ${item.modules.moduleAuthor!.pubAction}' : ''}',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: theme.colorScheme.outline,
|
color: theme.colorScheme.outline,
|
||||||
fontSize: theme.textTheme.labelSmall!.fontSize,
|
fontSize: theme.textTheme.labelSmall!.fontSize,
|
||||||
@@ -117,7 +118,7 @@ class AuthorPanel extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
Align(
|
Align(
|
||||||
alignment: Alignment.centerRight,
|
alignment: Alignment.centerRight,
|
||||||
child: source != 'detail' && item.modules?.moduleTag?.text != null
|
child: source != 'detail' && item.modules.moduleTag?.text != null
|
||||||
? Row(
|
? Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
@@ -133,7 +134,7 @@ class AuthorPanel extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
item.modules.moduleTag.text,
|
item.modules.moduleTag!.text!,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
height: 1,
|
height: 1,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
@@ -149,7 +150,7 @@ class AuthorPanel extends StatelessWidget {
|
|||||||
_moreWidget(context),
|
_moreWidget(context),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
: item.modules.moduleAuthor.decorate != null
|
: item.modules.moduleAuthor!.decorate != null
|
||||||
? Row(
|
? Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
@@ -159,31 +160,31 @@ class AuthorPanel extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
CachedNetworkImage(
|
CachedNetworkImage(
|
||||||
height: 32,
|
height: 32,
|
||||||
imageUrl: (item.modules.moduleAuthor
|
imageUrl: (item.modules.moduleAuthor!
|
||||||
.decorate['card_url'] as String)
|
.decorate!['card_url'] as String)
|
||||||
.http2https,
|
.http2https,
|
||||||
),
|
),
|
||||||
if ((item.modules.moduleAuthor.decorate?['fan']
|
if ((item.modules.moduleAuthor?.decorate?['fan']
|
||||||
?['num_str'] as String?)
|
?['num_str'] as String?)
|
||||||
?.isNotEmpty ==
|
?.isNotEmpty ==
|
||||||
true)
|
true)
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(right: 32),
|
padding: const EdgeInsets.only(right: 32),
|
||||||
child: Text(
|
child: Text(
|
||||||
'${item.modules.moduleAuthor.decorate['fan']['num_str']}',
|
'${item.modules.moduleAuthor!.decorate!['fan']['num_str']}',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
height: 1,
|
height: 1,
|
||||||
fontSize: 11,
|
fontSize: 11,
|
||||||
fontFamily: 'digital_id_num',
|
fontFamily: 'digital_id_num',
|
||||||
color: (item.modules.moduleAuthor
|
color: (item.modules.moduleAuthor!
|
||||||
.decorate?['fan']
|
.decorate!['fan']
|
||||||
?['color'] as String?)
|
['color'] as String?)
|
||||||
?.startsWith('#') ==
|
?.startsWith('#') ==
|
||||||
true
|
true
|
||||||
? Color(
|
? Color(
|
||||||
int.parse(
|
int.parse(
|
||||||
item.modules.moduleAuthor
|
item.modules.moduleAuthor!
|
||||||
.decorate['fan']['color']
|
.decorate!['fan']['color']
|
||||||
.replaceFirst('#', '0xFF'),
|
.replaceFirst('#', '0xFF'),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -220,15 +221,15 @@ class AuthorPanel extends StatelessWidget {
|
|||||||
void morePanel(BuildContext context) {
|
void morePanel(BuildContext context) {
|
||||||
String? bvid;
|
String? bvid;
|
||||||
try {
|
try {
|
||||||
getBvid(String? type, dynamic major) => switch (type) {
|
getBvid(String? type, DynamicMajorModel? major) => switch (type) {
|
||||||
'DYNAMIC_TYPE_AV' => major?.archive?.bvid,
|
'DYNAMIC_TYPE_AV' => major?.archive?.bvid,
|
||||||
'DYNAMIC_TYPE_UGC_SEASON' => major?.ugcSeason?.bvid,
|
'DYNAMIC_TYPE_UGC_SEASON' => major?.ugcSeason?.bvid,
|
||||||
_ => null,
|
_ => null,
|
||||||
};
|
};
|
||||||
bvid = getBvid(item.type, item.modules?.moduleDynamic?.major);
|
bvid = getBvid(item.type, item.modules.moduleDynamic?.major);
|
||||||
if (bvid == null && item.orig != null) {
|
if (bvid == null && item.orig != null) {
|
||||||
bvid =
|
bvid =
|
||||||
getBvid(item.orig.type, item.orig?.modules?.moduleDynamic?.major);
|
getBvid(item.orig!.type, item.orig?.modules.moduleDynamic?.major);
|
||||||
}
|
}
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
|
|
||||||
@@ -308,8 +309,8 @@ class AuthorPanel extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
minLeadingWidth: 0,
|
minLeadingWidth: 0,
|
||||||
),
|
),
|
||||||
if (item.basic['comment_type'] == 17 ||
|
if (item.basic!.commentType == 17 ||
|
||||||
item.basic['comment_type'] == 11)
|
item.basic!.commentType == 11)
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
'分享至消息',
|
'分享至消息',
|
||||||
@@ -319,23 +320,23 @@ class AuthorPanel extends StatelessWidget {
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
Get.back();
|
Get.back();
|
||||||
try {
|
try {
|
||||||
bool isDyn = item.basic['comment_type'] == 17;
|
bool isDyn = item.basic!.commentType == 17;
|
||||||
String id = isDyn ? item.idStr : item.basic['rid_str'];
|
String id = isDyn ? item.idStr : item.basic!.ridStr!;
|
||||||
int source = isDyn ? 11 : 2;
|
int source = isDyn ? 11 : 2;
|
||||||
String title;
|
String title;
|
||||||
if (item.modules.moduleDynamic.desc != null) {
|
if (item.modules.moduleDynamic?.desc != null) {
|
||||||
title = item.modules.moduleDynamic.desc.text;
|
title = item.modules.moduleDynamic!.desc!.text!;
|
||||||
} else if (item.modules.moduleDynamic.major != null) {
|
} else if (item.modules.moduleDynamic?.major != null) {
|
||||||
title =
|
title = item
|
||||||
item.modules.moduleDynamic.major.opus.summary.text;
|
.modules.moduleDynamic!.major!.opus!.summary!.text!;
|
||||||
} else {
|
} else {
|
||||||
throw UnsupportedError(
|
throw UnsupportedError(
|
||||||
'error getting title: {"type": ${item.basic['comment_type']}, "id": $id}');
|
'error getting title: {"type": ${item.basic!.commentType}, "id": $id}');
|
||||||
}
|
}
|
||||||
String thumb = isDyn
|
String thumb = isDyn
|
||||||
? item.modules.moduleAuthor.face
|
? item.modules.moduleAuthor!.face!
|
||||||
: item
|
: item.modules.moduleDynamic!.major!.opus!.pics!.first
|
||||||
.modules.moduleDynamic.major.opus.pics.first.url;
|
.url!;
|
||||||
PageUtils.pmShare(
|
PageUtils.pmShare(
|
||||||
content: {
|
content: {
|
||||||
"id": id,
|
"id": id,
|
||||||
@@ -344,8 +345,8 @@ class AuthorPanel extends StatelessWidget {
|
|||||||
"source": source,
|
"source": source,
|
||||||
"extra": {},
|
"extra": {},
|
||||||
"thumb": thumb,
|
"thumb": thumb,
|
||||||
"author": item.modules.moduleAuthor.name,
|
"author": item.modules.moduleAuthor!.name,
|
||||||
"author_id": item.modules.moduleAuthor.mid.toString()
|
"author_id": item.modules.moduleAuthor!.mid.toString()
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -356,7 +357,7 @@ class AuthorPanel extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
'临时屏蔽:${item.modules?.moduleAuthor?.name}',
|
'临时屏蔽:${item.modules.moduleAuthor?.name}',
|
||||||
style: Theme.of(context).textTheme.titleSmall,
|
style: Theme.of(context).textTheme.titleSmall,
|
||||||
),
|
),
|
||||||
leading: const Icon(Icons.visibility_off_outlined, size: 19),
|
leading: const Icon(Icons.visibility_off_outlined, size: 19),
|
||||||
@@ -364,13 +365,13 @@ class AuthorPanel extends StatelessWidget {
|
|||||||
Get.back();
|
Get.back();
|
||||||
Get.find<DynamicsController>()
|
Get.find<DynamicsController>()
|
||||||
.tempBannedList
|
.tempBannedList
|
||||||
.add(item.modules.moduleAuthor.mid);
|
.add(item.modules.moduleAuthor!.mid!);
|
||||||
SmartDialog.showToast(
|
SmartDialog.showToast(
|
||||||
'已临时屏蔽${item.modules?.moduleAuthor?.name}(${item.modules.moduleAuthor.mid}),重启恢复');
|
'已临时屏蔽${item.modules.moduleAuthor?.name}(${item.modules.moduleAuthor!.mid}),重启恢复');
|
||||||
},
|
},
|
||||||
minLeadingWidth: 0,
|
minLeadingWidth: 0,
|
||||||
),
|
),
|
||||||
if (item.modules?.moduleAuthor?.mid == Accounts.main.mid) ...[
|
if (item.modules.moduleAuthor?.mid == Accounts.main.mid) ...[
|
||||||
ListTile(
|
ListTile(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Get.back();
|
Get.back();
|
||||||
@@ -393,12 +394,12 @@ class AuthorPanel extends StatelessWidget {
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
Get.back();
|
Get.back();
|
||||||
onSetTop!(
|
onSetTop!(
|
||||||
item.modules?.moduleTag?.text != null, item.idStr);
|
item.modules.moduleTag?.text != null, item.idStr);
|
||||||
},
|
},
|
||||||
minLeadingWidth: 0,
|
minLeadingWidth: 0,
|
||||||
leading: const Icon(Icons.vertical_align_top, size: 19),
|
leading: const Icon(Icons.vertical_align_top, size: 19),
|
||||||
title: Text(
|
title: Text(
|
||||||
'${item.modules?.moduleTag?.text != null ? '取消' : ''}置顶',
|
'${item.modules.moduleTag?.text != null ? '取消' : ''}置顶',
|
||||||
style: Theme.of(context).textTheme.titleSmall!),
|
style: Theme.of(context).textTheme.titleSmall!),
|
||||||
),
|
),
|
||||||
if (onRemove != null)
|
if (onRemove != null)
|
||||||
@@ -459,13 +460,13 @@ class AuthorPanel extends StatelessWidget {
|
|||||||
(reasonType, reasonDesc, banUid) {
|
(reasonType, reasonDesc, banUid) {
|
||||||
if (banUid) {
|
if (banUid) {
|
||||||
VideoHttp.relationMod(
|
VideoHttp.relationMod(
|
||||||
mid: item.modules!.moduleAuthor!.mid!,
|
mid: item.modules.moduleAuthor!.mid!,
|
||||||
act: 5,
|
act: 5,
|
||||||
reSrc: 11,
|
reSrc: 11,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return UserHttp.dynamicReport(
|
return UserHttp.dynamicReport(
|
||||||
mid: item.modules!.moduleAuthor!.mid,
|
mid: item.modules.moduleAuthor!.mid,
|
||||||
dynId: item.idStr,
|
dynId: item.idStr,
|
||||||
reasonType: reasonType,
|
reasonType: reasonType,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -74,8 +74,8 @@ class DynamicPanel extends StatelessWidget {
|
|||||||
padding: const EdgeInsets.fromLTRB(12, 12, 12, 6),
|
padding: const EdgeInsets.fromLTRB(12, 12, 12, 6),
|
||||||
child: authorWidget,
|
child: authorWidget,
|
||||||
),
|
),
|
||||||
if (item.modules!.moduleDynamic!.desc != null ||
|
if (item.modules.moduleDynamic!.desc != null ||
|
||||||
item.modules!.moduleDynamic!.major != null)
|
item.modules.moduleDynamic!.major != null)
|
||||||
content(isSave, context, item, source, callback),
|
content(isSave, context, item, source, callback),
|
||||||
forWard(isSave, item, context, source, callback),
|
forWard(isSave, item, context, source, callback),
|
||||||
const SizedBox(height: 2),
|
const SizedBox(height: 2),
|
||||||
@@ -94,7 +94,7 @@ class DynamicPanel extends StatelessWidget {
|
|||||||
) {
|
) {
|
||||||
late String? title;
|
late String? title;
|
||||||
late String? cover;
|
late String? cover;
|
||||||
late final major = item.modules?.moduleDynamic?.major;
|
late final major = item.modules.moduleDynamic?.major;
|
||||||
switch (item.type) {
|
switch (item.type) {
|
||||||
case 'DYNAMIC_TYPE_AV':
|
case 'DYNAMIC_TYPE_AV':
|
||||||
title = major?.archive?.title;
|
title = major?.archive?.title;
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ Widget forWard(bool isSave, item, BuildContext context, source, callback,
|
|||||||
item.modules.moduleDynamic.additional.type,
|
item.modules.moduleDynamic.additional.type,
|
||||||
floor: floor,
|
floor: floor,
|
||||||
),
|
),
|
||||||
if (item?.modules?.moduleDynamic?.major?.blocked != null)
|
if (item?.modules.moduleDynamic?.major?.blocked != null)
|
||||||
_blockedItem(context, item, source),
|
_blockedItem(context, item, source),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -155,27 +155,27 @@ Widget forWard(bool isSave, item, BuildContext context, source, callback,
|
|||||||
return switch (item) {
|
return switch (item) {
|
||||||
DynamicItemModel() => item.isForwarded == true
|
DynamicItemModel() => item.isForwarded == true
|
||||||
? articlePanel(source, item, context, callback, floor: floor)
|
? articlePanel(source, item, context, callback, floor: floor)
|
||||||
: item.modules?.moduleDynamic?.major?.blocked != null
|
: item.modules.moduleDynamic?.major?.blocked != null
|
||||||
? Padding(
|
? Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
if (item.modules?.moduleDynamic?.major
|
if (item.modules.moduleDynamic?.major
|
||||||
?.blocked?['title'] !=
|
?.blocked?['title'] !=
|
||||||
null)
|
null)
|
||||||
Text(
|
Text(
|
||||||
'${item.modules?.moduleDynamic?.major?.blocked!['title']}',
|
'${item.modules.moduleDynamic?.major?.blocked!['title']}',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context).colorScheme.secondary,
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (item.modules?.moduleDynamic?.major
|
if (item.modules.moduleDynamic?.major
|
||||||
?.blocked?['hint_message'] !=
|
?.blocked?['hint_message'] !=
|
||||||
null)
|
null)
|
||||||
Text(
|
Text(
|
||||||
'${item.modules?.moduleDynamic?.major?.blocked!['hint_message']}',
|
'${item.modules.moduleDynamic?.major?.blocked!['hint_message']}',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: Theme.of(context).colorScheme.outline,
|
color: Theme.of(context).colorScheme.outline,
|
||||||
@@ -304,7 +304,7 @@ Widget forWard(bool isSave, item, BuildContext context, source, callback,
|
|||||||
item.modules.moduleDynamic.additional.type,
|
item.modules.moduleDynamic.additional.type,
|
||||||
floor: floor,
|
floor: floor,
|
||||||
)
|
)
|
||||||
: item?.modules?.moduleDynamic?.major?.blocked != null
|
: item?.modules.moduleDynamic?.major?.blocked != null
|
||||||
? _blockedItem(context, item, source)
|
? _blockedItem(context, item, source)
|
||||||
: const SizedBox(height: 0);
|
: const SizedBox(height: 0);
|
||||||
case 'DYNAMIC_TYPE_PGC':
|
case 'DYNAMIC_TYPE_PGC':
|
||||||
|
|||||||
@@ -72,13 +72,13 @@ class MemberDynamicsController
|
|||||||
var res = await DynamicsHttp.setTop(dynamicId: dynamicId);
|
var res = await DynamicsHttp.setTop(dynamicId: dynamicId);
|
||||||
if (res['status']) {
|
if (res['status']) {
|
||||||
List<DynamicItemModel> list = (loadingState.value as Success).response;
|
List<DynamicItemModel> list = (loadingState.value as Success).response;
|
||||||
list[0].modules?.moduleTag = null;
|
list[0].modules.moduleTag = null;
|
||||||
if (isTop) {
|
if (isTop) {
|
||||||
loadingState.refresh();
|
loadingState.refresh();
|
||||||
SmartDialog.showToast('取消置顶成功');
|
SmartDialog.showToast('取消置顶成功');
|
||||||
} else {
|
} else {
|
||||||
final item = list.firstWhere((item) => item.idStr == dynamicId);
|
final item = list.firstWhere((item) => item.idStr == dynamicId);
|
||||||
item.modules?.moduleTag = ModuleTag(text: '置顶');
|
item.modules.moduleTag = ModuleTag(text: '置顶');
|
||||||
list.remove(item);
|
list.remove(item);
|
||||||
list.insert(0, item);
|
list.insert(0, item);
|
||||||
loadingState.refresh();
|
loadingState.refresh();
|
||||||
|
|||||||
@@ -265,7 +265,7 @@ class PageUtils {
|
|||||||
SmartDialog.dismiss();
|
SmartDialog.dismiss();
|
||||||
if (res['status']) {
|
if (res['status']) {
|
||||||
DynamicItemModel data = res['data'];
|
DynamicItemModel data = res['data'];
|
||||||
if (data.basic?['comment_type'] == 12) {
|
if (data.basic?.commentType == 12) {
|
||||||
toDupNamed(
|
toDupNamed(
|
||||||
'/articlePage',
|
'/articlePage',
|
||||||
parameters: {
|
parameters: {
|
||||||
|
|||||||
@@ -304,29 +304,24 @@ class RequestUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 动态点赞
|
// 动态点赞
|
||||||
static Future onLikeDynamic(item, VoidCallback callback) async {
|
static Future onLikeDynamic(
|
||||||
|
DynamicItemModel item, VoidCallback callback) async {
|
||||||
feedBack();
|
feedBack();
|
||||||
String dynamicId = item.idStr!;
|
String dynamicId = item.idStr!;
|
||||||
// 1 已点赞 2 不喜欢 0 未操作
|
// 1 已点赞 2 不喜欢 0 未操作
|
||||||
item.modules?.moduleStat ??= ModuleStatModel();
|
DynamicStat? like = item.modules.moduleStat?.like;
|
||||||
item.modules?.moduleStat.like ??= Like();
|
int count = like?.count ?? 0;
|
||||||
Like like = item.modules.moduleStat.like;
|
bool status = like?.status ?? false;
|
||||||
int count = like.count == '点赞' ? 0 : int.parse(like.count ?? '0');
|
|
||||||
bool status = like.status ?? false;
|
|
||||||
int up = status ? 2 : 1;
|
int up = status ? 2 : 1;
|
||||||
var res = await DynamicsHttp.likeDynamic(dynamicId: dynamicId, up: up);
|
var res = await DynamicsHttp.likeDynamic(dynamicId: dynamicId, up: up);
|
||||||
if (res['status']) {
|
if (res['status']) {
|
||||||
SmartDialog.showToast(!status ? '点赞成功' : '取消赞');
|
SmartDialog.showToast(!status ? '点赞成功' : '取消赞');
|
||||||
if (up == 1) {
|
if (up == 1) {
|
||||||
item.modules.moduleStat.like.count = (count + 1).toString();
|
like?.count = count + 1;
|
||||||
item.modules.moduleStat.like.status = true;
|
like?.status = true;
|
||||||
} else {
|
} else {
|
||||||
if (count == 1) {
|
like?.count = count - 1;
|
||||||
item.modules.moduleStat.like.count = '点赞';
|
like?.status = false;
|
||||||
} else {
|
|
||||||
item.modules.moduleStat.like.count = (count - 1).toString();
|
|
||||||
}
|
|
||||||
item.modules.moduleStat.like.status = false;
|
|
||||||
}
|
}
|
||||||
callback();
|
callback();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user