mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-08-24 17:31:06 +08:00

Instead of the legacy Provider.of. Less scope of bugs this way and the code is so much nicer to read.
99 lines
3.6 KiB
Dart
99 lines
3.6 KiB
Dart
/*
|
|
* SPDX-FileCopyrightText: 2020-2021 Roland Fredenhagen <important@van-fredenhagen.de>
|
|
* SPDX-FileCopyrightText: 2020-2021 Vishesh Handa <me@vhanda.in>
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:gitjournal/settings/markdown_renderer_config.dart';
|
|
import 'package:gitjournal/widgets/images/markdown_image.dart';
|
|
import 'package:gitjournal/widgets/images/themable_image.dart';
|
|
import 'package:photo_view/photo_view.dart';
|
|
import 'package:provider/provider.dart';
|
|
|
|
class ImageDetails extends StatefulWidget {
|
|
final ThemableImage image;
|
|
final String caption;
|
|
const ImageDetails(this.image, this.caption);
|
|
|
|
@override
|
|
_ImageDetailsState createState() => _ImageDetailsState();
|
|
}
|
|
|
|
class _ImageDetailsState extends State<ImageDetails> {
|
|
int _rotation = 0;
|
|
bool _showUI = true;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final theme = Theme.of(context);
|
|
final settings = context.watch<MarkdownRendererConfig>();
|
|
final bg =
|
|
theme.brightness == Brightness.dark ? Colors.black : Colors.white;
|
|
final overlayColor = getOverlayBackgroundColor(settings, theme,
|
|
light: Colors.white, dark: Colors.black);
|
|
return Stack(
|
|
children: [
|
|
PhotoView.customChild(
|
|
backgroundDecoration: BoxDecoration(color: bg),
|
|
minScale: 1.0,
|
|
maxScale: settings.maxImageZoom,
|
|
heroAttributes: PhotoViewHeroAttributes(tag: widget.image),
|
|
onTapUp: (context, details, controllerValue) =>
|
|
setState(() => _showUI = !_showUI),
|
|
enableRotation: settings.rotateImageGestures,
|
|
child: RotatedBox(
|
|
quarterTurns: _rotation,
|
|
child: ThemableImage.from(widget.image, bg: bg)),
|
|
),
|
|
if (_showUI)
|
|
Positioned(
|
|
top: MediaQuery.of(context).padding.top,
|
|
left: 0,
|
|
right: 0,
|
|
height: 60,
|
|
child: Material(
|
|
color: overlayColor,
|
|
child: Padding(
|
|
padding: const EdgeInsetsDirectional.fromSTEB(8, 0, 0, 0),
|
|
child: Row(
|
|
children: [
|
|
IconButton(
|
|
splashRadius: 20,
|
|
icon: const Icon(Icons.arrow_back),
|
|
onPressed: () => Navigator.pop(context)),
|
|
const Spacer(),
|
|
IconButton(
|
|
splashRadius: 20,
|
|
icon: const Icon(Icons.rotate_90_degrees_ccw),
|
|
onPressed: () => setState(() => _rotation--))
|
|
],
|
|
)))),
|
|
// TODO use a DraggableScrollableSheet, when they can be dynamically
|
|
// height restricted https://github.com/flutter/flutter/issues/41599
|
|
if (_showUI && widget.caption.isNotEmpty)
|
|
Positioned(
|
|
bottom: 0,
|
|
left: 0,
|
|
right: 0,
|
|
child: Hero(
|
|
tag: "caption",
|
|
child: Container(
|
|
color: overlayColor,
|
|
padding:
|
|
const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
|
child: ConstrainedBox(
|
|
constraints: const BoxConstraints(maxHeight: 200),
|
|
child: SingleChildScrollView(
|
|
child: Text(
|
|
widget.caption,
|
|
style: theme.primaryTextTheme.bodyLarge,
|
|
)),
|
|
),
|
|
)))
|
|
],
|
|
);
|
|
}
|
|
}
|