mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-05-14 21:24:02 +08:00
@@ -1,112 +0,0 @@
|
||||
import 'package:PiliPlus/common/style.dart';
|
||||
import 'package:PiliPlus/pages/home/controller.dart';
|
||||
import 'package:PiliPlus/pages/main/controller.dart';
|
||||
import 'package:flutter/foundation.dart' show clampDouble;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
abstract class CommonPageState<T extends StatefulWidget> extends State<T> {
|
||||
RxDouble? _barOffset;
|
||||
RxBool? _showTopBar;
|
||||
RxBool? _showBottomBar;
|
||||
final _mainController = Get.find<MainController>();
|
||||
|
||||
bool get needsCorrection => false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_barOffset = _mainController.barOffset;
|
||||
_showBottomBar = _mainController.showBottomBar;
|
||||
try {
|
||||
_showTopBar = Get.find<HomeController>().showTopBar;
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
Widget onBuild(Widget child) {
|
||||
if (_barOffset != null) {
|
||||
return NotificationListener<ScrollNotification>(
|
||||
onNotification: onNotificationType2,
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
if (_showTopBar != null || _showBottomBar != null) {
|
||||
return NotificationListener<UserScrollNotification>(
|
||||
onNotification: onNotificationType1,
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
||||
bool onNotificationType1(UserScrollNotification notification) {
|
||||
if (!_mainController.useBottomNav) return false;
|
||||
if (notification.metrics.axis == .horizontal) return false;
|
||||
switch (notification.direction) {
|
||||
case .forward:
|
||||
_showTopBar?.value = true;
|
||||
_showBottomBar?.value = true;
|
||||
case .reverse:
|
||||
_showTopBar?.value = false;
|
||||
_showBottomBar?.value = false;
|
||||
case _:
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void _updateOffset(double scrollDelta) {
|
||||
_barOffset!.value = clampDouble(
|
||||
_barOffset!.value + scrollDelta,
|
||||
0.0,
|
||||
Style.topBarHeight,
|
||||
);
|
||||
}
|
||||
|
||||
bool onNotificationType2(ScrollNotification notification) {
|
||||
if (!_mainController.useBottomNav) return false;
|
||||
|
||||
final metrics = notification.metrics;
|
||||
if (metrics.axis == .horizontal) return false;
|
||||
|
||||
if (notification is ScrollUpdateNotification) {
|
||||
if (notification.dragDetails == null) return false;
|
||||
final pixel = metrics.pixels;
|
||||
final scrollDelta = notification.scrollDelta ?? 0;
|
||||
if (pixel < 0.0 && scrollDelta > 0) return false;
|
||||
if (needsCorrection) {
|
||||
final value = _barOffset!.value;
|
||||
final newValue = clampDouble(
|
||||
value + scrollDelta,
|
||||
0.0,
|
||||
Style.topBarHeight,
|
||||
);
|
||||
final offset = value - newValue;
|
||||
if (offset != 0) {
|
||||
_barOffset!.value = newValue;
|
||||
if (pixel < 0.0 && scrollDelta < 0.0 && value > 0.0) {
|
||||
return false;
|
||||
}
|
||||
Scrollable.of(notification.context!).position.correctBy(offset);
|
||||
}
|
||||
} else {
|
||||
_updateOffset(scrollDelta);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (notification is OverscrollNotification) {
|
||||
_updateOffset(notification.overscroll);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_barOffset = null;
|
||||
_showTopBar = null;
|
||||
_showBottomBar = null;
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
@@ -14,13 +14,11 @@ abstract class CommonDynController extends ReplyController<MainListReply> {
|
||||
late final horizontalPreview = Pref.horizontalPreview;
|
||||
late final List<double> ratio = Pref.dynamicDetailRatio;
|
||||
|
||||
late final showDynActionBar = Pref.showDynActionBar;
|
||||
|
||||
@override
|
||||
Future<LoadingState<MainListReply>> customGetData() => ReplyGrpc.mainList(
|
||||
type: replyType,
|
||||
oid: oid,
|
||||
mode: mode.value,
|
||||
mode: mode,
|
||||
cursorNext: cursorNext,
|
||||
offset: paginationReply?.nextOffset,
|
||||
);
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:PiliPlus/common/skeleton/video_reply.dart';
|
||||
import 'package:PiliPlus/common/style.dart';
|
||||
import 'package:PiliPlus/common/widgets/custom_icon.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||
import 'package:PiliPlus/common/widgets/scaffold.dart';
|
||||
import 'package:PiliPlus/common/widgets/sliver/sliver_pinned_header.dart';
|
||||
import 'package:PiliPlus/common/widgets/view_safe_area.dart';
|
||||
import 'package:PiliPlus/grpc/bilibili/main/community/reply/v1.pb.dart'
|
||||
@@ -190,8 +191,7 @@ abstract class CommonDynPageState<T extends StatefulWidget> extends State<T>
|
||||
),
|
||||
);
|
||||
if (showBackBtn) {
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
return scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('评论详情'),
|
||||
shape: Border(
|
||||
@@ -269,16 +269,6 @@ abstract class CommonDynPageState<T extends StatefulWidget> extends State<T>
|
||||
icon: const Icon(CustomIcons.splitscreen_rotate_90, size: 19),
|
||||
);
|
||||
|
||||
FloatingActionButtonLocation get floatingActionButtonLocation =>
|
||||
controller.showDynActionBar
|
||||
? const ActionBarLocation()
|
||||
: const NoBottomPaddingFabLocation();
|
||||
|
||||
Widget get fabButton => Padding(
|
||||
padding: .only(bottom: padding.bottom + kFloatingActionButtonMargin),
|
||||
child: replyButton,
|
||||
);
|
||||
|
||||
Widget get replyButton => FloatingActionButton(
|
||||
heroTag: null,
|
||||
onPressed: () {
|
||||
|
||||
@@ -40,39 +40,3 @@ mixin FabMixin<T extends StatefulWidget> on State<T>, TickerProvider {
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
mixin _NoRightMarginMixin on StandardFabLocation {
|
||||
@override
|
||||
double getOffsetX(scaffoldGeometry, _) {
|
||||
return scaffoldGeometry.scaffoldSize.width -
|
||||
scaffoldGeometry.minInsets.right -
|
||||
scaffoldGeometry.floatingActionButtonSize.width;
|
||||
}
|
||||
}
|
||||
|
||||
mixin _NoBottomPaddingMixin on StandardFabLocation {
|
||||
@override
|
||||
double getOffsetY(scaffoldGeometry, _) {
|
||||
return scaffoldGeometry.contentBottom -
|
||||
scaffoldGeometry.floatingActionButtonSize.height;
|
||||
}
|
||||
}
|
||||
|
||||
class NoRightMarginFabLocation extends StandardFabLocation
|
||||
with FabFloatOffsetY, _NoRightMarginMixin {
|
||||
const NoRightMarginFabLocation();
|
||||
}
|
||||
|
||||
class NoBottomPaddingFabLocation extends StandardFabLocation
|
||||
with FabEndOffsetX, _NoBottomPaddingMixin {
|
||||
const NoBottomPaddingFabLocation();
|
||||
}
|
||||
|
||||
class ActionBarLocation extends StandardFabLocation with _NoBottomPaddingMixin {
|
||||
const ActionBarLocation();
|
||||
|
||||
@override
|
||||
double getOffsetX(scaffoldGeometry, _) {
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import 'dart:math' show max;
|
||||
|
||||
import 'package:PiliPlus/models/common/publish_panel_type.dart';
|
||||
import 'package:PiliPlus/utils/extension/context_ext.dart';
|
||||
import 'package:PiliPlus/utils/storage_pref.dart';
|
||||
import 'package:chat_bottom_container/chat_bottom_container.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
@@ -28,9 +27,7 @@ abstract class CommonPublishPageState<T extends CommonPublishPage>
|
||||
extends State<T>
|
||||
with WidgetsBindingObserver {
|
||||
late final FocusNode focusNode;
|
||||
late final controller = ChatBottomPanelContainerController<PanelType>(
|
||||
uiScale: Pref.uiScale,
|
||||
);
|
||||
late final controller = ChatBottomPanelContainerController<PanelType>();
|
||||
TextEditingController get editController;
|
||||
|
||||
final Rx<PanelType> panelType = PanelType.none.obs;
|
||||
|
||||
@@ -9,7 +9,6 @@ import 'package:PiliPlus/pages/common/common_list_controller.dart';
|
||||
import 'package:PiliPlus/pages/common/publish/publish_route.dart';
|
||||
import 'package:PiliPlus/pages/video/reply_new/view.dart';
|
||||
import 'package:PiliPlus/utils/reply_utils.dart';
|
||||
import 'package:PiliPlus/utils/storage_pref.dart';
|
||||
import 'package:fixnum/fixnum.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
@@ -18,8 +17,8 @@ import 'package:get/get.dart';
|
||||
abstract class ReplyController<R> extends CommonListController<R, ReplyInfo> {
|
||||
final RxInt count = (-1).obs;
|
||||
|
||||
late final Rx<ReplySortType> sortType;
|
||||
late final Rx<Mode> mode;
|
||||
late final Rx<ReplySortType> sortType = Rx(.hot);
|
||||
Mode mode = Mode.MAIN_LIST_HOT;
|
||||
|
||||
final savedReplies = <Object, List<RichTextItem>?>{};
|
||||
|
||||
@@ -32,22 +31,6 @@ abstract class ReplyController<R> extends CommonListController<R, ReplyInfo> {
|
||||
@override
|
||||
bool? get hasFooter => true;
|
||||
|
||||
// comment antifraud
|
||||
late final _enableCommAntifraud = Pref.enableCommAntifraud;
|
||||
late final _biliSendCommAntifraud = Pref.biliSendCommAntifraud;
|
||||
bool get enableCommAntifraud =>
|
||||
_enableCommAntifraud || _biliSendCommAntifraud;
|
||||
dynamic get sourceId;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
final cacheSortType = Pref.replySortType;
|
||||
sortType = cacheSortType.obs;
|
||||
mode =
|
||||
(cacheSortType == .time ? Mode.MAIN_LIST_TIME : Mode.MAIN_LIST_HOT).obs;
|
||||
}
|
||||
|
||||
@override
|
||||
void checkIsEnd(int length) {
|
||||
final count = this.count.value;
|
||||
@@ -89,15 +72,15 @@ abstract class ReplyController<R> extends CommonListController<R, ReplyInfo> {
|
||||
void queryBySort() {
|
||||
if (isLoading) return;
|
||||
switch (sortType.value) {
|
||||
case ReplySortType.time:
|
||||
sortType.value = ReplySortType.hot;
|
||||
mode.value = Mode.MAIN_LIST_HOT;
|
||||
case .time:
|
||||
sortType.value = .hot;
|
||||
mode = Mode.MAIN_LIST_HOT;
|
||||
break;
|
||||
case ReplySortType.hot:
|
||||
sortType.value = ReplySortType.time;
|
||||
mode.value = Mode.MAIN_LIST_TIME;
|
||||
case .hot:
|
||||
sortType.value = .time;
|
||||
mode = Mode.MAIN_LIST_TIME;
|
||||
break;
|
||||
case ReplySortType.select:
|
||||
case .select:
|
||||
return;
|
||||
}
|
||||
onReload();
|
||||
@@ -193,9 +176,7 @@ abstract class ReplyController<R> extends CommonListController<R, ReplyInfo> {
|
||||
count.value += 1;
|
||||
|
||||
// check reply
|
||||
if (enableCommAntifraud) {
|
||||
onCheckReply(replyInfo, isManual: false);
|
||||
}
|
||||
onCheckReply(replyInfo, isManual: false);
|
||||
}
|
||||
},
|
||||
);
|
||||
@@ -216,8 +197,6 @@ abstract class ReplyController<R> extends CommonListController<R, ReplyInfo> {
|
||||
void onCheckReply(ReplyInfo replyInfo, {required bool isManual}) {
|
||||
ReplyUtils.onCheckReply(
|
||||
replyInfo: replyInfo,
|
||||
biliSendCommAntifraud: _biliSendCommAntifraud,
|
||||
sourceId: sourceId,
|
||||
isManual: isManual,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:PiliPlus/common/widgets/appbar/appbar.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/pop_scope.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||
import 'package:PiliPlus/common/widgets/scaffold.dart';
|
||||
import 'package:PiliPlus/common/widgets/view_sliver_safe_area.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/pages/common/multi_select/base.dart';
|
||||
@@ -36,7 +37,7 @@ abstract class CommonSearchPageState<S extends StatefulWidget, R, T>
|
||||
}
|
||||
|
||||
Widget _build(bool multiSelect) {
|
||||
return Scaffold(
|
||||
return scaffold(
|
||||
appBar: _buildBar(multiSelect),
|
||||
body: CustomScrollView(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
|
||||
Reference in New Issue
Block a user