mirror of
https://github.com/StarCitizenToolBox/app.git
synced 2026-01-13 11:40:27 +00:00
feat: citizen news support
This commit is contained in:
parent
8d635827c4
commit
c2a512699c
23
lib/api/news_api.dart
Normal file
23
lib/api/news_api.dart
Normal file
@ -0,0 +1,23 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import '../common/conf/url_conf.dart';
|
||||
import '../common/io/rs_http.dart';
|
||||
import '../common/utils/log.dart';
|
||||
import '../data/citizen_news_data.dart';
|
||||
import 'api.dart';
|
||||
|
||||
class NewsApi {
|
||||
static Future<CitizenNewsData?> getLatest() async {
|
||||
try {
|
||||
final data = await RSHttp.getText(
|
||||
"${URLConf.newsApiHome}/api/latest",
|
||||
withCustomDns: await Api.isUseInternalDNS(),
|
||||
);
|
||||
final map = json.decode(data);
|
||||
return CitizenNewsData.fromJson(map);
|
||||
} catch (e) {
|
||||
dPrint("getLatestNews error: $e");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:dart_rss/dart_rss.dart';
|
||||
import 'package:starcitizen_doctor/common/io/rs_http.dart';
|
||||
import 'package:starcitizen_doctor/common/conf/url_conf.dart';
|
||||
|
||||
class RSSApi {
|
||||
static Future<List<RssItem>> getRssVideo() async {
|
||||
final r = await RSHttp.getText(URLConf.rssVideoUrl);
|
||||
final f = RssFeed.parse(r);
|
||||
return f.items.sublist(0, 8);
|
||||
}
|
||||
|
||||
static Future<List<RssItem>> getRssText() async {
|
||||
final r2 = await RSHttp.getText(URLConf.rssTextUrl2);
|
||||
final r2f = RssFeed.parse(r2);
|
||||
final items = r2f.items;
|
||||
items.sort((a, b) {
|
||||
final aDate = HttpDate.parse(a.pubDate ?? "").millisecondsSinceEpoch;
|
||||
final bDate = HttpDate.parse(b.pubDate ?? "").millisecondsSinceEpoch;
|
||||
return bDate - aDate;
|
||||
});
|
||||
return items;
|
||||
}
|
||||
}
|
||||
@ -7,7 +7,7 @@ import 'package:starcitizen_doctor/common/utils/log.dart';
|
||||
class URLConf {
|
||||
/// HOME API
|
||||
static String gitApiHome = "https://git.scbox.xkeyc.cn";
|
||||
static String rssApiHome = "https://rss.scbox.xkeyc.cn";
|
||||
static String newsApiHome = "https://scbox.citizenwiki.cn";
|
||||
static const String analyticsApiHome = "https://scbox.org";
|
||||
|
||||
static bool isUrlCheckPass = false;
|
||||
@ -15,31 +15,22 @@ class URLConf {
|
||||
/// URLS
|
||||
static String get giteaAttachmentsUrl => "$gitApiHome/SCToolBox/Release";
|
||||
|
||||
static String get gitlabLocalizationUrl =>
|
||||
"$gitApiHome/SCToolBox/LocalizationData";
|
||||
static String get gitlabLocalizationUrl => "$gitApiHome/SCToolBox/LocalizationData";
|
||||
|
||||
static String get gitApiRSILauncherEnhanceUrl =>
|
||||
"$gitApiHome/SCToolBox/RSILauncherEnhance";
|
||||
static String get gitApiRSILauncherEnhanceUrl => "$gitApiHome/SCToolBox/RSILauncherEnhance";
|
||||
|
||||
static String get apiRepoPath => "$gitApiHome/SCToolBox/api/raw/branch/main";
|
||||
|
||||
static String get gitlabApiPath => "$gitApiHome/api/v1/";
|
||||
|
||||
static String get webTranslateHomeUrl =>
|
||||
"$gitApiHome/SCToolBox/ScWeb_Chinese_Translate/raw/branch/main/json/locales";
|
||||
static String get webTranslateHomeUrl => "$gitApiHome/SCToolBox/ScWeb_Chinese_Translate/raw/branch/main/json/locales";
|
||||
|
||||
static String get rssVideoUrl =>
|
||||
"$rssApiHome/bilibili/user/channel/27976358/290653";
|
||||
|
||||
static String get rssTextUrl2 =>
|
||||
"$rssApiHome/baidu/tieba/user/%E7%81%AC%E7%81%ACG%E7%81%AC%E7%81%AC&";
|
||||
|
||||
static const String googleTranslateApiUrl =
|
||||
"https://translate-g-proxy.xkeyc.com";
|
||||
static const String googleTranslateApiUrl = "https://translate-g-proxy.xkeyc.com";
|
||||
|
||||
static const feedbackUrl = "https://support.citizenwiki.cn/all";
|
||||
static const feedbackFAQUrl = "https://support.citizenwiki.cn/t/sc-toolbox";
|
||||
static String nav42KitUrl = "https://payload.citizenwiki.cn/api/community-navs?sort=is_sponsored&depth=2&page=1&limit=1000";
|
||||
static String nav42KitUrl =
|
||||
"https://payload.citizenwiki.cn/api/community-navs?sort=is_sponsored&depth=2&page=1&limit=1000";
|
||||
|
||||
static String get devReleaseUrl => "$gitApiHome/SCToolBox/Release/releases";
|
||||
|
||||
@ -47,19 +38,19 @@ class URLConf {
|
||||
// 使用 DNS 获取可用列表
|
||||
final gitApiList = _genFinalList(await dnsLookupTxt("git.dns.scbox.org"));
|
||||
dPrint("DNS gitApiList ==== $gitApiList");
|
||||
final fasterGit = await getFasterUrl(gitApiList);
|
||||
final fasterGit = await getFasterUrl(gitApiList, "git");
|
||||
dPrint("gitApiList.Faster ==== $fasterGit");
|
||||
if (fasterGit != null) {
|
||||
gitApiHome = fasterGit;
|
||||
}
|
||||
final rssApiList = _genFinalList(await dnsLookupTxt("rss.dns.scbox.org"));
|
||||
final fasterRss = await getFasterUrl(rssApiList);
|
||||
dPrint("DNS rssApiList ==== $rssApiList");
|
||||
dPrint("rssApiList.Faster ==== $fasterRss");
|
||||
if (fasterRss != null) {
|
||||
rssApiHome = fasterRss;
|
||||
final newsApiList = _genFinalList(await dnsLookupTxt("news.dns.scbox.org"));
|
||||
final fasterNews = await getFasterUrl(newsApiList, "news");
|
||||
dPrint("DNS newsApiList ==== $newsApiList");
|
||||
dPrint("newsApiList.Faster ==== $fasterNews");
|
||||
if (fasterNews != null) {
|
||||
newsApiHome = fasterNews;
|
||||
}
|
||||
isUrlCheckPass = fasterGit != null && fasterRss != null;
|
||||
isUrlCheckPass = fasterGit != null && fasterNews != null;
|
||||
return isUrlCheckPass;
|
||||
}
|
||||
|
||||
@ -72,7 +63,7 @@ class URLConf {
|
||||
return (await DohClient.resolveTXT(host)) ?? [];
|
||||
}
|
||||
|
||||
static Future<String?> getFasterUrl(List<String> urls) async {
|
||||
static Future<String?> getFasterUrl(List<String> urls, String mode) async {
|
||||
String firstUrl = "";
|
||||
int callLen = 0;
|
||||
|
||||
@ -83,11 +74,23 @@ class URLConf {
|
||||
}
|
||||
}
|
||||
|
||||
for (var value in urls) {
|
||||
RSHttp.head(value).then((resp) => onCall(resp, value), onError: (err) {
|
||||
callLen++;
|
||||
dPrint("RSHttp.head error $err");
|
||||
});
|
||||
for (var url in urls) {
|
||||
var reqUrl = url;
|
||||
switch (mode) {
|
||||
case "git":
|
||||
reqUrl = "$url/SCToolBox/Api/raw/branch/main/sc_doctor/version.json";
|
||||
break;
|
||||
case "news":
|
||||
reqUrl = "$url/api/latest";
|
||||
break;
|
||||
}
|
||||
RSHttp.head(reqUrl).then(
|
||||
(resp) => onCall(resp, url),
|
||||
onError: (err) {
|
||||
callLen++;
|
||||
dPrint("RSHttp.head error $err");
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
while (true) {
|
||||
|
||||
54
lib/data/citizen_news_data.dart
Normal file
54
lib/data/citizen_news_data.dart
Normal file
@ -0,0 +1,54 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'citizen_news_data.freezed.dart';
|
||||
|
||||
part 'citizen_news_data.g.dart';
|
||||
|
||||
@freezed
|
||||
sealed class CitizenNewsData with _$CitizenNewsData {
|
||||
const factory CitizenNewsData({
|
||||
@Default(<CitizenNewsVideosItemData>[]) @JsonKey(name: 'videos') List<CitizenNewsVideosItemData> videos,
|
||||
@Default(<CitizenNewsArticlesItemData>[]) @JsonKey(name: 'articles') List<CitizenNewsArticlesItemData> articles,
|
||||
}) = _CitizenNewsData;
|
||||
|
||||
const CitizenNewsData._();
|
||||
|
||||
factory CitizenNewsData.fromJson(Map<String, Object?> json) => _$CitizenNewsDataFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
sealed class CitizenNewsVideosItemData with _$CitizenNewsVideosItemData {
|
||||
const factory CitizenNewsVideosItemData({
|
||||
@Default('') @JsonKey(name: 'title') String title,
|
||||
@Default('') @JsonKey(name: 'author') String author,
|
||||
@Default('') @JsonKey(name: 'description') String description,
|
||||
@Default('') @JsonKey(name: 'link') String link,
|
||||
@Default('') @JsonKey(name: 'pubDate') String pubDate,
|
||||
@Default('') @JsonKey(name: 'postId') String postId,
|
||||
@Default(<String>[]) @JsonKey(name: 'detailedDescription') List<String> detailedDescription,
|
||||
@Default('') @JsonKey(name: 'tag') String tag,
|
||||
}) = _CitizenNewsVideosItemData;
|
||||
|
||||
const CitizenNewsVideosItemData._();
|
||||
|
||||
factory CitizenNewsVideosItemData.fromJson(Map<String, Object?> json) => _$CitizenNewsVideosItemDataFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
sealed class CitizenNewsArticlesItemData with _$CitizenNewsArticlesItemData {
|
||||
const factory CitizenNewsArticlesItemData({
|
||||
@Default('') @JsonKey(name: 'title') String title,
|
||||
@Default('') @JsonKey(name: 'author') String author,
|
||||
@Default('') @JsonKey(name: 'description') String description,
|
||||
@Default('') @JsonKey(name: 'link') String link,
|
||||
@Default('') @JsonKey(name: 'pubDate') String pubDate,
|
||||
@Default('') @JsonKey(name: 'postId') String postId,
|
||||
@Default(<String>[]) @JsonKey(name: 'detailedDescription') List<String> detailedDescription,
|
||||
@Default('') @JsonKey(name: 'tag') String tag,
|
||||
}) = _CitizenNewsArticlesItemData;
|
||||
|
||||
const CitizenNewsArticlesItemData._();
|
||||
|
||||
factory CitizenNewsArticlesItemData.fromJson(Map<String, Object?> json) =>
|
||||
_$CitizenNewsArticlesItemDataFromJson(json);
|
||||
}
|
||||
854
lib/data/citizen_news_data.freezed.dart
Normal file
854
lib/data/citizen_news_data.freezed.dart
Normal file
@ -0,0 +1,854 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'citizen_news_data.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
/// @nodoc
|
||||
mixin _$CitizenNewsData {
|
||||
|
||||
@JsonKey(name: 'videos') List<CitizenNewsVideosItemData> get videos;@JsonKey(name: 'articles') List<CitizenNewsArticlesItemData> get articles;
|
||||
/// Create a copy of CitizenNewsData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$CitizenNewsDataCopyWith<CitizenNewsData> get copyWith => _$CitizenNewsDataCopyWithImpl<CitizenNewsData>(this as CitizenNewsData, _$identity);
|
||||
|
||||
/// Serializes this CitizenNewsData to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is CitizenNewsData&&const DeepCollectionEquality().equals(other.videos, videos)&&const DeepCollectionEquality().equals(other.articles, articles));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(videos),const DeepCollectionEquality().hash(articles));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'CitizenNewsData(videos: $videos, articles: $articles)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $CitizenNewsDataCopyWith<$Res> {
|
||||
factory $CitizenNewsDataCopyWith(CitizenNewsData value, $Res Function(CitizenNewsData) _then) = _$CitizenNewsDataCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
@JsonKey(name: 'videos') List<CitizenNewsVideosItemData> videos,@JsonKey(name: 'articles') List<CitizenNewsArticlesItemData> articles
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$CitizenNewsDataCopyWithImpl<$Res>
|
||||
implements $CitizenNewsDataCopyWith<$Res> {
|
||||
_$CitizenNewsDataCopyWithImpl(this._self, this._then);
|
||||
|
||||
final CitizenNewsData _self;
|
||||
final $Res Function(CitizenNewsData) _then;
|
||||
|
||||
/// Create a copy of CitizenNewsData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? videos = null,Object? articles = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
videos: null == videos ? _self.videos : videos // ignore: cast_nullable_to_non_nullable
|
||||
as List<CitizenNewsVideosItemData>,articles: null == articles ? _self.articles : articles // ignore: cast_nullable_to_non_nullable
|
||||
as List<CitizenNewsArticlesItemData>,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [CitizenNewsData].
|
||||
extension CitizenNewsDataPatterns on CitizenNewsData {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _CitizenNewsData value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _CitizenNewsData() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _CitizenNewsData value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _CitizenNewsData():
|
||||
return $default(_that);}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _CitizenNewsData value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _CitizenNewsData() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function(@JsonKey(name: 'videos') List<CitizenNewsVideosItemData> videos, @JsonKey(name: 'articles') List<CitizenNewsArticlesItemData> articles)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _CitizenNewsData() when $default != null:
|
||||
return $default(_that.videos,_that.articles);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function(@JsonKey(name: 'videos') List<CitizenNewsVideosItemData> videos, @JsonKey(name: 'articles') List<CitizenNewsArticlesItemData> articles) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _CitizenNewsData():
|
||||
return $default(_that.videos,_that.articles);}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function(@JsonKey(name: 'videos') List<CitizenNewsVideosItemData> videos, @JsonKey(name: 'articles') List<CitizenNewsArticlesItemData> articles)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _CitizenNewsData() when $default != null:
|
||||
return $default(_that.videos,_that.articles);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _CitizenNewsData extends CitizenNewsData {
|
||||
const _CitizenNewsData({@JsonKey(name: 'videos') final List<CitizenNewsVideosItemData> videos = const <CitizenNewsVideosItemData>[], @JsonKey(name: 'articles') final List<CitizenNewsArticlesItemData> articles = const <CitizenNewsArticlesItemData>[]}): _videos = videos,_articles = articles,super._();
|
||||
factory _CitizenNewsData.fromJson(Map<String, dynamic> json) => _$CitizenNewsDataFromJson(json);
|
||||
|
||||
final List<CitizenNewsVideosItemData> _videos;
|
||||
@override@JsonKey(name: 'videos') List<CitizenNewsVideosItemData> get videos {
|
||||
if (_videos is EqualUnmodifiableListView) return _videos;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_videos);
|
||||
}
|
||||
|
||||
final List<CitizenNewsArticlesItemData> _articles;
|
||||
@override@JsonKey(name: 'articles') List<CitizenNewsArticlesItemData> get articles {
|
||||
if (_articles is EqualUnmodifiableListView) return _articles;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_articles);
|
||||
}
|
||||
|
||||
|
||||
/// Create a copy of CitizenNewsData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$CitizenNewsDataCopyWith<_CitizenNewsData> get copyWith => __$CitizenNewsDataCopyWithImpl<_CitizenNewsData>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$CitizenNewsDataToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _CitizenNewsData&&const DeepCollectionEquality().equals(other._videos, _videos)&&const DeepCollectionEquality().equals(other._articles, _articles));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_videos),const DeepCollectionEquality().hash(_articles));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'CitizenNewsData(videos: $videos, articles: $articles)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$CitizenNewsDataCopyWith<$Res> implements $CitizenNewsDataCopyWith<$Res> {
|
||||
factory _$CitizenNewsDataCopyWith(_CitizenNewsData value, $Res Function(_CitizenNewsData) _then) = __$CitizenNewsDataCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
@JsonKey(name: 'videos') List<CitizenNewsVideosItemData> videos,@JsonKey(name: 'articles') List<CitizenNewsArticlesItemData> articles
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$CitizenNewsDataCopyWithImpl<$Res>
|
||||
implements _$CitizenNewsDataCopyWith<$Res> {
|
||||
__$CitizenNewsDataCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _CitizenNewsData _self;
|
||||
final $Res Function(_CitizenNewsData) _then;
|
||||
|
||||
/// Create a copy of CitizenNewsData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? videos = null,Object? articles = null,}) {
|
||||
return _then(_CitizenNewsData(
|
||||
videos: null == videos ? _self._videos : videos // ignore: cast_nullable_to_non_nullable
|
||||
as List<CitizenNewsVideosItemData>,articles: null == articles ? _self._articles : articles // ignore: cast_nullable_to_non_nullable
|
||||
as List<CitizenNewsArticlesItemData>,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// @nodoc
|
||||
mixin _$CitizenNewsVideosItemData {
|
||||
|
||||
@JsonKey(name: 'title') String get title;@JsonKey(name: 'author') String get author;@JsonKey(name: 'description') String get description;@JsonKey(name: 'link') String get link;@JsonKey(name: 'pubDate') String get pubDate;@JsonKey(name: 'postId') String get postId;@JsonKey(name: 'detailedDescription') List<String> get detailedDescription;@JsonKey(name: 'tag') String get tag;
|
||||
/// Create a copy of CitizenNewsVideosItemData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$CitizenNewsVideosItemDataCopyWith<CitizenNewsVideosItemData> get copyWith => _$CitizenNewsVideosItemDataCopyWithImpl<CitizenNewsVideosItemData>(this as CitizenNewsVideosItemData, _$identity);
|
||||
|
||||
/// Serializes this CitizenNewsVideosItemData to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is CitizenNewsVideosItemData&&(identical(other.title, title) || other.title == title)&&(identical(other.author, author) || other.author == author)&&(identical(other.description, description) || other.description == description)&&(identical(other.link, link) || other.link == link)&&(identical(other.pubDate, pubDate) || other.pubDate == pubDate)&&(identical(other.postId, postId) || other.postId == postId)&&const DeepCollectionEquality().equals(other.detailedDescription, detailedDescription)&&(identical(other.tag, tag) || other.tag == tag));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,title,author,description,link,pubDate,postId,const DeepCollectionEquality().hash(detailedDescription),tag);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'CitizenNewsVideosItemData(title: $title, author: $author, description: $description, link: $link, pubDate: $pubDate, postId: $postId, detailedDescription: $detailedDescription, tag: $tag)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $CitizenNewsVideosItemDataCopyWith<$Res> {
|
||||
factory $CitizenNewsVideosItemDataCopyWith(CitizenNewsVideosItemData value, $Res Function(CitizenNewsVideosItemData) _then) = _$CitizenNewsVideosItemDataCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
@JsonKey(name: 'title') String title,@JsonKey(name: 'author') String author,@JsonKey(name: 'description') String description,@JsonKey(name: 'link') String link,@JsonKey(name: 'pubDate') String pubDate,@JsonKey(name: 'postId') String postId,@JsonKey(name: 'detailedDescription') List<String> detailedDescription,@JsonKey(name: 'tag') String tag
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$CitizenNewsVideosItemDataCopyWithImpl<$Res>
|
||||
implements $CitizenNewsVideosItemDataCopyWith<$Res> {
|
||||
_$CitizenNewsVideosItemDataCopyWithImpl(this._self, this._then);
|
||||
|
||||
final CitizenNewsVideosItemData _self;
|
||||
final $Res Function(CitizenNewsVideosItemData) _then;
|
||||
|
||||
/// Create a copy of CitizenNewsVideosItemData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? title = null,Object? author = null,Object? description = null,Object? link = null,Object? pubDate = null,Object? postId = null,Object? detailedDescription = null,Object? tag = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
||||
as String,author: null == author ? _self.author : author // ignore: cast_nullable_to_non_nullable
|
||||
as String,description: null == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
||||
as String,link: null == link ? _self.link : link // ignore: cast_nullable_to_non_nullable
|
||||
as String,pubDate: null == pubDate ? _self.pubDate : pubDate // ignore: cast_nullable_to_non_nullable
|
||||
as String,postId: null == postId ? _self.postId : postId // ignore: cast_nullable_to_non_nullable
|
||||
as String,detailedDescription: null == detailedDescription ? _self.detailedDescription : detailedDescription // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>,tag: null == tag ? _self.tag : tag // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [CitizenNewsVideosItemData].
|
||||
extension CitizenNewsVideosItemDataPatterns on CitizenNewsVideosItemData {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _CitizenNewsVideosItemData value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _CitizenNewsVideosItemData() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _CitizenNewsVideosItemData value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _CitizenNewsVideosItemData():
|
||||
return $default(_that);}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _CitizenNewsVideosItemData value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _CitizenNewsVideosItemData() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function(@JsonKey(name: 'title') String title, @JsonKey(name: 'author') String author, @JsonKey(name: 'description') String description, @JsonKey(name: 'link') String link, @JsonKey(name: 'pubDate') String pubDate, @JsonKey(name: 'postId') String postId, @JsonKey(name: 'detailedDescription') List<String> detailedDescription, @JsonKey(name: 'tag') String tag)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _CitizenNewsVideosItemData() when $default != null:
|
||||
return $default(_that.title,_that.author,_that.description,_that.link,_that.pubDate,_that.postId,_that.detailedDescription,_that.tag);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function(@JsonKey(name: 'title') String title, @JsonKey(name: 'author') String author, @JsonKey(name: 'description') String description, @JsonKey(name: 'link') String link, @JsonKey(name: 'pubDate') String pubDate, @JsonKey(name: 'postId') String postId, @JsonKey(name: 'detailedDescription') List<String> detailedDescription, @JsonKey(name: 'tag') String tag) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _CitizenNewsVideosItemData():
|
||||
return $default(_that.title,_that.author,_that.description,_that.link,_that.pubDate,_that.postId,_that.detailedDescription,_that.tag);}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function(@JsonKey(name: 'title') String title, @JsonKey(name: 'author') String author, @JsonKey(name: 'description') String description, @JsonKey(name: 'link') String link, @JsonKey(name: 'pubDate') String pubDate, @JsonKey(name: 'postId') String postId, @JsonKey(name: 'detailedDescription') List<String> detailedDescription, @JsonKey(name: 'tag') String tag)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _CitizenNewsVideosItemData() when $default != null:
|
||||
return $default(_that.title,_that.author,_that.description,_that.link,_that.pubDate,_that.postId,_that.detailedDescription,_that.tag);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _CitizenNewsVideosItemData extends CitizenNewsVideosItemData {
|
||||
const _CitizenNewsVideosItemData({@JsonKey(name: 'title') this.title = '', @JsonKey(name: 'author') this.author = '', @JsonKey(name: 'description') this.description = '', @JsonKey(name: 'link') this.link = '', @JsonKey(name: 'pubDate') this.pubDate = '', @JsonKey(name: 'postId') this.postId = '', @JsonKey(name: 'detailedDescription') final List<String> detailedDescription = const <String>[], @JsonKey(name: 'tag') this.tag = ''}): _detailedDescription = detailedDescription,super._();
|
||||
factory _CitizenNewsVideosItemData.fromJson(Map<String, dynamic> json) => _$CitizenNewsVideosItemDataFromJson(json);
|
||||
|
||||
@override@JsonKey(name: 'title') final String title;
|
||||
@override@JsonKey(name: 'author') final String author;
|
||||
@override@JsonKey(name: 'description') final String description;
|
||||
@override@JsonKey(name: 'link') final String link;
|
||||
@override@JsonKey(name: 'pubDate') final String pubDate;
|
||||
@override@JsonKey(name: 'postId') final String postId;
|
||||
final List<String> _detailedDescription;
|
||||
@override@JsonKey(name: 'detailedDescription') List<String> get detailedDescription {
|
||||
if (_detailedDescription is EqualUnmodifiableListView) return _detailedDescription;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_detailedDescription);
|
||||
}
|
||||
|
||||
@override@JsonKey(name: 'tag') final String tag;
|
||||
|
||||
/// Create a copy of CitizenNewsVideosItemData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$CitizenNewsVideosItemDataCopyWith<_CitizenNewsVideosItemData> get copyWith => __$CitizenNewsVideosItemDataCopyWithImpl<_CitizenNewsVideosItemData>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$CitizenNewsVideosItemDataToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _CitizenNewsVideosItemData&&(identical(other.title, title) || other.title == title)&&(identical(other.author, author) || other.author == author)&&(identical(other.description, description) || other.description == description)&&(identical(other.link, link) || other.link == link)&&(identical(other.pubDate, pubDate) || other.pubDate == pubDate)&&(identical(other.postId, postId) || other.postId == postId)&&const DeepCollectionEquality().equals(other._detailedDescription, _detailedDescription)&&(identical(other.tag, tag) || other.tag == tag));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,title,author,description,link,pubDate,postId,const DeepCollectionEquality().hash(_detailedDescription),tag);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'CitizenNewsVideosItemData(title: $title, author: $author, description: $description, link: $link, pubDate: $pubDate, postId: $postId, detailedDescription: $detailedDescription, tag: $tag)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$CitizenNewsVideosItemDataCopyWith<$Res> implements $CitizenNewsVideosItemDataCopyWith<$Res> {
|
||||
factory _$CitizenNewsVideosItemDataCopyWith(_CitizenNewsVideosItemData value, $Res Function(_CitizenNewsVideosItemData) _then) = __$CitizenNewsVideosItemDataCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
@JsonKey(name: 'title') String title,@JsonKey(name: 'author') String author,@JsonKey(name: 'description') String description,@JsonKey(name: 'link') String link,@JsonKey(name: 'pubDate') String pubDate,@JsonKey(name: 'postId') String postId,@JsonKey(name: 'detailedDescription') List<String> detailedDescription,@JsonKey(name: 'tag') String tag
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$CitizenNewsVideosItemDataCopyWithImpl<$Res>
|
||||
implements _$CitizenNewsVideosItemDataCopyWith<$Res> {
|
||||
__$CitizenNewsVideosItemDataCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _CitizenNewsVideosItemData _self;
|
||||
final $Res Function(_CitizenNewsVideosItemData) _then;
|
||||
|
||||
/// Create a copy of CitizenNewsVideosItemData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? title = null,Object? author = null,Object? description = null,Object? link = null,Object? pubDate = null,Object? postId = null,Object? detailedDescription = null,Object? tag = null,}) {
|
||||
return _then(_CitizenNewsVideosItemData(
|
||||
title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
||||
as String,author: null == author ? _self.author : author // ignore: cast_nullable_to_non_nullable
|
||||
as String,description: null == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
||||
as String,link: null == link ? _self.link : link // ignore: cast_nullable_to_non_nullable
|
||||
as String,pubDate: null == pubDate ? _self.pubDate : pubDate // ignore: cast_nullable_to_non_nullable
|
||||
as String,postId: null == postId ? _self.postId : postId // ignore: cast_nullable_to_non_nullable
|
||||
as String,detailedDescription: null == detailedDescription ? _self._detailedDescription : detailedDescription // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>,tag: null == tag ? _self.tag : tag // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// @nodoc
|
||||
mixin _$CitizenNewsArticlesItemData {
|
||||
|
||||
@JsonKey(name: 'title') String get title;@JsonKey(name: 'author') String get author;@JsonKey(name: 'description') String get description;@JsonKey(name: 'link') String get link;@JsonKey(name: 'pubDate') String get pubDate;@JsonKey(name: 'postId') String get postId;@JsonKey(name: 'detailedDescription') List<String> get detailedDescription;@JsonKey(name: 'tag') String get tag;
|
||||
/// Create a copy of CitizenNewsArticlesItemData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$CitizenNewsArticlesItemDataCopyWith<CitizenNewsArticlesItemData> get copyWith => _$CitizenNewsArticlesItemDataCopyWithImpl<CitizenNewsArticlesItemData>(this as CitizenNewsArticlesItemData, _$identity);
|
||||
|
||||
/// Serializes this CitizenNewsArticlesItemData to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is CitizenNewsArticlesItemData&&(identical(other.title, title) || other.title == title)&&(identical(other.author, author) || other.author == author)&&(identical(other.description, description) || other.description == description)&&(identical(other.link, link) || other.link == link)&&(identical(other.pubDate, pubDate) || other.pubDate == pubDate)&&(identical(other.postId, postId) || other.postId == postId)&&const DeepCollectionEquality().equals(other.detailedDescription, detailedDescription)&&(identical(other.tag, tag) || other.tag == tag));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,title,author,description,link,pubDate,postId,const DeepCollectionEquality().hash(detailedDescription),tag);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'CitizenNewsArticlesItemData(title: $title, author: $author, description: $description, link: $link, pubDate: $pubDate, postId: $postId, detailedDescription: $detailedDescription, tag: $tag)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $CitizenNewsArticlesItemDataCopyWith<$Res> {
|
||||
factory $CitizenNewsArticlesItemDataCopyWith(CitizenNewsArticlesItemData value, $Res Function(CitizenNewsArticlesItemData) _then) = _$CitizenNewsArticlesItemDataCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
@JsonKey(name: 'title') String title,@JsonKey(name: 'author') String author,@JsonKey(name: 'description') String description,@JsonKey(name: 'link') String link,@JsonKey(name: 'pubDate') String pubDate,@JsonKey(name: 'postId') String postId,@JsonKey(name: 'detailedDescription') List<String> detailedDescription,@JsonKey(name: 'tag') String tag
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$CitizenNewsArticlesItemDataCopyWithImpl<$Res>
|
||||
implements $CitizenNewsArticlesItemDataCopyWith<$Res> {
|
||||
_$CitizenNewsArticlesItemDataCopyWithImpl(this._self, this._then);
|
||||
|
||||
final CitizenNewsArticlesItemData _self;
|
||||
final $Res Function(CitizenNewsArticlesItemData) _then;
|
||||
|
||||
/// Create a copy of CitizenNewsArticlesItemData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? title = null,Object? author = null,Object? description = null,Object? link = null,Object? pubDate = null,Object? postId = null,Object? detailedDescription = null,Object? tag = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
||||
as String,author: null == author ? _self.author : author // ignore: cast_nullable_to_non_nullable
|
||||
as String,description: null == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
||||
as String,link: null == link ? _self.link : link // ignore: cast_nullable_to_non_nullable
|
||||
as String,pubDate: null == pubDate ? _self.pubDate : pubDate // ignore: cast_nullable_to_non_nullable
|
||||
as String,postId: null == postId ? _self.postId : postId // ignore: cast_nullable_to_non_nullable
|
||||
as String,detailedDescription: null == detailedDescription ? _self.detailedDescription : detailedDescription // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>,tag: null == tag ? _self.tag : tag // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [CitizenNewsArticlesItemData].
|
||||
extension CitizenNewsArticlesItemDataPatterns on CitizenNewsArticlesItemData {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _CitizenNewsArticlesItemData value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _CitizenNewsArticlesItemData() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _CitizenNewsArticlesItemData value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _CitizenNewsArticlesItemData():
|
||||
return $default(_that);}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _CitizenNewsArticlesItemData value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _CitizenNewsArticlesItemData() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function(@JsonKey(name: 'title') String title, @JsonKey(name: 'author') String author, @JsonKey(name: 'description') String description, @JsonKey(name: 'link') String link, @JsonKey(name: 'pubDate') String pubDate, @JsonKey(name: 'postId') String postId, @JsonKey(name: 'detailedDescription') List<String> detailedDescription, @JsonKey(name: 'tag') String tag)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _CitizenNewsArticlesItemData() when $default != null:
|
||||
return $default(_that.title,_that.author,_that.description,_that.link,_that.pubDate,_that.postId,_that.detailedDescription,_that.tag);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function(@JsonKey(name: 'title') String title, @JsonKey(name: 'author') String author, @JsonKey(name: 'description') String description, @JsonKey(name: 'link') String link, @JsonKey(name: 'pubDate') String pubDate, @JsonKey(name: 'postId') String postId, @JsonKey(name: 'detailedDescription') List<String> detailedDescription, @JsonKey(name: 'tag') String tag) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _CitizenNewsArticlesItemData():
|
||||
return $default(_that.title,_that.author,_that.description,_that.link,_that.pubDate,_that.postId,_that.detailedDescription,_that.tag);}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function(@JsonKey(name: 'title') String title, @JsonKey(name: 'author') String author, @JsonKey(name: 'description') String description, @JsonKey(name: 'link') String link, @JsonKey(name: 'pubDate') String pubDate, @JsonKey(name: 'postId') String postId, @JsonKey(name: 'detailedDescription') List<String> detailedDescription, @JsonKey(name: 'tag') String tag)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _CitizenNewsArticlesItemData() when $default != null:
|
||||
return $default(_that.title,_that.author,_that.description,_that.link,_that.pubDate,_that.postId,_that.detailedDescription,_that.tag);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _CitizenNewsArticlesItemData extends CitizenNewsArticlesItemData {
|
||||
const _CitizenNewsArticlesItemData({@JsonKey(name: 'title') this.title = '', @JsonKey(name: 'author') this.author = '', @JsonKey(name: 'description') this.description = '', @JsonKey(name: 'link') this.link = '', @JsonKey(name: 'pubDate') this.pubDate = '', @JsonKey(name: 'postId') this.postId = '', @JsonKey(name: 'detailedDescription') final List<String> detailedDescription = const <String>[], @JsonKey(name: 'tag') this.tag = ''}): _detailedDescription = detailedDescription,super._();
|
||||
factory _CitizenNewsArticlesItemData.fromJson(Map<String, dynamic> json) => _$CitizenNewsArticlesItemDataFromJson(json);
|
||||
|
||||
@override@JsonKey(name: 'title') final String title;
|
||||
@override@JsonKey(name: 'author') final String author;
|
||||
@override@JsonKey(name: 'description') final String description;
|
||||
@override@JsonKey(name: 'link') final String link;
|
||||
@override@JsonKey(name: 'pubDate') final String pubDate;
|
||||
@override@JsonKey(name: 'postId') final String postId;
|
||||
final List<String> _detailedDescription;
|
||||
@override@JsonKey(name: 'detailedDescription') List<String> get detailedDescription {
|
||||
if (_detailedDescription is EqualUnmodifiableListView) return _detailedDescription;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_detailedDescription);
|
||||
}
|
||||
|
||||
@override@JsonKey(name: 'tag') final String tag;
|
||||
|
||||
/// Create a copy of CitizenNewsArticlesItemData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$CitizenNewsArticlesItemDataCopyWith<_CitizenNewsArticlesItemData> get copyWith => __$CitizenNewsArticlesItemDataCopyWithImpl<_CitizenNewsArticlesItemData>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$CitizenNewsArticlesItemDataToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _CitizenNewsArticlesItemData&&(identical(other.title, title) || other.title == title)&&(identical(other.author, author) || other.author == author)&&(identical(other.description, description) || other.description == description)&&(identical(other.link, link) || other.link == link)&&(identical(other.pubDate, pubDate) || other.pubDate == pubDate)&&(identical(other.postId, postId) || other.postId == postId)&&const DeepCollectionEquality().equals(other._detailedDescription, _detailedDescription)&&(identical(other.tag, tag) || other.tag == tag));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,title,author,description,link,pubDate,postId,const DeepCollectionEquality().hash(_detailedDescription),tag);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'CitizenNewsArticlesItemData(title: $title, author: $author, description: $description, link: $link, pubDate: $pubDate, postId: $postId, detailedDescription: $detailedDescription, tag: $tag)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$CitizenNewsArticlesItemDataCopyWith<$Res> implements $CitizenNewsArticlesItemDataCopyWith<$Res> {
|
||||
factory _$CitizenNewsArticlesItemDataCopyWith(_CitizenNewsArticlesItemData value, $Res Function(_CitizenNewsArticlesItemData) _then) = __$CitizenNewsArticlesItemDataCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
@JsonKey(name: 'title') String title,@JsonKey(name: 'author') String author,@JsonKey(name: 'description') String description,@JsonKey(name: 'link') String link,@JsonKey(name: 'pubDate') String pubDate,@JsonKey(name: 'postId') String postId,@JsonKey(name: 'detailedDescription') List<String> detailedDescription,@JsonKey(name: 'tag') String tag
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$CitizenNewsArticlesItemDataCopyWithImpl<$Res>
|
||||
implements _$CitizenNewsArticlesItemDataCopyWith<$Res> {
|
||||
__$CitizenNewsArticlesItemDataCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _CitizenNewsArticlesItemData _self;
|
||||
final $Res Function(_CitizenNewsArticlesItemData) _then;
|
||||
|
||||
/// Create a copy of CitizenNewsArticlesItemData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? title = null,Object? author = null,Object? description = null,Object? link = null,Object? pubDate = null,Object? postId = null,Object? detailedDescription = null,Object? tag = null,}) {
|
||||
return _then(_CitizenNewsArticlesItemData(
|
||||
title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
||||
as String,author: null == author ? _self.author : author // ignore: cast_nullable_to_non_nullable
|
||||
as String,description: null == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
||||
as String,link: null == link ? _self.link : link // ignore: cast_nullable_to_non_nullable
|
||||
as String,pubDate: null == pubDate ? _self.pubDate : pubDate // ignore: cast_nullable_to_non_nullable
|
||||
as String,postId: null == postId ? _self.postId : postId // ignore: cast_nullable_to_non_nullable
|
||||
as String,detailedDescription: null == detailedDescription ? _self._detailedDescription : detailedDescription // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>,tag: null == tag ? _self.tag : tag // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
91
lib/data/citizen_news_data.g.dart
Normal file
91
lib/data/citizen_news_data.g.dart
Normal file
@ -0,0 +1,91 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'citizen_news_data.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_CitizenNewsData _$CitizenNewsDataFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _CitizenNewsData(
|
||||
videos:
|
||||
(json['videos'] as List<dynamic>?)
|
||||
?.map(
|
||||
(e) =>
|
||||
CitizenNewsVideosItemData.fromJson(e as Map<String, dynamic>),
|
||||
)
|
||||
.toList() ??
|
||||
const <CitizenNewsVideosItemData>[],
|
||||
articles:
|
||||
(json['articles'] as List<dynamic>?)
|
||||
?.map(
|
||||
(e) =>
|
||||
CitizenNewsArticlesItemData.fromJson(e as Map<String, dynamic>),
|
||||
)
|
||||
.toList() ??
|
||||
const <CitizenNewsArticlesItemData>[],
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$CitizenNewsDataToJson(_CitizenNewsData instance) =>
|
||||
<String, dynamic>{'videos': instance.videos, 'articles': instance.articles};
|
||||
|
||||
_CitizenNewsVideosItemData _$CitizenNewsVideosItemDataFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _CitizenNewsVideosItemData(
|
||||
title: json['title'] as String? ?? '',
|
||||
author: json['author'] as String? ?? '',
|
||||
description: json['description'] as String? ?? '',
|
||||
link: json['link'] as String? ?? '',
|
||||
pubDate: json['pubDate'] as String? ?? '',
|
||||
postId: json['postId'] as String? ?? '',
|
||||
detailedDescription:
|
||||
(json['detailedDescription'] as List<dynamic>?)
|
||||
?.map((e) => e as String)
|
||||
.toList() ??
|
||||
const <String>[],
|
||||
tag: json['tag'] as String? ?? '',
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$CitizenNewsVideosItemDataToJson(
|
||||
_CitizenNewsVideosItemData instance,
|
||||
) => <String, dynamic>{
|
||||
'title': instance.title,
|
||||
'author': instance.author,
|
||||
'description': instance.description,
|
||||
'link': instance.link,
|
||||
'pubDate': instance.pubDate,
|
||||
'postId': instance.postId,
|
||||
'detailedDescription': instance.detailedDescription,
|
||||
'tag': instance.tag,
|
||||
};
|
||||
|
||||
_CitizenNewsArticlesItemData _$CitizenNewsArticlesItemDataFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _CitizenNewsArticlesItemData(
|
||||
title: json['title'] as String? ?? '',
|
||||
author: json['author'] as String? ?? '',
|
||||
description: json['description'] as String? ?? '',
|
||||
link: json['link'] as String? ?? '',
|
||||
pubDate: json['pubDate'] as String? ?? '',
|
||||
postId: json['postId'] as String? ?? '',
|
||||
detailedDescription:
|
||||
(json['detailedDescription'] as List<dynamic>?)
|
||||
?.map((e) => e as String)
|
||||
.toList() ??
|
||||
const <String>[],
|
||||
tag: json['tag'] as String? ?? '',
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$CitizenNewsArticlesItemDataToJson(
|
||||
_CitizenNewsArticlesItemData instance,
|
||||
) => <String, dynamic>{
|
||||
'title': instance.title,
|
||||
'author': instance.author,
|
||||
'description': instance.description,
|
||||
'link': instance.link,
|
||||
'pubDate': instance.pubDate,
|
||||
'postId': instance.postId,
|
||||
'detailedDescription': instance.detailedDescription,
|
||||
'tag': instance.tag,
|
||||
};
|
||||
@ -6,18 +6,17 @@ import 'package:starcitizen_doctor/widgets/widgets.dart';
|
||||
|
||||
class HomeMdContentDialogUI extends HookConsumerWidget {
|
||||
final String title;
|
||||
final String url;
|
||||
final String? url;
|
||||
final String? mdContent;
|
||||
|
||||
const HomeMdContentDialogUI(
|
||||
{super.key, required this.title, required this.url});
|
||||
const HomeMdContentDialogUI({super.key, required this.title, this.url, this.mdContent})
|
||||
: assert(url != null || mdContent != null, "Either url or htmlContent must be provided");
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return Material(
|
||||
child: ContentDialog(
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: MediaQuery.of(context).size.width * .6,
|
||||
),
|
||||
constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * .6),
|
||||
title: Text(title),
|
||||
content: LoadingWidget(
|
||||
onLoadData: _getContent,
|
||||
@ -36,21 +35,24 @@ class HomeMdContentDialogUI extends HookConsumerWidget {
|
||||
),
|
||||
actions: [
|
||||
FilledButton(
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(left: 8, right: 8, top: 2, bottom: 2),
|
||||
child: Text(S.current.action_close),
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
})
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 8, right: 8, top: 2, bottom: 2),
|
||||
child: Text(S.current.action_close),
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<String> _getContent() async {
|
||||
final r = await RSHttp.getText(url);
|
||||
if (mdContent != null) {
|
||||
return mdContent!;
|
||||
}
|
||||
final r = await RSHttp.getText(url!);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,29 +59,27 @@ class HomeUI extends HookConsumerWidget {
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
],
|
||||
...makeIndex(context, model, homeState, ref)
|
||||
...makeIndex(context, model, homeState, ref),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
if (homeState.isFixing)
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black.withAlpha(150),
|
||||
),
|
||||
decoration: BoxDecoration(color: Colors.black.withAlpha(150)),
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const ProgressRing(),
|
||||
const SizedBox(height: 12),
|
||||
Text(homeState.isFixingString.isNotEmpty
|
||||
? homeState.isFixingString
|
||||
: S.current.doctor_info_processing),
|
||||
Text(
|
||||
homeState.isFixingString.isNotEmpty ? homeState.isFixingString : S.current.doctor_info_processing,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
@ -100,28 +98,16 @@ class HomeUI extends HookConsumerWidget {
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 30),
|
||||
child: Image.asset(
|
||||
"assets/sc_logo.png",
|
||||
fit: BoxFit.fitHeight,
|
||||
height: 260,
|
||||
),
|
||||
child: Image.asset("assets/sc_logo.png", fit: BoxFit.fitHeight, height: 260),
|
||||
),
|
||||
makeGameStatusCard(context, model, 340, homeState)
|
||||
makeGameStatusCard(context, model, 340, homeState),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: 0,
|
||||
left: 24,
|
||||
child: makeLeftColumn(context, model, width, homeState),
|
||||
),
|
||||
Positioned(
|
||||
right: 24,
|
||||
top: 0,
|
||||
child: makeNewsCard(context, model, homeState),
|
||||
),
|
||||
Positioned(top: 0, left: 24, child: makeLeftColumn(context, model, width, homeState)),
|
||||
Positioned(right: 24, top: 0, child: makeNewsCard(context, model, homeState)),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
@ -137,10 +123,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
await context.push("/guide");
|
||||
await model.reScanPath();
|
||||
},
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(6),
|
||||
child: Icon(FluentIcons.settings),
|
||||
),
|
||||
child: const Padding(padding: EdgeInsets.all(6), child: Icon(FluentIcons.settings)),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Expanded(
|
||||
@ -148,17 +131,12 @@ class HomeUI extends HookConsumerWidget {
|
||||
value: homeState.scInstalledPath,
|
||||
isExpanded: true,
|
||||
items: [
|
||||
ComboBoxItem(
|
||||
value: "not_install",
|
||||
child: Text(S.current.home_not_installed_or_failed),
|
||||
),
|
||||
ComboBoxItem(value: "not_install", child: Text(S.current.home_not_installed_or_failed)),
|
||||
for (final path in homeState.scInstallPaths)
|
||||
ComboBoxItem(
|
||||
value: path,
|
||||
child: Row(
|
||||
children: [Text(path)],
|
||||
),
|
||||
)
|
||||
child: Row(children: [Text(path)]),
|
||||
),
|
||||
],
|
||||
onChanged: model.onChangeInstallPath,
|
||||
),
|
||||
@ -166,38 +144,29 @@ class HomeUI extends HookConsumerWidget {
|
||||
if (S.current.app_language_code == NoL10n.langCodeZhCn) ...[
|
||||
const SizedBox(width: 12),
|
||||
Button(
|
||||
onPressed: homeState.webLocalizationVersionsData == null ? null : () => model.launchRSI(context),
|
||||
style: homeState.isCurGameRunning
|
||||
? null
|
||||
: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.resolveWith(_getRunButtonColor),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(6),
|
||||
child: Icon(
|
||||
homeState.isCurGameRunning ? FluentIcons.stop_solid : FluentIcons.play_solid,
|
||||
color: homeState.isCurGameRunning ? Colors.red.withValues(alpha: .8) : Colors.white,
|
||||
),
|
||||
)),
|
||||
onPressed: homeState.webLocalizationVersionsData == null ? null : () => model.launchRSI(context),
|
||||
style: homeState.isCurGameRunning
|
||||
? null
|
||||
: ButtonStyle(backgroundColor: WidgetStateProperty.resolveWith(_getRunButtonColor)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(6),
|
||||
child: Icon(
|
||||
homeState.isCurGameRunning ? FluentIcons.stop_solid : FluentIcons.play_solid,
|
||||
color: homeState.isCurGameRunning ? Colors.red.withValues(alpha: .8) : Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
const SizedBox(width: 12),
|
||||
Button(
|
||||
onPressed: () => _checkAndGoInputMethod(context, homeState, model, ref),
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.resolveWith((_) => Colors.blue),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(6),
|
||||
child: Icon(FluentIcons.keyboard_classic),
|
||||
),
|
||||
style: ButtonStyle(backgroundColor: WidgetStateProperty.resolveWith((_) => Colors.blue)),
|
||||
child: Padding(padding: const EdgeInsets.all(6), child: Icon(FluentIcons.keyboard_classic)),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Button(
|
||||
onPressed: model.reScanPath,
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(6),
|
||||
child: Icon(FluentIcons.refresh),
|
||||
),
|
||||
child: const Padding(padding: EdgeInsets.all(6), child: Icon(FluentIcons.refresh)),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -223,55 +192,44 @@ class HomeUI extends HookConsumerWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
makeWebViewButton(context, model,
|
||||
icon: SvgPicture.asset(
|
||||
"assets/rsi.svg",
|
||||
colorFilter: makeSvgColor(Colors.white),
|
||||
height: 18,
|
||||
),
|
||||
name: S.current.home_action_star_citizen_website_localization,
|
||||
webTitle: S.current.home_action_star_citizen_website_localization,
|
||||
webURL: "https://robertsspaceindustries.com",
|
||||
info: S.current.home_action_info_roberts_space_industries_origin,
|
||||
useLocalization: true,
|
||||
width: width,
|
||||
touchKey: "webLocalization_rsi"),
|
||||
makeWebViewButton(
|
||||
context,
|
||||
model,
|
||||
icon: SvgPicture.asset("assets/rsi.svg", colorFilter: makeSvgColor(Colors.white), height: 18),
|
||||
name: S.current.home_action_star_citizen_website_localization,
|
||||
webTitle: S.current.home_action_star_citizen_website_localization,
|
||||
webURL: "https://robertsspaceindustries.com",
|
||||
info: S.current.home_action_info_roberts_space_industries_origin,
|
||||
useLocalization: true,
|
||||
width: width,
|
||||
touchKey: "webLocalization_rsi",
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
makeWebViewButton(context, model,
|
||||
icon: Row(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
"assets/uex.svg",
|
||||
height: 18,
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
],
|
||||
),
|
||||
name: S.current.home_action_uex_localization,
|
||||
webTitle: S.current.home_action_uex_localization,
|
||||
webURL: "https://uexcorp.space/",
|
||||
info: S.current.home_action_info_mining_refining_trade_calculator,
|
||||
useLocalization: true,
|
||||
width: width,
|
||||
touchKey: "webLocalization_uex"),
|
||||
makeWebViewButton(
|
||||
context,
|
||||
model,
|
||||
icon: Row(children: [SvgPicture.asset("assets/uex.svg", height: 18), const SizedBox(width: 12)]),
|
||||
name: S.current.home_action_uex_localization,
|
||||
webTitle: S.current.home_action_uex_localization,
|
||||
webURL: "https://uexcorp.space/",
|
||||
info: S.current.home_action_info_mining_refining_trade_calculator,
|
||||
useLocalization: true,
|
||||
width: width,
|
||||
touchKey: "webLocalization_uex",
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
makeWebViewButton(context, model,
|
||||
icon: Row(
|
||||
children: [
|
||||
Image.asset(
|
||||
"assets/dps.png",
|
||||
height: 20,
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
],
|
||||
),
|
||||
name: S.current.home_action_dps_calculator_localization,
|
||||
webTitle: S.current.home_action_dps_calculator_localization,
|
||||
webURL: "https://www.erkul.games/live/calculator",
|
||||
info: S.current.home_action_info_ship_upgrade_damage_value_query,
|
||||
useLocalization: true,
|
||||
width: width,
|
||||
touchKey: "webLocalization_dps"),
|
||||
makeWebViewButton(
|
||||
context,
|
||||
model,
|
||||
icon: Row(children: [Image.asset("assets/dps.png", height: 20), const SizedBox(width: 12)]),
|
||||
name: S.current.home_action_dps_calculator_localization,
|
||||
webTitle: S.current.home_action_dps_calculator_localization,
|
||||
webURL: "https://www.erkul.games/live/calculator",
|
||||
info: S.current.home_action_info_ship_upgrade_damage_value_query,
|
||||
useLocalization: true,
|
||||
width: width,
|
||||
touchKey: "webLocalization_dps",
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Text(S.current.home_action_external_browser_extension),
|
||||
const SizedBox(height: 12),
|
||||
@ -281,7 +239,8 @@ class HomeUI extends HookConsumerWidget {
|
||||
child: const FaIcon(FontAwesomeIcons.chrome, size: 18),
|
||||
onPressed: () {
|
||||
launchUrlString(
|
||||
"https://chrome.google.com/webstore/detail/gocnjckojmledijgmadmacoikibcggja?authuser=0&hl=zh-CN");
|
||||
"https://chrome.google.com/webstore/detail/gocnjckojmledijgmadmacoikibcggja?authuser=0&hl=zh-CN",
|
||||
);
|
||||
},
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
@ -289,15 +248,18 @@ class HomeUI extends HookConsumerWidget {
|
||||
child: const FaIcon(FontAwesomeIcons.edge, size: 18),
|
||||
onPressed: () {
|
||||
launchUrlString(
|
||||
"https://microsoftedge.microsoft.com/addons/detail/lipbbcckldklpdcpfagicipecaacikgi");
|
||||
"https://microsoftedge.microsoft.com/addons/detail/lipbbcckldklpdcpfagicipecaacikgi",
|
||||
);
|
||||
},
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Button(
|
||||
child: const FaIcon(FontAwesomeIcons.firefoxBrowser, size: 18),
|
||||
onPressed: () {
|
||||
launchUrlString("https://addons.mozilla.org/zh-CN/firefox/"
|
||||
"addon/%E6%98%9F%E9%99%85%E5%85%AC%E6%B0%91%E7%9B%92%E5%AD%90%E6%B5%8F%E8%A7%88%E5%99%A8%E6%8B%93%E5%B1%95/");
|
||||
launchUrlString(
|
||||
"https://addons.mozilla.org/zh-CN/firefox/"
|
||||
"addon/%E6%98%9F%E9%99%85%E5%85%AC%E6%B0%91%E7%9B%92%E5%AD%90%E6%B5%8F%E8%A7%88%E5%99%A8%E6%8B%93%E5%B1%95/",
|
||||
);
|
||||
},
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
@ -308,7 +270,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -319,13 +281,14 @@ class HomeUI extends HookConsumerWidget {
|
||||
),
|
||||
if (homeState.webLocalizationVersionsData == null)
|
||||
Positioned.fill(
|
||||
child: Container(
|
||||
decoration:
|
||||
BoxDecoration(color: Colors.black.withValues(alpha: .3), borderRadius: BorderRadius.circular(12)),
|
||||
child: const Center(
|
||||
child: ProgressRing(),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black.withValues(alpha: .3),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: const Center(child: ProgressRing()),
|
||||
),
|
||||
))
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
@ -334,95 +297,113 @@ class HomeUI extends HookConsumerWidget {
|
||||
return ScrollConfiguration(
|
||||
behavior: ScrollConfiguration.of(context).copyWith(scrollbars: false),
|
||||
child: Container(
|
||||
width: 316,
|
||||
height: 386,
|
||||
decoration: BoxDecoration(color: Colors.white.withValues(alpha: .1), borderRadius: BorderRadius.circular(12)),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 190,
|
||||
width: 316,
|
||||
child: Tilt(
|
||||
shadowConfig: const ShadowConfig(maxIntensity: .3),
|
||||
borderRadius: const BorderRadius.only(
|
||||
topLeft: Radius.circular(12),
|
||||
topRight: Radius.circular(12),
|
||||
),
|
||||
child: homeState.rssVideoItems == null
|
||||
? Container(
|
||||
decoration: BoxDecoration(color: Colors.white.withValues(alpha: .1)),
|
||||
child: makeLoading(context),
|
||||
)
|
||||
: Swiper(
|
||||
itemCount: getMinNumber([homeState.rssVideoItems?.length ?? 0, 6]),
|
||||
itemBuilder: (context, index) {
|
||||
final item = homeState.rssVideoItems![index];
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
if (item.link != null) {
|
||||
launchUrlString(item.link!);
|
||||
}
|
||||
},
|
||||
child: CacheNetImage(
|
||||
url: model.getRssImage(item),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
);
|
||||
},
|
||||
autoplay: true,
|
||||
),
|
||||
)),
|
||||
const SizedBox(height: 1),
|
||||
if (homeState.rssTextItems == null)
|
||||
makeLoading(context)
|
||||
else
|
||||
ListView.builder(
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final item = homeState.rssTextItems![index];
|
||||
return Tilt(
|
||||
shadowConfig: const ShadowConfig(maxIntensity: .3),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: GestureDetector(
|
||||
width: 316,
|
||||
height: 386,
|
||||
decoration: BoxDecoration(color: Colors.white.withValues(alpha: .1), borderRadius: BorderRadius.circular(12)),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 210,
|
||||
width: 316,
|
||||
child: homeState.citizenNewsData == null
|
||||
? Container(
|
||||
decoration: BoxDecoration(color: Colors.white.withValues(alpha: .1)),
|
||||
child: makeLoading(context),
|
||||
)
|
||||
: HoverSwiper(
|
||||
itemCount: getMinNumber([homeState.citizenNewsData?.videos.length ?? 0, 6]),
|
||||
itemBuilder: (context, index) {
|
||||
final item = homeState.citizenNewsData?.videos[index];
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
if (item.link != null) {
|
||||
launchUrlString(item.link!);
|
||||
}
|
||||
launchUrlString(item?.link ?? "");
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 12, right: 12, top: 4, bottom: 4),
|
||||
child: Row(
|
||||
children: [
|
||||
getRssIcon(item.link ?? ""),
|
||||
const SizedBox(width: 6),
|
||||
Expanded(
|
||||
child: Text(
|
||||
model.handleTitle(item.title),
|
||||
textAlign: TextAlign.start,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(fontSize: 12.2),
|
||||
child: Column(
|
||||
children: [
|
||||
CacheNetImage(
|
||||
url: model.getRssImage(item?.description),
|
||||
fit: BoxFit.cover,
|
||||
height: 180,
|
||||
),
|
||||
SizedBox(
|
||||
height: 30,
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(color: Colors.black),
|
||||
padding: EdgeInsets.symmetric(horizontal: 6),
|
||||
child: Center(
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
"${index + 1}. ${(item?.title ?? "").replaceAll("【寰宇周刊】", "")}",
|
||||
style: TextStyle(fontSize: 12),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Icon(
|
||||
FluentIcons.chevron_right,
|
||||
size: 12,
|
||||
color: Colors.white.withValues(alpha: .4),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
));
|
||||
},
|
||||
itemCount: homeState.rssTextItems?.length,
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
],
|
||||
),
|
||||
)),
|
||||
);
|
||||
},
|
||||
paginationActiveSize: 8.0,
|
||||
controlSize: 24,
|
||||
controlPadding: const EdgeInsets.symmetric(horizontal: 8, vertical: 0),
|
||||
autoplayDelay: 5000,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 1),
|
||||
if (homeState.citizenNewsData?.articles == null)
|
||||
makeLoading(context)
|
||||
else
|
||||
ListView.builder(
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final item = homeState.citizenNewsData!.articles[index];
|
||||
return Tilt(
|
||||
shadowConfig: const ShadowConfig(maxIntensity: .3),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
launchUrlString(item.link);
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 12, right: 12, top: 4, bottom: 4),
|
||||
child: Row(
|
||||
children: [
|
||||
getRssIcon(item.link),
|
||||
const SizedBox(width: 6),
|
||||
Expanded(
|
||||
child: Text(
|
||||
model.handleTitle(item.title),
|
||||
textAlign: TextAlign.start,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(fontSize: 12.2),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Icon(FluentIcons.chevron_right, size: 12, color: Colors.white.withValues(alpha: .4)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
itemCount: homeState.citizenNewsData?.articles.length ?? 0,
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -432,11 +413,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
if (url.startsWith("https://www.bilibili.com")) {
|
||||
return const FaIcon(
|
||||
FontAwesomeIcons.bilibili,
|
||||
size: 14,
|
||||
color: Color.fromRGBO(0, 161, 214, 1),
|
||||
);
|
||||
return const FaIcon(FontAwesomeIcons.bilibili, size: 14, color: Color.fromRGBO(0, 161, 214, 1));
|
||||
}
|
||||
|
||||
return const FaIcon(FontAwesomeIcons.rss, size: 14);
|
||||
@ -444,97 +421,104 @@ class HomeUI extends HookConsumerWidget {
|
||||
|
||||
Widget makeIndexActionLists(BuildContext context, HomeUIModel model, HomeUIModelState homeState, WidgetRef ref) {
|
||||
final items = [
|
||||
_HomeItemData("game_doctor", S.current.home_action_one_click_diagnosis,
|
||||
S.current.home_action_info_one_click_diagnosis_star_citizen, FluentIcons.auto_deploy_settings),
|
||||
_HomeItemData("localization", S.current.home_action_localization_management,
|
||||
S.current.home_action_info_quick_install_localization_resources, FluentIcons.locale_language),
|
||||
_HomeItemData("performance", S.current.home_action_performance_optimization,
|
||||
S.current.home_action_info_engine_config_optimization, FluentIcons.process_meta_task),
|
||||
_HomeItemData(
|
||||
"game_doctor",
|
||||
S.current.home_action_one_click_diagnosis,
|
||||
S.current.home_action_info_one_click_diagnosis_star_citizen,
|
||||
FluentIcons.auto_deploy_settings,
|
||||
),
|
||||
_HomeItemData(
|
||||
"localization",
|
||||
S.current.home_action_localization_management,
|
||||
S.current.home_action_info_quick_install_localization_resources,
|
||||
FluentIcons.locale_language,
|
||||
),
|
||||
_HomeItemData(
|
||||
"performance",
|
||||
S.current.home_action_performance_optimization,
|
||||
S.current.home_action_info_engine_config_optimization,
|
||||
FluentIcons.process_meta_task,
|
||||
),
|
||||
];
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: AlignedGridView.count(
|
||||
crossAxisCount: 3,
|
||||
mainAxisSpacing: 12,
|
||||
crossAxisSpacing: 12,
|
||||
itemCount: items.length,
|
||||
shrinkWrap: true,
|
||||
itemBuilder: (context, index) {
|
||||
final item = items.elementAt(index);
|
||||
return HoverButton(
|
||||
onPressed: () => _onMenuTap(context, item.key, homeState, ref),
|
||||
builder: (BuildContext context, Set<WidgetState> states) {
|
||||
return Container(
|
||||
width: 300,
|
||||
height: 120,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: states.isHovered
|
||||
? FluentTheme.of(context).cardColor.withValues(alpha: .1)
|
||||
: FluentTheme.of(context).cardColor,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withValues(alpha: .2), borderRadius: BorderRadius.circular(1000)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Icon(
|
||||
item.icon,
|
||||
size: 24,
|
||||
),
|
||||
),
|
||||
crossAxisCount: 3,
|
||||
mainAxisSpacing: 12,
|
||||
crossAxisSpacing: 12,
|
||||
itemCount: items.length,
|
||||
shrinkWrap: true,
|
||||
itemBuilder: (context, index) {
|
||||
final item = items.elementAt(index);
|
||||
return HoverButton(
|
||||
onPressed: () => _onMenuTap(context, item.key, homeState, ref),
|
||||
builder: (BuildContext context, Set<WidgetState> states) {
|
||||
return Container(
|
||||
width: 300,
|
||||
height: 120,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: states.isHovered
|
||||
? FluentTheme.of(context).cardColor.withValues(alpha: .1)
|
||||
: FluentTheme.of(context).cardColor,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withValues(alpha: .2),
|
||||
borderRadius: BorderRadius.circular(1000),
|
||||
),
|
||||
const SizedBox(width: 24),
|
||||
Expanded(
|
||||
child: Column(
|
||||
child: Padding(padding: const EdgeInsets.all(12), child: Icon(item.icon, size: 24)),
|
||||
),
|
||||
const SizedBox(width: 24),
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
item.name,
|
||||
style: const TextStyle(fontSize: 18),
|
||||
),
|
||||
Text(item.name, style: const TextStyle(fontSize: 18)),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
item.infoString,
|
||||
style: TextStyle(fontSize: 14, color: Colors.white.withValues(alpha: .6)),
|
||||
),
|
||||
],
|
||||
)),
|
||||
if (item.key == "localization" && homeState.localizationUpdateInfo != null)
|
||||
Container(
|
||||
padding: const EdgeInsets.only(top: 3, bottom: 3, left: 8, right: 8),
|
||||
decoration: BoxDecoration(color: Colors.red, borderRadius: BorderRadius.circular(12)),
|
||||
child: Text(homeState.localizationUpdateInfo?.key ?? " "),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
const Icon(
|
||||
FluentIcons.chevron_right,
|
||||
size: 16,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
if (item.key == "localization" && homeState.localizationUpdateInfo != null)
|
||||
Container(
|
||||
padding: const EdgeInsets.only(top: 3, bottom: 3, left: 8, right: 8),
|
||||
decoration: BoxDecoration(color: Colors.red, borderRadius: BorderRadius.circular(12)),
|
||||
child: Text(homeState.localizationUpdateInfo?.key ?? " "),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
const Icon(FluentIcons.chevron_right, size: 16),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget makeWebViewButton(BuildContext context, HomeUIModel model,
|
||||
{required Widget icon,
|
||||
required String name,
|
||||
required String webTitle,
|
||||
required String webURL,
|
||||
required bool useLocalization,
|
||||
required double width,
|
||||
String? info,
|
||||
String? touchKey}) {
|
||||
Widget makeWebViewButton(
|
||||
BuildContext context,
|
||||
HomeUIModel model, {
|
||||
required Widget icon,
|
||||
required String name,
|
||||
required String webTitle,
|
||||
required String webURL,
|
||||
required bool useLocalization,
|
||||
required double width,
|
||||
String? info,
|
||||
String? touchKey,
|
||||
}) {
|
||||
return Tilt(
|
||||
shadowConfig: const ShadowConfig(maxIntensity: .3),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
@ -547,9 +531,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
},
|
||||
child: Container(
|
||||
width: width,
|
||||
decoration: BoxDecoration(
|
||||
color: FluentTheme.of(context).cardColor,
|
||||
),
|
||||
decoration: BoxDecoration(color: FluentTheme.of(context).cardColor),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
@ -561,10 +543,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
Row(
|
||||
children: [
|
||||
icon,
|
||||
Text(
|
||||
name,
|
||||
style: const TextStyle(fontSize: 14),
|
||||
),
|
||||
Text(name, style: const TextStyle(fontSize: 14)),
|
||||
],
|
||||
),
|
||||
if (info != null)
|
||||
@ -575,16 +554,12 @@ class HomeUI extends HookConsumerWidget {
|
||||
maxLines: 1,
|
||||
style: TextStyle(fontSize: 12, color: Colors.white.withValues(alpha: .6)),
|
||||
),
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Icon(
|
||||
FluentIcons.chevron_right,
|
||||
size: 14,
|
||||
color: Colors.white.withValues(alpha: .6),
|
||||
)
|
||||
Icon(FluentIcons.chevron_right, size: 14, color: Colors.white.withValues(alpha: .6)),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -598,7 +573,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
"Platform": S.current.home_action_rsi_status_platform,
|
||||
"Persistent Universe": S.current.home_action_rsi_status_persistent_universe,
|
||||
"Electronic Access": S.current.home_action_rsi_status_electronic_access,
|
||||
"Arena Commander": S.current.home_action_rsi_status_arena_commander
|
||||
"Arena Commander": S.current.home_action_rsi_status_arena_commander,
|
||||
};
|
||||
|
||||
return Tilt(
|
||||
@ -607,52 +582,48 @@ class HomeUI extends HookConsumerWidget {
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
model.goWebView(
|
||||
context, S.current.home_action_rsi_status_rsi_server_status, "https://status.robertsspaceindustries.com/",
|
||||
useLocalization: true);
|
||||
context,
|
||||
S.current.home_action_rsi_status_rsi_server_status,
|
||||
"https://status.robertsspaceindustries.com/",
|
||||
useLocalization: true,
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
width: width,
|
||||
decoration: BoxDecoration(
|
||||
color: FluentTheme.of(context).cardColor,
|
||||
),
|
||||
decoration: BoxDecoration(color: FluentTheme.of(context).cardColor),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Column(children: [
|
||||
if (homeState.scServerStatus == null)
|
||||
makeLoading(context, width: 20)
|
||||
else
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(S.current.home_action_rsi_status_status),
|
||||
for (final item in homeState.scServerStatus ?? [])
|
||||
Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 14,
|
||||
child: Center(
|
||||
child: Icon(
|
||||
FontAwesomeIcons.solidCircle,
|
||||
color: model.isRSIServerStatusOK(item) ? Colors.green : Colors.red,
|
||||
size: 12,
|
||||
child: Column(
|
||||
children: [
|
||||
if (homeState.scServerStatus == null)
|
||||
makeLoading(context, width: 20)
|
||||
else
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(S.current.home_action_rsi_status_status),
|
||||
for (final item in homeState.scServerStatus ?? [])
|
||||
Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 14,
|
||||
child: Center(
|
||||
child: Icon(
|
||||
FontAwesomeIcons.solidCircle,
|
||||
color: model.isRSIServerStatusOK(item) ? Colors.green : Colors.red,
|
||||
size: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
Text(
|
||||
"${statusCnName[item["name"]] ?? item["name"]}",
|
||||
style: const TextStyle(fontSize: 13),
|
||||
),
|
||||
],
|
||||
),
|
||||
Icon(
|
||||
FluentIcons.chevron_right,
|
||||
size: 12,
|
||||
color: Colors.white.withValues(alpha: .4),
|
||||
)
|
||||
],
|
||||
)
|
||||
]),
|
||||
const SizedBox(width: 5),
|
||||
Text("${statusCnName[item["name"]] ?? item["name"]}", style: const TextStyle(fontSize: 13)),
|
||||
],
|
||||
),
|
||||
Icon(FluentIcons.chevron_right, size: 12, color: Colors.white.withValues(alpha: .4)),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -666,65 +637,55 @@ class HomeUI extends HookConsumerWidget {
|
||||
child: GestureDetector(
|
||||
onTap: () => _onTapFestival(context),
|
||||
child: Container(
|
||||
width: width + 24,
|
||||
decoration: BoxDecoration(color: FluentTheme.of(context).cardColor),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 12, right: 12, top: 8, bottom: 8),
|
||||
child: (homeState.countdownFestivalListData == null)
|
||||
? SizedBox(
|
||||
width: width,
|
||||
height: 62,
|
||||
child: const Center(
|
||||
child: ProgressRing(),
|
||||
),
|
||||
)
|
||||
: SizedBox(
|
||||
width: width,
|
||||
height: 62,
|
||||
child: Swiper(
|
||||
itemCount: getMinNumber([homeState.countdownFestivalListData!.length, 6]),
|
||||
autoplay: true,
|
||||
autoplayDelay: 5000,
|
||||
itemBuilder: (context, index) {
|
||||
final item = homeState.countdownFestivalListData![index];
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
if (item.icon != null && item.icon != "") ...[
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(1000),
|
||||
child: Image.asset(
|
||||
"assets/countdown/${item.icon}",
|
||||
width: 48,
|
||||
height: 48,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
width: width + 24,
|
||||
decoration: BoxDecoration(color: FluentTheme.of(context).cardColor),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 12, right: 12, top: 8, bottom: 8),
|
||||
child: (homeState.countdownFestivalListData == null)
|
||||
? SizedBox(
|
||||
width: width,
|
||||
height: 62,
|
||||
child: const Center(child: ProgressRing()),
|
||||
)
|
||||
: SizedBox(
|
||||
width: width,
|
||||
height: 62,
|
||||
child: Swiper(
|
||||
itemCount: getMinNumber([homeState.countdownFestivalListData!.length, 6]),
|
||||
autoplay: true,
|
||||
autoplayDelay: 5000,
|
||||
itemBuilder: (context, index) {
|
||||
final item = homeState.countdownFestivalListData![index];
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
if (item.icon != null && item.icon != "") ...[
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(1000),
|
||||
child: Image.asset(
|
||||
"assets/countdown/${item.icon}",
|
||||
width: 48,
|
||||
height: 48,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
],
|
||||
Column(
|
||||
children: [
|
||||
Text(
|
||||
item.name ?? "",
|
||||
style: const TextStyle(fontSize: 15),
|
||||
),
|
||||
const SizedBox(height: 3),
|
||||
CountdownTimeText(
|
||||
targetTime: DateTime.fromMillisecondsSinceEpoch(item.time ?? 0),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Icon(
|
||||
FluentIcons.chevron_right,
|
||||
size: 14,
|
||||
color: Colors.white.withValues(alpha: .6),
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
Column(
|
||||
children: [
|
||||
Text(item.name ?? "", style: const TextStyle(fontSize: 15)),
|
||||
const SizedBox(height: 3),
|
||||
CountdownTimeText(targetTime: DateTime.fromMillisecondsSinceEpoch(item.time ?? 0)),
|
||||
],
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Icon(FluentIcons.chevron_right, size: 14, color: Colors.white.withValues(alpha: .6)),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -736,13 +697,14 @@ class HomeUI extends HookConsumerWidget {
|
||||
return;
|
||||
case "doc":
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return HomeMdContentDialogUI(
|
||||
title: homeState.appPlacardData?.title ?? S.current.home_announcement_details,
|
||||
url: homeState.appPlacardData?.link,
|
||||
);
|
||||
});
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return HomeMdContentDialogUI(
|
||||
title: homeState.appPlacardData?.title ?? S.current.home_announcement_details,
|
||||
url: homeState.appPlacardData?.link,
|
||||
);
|
||||
},
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -804,15 +766,22 @@ class HomeUI extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
void _checkAndGoInputMethod(
|
||||
BuildContext context, HomeUIModelState homeState, HomeUIModel model, WidgetRef ref) async {
|
||||
BuildContext context,
|
||||
HomeUIModelState homeState,
|
||||
HomeUIModel model,
|
||||
WidgetRef ref,
|
||||
) async {
|
||||
final localizationState = ref.read(localizationUIModelProvider);
|
||||
if (localizationState.communityInputMethodLanguageData == null) {
|
||||
showToast(context, S.current.input_method_feature_maintenance);
|
||||
return;
|
||||
}
|
||||
if (localizationState.installedCommunityInputMethodSupportVersion == null) {
|
||||
final userOK = await showConfirmDialogs(context, S.current.input_method_community_input_method_not_installed,
|
||||
Text(S.current.input_method_install_community_input_method_prompt));
|
||||
final userOK = await showConfirmDialogs(
|
||||
context,
|
||||
S.current.input_method_community_input_method_not_installed,
|
||||
Text(S.current.input_method_install_community_input_method_prompt),
|
||||
);
|
||||
if (userOK) {
|
||||
if (!context.mounted) return;
|
||||
() async {
|
||||
@ -837,10 +806,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
Future<void> _goInputMethod(BuildContext context, HomeUIModel model) async {
|
||||
await showDialog(
|
||||
context: context,
|
||||
builder: (context) => const InputMethodDialogUI(),
|
||||
);
|
||||
await showDialog(context: context, builder: (context) => const InputMethodDialogUI());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2,7 +2,6 @@ import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:dart_rss/domain/rss_item.dart';
|
||||
import 'package:desktop_webview_window/desktop_webview_window.dart';
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
@ -10,7 +9,7 @@ import 'package:hive_ce/hive.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:starcitizen_doctor/api/analytics.dart';
|
||||
import 'package:starcitizen_doctor/api/api.dart';
|
||||
import 'package:starcitizen_doctor/api/rss.dart';
|
||||
import 'package:starcitizen_doctor/api/news_api.dart';
|
||||
import 'package:starcitizen_doctor/common/conf/conf.dart';
|
||||
import 'package:starcitizen_doctor/common/conf/url_conf.dart';
|
||||
import 'package:starcitizen_doctor/common/helper/log_helper.dart';
|
||||
@ -23,12 +22,12 @@ import 'package:starcitizen_doctor/common/utils/log.dart';
|
||||
import 'package:starcitizen_doctor/common/utils/provider.dart';
|
||||
import 'package:starcitizen_doctor/data/app_placard_data.dart';
|
||||
import 'package:starcitizen_doctor/data/app_web_localization_versions_data.dart';
|
||||
import 'package:starcitizen_doctor/data/citizen_news_data.dart';
|
||||
import 'package:starcitizen_doctor/data/countdown_festival_item_data.dart';
|
||||
import 'package:starcitizen_doctor/ui/home/dialogs/home_game_login_dialog_ui.dart';
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
import 'package:html/parser.dart' as html;
|
||||
import 'package:html/dom.dart' as html_dom;
|
||||
|
||||
import '../webview/webview.dart';
|
||||
import 'localization/localization_ui_model.dart';
|
||||
|
||||
@ -46,8 +45,7 @@ abstract class HomeUIModelState with _$HomeUIModelState {
|
||||
@Default([]) List<String> scInstallPaths,
|
||||
AppWebLocalizationVersionsData? webLocalizationVersionsData,
|
||||
@Default("") String lastScreenInfo,
|
||||
List<RssItem>? rssVideoItems,
|
||||
List<RssItem>? rssTextItems,
|
||||
CitizenNewsData? citizenNewsData,
|
||||
MapEntry<String, bool>? localizationUpdateInfo,
|
||||
List? scServerStatus,
|
||||
List<CountdownFestivalItemData>? countdownFestivalListData,
|
||||
@ -115,8 +113,9 @@ class HomeUIModel extends _$HomeUIModel {
|
||||
}
|
||||
}
|
||||
|
||||
String getRssImage(RssItem item) {
|
||||
final h = html.parse(item.description ?? "");
|
||||
String getRssImage(String? htmlString) {
|
||||
if (htmlString == null) return "";
|
||||
final h = html.parse(htmlString);
|
||||
if (h.body == null) return "";
|
||||
for (var node in h.body!.nodes) {
|
||||
if (node is html_dom.Element) {
|
||||
@ -135,14 +134,15 @@ class HomeUIModel extends _$HomeUIModel {
|
||||
return title;
|
||||
}
|
||||
|
||||
// ignore: avoid_build_context_in_providers
|
||||
Future<void> goWebView(BuildContext context,
|
||||
String title,
|
||||
String url, {
|
||||
bool useLocalization = false,
|
||||
bool loginMode = false,
|
||||
RsiLoginCallback? rsiLoginCallback,
|
||||
}) async {
|
||||
Future<void> goWebView(
|
||||
// ignore: avoid_build_context_in_providers
|
||||
BuildContext context,
|
||||
String title,
|
||||
String url, {
|
||||
bool useLocalization = false,
|
||||
bool loginMode = false,
|
||||
RsiLoginCallback? rsiLoginCallback,
|
||||
}) async {
|
||||
if (useLocalization) {
|
||||
const tipVersion = 2;
|
||||
final box = await Hive.openBox("app_conf");
|
||||
@ -153,10 +153,7 @@ class HomeUIModel extends _$HomeUIModel {
|
||||
context,
|
||||
S.current.home_action_title_star_citizen_website_localization,
|
||||
Text(S.current.home_action_info_web_localization_plugin_disclaimer, style: const TextStyle(fontSize: 16)),
|
||||
constraints: BoxConstraints(maxWidth: MediaQuery
|
||||
.of(context)
|
||||
.size
|
||||
.width * .6),
|
||||
constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * .6),
|
||||
);
|
||||
if (!ok) {
|
||||
if (loginMode) {
|
||||
@ -227,7 +224,8 @@ class HomeUIModel extends _$HomeUIModel {
|
||||
final box = await Hive.openBox("app_conf");
|
||||
final version = box.get("close_placard", defaultValue: "");
|
||||
if (r.enable == true) {
|
||||
if (r.alwaysShow != true && version == r.version) {} else {
|
||||
if (r.alwaysShow != true && version == r.version) {
|
||||
} else {
|
||||
state = state.copyWith(appPlacardData: r);
|
||||
}
|
||||
}
|
||||
@ -241,7 +239,7 @@ class HomeUIModel extends _$HomeUIModel {
|
||||
countdownFestivalListData: _fixFestivalCountdownListDateTime(countdownFestivalListData),
|
||||
);
|
||||
_updateSCServerStatus();
|
||||
_loadRRS();
|
||||
_loadNews();
|
||||
} catch (e) {
|
||||
dPrint(e);
|
||||
}
|
||||
@ -255,10 +253,10 @@ class HomeUIModel extends _$HomeUIModel {
|
||||
|
||||
return list.map((item) {
|
||||
if (item.time == null) return item;
|
||||
final itemDateTime = DateTime.fromMillisecondsSinceEpoch(item.time! * 1000);
|
||||
final itemDateTime = DateTime.fromMillisecondsSinceEpoch(item.time!);
|
||||
final itemDatePlusSeven = itemDateTime.add(const Duration(days: 7));
|
||||
if (itemDatePlusSeven.isBefore(now)) {
|
||||
final nextYearDate = DateTime(
|
||||
final nextDate = DateTime(
|
||||
now.year + 1,
|
||||
itemDateTime.month,
|
||||
itemDateTime.day,
|
||||
@ -266,7 +264,7 @@ class HomeUIModel extends _$HomeUIModel {
|
||||
itemDateTime.minute,
|
||||
itemDateTime.second,
|
||||
);
|
||||
final newTimestamp = (nextYearDate.millisecondsSinceEpoch / 1000).round();
|
||||
final newTimestamp = (nextDate.millisecondsSinceEpoch).round();
|
||||
return CountdownFestivalItemData(name: item.name, time: newTimestamp, icon: item.icon);
|
||||
}
|
||||
|
||||
@ -284,23 +282,9 @@ class HomeUIModel extends _$HomeUIModel {
|
||||
}
|
||||
}
|
||||
|
||||
Future _loadRRS() async {
|
||||
try {
|
||||
final rssVideoItems = await RSSApi.getRssVideo();
|
||||
state = state.copyWith(rssVideoItems: rssVideoItems);
|
||||
final rssTextItems = await RSSApi.getRssText();
|
||||
state = state.copyWith(rssTextItems: rssTextItems);
|
||||
dPrint("RSS update Success !");
|
||||
} catch (e) {
|
||||
dPrint("_loadRRS Error:$e");
|
||||
// 避免持续显示 loading
|
||||
if (state.rssTextItems == null) {
|
||||
state = state.copyWith(rssTextItems: []);
|
||||
}
|
||||
if (state.rssVideoItems == null) {
|
||||
state = state.copyWith(rssVideoItems: []);
|
||||
}
|
||||
}
|
||||
Future _loadNews() async {
|
||||
final news = await NewsApi.getLatest();
|
||||
state = state.copyWith(citizenNewsData: news ?? CitizenNewsData());
|
||||
}
|
||||
|
||||
Future<void> checkLocalizationUpdate({bool skipReload = false}) async {
|
||||
@ -362,12 +346,14 @@ class HomeUIModel extends _$HomeUIModel {
|
||||
ref.read(localizationUIModelProvider.notifier).onChangeGameInstallPath(value);
|
||||
}
|
||||
|
||||
Future<void> doLaunchGame(// ignore: avoid_build_context_in_providers
|
||||
BuildContext context,
|
||||
String launchExe,
|
||||
List<String> args,
|
||||
String installPath,
|
||||
String? processorAffinity,) async {
|
||||
Future<void> doLaunchGame(
|
||||
// ignore: avoid_build_context_in_providers
|
||||
BuildContext context,
|
||||
String launchExe,
|
||||
List<String> args,
|
||||
String installPath,
|
||||
String? processorAffinity,
|
||||
) async {
|
||||
var runningMap = Map<String, bool>.from(state.isGameRunning);
|
||||
runningMap[installPath] = true;
|
||||
state = state.copyWith(isGameRunning: runningMap);
|
||||
|
||||
@ -14,7 +14,7 @@ T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$HomeUIModelState {
|
||||
|
||||
AppPlacardData? get appPlacardData; bool get isFixing; String get isFixingString; String? get scInstalledPath; List<String> get scInstallPaths; AppWebLocalizationVersionsData? get webLocalizationVersionsData; String get lastScreenInfo; List<RssItem>? get rssVideoItems; List<RssItem>? get rssTextItems; MapEntry<String, bool>? get localizationUpdateInfo; List? get scServerStatus; List<CountdownFestivalItemData>? get countdownFestivalListData; Map<String, bool> get isGameRunning;
|
||||
AppPlacardData? get appPlacardData; bool get isFixing; String get isFixingString; String? get scInstalledPath; List<String> get scInstallPaths; AppWebLocalizationVersionsData? get webLocalizationVersionsData; String get lastScreenInfo; CitizenNewsData? get citizenNewsData; MapEntry<String, bool>? get localizationUpdateInfo; List? get scServerStatus; List<CountdownFestivalItemData>? get countdownFestivalListData; Map<String, bool> get isGameRunning;
|
||||
/// Create a copy of HomeUIModelState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@ -25,16 +25,16 @@ $HomeUIModelStateCopyWith<HomeUIModelState> get copyWith => _$HomeUIModelStateCo
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is HomeUIModelState&&(identical(other.appPlacardData, appPlacardData) || other.appPlacardData == appPlacardData)&&(identical(other.isFixing, isFixing) || other.isFixing == isFixing)&&(identical(other.isFixingString, isFixingString) || other.isFixingString == isFixingString)&&(identical(other.scInstalledPath, scInstalledPath) || other.scInstalledPath == scInstalledPath)&&const DeepCollectionEquality().equals(other.scInstallPaths, scInstallPaths)&&(identical(other.webLocalizationVersionsData, webLocalizationVersionsData) || other.webLocalizationVersionsData == webLocalizationVersionsData)&&(identical(other.lastScreenInfo, lastScreenInfo) || other.lastScreenInfo == lastScreenInfo)&&const DeepCollectionEquality().equals(other.rssVideoItems, rssVideoItems)&&const DeepCollectionEquality().equals(other.rssTextItems, rssTextItems)&&(identical(other.localizationUpdateInfo, localizationUpdateInfo) || other.localizationUpdateInfo == localizationUpdateInfo)&&const DeepCollectionEquality().equals(other.scServerStatus, scServerStatus)&&const DeepCollectionEquality().equals(other.countdownFestivalListData, countdownFestivalListData)&&const DeepCollectionEquality().equals(other.isGameRunning, isGameRunning));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is HomeUIModelState&&(identical(other.appPlacardData, appPlacardData) || other.appPlacardData == appPlacardData)&&(identical(other.isFixing, isFixing) || other.isFixing == isFixing)&&(identical(other.isFixingString, isFixingString) || other.isFixingString == isFixingString)&&(identical(other.scInstalledPath, scInstalledPath) || other.scInstalledPath == scInstalledPath)&&const DeepCollectionEquality().equals(other.scInstallPaths, scInstallPaths)&&(identical(other.webLocalizationVersionsData, webLocalizationVersionsData) || other.webLocalizationVersionsData == webLocalizationVersionsData)&&(identical(other.lastScreenInfo, lastScreenInfo) || other.lastScreenInfo == lastScreenInfo)&&(identical(other.citizenNewsData, citizenNewsData) || other.citizenNewsData == citizenNewsData)&&(identical(other.localizationUpdateInfo, localizationUpdateInfo) || other.localizationUpdateInfo == localizationUpdateInfo)&&const DeepCollectionEquality().equals(other.scServerStatus, scServerStatus)&&const DeepCollectionEquality().equals(other.countdownFestivalListData, countdownFestivalListData)&&const DeepCollectionEquality().equals(other.isGameRunning, isGameRunning));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,appPlacardData,isFixing,isFixingString,scInstalledPath,const DeepCollectionEquality().hash(scInstallPaths),webLocalizationVersionsData,lastScreenInfo,const DeepCollectionEquality().hash(rssVideoItems),const DeepCollectionEquality().hash(rssTextItems),localizationUpdateInfo,const DeepCollectionEquality().hash(scServerStatus),const DeepCollectionEquality().hash(countdownFestivalListData),const DeepCollectionEquality().hash(isGameRunning));
|
||||
int get hashCode => Object.hash(runtimeType,appPlacardData,isFixing,isFixingString,scInstalledPath,const DeepCollectionEquality().hash(scInstallPaths),webLocalizationVersionsData,lastScreenInfo,citizenNewsData,localizationUpdateInfo,const DeepCollectionEquality().hash(scServerStatus),const DeepCollectionEquality().hash(countdownFestivalListData),const DeepCollectionEquality().hash(isGameRunning));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'HomeUIModelState(appPlacardData: $appPlacardData, isFixing: $isFixing, isFixingString: $isFixingString, scInstalledPath: $scInstalledPath, scInstallPaths: $scInstallPaths, webLocalizationVersionsData: $webLocalizationVersionsData, lastScreenInfo: $lastScreenInfo, rssVideoItems: $rssVideoItems, rssTextItems: $rssTextItems, localizationUpdateInfo: $localizationUpdateInfo, scServerStatus: $scServerStatus, countdownFestivalListData: $countdownFestivalListData, isGameRunning: $isGameRunning)';
|
||||
return 'HomeUIModelState(appPlacardData: $appPlacardData, isFixing: $isFixing, isFixingString: $isFixingString, scInstalledPath: $scInstalledPath, scInstallPaths: $scInstallPaths, webLocalizationVersionsData: $webLocalizationVersionsData, lastScreenInfo: $lastScreenInfo, citizenNewsData: $citizenNewsData, localizationUpdateInfo: $localizationUpdateInfo, scServerStatus: $scServerStatus, countdownFestivalListData: $countdownFestivalListData, isGameRunning: $isGameRunning)';
|
||||
}
|
||||
|
||||
|
||||
@ -45,11 +45,11 @@ abstract mixin class $HomeUIModelStateCopyWith<$Res> {
|
||||
factory $HomeUIModelStateCopyWith(HomeUIModelState value, $Res Function(HomeUIModelState) _then) = _$HomeUIModelStateCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
AppPlacardData? appPlacardData, bool isFixing, String isFixingString, String? scInstalledPath, List<String> scInstallPaths, AppWebLocalizationVersionsData? webLocalizationVersionsData, String lastScreenInfo, List<RssItem>? rssVideoItems, List<RssItem>? rssTextItems, MapEntry<String, bool>? localizationUpdateInfo, List? scServerStatus, List<CountdownFestivalItemData>? countdownFestivalListData, Map<String, bool> isGameRunning
|
||||
AppPlacardData? appPlacardData, bool isFixing, String isFixingString, String? scInstalledPath, List<String> scInstallPaths, AppWebLocalizationVersionsData? webLocalizationVersionsData, String lastScreenInfo, CitizenNewsData? citizenNewsData, MapEntry<String, bool>? localizationUpdateInfo, List? scServerStatus, List<CountdownFestivalItemData>? countdownFestivalListData, Map<String, bool> isGameRunning
|
||||
});
|
||||
|
||||
|
||||
|
||||
$CitizenNewsDataCopyWith<$Res>? get citizenNewsData;
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
@ -62,7 +62,7 @@ class _$HomeUIModelStateCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of HomeUIModelState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? appPlacardData = freezed,Object? isFixing = null,Object? isFixingString = null,Object? scInstalledPath = freezed,Object? scInstallPaths = null,Object? webLocalizationVersionsData = freezed,Object? lastScreenInfo = null,Object? rssVideoItems = freezed,Object? rssTextItems = freezed,Object? localizationUpdateInfo = freezed,Object? scServerStatus = freezed,Object? countdownFestivalListData = freezed,Object? isGameRunning = null,}) {
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? appPlacardData = freezed,Object? isFixing = null,Object? isFixingString = null,Object? scInstalledPath = freezed,Object? scInstallPaths = null,Object? webLocalizationVersionsData = freezed,Object? lastScreenInfo = null,Object? citizenNewsData = freezed,Object? localizationUpdateInfo = freezed,Object? scServerStatus = freezed,Object? countdownFestivalListData = freezed,Object? isGameRunning = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
appPlacardData: freezed == appPlacardData ? _self.appPlacardData : appPlacardData // ignore: cast_nullable_to_non_nullable
|
||||
as AppPlacardData?,isFixing: null == isFixing ? _self.isFixing : isFixing // ignore: cast_nullable_to_non_nullable
|
||||
@ -71,16 +71,27 @@ as String,scInstalledPath: freezed == scInstalledPath ? _self.scInstalledPath :
|
||||
as String?,scInstallPaths: null == scInstallPaths ? _self.scInstallPaths : scInstallPaths // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>,webLocalizationVersionsData: freezed == webLocalizationVersionsData ? _self.webLocalizationVersionsData : webLocalizationVersionsData // ignore: cast_nullable_to_non_nullable
|
||||
as AppWebLocalizationVersionsData?,lastScreenInfo: null == lastScreenInfo ? _self.lastScreenInfo : lastScreenInfo // ignore: cast_nullable_to_non_nullable
|
||||
as String,rssVideoItems: freezed == rssVideoItems ? _self.rssVideoItems : rssVideoItems // ignore: cast_nullable_to_non_nullable
|
||||
as List<RssItem>?,rssTextItems: freezed == rssTextItems ? _self.rssTextItems : rssTextItems // ignore: cast_nullable_to_non_nullable
|
||||
as List<RssItem>?,localizationUpdateInfo: freezed == localizationUpdateInfo ? _self.localizationUpdateInfo : localizationUpdateInfo // ignore: cast_nullable_to_non_nullable
|
||||
as String,citizenNewsData: freezed == citizenNewsData ? _self.citizenNewsData : citizenNewsData // ignore: cast_nullable_to_non_nullable
|
||||
as CitizenNewsData?,localizationUpdateInfo: freezed == localizationUpdateInfo ? _self.localizationUpdateInfo : localizationUpdateInfo // ignore: cast_nullable_to_non_nullable
|
||||
as MapEntry<String, bool>?,scServerStatus: freezed == scServerStatus ? _self.scServerStatus : scServerStatus // ignore: cast_nullable_to_non_nullable
|
||||
as List?,countdownFestivalListData: freezed == countdownFestivalListData ? _self.countdownFestivalListData : countdownFestivalListData // ignore: cast_nullable_to_non_nullable
|
||||
as List<CountdownFestivalItemData>?,isGameRunning: null == isGameRunning ? _self.isGameRunning : isGameRunning // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, bool>,
|
||||
));
|
||||
}
|
||||
/// Create a copy of HomeUIModelState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$CitizenNewsDataCopyWith<$Res>? get citizenNewsData {
|
||||
if (_self.citizenNewsData == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $CitizenNewsDataCopyWith<$Res>(_self.citizenNewsData!, (value) {
|
||||
return _then(_self.copyWith(citizenNewsData: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -162,10 +173,10 @@ return $default(_that);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( AppPlacardData? appPlacardData, bool isFixing, String isFixingString, String? scInstalledPath, List<String> scInstallPaths, AppWebLocalizationVersionsData? webLocalizationVersionsData, String lastScreenInfo, List<RssItem>? rssVideoItems, List<RssItem>? rssTextItems, MapEntry<String, bool>? localizationUpdateInfo, List? scServerStatus, List<CountdownFestivalItemData>? countdownFestivalListData, Map<String, bool> isGameRunning)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( AppPlacardData? appPlacardData, bool isFixing, String isFixingString, String? scInstalledPath, List<String> scInstallPaths, AppWebLocalizationVersionsData? webLocalizationVersionsData, String lastScreenInfo, CitizenNewsData? citizenNewsData, MapEntry<String, bool>? localizationUpdateInfo, List? scServerStatus, List<CountdownFestivalItemData>? countdownFestivalListData, Map<String, bool> isGameRunning)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _HomeUIModelState() when $default != null:
|
||||
return $default(_that.appPlacardData,_that.isFixing,_that.isFixingString,_that.scInstalledPath,_that.scInstallPaths,_that.webLocalizationVersionsData,_that.lastScreenInfo,_that.rssVideoItems,_that.rssTextItems,_that.localizationUpdateInfo,_that.scServerStatus,_that.countdownFestivalListData,_that.isGameRunning);case _:
|
||||
return $default(_that.appPlacardData,_that.isFixing,_that.isFixingString,_that.scInstalledPath,_that.scInstallPaths,_that.webLocalizationVersionsData,_that.lastScreenInfo,_that.citizenNewsData,_that.localizationUpdateInfo,_that.scServerStatus,_that.countdownFestivalListData,_that.isGameRunning);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
@ -183,10 +194,10 @@ return $default(_that.appPlacardData,_that.isFixing,_that.isFixingString,_that.s
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( AppPlacardData? appPlacardData, bool isFixing, String isFixingString, String? scInstalledPath, List<String> scInstallPaths, AppWebLocalizationVersionsData? webLocalizationVersionsData, String lastScreenInfo, List<RssItem>? rssVideoItems, List<RssItem>? rssTextItems, MapEntry<String, bool>? localizationUpdateInfo, List? scServerStatus, List<CountdownFestivalItemData>? countdownFestivalListData, Map<String, bool> isGameRunning) $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( AppPlacardData? appPlacardData, bool isFixing, String isFixingString, String? scInstalledPath, List<String> scInstallPaths, AppWebLocalizationVersionsData? webLocalizationVersionsData, String lastScreenInfo, CitizenNewsData? citizenNewsData, MapEntry<String, bool>? localizationUpdateInfo, List? scServerStatus, List<CountdownFestivalItemData>? countdownFestivalListData, Map<String, bool> isGameRunning) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _HomeUIModelState():
|
||||
return $default(_that.appPlacardData,_that.isFixing,_that.isFixingString,_that.scInstalledPath,_that.scInstallPaths,_that.webLocalizationVersionsData,_that.lastScreenInfo,_that.rssVideoItems,_that.rssTextItems,_that.localizationUpdateInfo,_that.scServerStatus,_that.countdownFestivalListData,_that.isGameRunning);case _:
|
||||
return $default(_that.appPlacardData,_that.isFixing,_that.isFixingString,_that.scInstalledPath,_that.scInstallPaths,_that.webLocalizationVersionsData,_that.lastScreenInfo,_that.citizenNewsData,_that.localizationUpdateInfo,_that.scServerStatus,_that.countdownFestivalListData,_that.isGameRunning);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
@ -203,10 +214,10 @@ return $default(_that.appPlacardData,_that.isFixing,_that.isFixingString,_that.s
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( AppPlacardData? appPlacardData, bool isFixing, String isFixingString, String? scInstalledPath, List<String> scInstallPaths, AppWebLocalizationVersionsData? webLocalizationVersionsData, String lastScreenInfo, List<RssItem>? rssVideoItems, List<RssItem>? rssTextItems, MapEntry<String, bool>? localizationUpdateInfo, List? scServerStatus, List<CountdownFestivalItemData>? countdownFestivalListData, Map<String, bool> isGameRunning)? $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( AppPlacardData? appPlacardData, bool isFixing, String isFixingString, String? scInstalledPath, List<String> scInstallPaths, AppWebLocalizationVersionsData? webLocalizationVersionsData, String lastScreenInfo, CitizenNewsData? citizenNewsData, MapEntry<String, bool>? localizationUpdateInfo, List? scServerStatus, List<CountdownFestivalItemData>? countdownFestivalListData, Map<String, bool> isGameRunning)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _HomeUIModelState() when $default != null:
|
||||
return $default(_that.appPlacardData,_that.isFixing,_that.isFixingString,_that.scInstalledPath,_that.scInstallPaths,_that.webLocalizationVersionsData,_that.lastScreenInfo,_that.rssVideoItems,_that.rssTextItems,_that.localizationUpdateInfo,_that.scServerStatus,_that.countdownFestivalListData,_that.isGameRunning);case _:
|
||||
return $default(_that.appPlacardData,_that.isFixing,_that.isFixingString,_that.scInstalledPath,_that.scInstallPaths,_that.webLocalizationVersionsData,_that.lastScreenInfo,_that.citizenNewsData,_that.localizationUpdateInfo,_that.scServerStatus,_that.countdownFestivalListData,_that.isGameRunning);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
@ -218,7 +229,7 @@ return $default(_that.appPlacardData,_that.isFixing,_that.isFixingString,_that.s
|
||||
|
||||
|
||||
class _HomeUIModelState implements HomeUIModelState {
|
||||
_HomeUIModelState({this.appPlacardData, this.isFixing = false, this.isFixingString = "", this.scInstalledPath, final List<String> scInstallPaths = const [], this.webLocalizationVersionsData, this.lastScreenInfo = "", final List<RssItem>? rssVideoItems, final List<RssItem>? rssTextItems, this.localizationUpdateInfo, final List? scServerStatus, final List<CountdownFestivalItemData>? countdownFestivalListData, final Map<String, bool> isGameRunning = const {}}): _scInstallPaths = scInstallPaths,_rssVideoItems = rssVideoItems,_rssTextItems = rssTextItems,_scServerStatus = scServerStatus,_countdownFestivalListData = countdownFestivalListData,_isGameRunning = isGameRunning;
|
||||
_HomeUIModelState({this.appPlacardData, this.isFixing = false, this.isFixingString = "", this.scInstalledPath, final List<String> scInstallPaths = const [], this.webLocalizationVersionsData, this.lastScreenInfo = "", this.citizenNewsData, this.localizationUpdateInfo, final List? scServerStatus, final List<CountdownFestivalItemData>? countdownFestivalListData, final Map<String, bool> isGameRunning = const {}}): _scInstallPaths = scInstallPaths,_scServerStatus = scServerStatus,_countdownFestivalListData = countdownFestivalListData,_isGameRunning = isGameRunning;
|
||||
|
||||
|
||||
@override final AppPlacardData? appPlacardData;
|
||||
@ -234,24 +245,7 @@ class _HomeUIModelState implements HomeUIModelState {
|
||||
|
||||
@override final AppWebLocalizationVersionsData? webLocalizationVersionsData;
|
||||
@override@JsonKey() final String lastScreenInfo;
|
||||
final List<RssItem>? _rssVideoItems;
|
||||
@override List<RssItem>? get rssVideoItems {
|
||||
final value = _rssVideoItems;
|
||||
if (value == null) return null;
|
||||
if (_rssVideoItems is EqualUnmodifiableListView) return _rssVideoItems;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(value);
|
||||
}
|
||||
|
||||
final List<RssItem>? _rssTextItems;
|
||||
@override List<RssItem>? get rssTextItems {
|
||||
final value = _rssTextItems;
|
||||
if (value == null) return null;
|
||||
if (_rssTextItems is EqualUnmodifiableListView) return _rssTextItems;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(value);
|
||||
}
|
||||
|
||||
@override final CitizenNewsData? citizenNewsData;
|
||||
@override final MapEntry<String, bool>? localizationUpdateInfo;
|
||||
final List? _scServerStatus;
|
||||
@override List? get scServerStatus {
|
||||
@ -289,16 +283,16 @@ _$HomeUIModelStateCopyWith<_HomeUIModelState> get copyWith => __$HomeUIModelStat
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _HomeUIModelState&&(identical(other.appPlacardData, appPlacardData) || other.appPlacardData == appPlacardData)&&(identical(other.isFixing, isFixing) || other.isFixing == isFixing)&&(identical(other.isFixingString, isFixingString) || other.isFixingString == isFixingString)&&(identical(other.scInstalledPath, scInstalledPath) || other.scInstalledPath == scInstalledPath)&&const DeepCollectionEquality().equals(other._scInstallPaths, _scInstallPaths)&&(identical(other.webLocalizationVersionsData, webLocalizationVersionsData) || other.webLocalizationVersionsData == webLocalizationVersionsData)&&(identical(other.lastScreenInfo, lastScreenInfo) || other.lastScreenInfo == lastScreenInfo)&&const DeepCollectionEquality().equals(other._rssVideoItems, _rssVideoItems)&&const DeepCollectionEquality().equals(other._rssTextItems, _rssTextItems)&&(identical(other.localizationUpdateInfo, localizationUpdateInfo) || other.localizationUpdateInfo == localizationUpdateInfo)&&const DeepCollectionEquality().equals(other._scServerStatus, _scServerStatus)&&const DeepCollectionEquality().equals(other._countdownFestivalListData, _countdownFestivalListData)&&const DeepCollectionEquality().equals(other._isGameRunning, _isGameRunning));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _HomeUIModelState&&(identical(other.appPlacardData, appPlacardData) || other.appPlacardData == appPlacardData)&&(identical(other.isFixing, isFixing) || other.isFixing == isFixing)&&(identical(other.isFixingString, isFixingString) || other.isFixingString == isFixingString)&&(identical(other.scInstalledPath, scInstalledPath) || other.scInstalledPath == scInstalledPath)&&const DeepCollectionEquality().equals(other._scInstallPaths, _scInstallPaths)&&(identical(other.webLocalizationVersionsData, webLocalizationVersionsData) || other.webLocalizationVersionsData == webLocalizationVersionsData)&&(identical(other.lastScreenInfo, lastScreenInfo) || other.lastScreenInfo == lastScreenInfo)&&(identical(other.citizenNewsData, citizenNewsData) || other.citizenNewsData == citizenNewsData)&&(identical(other.localizationUpdateInfo, localizationUpdateInfo) || other.localizationUpdateInfo == localizationUpdateInfo)&&const DeepCollectionEquality().equals(other._scServerStatus, _scServerStatus)&&const DeepCollectionEquality().equals(other._countdownFestivalListData, _countdownFestivalListData)&&const DeepCollectionEquality().equals(other._isGameRunning, _isGameRunning));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,appPlacardData,isFixing,isFixingString,scInstalledPath,const DeepCollectionEquality().hash(_scInstallPaths),webLocalizationVersionsData,lastScreenInfo,const DeepCollectionEquality().hash(_rssVideoItems),const DeepCollectionEquality().hash(_rssTextItems),localizationUpdateInfo,const DeepCollectionEquality().hash(_scServerStatus),const DeepCollectionEquality().hash(_countdownFestivalListData),const DeepCollectionEquality().hash(_isGameRunning));
|
||||
int get hashCode => Object.hash(runtimeType,appPlacardData,isFixing,isFixingString,scInstalledPath,const DeepCollectionEquality().hash(_scInstallPaths),webLocalizationVersionsData,lastScreenInfo,citizenNewsData,localizationUpdateInfo,const DeepCollectionEquality().hash(_scServerStatus),const DeepCollectionEquality().hash(_countdownFestivalListData),const DeepCollectionEquality().hash(_isGameRunning));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'HomeUIModelState(appPlacardData: $appPlacardData, isFixing: $isFixing, isFixingString: $isFixingString, scInstalledPath: $scInstalledPath, scInstallPaths: $scInstallPaths, webLocalizationVersionsData: $webLocalizationVersionsData, lastScreenInfo: $lastScreenInfo, rssVideoItems: $rssVideoItems, rssTextItems: $rssTextItems, localizationUpdateInfo: $localizationUpdateInfo, scServerStatus: $scServerStatus, countdownFestivalListData: $countdownFestivalListData, isGameRunning: $isGameRunning)';
|
||||
return 'HomeUIModelState(appPlacardData: $appPlacardData, isFixing: $isFixing, isFixingString: $isFixingString, scInstalledPath: $scInstalledPath, scInstallPaths: $scInstallPaths, webLocalizationVersionsData: $webLocalizationVersionsData, lastScreenInfo: $lastScreenInfo, citizenNewsData: $citizenNewsData, localizationUpdateInfo: $localizationUpdateInfo, scServerStatus: $scServerStatus, countdownFestivalListData: $countdownFestivalListData, isGameRunning: $isGameRunning)';
|
||||
}
|
||||
|
||||
|
||||
@ -309,11 +303,11 @@ abstract mixin class _$HomeUIModelStateCopyWith<$Res> implements $HomeUIModelSta
|
||||
factory _$HomeUIModelStateCopyWith(_HomeUIModelState value, $Res Function(_HomeUIModelState) _then) = __$HomeUIModelStateCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
AppPlacardData? appPlacardData, bool isFixing, String isFixingString, String? scInstalledPath, List<String> scInstallPaths, AppWebLocalizationVersionsData? webLocalizationVersionsData, String lastScreenInfo, List<RssItem>? rssVideoItems, List<RssItem>? rssTextItems, MapEntry<String, bool>? localizationUpdateInfo, List? scServerStatus, List<CountdownFestivalItemData>? countdownFestivalListData, Map<String, bool> isGameRunning
|
||||
AppPlacardData? appPlacardData, bool isFixing, String isFixingString, String? scInstalledPath, List<String> scInstallPaths, AppWebLocalizationVersionsData? webLocalizationVersionsData, String lastScreenInfo, CitizenNewsData? citizenNewsData, MapEntry<String, bool>? localizationUpdateInfo, List? scServerStatus, List<CountdownFestivalItemData>? countdownFestivalListData, Map<String, bool> isGameRunning
|
||||
});
|
||||
|
||||
|
||||
|
||||
@override $CitizenNewsDataCopyWith<$Res>? get citizenNewsData;
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
@ -326,7 +320,7 @@ class __$HomeUIModelStateCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of HomeUIModelState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? appPlacardData = freezed,Object? isFixing = null,Object? isFixingString = null,Object? scInstalledPath = freezed,Object? scInstallPaths = null,Object? webLocalizationVersionsData = freezed,Object? lastScreenInfo = null,Object? rssVideoItems = freezed,Object? rssTextItems = freezed,Object? localizationUpdateInfo = freezed,Object? scServerStatus = freezed,Object? countdownFestivalListData = freezed,Object? isGameRunning = null,}) {
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? appPlacardData = freezed,Object? isFixing = null,Object? isFixingString = null,Object? scInstalledPath = freezed,Object? scInstallPaths = null,Object? webLocalizationVersionsData = freezed,Object? lastScreenInfo = null,Object? citizenNewsData = freezed,Object? localizationUpdateInfo = freezed,Object? scServerStatus = freezed,Object? countdownFestivalListData = freezed,Object? isGameRunning = null,}) {
|
||||
return _then(_HomeUIModelState(
|
||||
appPlacardData: freezed == appPlacardData ? _self.appPlacardData : appPlacardData // ignore: cast_nullable_to_non_nullable
|
||||
as AppPlacardData?,isFixing: null == isFixing ? _self.isFixing : isFixing // ignore: cast_nullable_to_non_nullable
|
||||
@ -335,9 +329,8 @@ as String,scInstalledPath: freezed == scInstalledPath ? _self.scInstalledPath :
|
||||
as String?,scInstallPaths: null == scInstallPaths ? _self._scInstallPaths : scInstallPaths // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>,webLocalizationVersionsData: freezed == webLocalizationVersionsData ? _self.webLocalizationVersionsData : webLocalizationVersionsData // ignore: cast_nullable_to_non_nullable
|
||||
as AppWebLocalizationVersionsData?,lastScreenInfo: null == lastScreenInfo ? _self.lastScreenInfo : lastScreenInfo // ignore: cast_nullable_to_non_nullable
|
||||
as String,rssVideoItems: freezed == rssVideoItems ? _self._rssVideoItems : rssVideoItems // ignore: cast_nullable_to_non_nullable
|
||||
as List<RssItem>?,rssTextItems: freezed == rssTextItems ? _self._rssTextItems : rssTextItems // ignore: cast_nullable_to_non_nullable
|
||||
as List<RssItem>?,localizationUpdateInfo: freezed == localizationUpdateInfo ? _self.localizationUpdateInfo : localizationUpdateInfo // ignore: cast_nullable_to_non_nullable
|
||||
as String,citizenNewsData: freezed == citizenNewsData ? _self.citizenNewsData : citizenNewsData // ignore: cast_nullable_to_non_nullable
|
||||
as CitizenNewsData?,localizationUpdateInfo: freezed == localizationUpdateInfo ? _self.localizationUpdateInfo : localizationUpdateInfo // ignore: cast_nullable_to_non_nullable
|
||||
as MapEntry<String, bool>?,scServerStatus: freezed == scServerStatus ? _self._scServerStatus : scServerStatus // ignore: cast_nullable_to_non_nullable
|
||||
as List?,countdownFestivalListData: freezed == countdownFestivalListData ? _self._countdownFestivalListData : countdownFestivalListData // ignore: cast_nullable_to_non_nullable
|
||||
as List<CountdownFestivalItemData>?,isGameRunning: null == isGameRunning ? _self._isGameRunning : isGameRunning // ignore: cast_nullable_to_non_nullable
|
||||
@ -345,7 +338,19 @@ as Map<String, bool>,
|
||||
));
|
||||
}
|
||||
|
||||
/// Create a copy of HomeUIModelState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$CitizenNewsDataCopyWith<$Res>? get citizenNewsData {
|
||||
if (_self.citizenNewsData == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $CitizenNewsDataCopyWith<$Res>(_self.citizenNewsData!, (value) {
|
||||
return _then(_self.copyWith(citizenNewsData: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// dart format on
|
||||
|
||||
@ -41,7 +41,7 @@ final class HomeUIModelProvider
|
||||
}
|
||||
}
|
||||
|
||||
String _$homeUIModelHash() => r'84eb149f999237410a7e0a95b74bd5729c2726d4';
|
||||
String _$homeUIModelHash() => r'9dc8191f358c2d8e21ed931b3755e08ce394558e';
|
||||
|
||||
abstract class _$HomeUIModel extends $Notifier<HomeUIModelState> {
|
||||
HomeUIModelState build();
|
||||
|
||||
@ -41,7 +41,7 @@ final class SettingsUIModelProvider
|
||||
}
|
||||
}
|
||||
|
||||
String _$settingsUIModelHash() => r'd19104d924f018a9230548d0372692fc344adacd';
|
||||
String _$settingsUIModelHash() => r'5c08c56bf5464ef44bee8edb8c18c08d4217f135';
|
||||
|
||||
abstract class _$SettingsUIModel extends $Notifier<SettingsUIState> {
|
||||
SettingsUIState build();
|
||||
|
||||
@ -10,12 +10,13 @@ class FlowNumberText extends HookConsumerWidget {
|
||||
final TextStyle? style;
|
||||
final Curve curve;
|
||||
|
||||
FlowNumberText(
|
||||
{super.key,
|
||||
required this.targetValue,
|
||||
this.duration = const Duration(seconds: 1),
|
||||
this.style,
|
||||
this.curve = Curves.bounceOut});
|
||||
FlowNumberText({
|
||||
super.key,
|
||||
required this.targetValue,
|
||||
this.duration = const Duration(seconds: 1),
|
||||
this.style,
|
||||
this.curve = Curves.bounceOut,
|
||||
});
|
||||
|
||||
final _formatter = NumberFormat.decimalPattern();
|
||||
|
||||
@ -46,9 +47,6 @@ class FlowNumberText extends HookConsumerWidget {
|
||||
return timer.value?.cancel;
|
||||
}, [targetValue]);
|
||||
|
||||
return Text(
|
||||
_formatter.format(value.value.toInt()),
|
||||
style: style,
|
||||
);
|
||||
return Text(_formatter.format(value.value.toInt()), style: style);
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,19 +20,14 @@ class GridItemAnimator extends HookWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// 创建动画控制器
|
||||
final animationController = useAnimationController(
|
||||
duration: duration,
|
||||
);
|
||||
final animationController = useAnimationController(duration: duration);
|
||||
|
||||
// 创建不透明度动画
|
||||
final opacityAnimation = useAnimation(
|
||||
Tween<double>(
|
||||
begin: 0.0, // 开始时完全透明
|
||||
end: 1.0, // 结束时完全不透明
|
||||
).animate(CurvedAnimation(
|
||||
parent: animationController,
|
||||
curve: Curves.easeOut,
|
||||
)),
|
||||
).animate(CurvedAnimation(parent: animationController, curve: Curves.easeOut)),
|
||||
);
|
||||
|
||||
// 创建位移动画
|
||||
@ -40,23 +35,24 @@ class GridItemAnimator extends HookWidget {
|
||||
Tween<double>(
|
||||
begin: 1.0, // 开始位置
|
||||
end: 0.0, // 结束位置
|
||||
).animate(CurvedAnimation(
|
||||
parent: animationController,
|
||||
curve: Curves.easeOutCubic,
|
||||
)),
|
||||
).animate(CurvedAnimation(parent: animationController, curve: Curves.easeOutCubic)),
|
||||
);
|
||||
|
||||
// 组件挂载后启动动画
|
||||
useEffect(() {
|
||||
// 根据索引计算延迟时间,实现逐个条目入场
|
||||
final delay = delayPerItem * index;
|
||||
bool cancelled = false;
|
||||
|
||||
Future.delayed(delay, () {
|
||||
if (animationController.status != AnimationStatus.completed) {
|
||||
if (!cancelled && animationController.status != AnimationStatus.completed) {
|
||||
animationController.forward();
|
||||
}
|
||||
});
|
||||
return null;
|
||||
|
||||
return () {
|
||||
cancelled = true;
|
||||
};
|
||||
}, const []);
|
||||
|
||||
// 应用动画效果
|
||||
|
||||
115
lib/widgets/src/swiper.dart
Normal file
115
lib/widgets/src/swiper.dart
Normal file
@ -0,0 +1,115 @@
|
||||
import 'package:card_swiper/card_swiper.dart';
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:flutter_tilt/flutter_tilt.dart';
|
||||
|
||||
class HoverSwiper extends HookWidget {
|
||||
const HoverSwiper({
|
||||
super.key,
|
||||
required this.itemCount,
|
||||
required this.itemBuilder,
|
||||
this.autoplayDelay = 3000,
|
||||
this.paginationActiveSize = 8.0,
|
||||
this.controlSize = 24,
|
||||
this.controlPadding = const EdgeInsets.symmetric(horizontal: 8, vertical: 0),
|
||||
});
|
||||
|
||||
final int itemCount;
|
||||
final IndexedWidgetBuilder itemBuilder;
|
||||
final double paginationActiveSize;
|
||||
final double controlSize;
|
||||
final EdgeInsets controlPadding;
|
||||
final int autoplayDelay;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isHovered = useState(false);
|
||||
final controller = useMemoized(() => SwiperController());
|
||||
|
||||
useEffect(() {
|
||||
return controller.dispose;
|
||||
}, [controller]);
|
||||
|
||||
return MouseRegion(
|
||||
onEnter: (_) {
|
||||
isHovered.value = true;
|
||||
controller.stopAutoplay();
|
||||
},
|
||||
onExit: (_) {
|
||||
isHovered.value = false;
|
||||
controller.startAutoplay();
|
||||
},
|
||||
child: Stack(
|
||||
children: [
|
||||
Tilt(
|
||||
shadowConfig: const ShadowConfig(maxIntensity: .3),
|
||||
borderRadius: const BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12)),
|
||||
child: Swiper(
|
||||
controller: controller,
|
||||
itemCount: itemCount,
|
||||
itemBuilder: itemBuilder,
|
||||
autoplay: true,
|
||||
autoplayDelay: autoplayDelay,
|
||||
),
|
||||
),
|
||||
// Left control button
|
||||
_buildControlButton(
|
||||
isHovered: isHovered.value,
|
||||
position: 'left',
|
||||
onTap: () => controller.previous(),
|
||||
icon: FluentIcons.chevron_left,
|
||||
),
|
||||
// Right control button
|
||||
_buildControlButton(
|
||||
isHovered: isHovered.value,
|
||||
position: 'right',
|
||||
onTap: () => controller.next(),
|
||||
icon: FluentIcons.chevron_right,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// 构建控制按钮(左/右箭头)
|
||||
Widget _buildControlButton({
|
||||
required bool isHovered,
|
||||
required String position,
|
||||
required VoidCallback onTap,
|
||||
required IconData icon,
|
||||
}) {
|
||||
final isLeft = position == 'left';
|
||||
return Positioned(
|
||||
left: isLeft ? 0 : null,
|
||||
right: isLeft ? null : 0,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
child: AnimatedOpacity(
|
||||
opacity: isHovered ? 1.0 : 0.0,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: IgnorePointer(
|
||||
ignoring: !isHovered,
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: controlPadding,
|
||||
child: MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(2),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black.withValues(alpha: .3),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Icon(icon, size: controlSize, color: Colors.white.withValues(alpha: .8)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -17,53 +17,42 @@ export 'src/cache_image.dart';
|
||||
export 'src/countdown_time_text.dart';
|
||||
export 'src/cache_svg_image.dart';
|
||||
export 'src/grid_item_animator.dart';
|
||||
export 'src/swiper.dart';
|
||||
|
||||
export '../common/utils/async.dart';
|
||||
export '../common/utils/base_utils.dart';
|
||||
export 'package:starcitizen_doctor/generated/l10n.dart';
|
||||
|
||||
Widget makeLoading(
|
||||
BuildContext context, {
|
||||
double? width,
|
||||
}) {
|
||||
Widget makeLoading(BuildContext context, {double? width}) {
|
||||
width ??= 30;
|
||||
return Center(
|
||||
child: SizedBox(
|
||||
width: width,
|
||||
height: width,
|
||||
child: const ProgressRing(),
|
||||
),
|
||||
child: SizedBox(width: width, height: width, child: const ProgressRing()),
|
||||
);
|
||||
}
|
||||
|
||||
Widget makeDefaultPage(BuildContext context,
|
||||
{Widget? titleRow,
|
||||
List<Widget>? actions,
|
||||
Widget? content,
|
||||
bool automaticallyImplyLeading = true,
|
||||
String title = "",
|
||||
bool useBodyContainer = false}) {
|
||||
Widget makeDefaultPage(
|
||||
BuildContext context, {
|
||||
Widget? titleRow,
|
||||
List<Widget>? actions,
|
||||
Widget? content,
|
||||
bool automaticallyImplyLeading = true,
|
||||
String title = "",
|
||||
bool useBodyContainer = false,
|
||||
}) {
|
||||
return NavigationView(
|
||||
appBar: NavigationAppBar(
|
||||
automaticallyImplyLeading: automaticallyImplyLeading,
|
||||
title: DragToMoveArea(
|
||||
child: titleRow ??
|
||||
Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
Text(title),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
actions: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [...?actions, const WindowButtons()],
|
||||
)),
|
||||
automaticallyImplyLeading: automaticallyImplyLeading,
|
||||
title: DragToMoveArea(
|
||||
child:
|
||||
titleRow ??
|
||||
Column(
|
||||
children: [
|
||||
Expanded(child: Row(children: [Text(title)])),
|
||||
],
|
||||
),
|
||||
),
|
||||
actions: Row(mainAxisAlignment: MainAxisAlignment.end, children: [...?actions, const WindowButtons()]),
|
||||
),
|
||||
content: useBodyContainer
|
||||
? Container(
|
||||
decoration: BoxDecoration(
|
||||
@ -85,55 +74,63 @@ class WindowButtons extends StatelessWidget {
|
||||
return SizedBox(
|
||||
width: 138,
|
||||
height: 50,
|
||||
child: WindowCaption(
|
||||
brightness: theme.brightness,
|
||||
backgroundColor: Colors.transparent,
|
||||
),
|
||||
child: WindowCaption(brightness: theme.brightness, backgroundColor: Colors.transparent),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
List<Widget> makeMarkdownView(String description, {String? attachmentsUrl}) {
|
||||
return MarkdownGenerator().buildWidgets(description,
|
||||
config: MarkdownConfig(configs: [
|
||||
LinkConfig(onTap: (url) {
|
||||
if (url.startsWith("/") && attachmentsUrl != null) {
|
||||
url = "$attachmentsUrl/$url";
|
||||
}
|
||||
launchUrlString(url);
|
||||
}),
|
||||
ImgConfig(builder: (String url, Map<String, String> attributes) {
|
||||
if (url.startsWith("/") && attachmentsUrl != null) {
|
||||
url = "$attachmentsUrl/$url";
|
||||
}
|
||||
return ExtendedImage.network(
|
||||
url,
|
||||
loadStateChanged: (ExtendedImageState state) {
|
||||
switch (state.extendedImageLoadState) {
|
||||
case LoadState.loading:
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
const ProgressRing(),
|
||||
const SizedBox(height: 12),
|
||||
Text(S.current.app_common_loading_images)
|
||||
],
|
||||
return MarkdownGenerator().buildWidgets(
|
||||
description,
|
||||
config: MarkdownConfig(
|
||||
configs: [
|
||||
LinkConfig(
|
||||
onTap: (url) {
|
||||
if (url.startsWith("/") && attachmentsUrl != null) {
|
||||
url = "$attachmentsUrl/$url";
|
||||
}
|
||||
launchUrlString(url);
|
||||
},
|
||||
),
|
||||
ImgConfig(
|
||||
builder: (String url, Map<String, String> attributes) {
|
||||
if (url.startsWith("/") && attachmentsUrl != null) {
|
||||
url = "$attachmentsUrl/$url";
|
||||
}
|
||||
return ExtendedImage.network(
|
||||
url,
|
||||
loadStateChanged: (ExtendedImageState state) {
|
||||
switch (state.extendedImageLoadState) {
|
||||
case LoadState.loading:
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
const ProgressRing(),
|
||||
const SizedBox(height: 12),
|
||||
Text(S.current.app_common_loading_images),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
case LoadState.completed:
|
||||
return ExtendedRawImage(
|
||||
image: state.extendedImageInfo?.image,
|
||||
);
|
||||
case LoadState.failed:
|
||||
return Text("Loading Image error $url");
|
||||
}
|
||||
},
|
||||
);
|
||||
})
|
||||
]));
|
||||
);
|
||||
case LoadState.completed:
|
||||
return ExtendedRawImage(image: state.extendedImageInfo?.image);
|
||||
case LoadState.failed:
|
||||
return Button(
|
||||
onPressed: () {
|
||||
launchUrlString(url);
|
||||
},
|
||||
child: Text("Loading Image error $url"),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
ColorFilter makeSvgColor(Color color) {
|
||||
@ -142,22 +139,20 @@ ColorFilter makeSvgColor(Color color) {
|
||||
|
||||
CustomTransitionPage<T> myPageBuilder<T>(BuildContext context, GoRouterState state, Widget child) {
|
||||
return CustomTransitionPage(
|
||||
child: child,
|
||||
transitionDuration: const Duration(milliseconds: 150),
|
||||
reverseTransitionDuration: const Duration(milliseconds: 150),
|
||||
transitionsBuilder:
|
||||
(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
|
||||
return SlideTransition(
|
||||
position: Tween<Offset>(
|
||||
begin: const Offset(0.0, 1.0),
|
||||
end: const Offset(0.0, 0.0),
|
||||
).animate(CurvedAnimation(
|
||||
parent: animation,
|
||||
curve: Curves.easeInOut,
|
||||
)),
|
||||
child: child,
|
||||
);
|
||||
});
|
||||
child: child,
|
||||
transitionDuration: const Duration(milliseconds: 150),
|
||||
reverseTransitionDuration: const Duration(milliseconds: 150),
|
||||
transitionsBuilder:
|
||||
(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
|
||||
return SlideTransition(
|
||||
position: Tween<Offset>(
|
||||
begin: const Offset(0.0, 1.0),
|
||||
end: const Offset(0.0, 0.0),
|
||||
).animate(CurvedAnimation(parent: animation, curve: Curves.easeInOut)),
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
class LoadingWidget<T> extends HookConsumerWidget {
|
||||
@ -192,9 +187,7 @@ class LoadingWidget<T> extends HookConsumerWidget {
|
||||
onPressed: () {
|
||||
_loadData(dataState, errorMsg);
|
||||
},
|
||||
child: Center(
|
||||
child: Text(errorMsg.value),
|
||||
),
|
||||
child: Center(child: Text(errorMsg.value)),
|
||||
);
|
||||
}
|
||||
if (dataState.value == null && data == null) return makeLoading(context);
|
||||
|
||||
10
pubspec.lock
10
pubspec.lock
@ -306,14 +306,6 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.0+7.7.0"
|
||||
dart_rss:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: dart_rss
|
||||
sha256: "73539d4b7153b47beef8b51763ca55dcb6fc0bb412b29e0f5e74e93fabfd1ac6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.3"
|
||||
dart_style:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1610,7 +1602,7 @@ packages:
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
xml:
|
||||
dependency: "direct main"
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xml
|
||||
sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025"
|
||||
|
||||
@ -47,9 +47,7 @@ dependencies:
|
||||
freezed_annotation: ^3.1.0
|
||||
meta: ^1.16.0
|
||||
hexcolor: ^3.0.1
|
||||
dart_rss: ^3.0.3
|
||||
html: ^0.15.6
|
||||
xml: ^6.6.1
|
||||
fixnum: ^1.1.1
|
||||
rust_builder:
|
||||
path: rust_builder
|
||||
|
||||
Loading…
Reference in New Issue
Block a user