mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-23 18:46:53 +08:00
@@ -75,9 +75,7 @@ class PBadge extends StatelessWidget {
|
|||||||
bgColor = Colors.transparent;
|
bgColor = Colors.transparent;
|
||||||
borderColor = theme.secondary;
|
borderColor = theme.secondary;
|
||||||
case PBadgeType.free:
|
case PBadgeType.free:
|
||||||
bgColor = Get.isDarkMode
|
bgColor = theme.freeColor;
|
||||||
? const Color(0xFFD66011)
|
|
||||||
: const Color(0xFFFF7F24);
|
|
||||||
color = Colors.white;
|
color = Colors.white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,11 +45,11 @@ Widget imageView(
|
|||||||
ValueChanged<int>? onDismissed,
|
ValueChanged<int>? onDismissed,
|
||||||
Function(List<String>, int)? callback,
|
Function(List<String>, int)? callback,
|
||||||
}) {
|
}) {
|
||||||
double imageWidth = (maxWidth - 2 * 5) / 3;
|
double imageWidth = (maxWidth - 10) / 3;
|
||||||
double imageHeight = imageWidth;
|
double imageHeight = imageWidth;
|
||||||
if (picArr.length == 1) {
|
if (picArr.length == 1) {
|
||||||
dynamic width = picArr[0].width;
|
num width = picArr[0].width;
|
||||||
dynamic height = picArr[0].height;
|
num height = picArr[0].height;
|
||||||
double ratioWH = width / height;
|
double ratioWH = width / height;
|
||||||
double ratioHW = height / width;
|
double ratioHW = height / width;
|
||||||
imageWidth = ratioWH > 1.5
|
imageWidth = ratioWH > 1.5
|
||||||
@@ -57,6 +57,9 @@ Widget imageView(
|
|||||||
: (ratioWH >= 1 || (height > width && ratioHW < 1.5))
|
: (ratioWH >= 1 || (height > width && ratioHW < 1.5))
|
||||||
? 2 * imageWidth
|
? 2 * imageWidth
|
||||||
: 1.5 * imageWidth;
|
: 1.5 * imageWidth;
|
||||||
|
if (width != 1) {
|
||||||
|
imageWidth = min(imageWidth, width.toDouble());
|
||||||
|
}
|
||||||
imageHeight = imageWidth * min(ratioHW, _maxRatio);
|
imageHeight = imageWidth * min(ratioHW, _maxRatio);
|
||||||
} else if (picArr.length == 2) {
|
} else if (picArr.length == 2) {
|
||||||
imageWidth = imageHeight = 2 * imageWidth;
|
imageWidth = imageHeight = 2 * imageWidth;
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ class _DynMentionPanelState extends SearchState<DynMentionPanel> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onKeywordChanged(String value) => _controller
|
void onValueChanged(String value) => _controller
|
||||||
..enableClear.value = value.isNotEmpty
|
..enableClear.value = value.isNotEmpty
|
||||||
..onRefresh().whenComplete(
|
..onRefresh().whenComplete(
|
||||||
() => WidgetsBinding.instance.addPostFrameCallback(
|
() => WidgetsBinding.instance.addPostFrameCallback(
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ class _SelectTopicPanelState extends SearchState<SelectTopicPanel> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onKeywordChanged(String value) => _controller
|
void onValueChanged(String value) => _controller
|
||||||
..enableClear.value = value.isNotEmpty
|
..enableClear.value = value.isNotEmpty
|
||||||
..onRefresh().whenComplete(
|
..onRefresh().whenComplete(
|
||||||
() => WidgetsBinding.instance.addPostFrameCallback(
|
() => WidgetsBinding.instance.addPostFrameCallback(
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ class _FavNoteChildPageState extends State<FavNoteChildPage>
|
|||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
_favNoteController.handleSelect(
|
_favNoteController.handleSelect(
|
||||||
checked: !_favNoteController.allSelected.value,
|
checked: !_favNoteController.allSelected.value,
|
||||||
|
disableSelect: false,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ class _FavPgcChildPageState extends State<FavPgcChildPage>
|
|||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
_favPgcController.handleSelect(
|
_favPgcController.handleSelect(
|
||||||
checked: !_favPgcController.allSelected.value,
|
checked: !_favPgcController.allSelected.value,
|
||||||
|
disableSelect: false,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -14,17 +14,15 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:stream_transform/stream_transform.dart';
|
import 'package:stream_transform/stream_transform.dart';
|
||||||
|
|
||||||
mixin SearchKeywordMixin {
|
mixin DebounceStreamMixin<T> {
|
||||||
Duration duration = const Duration(milliseconds: 200);
|
Duration duration = const Duration(milliseconds: 200);
|
||||||
StreamController<String>? ctr;
|
StreamController<T>? ctr;
|
||||||
StreamSubscription<String>? sub;
|
StreamSubscription<T>? sub;
|
||||||
void onKeywordChanged(String value);
|
void onValueChanged(T value);
|
||||||
|
|
||||||
void subInit() {
|
void subInit() {
|
||||||
ctr = StreamController<String>();
|
ctr = StreamController<T>();
|
||||||
sub = ctr!.stream
|
sub = ctr!.stream.debounce(duration, trailing: true).listen(onValueChanged);
|
||||||
.debounce(duration, trailing: true)
|
|
||||||
.listen(onKeywordChanged);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void subDispose() {
|
void subDispose() {
|
||||||
@@ -36,7 +34,7 @@ mixin SearchKeywordMixin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract class SearchState<T extends StatefulWidget> extends State<T>
|
abstract class SearchState<T extends StatefulWidget> extends State<T>
|
||||||
with SearchKeywordMixin {
|
with DebounceStreamMixin<String> {
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
subDispose();
|
subDispose();
|
||||||
@@ -50,7 +48,8 @@ abstract class SearchState<T extends StatefulWidget> extends State<T>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SSearchController extends GetxController with SearchKeywordMixin {
|
class SSearchController extends GetxController
|
||||||
|
with DebounceStreamMixin<String> {
|
||||||
SSearchController(this.tag);
|
SSearchController(this.tag);
|
||||||
final String tag;
|
final String tag;
|
||||||
|
|
||||||
@@ -187,7 +186,7 @@ class SSearchController extends GetxController with SearchKeywordMixin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onKeywordChanged(String value) async {
|
Future<void> onValueChanged(String value) async {
|
||||||
var res = await SearchHttp.searchSuggest(term: value);
|
var res = await SearchHttp.searchSuggest(term: value);
|
||||||
if (res['status']) {
|
if (res['status']) {
|
||||||
SearchSuggestModel data = res['data'];
|
SearchSuggestModel data = res['data'];
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class _SettingsSearchPageState extends SearchState<SettingsSearchPage> {
|
|||||||
];
|
];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onKeywordChanged(String value) {
|
void onValueChanged(String value) {
|
||||||
if (value.isEmpty) {
|
if (value.isEmpty) {
|
||||||
_list.clear();
|
_list.clear();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import 'package:PiliPlus/models_new/pgc/pgc_info_model/new_ep.dart';
|
|||||||
import 'package:PiliPlus/models_new/video/video_detail/episode.dart'
|
import 'package:PiliPlus/models_new/video/video_detail/episode.dart'
|
||||||
hide EpisodeItem;
|
hide EpisodeItem;
|
||||||
import 'package:PiliPlus/pages/video/controller.dart';
|
import 'package:PiliPlus/pages/video/controller.dart';
|
||||||
|
import 'package:PiliPlus/utils/extension.dart';
|
||||||
import 'package:PiliPlus/utils/storage_pref.dart';
|
import 'package:PiliPlus/utils/storage_pref.dart';
|
||||||
import 'package:PiliPlus/utils/utils.dart';
|
import 'package:PiliPlus/utils/utils.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@@ -86,7 +87,7 @@ class _PgcPanelState extends State<PgcPanel> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context).colorScheme;
|
||||||
final currEpisode = widget.pages[currentIndex];
|
final currEpisode = widget.pages[currentIndex];
|
||||||
final isPugv = currEpisode.from == 'pugv';
|
final isPugv = currEpisode.from == 'pugv';
|
||||||
return Column(
|
return Column(
|
||||||
@@ -101,10 +102,7 @@ class _PgcPanelState extends State<PgcPanel> {
|
|||||||
child: Text(
|
child: Text(
|
||||||
' 正在播放:${currEpisode.longTitle ?? currEpisode.title}',
|
' 正在播放:${currEpisode.longTitle ?? currEpisode.title}',
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
style: TextStyle(
|
style: TextStyle(fontSize: 12, color: theme.outline),
|
||||||
fontSize: 12,
|
|
||||||
color: theme.colorScheme.outline,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
@@ -149,12 +147,10 @@ class _PgcPanelState extends State<PgcPanel> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildItem(ThemeData theme, bool isPugv, int index) {
|
Widget _buildItem(ColorScheme theme, bool isPugv, int index) {
|
||||||
final item = widget.pages[index];
|
final item = widget.pages[index];
|
||||||
final hasLongTitle = item.longTitle?.isNotEmpty == true;
|
final hasLongTitle = item.longTitle?.isNotEmpty == true;
|
||||||
final color = index == currentIndex
|
final color = index == currentIndex ? theme.primary : theme.onSurface;
|
||||||
? theme.colorScheme.primary
|
|
||||||
: theme.colorScheme.onSurface;
|
|
||||||
return Container(
|
return Container(
|
||||||
width: 150,
|
width: 150,
|
||||||
height: 60,
|
height: 60,
|
||||||
@@ -162,7 +158,7 @@ class _PgcPanelState extends State<PgcPanel> {
|
|||||||
? const EdgeInsets.only(right: 10)
|
? const EdgeInsets.only(right: 10)
|
||||||
: null,
|
: null,
|
||||||
child: Material(
|
child: Material(
|
||||||
color: theme.colorScheme.onInverseSurface,
|
color: theme.onInverseSurface,
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(6)),
|
borderRadius: const BorderRadius.all(Radius.circular(6)),
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(6)),
|
borderRadius: const BorderRadius.all(Radius.circular(6)),
|
||||||
@@ -192,7 +188,7 @@ class _PgcPanelState extends State<PgcPanel> {
|
|||||||
padding: const EdgeInsets.only(right: 6),
|
padding: const EdgeInsets.only(right: 6),
|
||||||
child: Image.asset(
|
child: Image.asset(
|
||||||
'assets/images/live.png',
|
'assets/images/live.png',
|
||||||
color: theme.colorScheme.primary,
|
color: theme.primary,
|
||||||
height: 12,
|
height: 12,
|
||||||
semanticLabel: "正在播放:",
|
semanticLabel: "正在播放:",
|
||||||
),
|
),
|
||||||
@@ -222,7 +218,11 @@ class _PgcPanelState extends State<PgcPanel> {
|
|||||||
item.badge!,
|
item.badge!,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 11,
|
fontSize: 11,
|
||||||
color: theme.colorScheme.primary,
|
color: switch (item.badge) {
|
||||||
|
'限免' => theme.freeColor,
|
||||||
|
'预告' => theme.onSurfaceVariant,
|
||||||
|
_ => theme.primary,
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
|||||||
class WebDavSettingPage extends StatefulWidget {
|
class WebDavSettingPage extends StatefulWidget {
|
||||||
const WebDavSettingPage({
|
const WebDavSettingPage({
|
||||||
super.key,
|
super.key,
|
||||||
this.showAppBar,
|
this.showAppBar = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
final bool? showAppBar;
|
final bool showAppBar;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<WebDavSettingPage> createState() => _WebDavSettingPageState();
|
State<WebDavSettingPage> createState() => _WebDavSettingPageState();
|
||||||
@@ -38,7 +38,8 @@ class _WebDavSettingPageState extends State<WebDavSettingPage> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
EdgeInsets padding = MediaQuery.paddingOf(context);
|
EdgeInsets padding = MediaQuery.paddingOf(context);
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: widget.showAppBar == false
|
resizeToAvoidBottomInset: widget.showAppBar,
|
||||||
|
appBar: !widget.showAppBar
|
||||||
? null
|
? null
|
||||||
: AppBar(title: const Text('WebDAV 设置')),
|
: AppBar(title: const Text('WebDAV 设置')),
|
||||||
body: ListView(
|
body: ListView(
|
||||||
|
|||||||
@@ -38,6 +38,11 @@ class _WebviewPageState extends State<WebviewPage> {
|
|||||||
|
|
||||||
InAppWebViewController? _webViewController;
|
InAppWebViewController? _webViewController;
|
||||||
|
|
||||||
|
static final _prefixRegex = RegExp(
|
||||||
|
r'^(?!(https?://))\S+://',
|
||||||
|
caseSensitive: false,
|
||||||
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
@@ -298,10 +303,7 @@ class _WebviewPageState extends State<WebviewPage> {
|
|||||||
if (hasMatch) {
|
if (hasMatch) {
|
||||||
progress.value = 1;
|
progress.value = 1;
|
||||||
return NavigationActionPolicy.CANCEL;
|
return NavigationActionPolicy.CANCEL;
|
||||||
} else if (RegExp(
|
} else if (_prefixRegex.hasMatch(url)) {
|
||||||
r'^(?!(https?://))\S+://',
|
|
||||||
caseSensitive: false,
|
|
||||||
).hasMatch(url)) {
|
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
SnackBar snackBar = SnackBar(
|
SnackBar snackBar = SnackBar(
|
||||||
content: const Text('当前网页将要打开外部链接,是否打开'),
|
content: const Text('当前网页将要打开外部链接,是否打开'),
|
||||||
|
|||||||
@@ -85,6 +85,9 @@ extension StringExt on String? {
|
|||||||
extension ColorSchemeExt on ColorScheme {
|
extension ColorSchemeExt on ColorScheme {
|
||||||
Color get vipColor =>
|
Color get vipColor =>
|
||||||
brightness.isLight ? const Color(0xFFFF6699) : const Color(0xFFD44E7D);
|
brightness.isLight ? const Color(0xFFFF6699) : const Color(0xFFD44E7D);
|
||||||
|
|
||||||
|
Color get freeColor =>
|
||||||
|
brightness.isLight ? const Color(0xFFFF7F24) : const Color(0xFFD66011);
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Unique<E, Id> on List<E> {
|
extension Unique<E, Id> on List<E> {
|
||||||
|
|||||||
Reference in New Issue
Block a user