opt fab location

Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
dom
2026-03-16 10:12:36 +08:00
parent e04affd0fe
commit ed66a4655b
18 changed files with 556 additions and 619 deletions

View File

@@ -6,11 +6,9 @@ import 'package:PiliPlus/models/common/video/video_type.dart';
import 'package:PiliPlus/pages/common/reply_controller.dart';
import 'package:PiliPlus/pages/video/controller.dart';
import 'package:PiliPlus/utils/id_utils.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class VideoReplyController extends ReplyController<MainListReply>
with GetSingleTickerProviderStateMixin {
class VideoReplyController extends ReplyController<MainListReply> {
VideoReplyController({
required this.aid,
required this.videoType,
@@ -26,39 +24,6 @@ class VideoReplyController extends ReplyController<MainListReply>
@override
dynamic get sourceId => IdUtils.av2bv(aid);
bool _isFabVisible = true;
late final AnimationController _fabAnimationCtr;
late final Animation<Offset> animation;
@override
void onInit() {
super.onInit();
_fabAnimationCtr = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 100),
)..forward();
animation = _fabAnimationCtr.drive(
Tween<Offset>(
begin: const Offset(0.0, 2.0),
end: Offset.zero,
).chain(CurveTween(curve: Curves.easeInOut)),
);
}
void showFab() {
if (!_isFabVisible) {
_isFabVisible = true;
_fabAnimationCtr.forward();
}
}
void hideFab() {
if (_isFabVisible) {
_isFabVisible = false;
_fabAnimationCtr.reverse();
}
}
@override
List<ReplyInfo>? getDataList(MainListReply response) {
return response.replies;
@@ -72,10 +37,4 @@ class VideoReplyController extends ReplyController<MainListReply>
cursorNext: cursorNext,
offset: paginationReply?.nextOffset,
);
@override
void onClose() {
_fabAnimationCtr.dispose();
super.onClose();
}
}

View File

@@ -6,6 +6,7 @@ import 'package:PiliPlus/common/widgets/sliver/sliver_floating_header.dart';
import 'package:PiliPlus/grpc/bilibili/main/community/reply/v1.pb.dart'
show ReplyInfo;
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/pages/common/fab_mixin.dart';
import 'package:PiliPlus/pages/video/reply/controller.dart';
import 'package:PiliPlus/pages/video/reply/widgets/reply_item_grpc.dart';
import 'package:PiliPlus/pages/video/reply_reply/view.dart';
@@ -13,7 +14,6 @@ import 'package:PiliPlus/utils/feed_back.dart';
import 'package:easy_debounce/easy_throttle.dart';
import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:get/get.dart';
class VideoReplyPanel extends StatefulWidget {
@@ -33,7 +33,10 @@ class VideoReplyPanel extends StatefulWidget {
}
class _VideoReplyPanelState extends State<VideoReplyPanel>
with AutomaticKeepAliveClientMixin {
with
AutomaticKeepAliveClientMixin,
SingleTickerProviderStateMixin,
FabMixin {
late VideoReplyController _videoReplyController;
String get heroTag => widget.heroTag;
@@ -64,11 +67,12 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
final theme = Theme.of(context);
final child = NotificationListener<UserScrollNotification>(
onNotification: (notification) {
final direction = notification.direction;
if (direction == ScrollDirection.forward) {
_videoReplyController.showFab();
} else if (direction == ScrollDirection.reverse) {
_videoReplyController.hideFab();
switch (notification.direction) {
case .forward:
showFab();
case .reverse:
hideFab();
case _:
}
return false;
},
@@ -129,22 +133,28 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
],
),
Positioned(
right: kFloatingActionButtonMargin,
bottom: kFloatingActionButtonMargin + bottom,
right: 0,
bottom: 0,
child: SlideTransition(
position: _videoReplyController.animation,
child: FloatingActionButton(
heroTag: null,
onPressed: () {
feedBack();
_videoReplyController.onReply(
null,
oid: _videoReplyController.aid,
replyType: _videoReplyController.videoType.replyType,
);
},
tooltip: '发表评论',
child: const Icon(Icons.reply),
position: fabAnimation,
child: Padding(
padding: .only(
right: kFloatingActionButtonMargin,
bottom: kFloatingActionButtonMargin + bottom,
),
child: FloatingActionButton(
heroTag: null,
onPressed: () {
feedBack();
_videoReplyController.onReply(
null,
oid: _videoReplyController.aid,
replyType: _videoReplyController.videoType.replyType,
);
},
tooltip: '发表评论',
child: const Icon(Icons.reply),
),
),
),
),