Skip to content

lightbox: Prototype lightbox #29

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
PODS:
- device_info_plus (0.0.1):
- Flutter
- Flutter (1.0.0)
- path_provider_foundation (0.0.1):
- Flutter
Expand All @@ -7,11 +9,14 @@ PODS:
- Flutter

DEPENDENCIES:
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- Flutter (from `Flutter`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- share_plus (from `.symlinks/plugins/share_plus/ios`)

EXTERNAL SOURCES:
device_info_plus:
:path: ".symlinks/plugins/device_info_plus/ios"
Flutter:
:path: Flutter
path_provider_foundation:
Expand All @@ -20,6 +25,7 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/share_plus/ios"

SPEC CHECKSUMS:
device_info_plus: e5c5da33f982a436e103237c0c85f9031142abed
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9
share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68
Expand Down
43 changes: 43 additions & 0 deletions lib/widgets/clipboard.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

/// Copies [data] to the clipboard and shows a popup on success.
///
/// Must have a [Scaffold] ancestor.
///
/// On newer Android the popup is defined and shown by the platform. On older
/// Android and on iOS, shows a [Snackbar] with [successContent].
///
/// In English, the text in [successContent] should be short, should start with
/// a capital letter, and should have no ending punctuation: "{noun} copied".
void copyWithPopup({
required BuildContext context,
required ClipboardData data,
required Widget successContent,
}) async {
await Clipboard.setData(data);
final deviceInfo = await DeviceInfoPlugin().deviceInfo;

if (context.mounted) {} // https://github.com/dart-lang/linter/issues/4007
else {
return;
}

final bool shouldShowSnackbar;
switch (deviceInfo) {
case AndroidDeviceInfo(:var version):
// Android 13+ shows its own popup on copying to the clipboard,
// so we suppress ours, following the advice at:
// https://developer.android.com/develop/ui/views/touch-and-input/copy-paste#duplicate-notifications
// TODO(android-sdk-33): Simplify this and dartdoc
shouldShowSnackbar = version.sdkInt <= 32;
default:
shouldShowSnackbar = true;
}

if (shouldShowSnackbar) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(behavior: SnackBarBehavior.floating, content: successContent));
}
}
63 changes: 45 additions & 18 deletions lib/widgets/content.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import '../api/model/model.dart';
import '../model/content.dart';
import '../model/store.dart';
import 'store.dart';
import 'lightbox.dart';

/// The font size for message content in a plain unstyled paragraph.
const double kBaseFontSize = 14;
Expand All @@ -22,7 +23,24 @@ class MessageContent extends StatelessWidget {

@override
Widget build(BuildContext context) {
return BlockContentList(nodes: content.nodes);
return InheritedMessage(message: message,
child: BlockContentList(nodes: content.nodes));
}
}

class InheritedMessage extends InheritedWidget {
const InheritedMessage({super.key, required this.message, required super.child});

final Message message;

@override
bool updateShouldNotify(covariant InheritedMessage oldWidget) =>
!identical(oldWidget.message, message);

static Message of(BuildContext context) {
final widget = context.dependOnInheritedWidgetOfExactType<InheritedMessage>();
assert(widget != null, 'No InheritedMessage ancestor');
return widget!.message;
}
}

Expand Down Expand Up @@ -180,30 +198,39 @@ class MessageImage extends StatelessWidget {

@override
Widget build(BuildContext context) {
final message = InheritedMessage.of(context);

// TODO multiple images in a row
// TODO image hover animation
final src = node.srcUrl;

final store = PerAccountStoreWidget.of(context);
final resolvedSrc = resolveUrl(src, store.account);

return Align(
alignment: Alignment.centerLeft,
child: Padding(
// TODO clean up this padding by imitating web less precisely;
// in particular, avoid adding loose whitespace at end of message.
// The corresponding element on web has a 5px two-sided margin…
// and then a 1px transparent border all around.
padding: const EdgeInsets.fromLTRB(1, 1, 6, 6),
child: Container(
height: 100,
width: 150,
alignment: Alignment.center,
color: const Color.fromRGBO(0, 0, 0, 0.03),
child: RealmContentNetworkImage(
resolvedSrc,
filterQuality: FilterQuality.medium,
))));
return GestureDetector(
onTap: () {
Navigator.of(context).push(getLightboxRoute(
context: context, message: message, src: resolvedSrc));
},
child: Align(
alignment: Alignment.centerLeft,
child: Padding(
// TODO clean up this padding by imitating web less precisely;
// in particular, avoid adding loose whitespace at end of message.
// The corresponding element on web has a 5px two-sided margin…
// and then a 1px transparent border all around.
padding: const EdgeInsets.fromLTRB(1, 1, 6, 6),
child: Container(
height: 100,
width: 150,
alignment: Alignment.center,
color: const Color.fromRGBO(0, 0, 0, 0.03),
child: LightboxHero(
message: message,
src: resolvedSrc,
child: RealmContentNetworkImage(
resolvedSrc,
Comment on lines +230 to +232
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, this feels kind of redundant. Can the LightboxHero use src to construct this RealmContentNetworkImage widget for itself?

filterQuality: FilterQuality.medium))))));
}
}

Expand Down
Loading