mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-17 23:56:13 +08:00
committed by
GitHub
parent
c899ea95e1
commit
8d34e6f340
@@ -96,9 +96,7 @@ class NetworkImgLayer extends StatelessWidget {
|
|||||||
? BorderRadius.circular(radius!)
|
? BorderRadius.circular(radius!)
|
||||||
: StyleString.mdRadius,
|
: StyleString.mdRadius,
|
||||||
),
|
),
|
||||||
child: type == 'bg'
|
child: Center(
|
||||||
? const SizedBox.shrink()
|
|
||||||
: Center(
|
|
||||||
child: Image.asset(
|
child: Image.asset(
|
||||||
type == ImageType.avatar
|
type == ImageType.avatar
|
||||||
? 'assets/images/noface.jpeg'
|
? 'assets/images/noface.jpeg'
|
||||||
|
|||||||
@@ -1,30 +1,16 @@
|
|||||||
// ignore_for_file: constant_identifier_names
|
enum AudioQuality {
|
||||||
|
k64(30216, '64K'),
|
||||||
|
k132(30232, '132K'),
|
||||||
|
k192(30280, '192K'),
|
||||||
|
dolby(30250, '杜比全景声'),
|
||||||
|
hiRes(30251, 'Hi-Res无损');
|
||||||
|
|
||||||
enum AudioQuality { k64, k132, k192, dolby, hiRes }
|
final int code;
|
||||||
|
final String description;
|
||||||
|
|
||||||
extension AudioQualityExt on AudioQuality {
|
const AudioQuality(this.code, this.description);
|
||||||
static const List<int> _codeList = [
|
|
||||||
30216,
|
|
||||||
30232,
|
|
||||||
30280,
|
|
||||||
30250,
|
|
||||||
30251,
|
|
||||||
];
|
|
||||||
int get code => _codeList[index];
|
|
||||||
|
|
||||||
static AudioQuality? fromCode(int code) {
|
static final _codeMap = {for (var i in values) i.code: i};
|
||||||
final index = _codeList.indexOf(code);
|
|
||||||
if (index != -1) {
|
|
||||||
return AudioQuality.values[index];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
String get description => const [
|
static AudioQuality fromCode(int code) => _codeMap[code]!;
|
||||||
'64K',
|
|
||||||
'132K',
|
|
||||||
'192K',
|
|
||||||
'杜比全景声',
|
|
||||||
'Hi-Res无损',
|
|
||||||
][index];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,55 +1,23 @@
|
|||||||
enum VideoQuality {
|
enum VideoQuality {
|
||||||
speed240,
|
speed240(6, '240P 极速'),
|
||||||
fluent360,
|
fluent360(16, '360P 流畅'),
|
||||||
clear480,
|
clear480(32, '480P 清晰'),
|
||||||
high720,
|
high720(64, '720P 高清'),
|
||||||
high72060,
|
high72060(74, '720P60 高帧率'),
|
||||||
high1080,
|
high1080(80, '1080P 高清'),
|
||||||
high1080plus,
|
high1080plus(112, '1080P+ 高码率'),
|
||||||
high108060,
|
high108060(116, '1080P60 高帧率'),
|
||||||
super4K,
|
super4K(120, '4K 超清'),
|
||||||
hdr,
|
hdr(125, 'HDR 真彩色'),
|
||||||
dolbyVision,
|
dolbyVision(126, '杜比视界'),
|
||||||
super8k
|
super8k(127, '8K 超高清');
|
||||||
}
|
|
||||||
|
final int code;
|
||||||
extension VideoQualityExt on VideoQuality {
|
final String description;
|
||||||
static const List<int> _codeList = [
|
|
||||||
6,
|
const VideoQuality(this.code, this.description);
|
||||||
16,
|
|
||||||
32,
|
static final _codeMap = {for (var i in values) i.code: i};
|
||||||
64,
|
|
||||||
74,
|
static VideoQuality fromCode(int code) => _codeMap[code]!;
|
||||||
80,
|
|
||||||
112,
|
|
||||||
116,
|
|
||||||
120,
|
|
||||||
125,
|
|
||||||
126,
|
|
||||||
127,
|
|
||||||
];
|
|
||||||
int get code => _codeList[index];
|
|
||||||
|
|
||||||
static VideoQuality? fromCode(int code) {
|
|
||||||
final index = _codeList.indexOf(code);
|
|
||||||
if (index != -1) {
|
|
||||||
return VideoQuality.values[index];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
String get description => const [
|
|
||||||
'240P 极速',
|
|
||||||
'360P 流畅',
|
|
||||||
'480P 清晰',
|
|
||||||
'720P 高清',
|
|
||||||
'720P60 高帧率',
|
|
||||||
'1080P 高清',
|
|
||||||
'1080P+ 高码率',
|
|
||||||
'1080P60 高帧率',
|
|
||||||
'4K 超清',
|
|
||||||
'HDR 真彩色',
|
|
||||||
'杜比视界',
|
|
||||||
'8K 超高清'
|
|
||||||
][index];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,84 +0,0 @@
|
|||||||
import 'package:PiliPlus/models/dynamics/article_list/category.dart';
|
|
||||||
import 'package:PiliPlus/models/dynamics/article_list/stats.dart';
|
|
||||||
|
|
||||||
class Article {
|
|
||||||
int? id;
|
|
||||||
String? title;
|
|
||||||
int? state;
|
|
||||||
int? publishTime;
|
|
||||||
int? words;
|
|
||||||
List? imageUrls;
|
|
||||||
Category? category;
|
|
||||||
List<Category>? categories;
|
|
||||||
String? summary;
|
|
||||||
int? type;
|
|
||||||
String? dynIdStr;
|
|
||||||
int? attributes;
|
|
||||||
int? authorUid;
|
|
||||||
int? onlyFans;
|
|
||||||
Stats? stats;
|
|
||||||
int? likeState;
|
|
||||||
|
|
||||||
Article({
|
|
||||||
this.id,
|
|
||||||
this.title,
|
|
||||||
this.state,
|
|
||||||
this.publishTime,
|
|
||||||
this.words,
|
|
||||||
this.imageUrls,
|
|
||||||
this.category,
|
|
||||||
this.categories,
|
|
||||||
this.summary,
|
|
||||||
this.type,
|
|
||||||
this.dynIdStr,
|
|
||||||
this.attributes,
|
|
||||||
this.authorUid,
|
|
||||||
this.onlyFans,
|
|
||||||
this.stats,
|
|
||||||
this.likeState,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory Article.fromJson(Map<String, dynamic> json) => Article(
|
|
||||||
id: json['id'] as int?,
|
|
||||||
title: json['title'] as String?,
|
|
||||||
state: json['state'] as int?,
|
|
||||||
publishTime: json['publish_time'] as int?,
|
|
||||||
words: json['words'] as int?,
|
|
||||||
imageUrls: json['image_urls'],
|
|
||||||
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(),
|
|
||||||
summary: json['summary'] as String?,
|
|
||||||
type: json['type'] as int?,
|
|
||||||
dynIdStr: json['dyn_id_str'] as String?,
|
|
||||||
attributes: json['attributes'] as int?,
|
|
||||||
authorUid: json['author_uid'] as int?,
|
|
||||||
onlyFans: json['only_fans'] as int?,
|
|
||||||
stats: json['stats'] == null
|
|
||||||
? null
|
|
||||||
: Stats.fromJson(json['stats'] as Map<String, dynamic>),
|
|
||||||
likeState: json['like_state'] as int?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'id': id,
|
|
||||||
'title': title,
|
|
||||||
'state': state,
|
|
||||||
'publish_time': publishTime,
|
|
||||||
'words': words,
|
|
||||||
'image_urls': imageUrls,
|
|
||||||
'category': category?.toJson(),
|
|
||||||
'categories': categories?.map((e) => e.toJson()).toList(),
|
|
||||||
'summary': summary,
|
|
||||||
'type': type,
|
|
||||||
'dyn_id_str': dynIdStr,
|
|
||||||
'attributes': attributes,
|
|
||||||
'author_uid': authorUid,
|
|
||||||
'only_fans': onlyFans,
|
|
||||||
'stats': stats?.toJson(),
|
|
||||||
'like_state': likeState,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
class Author {
|
|
||||||
int? mid;
|
|
||||||
String? name;
|
|
||||||
String? face;
|
|
||||||
|
|
||||||
Author({
|
|
||||||
this.mid,
|
|
||||||
this.name,
|
|
||||||
this.face,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory Author.fromJson(Map<String, dynamic> json) => Author(
|
|
||||||
mid: json['mid'] as int?,
|
|
||||||
name: json['name'] as String?,
|
|
||||||
face: json['face'] as String?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'mid': mid,
|
|
||||||
'name': name,
|
|
||||||
'face': face,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
class Category {
|
|
||||||
int? id;
|
|
||||||
int? parentId;
|
|
||||||
String? name;
|
|
||||||
|
|
||||||
Category({this.id, this.parentId, this.name});
|
|
||||||
|
|
||||||
factory Category.fromJson(Map<String, dynamic> json) => Category(
|
|
||||||
id: json['id'] as int?,
|
|
||||||
parentId: json['parent_id'] as int?,
|
|
||||||
name: json['name'] as String?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'id': id,
|
|
||||||
'parent_id': parentId,
|
|
||||||
'name': name,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
import 'package:PiliPlus/models/dynamics/article_list/article.dart';
|
|
||||||
import 'package:PiliPlus/models/dynamics/article_list/author.dart';
|
|
||||||
import 'package:PiliPlus/models/dynamics/article_list/list.dart';
|
import 'package:PiliPlus/models/dynamics/article_list/list.dart';
|
||||||
|
import 'package:PiliPlus/models/model_owner.dart';
|
||||||
|
import 'package:PiliPlus/models/space_article/item.dart';
|
||||||
|
|
||||||
class ArticleListData {
|
class ArticleListData {
|
||||||
ArticleList? list;
|
ArticleList? list;
|
||||||
List<Article>? articles;
|
List<SpaceArticleItem>? articles;
|
||||||
Author? author;
|
Owner? author;
|
||||||
bool? attention;
|
bool? attention;
|
||||||
|
|
||||||
ArticleListData({
|
ArticleListData({
|
||||||
@@ -21,18 +21,11 @@ class ArticleListData {
|
|||||||
? null
|
? null
|
||||||
: ArticleList.fromJson(json['list'] as Map<String, dynamic>),
|
: ArticleList.fromJson(json['list'] as Map<String, dynamic>),
|
||||||
articles: (json['articles'] as List<dynamic>?)
|
articles: (json['articles'] as List<dynamic>?)
|
||||||
?.map((e) => Article.fromJson(e as Map<String, dynamic>))
|
?.map((e) => SpaceArticleItem.fromJson(e as Map<String, dynamic>))
|
||||||
.toList(),
|
.toList(),
|
||||||
author: json['author'] == null
|
author: json['author'] == null
|
||||||
? null
|
? null
|
||||||
: Author.fromJson(json['author'] as Map<String, dynamic>),
|
: Owner.fromJson(json['author'] as Map<String, dynamic>),
|
||||||
attention: json['attention'] as bool?,
|
attention: json['attention'] as bool?,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'list': list?.toJson(),
|
|
||||||
'articles': articles?.map((e) => e.toJson()).toList(),
|
|
||||||
'author': author?.toJson(),
|
|
||||||
'attention': attention,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
class Stats {
|
|
||||||
int? view;
|
|
||||||
int? favorite;
|
|
||||||
int? like;
|
|
||||||
int? dislike;
|
|
||||||
int? reply;
|
|
||||||
int? share;
|
|
||||||
int? coin;
|
|
||||||
int? dynam1c;
|
|
||||||
|
|
||||||
Stats({
|
|
||||||
this.view,
|
|
||||||
this.favorite,
|
|
||||||
this.like,
|
|
||||||
this.dislike,
|
|
||||||
this.reply,
|
|
||||||
this.share,
|
|
||||||
this.coin,
|
|
||||||
this.dynam1c,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory Stats.fromJson(Map<String, dynamic> json) => Stats(
|
|
||||||
view: json['view'] as int?,
|
|
||||||
favorite: json['favorite'] as int?,
|
|
||||||
like: json['like'] as int?,
|
|
||||||
dislike: json['dislike'] as int?,
|
|
||||||
reply: json['reply'] as int?,
|
|
||||||
share: json['share'] as int?,
|
|
||||||
coin: json['coin'] as int?,
|
|
||||||
dynam1c: json['dynamic'] as int?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'view': view,
|
|
||||||
'favorite': favorite,
|
|
||||||
'like': like,
|
|
||||||
'dislike': dislike,
|
|
||||||
'reply': reply,
|
|
||||||
'share': share,
|
|
||||||
'coin': coin,
|
|
||||||
'dynamic': dynam1c,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -136,24 +136,7 @@ bool _isMCDNorPCDN(String url) {
|
|||||||
_ipRegExp.hasMatch(url);
|
_ipRegExp.hasMatch(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
class VideoItem {
|
abstract class BaseItem {
|
||||||
VideoItem({
|
|
||||||
this.id,
|
|
||||||
this.baseUrl,
|
|
||||||
this.backupUrl,
|
|
||||||
this.bandWidth,
|
|
||||||
this.mimeType,
|
|
||||||
this.codecs,
|
|
||||||
this.width,
|
|
||||||
this.height,
|
|
||||||
this.frameRate,
|
|
||||||
this.sar,
|
|
||||||
this.startWithSap,
|
|
||||||
this.segmentBase,
|
|
||||||
this.codecid,
|
|
||||||
this.quality,
|
|
||||||
});
|
|
||||||
|
|
||||||
int? id;
|
int? id;
|
||||||
String? baseUrl;
|
String? baseUrl;
|
||||||
String? backupUrl;
|
String? backupUrl;
|
||||||
@@ -167,16 +150,31 @@ class VideoItem {
|
|||||||
int? startWithSap;
|
int? startWithSap;
|
||||||
Map? segmentBase;
|
Map? segmentBase;
|
||||||
int? codecid;
|
int? codecid;
|
||||||
VideoQuality? quality;
|
|
||||||
|
|
||||||
VideoItem.fromJson(Map<String, dynamic> json) {
|
BaseItem({
|
||||||
|
this.id,
|
||||||
|
this.baseUrl,
|
||||||
|
this.backupUrl,
|
||||||
|
this.bandWidth,
|
||||||
|
this.mimeType,
|
||||||
|
this.codecs,
|
||||||
|
this.width,
|
||||||
|
this.height,
|
||||||
|
this.frameRate,
|
||||||
|
this.sar,
|
||||||
|
this.startWithSap,
|
||||||
|
this.segmentBase,
|
||||||
|
this.codecid,
|
||||||
|
});
|
||||||
|
|
||||||
|
BaseItem.fromJson(Map<String, dynamic> json) {
|
||||||
id = json['id'];
|
id = json['id'];
|
||||||
baseUrl = json['baseUrl'];
|
baseUrl = json['baseUrl'];
|
||||||
var backupUrls = json['backupUrl']?.toList() ?? [];
|
final backupUrls = (json['backupUrl'] as List?)?.cast<String>() ?? [];
|
||||||
backupUrl = backupUrls.isNotEmpty
|
backupUrl = backupUrls.isNotEmpty
|
||||||
? backupUrls.firstWhere((i) => !_isMCDNorPCDN(i),
|
? backupUrls.firstWhere((i) => !_isMCDNorPCDN(i),
|
||||||
orElse: () => backupUrls.first)
|
orElse: () => backupUrls.first)
|
||||||
: '';
|
: null;
|
||||||
bandWidth = json['bandWidth'];
|
bandWidth = json['bandWidth'];
|
||||||
mimeType = json['mime_type'];
|
mimeType = json['mime_type'];
|
||||||
codecs = json['codecs'];
|
codecs = json['codecs'];
|
||||||
@@ -187,82 +185,41 @@ class VideoItem {
|
|||||||
startWithSap = json['startWithSap'];
|
startWithSap = json['startWithSap'];
|
||||||
segmentBase = json['segmentBase'];
|
segmentBase = json['segmentBase'];
|
||||||
codecid = json['codecid'];
|
codecid = json['codecid'];
|
||||||
quality = VideoQuality.values.firstWhere((i) => i.code == json['id']);
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
|
||||||
Map<String, dynamic> data = <String, dynamic>{};
|
|
||||||
data['id'] = id;
|
|
||||||
data['baseUrl'] = baseUrl;
|
|
||||||
data['backupUrl'] = backupUrl;
|
|
||||||
data['bandWidth'] = bandWidth;
|
|
||||||
data['mime_type'] = mimeType;
|
|
||||||
data['codecs'] = codecs;
|
|
||||||
data['width'] = width;
|
|
||||||
data['height'] = height;
|
|
||||||
data['frameRate'] = frameRate;
|
|
||||||
data['sar'] = sar;
|
|
||||||
data['startWithSap'] = startWithSap;
|
|
||||||
data['segmentBase'] = segmentBase;
|
|
||||||
data['codecid'] = codecid;
|
|
||||||
data['quality'] = quality;
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AudioItem {
|
class VideoItem extends BaseItem {
|
||||||
AudioItem({
|
late VideoQuality quality;
|
||||||
this.id,
|
|
||||||
this.baseUrl,
|
VideoItem({
|
||||||
this.backupUrl,
|
super.id,
|
||||||
this.bandWidth,
|
super.baseUrl,
|
||||||
this.mimeType,
|
super.backupUrl,
|
||||||
this.codecs,
|
super.bandWidth,
|
||||||
this.width,
|
super.mimeType,
|
||||||
this.height,
|
super.codecs,
|
||||||
this.frameRate,
|
super.width,
|
||||||
this.sar,
|
super.height,
|
||||||
this.startWithSap,
|
super.frameRate,
|
||||||
this.segmentBase,
|
super.sar,
|
||||||
this.codecid,
|
super.startWithSap,
|
||||||
this.quality,
|
super.segmentBase,
|
||||||
|
super.codecid,
|
||||||
|
required this.quality,
|
||||||
});
|
});
|
||||||
|
|
||||||
int? id;
|
VideoItem.fromJson(Map<String, dynamic> json) : super.fromJson(json) {
|
||||||
String? baseUrl;
|
quality = VideoQuality.fromCode(json['id']);
|
||||||
String? backupUrl;
|
}
|
||||||
int? bandWidth;
|
}
|
||||||
String? mimeType;
|
|
||||||
String? codecs;
|
|
||||||
int? width;
|
|
||||||
int? height;
|
|
||||||
String? frameRate;
|
|
||||||
String? sar;
|
|
||||||
int? startWithSap;
|
|
||||||
Map? segmentBase;
|
|
||||||
int? codecid;
|
|
||||||
String? quality;
|
|
||||||
|
|
||||||
AudioItem.fromJson(Map<String, dynamic> json) {
|
class AudioItem extends BaseItem {
|
||||||
id = json['id'];
|
late String quality;
|
||||||
baseUrl = json['baseUrl'];
|
|
||||||
var backupUrls = json['backupUrl']?.toList() ?? [];
|
AudioItem();
|
||||||
backupUrl = backupUrls.isNotEmpty
|
|
||||||
? backupUrls.firstWhere((i) => !_isMCDNorPCDN(i),
|
AudioItem.fromJson(Map<String, dynamic> json) : super.fromJson(json) {
|
||||||
orElse: () => backupUrls.first)
|
quality = AudioQuality.fromCode(json['id']).description;
|
||||||
: '';
|
|
||||||
bandWidth = json['bandWidth'];
|
|
||||||
mimeType = json['mime_type'];
|
|
||||||
codecs = json['codecs'];
|
|
||||||
width = json['width'];
|
|
||||||
height = json['height'];
|
|
||||||
frameRate = json['frameRate'];
|
|
||||||
sar = json['sar'];
|
|
||||||
startWithSap = json['startWithSap'];
|
|
||||||
segmentBase = json['segmentBase'];
|
|
||||||
codecid = json['codecid'];
|
|
||||||
quality =
|
|
||||||
AudioQuality.values.firstWhere((i) => i.code == json['id']).description;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import 'package:PiliPlus/http/dynamics.dart';
|
import 'package:PiliPlus/http/dynamics.dart';
|
||||||
import 'package:PiliPlus/http/loading_state.dart';
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
import 'package:PiliPlus/models/dynamics/article_list/article.dart';
|
|
||||||
import 'package:PiliPlus/models/dynamics/article_list/author.dart';
|
|
||||||
import 'package:PiliPlus/models/dynamics/article_list/data.dart';
|
import 'package:PiliPlus/models/dynamics/article_list/data.dart';
|
||||||
import 'package:PiliPlus/models/dynamics/article_list/list.dart';
|
import 'package:PiliPlus/models/dynamics/article_list/list.dart';
|
||||||
|
import 'package:PiliPlus/models/model_owner.dart';
|
||||||
|
import 'package:PiliPlus/models/space_article/item.dart';
|
||||||
import 'package:PiliPlus/pages/common/common_list_controller.dart';
|
import 'package:PiliPlus/pages/common/common_list_controller.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
class ArticleListController
|
class ArticleListController
|
||||||
extends CommonListController<ArticleListData, Article> {
|
extends CommonListController<ArticleListData, SpaceArticleItem> {
|
||||||
final id = Get.parameters['id'];
|
final id = Get.parameters['id'];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -18,10 +18,10 @@ class ArticleListController
|
|||||||
}
|
}
|
||||||
|
|
||||||
Rx<ArticleList?> list = Rx<ArticleList?>(null);
|
Rx<ArticleList?> list = Rx<ArticleList?>(null);
|
||||||
Author? author;
|
Owner? author;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Article>? getDataList(ArticleListData response) {
|
List<SpaceArticleItem>? getDataList(ArticleListData response) {
|
||||||
list.value = response.list;
|
list.value = response.list;
|
||||||
author = response.author;
|
author = response.author;
|
||||||
return response.articles;
|
return response.articles;
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
|||||||
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
|
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
|
||||||
import 'package:PiliPlus/http/loading_state.dart';
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
import 'package:PiliPlus/models/common/image_type.dart';
|
import 'package:PiliPlus/models/common/image_type.dart';
|
||||||
import 'package:PiliPlus/models/dynamics/article_list/article.dart';
|
|
||||||
import 'package:PiliPlus/models/dynamics/article_list/list.dart';
|
import 'package:PiliPlus/models/dynamics/article_list/list.dart';
|
||||||
|
import 'package:PiliPlus/models/space_article/item.dart';
|
||||||
import 'package:PiliPlus/pages/article_list/controller.dart';
|
import 'package:PiliPlus/pages/article_list/controller.dart';
|
||||||
import 'package:PiliPlus/pages/article_list/widgets/item.dart';
|
import 'package:PiliPlus/pages/article_list/widgets/item.dart';
|
||||||
import 'package:PiliPlus/utils/grid.dart';
|
import 'package:PiliPlus/utils/grid.dart';
|
||||||
@@ -51,7 +51,7 @@ class _ArticleListPageState extends State<ArticleListPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBody(
|
Widget _buildBody(
|
||||||
ThemeData theme, LoadingState<List<Article>?> loadingState) {
|
ThemeData theme, LoadingState<List<SpaceArticleItem>?> loadingState) {
|
||||||
return switch (loadingState) {
|
return switch (loadingState) {
|
||||||
Loading() => SliverPadding(
|
Loading() => SliverPadding(
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:PiliPlus/common/constants.dart';
|
import 'package:PiliPlus/common/constants.dart';
|
||||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||||
import 'package:PiliPlus/common/widgets/stat/stat.dart';
|
import 'package:PiliPlus/common/widgets/stat/stat.dart';
|
||||||
import 'package:PiliPlus/models/dynamics/article_list/article.dart';
|
import 'package:PiliPlus/models/space_article/item.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ class ArticleListItem extends StatelessWidget {
|
|||||||
required this.item,
|
required this.item,
|
||||||
});
|
});
|
||||||
|
|
||||||
final Article item;
|
final SpaceArticleItem item;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|||||||
@@ -1064,7 +1064,7 @@ List<SettingsModel> get videoSettings => [
|
|||||||
title: '默认画质',
|
title: '默认画质',
|
||||||
leading: const Icon(Icons.video_settings_outlined),
|
leading: const Icon(Icons.video_settings_outlined),
|
||||||
getSubtitle: () =>
|
getSubtitle: () =>
|
||||||
'当前画质:${VideoQualityExt.fromCode(GStorage.defaultVideoQa)!.description}',
|
'当前画质:${VideoQuality.fromCode(GStorage.defaultVideoQa).description}',
|
||||||
onTap: (setState) async {
|
onTap: (setState) async {
|
||||||
int? result = await showDialog(
|
int? result = await showDialog(
|
||||||
context: Get.context!,
|
context: Get.context!,
|
||||||
@@ -1089,7 +1089,7 @@ List<SettingsModel> get videoSettings => [
|
|||||||
title: '蜂窝网络画质',
|
title: '蜂窝网络画质',
|
||||||
leading: const Icon(Icons.video_settings_outlined),
|
leading: const Icon(Icons.video_settings_outlined),
|
||||||
getSubtitle: () =>
|
getSubtitle: () =>
|
||||||
'当前画质:${VideoQualityExt.fromCode(GStorage.defaultVideoQaCellular)!.description}',
|
'当前画质:${VideoQuality.fromCode(GStorage.defaultVideoQaCellular).description}',
|
||||||
onTap: (setState) async {
|
onTap: (setState) async {
|
||||||
int? result = await showDialog(
|
int? result = await showDialog(
|
||||||
context: Get.context!,
|
context: Get.context!,
|
||||||
@@ -1115,7 +1115,7 @@ List<SettingsModel> get videoSettings => [
|
|||||||
title: '默认音质',
|
title: '默认音质',
|
||||||
leading: const Icon(Icons.music_video_outlined),
|
leading: const Icon(Icons.music_video_outlined),
|
||||||
getSubtitle: () =>
|
getSubtitle: () =>
|
||||||
'当前音质:${AudioQualityExt.fromCode(GStorage.defaultAudioQa)!.description}',
|
'当前音质:${AudioQuality.fromCode(GStorage.defaultAudioQa).description}',
|
||||||
onTap: (setState) async {
|
onTap: (setState) async {
|
||||||
int? result = await showDialog(
|
int? result = await showDialog(
|
||||||
context: Get.context!,
|
context: Get.context!,
|
||||||
@@ -1140,7 +1140,7 @@ List<SettingsModel> get videoSettings => [
|
|||||||
title: '蜂窝网络音质',
|
title: '蜂窝网络音质',
|
||||||
leading: const Icon(Icons.music_video_outlined),
|
leading: const Icon(Icons.music_video_outlined),
|
||||||
getSubtitle: () =>
|
getSubtitle: () =>
|
||||||
'当前音质:${AudioQualityExt.fromCode(GStorage.defaultAudioQaCellular)!.description}',
|
'当前音质:${AudioQuality.fromCode(GStorage.defaultAudioQaCellular).description}',
|
||||||
onTap: (setState) async {
|
onTap: (setState) async {
|
||||||
int? result = await showDialog(
|
int? result = await showDialog(
|
||||||
context: Get.context!,
|
context: Get.context!,
|
||||||
|
|||||||
@@ -1169,10 +1169,10 @@ class VideoDetailController extends GetxController
|
|||||||
id: data.quality!,
|
id: data.quality!,
|
||||||
baseUrl: videoUrl,
|
baseUrl: videoUrl,
|
||||||
codecs: 'avc1',
|
codecs: 'avc1',
|
||||||
quality: VideoQualityExt.fromCode(data.quality!)!);
|
quality: VideoQuality.fromCode(data.quality!));
|
||||||
setVideoHeight();
|
setVideoHeight();
|
||||||
currentDecodeFormats = VideoDecodeFormatTypeExt.fromString('avc1')!;
|
currentDecodeFormats = VideoDecodeFormatTypeExt.fromString('avc1')!;
|
||||||
currentVideoQa = VideoQualityExt.fromCode(data.quality!)!;
|
currentVideoQa = VideoQuality.fromCode(data.quality!);
|
||||||
if (autoPlay.value) {
|
if (autoPlay.value) {
|
||||||
isShowCover.value = false;
|
isShowCover.value = false;
|
||||||
await playerInit();
|
await playerInit();
|
||||||
@@ -1196,7 +1196,7 @@ class VideoDetailController extends GetxController
|
|||||||
final List<VideoItem> allVideosList = data.dash!.video!;
|
final List<VideoItem> allVideosList = data.dash!.video!;
|
||||||
// debugPrint("allVideosList:${allVideosList}");
|
// debugPrint("allVideosList:${allVideosList}");
|
||||||
// 当前可播放的最高质量视频
|
// 当前可播放的最高质量视频
|
||||||
int currentHighVideoQa = allVideosList.first.quality!.code;
|
int currentHighVideoQa = allVideosList.first.quality.code;
|
||||||
// 预设的画质为null,则当前可用的最高质量
|
// 预设的画质为null,则当前可用的最高质量
|
||||||
int resVideoQa = currentHighVideoQa;
|
int resVideoQa = currentHighVideoQa;
|
||||||
if (plPlayerController.cacheVideoQa! <= currentHighVideoQa) {
|
if (plPlayerController.cacheVideoQa! <= currentHighVideoQa) {
|
||||||
@@ -1206,11 +1206,11 @@ class VideoDetailController extends GetxController
|
|||||||
resVideoQa =
|
resVideoQa =
|
||||||
Utils.findClosestNumber(plPlayerController.cacheVideoQa!, numbers);
|
Utils.findClosestNumber(plPlayerController.cacheVideoQa!, numbers);
|
||||||
}
|
}
|
||||||
currentVideoQa = VideoQualityExt.fromCode(resVideoQa)!;
|
currentVideoQa = VideoQuality.fromCode(resVideoQa);
|
||||||
|
|
||||||
/// 取出符合当前画质的videoList
|
/// 取出符合当前画质的videoList
|
||||||
final List<VideoItem> videosList =
|
final List<VideoItem> videosList =
|
||||||
allVideosList.where((e) => e.quality!.code == resVideoQa).toList();
|
allVideosList.where((e) => e.quality.code == resVideoQa).toList();
|
||||||
|
|
||||||
/// 优先顺序 设置中指定解码格式 -> 当前可选的首个解码格式
|
/// 优先顺序 设置中指定解码格式 -> 当前可选的首个解码格式
|
||||||
final List<FormatItem> supportFormats = data.supportFormats!;
|
final List<FormatItem> supportFormats = data.supportFormats!;
|
||||||
@@ -1274,7 +1274,7 @@ class VideoDetailController extends GetxController
|
|||||||
orElse: () => audiosList.first);
|
orElse: () => audiosList.first);
|
||||||
audioUrl = VideoUtils.getCdnUrl(firstAudio);
|
audioUrl = VideoUtils.getCdnUrl(firstAudio);
|
||||||
if (firstAudio.id != null) {
|
if (firstAudio.id != null) {
|
||||||
currentAudioQa = AudioQualityExt.fromCode(firstAudio.id!)!;
|
currentAudioQa = AudioQuality.fromCode(firstAudio.id!);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
firstAudio = AudioItem();
|
firstAudio = AudioItem();
|
||||||
|
|||||||
@@ -650,7 +650,7 @@ class HeaderControlState extends State<HeaderControl> {
|
|||||||
final int quality = videoFormat[i].quality!;
|
final int quality = videoFormat[i].quality!;
|
||||||
videoDetailCtr
|
videoDetailCtr
|
||||||
..currentVideoQa =
|
..currentVideoQa =
|
||||||
VideoQualityExt.fromCode(quality)!
|
VideoQuality.fromCode(quality)
|
||||||
..updatePlayer();
|
..updatePlayer();
|
||||||
|
|
||||||
// update
|
// update
|
||||||
@@ -659,16 +659,16 @@ class HeaderControlState extends State<HeaderControl> {
|
|||||||
.checkConnectivity()
|
.checkConnectivity()
|
||||||
.then((res) {
|
.then((res) {
|
||||||
if (res.contains(ConnectivityResult.wifi)) {
|
if (res.contains(ConnectivityResult.wifi)) {
|
||||||
oldQualityDesc = VideoQualityExt.fromCode(
|
oldQualityDesc = VideoQuality.fromCode(
|
||||||
GStorage.defaultVideoQa)!
|
GStorage.defaultVideoQa)
|
||||||
.description;
|
.description;
|
||||||
setting.put(
|
setting.put(
|
||||||
SettingBoxKey.defaultVideoQa,
|
SettingBoxKey.defaultVideoQa,
|
||||||
quality,
|
quality,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
oldQualityDesc = VideoQualityExt.fromCode(
|
oldQualityDesc = VideoQuality.fromCode(
|
||||||
GStorage.defaultVideoQaCellular)!
|
GStorage.defaultVideoQaCellular)
|
||||||
.description;
|
.description;
|
||||||
setting.put(
|
setting.put(
|
||||||
SettingBoxKey.defaultVideoQaCellular,
|
SettingBoxKey.defaultVideoQaCellular,
|
||||||
@@ -677,7 +677,7 @@ class HeaderControlState extends State<HeaderControl> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
SmartDialog.showToast(
|
SmartDialog.showToast(
|
||||||
"默认画质由:$oldQualityDesc 变为:${VideoQualityExt.fromCode(quality)!.description}",
|
"默认画质由:$oldQualityDesc 变为:${VideoQuality.fromCode(quality).description}",
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
// 可能包含会员解锁画质
|
// 可能包含会员解锁画质
|
||||||
@@ -745,7 +745,7 @@ class HeaderControlState extends State<HeaderControl> {
|
|||||||
final int quality = i.id!;
|
final int quality = i.id!;
|
||||||
videoDetailCtr
|
videoDetailCtr
|
||||||
..currentAudioQa =
|
..currentAudioQa =
|
||||||
AudioQualityExt.fromCode(quality)!
|
AudioQuality.fromCode(quality)
|
||||||
..updatePlayer();
|
..updatePlayer();
|
||||||
|
|
||||||
// update
|
// update
|
||||||
@@ -754,16 +754,16 @@ class HeaderControlState extends State<HeaderControl> {
|
|||||||
.checkConnectivity()
|
.checkConnectivity()
|
||||||
.then((res) {
|
.then((res) {
|
||||||
if (res.contains(ConnectivityResult.wifi)) {
|
if (res.contains(ConnectivityResult.wifi)) {
|
||||||
oldQualityDesc = AudioQualityExt.fromCode(
|
oldQualityDesc = AudioQuality.fromCode(
|
||||||
GStorage.defaultAudioQa)!
|
GStorage.defaultAudioQa)
|
||||||
.description;
|
.description;
|
||||||
setting.put(
|
setting.put(
|
||||||
SettingBoxKey.defaultAudioQa,
|
SettingBoxKey.defaultAudioQa,
|
||||||
quality,
|
quality,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
oldQualityDesc = AudioQualityExt.fromCode(
|
oldQualityDesc = AudioQuality.fromCode(
|
||||||
GStorage.defaultAudioQaCellular)!
|
GStorage.defaultAudioQaCellular)
|
||||||
.description;
|
.description;
|
||||||
setting.put(
|
setting.put(
|
||||||
SettingBoxKey.defaultAudioQaCellular,
|
SettingBoxKey.defaultAudioQaCellular,
|
||||||
@@ -772,12 +772,12 @@ class HeaderControlState extends State<HeaderControl> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
SmartDialog.showToast(
|
SmartDialog.showToast(
|
||||||
"默认音质由:$oldQualityDesc 变为:${AudioQualityExt.fromCode(quality)!.description}",
|
"默认音质由:$oldQualityDesc 变为:${AudioQuality.fromCode(quality).description}",
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
contentPadding:
|
contentPadding:
|
||||||
const EdgeInsets.only(left: 20, right: 20),
|
const EdgeInsets.only(left: 20, right: 20),
|
||||||
title: Text(i.quality!),
|
title: Text(i.quality),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
i.codecs!,
|
i.codecs!,
|
||||||
style: subTitleStyle,
|
style: subTitleStyle,
|
||||||
@@ -811,7 +811,7 @@ class HeaderControlState extends State<HeaderControl> {
|
|||||||
// 当前视频可用的解码格式
|
// 当前视频可用的解码格式
|
||||||
final List<FormatItem> videoFormat = videoInfo.supportFormats!;
|
final List<FormatItem> videoFormat = videoInfo.supportFormats!;
|
||||||
final List? list = videoFormat
|
final List? list = videoFormat
|
||||||
.firstWhere((FormatItem e) => e.quality == firstVideo.quality!.code)
|
.firstWhere((FormatItem e) => e.quality == firstVideo.quality.code)
|
||||||
.codecs;
|
.codecs;
|
||||||
if (list == null) {
|
if (list == null) {
|
||||||
SmartDialog.showToast('当前视频不支持选择解码格式');
|
SmartDialog.showToast('当前视频不支持选择解码格式');
|
||||||
|
|||||||
Reference in New Issue
Block a user