Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-12-16 14:22:47 +08:00
parent 13818533a7
commit 0baf3fcd36
283 changed files with 803 additions and 1550 deletions

View File

@@ -8,9 +8,9 @@ import 'package:PiliPlus/models/common/account_type.dart';
import 'package:PiliPlus/utils/accounts.dart';
import 'package:PiliPlus/utils/accounts/account.dart';
import 'package:PiliPlus/utils/app_sign.dart';
import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/extension/string_ext.dart';
import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:PiliPlus/utils/storage_pref.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart' show kDebugMode;
@@ -363,7 +363,7 @@ class AccountManager extends Interceptor {
case DioExceptionType.unknown:
String desc;
try {
desc = Utils.isMobile
desc = PlatformUtils.isMobile
? (await Connectivity().checkConnectivity()).first.desc
: '';
} catch (_) {

View File

@@ -1,5 +1,5 @@
import 'package:PiliPlus/models/common/account_type.dart';
import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/extension/iterable_ext.dart';
import 'package:hive/hive.dart';
class AccountTypeAdapter extends TypeAdapter<AccountType> {

View File

@@ -14,7 +14,7 @@ import 'package:PiliPlus/pages/live/view.dart';
import 'package:PiliPlus/pages/rank/view.dart';
import 'package:PiliPlus/pages/subscription_detail/view.dart';
import 'package:PiliPlus/pages/video/reply_reply/view.dart';
import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/extension/iterable_ext.dart';
import 'package:PiliPlus/utils/id_utils.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/request_utils.dart';

View File

@@ -1,9 +1,9 @@
import 'dart:async';
import 'dart:io';
import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/extension/iterable_ext.dart';
import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:PiliPlus/utils/storage_pref.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:path_provider/path_provider.dart';
abstract class CacheManager {
@@ -14,7 +14,7 @@ abstract class CacheManager {
]) async {
try {
final Directory tempDirectory = await getTemporaryDirectory();
if (Utils.isDesktop) {
if (PlatformUtils.isDesktop) {
final dir = Directory('${tempDirectory.path}/libCachedImageData');
if (dir.existsSync()) {
return await getTotalSizeOfFilesInDir(dir, maxSize);
@@ -62,7 +62,7 @@ abstract class CacheManager {
static Future<void> clearLibraryCache() async {
try {
final Directory tempDirectory = await getTemporaryDirectory();
if (Utils.isDesktop) {
if (PlatformUtils.isDesktop) {
final dir = Directory('${tempDirectory.path}/libCachedImageData');
if (dir.existsSync()) {
await dir.delete(recursive: true);

View File

@@ -1,291 +0,0 @@
import 'dart:io';
import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
import 'package:PiliPlus/grpc/bilibili/app/im/v1.pb.dart' show ThreeDotItem;
import 'package:PiliPlus/grpc/bilibili/app/im/v1.pbenum.dart'
show IMSettingType, ThreeDotItemType;
import 'package:PiliPlus/pages/common/common_whisper_controller.dart';
import 'package:PiliPlus/pages/contact/view.dart';
import 'package:PiliPlus/pages/whisper_settings/view.dart';
import 'package:floating/floating.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart' hide ContextExtensionss;
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
extension ImageExtension on num {
int? cacheSize(BuildContext context) {
if (this == 0) {
return null;
}
return (this * MediaQuery.devicePixelRatioOf(context)).round();
}
}
extension IntExt on int? {
int? operator +(int other) => this == null ? null : this! + other;
int? operator -(int other) => this == null ? null : this! - other;
}
extension ScrollControllerExt on ScrollController {
void animToTop() => animTo(0);
void animTo(
double offset, {
Duration duration = const Duration(milliseconds: 500),
}) {
if (!hasClients) return;
if ((offset - this.offset).abs() >= position.viewportDimension * 7) {
jumpTo(offset);
} else {
animateTo(
offset,
duration: duration,
curve: Curves.easeInOut,
);
}
}
void jumpToTop() {
if (!hasClients) return;
jumpTo(0);
}
}
extension IterableExt<T> on Iterable<T>? {
bool get isNullOrEmpty => this == null || this!.isEmpty;
}
extension NonNullIterableExt<T> on Iterable<T> {
T? reduceOrNull(T Function(T value, T element) combine) {
Iterator<T> iterator = this.iterator;
if (!iterator.moveNext()) {
return null;
}
T value = iterator.current;
while (iterator.moveNext()) {
value = combine(value, iterator.current);
}
return value;
}
}
extension MapExt<K, V> on Map<K, V> {
Map<RK, RV> fromCast<RK, RV>() {
return Map<RK, RV>.from(this);
}
}
extension ListExt<T> on List<T> {
T? getOrNull(int index) {
if (index < 0 || index >= length) {
return null;
}
return this[index];
}
bool removeFirstWhere(bool Function(T) test) {
final index = indexWhere(test);
if (index != -1) {
removeAt(index);
return true;
}
return false;
}
List<R> fromCast<R>() {
return List<R>.from(this);
}
T findClosestTarget(
bool Function(T) test,
T Function(T, T) combine,
) {
return where(test).reduceOrNull(combine) ?? reduce(combine);
}
}
final _regExp = RegExp("^(http:)?//", caseSensitive: false);
extension StringExt on String? {
String get http2https => this?.replaceFirst(_regExp, "https://") ?? '';
bool get isNullOrEmpty => this == null || this!.isEmpty;
}
extension ColorSchemeExt on ColorScheme {
Color get vipColor =>
brightness.isLight ? const Color(0xFFFF6699) : const Color(0xFFD44E7D);
Color get freeColor =>
brightness.isLight ? const Color(0xFFFF7F24) : const Color(0xFFD66011);
bool get isLight => brightness.isLight;
bool get isDark => brightness.isDark;
}
extension Unique<E, Id> on List<E> {
List<E> unique([Id Function(E element)? id, bool inplace = true]) {
final ids = <Id>{};
return (inplace ? this : List<E>.from(this))
..retainWhere((x) => ids.add(id != null ? id(x) : x as Id));
}
}
extension ColorExtension on Color {
Color darken([double amount = .5]) {
assert(amount >= 0 && amount <= 1, 'Amount must be between 0 and 1');
return Color.lerp(this, Colors.black, amount)!;
}
}
extension BrightnessExt on Brightness {
Brightness get reverse => isLight ? Brightness.dark : Brightness.light;
bool get isLight => this == Brightness.light;
bool get isDark => this == Brightness.dark;
}
extension RationalExt on Rational {
/// Checks whether given [Rational] instance fits into Android requirements
/// or not.
///
/// Android docs specified boundaries as inclusive.
bool get fitsInAndroidRequirements {
final aspectRatio = numerator / denominator;
const min = 1 / 2.39;
const max = 2.39;
return (min <= aspectRatio) && (aspectRatio <= max);
}
}
extension ThreeDotItemTypeExt on ThreeDotItemType {
Icon get icon => switch (this) {
ThreeDotItemType.THREE_DOT_ITEM_TYPE_MSG_SETTING => const Icon(
Icons.settings,
size: 20,
),
ThreeDotItemType.THREE_DOT_ITEM_TYPE_READ_ALL => const Icon(
Icons.cleaning_services,
size: 20,
),
ThreeDotItemType.THREE_DOT_ITEM_TYPE_CLEAR_LIST => const Icon(
Icons.delete_forever_outlined,
size: 20,
),
ThreeDotItemType.THREE_DOT_ITEM_TYPE_UP_HELPER => const Icon(
Icons.live_tv,
size: 20,
),
ThreeDotItemType.THREE_DOT_ITEM_TYPE_CONTACTS => const Icon(
Icons.account_box_outlined,
size: 20,
),
ThreeDotItemType.THREE_DOT_ITEM_TYPE_FANS_GROUP_HELPER => const Icon(
Icons.notifications_none,
size: 20,
),
_ => const Icon(MdiIcons.circleMedium, size: 20),
};
void action({
required BuildContext context,
required CommonWhisperController controller,
required ThreeDotItem item,
}) {
switch (this) {
case ThreeDotItemType.THREE_DOT_ITEM_TYPE_READ_ALL:
showConfirmDialog(
context: context,
title: '一键已读',
content: '是否清除全部新消息提醒?',
onConfirm: controller.onClearUnread,
);
case ThreeDotItemType.THREE_DOT_ITEM_TYPE_CLEAR_LIST:
showConfirmDialog(
context: context,
title: '清空列表',
content: '清空后所有消息将被删除,无法恢复',
onConfirm: controller.onDeleteList,
);
case ThreeDotItemType.THREE_DOT_ITEM_TYPE_MSG_SETTING:
Get.to(
const WhisperSettingsPage(
imSettingType: IMSettingType.SETTING_TYPE_NEED_ALL,
),
);
case ThreeDotItemType.THREE_DOT_ITEM_TYPE_UP_HELPER:
dynamic talkerId = RegExp(r'/(\d{3,})').firstMatch(item.url)?.group(1);
if (talkerId != null) {
talkerId = int.parse(talkerId);
Get.toNamed(
'/whisperDetail',
arguments: {
'talkerId': talkerId,
'name': item.title,
'face': switch (talkerId) {
844424930131966 =>
'https://message.biliimg.com/bfs/im/489a63efadfb202366c2f88853d2217b5ddc7a13.png',
844424930131964 =>
'https://i0.hdslb.com/bfs/im_new/58eda511672db078466e7ab8db22a95c1503684976.png',
_ => item.icon,
},
},
);
}
case ThreeDotItemType.THREE_DOT_ITEM_TYPE_CONTACTS:
Get.to(const ContactPage(isFromSelect: false));
default:
SmartDialog.showToast('TODO: $name');
}
}
}
extension FileExt on File {
Future<void> tryDel({bool recursive = false}) async {
try {
await delete(recursive: recursive);
} catch (_) {}
}
}
extension DirectoryExt on Directory {
Future<void> tryDel({bool recursive = false}) async {
try {
await delete(recursive: recursive);
} catch (_) {}
}
Future<bool> lengthGte(int length) async {
int count = 0;
await for (var _ in list()) {
if (++count == length) return true;
}
return false;
}
}
extension SizeExt on Size {
bool get isPortrait => width < 600 || height >= width;
}
extension GetExt on GetInterface {
S putOrFind<S>(InstanceBuilderCallback<S> dep, {String? tag}) =>
GetInstance().putOrFind(dep, tag: tag);
}
extension WidgetExt on Widget {
Widget constraintWidth({
BoxConstraints constraints = const BoxConstraints(maxWidth: 625),
}) {
return Align(
alignment: Alignment.topCenter,
child: ConstrainedBox(
constraints: constraints,
child: this,
),
);
}
}

View File

@@ -0,0 +1,14 @@
import 'package:floating/floating.dart';
extension RationalExt on Rational {
/// Checks whether given [Rational] instance fits into Android requirements
/// or not.
///
/// Android docs specified boundaries as inclusive.
bool get fitsInAndroidRequirements {
final aspectRatio = numerator / denominator;
const min = 1 / 2.39;
const max = 2.39;
return (min <= aspectRatio) && (aspectRatio <= max);
}
}

View File

@@ -0,0 +1,25 @@
import 'dart:io';
extension FileExt on File {
Future<void> tryDel({bool recursive = false}) async {
try {
await delete(recursive: recursive);
} catch (_) {}
}
}
extension DirectoryExt on Directory {
Future<void> tryDel({bool recursive = false}) async {
try {
await delete(recursive: recursive);
} catch (_) {}
}
Future<bool> lengthGte(int length) async {
int count = 0;
await for (var _ in list()) {
if (++count == length) return true;
}
return false;
}
}

View File

@@ -0,0 +1,6 @@
import 'package:get/get.dart';
extension GetExt on GetInterface {
S putOrFind<S>(InstanceBuilderCallback<S> dep, {String? tag}) =>
GetInstance().putOrFind(dep, tag: tag);
}

View File

@@ -0,0 +1,46 @@
extension NullableIterableExt<T> on Iterable<T>? {
bool get isNullOrEmpty => this == null || this!.isEmpty;
}
extension IterableExt<T> on Iterable<T> {
T? reduceOrNull(T Function(T value, T element) combine) {
Iterator<T> iterator = this.iterator;
if (!iterator.moveNext()) {
return null;
}
T value = iterator.current;
while (iterator.moveNext()) {
value = combine(value, iterator.current);
}
return value;
}
}
extension ListExt<T> on List<T> {
T? getOrNull(int index) {
if (index < 0 || index >= length) {
return null;
}
return this[index];
}
bool removeFirstWhere(bool Function(T) test) {
final index = indexWhere(test);
if (index != -1) {
removeAt(index);
return true;
}
return false;
}
List<R> fromCast<R>() {
return List<R>.from(this);
}
T findClosestTarget(
bool Function(T) test,
T Function(T, T) combine,
) {
return where(test).reduceOrNull(combine) ?? reduce(combine);
}
}

View File

@@ -0,0 +1,5 @@
extension MapExt<K, V> on Map<K, V> {
Map<RK, RV> fromCast<RK, RV>() {
return Map<RK, RV>.from(this);
}
}

View File

@@ -0,0 +1,15 @@
import 'package:flutter/widgets.dart';
extension ImageExtension on num {
int? cacheSize(BuildContext context) {
if (this == 0) {
return null;
}
return (this * MediaQuery.devicePixelRatioOf(context)).round();
}
}
extension IntExt on int? {
int? operator +(int other) => this == null ? null : this! + other;
int? operator -(int other) => this == null ? null : this! - other;
}

View File

@@ -0,0 +1,26 @@
import 'package:flutter/widgets.dart';
extension ScrollControllerExt on ScrollController {
void animToTop() => animTo(0);
void animTo(
double offset, {
Duration duration = const Duration(milliseconds: 500),
}) {
if (!hasClients) return;
if ((offset - this.offset).abs() >= position.viewportDimension * 7) {
jumpTo(offset);
} else {
animateTo(
offset,
duration: duration,
curve: Curves.easeInOut,
);
}
}
void jumpToTop() {
if (!hasClients) return;
jumpTo(0);
}
}

View File

@@ -0,0 +1,5 @@
import 'dart:ui' show Size;
extension SizeExt on Size {
bool get isPortrait => width < 600 || height >= width;
}

View File

@@ -0,0 +1,7 @@
final _regExp = RegExp("^(http:)?//", caseSensitive: false);
extension StringExt on String? {
String get http2https => this?.replaceFirst(_regExp, "https://") ?? '';
bool get isNullOrEmpty => this == null || this!.isEmpty;
}

View File

@@ -0,0 +1,28 @@
import 'package:flutter/material.dart';
extension ColorSchemeExt on ColorScheme {
Color get vipColor =>
brightness.isLight ? const Color(0xFFFF6699) : const Color(0xFFD44E7D);
Color get freeColor =>
brightness.isLight ? const Color(0xFFFF7F24) : const Color(0xFFD66011);
bool get isLight => brightness.isLight;
bool get isDark => brightness.isDark;
}
extension ColorExtension on Color {
Color darken([double amount = .5]) {
assert(amount >= 0 && amount <= 1, 'Amount must be between 0 and 1');
return Color.lerp(this, Colors.black, amount)!;
}
}
extension BrightnessExt on Brightness {
Brightness get reverse => isLight ? Brightness.dark : Brightness.light;
bool get isLight => this == Brightness.light;
bool get isDark => this == Brightness.dark;
}

View File

@@ -0,0 +1,92 @@
import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
import 'package:PiliPlus/grpc/bilibili/app/im/v1.pb.dart'
show ThreeDotItem, ThreeDotItemType, IMSettingType;
import 'package:PiliPlus/pages/common/common_whisper_controller.dart';
import 'package:PiliPlus/pages/contact/view.dart';
import 'package:PiliPlus/pages/whisper_settings/view.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
extension ThreeDotItemTypeExt on ThreeDotItemType {
Icon get icon => switch (this) {
ThreeDotItemType.THREE_DOT_ITEM_TYPE_MSG_SETTING => const Icon(
Icons.settings,
size: 20,
),
ThreeDotItemType.THREE_DOT_ITEM_TYPE_READ_ALL => const Icon(
Icons.cleaning_services,
size: 20,
),
ThreeDotItemType.THREE_DOT_ITEM_TYPE_CLEAR_LIST => const Icon(
Icons.delete_forever_outlined,
size: 20,
),
ThreeDotItemType.THREE_DOT_ITEM_TYPE_UP_HELPER => const Icon(
Icons.live_tv,
size: 20,
),
ThreeDotItemType.THREE_DOT_ITEM_TYPE_CONTACTS => const Icon(
Icons.account_box_outlined,
size: 20,
),
ThreeDotItemType.THREE_DOT_ITEM_TYPE_FANS_GROUP_HELPER => const Icon(
Icons.notifications_none,
size: 20,
),
_ => const Icon(MdiIcons.circleMedium, size: 20),
};
void action({
required BuildContext context,
required CommonWhisperController controller,
required ThreeDotItem item,
}) {
switch (this) {
case ThreeDotItemType.THREE_DOT_ITEM_TYPE_READ_ALL:
showConfirmDialog(
context: context,
title: '一键已读',
content: '是否清除全部新消息提醒?',
onConfirm: controller.onClearUnread,
);
case ThreeDotItemType.THREE_DOT_ITEM_TYPE_CLEAR_LIST:
showConfirmDialog(
context: context,
title: '清空列表',
content: '清空后所有消息将被删除,无法恢复',
onConfirm: controller.onDeleteList,
);
case ThreeDotItemType.THREE_DOT_ITEM_TYPE_MSG_SETTING:
Get.to(
const WhisperSettingsPage(
imSettingType: IMSettingType.SETTING_TYPE_NEED_ALL,
),
);
case ThreeDotItemType.THREE_DOT_ITEM_TYPE_UP_HELPER:
dynamic talkerId = RegExp(r'/(\d{3,})').firstMatch(item.url)?.group(1);
if (talkerId != null) {
talkerId = int.parse(talkerId);
Get.toNamed(
'/whisperDetail',
arguments: {
'talkerId': talkerId,
'name': item.title,
'face': switch (talkerId) {
844424930131966 =>
'https://message.biliimg.com/bfs/im/489a63efadfb202366c2f88853d2217b5ddc7a13.png',
844424930131964 =>
'https://i0.hdslb.com/bfs/im_new/58eda511672db078466e7ab8db22a95c1503684976.png',
_ => item.icon,
},
},
);
}
case ThreeDotItemType.THREE_DOT_ITEM_TYPE_CONTACTS:
Get.to(const ContactPage(isFromSelect: false));
default:
SmartDialog.showToast('TODO: $name');
}
}
}

View File

@@ -0,0 +1,15 @@
import 'package:flutter/widgets.dart';
extension WidgetExt on Widget {
Widget constraintWidth({
BoxConstraints constraints = const BoxConstraints(maxWidth: 625),
}) {
return Align(
alignment: Alignment.topCenter,
child: ConstrainedBox(
constraints: constraints,
child: this,
),
);
}
}

View File

@@ -3,10 +3,12 @@ import 'dart:typed_data';
import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/http/init.dart';
import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/extension/file_ext.dart';
import 'package:PiliPlus/utils/extension/string_ext.dart';
import 'package:PiliPlus/utils/global_data.dart';
import 'package:PiliPlus/utils/path_utils.dart';
import 'package:PiliPlus/utils/permission_handler.dart';
import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:PiliPlus/utils/storage_pref.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:dio/dio.dart';
@@ -109,7 +111,8 @@ abstract class ImageUtils {
required int height,
}) async {
try {
if (Utils.isMobile && !await checkPermissionDependOnSdkInt(context)) {
if (PlatformUtils.isMobile &&
!await checkPermissionDependOnSdkInt(context)) {
return false;
}
if (!silentDownImg) SmartDialog.showLoading(msg: '正在下载');
@@ -168,7 +171,8 @@ abstract class ImageUtils {
List<String> imgList, [
CacheManager? manager,
]) async {
if (Utils.isMobile && !await checkPermissionDependOnSdkInt(context)) {
if (PlatformUtils.isMobile &&
!await checkPermissionDependOnSdkInt(context)) {
return false;
}
CancelToken? cancelToken;
@@ -211,7 +215,7 @@ abstract class ImageUtils {
}
});
final result = await Future.wait(futures, eagerError: true);
if (Utils.isMobile) {
if (PlatformUtils.isMobile) {
final delList = <String>[];
final saveList = <SaveFileData>[];
for (var i in result) {
@@ -292,7 +296,7 @@ abstract class ImageUtils {
}) async {
SaveResult? result;
fileName += '.$ext';
if (Utils.isMobile) {
if (PlatformUtils.isMobile) {
SmartDialog.showLoading(msg: '正在保存');
result = await SaverGallery.saveImage(
bytes,
@@ -336,7 +340,7 @@ abstract class ImageUtils {
return;
}
SaveResult? result;
if (Utils.isMobile) {
if (PlatformUtils.isMobile) {
result = await SaverGallery.saveFile(
filePath: filePath,
fileName: fileName,

View File

@@ -18,8 +18,9 @@ import 'package:PiliPlus/pages/share/view.dart';
import 'package:PiliPlus/pages/video/introduction/ugc/widgets/menu_row.dart';
import 'package:PiliPlus/services/shutdown_timer_service.dart';
import 'package:PiliPlus/utils/app_scheme.dart';
import 'package:PiliPlus/utils/context_ext.dart';
import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/extension/context_ext.dart';
import 'package:PiliPlus/utils/extension/extension.dart';
import 'package:PiliPlus/utils/extension/string_ext.dart';
import 'package:PiliPlus/utils/feed_back.dart';
import 'package:PiliPlus/utils/global_data.dart';
import 'package:PiliPlus/utils/id_utils.dart';
@@ -423,10 +424,7 @@ abstract class PageUtils {
}
}
// redirectUrl from jumpUrl
if (await UrlUtils.parseRedirectUrl(
archive.jumpUrl.http2https,
false,
)
if (await UrlUtils.parseRedirectUrl(archive.jumpUrl.http2https, false)
case final redirectUrl?) {
if (viewPgcFromUri(redirectUrl)) {
return;

View File

@@ -0,0 +1,10 @@
import 'dart:io' show Platform;
abstract final class PlatformUtils {
@pragma("vm:platform-const")
static final bool isMobile = Platform.isAndroid || Platform.isIOS;
@pragma("vm:platform-const")
static final bool isDesktop =
Platform.isWindows || Platform.isMacOS || Platform.isLinux;
}

View File

@@ -9,7 +9,7 @@ import 'package:PiliPlus/models/common/reply/reply_sort_type.dart';
import 'package:PiliPlus/models_new/reply/data.dart';
import 'package:PiliPlus/utils/accounts.dart';
import 'package:PiliPlus/utils/accounts/account.dart';
import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/extension/iterable_ext.dart';
import 'package:PiliPlus/utils/id_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/foundation.dart' show kDebugMode;

View File

@@ -24,9 +24,10 @@ import 'package:PiliPlus/pages/group_panel/view.dart';
import 'package:PiliPlus/pages/later/controller.dart';
import 'package:PiliPlus/pages/login/geetest/geetest_webview_dialog.dart';
import 'package:PiliPlus/utils/accounts.dart';
import 'package:PiliPlus/utils/context_ext.dart';
import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/extension/context_ext.dart';
import 'package:PiliPlus/utils/extension/string_ext.dart';
import 'package:PiliPlus/utils/feed_back.dart';
import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:PiliPlus/utils/storage.dart';
import 'package:PiliPlus/utils/storage_key.dart';
import 'package:PiliPlus/utils/storage_pref.dart';
@@ -542,7 +543,7 @@ abstract final class RequestUtils {
}
}
if (Utils.isDesktop) {
if (PlatformUtils.isDesktop) {
final json = await Get.dialog<Map<String, dynamic>>(
GeetestWebviewDialog(gt!, challenge!),
);

View File

@@ -24,13 +24,13 @@ import 'package:PiliPlus/plugin/pl_player/models/bottom_progress_behavior.dart';
import 'package:PiliPlus/plugin/pl_player/models/fullscreen_mode.dart';
import 'package:PiliPlus/plugin/pl_player/models/hwdec_type.dart';
import 'package:PiliPlus/plugin/pl_player/models/play_repeat.dart';
import 'package:PiliPlus/utils/context_ext.dart';
import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/extension/context_ext.dart';
import 'package:PiliPlus/utils/extension/iterable_ext.dart';
import 'package:PiliPlus/utils/global_data.dart';
import 'package:PiliPlus/utils/login_utils.dart';
import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:PiliPlus/utils/storage.dart';
import 'package:PiliPlus/utils/storage_key.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart' hide ContextExtensionss;
import 'package:hive/hive.dart';
@@ -277,7 +277,7 @@ abstract class Pref {
static double get refreshDisplacement => _setting.get(
SettingBoxKey.refreshDisplacement,
defaultValue: Utils.isMobile ? 20.0 : 40.0,
defaultValue: PlatformUtils.isMobile ? 20.0 : 40.0,
);
static String get blockUserID {
@@ -878,7 +878,7 @@ abstract class Pref {
static bool get showBatteryLevel => _setting.get(
SettingBoxKey.showBatteryLevel,
defaultValue: Utils.isMobile,
defaultValue: PlatformUtils.isMobile,
);
static FollowOrderType get followOrderType =>

View File

@@ -1,6 +1,6 @@
import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/main.dart';
import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/extension/theme_ext.dart';
import 'package:PiliPlus/utils/storage_pref.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

View File

@@ -6,7 +6,7 @@ import 'package:PiliPlus/http/api.dart';
import 'package:PiliPlus/http/init.dart';
import 'package:PiliPlus/http/ua_type.dart';
import 'package:PiliPlus/utils/accounts/account.dart';
import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/extension/string_ext.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/storage.dart';
import 'package:PiliPlus/utils/storage_key.dart';

View File

@@ -4,6 +4,7 @@ import 'dart:io';
import 'dart:math' show Random;
import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:catcher_2/catcher_2.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:device_info_plus/device_info_plus.dart';
@@ -18,13 +19,6 @@ abstract class Utils {
static const channel = MethodChannel(Constants.appName);
@pragma("vm:platform-const")
static final bool isMobile = Platform.isAndroid || Platform.isIOS;
@pragma("vm:platform-const")
static final bool isDesktop =
Platform.isWindows || Platform.isMacOS || Platform.isLinux;
static const jsonEncoder = JsonEncoder.withIndent(' ');
static Future<void> saveBytes2File({
@@ -38,13 +32,13 @@ abstract class Utils {
allowedExtensions: allowedExtensions,
type: type,
fileName: name,
bytes: Utils.isDesktop ? null : bytes,
bytes: PlatformUtils.isDesktop ? null : bytes,
);
if (path == null) {
SmartDialog.showToast("取消保存");
return;
}
if (Utils.isDesktop) {
if (PlatformUtils.isDesktop) {
await File(path).writeAsBytes(bytes);
}
SmartDialog.showToast("已保存");
@@ -62,7 +56,7 @@ abstract class Utils {
static Future<bool> get isWiFi async {
try {
return Utils.isMobile &&
return PlatformUtils.isMobile &&
(await Connectivity().checkConnectivity()).contains(
ConnectivityResult.wifi,
);
@@ -96,7 +90,7 @@ abstract class Utils {
}
static Future<void> shareText(String text) async {
if (Utils.isDesktop) {
if (PlatformUtils.isDesktop) {
copyText(text);
return;
}