mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
feat: show member article
This commit is contained in:
@@ -300,6 +300,9 @@ class Api {
|
||||
static const String spaceBangumi =
|
||||
'${HttpString.appBaseUrl}/x/v2/space/bangumi';
|
||||
|
||||
static const String spaceArticle =
|
||||
'${HttpString.appBaseUrl}/x/v2/space/article';
|
||||
|
||||
static const String spaceFav = '/x/v3/fav/folder/space';
|
||||
|
||||
// 用户名片信息
|
||||
|
||||
@@ -20,6 +20,7 @@ import '../models/member/info.dart';
|
||||
import '../models/member/seasons.dart';
|
||||
import '../models/member/tags.dart';
|
||||
import '../models/space_archive/data.dart' as archive;
|
||||
import '../models/space_article/data.dart' as article;
|
||||
import '../utils/utils.dart';
|
||||
import '../utils/wbi_sign.dart';
|
||||
import 'index.dart';
|
||||
@@ -60,6 +61,54 @@ class MemberHttp {
|
||||
}
|
||||
}
|
||||
|
||||
static Future<LoadingState> spaceArticle({
|
||||
required int mid,
|
||||
required int page,
|
||||
}) async {
|
||||
String? accessKey = GStorage.localCache
|
||||
.get(LocalCacheKey.accessKey, defaultValue: {})['value'];
|
||||
Map<String, String> data = {
|
||||
if (accessKey != null) 'access_key': accessKey,
|
||||
'appkey': Constants.appKey,
|
||||
'build': '1462100',
|
||||
'c_locale': 'zh_CN',
|
||||
'channel': 'yingyongbao',
|
||||
'mobi_app': 'android_hd',
|
||||
'platform': 'android',
|
||||
'pn': '$page',
|
||||
'ps': '10',
|
||||
's_locale': 'zh_CN',
|
||||
'statistics': Constants.statistics,
|
||||
'ts': (DateTime.now().millisecondsSinceEpoch ~/ 1000).toString(),
|
||||
'vmid': mid.toString(),
|
||||
};
|
||||
String sign = Utils.appSign(
|
||||
data,
|
||||
Constants.appKey,
|
||||
Constants.appSec,
|
||||
);
|
||||
data['sign'] = sign;
|
||||
int? _mid = GStorage.userInfo.get('userInfoCache')?.mid;
|
||||
dynamic res = await Request().get(
|
||||
Api.spaceArticle,
|
||||
data: data,
|
||||
options: Options(
|
||||
headers: {
|
||||
'env': 'prod',
|
||||
'app-key': 'android_hd',
|
||||
'x-bili-mid': _mid,
|
||||
'bili-http-engine': 'cronet',
|
||||
'user-agent': Constants.userAgent,
|
||||
},
|
||||
),
|
||||
);
|
||||
if (res.data['code'] == 0) {
|
||||
return LoadingState.success(article.Data.fromJson(res.data['data']));
|
||||
} else {
|
||||
return LoadingState.error(res.data['message']);
|
||||
}
|
||||
}
|
||||
|
||||
static Future<LoadingState> spaceFav({
|
||||
required int mid,
|
||||
}) async {
|
||||
|
||||
@@ -15,6 +15,7 @@ import 'series.dart';
|
||||
import 'setting.dart';
|
||||
import 'tab.dart';
|
||||
import 'tab2.dart';
|
||||
import 'package:PiliPalaX/models/space_article/data.dart' as space;
|
||||
|
||||
part 'data.g.dart';
|
||||
|
||||
@@ -35,7 +36,7 @@ class Data {
|
||||
Images? images;
|
||||
Archive? archive;
|
||||
Series? series;
|
||||
Article? article;
|
||||
space.Data? article;
|
||||
Season? season;
|
||||
@JsonKey(name: 'coin_archive')
|
||||
CoinArchive? coinArchive;
|
||||
|
||||
@@ -32,7 +32,7 @@ Data _$DataFromJson(Map<String, dynamic> json) => Data(
|
||||
: Series.fromJson(json['series'] as Map<String, dynamic>),
|
||||
article: json['article'] == null
|
||||
? null
|
||||
: Article.fromJson(json['article'] as Map<String, dynamic>),
|
||||
: space.Data.fromJson(json['article'] as Map<String, dynamic>),
|
||||
season: json['season'] == null
|
||||
? null
|
||||
: Season.fromJson(json['season'] as Map<String, dynamic>),
|
||||
|
||||
36
lib/models/space_article/author.dart
Normal file
36
lib/models/space_article/author.dart
Normal file
@@ -0,0 +1,36 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'nameplate.dart';
|
||||
import 'official_verify.dart';
|
||||
import 'pendant.dart';
|
||||
import 'vip.dart';
|
||||
|
||||
part 'author.g.dart';
|
||||
|
||||
@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<String, dynamic> json) {
|
||||
return _$AuthorFromJson(json);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => _$AuthorToJson(this);
|
||||
}
|
||||
36
lib/models/space_article/author.g.dart
Normal file
36
lib/models/space_article/author.g.dart
Normal file
@@ -0,0 +1,36 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'author.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
Author _$AuthorFromJson(Map<String, dynamic> json) => Author(
|
||||
mid: (json['mid'] as num?)?.toInt(),
|
||||
name: json['name'] as String?,
|
||||
face: json['face'] as String?,
|
||||
pendant: json['pendant'] == null
|
||||
? null
|
||||
: Pendant.fromJson(json['pendant'] as Map<String, dynamic>),
|
||||
officialVerify: json['official_verify'] == null
|
||||
? null
|
||||
: OfficialVerify.fromJson(
|
||||
json['official_verify'] as Map<String, dynamic>),
|
||||
nameplate: json['nameplate'] == null
|
||||
? null
|
||||
: Nameplate.fromJson(json['nameplate'] as Map<String, dynamic>),
|
||||
vip: json['vip'] == null
|
||||
? null
|
||||
: Vip.fromJson(json['vip'] as Map<String, dynamic>),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$AuthorToJson(Author instance) => <String, dynamic>{
|
||||
'mid': instance.mid,
|
||||
'name': instance.name,
|
||||
'face': instance.face,
|
||||
'pendant': instance.pendant,
|
||||
'official_verify': instance.officialVerify,
|
||||
'nameplate': instance.nameplate,
|
||||
'vip': instance.vip,
|
||||
};
|
||||
19
lib/models/space_article/category.dart
Normal file
19
lib/models/space_article/category.dart
Normal file
@@ -0,0 +1,19 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'category.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class Category {
|
||||
int? id;
|
||||
@JsonKey(name: 'parent_id')
|
||||
int? parentId;
|
||||
String? name;
|
||||
|
||||
Category({this.id, this.parentId, this.name});
|
||||
|
||||
factory Category.fromJson(Map<String, dynamic> json) {
|
||||
return _$CategoryFromJson(json);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => _$CategoryToJson(this);
|
||||
}
|
||||
19
lib/models/space_article/category.g.dart
Normal file
19
lib/models/space_article/category.g.dart
Normal file
@@ -0,0 +1,19 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'category.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
Category _$CategoryFromJson(Map<String, dynamic> json) => Category(
|
||||
id: (json['id'] as num?)?.toInt(),
|
||||
parentId: (json['parent_id'] as num?)?.toInt(),
|
||||
name: json['name'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$CategoryToJson(Category instance) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'parent_id': instance.parentId,
|
||||
'name': instance.name,
|
||||
};
|
||||
21
lib/models/space_article/data.dart
Normal file
21
lib/models/space_article/data.dart
Normal file
@@ -0,0 +1,21 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'item.dart';
|
||||
import 'list.dart';
|
||||
|
||||
part 'data.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class Data {
|
||||
int? count;
|
||||
List<Item>? item;
|
||||
@JsonKey(name: 'lists_count')
|
||||
int? listsCount;
|
||||
List<ArticleList>? lists;
|
||||
|
||||
Data({this.count, this.item, this.listsCount, this.lists});
|
||||
|
||||
factory Data.fromJson(Map<String, dynamic> json) => _$DataFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$DataToJson(this);
|
||||
}
|
||||
25
lib/models/space_article/data.g.dart
Normal file
25
lib/models/space_article/data.g.dart
Normal file
@@ -0,0 +1,25 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'data.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
Data _$DataFromJson(Map<String, dynamic> json) => Data(
|
||||
count: (json['count'] as num?)?.toInt(),
|
||||
item: (json['item'] as List<dynamic>?)
|
||||
?.map((item) => Item.fromJson(item))
|
||||
.toList(),
|
||||
listsCount: (json['lists_count'] as num?)?.toInt(),
|
||||
lists: (json['lists'] as List<dynamic>?)
|
||||
?.map((item) => ArticleList.fromJson(item))
|
||||
.toList(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$DataToJson(Data instance) => <String, dynamic>{
|
||||
'count': instance.count,
|
||||
'item': instance.item,
|
||||
'lists_count': instance.listsCount,
|
||||
'lists': instance.lists,
|
||||
};
|
||||
107
lib/models/space_article/item.dart
Normal file
107
lib/models/space_article/item.dart
Normal file
@@ -0,0 +1,107 @@
|
||||
import 'package:json_annotation/json_annotation.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<Category>? 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<String>? imageUrls;
|
||||
@JsonKey(name: 'publish_time')
|
||||
int? publishTime;
|
||||
int? ctime;
|
||||
int? mtime;
|
||||
Stats? stats;
|
||||
int? attributes;
|
||||
int? words;
|
||||
@JsonKey(name: 'origin_image_urls')
|
||||
List<String>? 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,
|
||||
});
|
||||
|
||||
factory Item.fromJson(Map<String, dynamic> json) => _$ItemFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$ItemToJson(this);
|
||||
}
|
||||
101
lib/models/space_article/item.g.dart
Normal file
101
lib/models/space_article/item.g.dart
Normal file
@@ -0,0 +1,101 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'item.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
Item _$ItemFromJson(Map<String, dynamic> json) => Item(
|
||||
id: (json['id'] as num?)?.toInt(),
|
||||
category: json['category'] == null
|
||||
? null
|
||||
: Category.fromJson(json['category'] as Map<String, dynamic>),
|
||||
categories: (json['categories'] as List<dynamic>?)
|
||||
?.map((e) => Category.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
title: json['title'] as String?,
|
||||
summary: json['summary'] as String?,
|
||||
bannerUrl: json['banner_url'] as String?,
|
||||
templateId: (json['template_id'] as num?)?.toInt(),
|
||||
state: (json['state'] as num?)?.toInt(),
|
||||
author: json['author'] == null
|
||||
? null
|
||||
: Author.fromJson(json['author'] as Map<String, dynamic>),
|
||||
reprint: (json['reprint'] as num?)?.toInt(),
|
||||
imageUrls: (json['image_urls'] as List<dynamic>?)
|
||||
?.map((e) => e as String)
|
||||
.toList(),
|
||||
publishTime: (json['publish_time'] as num?)?.toInt(),
|
||||
ctime: (json['ctime'] as num?)?.toInt(),
|
||||
mtime: (json['mtime'] as num?)?.toInt(),
|
||||
stats: json['stats'] == null
|
||||
? null
|
||||
: Stats.fromJson(json['stats'] as Map<String, dynamic>),
|
||||
attributes: (json['attributes'] as num?)?.toInt(),
|
||||
words: (json['words'] as num?)?.toInt(),
|
||||
originImageUrls: (json['origin_image_urls'] as List<dynamic>?)
|
||||
?.map((e) => e as String)
|
||||
.toList(),
|
||||
list: json['list'],
|
||||
isLike: json['is_like'] as bool?,
|
||||
media: json['media'] == null
|
||||
? null
|
||||
: Media.fromJson(json['media'] as Map<String, dynamic>),
|
||||
applyTime: json['apply_time'] as String?,
|
||||
checkTime: json['check_time'] as String?,
|
||||
original: (json['original'] as num?)?.toInt(),
|
||||
actId: (json['act_id'] as num?)?.toInt(),
|
||||
dispute: json['dispute'],
|
||||
authenMark: json['authenMark'],
|
||||
coverAvid: (json['cover_avid'] as num?)?.toInt(),
|
||||
topVideoInfo: json['top_video_info'],
|
||||
type: (json['type'] as num?)?.toInt(),
|
||||
checkState: (json['check_state'] as num?)?.toInt(),
|
||||
originTemplateId: (json['origin_template_id'] as num?)?.toInt(),
|
||||
uri: json['uri'] as String?,
|
||||
param: json['param'] as String?,
|
||||
goto: json['goto'] as String?,
|
||||
publishTimeText: json['publish_time_text'] as String?,
|
||||
dyn: json['dynamic'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$ItemToJson(Item instance) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'category': instance.category,
|
||||
'categories': instance.categories,
|
||||
'title': instance.title,
|
||||
'summary': instance.summary,
|
||||
'banner_url': instance.bannerUrl,
|
||||
'template_id': instance.templateId,
|
||||
'state': instance.state,
|
||||
'author': instance.author,
|
||||
'reprint': instance.reprint,
|
||||
'image_urls': instance.imageUrls,
|
||||
'publish_time': instance.publishTime,
|
||||
'ctime': instance.ctime,
|
||||
'mtime': instance.mtime,
|
||||
'stats': instance.stats,
|
||||
'attributes': instance.attributes,
|
||||
'words': instance.words,
|
||||
'origin_image_urls': instance.originImageUrls,
|
||||
'list': instance.list,
|
||||
'is_like': instance.isLike,
|
||||
'media': instance.media,
|
||||
'apply_time': instance.applyTime,
|
||||
'check_time': instance.checkTime,
|
||||
'original': instance.original,
|
||||
'act_id': instance.actId,
|
||||
'dispute': instance.dispute,
|
||||
'authenMark': instance.authenMark,
|
||||
'cover_avid': instance.coverAvid,
|
||||
'top_video_info': instance.topVideoInfo,
|
||||
'type': instance.type,
|
||||
'check_state': instance.checkState,
|
||||
'origin_template_id': instance.originTemplateId,
|
||||
'uri': instance.uri,
|
||||
'param': instance.param,
|
||||
'goto': instance.goto,
|
||||
'publish_time_text': instance.publishTimeText,
|
||||
'dynamic': instance.dyn,
|
||||
};
|
||||
17
lib/models/space_article/label.dart
Normal file
17
lib/models/space_article/label.dart
Normal file
@@ -0,0 +1,17 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'label.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class Label {
|
||||
String? path;
|
||||
String? text;
|
||||
@JsonKey(name: 'label_theme')
|
||||
String? labelTheme;
|
||||
|
||||
Label({this.path, this.text, this.labelTheme});
|
||||
|
||||
factory Label.fromJson(Map<String, dynamic> json) => _$LabelFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$LabelToJson(this);
|
||||
}
|
||||
19
lib/models/space_article/label.g.dart
Normal file
19
lib/models/space_article/label.g.dart
Normal file
@@ -0,0 +1,19 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'label.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
Label _$LabelFromJson(Map<String, dynamic> json) => Label(
|
||||
path: json['path'] as String?,
|
||||
text: json['text'] as String?,
|
||||
labelTheme: json['label_theme'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$LabelToJson(Label instance) => <String, dynamic>{
|
||||
'path': instance.path,
|
||||
'text': instance.text,
|
||||
'label_theme': instance.labelTheme,
|
||||
};
|
||||
44
lib/models/space_article/list.dart
Normal file
44
lib/models/space_article/list.dart
Normal file
@@ -0,0 +1,44 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'list.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class ArticleList {
|
||||
int? id;
|
||||
int? mid;
|
||||
String? name;
|
||||
@JsonKey(name: 'image_url')
|
||||
String? imageUrl;
|
||||
@JsonKey(name: 'update_time')
|
||||
int? updateTime;
|
||||
int? ctime;
|
||||
@JsonKey(name: 'publish_time')
|
||||
int? publishTime;
|
||||
String? summary;
|
||||
int? words;
|
||||
int? read;
|
||||
@JsonKey(name: 'articles_count')
|
||||
int? articlesCount;
|
||||
@JsonKey(name: 'update_time_text')
|
||||
String? updateTimeText;
|
||||
|
||||
ArticleList({
|
||||
this.id,
|
||||
this.mid,
|
||||
this.name,
|
||||
this.imageUrl,
|
||||
this.updateTime,
|
||||
this.ctime,
|
||||
this.publishTime,
|
||||
this.summary,
|
||||
this.words,
|
||||
this.read,
|
||||
this.articlesCount,
|
||||
this.updateTimeText,
|
||||
});
|
||||
|
||||
factory ArticleList.fromJson(Map<String, dynamic> json) =>
|
||||
_$ListFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$ListToJson(this);
|
||||
}
|
||||
37
lib/models/space_article/list.g.dart
Normal file
37
lib/models/space_article/list.g.dart
Normal file
@@ -0,0 +1,37 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'list.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
ArticleList _$ListFromJson(Map<String, dynamic> json) => ArticleList(
|
||||
id: (json['id'] as num?)?.toInt(),
|
||||
mid: (json['mid'] as num?)?.toInt(),
|
||||
name: json['name'] as String?,
|
||||
imageUrl: json['image_url'] as String?,
|
||||
updateTime: (json['update_time'] as num?)?.toInt(),
|
||||
ctime: (json['ctime'] as num?)?.toInt(),
|
||||
publishTime: (json['publish_time'] as num?)?.toInt(),
|
||||
summary: json['summary'] as String?,
|
||||
words: (json['words'] as num?)?.toInt(),
|
||||
read: (json['read'] as num?)?.toInt(),
|
||||
articlesCount: (json['articles_count'] as num?)?.toInt(),
|
||||
updateTimeText: json['update_time_text'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$ListToJson(ArticleList instance) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'mid': instance.mid,
|
||||
'name': instance.name,
|
||||
'image_url': instance.imageUrl,
|
||||
'update_time': instance.updateTime,
|
||||
'ctime': instance.ctime,
|
||||
'publish_time': instance.publishTime,
|
||||
'summary': instance.summary,
|
||||
'words': instance.words,
|
||||
'read': instance.read,
|
||||
'articles_count': instance.articlesCount,
|
||||
'update_time_text': instance.updateTimeText,
|
||||
};
|
||||
33
lib/models/space_article/media.dart
Normal file
33
lib/models/space_article/media.dart
Normal file
@@ -0,0 +1,33 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'media.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class Media {
|
||||
int? score;
|
||||
@JsonKey(name: 'media_id')
|
||||
int? mediaId;
|
||||
String? title;
|
||||
String? cover;
|
||||
String? area;
|
||||
@JsonKey(name: 'type_id')
|
||||
int? typeId;
|
||||
@JsonKey(name: 'type_name')
|
||||
String? typeName;
|
||||
int? spoiler;
|
||||
|
||||
Media({
|
||||
this.score,
|
||||
this.mediaId,
|
||||
this.title,
|
||||
this.cover,
|
||||
this.area,
|
||||
this.typeId,
|
||||
this.typeName,
|
||||
this.spoiler,
|
||||
});
|
||||
|
||||
factory Media.fromJson(Map<String, dynamic> json) => _$MediaFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$MediaToJson(this);
|
||||
}
|
||||
29
lib/models/space_article/media.g.dart
Normal file
29
lib/models/space_article/media.g.dart
Normal file
@@ -0,0 +1,29 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'media.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
Media _$MediaFromJson(Map<String, dynamic> json) => Media(
|
||||
score: (json['score'] as num?)?.toInt(),
|
||||
mediaId: (json['media_id'] as num?)?.toInt(),
|
||||
title: json['title'] as String?,
|
||||
cover: json['cover'] as String?,
|
||||
area: json['area'] as String?,
|
||||
typeId: (json['type_id'] as num?)?.toInt(),
|
||||
typeName: json['type_name'] as String?,
|
||||
spoiler: (json['spoiler'] as num?)?.toInt(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$MediaToJson(Media instance) => <String, dynamic>{
|
||||
'score': instance.score,
|
||||
'media_id': instance.mediaId,
|
||||
'title': instance.title,
|
||||
'cover': instance.cover,
|
||||
'area': instance.area,
|
||||
'type_id': instance.typeId,
|
||||
'type_name': instance.typeName,
|
||||
'spoiler': instance.spoiler,
|
||||
};
|
||||
29
lib/models/space_article/nameplate.dart
Normal file
29
lib/models/space_article/nameplate.dart
Normal file
@@ -0,0 +1,29 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'nameplate.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class Nameplate {
|
||||
int? nid;
|
||||
String? name;
|
||||
String? image;
|
||||
@JsonKey(name: 'image_small')
|
||||
String? imageSmall;
|
||||
String? level;
|
||||
String? condition;
|
||||
|
||||
Nameplate({
|
||||
this.nid,
|
||||
this.name,
|
||||
this.image,
|
||||
this.imageSmall,
|
||||
this.level,
|
||||
this.condition,
|
||||
});
|
||||
|
||||
factory Nameplate.fromJson(Map<String, dynamic> json) {
|
||||
return _$NameplateFromJson(json);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => _$NameplateToJson(this);
|
||||
}
|
||||
25
lib/models/space_article/nameplate.g.dart
Normal file
25
lib/models/space_article/nameplate.g.dart
Normal file
@@ -0,0 +1,25 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'nameplate.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
Nameplate _$NameplateFromJson(Map<String, dynamic> json) => Nameplate(
|
||||
nid: (json['nid'] as num?)?.toInt(),
|
||||
name: json['name'] as String?,
|
||||
image: json['image'] as String?,
|
||||
imageSmall: json['image_small'] as String?,
|
||||
level: json['level'] as String?,
|
||||
condition: json['condition'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$NameplateToJson(Nameplate instance) => <String, dynamic>{
|
||||
'nid': instance.nid,
|
||||
'name': instance.name,
|
||||
'image': instance.image,
|
||||
'image_small': instance.imageSmall,
|
||||
'level': instance.level,
|
||||
'condition': instance.condition,
|
||||
};
|
||||
17
lib/models/space_article/official_verify.dart
Normal file
17
lib/models/space_article/official_verify.dart
Normal file
@@ -0,0 +1,17 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'official_verify.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class OfficialVerify {
|
||||
int? type;
|
||||
String? desc;
|
||||
|
||||
OfficialVerify({this.type, this.desc});
|
||||
|
||||
factory OfficialVerify.fromJson(Map<String, dynamic> json) {
|
||||
return _$OfficialVerifyFromJson(json);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => _$OfficialVerifyToJson(this);
|
||||
}
|
||||
19
lib/models/space_article/official_verify.g.dart
Normal file
19
lib/models/space_article/official_verify.g.dart
Normal file
@@ -0,0 +1,19 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'official_verify.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
OfficialVerify _$OfficialVerifyFromJson(Map<String, dynamic> json) =>
|
||||
OfficialVerify(
|
||||
type: (json['type'] as num?)?.toInt(),
|
||||
desc: json['desc'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$OfficialVerifyToJson(OfficialVerify instance) =>
|
||||
<String, dynamic>{
|
||||
'type': instance.type,
|
||||
'desc': instance.desc,
|
||||
};
|
||||
19
lib/models/space_article/pendant.dart
Normal file
19
lib/models/space_article/pendant.dart
Normal file
@@ -0,0 +1,19 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'pendant.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class Pendant {
|
||||
int? pid;
|
||||
String? name;
|
||||
String? image;
|
||||
int? expire;
|
||||
|
||||
Pendant({this.pid, this.name, this.image, this.expire});
|
||||
|
||||
factory Pendant.fromJson(Map<String, dynamic> json) {
|
||||
return _$PendantFromJson(json);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => _$PendantToJson(this);
|
||||
}
|
||||
21
lib/models/space_article/pendant.g.dart
Normal file
21
lib/models/space_article/pendant.g.dart
Normal file
@@ -0,0 +1,21 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'pendant.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
Pendant _$PendantFromJson(Map<String, dynamic> json) => Pendant(
|
||||
pid: (json['pid'] as num?)?.toInt(),
|
||||
name: json['name'] as String?,
|
||||
image: json['image'] as String?,
|
||||
expire: (json['expire'] as num?)?.toInt(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$PendantToJson(Pendant instance) => <String, dynamic>{
|
||||
'pid': instance.pid,
|
||||
'name': instance.name,
|
||||
'image': instance.image,
|
||||
'expire': instance.expire,
|
||||
};
|
||||
21
lib/models/space_article/space_article.dart
Normal file
21
lib/models/space_article/space_article.dart
Normal file
@@ -0,0 +1,21 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'data.dart';
|
||||
|
||||
part 'space_article.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class SpaceArticle {
|
||||
int? code;
|
||||
String? message;
|
||||
int? ttl;
|
||||
Data? data;
|
||||
|
||||
SpaceArticle({this.code, this.message, this.ttl, this.data});
|
||||
|
||||
factory SpaceArticle.fromJson(Map<String, dynamic> json) {
|
||||
return _$SpaceArticleFromJson(json);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => _$SpaceArticleToJson(this);
|
||||
}
|
||||
24
lib/models/space_article/space_article.g.dart
Normal file
24
lib/models/space_article/space_article.g.dart
Normal file
@@ -0,0 +1,24 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'space_article.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
SpaceArticle _$SpaceArticleFromJson(Map<String, dynamic> json) => SpaceArticle(
|
||||
code: (json['code'] as num?)?.toInt(),
|
||||
message: json['message'] as String?,
|
||||
ttl: (json['ttl'] as num?)?.toInt(),
|
||||
data: json['data'] == null
|
||||
? null
|
||||
: Data.fromJson(json['data'] as Map<String, dynamic>),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$SpaceArticleToJson(SpaceArticle instance) =>
|
||||
<String, dynamic>{
|
||||
'code': instance.code,
|
||||
'message': instance.message,
|
||||
'ttl': instance.ttl,
|
||||
'data': instance.data,
|
||||
};
|
||||
30
lib/models/space_article/stats.dart
Normal file
30
lib/models/space_article/stats.dart
Normal file
@@ -0,0 +1,30 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'stats.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class Stats {
|
||||
int? view;
|
||||
int? favorite;
|
||||
int? like;
|
||||
int? dislike;
|
||||
int? reply;
|
||||
int? share;
|
||||
int? coin;
|
||||
int? dyn;
|
||||
|
||||
Stats({
|
||||
this.view,
|
||||
this.favorite,
|
||||
this.like,
|
||||
this.dislike,
|
||||
this.reply,
|
||||
this.share,
|
||||
this.coin,
|
||||
this.dyn,
|
||||
});
|
||||
|
||||
factory Stats.fromJson(Map<String, dynamic> json) => _$StatsFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$StatsToJson(this);
|
||||
}
|
||||
29
lib/models/space_article/stats.g.dart
Normal file
29
lib/models/space_article/stats.g.dart
Normal file
@@ -0,0 +1,29 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'stats.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
Stats _$StatsFromJson(Map<String, dynamic> json) => Stats(
|
||||
view: (json['view'] as num?)?.toInt(),
|
||||
favorite: (json['favorite'] as num?)?.toInt(),
|
||||
like: (json['like'] as num?)?.toInt(),
|
||||
dislike: (json['dislike'] as num?)?.toInt(),
|
||||
reply: (json['reply'] as num?)?.toInt(),
|
||||
share: (json['share'] as num?)?.toInt(),
|
||||
coin: (json['coin'] as num?)?.toInt(),
|
||||
dyn: (json['dynamic'] as num?)?.toInt(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$StatsToJson(Stats instance) => <String, dynamic>{
|
||||
'view': instance.view,
|
||||
'favorite': instance.favorite,
|
||||
'like': instance.like,
|
||||
'dislike': instance.dislike,
|
||||
'reply': instance.reply,
|
||||
'share': instance.share,
|
||||
'coin': instance.coin,
|
||||
'dynamic': instance.dyn,
|
||||
};
|
||||
37
lib/models/space_article/vip.dart
Normal file
37
lib/models/space_article/vip.dart
Normal file
@@ -0,0 +1,37 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'label.dart';
|
||||
|
||||
part 'vip.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class Vip {
|
||||
int? type;
|
||||
int? status;
|
||||
@JsonKey(name: 'due_date')
|
||||
int? dueDate;
|
||||
@JsonKey(name: 'vip_pay_type')
|
||||
int? vipPayType;
|
||||
@JsonKey(name: 'theme_type')
|
||||
int? themeType;
|
||||
Label? label;
|
||||
@JsonKey(name: 'avatar_subscript')
|
||||
int? avatarSubscript;
|
||||
@JsonKey(name: 'nickname_color')
|
||||
String? nicknameColor;
|
||||
|
||||
Vip({
|
||||
this.type,
|
||||
this.status,
|
||||
this.dueDate,
|
||||
this.vipPayType,
|
||||
this.themeType,
|
||||
this.label,
|
||||
this.avatarSubscript,
|
||||
this.nicknameColor,
|
||||
});
|
||||
|
||||
factory Vip.fromJson(Map<String, dynamic> json) => _$VipFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$VipToJson(this);
|
||||
}
|
||||
31
lib/models/space_article/vip.g.dart
Normal file
31
lib/models/space_article/vip.g.dart
Normal file
@@ -0,0 +1,31 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'vip.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
Vip _$VipFromJson(Map<String, dynamic> json) => Vip(
|
||||
type: (json['type'] as num?)?.toInt(),
|
||||
status: (json['status'] as num?)?.toInt(),
|
||||
dueDate: (json['due_date'] as num?)?.toInt(),
|
||||
vipPayType: (json['vip_pay_type'] as num?)?.toInt(),
|
||||
themeType: (json['theme_type'] as num?)?.toInt(),
|
||||
label: json['label'] == null
|
||||
? null
|
||||
: Label.fromJson(json['label'] as Map<String, dynamic>),
|
||||
avatarSubscript: (json['avatar_subscript'] as num?)?.toInt(),
|
||||
nicknameColor: json['nickname_color'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$VipToJson(Vip instance) => <String, dynamic>{
|
||||
'type': instance.type,
|
||||
'status': instance.status,
|
||||
'due_date': instance.dueDate,
|
||||
'vip_pay_type': instance.vipPayType,
|
||||
'theme_type': instance.themeType,
|
||||
'label': instance.label,
|
||||
'avatar_subscript': instance.avatarSubscript,
|
||||
'nickname_color': instance.nicknameColor,
|
||||
};
|
||||
@@ -1,12 +1,22 @@
|
||||
import 'package:PiliPalaX/common/constants.dart';
|
||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
||||
import 'package:PiliPalaX/common/widgets/network_img_layer.dart';
|
||||
import 'package:PiliPalaX/http/loading_state.dart';
|
||||
import 'package:PiliPalaX/models/space_article/item.dart';
|
||||
import 'package:PiliPalaX/pages/member/new/content/member_contribute/content/article/member_article_ctr.dart';
|
||||
import 'package:PiliPalaX/utils/app_scheme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class MemberArticle extends StatefulWidget {
|
||||
const MemberArticle({
|
||||
super.key,
|
||||
required this.heroTag,
|
||||
required this.mid,
|
||||
});
|
||||
|
||||
final String? heroTag;
|
||||
final int mid;
|
||||
|
||||
@override
|
||||
State<MemberArticle> createState() => _MemberArticleState();
|
||||
@@ -17,11 +27,91 @@ class _MemberArticleState extends State<MemberArticle>
|
||||
@override
|
||||
bool get wantKeepAlive => true;
|
||||
|
||||
late final _controller = Get.put(
|
||||
MemberArticleCtr(mid: widget.mid),
|
||||
tag: widget.heroTag,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
return Center(
|
||||
child: Text('Article'),
|
||||
return Obx(() => _buildBody(_controller.loadingState.value));
|
||||
}
|
||||
|
||||
_buildBody(LoadingState loadingState) {
|
||||
return loadingState is Success
|
||||
? MediaQuery.removePadding(
|
||||
context: context,
|
||||
removeTop: true,
|
||||
child: RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
await _controller.onRefresh();
|
||||
},
|
||||
child: ListView.separated(
|
||||
itemCount: loadingState.response.length,
|
||||
itemBuilder: (_, index) {
|
||||
if (index == loadingState.response.length - 1) {
|
||||
_controller.onLoadMore();
|
||||
}
|
||||
Item item = loadingState.response[index];
|
||||
return ListTile(
|
||||
dense: true,
|
||||
onTap: () {
|
||||
PiliScheme.routePush(Uri.parse(item.uri ?? ''));
|
||||
},
|
||||
leading: item.originImageUrls?.isNotEmpty == true
|
||||
? Container(
|
||||
margin: const EdgeInsets.symmetric(vertical: 6),
|
||||
child: LayoutBuilder(
|
||||
builder: (_, constraints) {
|
||||
return NetworkImgLayer(
|
||||
radius: 6,
|
||||
src: item.originImageUrls!.first,
|
||||
width: constraints.maxHeight *
|
||||
StyleString.aspectRatio,
|
||||
height: constraints.maxHeight,
|
||||
);
|
||||
},
|
||||
),
|
||||
)
|
||||
: null,
|
||||
title: Text(
|
||||
item.title ?? '',
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
subtitle: item.summary?.isNotEmpty == true
|
||||
? Text(
|
||||
item.summary!,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
),
|
||||
)
|
||||
: null,
|
||||
);
|
||||
},
|
||||
separatorBuilder: (_, index) => Divider(height: 1),
|
||||
),
|
||||
),
|
||||
)
|
||||
: loadingState is Error
|
||||
? Center(
|
||||
child: CustomScrollView(
|
||||
shrinkWrap: true,
|
||||
slivers: [
|
||||
HttpError(
|
||||
errMsg: loadingState.errMsg,
|
||||
fn: _controller.onReload,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import 'package:PiliPalaX/http/loading_state.dart';
|
||||
import 'package:PiliPalaX/http/member.dart';
|
||||
import 'package:PiliPalaX/models/space_article/data.dart';
|
||||
import 'package:PiliPalaX/pages/common/common_controller.dart';
|
||||
|
||||
class MemberArticleCtr extends CommonController {
|
||||
MemberArticleCtr({
|
||||
required this.mid,
|
||||
});
|
||||
|
||||
final int mid;
|
||||
|
||||
bool isEnd = false;
|
||||
int count = -1;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
queryData();
|
||||
}
|
||||
|
||||
@override
|
||||
Future onRefresh() async {
|
||||
isEnd = false;
|
||||
return super.onRefresh();
|
||||
}
|
||||
|
||||
@override
|
||||
Future queryData([bool isRefresh = true]) {
|
||||
if (isEnd) return Future.value();
|
||||
return super.queryData(isRefresh);
|
||||
}
|
||||
|
||||
@override
|
||||
bool customHandleResponse(Success response) {
|
||||
Data data = response.response;
|
||||
if (currentPage == 1) {
|
||||
count = data.count ?? -1;
|
||||
} else if (loadingState.value is Success) {
|
||||
data.item?.insertAll(0, (loadingState.value as Success).response);
|
||||
}
|
||||
isEnd = (data.item?.length ?? -1) >= count;
|
||||
loadingState.value = LoadingState.success(data.item);
|
||||
return true;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<LoadingState> customGetData() =>
|
||||
MemberHttp.spaceArticle(mid: mid, page: currentPage);
|
||||
}
|
||||
@@ -89,7 +89,10 @@ class _MemberContributeState extends State<MemberContribute>
|
||||
heroTag: widget.heroTag,
|
||||
mid: widget.mid,
|
||||
),
|
||||
'article' => MemberArticle(heroTag: widget.heroTag),
|
||||
'article' => MemberArticle(
|
||||
heroTag: widget.heroTag,
|
||||
mid: widget.mid,
|
||||
),
|
||||
'audio' => MemberAudio(heroTag: widget.heroTag),
|
||||
'season_video' => MemberVideo(
|
||||
type: ContributeType.season,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:PiliPalaX/common/constants.dart';
|
||||
import 'package:PiliPalaX/common/widgets/network_img_layer.dart';
|
||||
import 'package:PiliPalaX/common/widgets/video_card_v_member_home.dart';
|
||||
import 'package:PiliPalaX/http/loading_state.dart';
|
||||
import 'package:PiliPalaX/models/space/data.dart';
|
||||
@@ -13,6 +14,8 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../../../../../utils/app_scheme.dart';
|
||||
|
||||
class MemberHome extends StatefulWidget {
|
||||
const MemberHome({super.key, this.heroTag});
|
||||
|
||||
@@ -93,7 +96,7 @@ class _MemberHomeState extends State<MemberHome>
|
||||
true) ...[
|
||||
_videoHeader(
|
||||
title: '最近点赞的视频',
|
||||
param: 'coinArchive',
|
||||
param: 'likeArchive',
|
||||
count: loadingState.response.likeArchive.count,
|
||||
),
|
||||
// TODO
|
||||
@@ -105,7 +108,53 @@ class _MemberHomeState extends State<MemberHome>
|
||||
param1: 'article',
|
||||
count: loadingState.response.article.count,
|
||||
),
|
||||
// TODO
|
||||
SliverToBoxAdapter(
|
||||
child: ListTile(
|
||||
dense: true,
|
||||
onTap: () {
|
||||
PiliScheme.routePush(Uri.parse(
|
||||
loadingState.response.article.item.first.uri ?? ''));
|
||||
},
|
||||
leading: loadingState.response.article.item.first
|
||||
.originImageUrls?.isNotEmpty ==
|
||||
true
|
||||
? Container(
|
||||
margin: const EdgeInsets.symmetric(vertical: 6),
|
||||
child: LayoutBuilder(
|
||||
builder: (_, constraints) {
|
||||
return NetworkImgLayer(
|
||||
radius: 6,
|
||||
src: loadingState.response.article.item.first
|
||||
.originImageUrls!.first,
|
||||
width: constraints.maxHeight *
|
||||
StyleString.aspectRatio,
|
||||
height: constraints.maxHeight,
|
||||
);
|
||||
},
|
||||
),
|
||||
)
|
||||
: null,
|
||||
title: Text(
|
||||
loadingState.response.article.item.first.title ?? '',
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
subtitle: loadingState.response.article.item.first.summary
|
||||
?.isNotEmpty ==
|
||||
true
|
||||
? Text(
|
||||
loadingState.response.article.item.first.summary!,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
],
|
||||
if (loadingState.response?.audios?.item?.isNotEmpty == true) ...[
|
||||
_videoHeader(
|
||||
|
||||
Reference in New Issue
Block a user