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