|
1 | 1 | import 'package:flutter/material.dart';
|
2 | 2 | import 'package:flutter/scheduler.dart';
|
3 | 3 | import 'package:flutter/services.dart';
|
| 4 | +import 'package:http/http.dart' as httpClient; |
4 | 5 | import 'package:intl/intl.dart';
|
| 6 | +import 'package:share_plus/share_plus.dart'; |
5 | 7 | import 'package:video_player/video_player.dart';
|
6 | 8 |
|
7 | 9 | import '../api/core.dart';
|
@@ -89,6 +91,46 @@ class _CopyLinkButton extends StatelessWidget {
|
89 | 91 | }
|
90 | 92 | }
|
91 | 93 |
|
| 94 | +Future<XFile> _downloadImage(Uri url, Map<String, String> headers) async { |
| 95 | + final response = await httpClient.get(url, headers: headers); |
| 96 | + final bytes = response.bodyBytes; |
| 97 | + return XFile.fromData(bytes, |
| 98 | + name: url.pathSegments.last, |
| 99 | + mimeType: response.headers['content-type']); |
| 100 | +} |
| 101 | + |
| 102 | +class _ShareButton extends StatelessWidget { |
| 103 | + const _ShareButton({required this.url}); |
| 104 | + |
| 105 | + final Uri url; |
| 106 | + |
| 107 | + @override |
| 108 | + Widget build(BuildContext context) { |
| 109 | + final zulipLocalizations = ZulipLocalizations.of(context); |
| 110 | + return IconButton( |
| 111 | + tooltip: zulipLocalizations.lightboxShareImageTooltip, |
| 112 | + icon: const Icon(Icons.share), |
| 113 | + onPressed: () async { |
| 114 | + try { |
| 115 | + final store = PerAccountStoreWidget.of(context); |
| 116 | + final headers = { |
| 117 | + if (url.origin == store.account.realmUrl.origin) |
| 118 | + ...authHeader(email: store.account.email, apiKey: store.account.apiKey), |
| 119 | + ...userAgentHeader() |
| 120 | + }; |
| 121 | + final xFile = await _downloadImage(url, headers); |
| 122 | + await Share.shareXFiles([xFile]); |
| 123 | + } catch (error) { |
| 124 | + if (!context.mounted) return; |
| 125 | + showErrorDialog( |
| 126 | + context: context, |
| 127 | + title: zulipLocalizations.errorDialogTitle, |
| 128 | + message: zulipLocalizations.errorShareFailed); |
| 129 | + } |
| 130 | + }); |
| 131 | + } |
| 132 | +} |
| 133 | + |
92 | 134 | class _LightboxPageLayout extends StatefulWidget {
|
93 | 135 | const _LightboxPageLayout({
|
94 | 136 | required this.routeEntranceAnimation,
|
@@ -258,6 +300,7 @@ class _ImageLightboxPageState extends State<_ImageLightboxPage> {
|
258 | 300 | elevation: elevation,
|
259 | 301 | child: Row(children: [
|
260 | 302 | _CopyLinkButton(url: widget.src),
|
| 303 | + _ShareButton(url: widget.src), |
261 | 304 | // TODO(#43): Share image
|
262 | 305 | // TODO(#42): Download image
|
263 | 306 | ]),
|
|
0 commit comments