Add photo view for thumbnails, emotes, and badges (#372)
* Add photo view for emotes and badges * Add photo view to stream thumbnails * Remove dismissable and use close button * Use cached network image provider * Add dismissible
This commit is contained in:
parent
3de9eb8351
commit
a5cc7d8f3f
5 changed files with 74 additions and 2 deletions
|
|
@ -10,6 +10,7 @@ import 'package:frosty/screens/channel/chat/stores/chat_assets_store.dart';
|
||||||
import 'package:frosty/screens/settings/stores/settings_store.dart';
|
import 'package:frosty/screens/settings/stores/settings_store.dart';
|
||||||
import 'package:frosty/utils.dart';
|
import 'package:frosty/utils.dart';
|
||||||
import 'package:frosty/widgets/cached_image.dart';
|
import 'package:frosty/widgets/cached_image.dart';
|
||||||
|
import 'package:frosty/widgets/photo_view.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
|
|
@ -695,7 +696,13 @@ class IRCMessage {
|
||||||
primary: false,
|
primary: false,
|
||||||
children: [
|
children: [
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: leading,
|
leading: InkWell(
|
||||||
|
onTap: () => showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => FrostyPhotoViewDialog(imageUrl: url),
|
||||||
|
),
|
||||||
|
child: leading,
|
||||||
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
title,
|
title,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import 'package:frosty/utils.dart';
|
||||||
import 'package:frosty/widgets/block_report_modal.dart';
|
import 'package:frosty/widgets/block_report_modal.dart';
|
||||||
import 'package:frosty/widgets/cached_image.dart';
|
import 'package:frosty/widgets/cached_image.dart';
|
||||||
import 'package:frosty/widgets/loading_indicator.dart';
|
import 'package:frosty/widgets/loading_indicator.dart';
|
||||||
|
import 'package:frosty/widgets/photo_view.dart';
|
||||||
import 'package:frosty/widgets/profile_picture.dart';
|
import 'package:frosty/widgets/profile_picture.dart';
|
||||||
import 'package:frosty/widgets/uptime.dart';
|
import 'package:frosty/widgets/uptime.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
@ -72,7 +73,19 @@ class StreamCard extends StatelessWidget {
|
||||||
child: Stack(
|
child: Stack(
|
||||||
alignment: AlignmentDirectional.bottomEnd,
|
alignment: AlignmentDirectional.bottomEnd,
|
||||||
children: [
|
children: [
|
||||||
thumbnail,
|
GestureDetector(
|
||||||
|
onLongPress: () => showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => FrostyPhotoViewDialog(
|
||||||
|
imageUrl: streamInfo.thumbnailUrl.replaceFirst(
|
||||||
|
'-{width}x{height}',
|
||||||
|
'',
|
||||||
|
) +
|
||||||
|
cacheUrlExtension,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: thumbnail,
|
||||||
|
),
|
||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2),
|
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2),
|
||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
|
|
|
||||||
43
lib/widgets/photo_view.dart
Normal file
43
lib/widgets/photo_view.dart
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:photo_view/photo_view.dart';
|
||||||
|
|
||||||
|
class FrostyPhotoViewDialog extends StatefulWidget {
|
||||||
|
final String imageUrl;
|
||||||
|
|
||||||
|
const FrostyPhotoViewDialog({super.key, required this.imageUrl});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<FrostyPhotoViewDialog> createState() => _FrostyPhotoViewDialogState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _FrostyPhotoViewDialogState extends State<FrostyPhotoViewDialog> {
|
||||||
|
PhotoViewScaleState photoViewScaleState = PhotoViewScaleState.initial;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Stack(
|
||||||
|
alignment: Alignment.topCenter,
|
||||||
|
children: [
|
||||||
|
Dismissible(
|
||||||
|
key: const Key('photo_view_dismissible'),
|
||||||
|
direction: photoViewScaleState == PhotoViewScaleState.initial
|
||||||
|
? DismissDirection.vertical
|
||||||
|
: DismissDirection.none,
|
||||||
|
onDismissed: Navigator.of(context).pop,
|
||||||
|
child: PhotoView(
|
||||||
|
imageProvider: CachedNetworkImageProvider(widget.imageUrl),
|
||||||
|
scaleStateChangedCallback: (value) =>
|
||||||
|
setState(() => photoViewScaleState = value),
|
||||||
|
backgroundDecoration:
|
||||||
|
const BoxDecoration(color: Colors.transparent),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.close, color: Colors.white),
|
||||||
|
onPressed: Navigator.of(context).pop,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -837,6 +837,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.2"
|
version: "6.0.2"
|
||||||
|
photo_view:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: photo_view
|
||||||
|
sha256: "1fc3d970a91295fbd1364296575f854c9863f225505c28c46e0a03e48960c75e"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.15.0"
|
||||||
platform:
|
platform:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ dependencies:
|
||||||
advanced_in_app_review: ^1.1.3
|
advanced_in_app_review: ^1.1.3
|
||||||
webview_flutter_android: ^3.7.0
|
webview_flutter_android: ^3.7.0
|
||||||
webview_flutter_wkwebview: ^3.4.3
|
webview_flutter_wkwebview: ^3.4.3
|
||||||
|
photo_view: ^0.15.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue