matrix-0.8.13/lib/src/utils/event_localizations.dart

225 lines
10 KiB
Dart
Raw Permalink Normal View History

2022-04-18 08:57:08 +00:00
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020, 2021 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'package:collection/collection.dart';
import '../../encryption.dart';
import '../../matrix.dart';
abstract class EventLocalizations {
// As we need to create the localized body off of a different set of parameters, we
// might create it with `event.plaintextBody`, maybe with `event.body`, maybe with the
// reply fallback stripped, and maybe with the new body in `event.content['m.new_content']`.
// Thus, it seems easier to offload that logic into `Event.getLocalizedBody()` and pass the
// `body` variable around here.
static String _localizedBodyNormalMessage(
Event event, MatrixLocalizations i18n, String body) {
switch (event.messageType) {
case MessageTypes.Image:
return i18n.sentAPicture(event.sender.calcDisplayname());
case MessageTypes.File:
return i18n.sentAFile(event.sender.calcDisplayname());
case MessageTypes.Audio:
return i18n.sentAnAudio(event.sender.calcDisplayname());
case MessageTypes.Video:
return i18n.sentAVideo(event.sender.calcDisplayname());
case MessageTypes.Location:
return i18n.sharedTheLocation(event.sender.calcDisplayname());
case MessageTypes.Sticker:
return i18n.sentASticker(event.sender.calcDisplayname());
case MessageTypes.Emote:
return '* $body';
case MessageTypes.BadEncrypted:
String errorText;
switch (event.body) {
case DecryptException.channelCorrupted:
errorText = i18n.channelCorruptedDecryptError + '.';
break;
case DecryptException.notEnabled:
errorText = i18n.encryptionNotEnabled + '.';
break;
case DecryptException.unknownAlgorithm:
errorText = i18n.unknownEncryptionAlgorithm + '.';
break;
case DecryptException.unknownSession:
errorText = i18n.noPermission + '.';
break;
default:
errorText = body;
break;
}
return i18n.couldNotDecryptMessage(errorText);
case MessageTypes.Text:
case MessageTypes.Notice:
case MessageTypes.None:
default:
return body;
}
}
// This map holds how to localize event types, and thus which event types exist.
// If an event exists but it does not have a localized body, set its callback to null
static final Map<String,
String Function(Event event, MatrixLocalizations i18n, String body)?>
localizationsMap = {
EventTypes.Sticker: (event, i18n, body) =>
i18n.sentASticker(event.sender.calcDisplayname()),
EventTypes.Redaction: (event, i18n, body) =>
i18n.redactedAnEvent(event.sender.calcDisplayname()),
EventTypes.RoomAliases: (event, i18n, body) =>
i18n.changedTheRoomAliases(event.sender.calcDisplayname()),
EventTypes.RoomCanonicalAlias: (event, i18n, body) =>
i18n.changedTheRoomInvitationLink(event.sender.calcDisplayname()),
EventTypes.RoomCreate: (event, i18n, body) =>
i18n.createdTheChat(event.sender.calcDisplayname()),
EventTypes.RoomTombstone: (event, i18n, body) => i18n.roomHasBeenUpgraded,
EventTypes.RoomJoinRules: (event, i18n, body) {
final joinRules = JoinRules.values.firstWhereOrNull((r) =>
r.toString().replaceAll('JoinRules.', '') ==
event.content['join_rule']);
if (joinRules == null) {
return i18n.changedTheJoinRules(event.sender.calcDisplayname());
} else {
return i18n.changedTheJoinRulesTo(
event.sender.calcDisplayname(), joinRules.getLocalizedString(i18n));
}
},
EventTypes.RoomMember: (event, i18n, body) {
var text = 'Failed to parse member event';
final targetName = event.stateKeyUser?.calcDisplayname() ?? '';
// Has the membership changed?
final newMembership = event.content['membership'] ?? '';
final oldMembership = event.prevContent?['membership'] ?? '';
if (newMembership != oldMembership) {
if (oldMembership == 'invite' && newMembership == 'join') {
text = i18n.acceptedTheInvitation(targetName);
} else if (oldMembership == 'invite' && newMembership == 'leave') {
if (event.stateKey == event.senderId) {
text = i18n.rejectedTheInvitation(targetName);
} else {
text = i18n.hasWithdrawnTheInvitationFor(
event.sender.calcDisplayname(), targetName);
}
} else if (oldMembership == 'leave' && newMembership == 'join') {
text = i18n.joinedTheChat(targetName);
} else if (oldMembership == 'join' && newMembership == 'ban') {
text =
i18n.kickedAndBanned(event.sender.calcDisplayname(), targetName);
} else if (oldMembership == 'join' &&
newMembership == 'leave' &&
event.stateKey != event.senderId) {
text = i18n.kicked(event.sender.calcDisplayname(), targetName);
} else if (oldMembership == 'join' &&
newMembership == 'leave' &&
event.stateKey == event.senderId) {
text = i18n.userLeftTheChat(targetName);
} else if (oldMembership == 'invite' && newMembership == 'ban') {
text = i18n.bannedUser(event.sender.calcDisplayname(), targetName);
} else if (oldMembership == 'leave' && newMembership == 'ban') {
text = i18n.bannedUser(event.sender.calcDisplayname(), targetName);
} else if (oldMembership == 'ban' && newMembership == 'leave') {
text = i18n.unbannedUser(event.sender.calcDisplayname(), targetName);
} else if (newMembership == 'invite') {
text = i18n.invitedUser(event.sender.calcDisplayname(), targetName);
} else if (newMembership == 'join') {
text = i18n.joinedTheChat(targetName);
}
} else if (newMembership == 'join') {
final newAvatar = event.content.tryGet<String>('avatar_url') ?? '';
final oldAvatar = event.prevContent?.tryGet<String>('avatar_url') ?? '';
final newDisplayname =
event.content.tryGet<String>('displayname') ?? '';
final oldDisplayname =
event.prevContent?.tryGet<String>('displayname') ?? '';
final stateKey = event.stateKey;
// Has the user avatar changed?
if (newAvatar != oldAvatar) {
text = i18n.changedTheProfileAvatar(targetName);
}
// Has the user displayname changed?
else if (newDisplayname != oldDisplayname && stateKey != null) {
text = i18n.changedTheDisplaynameTo(oldDisplayname, newDisplayname);
}
}
return text;
},
EventTypes.RoomPowerLevels: (event, i18n, body) =>
i18n.changedTheChatPermissions(event.sender.calcDisplayname()),
EventTypes.RoomName: (event, i18n, body) => i18n.changedTheChatNameTo(
event.sender.calcDisplayname(), event.content['name']),
EventTypes.RoomTopic: (event, i18n, body) =>
i18n.changedTheChatDescriptionTo(
event.sender.calcDisplayname(), event.content['topic']),
EventTypes.RoomAvatar: (event, i18n, body) =>
i18n.changedTheChatAvatar(event.sender.calcDisplayname()),
EventTypes.GuestAccess: (event, i18n, body) {
final guestAccess = GuestAccess.values.firstWhereOrNull((r) =>
r.toString().replaceAll('GuestAccess.', '') ==
event.content['guest_access']);
if (guestAccess == null) {
return i18n.changedTheGuestAccessRules(event.sender.calcDisplayname());
} else {
return i18n.changedTheGuestAccessRulesTo(event.sender.calcDisplayname(),
guestAccess.getLocalizedString(i18n));
}
},
EventTypes.HistoryVisibility: (event, i18n, body) {
final historyVisibility = HistoryVisibility.values.firstWhereOrNull((r) =>
r.toString().replaceAll('HistoryVisibility.', '') ==
event.content['history_visibility']);
if (historyVisibility == null) {
return i18n.changedTheHistoryVisibility(event.sender.calcDisplayname());
} else {
return i18n.changedTheHistoryVisibilityTo(
event.sender.calcDisplayname(),
historyVisibility.getLocalizedString(i18n));
}
},
EventTypes.Encryption: (event, i18n, body) {
var localizedBody =
i18n.activatedEndToEndEncryption(event.sender.calcDisplayname());
if (event.room.client.encryptionEnabled == false) {
localizedBody += '. ' + i18n.needPantalaimonWarning;
}
return localizedBody;
},
EventTypes.CallAnswer: (event, i18n, body) =>
i18n.answeredTheCall(event.sender.calcDisplayname()),
EventTypes.CallHangup: (event, i18n, body) =>
i18n.endedTheCall(event.sender.calcDisplayname()),
EventTypes.CallInvite: (event, i18n, body) =>
i18n.startedACall(event.sender.calcDisplayname()),
EventTypes.CallCandidates: (event, i18n, body) =>
i18n.sentCallInformations(event.sender.calcDisplayname()),
EventTypes.Encrypted: (event, i18n, body) =>
_localizedBodyNormalMessage(event, i18n, body),
EventTypes.Message: (event, i18n, body) =>
_localizedBodyNormalMessage(event, i18n, body),
EventTypes.Reaction: (event, i18n, body) => i18n.sentReaction(
event.sender.calcDisplayname(),
event.content
.tryGetMap<String, dynamic>('m.relates_to')
?.tryGet<String>('key') ??
body,
),
};
}