opt: slide gesture

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-03-02 13:59:45 +08:00
parent 4735297285
commit a9f9b324a9

View File

@@ -123,6 +123,49 @@ class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return GStorage.slideDismissReplyPage return GStorage.slideDismissReplyPage
? Padding(
padding: EdgeInsets.only(top: padding.value),
child: _buildPage,
)
: _buildPage;
}
Widget get _buildPage => Scaffold(
key: _key,
resizeToAvoidBottomInset: false,
body: Column(
children: [
widget.source == 'videoDetail'
? Container(
height: 45,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
width: 1,
color:
Theme.of(context).dividerColor.withOpacity(0.1),
),
),
),
padding: const EdgeInsets.only(left: 12, right: 2),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(widget.isDialogue ? '对话列表' : '评论详情'),
IconButton(
tooltip: '关闭',
icon: const Icon(Icons.close, size: 20),
onPressed: Get.back,
),
],
),
)
: Divider(
height: 1,
color: Theme.of(context).dividerColor.withOpacity(0.1),
),
Expanded(
child: GStorage.slideDismissReplyPage
? GestureDetector( ? GestureDetector(
onPanDown: (event) { onPanDown: (event) {
if (event.localPosition.dx > 30) { if (event.localPosition.dx > 30) {
@@ -136,8 +179,10 @@ class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel>
return; return;
} else if (_isSliding == null) { } else if (_isSliding == null) {
if (_downPos != null) { if (_downPos != null) {
Offset cumulativeDelta = event.localPosition - _downPos!; Offset cumulativeDelta =
if (cumulativeDelta.dx.abs() >= cumulativeDelta.dy.abs()) { event.localPosition - _downPos!;
if (cumulativeDelta.dx.abs() >=
cumulativeDelta.dy.abs()) {
_isSliding = true; _isSliding = true;
setState(() { setState(() {
padding.value = event.localPosition.dx; padding.value = event.localPosition.dx;
@@ -178,50 +223,15 @@ class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel>
_downPos = null; _downPos = null;
_isSliding = null; _isSliding = null;
}, },
child: Padding( child: _buildList,
padding: EdgeInsets.only(top: padding.value),
child: _buildPage,
),
) )
: _buildPage; : _buildList,
}
Widget get _buildPage => Scaffold(
key: _key,
resizeToAvoidBottomInset: false,
body: Column(
children: [
widget.source == 'videoDetail'
? Container(
height: 45,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
width: 1,
color:
Theme.of(context).dividerColor.withOpacity(0.1),
),
),
),
padding: const EdgeInsets.only(left: 12, right: 2),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(widget.isDialogue ? '对话列表' : '评论详情'),
IconButton(
tooltip: '关闭',
icon: const Icon(Icons.close, size: 20),
onPressed: Get.back,
), ),
], ],
), ),
) );
: Divider(
height: 1, Widget get _buildList => ClipRect(
color: Theme.of(context).dividerColor.withOpacity(0.1),
),
Expanded(
child: ClipRect(
child: refreshIndicator( child: refreshIndicator(
onRefresh: () async { onRefresh: () async {
await _videoReplyReplyController.onRefresh(); await _videoReplyReplyController.onRefresh();
@@ -232,16 +242,15 @@ class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel>
ScrollablePositionedList.builder( ScrollablePositionedList.builder(
key: _listKey, key: _listKey,
itemPositionsListener: itemPositionsListener, itemPositionsListener: itemPositionsListener,
itemCount: _itemCount( itemCount:
_videoReplyReplyController.loadingState.value), _itemCount(_videoReplyReplyController.loadingState.value),
itemScrollController: itemScrollController:
_videoReplyReplyController.itemScrollCtr, _videoReplyReplyController.itemScrollCtr,
physics: const AlwaysScrollableScrollPhysics(), physics: const AlwaysScrollableScrollPhysics(),
itemBuilder: (context, index) { itemBuilder: (context, index) {
if (widget.isDialogue) { if (widget.isDialogue) {
return _buildBody( return _buildBody(
_videoReplyReplyController.loadingState.value, _videoReplyReplyController.loadingState.value, index);
index);
} else if (firstFloor != null) { } else if (firstFloor != null) {
if (index == 0) { if (index == 0) {
return GlobalData().grpcReply return GlobalData().grpcReply
@@ -276,17 +285,15 @@ class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel>
} else if (index == 1) { } else if (index == 1) {
return Divider( return Divider(
height: 20, height: 20,
color: Theme.of(context) color:
.dividerColor Theme.of(context).dividerColor.withOpacity(0.1),
.withOpacity(0.1),
thickness: 6, thickness: 6,
); );
} else if (index == 2) { } else if (index == 2) {
return _sortWidget; return _sortWidget;
} else { } else {
return _buildBody( return _buildBody(
_videoReplyReplyController _videoReplyReplyController.loadingState.value,
.loadingState.value,
index - 3); index - 3);
} }
} else { } else {
@@ -294,25 +301,19 @@ class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel>
return _sortWidget; return _sortWidget;
} else { } else {
return _buildBody( return _buildBody(
_videoReplyReplyController _videoReplyReplyController.loadingState.value,
.loadingState.value,
index - 1); index - 1);
} }
} }
}, },
), ),
if (!widget.isDialogue && if (!widget.isDialogue &&
_videoReplyReplyController.loadingState.value _videoReplyReplyController.loadingState.value is Success)
is Success)
_header, _header,
], ],
), ),
), ),
), ),
),
),
],
),
); );
Widget get _sortWidget => Container( Widget get _sortWidget => Container(