mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-02-02 14:56:20 +01:00
Show an indicator when the button bar can be scrolled in detail pane
This commit is contained in:
parent
b91a8f9e06
commit
b660126f60
1 changed files with 135 additions and 55 deletions
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue