diff --git a/lib/common/widgets/save_panel.dart b/lib/common/widgets/save_panel.dart index ab403592..92626124 100644 --- a/lib/common/widgets/save_panel.dart +++ b/lib/common/widgets/save_panel.dart @@ -105,7 +105,7 @@ class _SavePanelState extends State { } else if (currentRoute.startsWith('/dynamicDetail')) { try { DynamicItemModel dynItem = Get.arguments['item']; - uname = dynItem.modules?.moduleAuthor?.name; + uname = dynItem.modules.moduleAuthor?.name; final type = _item.type.toInt(); late final oid = dynItem.idStr; late final rootId = hasRoot ? _item.root : _item.id; @@ -117,7 +117,7 @@ class _SavePanelState extends State { 1 || 11 || 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', }; diff --git a/lib/http/dynamics.dart b/lib/http/dynamics.dart index ad68ade1..6bdce868 100644 --- a/lib/http/dynamics.dart +++ b/lib/http/dynamics.dart @@ -1,11 +1,10 @@ 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/storage.dart'; import 'package:PiliPlus/utils/wbi_sign.dart'; import 'package:dio/dio.dart'; +import '../models/space_article/item.dart'; import '../models/dynamics/result.dart'; import '../models/dynamics/up.dart'; import 'index.dart'; @@ -33,9 +32,9 @@ class DynamicsHttp { if (GStorage.antiGoodsDyn) { data.items?.removeWhere( (item) => - item.orig?.modules?.moduleDynamic?.additional?.type == + item.orig?.modules.moduleDynamic?.additional?.type == 'ADDITIONAL_TYPE_GOODS' || - item.modules?.moduleDynamic?.additional?.type == + item.modules.moduleDynamic?.additional?.type == 'ADDITIONAL_TYPE_GOODS', ); } @@ -160,37 +159,34 @@ class DynamicsHttp { } } - static Future articleView({ - required dynamic cvId, - }) async { - var res = await Request().get( + static Future> articleView({required dynamic cvId}) async { + final res = await Request().get( Api.articleView, queryParameters: await WbiSign.makSign({ 'id': cvId, 'gaia_source': 'main_web', + 'web_location': '333.976', }), ); - if (res.data['code'] == 0) { - return {'status': true, 'data': ArticleData.fromJson(res.data['data'])}; - } else { - return {'status': false, 'msg': res.data['message']}; - } + + return res.data['code'] == 0 + ? LoadingState.success(Item.fromJson(res.data['data'])) + : LoadingState.error(res.data['message']); } - static Future opusDetail({ - required dynamic opusId, - }) async { - var res = await Request().get( + static Future> opusDetail( + {required dynamic opusId}) async { + final res = await Request().get( Api.opusDetail, queryParameters: await WbiSign.makSign({ - 'id': opusId, + 'timezone_offset': '-480', 'features': 'htmlNewStyle', + 'id': opusId, }), ); - if (res.data['code'] == 0) { - return {'status': true, 'data': OpusData.fromJson(res.data['data'])}; - } else { - return {'status': false, 'msg': res.data['message']}; - } + + return res.data['code'] == 0 + ? LoadingState.success(DynamicItemModel.fromOpusJson(res.data['data'])) + : LoadingState.error(res.data['message']); } } diff --git a/lib/http/member.dart b/lib/http/member.dart index 2b339c40..bdc59b5b 100644 --- a/lib/http/member.dart +++ b/lib/http/member.dart @@ -414,9 +414,9 @@ class MemberHttp { DynamicsDataModel data = DynamicsDataModel.fromJson(res.data['data']); if (GStorage.antiGoodsDyn) { data.items?.removeWhere((item) => - item.orig?.modules?.moduleDynamic?.additional?.type == + item.orig?.modules.moduleDynamic?.additional?.type == 'ADDITIONAL_TYPE_GOODS' || - item.modules?.moduleDynamic?.additional?.type == + item.modules.moduleDynamic?.additional?.type == 'ADDITIONAL_TYPE_GOODS'); } return LoadingState.success(data); diff --git a/lib/models/dynamics/article_content_model.dart b/lib/models/dynamics/article_content_model.dart new file mode 100644 index 00000000..6f8a3d4f --- /dev/null +++ b/lib/models/dynamics/article_content_model.dart @@ -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 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? pics; + int? style; + String? url; + num? width; + num? height; + num? size; + String? liveUrl; + + double? calHeight; + + Pic.fromJson(Map 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 json) { + pic = json['pic'] == null ? null : Pic.fromJson(json['pic']); + } +} + +class Format { + Format({ + this.align, + }); + int? align; + + Format.fromJson(Map json) { + align = json['align']; + } +} + +class Text { + Text({ + this.nodes, + }); + List? nodes; + + Text.fromJson(Map json) { + nodes = + (json['nodes'] as List?)?.map((item) => Nodes.fromJson(item)).toList(); + } +} + +class Nodes { + int? nodeType; + Word? word; + Rich? rich; + + Nodes.fromJson(Map 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 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 json) { + bold = json['bold']; + italic = json['italic']; + strikethrough = json['strikethrough']; + } +} + +class Rich { + Style? style; + String? jumpUrl; + String? origText; + String? text; + + Rich.fromJson(Map 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 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 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 json) { + card = json['card'] == null ? null : Card.fromJson(json['card']); + } +} + +class L1st { + List? items; + int? style; + + L1st.fromJson(Map json) { + items = (json['items'] as List?)?.map((e) => Item.fromJson(e)).toList(); + style = json['style']; + } +} + +class Item { + int? level; + int? order; + List? nodes; + + Item.fromJson(Map 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 json) { + content = json['content']; + lang = json['lang']; + } +} + +// class ArticleContentModel { +// ArticleContentModel({ +// this.attributes, +// this.insert, +// }); +// Attributes? attributes; +// dynamic insert; + +// ArticleContentModel.fromJson(Map 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 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 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 json) { +// clazz = json['class']; +// bold = json['bold']; +// color = json['color']; +// italic = json['italic']; +// strike = json['strike']; +// } +// } diff --git a/lib/models/dynamics/article_view/article_view.dart b/lib/models/dynamics/article_view/article_view.dart deleted file mode 100644 index dd0089a3..00000000 --- a/lib/models/dynamics/article_view/article_view.dart +++ /dev/null @@ -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 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), - ); - - Map toJson() => { - 'code': code, - 'message': message, - 'ttl': ttl, - 'data': data?.toJson(), - }; -} diff --git a/lib/models/dynamics/article_view/author.dart b/lib/models/dynamics/article_view/author.dart deleted file mode 100644 index 35f74ab1..00000000 --- a/lib/models/dynamics/article_view/author.dart +++ /dev/null @@ -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 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), - officialVerify: json['official_verify'] == null - ? null - : OfficialVerify.fromJson(json['official_verify'] as Map), - nameplate: json['nameplate'] == null - ? null - : Nameplate.fromJson(json['nameplate'] as Map), - vip: json['vip'] == null - ? null - : Vip.fromJson(json['vip'] as Map), - fans: json['fans'] as int?, - level: json['level'] as int?, - ); - - Map toJson() => { - 'mid': mid, - 'name': name, - 'face': face, - 'pendant': pendant?.toJson(), - 'official_verify': officialVerify?.toJson(), - 'nameplate': nameplate?.toJson(), - 'vip': vip?.toJson(), - 'fans': fans, - 'level': level, - }; -} diff --git a/lib/models/dynamics/article_view/category.dart b/lib/models/dynamics/article_view/category.dart deleted file mode 100644 index ea85d9c4..00000000 --- a/lib/models/dynamics/article_view/category.dart +++ /dev/null @@ -1,19 +0,0 @@ -class Category { - int? id; - int? parentId; - String? name; - - Category({this.id, this.parentId, this.name}); - - factory Category.fromJson(Map json) => Category( - id: json['id'] as int?, - parentId: json['parent_id'] as int?, - name: json['name'] as String?, - ); - - Map toJson() => { - 'id': id, - 'parent_id': parentId, - 'name': name, - }; -} diff --git a/lib/models/dynamics/article_view/data.dart b/lib/models/dynamics/article_view/data.dart deleted file mode 100644 index fda2a014..00000000 --- a/lib/models/dynamics/article_view/data.dart +++ /dev/null @@ -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? 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? 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? 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 json) { - final data = ArticleData( - id: json['id'] as int?, - category: json['category'] == null - ? null - : Category.fromJson(json['category'] as Map), - categories: (json['categories'] as List?) - ?.map((e) => Category.fromJson(e as Map)) - .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), - 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), - tags: (json['tags'] as List?) - ?.map((e) => Tag.fromJson(e as Map)) - .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), - 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 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, - }; -} diff --git a/lib/models/dynamics/article_view/label.dart b/lib/models/dynamics/article_view/label.dart deleted file mode 100644 index 6387da61..00000000 --- a/lib/models/dynamics/article_view/label.dart +++ /dev/null @@ -1,19 +0,0 @@ -class Label { - String? path; - String? text; - String? labelTheme; - - Label({this.path, this.text, this.labelTheme}); - - factory Label.fromJson(Map json) => Label( - path: json['path'] as String?, - text: json['text'] as String?, - labelTheme: json['label_theme'] as String?, - ); - - Map toJson() => { - 'path': path, - 'text': text, - 'label_theme': labelTheme, - }; -} diff --git a/lib/models/dynamics/article_view/media.dart b/lib/models/dynamics/article_view/media.dart deleted file mode 100644 index 4080f495..00000000 --- a/lib/models/dynamics/article_view/media.dart +++ /dev/null @@ -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 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 toJson() => { - 'score': score, - 'media_id': mediaId, - 'title': title, - 'cover': cover, - 'area': area, - 'type_id': typeId, - 'type_name': typeName, - 'spoiler': spoiler, - 'season_id': seasonId, - }; -} diff --git a/lib/models/dynamics/article_view/nameplate.dart b/lib/models/dynamics/article_view/nameplate.dart deleted file mode 100644 index d6f9191d..00000000 --- a/lib/models/dynamics/article_view/nameplate.dart +++ /dev/null @@ -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 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 toJson() => { - 'nid': nid, - 'name': name, - 'image': image, - 'image_small': imageSmall, - 'level': level, - 'condition': condition, - }; -} diff --git a/lib/models/dynamics/article_view/official_verify.dart b/lib/models/dynamics/article_view/official_verify.dart deleted file mode 100644 index ed4c6f4d..00000000 --- a/lib/models/dynamics/article_view/official_verify.dart +++ /dev/null @@ -1,20 +0,0 @@ -class OfficialVerify { - int? type; - String? desc; - - OfficialVerify({this.type, this.desc}); - - factory OfficialVerify.fromJson(Map json) { - return OfficialVerify( - type: json['type'] as int?, - desc: json['desc'] as String?, - ); - } - - - - Map toJson() => { - 'type': type, - 'desc': desc, - }; -} diff --git a/lib/models/dynamics/article_view/pendant.dart b/lib/models/dynamics/article_view/pendant.dart deleted file mode 100644 index acb2e705..00000000 --- a/lib/models/dynamics/article_view/pendant.dart +++ /dev/null @@ -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 json) => Pendant( - pid: json['pid'] as int?, - name: json['name'] as String?, - image: json['image'] as String?, - expire: json['expire'] as int?, - ); - - Map toJson() => { - 'pid': pid, - 'name': name, - 'image': image, - 'expire': expire, - }; -} diff --git a/lib/models/dynamics/article_view/stats.dart b/lib/models/dynamics/article_view/stats.dart deleted file mode 100644 index ba12f9dc..00000000 --- a/lib/models/dynamics/article_view/stats.dart +++ /dev/null @@ -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 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 toJson() => { - 'view': view, - 'favorite': favorite, - 'like': like, - 'dislike': dislike, - 'reply': reply, - 'share': share, - 'coin': coin, - 'dynamic': dynam1c, - }; -} diff --git a/lib/models/dynamics/article_view/tag.dart b/lib/models/dynamics/article_view/tag.dart deleted file mode 100644 index c11893af..00000000 --- a/lib/models/dynamics/article_view/tag.dart +++ /dev/null @@ -1,16 +0,0 @@ -class Tag { - int? tid; - String? name; - - Tag({this.tid, this.name}); - - factory Tag.fromJson(Map json) => Tag( - tid: json['tid'] as int?, - name: json['name'] as String?, - ); - - Map toJson() => { - 'tid': tid, - 'name': name, - }; -} diff --git a/lib/models/dynamics/article_view/vip.dart b/lib/models/dynamics/article_view/vip.dart deleted file mode 100644 index f2c4559e..00000000 --- a/lib/models/dynamics/article_view/vip.dart +++ /dev/null @@ -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 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), - avatarSubscript: json['avatar_subscript'] as int?, - nicknameColor: json['nickname_color'] as String?, - ); - - Map toJson() => { - 'type': type, - 'status': status, - 'due_date': dueDate, - 'vip_pay_type': vipPayType, - 'theme_type': themeType, - 'label': label?.toJson(), - 'avatar_subscript': avatarSubscript, - 'nickname_color': nicknameColor, - }; -} diff --git a/lib/models/dynamics/opus_detail/avatar.dart b/lib/models/dynamics/opus_detail/avatar.dart deleted file mode 100644 index 6ee6f30f..00000000 --- a/lib/models/dynamics/opus_detail/avatar.dart +++ /dev/null @@ -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 json) => Avatar( - containerSize: json['container_size'] == null - ? null - : ContainerSize.fromJson(json['container_size'] as Map), - fallbackLayers: json['fallback_layers'] == null - ? null - : FallbackLayers.fromJson(json['fallback_layers'] as Map), - mid: json['mid'] as String?, - ); - - Map toJson() => { - 'container_size': containerSize?.toJson(), - 'fallback_layers': fallbackLayers?.toJson(), - 'mid': mid, - }; -} diff --git a/lib/models/dynamics/opus_detail/avatar_icon.dart b/lib/models/dynamics/opus_detail/avatar_icon.dart deleted file mode 100644 index 559f11e3..00000000 --- a/lib/models/dynamics/opus_detail/avatar_icon.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'icon_resource.dart'; - -class AvatarIcon { - IconResource? iconResource; - - AvatarIcon({this.iconResource}); - - factory AvatarIcon.fromJson(Map json) => AvatarIcon( - iconResource: json['icon_resource'] == null - ? null - : IconResource.fromJson(json['icon_resource'] as Map), - ); - - Map toJson() => { - 'icon_resource': iconResource?.toJson(), - }; -} diff --git a/lib/models/dynamics/opus_detail/avatar_layer.dart b/lib/models/dynamics/opus_detail/avatar_layer.dart deleted file mode 100644 index b2af911f..00000000 --- a/lib/models/dynamics/opus_detail/avatar_layer.dart +++ /dev/null @@ -1,14 +0,0 @@ - -class AvatarLayer { - AvatarLayer(); - - factory AvatarLayer.fromJson(Map json) { - // TODO: implement fromJson - throw UnimplementedError('AvatarLayer.fromJson($json) is not implemented'); - } - - Map toJson() { - // TODO: implement toJson - throw UnimplementedError(); - } -} \ No newline at end of file diff --git a/lib/models/dynamics/opus_detail/basic.dart b/lib/models/dynamics/opus_detail/basic.dart deleted file mode 100644 index 75f3e23b..00000000 --- a/lib/models/dynamics/opus_detail/basic.dart +++ /dev/null @@ -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 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), - ridStr: json['rid_str'] as String?, - title: json['title'] as String?, - uid: json['uid'] as int?, - ); - - Map toJson() => { - 'comment_id_str': commentIdStr, - 'comment_type': commentType, - 'like_icon': likeIcon?.toJson(), - 'rid_str': ridStr, - 'title': title, - 'uid': uid, - }; -} diff --git a/lib/models/dynamics/opus_detail/coin.dart b/lib/models/dynamics/opus_detail/coin.dart deleted file mode 100644 index 3bb24634..00000000 --- a/lib/models/dynamics/opus_detail/coin.dart +++ /dev/null @@ -1,19 +0,0 @@ -class Coin { - int? count; - bool? forbidden; - bool? status; - - Coin({this.count, this.forbidden, this.status}); - - factory Coin.fromJson(Map json) => Coin( - count: json['count'] as int?, - forbidden: json['forbidden'] as bool?, - status: json['status'] as bool?, - ); - - Map toJson() => { - 'count': count, - 'forbidden': forbidden, - 'status': status, - }; -} diff --git a/lib/models/dynamics/opus_detail/comment.dart b/lib/models/dynamics/opus_detail/comment.dart deleted file mode 100644 index 811158a2..00000000 --- a/lib/models/dynamics/opus_detail/comment.dart +++ /dev/null @@ -1,16 +0,0 @@ -class Comment { - int? count; - bool? forbidden; - - Comment({this.count, this.forbidden}); - - factory Comment.fromJson(Map json) => Comment( - count: json['count'] as int?, - forbidden: json['forbidden'] as bool?, - ); - - Map toJson() => { - 'count': count, - 'forbidden': forbidden, - }; -} diff --git a/lib/models/dynamics/opus_detail/container_size.dart b/lib/models/dynamics/opus_detail/container_size.dart deleted file mode 100644 index ea8185d0..00000000 --- a/lib/models/dynamics/opus_detail/container_size.dart +++ /dev/null @@ -1,16 +0,0 @@ -class ContainerSize { - double? height; - double? width; - - ContainerSize({this.height, this.width}); - - factory ContainerSize.fromJson(Map json) => ContainerSize( - height: (json['height'] as num?)?.toDouble(), - width: (json['width'] as num?)?.toDouble(), - ); - - Map toJson() => { - 'height': height, - 'width': width, - }; -} diff --git a/lib/models/dynamics/opus_detail/data.dart b/lib/models/dynamics/opus_detail/data.dart deleted file mode 100644 index a05db401..00000000 --- a/lib/models/dynamics/opus_detail/data.dart +++ /dev/null @@ -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 json) => OpusData( - item: json['item'] == null - ? null - : Item.fromJson(json['item'] as Map), - fallback: json['fallback'] == null - ? null - : Fallback.fromJson(json['fallback']), - ); - - Map toJson() => { - 'item': item?.toJson(), - 'fallback': fallback?.toJson(), - }; -} diff --git a/lib/models/dynamics/opus_detail/fallback.dart b/lib/models/dynamics/opus_detail/fallback.dart deleted file mode 100644 index 8f5bfd5d..00000000 --- a/lib/models/dynamics/opus_detail/fallback.dart +++ /dev/null @@ -1,19 +0,0 @@ -class Fallback { - String? id; - int? type; - - Fallback({ - this.id, - this.type, - }); - - factory Fallback.fromJson(Map json) => Fallback( - id: json['id'], - type: json['type'], - ); - - Map toJson() => { - 'id': id, - 'type': type, - }; -} diff --git a/lib/models/dynamics/opus_detail/fallback_layers.dart b/lib/models/dynamics/opus_detail/fallback_layers.dart deleted file mode 100644 index aba634f7..00000000 --- a/lib/models/dynamics/opus_detail/fallback_layers.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'layer.dart'; - -class FallbackLayers { - bool? isCriticalGroup; - List? layers; - - FallbackLayers({this.isCriticalGroup, this.layers}); - - factory FallbackLayers.fromJson(Map json) { - return FallbackLayers( - isCriticalGroup: json['is_critical_group'] as bool?, - layers: (json['layers'] as List?) - ?.map((e) => Layer.fromJson(e as Map)) - .toList(), - ); - } - - - - Map toJson() => { - 'is_critical_group': isCriticalGroup, - 'layers': layers?.map((e) => e.toJson()).toList(), - }; -} diff --git a/lib/models/dynamics/opus_detail/favorite.dart b/lib/models/dynamics/opus_detail/favorite.dart deleted file mode 100644 index b6f64e66..00000000 --- a/lib/models/dynamics/opus_detail/favorite.dart +++ /dev/null @@ -1,19 +0,0 @@ -class Favorite { - int? count; - bool? forbidden; - bool? status; - - Favorite({this.count, this.forbidden, this.status}); - - factory Favorite.fromJson(Map json) => Favorite( - count: json['count'] as int?, - forbidden: json['forbidden'] as bool?, - status: json['status'] as bool?, - ); - - Map toJson() => { - 'count': count, - 'forbidden': forbidden, - 'status': status, - }; -} diff --git a/lib/models/dynamics/opus_detail/forward.dart b/lib/models/dynamics/opus_detail/forward.dart deleted file mode 100644 index 62cbf1bd..00000000 --- a/lib/models/dynamics/opus_detail/forward.dart +++ /dev/null @@ -1,16 +0,0 @@ -class Forward { - int? count; - bool? forbidden; - - Forward({this.count, this.forbidden}); - - factory Forward.fromJson(Map json) => Forward( - count: json['count'] as int?, - forbidden: json['forbidden'] as bool?, - ); - - Map toJson() => { - 'count': count, - 'forbidden': forbidden, - }; -} diff --git a/lib/models/dynamics/opus_detail/general_cfg.dart b/lib/models/dynamics/opus_detail/general_cfg.dart deleted file mode 100644 index ebd2334c..00000000 --- a/lib/models/dynamics/opus_detail/general_cfg.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'general_config.dart'; - -class GeneralCfg { - int? configType; - GeneralConfig? generalConfig; - - GeneralCfg({this.configType, this.generalConfig}); - - factory GeneralCfg.fromJson(Map json) => GeneralCfg( - configType: json['config_type'] as int?, - generalConfig: json['general_config'] == null - ? null - : GeneralConfig.fromJson(json['general_config'] as Map), - ); - - Map toJson() => { - 'config_type': configType, - 'general_config': generalConfig?.toJson(), - }; -} diff --git a/lib/models/dynamics/opus_detail/general_config.dart b/lib/models/dynamics/opus_detail/general_config.dart deleted file mode 100644 index 5730e93a..00000000 --- a/lib/models/dynamics/opus_detail/general_config.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'web_css_style.dart'; - -class GeneralConfig { - WebCssStyle? webCssStyle; - - GeneralConfig({this.webCssStyle}); - - factory GeneralConfig.fromJson(Map json) => GeneralConfig( - webCssStyle: json['web_css_style'] == null - ? null - : WebCssStyle.fromJson(json['web_css_style'] as Map), - ); - - Map toJson() => { - 'web_css_style': webCssStyle?.toJson(), - }; -} diff --git a/lib/models/dynamics/opus_detail/general_spec.dart b/lib/models/dynamics/opus_detail/general_spec.dart deleted file mode 100644 index f6381068..00000000 --- a/lib/models/dynamics/opus_detail/general_spec.dart +++ /dev/null @@ -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 json) => GeneralSpec( - posSpec: json['pos_spec'] == null - ? null - : PosSpec.fromJson(json['pos_spec'] as Map), - renderSpec: json['render_spec'] == null - ? null - : RenderSpec.fromJson(json['render_spec'] as Map), - sizeSpec: json['size_spec'] == null - ? null - : SizeSpec.fromJson(json['size_spec'] as Map), - ); - - Map toJson() => { - 'pos_spec': posSpec?.toJson(), - 'render_spec': renderSpec?.toJson(), - 'size_spec': sizeSpec?.toJson(), - }; -} diff --git a/lib/models/dynamics/opus_detail/icon_resource.dart b/lib/models/dynamics/opus_detail/icon_resource.dart deleted file mode 100644 index 07fea5cd..00000000 --- a/lib/models/dynamics/opus_detail/icon_resource.dart +++ /dev/null @@ -1,14 +0,0 @@ - -class IconResource { - IconResource(); - - factory IconResource.fromJson(Map json) { - // TODO: implement fromJson - throw UnimplementedError('IconResource.fromJson($json) is not implemented'); - } - - Map toJson() { - // TODO: implement toJson - throw UnimplementedError(); - } -} \ No newline at end of file diff --git a/lib/models/dynamics/opus_detail/image_src.dart b/lib/models/dynamics/opus_detail/image_src.dart deleted file mode 100644 index 1b396594..00000000 --- a/lib/models/dynamics/opus_detail/image_src.dart +++ /dev/null @@ -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 json) => ImageSrc( - placeholder: json['placeholder'] as int?, - remote: json['remote'] == null - ? null - : Remote.fromJson(json['remote'] as Map), - srcType: json['src_type'] as int?, - ); - - Map toJson() => { - 'placeholder': placeholder, - 'remote': remote?.toJson(), - 'src_type': srcType, - }; -} diff --git a/lib/models/dynamics/opus_detail/item.dart b/lib/models/dynamics/opus_detail/item.dart deleted file mode 100644 index 0b67e99c..00000000 --- a/lib/models/dynamics/opus_detail/item.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'basic.dart'; -import 'module.dart'; - -class Item { - Basic? basic; - String? idStr; - List? modules; - int? type; - - Item({this.basic, this.idStr, this.modules, this.type}); - - factory Item.fromJson(Map json) => Item( - basic: json['basic'] == null - ? null - : Basic.fromJson(json['basic'] as Map), - idStr: json['id_str'] as String?, - modules: (json['modules'] as List?) - ?.map((e) => OpusModule.fromJson(e as Map)) - .toList(), - type: json['type'] as int?, - ); - - Map toJson() => { - 'basic': basic?.toJson(), - 'id_str': idStr, - 'modules': modules?.map((e) => e.toJson()).toList(), - 'type': type, - }; -} diff --git a/lib/models/dynamics/opus_detail/label.dart b/lib/models/dynamics/opus_detail/label.dart deleted file mode 100644 index 093c0663..00000000 --- a/lib/models/dynamics/opus_detail/label.dart +++ /dev/null @@ -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 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 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, - }; -} diff --git a/lib/models/dynamics/opus_detail/layer.dart b/lib/models/dynamics/opus_detail/layer.dart deleted file mode 100644 index 33854bc5..00000000 --- a/lib/models/dynamics/opus_detail/layer.dart +++ /dev/null @@ -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 json) => Layer( - generalSpec: json['general_spec'] == null - ? null - : GeneralSpec.fromJson(json['general_spec'] as Map), - layerConfig: json['layer_config'] == null - ? null - : LayerConfig.fromJson(json['layer_config'] as Map), - resource: json['resource'] == null - ? null - : Resource.fromJson(json['resource'] as Map), - visible: json['visible'] as bool?, - ); - - Map toJson() => { - 'general_spec': generalSpec?.toJson(), - 'layer_config': layerConfig?.toJson(), - 'resource': resource?.toJson(), - 'visible': visible, - }; -} diff --git a/lib/models/dynamics/opus_detail/layer_config.dart b/lib/models/dynamics/opus_detail/layer_config.dart deleted file mode 100644 index 711079c6..00000000 --- a/lib/models/dynamics/opus_detail/layer_config.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'tags.dart'; - -class LayerConfig { - bool? isCritical; - Tags? tags; - - LayerConfig({this.isCritical, this.tags}); - - factory LayerConfig.fromJson(Map json) => LayerConfig( - isCritical: json['is_critical'] as bool?, - tags: json['tags'] == null - ? null - : Tags.fromJson(json['tags'] as Map), - ); - - Map toJson() => { - 'is_critical': isCritical, - 'tags': tags?.toJson(), - }; -} diff --git a/lib/models/dynamics/opus_detail/like.dart b/lib/models/dynamics/opus_detail/like.dart deleted file mode 100644 index c705cd53..00000000 --- a/lib/models/dynamics/opus_detail/like.dart +++ /dev/null @@ -1,19 +0,0 @@ -class Like { - int? count; - bool? forbidden; - bool? status; - - Like({this.count, this.forbidden, this.status}); - - factory Like.fromJson(Map json) => Like( - count: json['count'] as int?, - forbidden: json['forbidden'] as bool?, - status: json['status'] as bool?, - ); - - Map toJson() => { - 'count': count, - 'forbidden': forbidden, - 'status': status, - }; -} diff --git a/lib/models/dynamics/opus_detail/like_icon.dart b/lib/models/dynamics/opus_detail/like_icon.dart deleted file mode 100644 index 8e22daac..00000000 --- a/lib/models/dynamics/opus_detail/like_icon.dart +++ /dev/null @@ -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 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 toJson() => { - 'action_url': actionUrl, - 'end_url': endUrl, - 'id': id, - 'start_url': startUrl, - }; -} diff --git a/lib/models/dynamics/opus_detail/module.dart b/lib/models/dynamics/opus_detail/module.dart deleted file mode 100644 index f8311530..00000000 --- a/lib/models/dynamics/opus_detail/module.dart +++ /dev/null @@ -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 json) => OpusModule( - moduleTitle: json['module_title'] == null - ? null - : ModuleTitle.fromJson( - json['module_title'] as Map), - moduleType: json['module_type'] as String?, - moduleAuthor: json['module_author'] == null - ? null - : ModuleAuthor.fromJson( - json['module_author'] as Map), - moduleContent: json['module_content'] == null - ? null - : ModuleContent.fromJson( - json['module_content'] as Map), - moduleExtend: json['module_extend'] == null - ? null - : ModuleExtend.fromJson( - json['module_extend'] as Map), - moduleBottom: json['module_bottom'] == null - ? null - : ModuleBottom.fromJson( - json['module_bottom'] as Map), - moduleStat: json['module_stat'] == null - ? null - : ModuleStat.fromJson(json['module_stat'] as Map), - ); - - Map 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(), - }; -} diff --git a/lib/models/dynamics/opus_detail/module_author.dart b/lib/models/dynamics/opus_detail/module_author.dart deleted file mode 100644 index 6a0b4fd9..00000000 --- a/lib/models/dynamics/opus_detail/module_author.dart +++ /dev/null @@ -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 json) => ModuleAuthor( - avatar: json['avatar'] == null - ? null - : Avatar.fromJson(json['avatar'] as Map), - 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), - pendant: json['pendant'] == null - ? null - : Pendant.fromJson(json['pendant'] as Map), - 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), - ); - - Map 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(), - }; -} diff --git a/lib/models/dynamics/opus_detail/module_bottom.dart b/lib/models/dynamics/opus_detail/module_bottom.dart deleted file mode 100644 index e7e410c8..00000000 --- a/lib/models/dynamics/opus_detail/module_bottom.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'share_info.dart'; - -class ModuleBottom { - ShareInfo? shareInfo; - - ModuleBottom({this.shareInfo}); - - factory ModuleBottom.fromJson(Map json) => ModuleBottom( - shareInfo: json['share_info'] == null - ? null - : ShareInfo.fromJson(json['share_info'] as Map), - ); - - Map toJson() => { - 'share_info': shareInfo?.toJson(), - }; -} diff --git a/lib/models/dynamics/opus_detail/module_content.dart b/lib/models/dynamics/opus_detail/module_content.dart deleted file mode 100644 index 6c90fa09..00000000 --- a/lib/models/dynamics/opus_detail/module_content.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'paragraph.dart'; - -class ModuleContent { - List? paragraphs; - - ModuleContent({this.paragraphs}); - - factory ModuleContent.fromJson(Map json) => ModuleContent( - paragraphs: (json['paragraphs'] as List?) - ?.map((e) => Paragraph.fromJson(e as Map)) - .toList(), - ); - - Map toJson() => { - 'paragraphs': paragraphs?.map((e) => e.toJson()).toList(), - }; -} diff --git a/lib/models/dynamics/opus_detail/module_extend.dart b/lib/models/dynamics/opus_detail/module_extend.dart deleted file mode 100644 index 85f9befd..00000000 --- a/lib/models/dynamics/opus_detail/module_extend.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'item.dart'; - -class ModuleExtend { - List? items; - - ModuleExtend({this.items}); - - factory ModuleExtend.fromJson(Map json) => ModuleExtend( - items: (json['items'] as List?) - ?.map((e) => Item.fromJson(e as Map)) - .toList(), - ); - - Map toJson() => { - 'items': items?.map((e) => e.toJson()).toList(), - }; -} diff --git a/lib/models/dynamics/opus_detail/module_stat.dart b/lib/models/dynamics/opus_detail/module_stat.dart deleted file mode 100644 index 4dce5fb1..00000000 --- a/lib/models/dynamics/opus_detail/module_stat.dart +++ /dev/null @@ -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 json) => ModuleStat( - coin: json['coin'] == null - ? null - : Coin.fromJson(json['coin'] as Map), - comment: json['comment'] == null - ? null - : Comment.fromJson(json['comment'] as Map), - favorite: json['favorite'] == null - ? null - : Favorite.fromJson(json['favorite'] as Map), - forward: json['forward'] == null - ? null - : Forward.fromJson(json['forward'] as Map), - like: json['like'] == null - ? null - : Like.fromJson(json['like'] as Map), - ); - - Map toJson() => { - 'coin': coin?.toJson(), - 'comment': comment?.toJson(), - 'favorite': favorite?.toJson(), - 'forward': forward?.toJson(), - 'like': like?.toJson(), - }; -} diff --git a/lib/models/dynamics/opus_detail/module_title.dart b/lib/models/dynamics/opus_detail/module_title.dart deleted file mode 100644 index 2cf1ee3c..00000000 --- a/lib/models/dynamics/opus_detail/module_title.dart +++ /dev/null @@ -1,13 +0,0 @@ -class ModuleTitle { - String? text; - - ModuleTitle({this.text}); - - factory ModuleTitle.fromJson(Map json) => ModuleTitle( - text: json['text'] as String?, - ); - - Map toJson() => { - 'text': text, - }; -} diff --git a/lib/models/dynamics/opus_detail/node.dart b/lib/models/dynamics/opus_detail/node.dart deleted file mode 100644 index 8f4169d4..00000000 --- a/lib/models/dynamics/opus_detail/node.dart +++ /dev/null @@ -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 json) => Node( - type: json['type'] as String?, - word: json['word'] == null - ? null - : Word.fromJson(json['word'] as Map), - rich: json['rich'] == null - ? null - : Rich.fromJson(json['rich'] as Map), - ); - - Map toJson() => { - 'type': type, - 'word': word?.toJson(), - 'rich': rich?.toJson(), - }; -} diff --git a/lib/models/dynamics/opus_detail/official.dart b/lib/models/dynamics/opus_detail/official.dart deleted file mode 100644 index 7667b60d..00000000 --- a/lib/models/dynamics/opus_detail/official.dart +++ /dev/null @@ -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 json) => Official( - desc: json['desc'] as String?, - role: json['role'] as int?, - title: json['title'] as String?, - type: json['type'] as int?, - ); - - Map toJson() => { - 'desc': desc, - 'role': role, - 'title': title, - 'type': type, - }; -} diff --git a/lib/models/dynamics/opus_detail/opus_detail.dart b/lib/models/dynamics/opus_detail/opus_detail.dart deleted file mode 100644 index b7c1a0d4..00000000 --- a/lib/models/dynamics/opus_detail/opus_detail.dart +++ /dev/null @@ -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 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), - ); - - Map toJson() => { - 'code': code, - 'message': message, - 'ttl': ttl, - 'data': data?.toJson(), - }; -} diff --git a/lib/models/dynamics/opus_detail/paragraph.dart b/lib/models/dynamics/opus_detail/paragraph.dart deleted file mode 100644 index ad98ad63..00000000 --- a/lib/models/dynamics/opus_detail/paragraph.dart +++ /dev/null @@ -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 json) => Paragraph( - align: json['align'] as int?, - paraType: json['para_type'] as int?, - text: json['text'] == null - ? null - : ParagraphText.fromJson(json['text'] as Map), - pic: json['pic'] == null - ? null - : Pic.fromJson(json['pic'] as Map), - 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 toJson() => { - 'align': align, - 'para_type': paraType, - 'text': text?.toJson(), - 'pic': pic?.toJson(), - }; -} - -class L1st { - List? items; - int? style; - - L1st.fromJson(Map json) { - items = (json['items'] as List?)?.map((e) => Item.fromJson(e)).toList(); - style = json['style']; - } -} - -class Item { - int? level; - int? order; - List? nodes; - - Item.fromJson(Map 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 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 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 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 json) { - card = json['card'] == null ? null : Card.fromJson(json['card']); - } -} - -class Line { - Line({ - this.pic, - }); - Pic? pic; - - Line.fromJson(Map json) { - pic = json['pic'] == null ? null : Pic.fromJson(json['pic']); - } -} diff --git a/lib/models/dynamics/opus_detail/pendant.dart b/lib/models/dynamics/opus_detail/pendant.dart deleted file mode 100644 index 6b53177c..00000000 --- a/lib/models/dynamics/opus_detail/pendant.dart +++ /dev/null @@ -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 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 toJson() => { - 'expire': expire, - 'image': image, - 'image_enhance': imageEnhance, - 'image_enhance_frame': imageEnhanceFrame, - 'n_pid': nPid, - 'name': name, - 'pid': pid, - }; -} diff --git a/lib/models/dynamics/opus_detail/pic.dart b/lib/models/dynamics/opus_detail/pic.dart deleted file mode 100644 index fdbcab53..00000000 --- a/lib/models/dynamics/opus_detail/pic.dart +++ /dev/null @@ -1,76 +0,0 @@ -class Pic { - List? 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 json) => Pic( - pics: (json['pics'] as List?) - ?.map((e) => PicItem.fromJson(e as Map)) - .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 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 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 toJson() => { - 'height': height, - 'width': width, - 'size': size, - 'url': url, - 'live_url': liveUrl, - }; -} diff --git a/lib/models/dynamics/opus_detail/pos_spec.dart b/lib/models/dynamics/opus_detail/pos_spec.dart deleted file mode 100644 index a80a78e5..00000000 --- a/lib/models/dynamics/opus_detail/pos_spec.dart +++ /dev/null @@ -1,19 +0,0 @@ -class PosSpec { - double? axisX; - double? axisY; - int? coordinatePos; - - PosSpec({this.axisX, this.axisY, this.coordinatePos}); - - factory PosSpec.fromJson(Map json) => PosSpec( - axisX: (json['axis_x'] as num?)?.toDouble(), - axisY: (json['axis_y'] as num?)?.toDouble(), - coordinatePos: json['coordinate_pos'] as int?, - ); - - Map toJson() => { - 'axis_x': axisX, - 'axis_y': axisY, - 'coordinate_pos': coordinatePos, - }; -} diff --git a/lib/models/dynamics/opus_detail/remote.dart b/lib/models/dynamics/opus_detail/remote.dart deleted file mode 100644 index e4daaafb..00000000 --- a/lib/models/dynamics/opus_detail/remote.dart +++ /dev/null @@ -1,16 +0,0 @@ -class Remote { - String? bfsStyle; - String? url; - - Remote({this.bfsStyle, this.url}); - - factory Remote.fromJson(Map json) => Remote( - bfsStyle: json['bfs_style'] as String?, - url: json['url'] as String?, - ); - - Map toJson() => { - 'bfs_style': bfsStyle, - 'url': url, - }; -} diff --git a/lib/models/dynamics/opus_detail/render_spec.dart b/lib/models/dynamics/opus_detail/render_spec.dart deleted file mode 100644 index 926b9650..00000000 --- a/lib/models/dynamics/opus_detail/render_spec.dart +++ /dev/null @@ -1,13 +0,0 @@ -class RenderSpec { - int? opacity; - - RenderSpec({this.opacity}); - - factory RenderSpec.fromJson(Map json) => RenderSpec( - opacity: json['opacity'] as int?, - ); - - Map toJson() => { - 'opacity': opacity, - }; -} diff --git a/lib/models/dynamics/opus_detail/res_image.dart b/lib/models/dynamics/opus_detail/res_image.dart deleted file mode 100644 index f5bf88b8..00000000 --- a/lib/models/dynamics/opus_detail/res_image.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'image_src.dart'; - -class ResImage { - ImageSrc? imageSrc; - - ResImage({this.imageSrc}); - - factory ResImage.fromJson(Map json) => ResImage( - imageSrc: json['image_src'] == null - ? null - : ImageSrc.fromJson(json['image_src'] as Map), - ); - - Map toJson() => { - 'image_src': imageSrc?.toJson(), - }; -} diff --git a/lib/models/dynamics/opus_detail/resource.dart b/lib/models/dynamics/opus_detail/resource.dart deleted file mode 100644 index 03f5d9ef..00000000 --- a/lib/models/dynamics/opus_detail/resource.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'res_image.dart'; - -class Resource { - ResImage? resImage; - int? resType; - - Resource({this.resImage, this.resType}); - - factory Resource.fromJson(Map json) => Resource( - resImage: json['res_image'] == null - ? null - : ResImage.fromJson(json['res_image'] as Map), - resType: json['res_type'] as int?, - ); - - Map toJson() => { - 'res_image': resImage?.toJson(), - 'res_type': resType, - }; -} diff --git a/lib/models/dynamics/opus_detail/rich.dart b/lib/models/dynamics/opus_detail/rich.dart deleted file mode 100644 index 3cc2a9f7..00000000 --- a/lib/models/dynamics/opus_detail/rich.dart +++ /dev/null @@ -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 json) => Rich( - style: json['style'] == null - ? null - : Style.fromJson(json['style'] as Map), - jumpUrl: json['jump_url'] as String?, - origText: json['orig_text'] as String?, - text: json['text'] as String?, - ); - - Map toJson() => { - 'style': style?.toJson(), - 'jump_url': jumpUrl, - 'orig_text': origText, - 'text': text, - }; -} diff --git a/lib/models/dynamics/opus_detail/share_info.dart b/lib/models/dynamics/opus_detail/share_info.dart deleted file mode 100644 index 9d991ac0..00000000 --- a/lib/models/dynamics/opus_detail/share_info.dart +++ /dev/null @@ -1,19 +0,0 @@ -class ShareInfo { - String? pic; - String? summary; - String? title; - - ShareInfo({this.pic, this.summary, this.title}); - - factory ShareInfo.fromJson(Map json) => ShareInfo( - pic: json['pic'] as String?, - summary: json['summary'] as String?, - title: json['title'] as String?, - ); - - Map toJson() => { - 'pic': pic, - 'summary': summary, - 'title': title, - }; -} diff --git a/lib/models/dynamics/opus_detail/size_spec.dart b/lib/models/dynamics/opus_detail/size_spec.dart deleted file mode 100644 index 88b13ec6..00000000 --- a/lib/models/dynamics/opus_detail/size_spec.dart +++ /dev/null @@ -1,16 +0,0 @@ -class SizeSpec { - num? height; - num? width; - - SizeSpec({this.height, this.width}); - - factory SizeSpec.fromJson(Map json) => SizeSpec( - height: json['height'], - width: json['width'], - ); - - Map toJson() => { - 'height': height, - 'width': width, - }; -} diff --git a/lib/models/dynamics/opus_detail/style.dart b/lib/models/dynamics/opus_detail/style.dart deleted file mode 100644 index 000bad73..00000000 --- a/lib/models/dynamics/opus_detail/style.dart +++ /dev/null @@ -1,22 +0,0 @@ -class Style { - Style({ - this.bold, - this.italic, - this.strikethrough, - }); - bool? bold; - bool? italic; - bool? strikethrough; - - factory Style.fromJson(Map json) => Style( - bold: json['bold'], - italic: json['italic'], - strikethrough: json['strikethrough'], - ); - - Map toJson() => { - 'bold': bold, - 'italic': italic, - 'strikethrough': strikethrough, - }; -} diff --git a/lib/models/dynamics/opus_detail/tags.dart b/lib/models/dynamics/opus_detail/tags.dart deleted file mode 100644 index f73a4095..00000000 --- a/lib/models/dynamics/opus_detail/tags.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'general_cfg.dart'; - -class Tags { - // AvatarLayer? avatarLayer; - GeneralCfg? generalCfg; - - Tags({ - // this.avatarLayer, - this.generalCfg, - }); - - factory Tags.fromJson(Map json) => Tags( - // avatarLayer: json['AVATAR_LAYER'] == null - // ? null - // : AvatarLayer.fromJson( - // json['AVATAR_LAYER'] as Map), - generalCfg: json['GENERAL_CFG'] == null - ? null - : GeneralCfg.fromJson(json['GENERAL_CFG'] as Map), - ); - - Map toJson() => { - // 'AVATAR_LAYER': avatarLayer?.toJson(), - 'GENERAL_CFG': generalCfg?.toJson(), - }; -} diff --git a/lib/models/dynamics/opus_detail/text.dart b/lib/models/dynamics/opus_detail/text.dart deleted file mode 100644 index 03d65086..00000000 --- a/lib/models/dynamics/opus_detail/text.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'node.dart'; - -class ParagraphText { - List? nodes; - - ParagraphText({this.nodes}); - - factory ParagraphText.fromJson(Map json) => ParagraphText( - nodes: (json['nodes'] as List?) - ?.map((e) => Node.fromJson(e as Map)) - .toList(), - ); - - Map toJson() => { - 'nodes': nodes?.map((e) => e.toJson()).toList(), - }; -} diff --git a/lib/models/dynamics/opus_detail/vip.dart b/lib/models/dynamics/opus_detail/vip.dart deleted file mode 100644 index 3dabed7d..00000000 --- a/lib/models/dynamics/opus_detail/vip.dart +++ /dev/null @@ -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 json) => Vip( - // avatarIcon: json['avatar_icon'] == null - // ? null - // : AvatarIcon.fromJson(json['avatar_icon'] as Map), - 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), - 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 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, - }; -} diff --git a/lib/models/dynamics/opus_detail/web_css_style.dart b/lib/models/dynamics/opus_detail/web_css_style.dart deleted file mode 100644 index 1d6a48b5..00000000 --- a/lib/models/dynamics/opus_detail/web_css_style.dart +++ /dev/null @@ -1,13 +0,0 @@ -class WebCssStyle { - String? borderRadius; - - WebCssStyle({this.borderRadius}); - - factory WebCssStyle.fromJson(Map json) => WebCssStyle( - borderRadius: json['borderRadius'] as String?, - ); - - Map toJson() => { - 'borderRadius': borderRadius, - }; -} diff --git a/lib/models/dynamics/opus_detail/word.dart b/lib/models/dynamics/opus_detail/word.dart deleted file mode 100644 index 84d93abb..00000000 --- a/lib/models/dynamics/opus_detail/word.dart +++ /dev/null @@ -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 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), - words: json['words'] as String?, - fontLevel: json['font_level'] as String?, - ); - - Map toJson() => { - 'color': color, - 'font_size': fontSize, - 'style': style?.toJson(), - 'words': words, - 'font_level': fontLevel, - }; -} diff --git a/lib/models/dynamics/result.dart b/lib/models/dynamics/result.dart index 6fd1442c..bd980096 100644 --- a/lib/models/dynamics/result.dart +++ b/lib/models/dynamics/result.dart @@ -1,14 +1,11 @@ import 'dart:convert'; import 'package:PiliPlus/common/widgets/avatar.dart'; +import 'package:PiliPlus/models/model_owner.dart'; + +import 'article_content_model.dart'; class DynamicsDataModel { - DynamicsDataModel({ - this.hasMore, - this.items, - this.offset, - this.total, - }); bool? hasMore; List? items; String? offset; @@ -26,50 +23,85 @@ class DynamicsDataModel { // 单个动态 class DynamicItemModel { - DynamicItemModel({ - this.basic, - this.idStr, - this.modules, - this.orig, - this.type, - this.visible, - }); - - Map? basic; + Basic? basic; dynamic idStr; - ItemModulesModel? modules; + late ItemModulesModel modules; + DynamicItemModel? orig; String? type; bool? visible; bool? isForwarded; + // opus + Fallback? fallback; + DynamicItemModel.fromJson(Map json) { - basic = json['basic']; + if (json['basic'] != null) basic = Basic.fromJson(json['basic']); idStr = json['id_str']; - modules = ItemModulesModel.fromJson(json['modules']); - orig = - json['orig'] != null ? DynamicItemModel.fromJson(json['orig']) : null; - orig?.isForwarded = true; + modules = json['modules'] == null + ? ItemModulesModel() + : ItemModulesModel.fromJson(json['modules']); + if (json['orig'] != null) { + orig = DynamicItemModel.fromJson(json['orig'])..isForwarded = true; + } type = json['type']; visible = json['visible']; } + + DynamicItemModel.fromOpusJson(Map 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 json) => Fallback( + id: json['id'], + type: json['type'], + ); + + Map toJson() => { + 'id': id, + 'type': type, + }; } // 单个动态详情 class ItemModulesModel { - ItemModulesModel({ - this.moduleAuthor, - this.moduleDynamic, - // this.moduleInter, - this.moduleStat, - this.moduleTag, - }); + ItemModulesModel(); ModuleAuthorModel? moduleAuthor; + ModuleStatModel? moduleStat; + ModuleTag? moduleTag; // 也做opus的title用 + + // 动态 ModuleDynamicModel? moduleDynamic; // ModuleInterModel? moduleInter; - ModuleStatModel? moduleStat; - ModuleTag? moduleTag; + + // 专栏 + List? moduleExtend; // opus的tag + List? moduleContent; + + // moduleBottom ItemModulesModel.fromJson(Map json) { moduleAuthor = json['module_author'] != null @@ -86,37 +118,63 @@ class ItemModulesModel { ? ModuleTag.fromJson(json['module_tag']) : null; } + + ItemModulesModel.fromOpusJson(List> 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? likeIcon; + String? ridStr; + + Basic.fromJson(Map json) { + commentIdStr = json['comment_id_str']; + commentType = json['comment_type']; + likeIcon = json['like_icon']; + ridStr = json['rid_str']; + } } // 单个动态详情 - 作者信息 -class ModuleAuthorModel { - 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; +class ModuleAuthorModel extends Owner { bool? following; String? jumpUrl; String? label; - int? mid; - String? name; String? pubAction; String? pubTime; int? pubTs; @@ -790,63 +848,49 @@ class ModuleStatModel { this.comment, this.forward, this.like, + this.favorite, }); - Comment? comment; - ForWard? forward; - Like? like; + DynamicStat? comment; + DynamicStat? forward; + DynamicStat? like; + DynamicStat? favorite; + // DynamicStat? coin; ModuleStatModel.fromJson(Map json) { - comment = Comment.fromJson(json['comment']); - forward = ForWard.fromJson(json['forward']); - like = Like.fromJson(json['like']); + comment = DynamicStat.fromJson(json['comment']); + forward = DynamicStat.fromJson(json['forward']); + like = DynamicStat.fromJson(json['like']); + if (json['favorite'] != null) { + favorite = DynamicStat.fromJson(json['favorite']); + } } } -// 动态状态 评论 -class Comment { - Comment({ - this.count, - this.forbidden, - }); - - String? count; - bool? forbidden; - - Comment.fromJson(Map 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 json) { - count = json['count'] == 0 ? null : json['count'].toString(); - forbidden = json['forbidden']; - } -} - -// 动态状态 点赞 -class Like { - Like({ +// 动态状态 +class DynamicStat { + DynamicStat({ this.count, this.forbidden, this.status, }); - String? count; + int? count; bool? forbidden; bool? status; - Like.fromJson(Map json) { - count = json['count'] == 0 ? null : json['count'].toString(); + DynamicStat.fromJson(Map json) { + count = json['count'] == 0 ? null : _parseInt(json['count']); forbidden = json['forbidden']; status = json['status']; } + + static int? _parseInt(dynamic x) => switch (x) { + int() => x, + String() => int.tryParse(x), + double() => x.toInt(), + _ => null + }; } class Stat { diff --git a/lib/models/space_article/author.dart b/lib/models/space_article/author.dart index 77f18f0f..50c53634 100644 --- a/lib/models/space_article/author.dart +++ b/lib/models/space_article/author.dart @@ -1,36 +1,27 @@ -import 'package:json_annotation/json_annotation.dart'; - +import '../model_owner.dart'; import 'nameplate.dart'; import 'official_verify.dart'; import 'pendant.dart'; import 'vip.dart'; -part 'author.g.dart'; +class Author extends Owner { + Pendant? pendant; + OfficialVerify? officialVerify; + Nameplate? nameplate; + Vip? vip; -@JsonSerializable() -class Author { - int? mid; - String? name; - String? face; - Pendant? pendant; - @JsonKey(name: 'official_verify') - OfficialVerify? officialVerify; - Nameplate? nameplate; - Vip? vip; - - Author({ - this.mid, - this.name, - this.face, - this.pendant, - this.officialVerify, - this.nameplate, - this.vip, - }); - - factory Author.fromJson(Map json) { - return _$AuthorFromJson(json); - } - - Map toJson() => _$AuthorToJson(this); + Author.fromJson(Map json) { + mid = json['mid']; + name = json['name'] as String?; + face = json['face'] as String?; + pendant = + json['pendant'] == null ? null : Pendant.fromJson(json['pendant']); + officialVerify = json['official_verify'] == null + ? null + : OfficialVerify.fromJson(json['official_verify']); + nameplate = json['nameplate'] == null + ? null + : Nameplate.fromJson(json['nameplate']); + vip = json['vip'] == null ? null : Vip.fromJson(json['vip']); + } } diff --git a/lib/models/space_article/author.g.dart b/lib/models/space_article/author.g.dart index 349368dc..8b137891 100644 --- a/lib/models/space_article/author.g.dart +++ b/lib/models/space_article/author.g.dart @@ -1,36 +1 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND -part of 'author.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Author _$AuthorFromJson(Map 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), - officialVerify: json['official_verify'] == null - ? null - : OfficialVerify.fromJson( - json['official_verify'] as Map), - nameplate: json['nameplate'] == null - ? null - : Nameplate.fromJson(json['nameplate'] as Map), - vip: json['vip'] == null - ? null - : Vip.fromJson(json['vip'] as Map), - ); - -Map _$AuthorToJson(Author instance) => { - 'mid': instance.mid, - 'name': instance.name, - 'face': instance.face, - 'pendant': instance.pendant, - 'official_verify': instance.officialVerify, - 'nameplate': instance.nameplate, - 'vip': instance.vip, - }; diff --git a/lib/models/space_article/item.dart b/lib/models/space_article/item.dart index e261f611..d5aa57cb 100644 --- a/lib/models/space_article/item.dart +++ b/lib/models/space_article/item.dart @@ -1,107 +1,142 @@ -import 'package:json_annotation/json_annotation.dart'; +import 'package:PiliPlus/models/dynamics/article_content_model.dart'; import 'author.dart'; import 'category.dart'; import 'media.dart'; import 'stats.dart'; -part 'item.g.dart'; - -@JsonSerializable() class Item { int? id; Category? category; List? categories; String? title; String? summary; - @JsonKey(name: 'banner_url') String? bannerUrl; - @JsonKey(name: 'template_id') int? templateId; int? state; Author? author; int? reprint; - @JsonKey(name: 'image_urls') List? imageUrls; - @JsonKey(name: 'publish_time') int? publishTime; int? ctime; int? mtime; Stats? stats; - int? attributes; int? words; - @JsonKey(name: 'origin_image_urls') List? originImageUrls; dynamic list; - @JsonKey(name: 'is_like') bool? isLike; Media? media; - @JsonKey(name: 'apply_time') String? applyTime; - @JsonKey(name: 'check_time') String? checkTime; int? original; - @JsonKey(name: 'act_id') int? actId; dynamic dispute; dynamic authenMark; - @JsonKey(name: 'cover_avid') int? coverAvid; - @JsonKey(name: 'top_video_info') dynamic topVideoInfo; int? type; - @JsonKey(name: 'check_state') int? checkState; - @JsonKey(name: 'origin_template_id') int? originTemplateId; + + // 动态 String? uri; String? param; String? goto; - @JsonKey(name: 'publish_time_text') String? publishTimeText; String? dyn; - Item({ - 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.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, - }); + // 专栏 + List? tags; + int? privatePub; + dynamic contentPicList; + String? content; + String? keywords; + Opus? opus; + int? versionId; + String? dynIdStr; + int? totalArtNum; - factory Item.fromJson(Map json) => _$ItemFromJson(json); + Item.fromJson(Map 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(); + 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(); + 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 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 json) { + tid = json["tid"]; + name = json["name"]; + } +} + +class Opus { + int? opusid; + int? opussource; + String? title; + List? content; + // PubInfo? pubinfo; + // Article? article; + // Version? version; + + Opus.fromJson(Map 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(); + } + } } diff --git a/lib/models/space_article/item.g.dart b/lib/models/space_article/item.g.dart deleted file mode 100644 index 988487a4..00000000 --- a/lib/models/space_article/item.g.dart +++ /dev/null @@ -1,101 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'item.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Item _$ItemFromJson(Map json) => Item( - id: (json['id'] as num?)?.toInt(), - category: json['category'] == null - ? null - : Category.fromJson(json['category'] as Map), - categories: (json['categories'] as List?) - ?.map((e) => Category.fromJson(e as Map)) - .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), - reprint: (json['reprint'] as num?)?.toInt(), - imageUrls: (json['image_urls'] as List?) - ?.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), - attributes: (json['attributes'] as num?)?.toInt(), - words: (json['words'] as num?)?.toInt(), - originImageUrls: (json['origin_image_urls'] as List?) - ?.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), - 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 _$ItemToJson(Item instance) => { - '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, - }; diff --git a/lib/pages/article/controller.dart b/lib/pages/article/controller.dart index 2adbe411..77b51920 100644 --- a/lib/pages/article/controller.dart +++ b/lib/pages/article/controller.dart @@ -3,14 +3,17 @@ import 'package:PiliPlus/http/dynamics.dart'; import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/http/user.dart'; import 'package:PiliPlus/http/video.dart'; -import 'package:PiliPlus/models/dynamics/article_view/data.dart'; -import 'package:PiliPlus/models/dynamics/opus_detail/data.dart'; -import 'package:PiliPlus/models/dynamics/opus_detail/favorite.dart'; +import 'package:PiliPlus/models/dynamics/article_content_model.dart' + show ArticleContentModel; 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/mine/controller.dart'; import 'package:PiliPlus/utils/storage.dart'; import 'package:PiliPlus/utils/url_utils.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; import 'package:PiliPlus/http/reply.dart'; @@ -20,9 +23,10 @@ class ArticleController extends ReplyController { late String id; late String type; - late final String url; + late String url; late int commentType; - dynamic commentId; + late int commentId; + final summary = Summary(); RxBool showTitle = false.obs; @@ -30,14 +34,15 @@ class ArticleController extends ReplyController { late final showDynActionBar = GStorage.showDynActionBar; @override - dynamic get sourceId => id; + dynamic get sourceId => commentType == 12 ? 'cv$commentId' : id; - RxBool isLoaded = false.obs; - late ArticleData articleData; - late OpusData opusData; + final RxBool isLoaded = false.obs; + DynamicItemModel? opusData; // 采用opus信息作为动态信息, 标题信息从summary获取 + Item? articleData; + final Rx stats = Rx(null); - late final Rx item = DynamicItemModel().obs; - late final RxMap favStat = {'status': false}.obs; + List? get opus => + opusData?.modules.moduleContent ?? articleData?.opus?.content; @override void onInit() { @@ -45,6 +50,13 @@ class ArticleController extends ReplyController { id = Get.parameters['id']!; 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 if (type == 'read') { UrlUtils.parseRedirectUrl('https://www.bilibili.com/read/cv$id/') @@ -60,101 +72,92 @@ class ArticleController extends ReplyController { } } - init() { + setUrl() { url = type == 'read' ? 'https://www.bilibili.com/read/cv$id' : 'https://www.bilibili.com/opus/$id'; + } + + init() { + setUrl(); commentType = type == 'picture' ? 11 : 12; - if (Get.arguments?['item'] is DynamicItemModel) { - item.value = Get.arguments['item']; - } - - _queryDynItem(); _queryContent(); } - _queryDynItem() async { - if (showDynActionBar) { - if (type == 'read') { - if (item.value.idStr == null) { - UrlUtils.parseRedirectUrl('https://www.bilibili.com/read/cv$id/') - .then((url) { - if (url != null) { - _queryDyn(url.split('/').last); - } - }); - } - _queryInfo(); - } else { - _queryDyn(id); + Future queryOpus(opusId) async { + final res = await DynamicsHttp.opusDetail(opusId: opusId); + if (res is Success) { + opusData = (res as Success).response; + //fallback + if (opusData?.fallback?.id != null) { + id = opusData!.fallback!.id!; + type = 'read'; + setUrl(); + _queryContent(); + return false; } + 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() { - DynamicsHttp.articleInfo(cvId: id).then((res) { - if (res['status']) { - favStat.addAll({ - 'status': true, - 'isFav': res['data']?['favorite'] ?? false, - 'favNum': res['data']?['stats']?['favorite'] ?? 0, - 'data': res['data'], - }); - } - }); - } + Future queryRead(cvid) async { + final res = await DynamicsHttp.articleView(cvId: cvid); + if (res is Success) { + articleData = (res as Success).response; + summary + ..author ??= articleData!.author + ..title ??= articleData!.title + ..cover ??= articleData!.originImageUrls?.firstOrNull; - _queryDyn(id) { - if (item.value.idStr != null) { - return; - } - 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; + if (showDynActionBar && opusData?.modules.moduleStat == null) { + final dynId = articleData!.dynIdStr; + if (dynId != null) { + _queryReadAsDyn(dynId); } else { - commentType = opusData.item?.basic?.commentType ?? - (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, - }); + debugPrint('cvid2opus failed: $id'); } + _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) { VideoHttp.historyReport(aid: commentId, type: 5); } - - queryData(); } } @@ -177,22 +180,48 @@ class ArticleController extends ReplyController { } Future onFav() async { - bool isFav = favStat['isFav'] == true; + bool isFav = stats.value?.favorite?.status == true; final res = type == 'read' ? isFav - ? await UserHttp.delFavArticle(id: id) - : await UserHttp.addFavArticle(id: id) + ? await UserHttp.delFavArticle(id: commentId) + : await UserHttp.addFavArticle(id: commentId) : await UserHttp.communityAction(opusId: id, action: isFav ? 4 : 3); if (res['status']) { - favStat['isFav'] = !isFav; + stats.value?.favorite?.status = !isFav; + var count = stats.value?.favorite?.count ?? 0; if (isFav) { - favStat['favNum'] -= 1; + stats.value?.favorite?.count = count - 1; } else { - favStat['favNum'] += 1; + stats.value?.favorite?.count = count + 1; } + stats.refresh(); SmartDialog.showToast('${isFav ? '取消' : ''}收藏成功'); } else { 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}); } diff --git a/lib/pages/article/view.dart b/lib/pages/article/view.dart index ed43a014..445d3b28 100644 --- a/lib/pages/article/view.dart +++ b/lib/pages/article/view.dart @@ -1,6 +1,7 @@ import 'dart:math'; 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/html_render.dart'; import 'package:PiliPlus/common/widgets/http_error.dart'; @@ -338,101 +339,98 @@ class _ArticlePageState extends State sliver: Obx( () { if (_articleCtr.isLoaded.value) { - if (_articleCtr.type == 'read') { - late final res = parser.parse(_articleCtr.articleData.content); - return SliverMainAxisGroup( - slivers: [ - if (_articleCtr.articleData.title != null) - SliverToBoxAdapter( - child: Text( - _articleCtr.articleData.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.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), - ), - ], + late Widget content; + if (_articleCtr.opus == null) { + debugPrint('html page'); + final res = parser.parse(_articleCtr.articleData!.content!); + content = 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 { - return opusContent( + debugPrint('json page'); + content = opusContent( context: context, - modules: _articleCtr.opusData.item?.modules, + opus: _articleCtr.opus!, callback: _getImageCallback, 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(); @@ -543,11 +541,7 @@ class _ArticlePageState extends State PreferredSizeWidget get _buildAppBar => AppBar( title: Obx(() { if (_articleCtr.isLoaded.value && _articleCtr.showTitle.value) { - return Text(_articleCtr.type == 'read' - ? _articleCtr.articleData.title ?? '' - : _articleCtr.opusData.item?.modules?.firstOrNull?.moduleTitle - ?.text ?? - ''); + return Text(_articleCtr.summary.title ?? ''); } return const SizedBox.shrink(); }), @@ -628,23 +622,21 @@ class _ArticlePageState extends State ], ), ), - if (_articleCtr.type == 'read' && _articleCtr.favStat['status']) + if (_articleCtr.commentType == 12 && + _articleCtr.stats.value != null) PopupMenuItem( onTap: () { try { PageUtils.pmShare( content: { - "id": _articleCtr.id, + "id": _articleCtr.commentId, "title": "- 哔哩哔哩专栏", - "headline": _articleCtr.favStat['data']['title'], + "headline": _articleCtr.summary.title!, // throw "source": 6, - "thumb": (_articleCtr.favStat['data'] - ['origin_image_urls'] as List?) - ?.firstOrNull ?? - '', - "author": _articleCtr.favStat['data']['author_name'], + "thumb": _articleCtr.summary.cover!, + "author": _articleCtr.summary.author!.name, "author_id": - _articleCtr.favStat['data']['mid'].toString(), + _articleCtr.summary.author!.mid.toString(), }, ); } catch (e) { @@ -704,8 +696,38 @@ class _ArticlePageState extends State child: button(), ), ) - : Obx( - () => Column( + : Obx(() { + 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, crossAxisAlignment: CrossAxisAlignment.end, children: [ @@ -713,13 +735,13 @@ class _ArticlePageState extends State padding: EdgeInsets.only( right: 14, bottom: 14 + - (_articleCtr.favStat['status'] + (_articleCtr.stats.value != null ? 0 : MediaQuery.of(context).padding.bottom), ), child: button(), ), - _articleCtr.favStat['status'] + _articleCtr.stats.value != null ? Container( decoration: BoxDecoration( color: @@ -743,34 +765,36 @@ class _ArticlePageState extends State Expanded( child: Builder( builder: (btnContext) => - TextButton.icon( - onPressed: () { + textIconButton( + text: '转发', + icon: FontAwesomeIcons + .shareFromSquare, + stat: _articleCtr + .stats.value?.forward, + callback: () { showModalBottomSheet( context: context, isScrollControlled: true, useSafeArea: true, builder: (context) => RepostPanel( - item: _articleCtr.item.value, + item: _articleCtr.opusData, + pic: + _articleCtr.summary.cover, + title: + _articleCtr.summary.title, callback: () { - int count = int.tryParse( - _articleCtr - .item - .value - .modules - ?.moduleStat - ?.forward - ?.count ?? - '0') ?? + int count = _articleCtr + .stats + .value + ?.forward + ?.count ?? 0; _articleCtr - .item - .value - .modules - ?.moduleStat - ?.forward! - .count = - (count + 1).toString(); + .stats + .value + ?.forward + ?.count = count + 1; if (btnContext.mounted) { (btnContext as Element?) ?.markNeedsBuild(); @@ -779,108 +803,34 @@ class _ArticlePageState extends State ), ); }, - 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( - child: TextButton.icon( - onPressed: () { - Utils.shareText(_articleCtr.url); - }, - icon: Icon( - FontAwesomeIcons.shareNodes, - 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: const Text('分享'), - ), - ), - if (_articleCtr.favStat['status']) + child: textIconButton( + text: '分享', + icon: FontAwesomeIcons.shareNodes, + stat: null, + callback: () => + Utils.shareText(_articleCtr.url), + )), + if (_articleCtr.stats.value != null) Expanded( - child: TextButton.icon( - onPressed: () { - _articleCtr.onFav(); - }, - icon: Icon( - _articleCtr.favStat['isFav'] == - true - ? FontAwesomeIcons.solidStar - : 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()), - ), - ), + child: textIconButton( + icon: FontAwesomeIcons.star, + activitedIcon: + FontAwesomeIcons.solidStar, + text: '收藏', + stat: + _articleCtr.stats.value!.favorite, + callback: _articleCtr.onFav, + )), Expanded( child: Builder( builder: (context) => TextButton.icon( onPressed: () => RequestUtils.onLikeDynamic( - _articleCtr.item.value, + _articleCtr.opusData!, () { if (context.mounted) { (context as Element?) @@ -889,25 +839,15 @@ class _ArticlePageState extends State }, ), icon: Icon( - _articleCtr - .item - .value - .modules - ?.moduleStat - ?.like + _articleCtr.stats.value?.like ?.status == true ? FontAwesomeIcons .solidThumbsUp : FontAwesomeIcons.thumbsUp, size: 16, - color: _articleCtr - .item - .value - .modules - ?.moduleStat - ?.like - ?.status == + color: _articleCtr.stats.value + ?.like?.status == true ? Theme.of(context) .colorScheme @@ -916,10 +856,8 @@ class _ArticlePageState extends State .colorScheme .outline, semanticLabel: _articleCtr - .item + .stats .value - .modules - ?.moduleStat ?.like ?.status == true @@ -928,8 +866,8 @@ class _ArticlePageState extends State ), style: TextButton.styleFrom( padding: - const EdgeInsets.fromLTRB( - 15, 0, 15, 0), + const EdgeInsets.symmetric( + horizontal: 15), foregroundColor: Theme.of(context) .colorScheme .outline, @@ -944,31 +882,16 @@ class _ArticlePageState extends State child: child); }, child: Text( - _articleCtr - .item - .value - .modules - ?.moduleStat - ?.like + _articleCtr.stats.value?.like ?.count != null ? Utils.numFormat( - _articleCtr - .item - .value - .modules! - .moduleStat! - .like! - .count) + _articleCtr.stats.value! + .like!.count) : '点赞', style: TextStyle( - color: _articleCtr - .item - .value - .modules - ?.moduleStat - ?.like - ?.status == + color: _articleCtr.stats.value + ?.like?.status == true ? Theme.of(context) .colorScheme @@ -987,8 +910,8 @@ class _ArticlePageState extends State ) : const SizedBox.shrink(), ], - ), - ); + ); + }); }, ), ), diff --git a/lib/pages/article/widgets/html_render.dart b/lib/pages/article/widgets/html_render.dart index 04cfe83a..dc8c5454 100644 --- a/lib/pages/article/widgets/html_render.dart +++ b/lib/pages/article/widgets/html_render.dart @@ -70,6 +70,7 @@ Widget htmlRender({ ), ); } catch (err) { + debugPrint('错误的HTML: $element'); return const SizedBox.shrink(); } }, diff --git a/lib/pages/article/widgets/opus_content.dart b/lib/pages/article/widgets/opus_content.dart index 46253db9..931695af 100644 --- a/lib/pages/article/widgets/opus_content.dart +++ b/lib/pages/article/widgets/opus_content.dart @@ -2,14 +2,14 @@ import 'package:PiliPlus/common/constants.dart'; import 'package:PiliPlus/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart' show SourceModel; 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/extension.dart'; import 'package:PiliPlus/utils/utils.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; -import 'package:get/get.dart'; import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; import 'package:re_highlight/languages/all.dart'; import 'package:re_highlight/re_highlight.dart'; @@ -17,339 +17,257 @@ import 'package:re_highlight/styles/all.dart'; Widget opusContent({ required BuildContext context, - required List? modules, + required List opus, Function(List, int)? callback, required double maxWidth, }) { debugPrint('opusContent'); - if (modules.isNullOrEmpty) { + if (opus.isEmpty) { return const SliverToBoxAdapter(); } - - return SliverMainAxisGroup( - slivers: modules!.map((item) { + final colorScheme = Theme.of(context).colorScheme; + return SliverList.separated( + itemCount: opus.length, + itemBuilder: (context, index) { + final element = opus[index]; try { - return switch (item.moduleType) { - // - 'MODULE_TYPE_TITLE' => SliverToBoxAdapter( - child: Text( - item.moduleTitle!.text!, - style: TextStyle( - fontSize: 17, - fontWeight: FontWeight.bold, + switch (element.paraType) { + case 1 || 4: + return SelectableText.rich( + textAlign: element.align == 1 ? TextAlign.center : null, + TextSpan( + children: element.text?.nodes?.map((item) { + if (item.rich != null) { + 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, ), ), - ), - - // - 'MODULE_TYPE_AUTHOR' => SliverToBoxAdapter( - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 10), - child: GestureDetector( - onTap: () { - Get.toNamed('/member?mid=${item.moduleAuthor?.mid}'); - }, + ); + case 3 when (element.line != null): + return CachedNetworkImage( + width: maxWidth, + fit: BoxFit.contain, + height: element.line?.pic?.height?.toDouble(), + imageUrl: Utils.thumbnailImgUrl(element.line!.pic!.url!), + ); + 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( children: [ NetworkImgLayer( - width: 40, - height: 40, - type: 'avatar', - src: item.moduleAuthor?.face, + radius: 6, + width: 65 * StyleString.aspectRatio, + height: 65, + src: element.linkCard!.card!.ugc!.cover, ), const SizedBox(width: 10), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - item.moduleAuthor!.name!, - style: TextStyle( - fontSize: Theme.of(context) - .textTheme - .titleSmall! - .fontSize, - ), - ), - if (item.moduleAuthor?.pubTime != null) + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(element.linkCard!.card!.ugc!.title!), Text( - item.moduleAuthor!.pubTime!, + element.linkCard!.card!.ugc!.descSecond!, style: TextStyle( - color: Theme.of(context).colorScheme.outline, - fontSize: Theme.of(context) - .textTheme - .labelSmall! - .fontSize, + fontSize: 13, + color: colorScheme.outline, ), ), - ], + ], + ), ), ], ), ), ), - ), - - // - 'MODULE_TYPE_CONTENT' => SliverList.separated( - itemCount: item.moduleContent!.paragraphs!.length, - itemBuilder: (context, index) { - final element = item.moduleContent!.paragraphs![index]; - - if (element.paraType == 1 || element.paraType == 4) { - return SelectableText.rich( - textAlign: element.align == 1 ? TextAlign.center : null, - TextSpan( - children: element.text?.nodes?.map((item) { - if (item.rich != null) { - 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: Theme.of(context).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()), - ); - } - - 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, - ), + ); + case 7 when (element.code != null): + final Highlight highlight = Highlight() + ..registerLanguages(builtinAllLanguages); + final HighlightResult result = highlight.highlightAuto( + element.code!.content!, + element.code!.lang == 'language-clike' + ? const ['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: colorScheme.onInverseSurface, + ), + width: double.infinity, + child: SelectableText.rich(renderer.span!), + ); + default: + debugPrint('unknown type ${element.paraType}'); + if (element.text?.nodes?.isNotEmpty == true) { + return SelectableText.rich( + textAlign: element.align == 1 ? TextAlign.center : null, + TextSpan( + children: element.text!.nodes!.map((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()), + ); + } - if (element.paraType == 3) { - return CachedNetworkImage( - width: maxWidth, - fit: BoxFit.contain, - 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((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(), - }; + return SelectableText('不支持的类型 (${element.paraType})', + style: const TextStyle( + fontWeight: FontWeight.bold, + color: Colors.red, + )); + } } 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), ); } diff --git a/lib/pages/dynamics/detail/controller.dart b/lib/pages/dynamics/detail/controller.dart index c0fba446..d286c852 100644 --- a/lib/pages/dynamics/detail/controller.dart +++ b/lib/pages/dynamics/detail/controller.dart @@ -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/loading_state.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/pages/common/reply_controller.dart'; import 'package:PiliPlus/utils/id_utils.dart'; @@ -31,7 +30,7 @@ class DynamicDetailController extends ReplyController { item = Get.arguments['item']; floor = Get.arguments['floor']; if (floor == 1) { - count.value = int.parse(item.modules!.moduleStat!.comment!.count ?? '0'); + count.value = item.modules.moduleStat?.comment?.count ?? 0; } if (oid != 0) { @@ -41,10 +40,10 @@ class DynamicDetailController extends ReplyController { getCommentParams(int id) async { var res = await DynamicsHttp.opusDetail(opusId: id); - if (res['status']) { - OpusData data = res['data']; - type = data.item!.basic!.commentType!; - oid = int.parse(data.item!.basic!.commentIdStr!); + if (res is Success) { + final data = (res as Success).response; + type = data.basic!.commentType!; + oid = int.parse(data.basic!.commentIdStr!); queryData(); } } diff --git a/lib/pages/dynamics/detail/view.dart b/lib/pages/dynamics/detail/view.dart index aad93247..e7699fd1 100644 --- a/lib/pages/dynamics/detail/view.dart +++ b/lib/pages/dynamics/detail/view.dart @@ -118,14 +118,15 @@ class _DynamicDetailPageState extends State // 楼层 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; if (floor == 1) { - oid = int.parse(args['item'].basic!['comment_id_str']); + oid = int.parse(item.basic!.commentIdStr!); } else { try { - ModuleDynamicModel moduleDynamic = args['item'].modules.moduleDynamic; + final moduleDynamic = item.modules.moduleDynamic!; String majorType = moduleDynamic.major!.type!; if (majorType == 'MAJOR_TYPE_OPUS') { @@ -528,32 +529,31 @@ class _DynamicDetailPageState extends State item: _dynamicDetailController .item, callback: () { - int count = int.tryParse( - _dynamicDetailController - .item - .modules - ?.moduleStat - ?.forward - ?.count ?? - '0') ?? - 0; + int count = + _dynamicDetailController + .item + .modules + .moduleStat + ?.forward + ?.count ?? + 0; _dynamicDetailController .item .modules - ?.moduleStat ??= + .moduleStat ??= ModuleStatModel(); - _dynamicDetailController - .item - .modules! - .moduleStat - ?.forward ??= ForWard(); _dynamicDetailController .item - .modules! - .moduleStat! - .forward! - .count = - (count + 1).toString(); + .modules + .moduleStat + ?.forward ??= + DynamicStat(); + _dynamicDetailController + .item + .modules + .moduleStat! + .forward! + .count = count + 1; if (btnContext.mounted) { (btnContext as Element?) ?.markNeedsBuild(); @@ -581,14 +581,14 @@ class _DynamicDetailPageState extends State _dynamicDetailController .item .modules - ?.moduleStat + .moduleStat ?.forward ?.count != null ? Utils.numFormat( _dynamicDetailController .item - .modules! + .modules .moduleStat! .forward! .count) @@ -638,7 +638,7 @@ class _DynamicDetailPageState extends State _dynamicDetailController .item .modules - ?.moduleStat + .moduleStat ?.like ?.status == true @@ -648,7 +648,7 @@ class _DynamicDetailPageState extends State color: _dynamicDetailController .item .modules - ?.moduleStat + .moduleStat ?.like ?.status == true @@ -662,7 +662,7 @@ class _DynamicDetailPageState extends State _dynamicDetailController .item .modules - ?.moduleStat + .moduleStat ?.like ?.status == true @@ -689,14 +689,14 @@ class _DynamicDetailPageState extends State _dynamicDetailController .item .modules - ?.moduleStat + .moduleStat ?.like ?.count != null ? Utils.numFormat( _dynamicDetailController .item - .modules! + .modules .moduleStat! .like! .count) @@ -705,7 +705,7 @@ class _DynamicDetailPageState extends State color: _dynamicDetailController .item .modules - ?.moduleStat + .moduleStat ?.like ?.status == true diff --git a/lib/pages/dynamics/repost_dyn_panel.dart b/lib/pages/dynamics/repost_dyn_panel.dart index 346860fc..a1be0447 100644 --- a/lib/pages/dynamics/repost_dyn_panel.dart +++ b/lib/pages/dynamics/repost_dyn_panel.dart @@ -34,7 +34,7 @@ class RepostPanel extends CommonPublishPage { final String? uname; final bool? isMax; - final dynamic item; + final DynamicItemModel? item; final VoidCallback? callback; @override @@ -44,53 +44,19 @@ class RepostPanel extends CommonPublishPage { class _RepostPanelState extends CommonPublishPageState { late bool _isMax = widget.isMax ?? false; - late final dynamic _pic = widget.pic ?? - (widget.item as DynamicItemModel?) - ?.modules - ?.moduleDynamic - ?.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 _pic = widget.pic ?? + widget.item?.modules.moduleDynamic?.major?.archive?.cover ?? + widget.item?.modules.moduleDynamic?.major?.pgc?.cover ?? + widget.item?.modules.moduleDynamic?.major?.opus?.pics?.firstOrNull?.url; late final _text = widget.title ?? - (widget.item as DynamicItemModel?) - ?.modules - ?.moduleDynamic - ?.major - ?.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 ?? + widget.item?.modules.moduleDynamic?.major?.opus?.summary?.text ?? + widget.item?.modules.moduleDynamic?.desc?.text ?? + widget.item?.modules.moduleDynamic?.major?.archive?.title ?? + widget.item?.modules.moduleDynamic?.major?.pgc?.title ?? ''; - late final _uname = widget.uname ?? - (widget.item as DynamicItemModel?)?.modules?.moduleAuthor?.name; + late final _uname = widget.uname ?? widget.item?.modules.moduleAuthor?.name; @override void dispose() { diff --git a/lib/pages/dynamics/tab/view.dart b/lib/pages/dynamics/tab/view.dart index 8a39d53d..20c79808 100644 --- a/lib/pages/dynamics/tab/view.dart +++ b/lib/pages/dynamics/tab/view.dart @@ -162,7 +162,7 @@ class _DynamicsTabPageState ] else ...[ for (var i in loadingState.response!) if (!dynamicsController.tempBannedList - .contains(i.modules?.moduleAuthor?.mid)) + .contains(i.modules.moduleAuthor?.mid)) DynamicPanel( item: i, onRemove: controller.onRemove, @@ -185,7 +185,7 @@ class _DynamicsTabPageState 4 && dynamicsController.mid.value != -1) || !dynamicsController.tempBannedList.contains( - item.modules?.moduleAuthor?.mid)) { + item.modules.moduleAuthor?.mid)) { return DynamicPanel( item: item, onRemove: controller.onRemove, diff --git a/lib/pages/dynamics/widgets/action_panel.dart b/lib/pages/dynamics/widgets/action_panel.dart index e19ea19c..b0e2b589 100644 --- a/lib/pages/dynamics/widgets/action_panel.dart +++ b/lib/pages/dynamics/widgets/action_panel.dart @@ -12,9 +12,9 @@ import 'package:PiliPlus/utils/feed_back.dart'; class ActionPanel extends StatefulWidget { const ActionPanel({ super.key, - this.item, + required this.item, }); - final dynamic item; + final DynamicItemModel item; @override State createState() => _ActionPanelState(); @@ -33,26 +33,22 @@ class _ActionPanelState extends State { // 动态点赞 Future onLikeDynamic() async { feedBack(); - var item = widget.item!; + final item = widget.item; String dynamicId = item.idStr!; // 1 已点赞 2 不喜欢 0 未操作 - Like like = item.modules.moduleStat.like; - int count = like.count == '点赞' ? 0 : int.parse(like.count ?? '0'); - bool status = like.status!; + DynamicStat? like = item.modules.moduleStat?.like; + int count = like?.count ?? 0; + bool status = like?.status == true; int up = status ? 2 : 1; var res = await DynamicsHttp.likeDynamic(dynamicId: dynamicId, up: up); if (res['status']) { SmartDialog.showToast(!status ? '点赞成功' : '取消赞'); if (up == 1) { - item.modules.moduleStat.like.count = (count + 1).toString(); - item.modules.moduleStat.like.status = true; + item.modules.moduleStat?.like?.count = count + 1; + item.modules.moduleStat?.like?.status = true; } else { - if (count == 1) { - item.modules.moduleStat.like.count = '点赞'; - } else { - item.modules.moduleStat.like.count = (count - 1).toString(); - } - item.modules.moduleStat.like.status = false; + item.modules.moduleStat?.like?.count = count - 1; + item.modules.moduleStat?.like?.status = false; } setState(() {}); } else { @@ -78,12 +74,9 @@ class _ActionPanelState extends State { builder: (context) => RepostPanel( item: widget.item, callback: () { - int count = int.tryParse( - widget.item!.modules.moduleStat.forward?.count ?? - '0') ?? - 0; - widget.item!.modules.moduleStat.forward!.count = - (count + 1).toString(); + int count = + widget.item.modules.moduleStat?.forward?.count ?? 0; + widget.item.modules.moduleStat!.forward!.count = count + 1; setState(() {}); }, ), @@ -100,9 +93,9 @@ class _ActionPanelState extends State { foregroundColor: Theme.of(context).colorScheme.outline, ), label: Text( - widget.item!.modules.moduleStat.forward!.count != null + widget.item.modules.moduleStat!.forward!.count != null ? Utils.numFormat( - widget.item!.modules.moduleStat.forward!.count) + widget.item.modules.moduleStat!.forward!.count) : '转发', ), ), @@ -123,9 +116,9 @@ class _ActionPanelState extends State { foregroundColor: Theme.of(context).colorScheme.outline, ), label: Text( - widget.item!.modules.moduleStat.comment!.count != null + widget.item.modules.moduleStat!.comment!.count != null ? Utils.numFormat( - widget.item!.modules.moduleStat.comment!.count) + widget.item.modules.moduleStat!.comment!.count) : '评论', ), ), @@ -135,15 +128,15 @@ class _ActionPanelState extends State { child: TextButton.icon( onPressed: () => handleState(onLikeDynamic), icon: Icon( - widget.item!.modules.moduleStat.like!.status! + widget.item.modules.moduleStat!.like!.status! ? FontAwesomeIcons.solidThumbsUp : FontAwesomeIcons.thumbsUp, size: 16, - color: widget.item!.modules.moduleStat.like!.status! + color: widget.item.modules.moduleStat!.like!.status! ? primary : color, semanticLabel: - widget.item!.modules.moduleStat.like!.status! ? "已赞" : "点赞", + widget.item.modules.moduleStat!.like!.status! ? "已赞" : "点赞", ), style: TextButton.styleFrom( padding: const EdgeInsets.fromLTRB(15, 0, 15, 0), @@ -155,14 +148,15 @@ class _ActionPanelState extends State { return ScaleTransition(scale: animation, child: child); }, child: Text( - widget.item!.modules.moduleStat.like!.count != null + widget.item.modules.moduleStat!.like!.count != null ? Utils.numFormat( - widget.item!.modules.moduleStat.like!.count) + widget.item.modules.moduleStat!.like!.count) : '点赞', key: ValueKey( - widget.item!.modules.moduleStat.like!.count ?? '点赞'), + widget.item.modules.moduleStat!.like!.count?.toString() ?? + '点赞'), style: TextStyle( - color: widget.item!.modules.moduleStat.like!.status! + color: widget.item.modules.moduleStat!.like!.status! ? primary : color, ), diff --git a/lib/pages/dynamics/widgets/author_panel.dart b/lib/pages/dynamics/widgets/author_panel.dart index 8bc1335a..e96a8f28 100644 --- a/lib/pages/dynamics/widgets/author_panel.dart +++ b/lib/pages/dynamics/widgets/author_panel.dart @@ -4,6 +4,7 @@ import 'package:PiliPlus/common/widgets/avatar.dart'; import 'package:PiliPlus/common/widgets/report.dart'; import 'package:PiliPlus/common/widgets/save_panel.dart'; import 'package:PiliPlus/http/video.dart'; +import 'package:PiliPlus/models/dynamics/result.dart'; import 'package:PiliPlus/utils/extension.dart'; import 'package:PiliPlus/utils/page_utils.dart'; import 'package:PiliPlus/utils/request_utils.dart'; @@ -20,7 +21,7 @@ import '../../../http/constants.dart'; import '../controller.dart'; class AuthorPanel extends StatelessWidget { - final dynamic item; + final DynamicItemModel item; final Function? addBannedList; final String? source; final Function? onRemove; @@ -40,7 +41,7 @@ class AuthorPanel extends StatelessWidget { Widget _buildAvatar() { String? pendant = item.modules.moduleAuthor?.pendant?['image']; Widget avatar = Avatar( - avatar: item.modules.moduleAuthor.face, + avatar: item.modules.moduleAuthor?.face ?? '', size: pendant.isNullOrEmpty ? 40 : 34, isVip: null, // item.modules.moduleAuthor!.vip['status'] > 0 officialType: null, // 已被注释 @@ -55,14 +56,14 @@ class AuthorPanel extends StatelessWidget { @override Widget build(BuildContext context) { final theme = Theme.of(context); - String? pubTime = item.modules.moduleAuthor.pubTs != null + final pubTime = item.modules.moduleAuthor?.pubTs != null ? isSave ? DateTime.fromMillisecondsSinceEpoch( - item.modules.moduleAuthor.pubTs * 1000) + item.modules.moduleAuthor!.pubTs! * 1000) .toString() .substring(0, 19) - : Utils.dateFormat(item.modules.moduleAuthor.pubTs) - : item.modules.moduleAuthor.pubTime; + : Utils.dateFormat(item.modules.moduleAuthor!.pubTs) + : item.modules.moduleAuthor?.pubTime; return Stack( alignment: Alignment.center, children: [ @@ -71,17 +72,17 @@ class AuthorPanel extends StatelessWidget { child: Row( mainAxisSize: MainAxisSize.min, children: [ - (item.modules.moduleAuthor.type == 'AUTHOR_TYPE_PGC' || - item.modules.moduleAuthor.type == + (item.modules.moduleAuthor!.type == 'AUTHOR_TYPE_PGC' || + item.modules.moduleAuthor!.type == 'AUTHOR_TYPE_UGC_SEASON') ? _buildAvatar() // 番剧 : GestureDetector( onTap: () { feedBack(); Get.toNamed( - '/member?mid=${item.modules.moduleAuthor.mid}', + '/member?mid=${item.modules.moduleAuthor!.mid}', arguments: { - 'face': item.modules.moduleAuthor.face, + 'face': item.modules.moduleAuthor!.face, }, ); }, @@ -92,11 +93,11 @@ class AuthorPanel extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - item.modules.moduleAuthor.name, + item.modules.moduleAuthor?.name ?? '', style: TextStyle( color: item.modules.moduleAuthor!.vip != null && - item.modules.moduleAuthor!.vip['status'] > 0 && - item.modules.moduleAuthor!.vip['type'] == 2 + item.modules.moduleAuthor!.vip!['status'] > 0 && + item.modules.moduleAuthor!.vip!['type'] == 2 ? context.vipColor : theme.colorScheme.onSurface, fontSize: theme.textTheme.titleSmall!.fontSize, @@ -104,7 +105,7 @@ class AuthorPanel extends StatelessWidget { ), if (pubTime != null) Text( - '$pubTime${item.modules.moduleAuthor.pubAction != null ? ' ${item.modules.moduleAuthor.pubAction}' : ''}', + '$pubTime${item.modules.moduleAuthor?.pubAction != null ? ' ${item.modules.moduleAuthor!.pubAction}' : ''}', style: TextStyle( color: theme.colorScheme.outline, fontSize: theme.textTheme.labelSmall!.fontSize, @@ -117,7 +118,7 @@ class AuthorPanel extends StatelessWidget { ), Align( alignment: Alignment.centerRight, - child: source != 'detail' && item.modules?.moduleTag?.text != null + child: source != 'detail' && item.modules.moduleTag?.text != null ? Row( mainAxisSize: MainAxisSize.min, children: [ @@ -133,7 +134,7 @@ class AuthorPanel extends StatelessWidget { ), ), child: Text( - item.modules.moduleTag.text, + item.modules.moduleTag!.text!, style: TextStyle( height: 1, fontSize: 12, @@ -149,7 +150,7 @@ class AuthorPanel extends StatelessWidget { _moreWidget(context), ], ) - : item.modules.moduleAuthor.decorate != null + : item.modules.moduleAuthor!.decorate != null ? Row( mainAxisSize: MainAxisSize.min, children: [ @@ -159,31 +160,31 @@ class AuthorPanel extends StatelessWidget { children: [ CachedNetworkImage( height: 32, - imageUrl: (item.modules.moduleAuthor - .decorate['card_url'] as String) + imageUrl: (item.modules.moduleAuthor! + .decorate!['card_url'] as String) .http2https, ), - if ((item.modules.moduleAuthor.decorate?['fan'] + if ((item.modules.moduleAuthor?.decorate?['fan'] ?['num_str'] as String?) ?.isNotEmpty == true) Padding( padding: const EdgeInsets.only(right: 32), child: Text( - '${item.modules.moduleAuthor.decorate['fan']['num_str']}', + '${item.modules.moduleAuthor!.decorate!['fan']['num_str']}', style: TextStyle( height: 1, fontSize: 11, fontFamily: 'digital_id_num', - color: (item.modules.moduleAuthor - .decorate?['fan'] - ?['color'] as String?) + color: (item.modules.moduleAuthor! + .decorate!['fan'] + ['color'] as String?) ?.startsWith('#') == true ? Color( int.parse( - item.modules.moduleAuthor - .decorate['fan']['color'] + item.modules.moduleAuthor! + .decorate!['fan']['color'] .replaceFirst('#', '0xFF'), ), ) @@ -220,15 +221,15 @@ class AuthorPanel extends StatelessWidget { void morePanel(BuildContext context) { String? bvid; try { - getBvid(String? type, dynamic major) => switch (type) { + getBvid(String? type, DynamicMajorModel? major) => switch (type) { 'DYNAMIC_TYPE_AV' => major?.archive?.bvid, 'DYNAMIC_TYPE_UGC_SEASON' => major?.ugcSeason?.bvid, _ => null, }; - bvid = getBvid(item.type, item.modules?.moduleDynamic?.major); + bvid = getBvid(item.type, item.modules.moduleDynamic?.major); if (bvid == null && item.orig != null) { bvid = - getBvid(item.orig.type, item.orig?.modules?.moduleDynamic?.major); + getBvid(item.orig!.type, item.orig?.modules.moduleDynamic?.major); } } catch (_) {} @@ -308,8 +309,8 @@ class AuthorPanel extends StatelessWidget { }, minLeadingWidth: 0, ), - if (item.basic['comment_type'] == 17 || - item.basic['comment_type'] == 11) + if (item.basic!.commentType == 17 || + item.basic!.commentType == 11) ListTile( title: Text( '分享至消息', @@ -319,23 +320,23 @@ class AuthorPanel extends StatelessWidget { onTap: () { Get.back(); try { - bool isDyn = item.basic['comment_type'] == 17; - String id = isDyn ? item.idStr : item.basic['rid_str']; + bool isDyn = item.basic!.commentType == 17; + String id = isDyn ? item.idStr : item.basic!.ridStr!; int source = isDyn ? 11 : 2; String title; - if (item.modules.moduleDynamic.desc != null) { - title = item.modules.moduleDynamic.desc.text; - } else if (item.modules.moduleDynamic.major != null) { - title = - item.modules.moduleDynamic.major.opus.summary.text; + if (item.modules.moduleDynamic?.desc != null) { + title = item.modules.moduleDynamic!.desc!.text!; + } else if (item.modules.moduleDynamic?.major != null) { + title = item + .modules.moduleDynamic!.major!.opus!.summary!.text!; } else { throw UnsupportedError( - 'error getting title: {"type": ${item.basic['comment_type']}, "id": $id}'); + 'error getting title: {"type": ${item.basic!.commentType}, "id": $id}'); } String thumb = isDyn - ? item.modules.moduleAuthor.face - : item - .modules.moduleDynamic.major.opus.pics.first.url; + ? item.modules.moduleAuthor!.face! + : item.modules.moduleDynamic!.major!.opus!.pics!.first + .url!; PageUtils.pmShare( content: { "id": id, @@ -344,8 +345,8 @@ class AuthorPanel extends StatelessWidget { "source": source, "extra": {}, "thumb": thumb, - "author": item.modules.moduleAuthor.name, - "author_id": item.modules.moduleAuthor.mid.toString() + "author": item.modules.moduleAuthor!.name, + "author_id": item.modules.moduleAuthor!.mid.toString() }, ); } catch (e) { @@ -356,7 +357,7 @@ class AuthorPanel extends StatelessWidget { ), ListTile( title: Text( - '临时屏蔽:${item.modules?.moduleAuthor?.name}', + '临时屏蔽:${item.modules.moduleAuthor?.name}', style: Theme.of(context).textTheme.titleSmall, ), leading: const Icon(Icons.visibility_off_outlined, size: 19), @@ -364,13 +365,13 @@ class AuthorPanel extends StatelessWidget { Get.back(); Get.find() .tempBannedList - .add(item.modules.moduleAuthor.mid); + .add(item.modules.moduleAuthor!.mid!); SmartDialog.showToast( - '已临时屏蔽${item.modules?.moduleAuthor?.name}(${item.modules.moduleAuthor.mid}),重启恢复'); + '已临时屏蔽${item.modules.moduleAuthor?.name}(${item.modules.moduleAuthor!.mid}),重启恢复'); }, minLeadingWidth: 0, ), - if (item.modules?.moduleAuthor?.mid == Accounts.main.mid) ...[ + if (item.modules.moduleAuthor?.mid == Accounts.main.mid) ...[ ListTile( onTap: () { Get.back(); @@ -393,12 +394,12 @@ class AuthorPanel extends StatelessWidget { onTap: () { Get.back(); onSetTop!( - item.modules?.moduleTag?.text != null, item.idStr); + item.modules.moduleTag?.text != null, item.idStr); }, minLeadingWidth: 0, leading: const Icon(Icons.vertical_align_top, size: 19), title: Text( - '${item.modules?.moduleTag?.text != null ? '取消' : ''}置顶', + '${item.modules.moduleTag?.text != null ? '取消' : ''}置顶', style: Theme.of(context).textTheme.titleSmall!), ), if (onRemove != null) @@ -459,13 +460,13 @@ class AuthorPanel extends StatelessWidget { (reasonType, reasonDesc, banUid) { if (banUid) { VideoHttp.relationMod( - mid: item.modules!.moduleAuthor!.mid!, + mid: item.modules.moduleAuthor!.mid!, act: 5, reSrc: 11, ); } return UserHttp.dynamicReport( - mid: item.modules!.moduleAuthor!.mid, + mid: item.modules.moduleAuthor!.mid, dynId: item.idStr, reasonType: reasonType, ); diff --git a/lib/pages/dynamics/widgets/dynamic_panel.dart b/lib/pages/dynamics/widgets/dynamic_panel.dart index c7ed2f1e..077742c5 100644 --- a/lib/pages/dynamics/widgets/dynamic_panel.dart +++ b/lib/pages/dynamics/widgets/dynamic_panel.dart @@ -74,8 +74,8 @@ class DynamicPanel extends StatelessWidget { padding: const EdgeInsets.fromLTRB(12, 12, 12, 6), child: authorWidget, ), - if (item.modules!.moduleDynamic!.desc != null || - item.modules!.moduleDynamic!.major != null) + if (item.modules.moduleDynamic!.desc != null || + item.modules.moduleDynamic!.major != null) content(isSave, context, item, source, callback), forWard(isSave, item, context, source, callback), const SizedBox(height: 2), @@ -94,7 +94,7 @@ class DynamicPanel extends StatelessWidget { ) { late String? title; late String? cover; - late final major = item.modules?.moduleDynamic?.major; + late final major = item.modules.moduleDynamic?.major; switch (item.type) { case 'DYNAMIC_TYPE_AV': title = major?.archive?.title; diff --git a/lib/pages/dynamics/widgets/forward_panel.dart b/lib/pages/dynamics/widgets/forward_panel.dart index 89ad6165..4a23ec1a 100644 --- a/lib/pages/dynamics/widgets/forward_panel.dart +++ b/lib/pages/dynamics/widgets/forward_panel.dart @@ -143,7 +143,7 @@ Widget forWard(bool isSave, item, BuildContext context, source, callback, item.modules.moduleDynamic.additional.type, floor: floor, ), - if (item?.modules?.moduleDynamic?.major?.blocked != null) + if (item?.modules.moduleDynamic?.major?.blocked != null) _blockedItem(context, item, source), ], ); @@ -155,27 +155,27 @@ Widget forWard(bool isSave, item, BuildContext context, source, callback, return switch (item) { DynamicItemModel() => item.isForwarded == true ? articlePanel(source, item, context, callback, floor: floor) - : item.modules?.moduleDynamic?.major?.blocked != null + : item.modules.moduleDynamic?.major?.blocked != null ? Padding( padding: const EdgeInsets.symmetric(horizontal: 12), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - if (item.modules?.moduleDynamic?.major + if (item.modules.moduleDynamic?.major ?.blocked?['title'] != null) Text( - '${item.modules?.moduleDynamic?.major?.blocked!['title']}', + '${item.modules.moduleDynamic?.major?.blocked!['title']}', style: TextStyle( color: Theme.of(context).colorScheme.secondary, ), ), - if (item.modules?.moduleDynamic?.major + if (item.modules.moduleDynamic?.major ?.blocked?['hint_message'] != null) Text( - '${item.modules?.moduleDynamic?.major?.blocked!['hint_message']}', + '${item.modules.moduleDynamic?.major?.blocked!['hint_message']}', style: TextStyle( fontSize: 12, color: Theme.of(context).colorScheme.outline, @@ -304,7 +304,7 @@ Widget forWard(bool isSave, item, BuildContext context, source, callback, item.modules.moduleDynamic.additional.type, floor: floor, ) - : item?.modules?.moduleDynamic?.major?.blocked != null + : item?.modules.moduleDynamic?.major?.blocked != null ? _blockedItem(context, item, source) : const SizedBox(height: 0); case 'DYNAMIC_TYPE_PGC': diff --git a/lib/pages/member_dynamics/controller.dart b/lib/pages/member_dynamics/controller.dart index 0fe37648..7d2205c2 100644 --- a/lib/pages/member_dynamics/controller.dart +++ b/lib/pages/member_dynamics/controller.dart @@ -72,13 +72,13 @@ class MemberDynamicsController var res = await DynamicsHttp.setTop(dynamicId: dynamicId); if (res['status']) { List list = (loadingState.value as Success).response; - list[0].modules?.moduleTag = null; + list[0].modules.moduleTag = null; if (isTop) { loadingState.refresh(); SmartDialog.showToast('取消置顶成功'); } else { final item = list.firstWhere((item) => item.idStr == dynamicId); - item.modules?.moduleTag = ModuleTag(text: '置顶'); + item.modules.moduleTag = ModuleTag(text: '置顶'); list.remove(item); list.insert(0, item); loadingState.refresh(); diff --git a/lib/utils/page_utils.dart b/lib/utils/page_utils.dart index 8bab2ef3..9e57c209 100644 --- a/lib/utils/page_utils.dart +++ b/lib/utils/page_utils.dart @@ -265,7 +265,7 @@ class PageUtils { SmartDialog.dismiss(); if (res['status']) { DynamicItemModel data = res['data']; - if (data.basic?['comment_type'] == 12) { + if (data.basic?.commentType == 12) { toDupNamed( '/articlePage', parameters: { diff --git a/lib/utils/request_utils.dart b/lib/utils/request_utils.dart index 66319af0..bdc92afe 100644 --- a/lib/utils/request_utils.dart +++ b/lib/utils/request_utils.dart @@ -304,29 +304,24 @@ class RequestUtils { } // 动态点赞 - static Future onLikeDynamic(item, VoidCallback callback) async { + static Future onLikeDynamic( + DynamicItemModel item, VoidCallback callback) async { feedBack(); String dynamicId = item.idStr!; // 1 已点赞 2 不喜欢 0 未操作 - item.modules?.moduleStat ??= ModuleStatModel(); - item.modules?.moduleStat.like ??= Like(); - Like like = item.modules.moduleStat.like; - int count = like.count == '点赞' ? 0 : int.parse(like.count ?? '0'); - bool status = like.status ?? false; + DynamicStat? like = item.modules.moduleStat?.like; + int count = like?.count ?? 0; + bool status = like?.status ?? false; int up = status ? 2 : 1; var res = await DynamicsHttp.likeDynamic(dynamicId: dynamicId, up: up); if (res['status']) { SmartDialog.showToast(!status ? '点赞成功' : '取消赞'); if (up == 1) { - item.modules.moduleStat.like.count = (count + 1).toString(); - item.modules.moduleStat.like.status = true; + like?.count = count + 1; + like?.status = true; } else { - if (count == 1) { - item.modules.moduleStat.like.count = '点赞'; - } else { - item.modules.moduleStat.like.count = (count - 1).toString(); - } - item.modules.moduleStat.like.status = false; + like?.count = count - 1; + like?.status = false; } callback(); } else {