mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 16:08:40 +00:00
fix #48
This commit is contained in:
parent
d9741ee877
commit
06feb2d18c
10 changed files with 178 additions and 52 deletions
|
|
@ -85,6 +85,8 @@ class _MessageSendStateIconState extends State<MessageSendStateIcon> {
|
||||||
|
|
||||||
for (final message in widget.messages) {
|
for (final message in widget.messages) {
|
||||||
if (icons.length == 2) break;
|
if (icons.length == 2) break;
|
||||||
|
if (kindsAlreadyShown.contains(message.kind)) continue;
|
||||||
|
kindsAlreadyShown.add(message.kind);
|
||||||
|
|
||||||
MessageSendState state = messageSendStateFromMessage(message);
|
MessageSendState state = messageSendStateFromMessage(message);
|
||||||
late Color color;
|
late Color color;
|
||||||
|
|
@ -94,14 +96,13 @@ class _MessageSendStateIconState extends State<MessageSendStateIcon> {
|
||||||
getMessageColorFromType(TextMessageContent(text: ""), twonlyColor);
|
getMessageColorFromType(TextMessageContent(text: ""), twonlyColor);
|
||||||
} else {
|
} else {
|
||||||
MessageContent? content = MessageContent.fromJson(
|
MessageContent? content = MessageContent.fromJson(
|
||||||
message.kind, jsonDecode(message.contentJson!));
|
message.kind,
|
||||||
|
jsonDecode(message.contentJson!),
|
||||||
|
);
|
||||||
if (content == null) continue;
|
if (content == null) continue;
|
||||||
color = getMessageColorFromType(content, twonlyColor);
|
color = getMessageColorFromType(content, twonlyColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kindsAlreadyShown.contains(message.kind)) continue;
|
|
||||||
kindsAlreadyShown.add(message.kind);
|
|
||||||
|
|
||||||
Widget icon = Placeholder();
|
Widget icon = Placeholder();
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
|
|
@ -140,6 +141,11 @@ class _MessageSendStateIconState extends State<MessageSendStateIcon> {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (message.kind == MessageKind.storedMediaFile) {
|
||||||
|
icon = FaIcon(FontAwesomeIcons.floppyDisk, size: 12, color: color);
|
||||||
|
text = "Stored in gallery";
|
||||||
|
}
|
||||||
|
|
||||||
icons.add(icon);
|
icons.add(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -76,13 +76,13 @@ class MessagesDao extends DatabaseAccessor<TwonlyDatabase>
|
||||||
.get();
|
.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future openedAllTextMessages(int contactId) {
|
Future openedAllNonMediaMessages(int contactId) {
|
||||||
final updates = MessagesCompanion(openedAt: Value(DateTime.now()));
|
final updates = MessagesCompanion(openedAt: Value(DateTime.now()));
|
||||||
return (update(messages)
|
return (update(messages)
|
||||||
..where((t) =>
|
..where((t) =>
|
||||||
t.contactId.equals(contactId) &
|
t.contactId.equals(contactId) &
|
||||||
t.openedAt.isNull() &
|
t.openedAt.isNull() &
|
||||||
t.kind.equals(MessageKind.textMessage.name)))
|
t.kind.equals(MessageKind.media.name).not()))
|
||||||
.write(updates);
|
.write(updates);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||||
|
|
||||||
enum MessageKind {
|
enum MessageKind {
|
||||||
textMessage,
|
textMessage,
|
||||||
|
storedMediaFile,
|
||||||
media,
|
media,
|
||||||
contactRequest,
|
contactRequest,
|
||||||
profileChange,
|
profileChange,
|
||||||
|
|
@ -20,7 +21,7 @@ Map<String, Color> messageKindColors = {
|
||||||
Color getMessageColorFromType(MessageContent content, Color primary) {
|
Color getMessageColorFromType(MessageContent content, Color primary) {
|
||||||
Color color;
|
Color color;
|
||||||
|
|
||||||
if (content is TextMessageContent) {
|
if (content is TextMessageContent || content is StoredMediaFileContent) {
|
||||||
color = messageKindColors["text"]!;
|
color = messageKindColors["text"]!;
|
||||||
} else {
|
} else {
|
||||||
if (content is MediaMessageContent) {
|
if (content is MediaMessageContent) {
|
||||||
|
|
@ -96,6 +97,8 @@ class MessageContent {
|
||||||
return TextMessageContent.fromJson(json);
|
return TextMessageContent.fromJson(json);
|
||||||
case MessageKind.profileChange:
|
case MessageKind.profileChange:
|
||||||
return ProfileContent.fromJson(json);
|
return ProfileContent.fromJson(json);
|
||||||
|
case MessageKind.storedMediaFile:
|
||||||
|
return StoredMediaFileContent.fromJson(json);
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -172,6 +175,20 @@ class TextMessageContent extends MessageContent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class StoredMediaFileContent extends MessageContent {
|
||||||
|
int messageId;
|
||||||
|
StoredMediaFileContent({required this.messageId});
|
||||||
|
|
||||||
|
static StoredMediaFileContent fromJson(Map json) {
|
||||||
|
return StoredMediaFileContent(messageId: json['messageId']);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map toJson() {
|
||||||
|
return {'messageId': messageId};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ProfileContent extends MessageContent {
|
class ProfileContent extends MessageContent {
|
||||||
String avatarSvg;
|
String avatarSvg;
|
||||||
String displayName;
|
String displayName;
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ class UserData {
|
||||||
String? avatarSvg;
|
String? avatarSvg;
|
||||||
String? avatarJson;
|
String? avatarJson;
|
||||||
int? avatarCounter;
|
int? avatarCounter;
|
||||||
|
int? defaultShowTime;
|
||||||
|
|
||||||
final int userId;
|
final int userId;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,8 @@ UserData _$UserDataFromJson(Map<String, dynamic> json) => UserData(
|
||||||
)
|
)
|
||||||
..avatarSvg = json['avatarSvg'] as String?
|
..avatarSvg = json['avatarSvg'] as String?
|
||||||
..avatarJson = json['avatarJson'] as String?
|
..avatarJson = json['avatarJson'] as String?
|
||||||
..avatarCounter = (json['avatarCounter'] as num?)?.toInt();
|
..avatarCounter = (json['avatarCounter'] as num?)?.toInt()
|
||||||
|
..defaultShowTime = (json['defaultShowTime'] as num?)?.toInt();
|
||||||
|
|
||||||
Map<String, dynamic> _$UserDataToJson(UserData instance) => <String, dynamic>{
|
Map<String, dynamic> _$UserDataToJson(UserData instance) => <String, dynamic>{
|
||||||
'username': instance.username,
|
'username': instance.username,
|
||||||
|
|
@ -21,5 +22,6 @@ Map<String, dynamic> _$UserDataToJson(UserData instance) => <String, dynamic>{
|
||||||
'avatarSvg': instance.avatarSvg,
|
'avatarSvg': instance.avatarSvg,
|
||||||
'avatarJson': instance.avatarJson,
|
'avatarJson': instance.avatarJson,
|
||||||
'avatarCounter': instance.avatarCounter,
|
'avatarCounter': instance.avatarCounter,
|
||||||
|
'defaultShowTime': instance.defaultShowTime,
|
||||||
'userId': instance.userId,
|
'userId': instance.userId,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -221,18 +221,28 @@ Future<client.Response> handleNewMessage(int fromUserId, Uint8List body) async {
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (message.kind != MessageKind.textMessage &&
|
if (message.kind != MessageKind.textMessage &&
|
||||||
message.kind != MessageKind.media) {
|
message.kind != MessageKind.media &&
|
||||||
|
message.kind != MessageKind.storedMediaFile) {
|
||||||
Logger("handleServerMessages")
|
Logger("handleServerMessages")
|
||||||
.shout("Got unknown MessageKind $message");
|
.shout("Got unknown MessageKind $message");
|
||||||
} else {
|
} else {
|
||||||
String content = jsonEncode(message.content!.toJson());
|
String content = jsonEncode(message.content!.toJson());
|
||||||
|
|
||||||
|
bool acknowledgeByUser = false;
|
||||||
|
DateTime? openedAt;
|
||||||
|
if (message.kind == MessageKind.storedMediaFile) {
|
||||||
|
acknowledgeByUser = true;
|
||||||
|
openedAt = DateTime.now();
|
||||||
|
}
|
||||||
|
|
||||||
final update = MessagesCompanion(
|
final update = MessagesCompanion(
|
||||||
contactId: Value(fromUserId),
|
contactId: Value(fromUserId),
|
||||||
kind: Value(message.kind),
|
kind: Value(message.kind),
|
||||||
messageOtherId: Value(message.messageId),
|
messageOtherId: Value(message.messageId),
|
||||||
contentJson: Value(content),
|
contentJson: Value(content),
|
||||||
acknowledgeByServer: Value(true),
|
acknowledgeByServer: Value(true),
|
||||||
|
acknowledgeByUser: Value(acknowledgeByUser),
|
||||||
|
openedAt: Value(openedAt),
|
||||||
downloadState: Value(message.kind == MessageKind.media
|
downloadState: Value(message.kind == MessageKind.media
|
||||||
? DownloadState.pending
|
? DownloadState.pending
|
||||||
: DownloadState.downloaded),
|
: DownloadState.downloaded),
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,7 @@ String getPushNotificationText(String key, String userName) {
|
||||||
"newImage": "%userName% hat dir ein Bild gesendet.",
|
"newImage": "%userName% hat dir ein Bild gesendet.",
|
||||||
"contactRequest": "%userName% möchte sich mir dir vernetzen.",
|
"contactRequest": "%userName% möchte sich mir dir vernetzen.",
|
||||||
"acceptRequest": "%userName% ist jetzt mit dir vernetzt.",
|
"acceptRequest": "%userName% ist jetzt mit dir vernetzt.",
|
||||||
|
"storedMediaFile": "%userName% hat dein Bild gespeichert."
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
pushNotificationText = {
|
pushNotificationText = {
|
||||||
|
|
@ -158,6 +159,7 @@ String getPushNotificationText(String key, String userName) {
|
||||||
"newImage": "%userName% has sent you an image.",
|
"newImage": "%userName% has sent you an image.",
|
||||||
"contactRequest": "%userName% wants to connect with you.",
|
"contactRequest": "%userName% wants to connect with you.",
|
||||||
"acceptRequest": "%userName% is now connected with you.",
|
"acceptRequest": "%userName% is now connected with you.",
|
||||||
|
"storedMediaFile": "%userName% has stored your image."
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -199,6 +201,11 @@ Future localPushNotificationNewMessage(
|
||||||
msg = getPushNotificationText("acceptRequest", getContactDisplayName(user));
|
msg = getPushNotificationText("acceptRequest", getContactDisplayName(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (message.kind == my.MessageKind.storedMediaFile) {
|
||||||
|
msg =
|
||||||
|
getPushNotificationText("storedMediaFile", getContactDisplayName(user));
|
||||||
|
}
|
||||||
|
|
||||||
if (msg == "") {
|
if (msg == "") {
|
||||||
Logger("localPushNotificationNewMessage")
|
Logger("localPushNotificationNewMessage")
|
||||||
.shout("No push notification type defined!");
|
.shout("No push notification type defined!");
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import 'package:twonly/src/database/twonly_database.dart';
|
||||||
import 'package:twonly/src/providers/api/media.dart';
|
import 'package:twonly/src/providers/api/media.dart';
|
||||||
import 'package:twonly/src/providers/send_next_media_to.dart';
|
import 'package:twonly/src/providers/send_next_media_to.dart';
|
||||||
import 'package:twonly/src/utils/misc.dart';
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
|
import 'package:twonly/src/utils/storage.dart';
|
||||||
import 'package:twonly/src/views/camera_to_share/share_image_view.dart';
|
import 'package:twonly/src/views/camera_to_share/share_image_view.dart';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
@ -35,7 +36,7 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
||||||
bool _imageSaved = false;
|
bool _imageSaved = false;
|
||||||
bool _imageSaving = false;
|
bool _imageSaving = false;
|
||||||
bool _isRealTwonly = false;
|
bool _isRealTwonly = false;
|
||||||
int _maxShowTime = 18;
|
int maxShowTime = 999999;
|
||||||
String? sendNextMediaToUserName;
|
String? sendNextMediaToUserName;
|
||||||
|
|
||||||
ImageItem currentImage = ImageItem();
|
ImageItem currentImage = ImageItem();
|
||||||
|
|
@ -44,9 +45,20 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
initAsync();
|
||||||
loadImage(widget.imageBytes);
|
loadImage(widget.imageBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void initAsync() async {
|
||||||
|
final user = await getUser();
|
||||||
|
if (user == null) return;
|
||||||
|
if (user.defaultShowTime != null) {
|
||||||
|
setState(() {
|
||||||
|
maxShowTime = user.defaultShowTime!;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
layers.clear();
|
layers.clear();
|
||||||
|
|
@ -114,24 +126,25 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
NotificationBadge(
|
NotificationBadge(
|
||||||
count: _maxShowTime == 999999 ? "∞" : _maxShowTime.toString(),
|
count: maxShowTime == 999999 ? "∞" : maxShowTime.toString(),
|
||||||
// count: "",
|
// count: "",
|
||||||
child: ActionButton(
|
child: ActionButton(
|
||||||
FontAwesomeIcons.stopwatch,
|
FontAwesomeIcons.stopwatch,
|
||||||
tooltipText: context.lang.protectAsARealTwonly,
|
tooltipText: context.lang.protectAsARealTwonly,
|
||||||
// disable: _isRealTwonly,
|
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if (_maxShowTime == 999999) {
|
if (maxShowTime == 999999) {
|
||||||
_maxShowTime = 4;
|
maxShowTime = 4;
|
||||||
} else if (_maxShowTime >= 22) {
|
} else if (maxShowTime >= 22) {
|
||||||
_maxShowTime = 999999;
|
maxShowTime = 999999;
|
||||||
} else {
|
} else {
|
||||||
_maxShowTime = _maxShowTime + 4;
|
maxShowTime = maxShowTime + 8;
|
||||||
}
|
}
|
||||||
setState(() {});
|
setState(() {});
|
||||||
|
var user = await getUser();
|
||||||
// _maxShowTime =
|
if (user != null) {
|
||||||
// _isRealTwonly = !_isRealTwonly;
|
user.defaultShowTime = maxShowTime;
|
||||||
|
updateUser(user);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -145,7 +158,7 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
_isRealTwonly = !_isRealTwonly;
|
_isRealTwonly = !_isRealTwonly;
|
||||||
if (_isRealTwonly) {
|
if (_isRealTwonly) {
|
||||||
_maxShowTime = 12;
|
maxShowTime = 12;
|
||||||
}
|
}
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
|
|
@ -369,7 +382,7 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
||||||
builder: (context) => ShareImageView(
|
builder: (context) => ShareImageView(
|
||||||
imageBytesFuture: imageBytes,
|
imageBytesFuture: imageBytes,
|
||||||
isRealTwonly: _isRealTwonly,
|
isRealTwonly: _isRealTwonly,
|
||||||
maxShowTime: _maxShowTime,
|
maxShowTime: maxShowTime,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -387,7 +400,7 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
||||||
[sendNextMediaToUserId],
|
[sendNextMediaToUserId],
|
||||||
imageBytes!,
|
imageBytes!,
|
||||||
_isRealTwonly,
|
_isRealTwonly,
|
||||||
_maxShowTime,
|
maxShowTime,
|
||||||
);
|
);
|
||||||
Navigator.popUntil(context, (route) => route.isFirst);
|
Navigator.popUntil(context, (route) => route.isFirst);
|
||||||
globalUpdateOfHomeViewPageIndex(1);
|
globalUpdateOfHomeViewPageIndex(1);
|
||||||
|
|
@ -402,7 +415,7 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
||||||
builder: (context) => ShareImageView(
|
builder: (context) => ShareImageView(
|
||||||
imageBytesFuture: imageBytes,
|
imageBytesFuture: imageBytes,
|
||||||
isRealTwonly: _isRealTwonly,
|
isRealTwonly: _isRealTwonly,
|
||||||
maxShowTime: _maxShowTime,
|
maxShowTime: maxShowTime,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,9 @@ class ChatListEntry extends StatelessWidget {
|
||||||
}
|
}
|
||||||
} else if (content is MediaMessageContent && !content.isVideo) {
|
} else if (content is MediaMessageContent && !content.isVideo) {
|
||||||
Color color = getMessageColorFromType(
|
Color color = getMessageColorFromType(
|
||||||
content, Theme.of(context).colorScheme.primary);
|
content,
|
||||||
|
Theme.of(context).colorScheme.primary,
|
||||||
|
);
|
||||||
|
|
||||||
child = GestureDetector(
|
child = GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
|
@ -112,6 +114,26 @@ class ChatListEntry extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
} else if (message.kind == MessageKind.storedMediaFile) {
|
||||||
|
child = Container(
|
||||||
|
padding: EdgeInsets.all(5),
|
||||||
|
width: 150,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(
|
||||||
|
color: messageKindColors["text"]!,
|
||||||
|
width: 1.0,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
),
|
||||||
|
child: Align(
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
child: MessageSendStateIcon(
|
||||||
|
[message],
|
||||||
|
mainAxisAlignment:
|
||||||
|
right ? MainAxisAlignment.center : MainAxisAlignment.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Align(
|
return Align(
|
||||||
|
|
@ -181,9 +203,8 @@ class _ChatItemDetailsViewState extends State<ChatItemDetailsView> {
|
||||||
notifyContactAboutOpeningMessage(widget.userid, msg.messageOtherId!);
|
notifyContactAboutOpeningMessage(widget.userid, msg.messageOtherId!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (updated) {
|
twonlyDatabase.messagesDao.openedAllNonMediaMessages(widget.userid);
|
||||||
twonlyDatabase.messagesDao.openedAllTextMessages(widget.userid);
|
if (!updated) {
|
||||||
} else {
|
|
||||||
// The stream should be get an update, so only update the UI when all are opened
|
// The stream should be get an update, so only update the UI when all are opened
|
||||||
setState(() {
|
setState(() {
|
||||||
messages = msgs;
|
messages = msgs;
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,9 @@ class _MediaViewerViewState extends State<MediaViewerView> {
|
||||||
bool isRealTwonly = false;
|
bool isRealTwonly = false;
|
||||||
bool isDownloading = false;
|
bool isDownloading = false;
|
||||||
|
|
||||||
|
bool imageSaved = false;
|
||||||
|
bool imageSaving = false;
|
||||||
|
|
||||||
List<Message> allMediaFiles = [];
|
List<Message> allMediaFiles = [];
|
||||||
late StreamSubscription<List<Message>> _subscription;
|
late StreamSubscription<List<Message>> _subscription;
|
||||||
|
|
||||||
|
|
@ -95,10 +98,11 @@ class _MediaViewerViewState extends State<MediaViewerView> {
|
||||||
MediaMessageContent.fromJson(jsonDecode(current.contentJson!));
|
MediaMessageContent.fromJson(jsonDecode(current.contentJson!));
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
// reset current image values
|
|
||||||
imageBytes = null;
|
imageBytes = null;
|
||||||
canBeSeenUntil = null;
|
canBeSeenUntil = null;
|
||||||
maxShowTime = 999999;
|
maxShowTime = 999999;
|
||||||
|
imageSaving = false;
|
||||||
|
imageSaved = false;
|
||||||
progress = 0;
|
progress = 0;
|
||||||
isDownloading = false;
|
isDownloading = false;
|
||||||
isRealTwonly = false;
|
isRealTwonly = false;
|
||||||
|
|
@ -281,7 +285,7 @@ class _MediaViewerViewState extends State<MediaViewerView> {
|
||||||
),
|
),
|
||||||
AnimatedPositioned(
|
AnimatedPositioned(
|
||||||
duration: Duration(milliseconds: 200), // Animation duration
|
duration: Duration(milliseconds: 200), // Animation duration
|
||||||
bottom: showShortReactions ? 130 : 90,
|
bottom: showShortReactions ? 100 : 90,
|
||||||
left: showShortReactions ? 0 : 150,
|
left: showShortReactions ? 0 : 150,
|
||||||
right: showShortReactions ? 0 : 150,
|
right: showShortReactions ? 0 : 150,
|
||||||
curve: Curves.linearToEaseOut,
|
curve: Curves.linearToEaseOut,
|
||||||
|
|
@ -341,32 +345,65 @@ class _MediaViewerViewState extends State<MediaViewerView> {
|
||||||
),
|
),
|
||||||
if (imageBytes != null)
|
if (imageBytes != null)
|
||||||
Positioned(
|
Positioned(
|
||||||
bottom: 30,
|
bottom: 0,
|
||||||
left: 0,
|
left: 0,
|
||||||
right: 0,
|
right: 0,
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
IconButton.outlined(
|
if (maxShowTime == 999999)
|
||||||
icon: FaIcon(FontAwesomeIcons.camera),
|
OutlinedButton(
|
||||||
onPressed: () async {
|
style: OutlinedButton.styleFrom(
|
||||||
context
|
iconColor: imageSaved
|
||||||
.read<SendNextMediaTo>()
|
? Theme.of(context).colorScheme.outline
|
||||||
.updateSendNextMediaTo(widget.userId.toInt());
|
: Theme.of(context).colorScheme.primary,
|
||||||
globalUpdateOfHomeViewPageIndex(0);
|
foregroundColor: imageSaved
|
||||||
Navigator.popUntil(context, (route) => route.isFirst);
|
? Theme.of(context).colorScheme.outline
|
||||||
},
|
: Theme.of(context).colorScheme.primary,
|
||||||
style: ButtonStyle(
|
),
|
||||||
padding: WidgetStateProperty.all<EdgeInsets>(
|
onPressed: () async {
|
||||||
EdgeInsets.symmetric(vertical: 10, horizontal: 30),
|
setState(() {
|
||||||
|
imageSaving = true;
|
||||||
|
});
|
||||||
|
encryptAndSendMessage(
|
||||||
|
null,
|
||||||
|
widget.userId,
|
||||||
|
MessageJson(
|
||||||
|
kind: MessageKind.storedMediaFile,
|
||||||
|
messageId: allMediaFiles.first.messageId,
|
||||||
|
content: StoredMediaFileContent(
|
||||||
|
messageId: allMediaFiles.first.messageId,
|
||||||
|
),
|
||||||
|
timestamp: DateTime.now(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
final res = await saveImageToGallery(imageBytes!);
|
||||||
|
if (res == null) {
|
||||||
|
setState(() {
|
||||||
|
imageSaving = false;
|
||||||
|
imageSaved = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
imageSaving
|
||||||
|
? SizedBox(
|
||||||
|
width: 10,
|
||||||
|
height: 10,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
strokeWidth: 1))
|
||||||
|
: imageSaved
|
||||||
|
? Icon(Icons.check)
|
||||||
|
: FaIcon(FontAwesomeIcons.floppyDisk),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
SizedBox(width: 10),
|
SizedBox(width: 10),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: SizedBox(
|
icon: SizedBox(
|
||||||
width: 40,
|
width: 30,
|
||||||
height: 40,
|
height: 30,
|
||||||
child: GridView.count(
|
child: GridView.count(
|
||||||
crossAxisCount: 2,
|
crossAxisCount: 2,
|
||||||
children: List.generate(
|
children: List.generate(
|
||||||
|
|
@ -391,14 +428,10 @@ class _MediaViewerViewState extends State<MediaViewerView> {
|
||||||
showShortReactions = !showShortReactions;
|
showShortReactions = !showShortReactions;
|
||||||
selectedShortReaction = -1;
|
selectedShortReaction = -1;
|
||||||
});
|
});
|
||||||
// context.read<SendNextMediaTo>().updateSendNextMediaTo(
|
|
||||||
// widget.otherUser.userId.toInt());
|
|
||||||
// globalUpdateOfHomeViewPageIndex(0);
|
|
||||||
// Navigator.popUntil(context, (route) => route.isFirst);
|
|
||||||
},
|
},
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
padding: WidgetStateProperty.all<EdgeInsets>(
|
padding: WidgetStateProperty.all<EdgeInsets>(
|
||||||
EdgeInsets.symmetric(vertical: 10, horizontal: 30),
|
EdgeInsets.symmetric(vertical: 10, horizontal: 20),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -416,7 +449,23 @@ class _MediaViewerViewState extends State<MediaViewerView> {
|
||||||
},
|
},
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
padding: WidgetStateProperty.all<EdgeInsets>(
|
padding: WidgetStateProperty.all<EdgeInsets>(
|
||||||
EdgeInsets.symmetric(vertical: 10, horizontal: 30),
|
EdgeInsets.symmetric(vertical: 10, horizontal: 20),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 10),
|
||||||
|
IconButton.outlined(
|
||||||
|
icon: FaIcon(FontAwesomeIcons.camera),
|
||||||
|
onPressed: () async {
|
||||||
|
context
|
||||||
|
.read<SendNextMediaTo>()
|
||||||
|
.updateSendNextMediaTo(widget.userId.toInt());
|
||||||
|
globalUpdateOfHomeViewPageIndex(0);
|
||||||
|
Navigator.popUntil(context, (route) => route.isFirst);
|
||||||
|
},
|
||||||
|
style: ButtonStyle(
|
||||||
|
padding: WidgetStateProperty.all<EdgeInsets>(
|
||||||
|
EdgeInsets.symmetric(vertical: 10, horizontal: 20),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue