Show an indicator when the button bar can be scrolled in detail pane

This commit is contained in:
Ming Ming 2024-06-22 02:22:32 +08:00
parent b91a8f9e06
commit b660126f60

View file

@ -94,11 +94,21 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
DiContainer.has(c, DiType.albumRepo); DiContainer.has(c, DiType.albumRepo);
@override @override
initState() { void initState() {
_log.info("[initState] File: ${widget.fd.fdPath}"); _log.info("[initState] File: ${widget.fd.fdPath}");
super.initState(); super.initState();
_dateTime = widget.fd.fdDateTime.toLocal(); _dateTime = widget.fd.fdDateTime.toLocal();
_initFile(); _initFile();
_buttonScrollController.addListener(
() => _updateButtonScroll(_buttonScrollController.position));
_ensureUpdateButtonScroll();
}
@override
void dispose() {
_buttonScrollController.dispose();
super.dispose();
} }
Future<void> _initFile() async { Future<void> _initFile() async {
@ -138,7 +148,7 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
} }
@override @override
build(BuildContext context) { Widget build(BuildContext context) {
final dateStr = DateFormat(DateFormat.YEAR_ABBR_MONTH_DAY, final dateStr = DateFormat(DateFormat.YEAR_ABBR_MONTH_DAY,
Localizations.localeOf(context).languageCode) Localizations.localeOf(context).languageCode)
.format(_dateTime); .format(_dateTime);
@ -163,8 +173,25 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
children: [ children: [
if (_file != null) ...[ if (_file != null) ...[
const SizedBox(height: 8), const SizedBox(height: 8),
Stack(
children: [
if (_hasLeftButton)
const Positioned(
left: 0,
top: 0,
bottom: 0,
child: Icon(Icons.keyboard_arrow_left),
),
if (_hasRightButton)
const Positioned(
right: 0,
top: 0,
bottom: 0,
child: Icon(Icons.keyboard_arrow_right),
),
SingleChildScrollView( SingleChildScrollView(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
controller: _buttonScrollController,
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -219,6 +246,8 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
], ],
), ),
), ),
],
),
const Padding( const Padding(
padding: EdgeInsets.symmetric(horizontal: 32), padding: EdgeInsets.symmetric(horizontal: 32),
child: Divider(), child: Divider(),
@ -501,6 +530,52 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
}); });
} }
bool _updateButtonScroll(ScrollPosition pos) {
if (!pos.hasContentDimensions || !pos.hasPixels) {
return false;
}
if (pos.pixels <= pos.minScrollExtent) {
if (_hasLeftButton) {
setState(() {
_hasLeftButton = false;
});
}
} else {
if (!_hasLeftButton) {
setState(() {
_hasLeftButton = true;
});
}
}
if (pos.pixels >= pos.maxScrollExtent) {
if (_hasRightButton) {
setState(() {
_hasRightButton = false;
});
}
} else {
if (!_hasRightButton) {
setState(() {
_hasRightButton = true;
});
}
}
_hasFirstButtonScrollUpdate = true;
return true;
}
void _ensureUpdateButtonScroll() {
if (_hasFirstButtonScrollUpdate || !mounted) {
return;
}
if (_buttonScrollController.hasClients) {
if (_updateButtonScroll(_buttonScrollController.position)) {
return;
}
}
Timer(const Duration(milliseconds: 100), _ensureUpdateButtonScroll);
}
late final DiContainer _c; late final DiContainer _c;
File? _file; File? _file;
@ -527,6 +602,11 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
CollectionAdapter.of(_c, widget.account, d.collection) CollectionAdapter.of(_c, widget.account, d.collection)
.isPermitted(CollectionCapability.manualCover)) ?? .isPermitted(CollectionCapability.manualCover)) ??
false; false;
late final _buttonScrollController = ScrollController();
var _hasFirstButtonScrollUpdate = false;
var _hasLeftButton = false;
var _hasRightButton = false;
} }
class _DetailPaneButton extends StatelessWidget { class _DetailPaneButton extends StatelessWidget {