✨ Detailed attachments
This commit is contained in:
37
lib/widgets/attachment/attachment_detail.dart
Normal file
37
lib/widgets/attachment/attachment_detail.dart
Normal file
@ -0,0 +1,37 @@
|
||||
import 'package:dismissible_page/dismissible_page.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:photo_view/photo_view.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:surface/providers/sn_network.dart';
|
||||
import 'package:surface/types/attachment.dart';
|
||||
import 'package:surface/widgets/universal_image.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
class AttachmentDetailPopup extends StatelessWidget {
|
||||
final SnAttachment data;
|
||||
final String? heroTag;
|
||||
const AttachmentDetailPopup({super.key, required this.data, this.heroTag});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final sn = context.read<SnNetworkProvider>();
|
||||
final uuid = Uuid();
|
||||
|
||||
return DismissiblePage(
|
||||
onDismissed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
direction: DismissiblePageDismissDirection.down,
|
||||
backgroundColor: Colors.transparent,
|
||||
isFullScreen: true,
|
||||
child: Hero(
|
||||
tag: 'attachment-${data.rid}-${heroTag ?? uuid.v4()}',
|
||||
child: PhotoView(
|
||||
imageProvider: UniversalImage.provider(
|
||||
sn.getAttachmentUrl(data.rid),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,25 +1,55 @@
|
||||
import 'package:dismissible_page/dismissible_page.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:surface/providers/sn_network.dart';
|
||||
import 'package:surface/types/attachment.dart';
|
||||
import 'package:surface/widgets/attachment/attachment_detail.dart';
|
||||
import 'package:surface/widgets/universal_image.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
class AttachmentItem extends StatelessWidget {
|
||||
final SnAttachment data;
|
||||
const AttachmentItem({super.key, required this.data});
|
||||
final bool isExpandable;
|
||||
const AttachmentItem({
|
||||
super.key,
|
||||
required this.data,
|
||||
this.isExpandable = false,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget _buildContent(BuildContext context, String heroTag) {
|
||||
final tp = data.mimetype.split('/').firstOrNull;
|
||||
final sn = context.read<SnNetworkProvider>();
|
||||
switch (tp) {
|
||||
case 'image':
|
||||
return UniversalImage(
|
||||
sn.getAttachmentUrl(data.rid),
|
||||
fit: BoxFit.cover,
|
||||
return Hero(
|
||||
tag: 'attachment-${data.rid}-$heroTag',
|
||||
child: UniversalImage(
|
||||
sn.getAttachmentUrl(data.rid),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
);
|
||||
default:
|
||||
return const Placeholder();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final uuid = Uuid();
|
||||
final heroTag = uuid.v4();
|
||||
|
||||
if (isExpandable) {
|
||||
return GestureDetector(
|
||||
child: _buildContent(context, heroTag),
|
||||
onTap: () {
|
||||
context.pushTransparentRoute(
|
||||
AttachmentDetailPopup(data: data, heroTag: heroTag),
|
||||
rootNavigator: true,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
return _buildContent(context, heroTag);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:responsive_framework/responsive_framework.dart';
|
||||
import 'package:surface/types/attachment.dart';
|
||||
import 'package:surface/widgets/attachment/attachment_item.dart';
|
||||
|
||||
@ -15,6 +18,10 @@ class AttachmentList extends StatelessWidget {
|
||||
this.maxListHeight,
|
||||
});
|
||||
|
||||
static const double kMaxListItemWidth = 520;
|
||||
static const BorderRadius kDefaultRadius =
|
||||
BorderRadius.all(Radius.circular(8));
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final borderSide = (bordered ?? false)
|
||||
@ -23,11 +30,36 @@ class AttachmentList extends StatelessWidget {
|
||||
|
||||
if (data.isEmpty) return const SizedBox.shrink();
|
||||
if (data.length == 1) {
|
||||
if (ResponsiveBreakpoints.of(context).largerThan(MOBILE)) {
|
||||
return Container(
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: math.min(
|
||||
MediaQuery.of(context).size.width - 20,
|
||||
kMaxListItemWidth,
|
||||
),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
border: Border(top: borderSide, bottom: borderSide),
|
||||
borderRadius: kDefaultRadius,
|
||||
),
|
||||
child: AspectRatio(
|
||||
aspectRatio: data[0].metadata['ratio']?.toDouble() ?? 1,
|
||||
child: ClipRRect(
|
||||
borderRadius: kDefaultRadius,
|
||||
child: AttachmentItem(data: data[0], isExpandable: true),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border(top: borderSide, bottom: borderSide),
|
||||
),
|
||||
child: AttachmentItem(data: data[0]),
|
||||
child: AspectRatio(
|
||||
aspectRatio: data[0].metadata['ratio']?.toDouble() ?? 1,
|
||||
child: AttachmentItem(data: data[0], isExpandable: true),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -39,20 +71,22 @@ class AttachmentList extends StatelessWidget {
|
||||
shrinkWrap: true,
|
||||
itemCount: data.length,
|
||||
itemBuilder: (context, idx) {
|
||||
const radius = BorderRadius.all(Radius.circular(8));
|
||||
return Container(
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: MediaQuery.of(context).size.width - 20,
|
||||
maxWidth: math.min(
|
||||
MediaQuery.of(context).size.width - 20,
|
||||
kMaxListItemWidth,
|
||||
),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
border: Border(top: borderSide, bottom: borderSide),
|
||||
borderRadius: radius,
|
||||
borderRadius: kDefaultRadius,
|
||||
),
|
||||
child: AspectRatio(
|
||||
aspectRatio: data[idx].metadata['ratio']?.toDouble() ?? 1,
|
||||
child: ClipRRect(
|
||||
borderRadius: radius,
|
||||
child: AttachmentItem(data: data[idx]),
|
||||
borderRadius: kDefaultRadius,
|
||||
child: AttachmentItem(data: data[idx], isExpandable: true),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
Reference in New Issue
Block a user