5246a97db2
A new look across the app and a set of everyday messaging features. Interface - Home screen with Chats, Contacts and Settings tabs, a large title, search across chats and message text (diacritics-insensitive), filters and pinned chats. - Conversation view with a translucent header and composer, grouped bubbles, author avatars and colours in groups, swipe to reply, an "N new messages" marker, a jump-to-latest button and in-chat search. - Contact and group profiles: verification, shared photos, groups in common, disappearing messages, mute, block; members, admin badges, adding people, rename and leave for groups. - Full-screen photo viewer that pages through the whole conversation. - A stable avatar colour per person and a clearly visible read state. Messaging - Polls in chats and groups, single or multiple choice, with votes that can be changed or withdrawn; older clients see them as text. - Drafts survive leaving a chat and show in the chat list. - Forwarding of messages, photos, files and voice messages. - Notes to self: a local-only, encrypted chat that never reaches the relay. - @mentions in groups that notify even when the group is muted. - Typing indicators sent as ephemeral messages, opt-in and mutual like read receipts. - Delivery and read times per message and per group member. - Profile photos, cropped, resized and stripped of metadata, delivered encrypted to contacts. - Voice message playback at 1.5x and 2x. - Call buttons in 1:1 chats and call log entries. Fixes - Muted groups no longer notify: muting was checked against the author's chat instead of the group. - A blocked contact could unblock itself by changing its delivery address. - Read receipts no longer regress to delivered when a late delivery receipt arrives. - A message marked as failed corrects itself once it is delivered. - Double ticks in groups now mean delivered to every member.
1719 lines
42 KiB
Dart
1719 lines
42 KiB
Dart
// ignore: unused_import
|
||
import 'package:intl/intl.dart' as intl;
|
||
import 'app_localizations.dart';
|
||
|
||
// ignore_for_file: type=lint
|
||
|
||
/// The translations for English (`en`).
|
||
class AppLocalizationsEn extends AppLocalizations {
|
||
AppLocalizationsEn([String locale = 'en']) : super(locale);
|
||
|
||
@override
|
||
String get appTitle => 'Šepot';
|
||
|
||
@override
|
||
String get settingsLanguage => 'App language';
|
||
|
||
@override
|
||
String get languageSystem => 'System default';
|
||
|
||
@override
|
||
String get commonUnknownContact => 'Unknown';
|
||
|
||
@override
|
||
String get verifyVerified => 'Verified';
|
||
|
||
@override
|
||
String get verifyUnverified => 'Not verified';
|
||
|
||
@override
|
||
String get chatMenuVerifyContact => 'Verify contact';
|
||
|
||
@override
|
||
String get chatDisappearingMessages => 'Disappearing messages';
|
||
|
||
@override
|
||
String get chatMenuUnblockContact => 'Unblock contact';
|
||
|
||
@override
|
||
String get chatMenuBlockContact => 'Block contact';
|
||
|
||
@override
|
||
String get reportAndBlock => 'Report and block';
|
||
|
||
@override
|
||
String errorGeneric(String error) {
|
||
return 'Error: $error';
|
||
}
|
||
|
||
@override
|
||
String get groupsYouLeftGroup => 'You\'re no longer in this group';
|
||
|
||
@override
|
||
String groupsMemberCount(int count) {
|
||
String _temp0 = intl.Intl.pluralLogic(
|
||
count,
|
||
locale: localeName,
|
||
other: '$count members',
|
||
one: '1 member',
|
||
);
|
||
return '$_temp0';
|
||
}
|
||
|
||
@override
|
||
String get groupsMembers => 'Members';
|
||
|
||
@override
|
||
String get groupsRename => 'Rename group';
|
||
|
||
@override
|
||
String get groupsLeave => 'Leave group';
|
||
|
||
@override
|
||
String get groupsLeftBanner =>
|
||
'You\'re no longer in this group. Your history stays, but new messages won\'t arrive.';
|
||
|
||
@override
|
||
String get groupsYou => 'You';
|
||
|
||
@override
|
||
String get groupsFounder => 'Founder';
|
||
|
||
@override
|
||
String get groupsAdmin => 'Admin';
|
||
|
||
@override
|
||
String get groupsMakeAdmin => 'Make admin';
|
||
|
||
@override
|
||
String get groupsDismissAdmin => 'Remove admin role';
|
||
|
||
@override
|
||
String get groupsRemoveMember => 'Remove from group';
|
||
|
||
@override
|
||
String groupsRemoveMemberConfirmTitle(String name) {
|
||
return 'Remove $name from the group?';
|
||
}
|
||
|
||
@override
|
||
String get groupsRemoveMemberConfirmBody =>
|
||
'They will stop getting new messages from this group. Their existing history stays.';
|
||
|
||
@override
|
||
String get groupsRemoveAction => 'Remove';
|
||
|
||
@override
|
||
String get groupsViewContact => 'View contact';
|
||
|
||
@override
|
||
String get groupsAdminOnlyHint =>
|
||
'Only admins can change the group name, members and admins.';
|
||
|
||
@override
|
||
String get groupsAdminOnlyCompatHint =>
|
||
'Only admins can rename the group or change admins. Anyone can still add people, because someone in the group has an older version of Šepot.';
|
||
|
||
@override
|
||
String groupsAdminActionFailed(String error) {
|
||
return 'The change failed: $error';
|
||
}
|
||
|
||
@override
|
||
String get groupsResyncNotice =>
|
||
'The group is catching up with its admin. Member changes may show up with a delay.';
|
||
|
||
@override
|
||
String get groupsRejectedChangeNotice =>
|
||
'Someone without permission tried to change the group. The change was not applied.';
|
||
|
||
@override
|
||
String get errorGroupNotAdmin => 'Only a group admin can do this.';
|
||
|
||
@override
|
||
String get errorGroupLastAdmin =>
|
||
'You\'re the only admin. Make someone else an admin first.';
|
||
|
||
@override
|
||
String get groupsNameHint => 'Group name';
|
||
|
||
@override
|
||
String get commonCancel => 'Cancel';
|
||
|
||
@override
|
||
String get commonSave => 'Save';
|
||
|
||
@override
|
||
String groupsRenameFailed(String error) {
|
||
return 'Rename failed: $error';
|
||
}
|
||
|
||
@override
|
||
String get groupsLeaveConfirmTitle => 'Leave group?';
|
||
|
||
@override
|
||
String get groupsLeaveConfirmBody =>
|
||
'Others will see that you\'ve left. Your history stays, but you won\'t receive new messages and someone will have to invite you back.';
|
||
|
||
@override
|
||
String get groupsLeaveAction => 'Leave';
|
||
|
||
@override
|
||
String groupsLeaveFailed(String error) {
|
||
return 'Leaving failed: $error';
|
||
}
|
||
|
||
@override
|
||
String get chatBlockedBanner =>
|
||
'This contact is blocked. You won\'t receive their messages and can\'t message them.';
|
||
|
||
@override
|
||
String get chatUnblock => 'Unblock';
|
||
|
||
@override
|
||
String chatContactBlocked(String name) {
|
||
return '$name is blocked';
|
||
}
|
||
|
||
@override
|
||
String chatContactUnblocked(String name) {
|
||
return '$name is unblocked';
|
||
}
|
||
|
||
@override
|
||
String reportAndBlockBody(String name) {
|
||
return 'We\'ll block $name and you\'ll stop receiving their messages. Then we\'ll show you a form to tell us what happened — we can\'t see message content, so without your description we won\'t know about it.';
|
||
}
|
||
|
||
@override
|
||
String get chatEmptyEncrypted => 'Messages are end-to-end encrypted.';
|
||
|
||
@override
|
||
String get chatEmptyNoOneElse => 'No one else can read them.';
|
||
|
||
@override
|
||
String get commonToday => 'Today';
|
||
|
||
@override
|
||
String get commonYesterday => 'Yesterday';
|
||
|
||
@override
|
||
String get chatMessageHint => 'Type a message…';
|
||
|
||
@override
|
||
String get chatDiscardRecording => 'Discard';
|
||
|
||
@override
|
||
String get chatRecording => 'Recording…';
|
||
|
||
@override
|
||
String get chatMicPermissionMissing => 'Microphone permission missing';
|
||
|
||
@override
|
||
String chatRecordingFailed(String error) {
|
||
return 'Recording failed: $error';
|
||
}
|
||
|
||
@override
|
||
String chatVoiceSendFailed(String error) {
|
||
return 'Sending voice message failed: $error';
|
||
}
|
||
|
||
@override
|
||
String get chatDeletedMessagePreview => 'Deleted message';
|
||
|
||
@override
|
||
String get chatVoiceMessagePreview => '🎤 Voice message';
|
||
|
||
@override
|
||
String get chatPhotoPreview => '📷 Photo';
|
||
|
||
@override
|
||
String get chatAttachmentPreview => '📎 Attachment';
|
||
|
||
@override
|
||
String get chatEditingMessage => 'Editing message';
|
||
|
||
@override
|
||
String get chatReply => 'Reply';
|
||
|
||
@override
|
||
String get chatActionReply => 'Reply';
|
||
|
||
@override
|
||
String get chatActionForward => 'Forward';
|
||
|
||
@override
|
||
String get forwardTitle => 'Forward to…';
|
||
|
||
@override
|
||
String get forwardSearchHint => 'Search contact or group';
|
||
|
||
@override
|
||
String get forwardEmpty => 'Nothing here';
|
||
|
||
@override
|
||
String forwardDone(String name) {
|
||
return 'Forwarded to $name';
|
||
}
|
||
|
||
@override
|
||
String forwardFailed(String error) {
|
||
return 'Forwarding failed: $error';
|
||
}
|
||
|
||
@override
|
||
String get commonCopy => 'Copy';
|
||
|
||
@override
|
||
String get commonEdit => 'Edit';
|
||
|
||
@override
|
||
String get chatDeleteForMe => 'Delete for me';
|
||
|
||
@override
|
||
String get chatDeleteForEveryone => 'Delete for everyone';
|
||
|
||
@override
|
||
String get commonOff => 'Off';
|
||
|
||
@override
|
||
String get chatDisappearing30s => '30 seconds';
|
||
|
||
@override
|
||
String get chatDisappearing5m => '5 minutes';
|
||
|
||
@override
|
||
String get chatDisappearing1h => '1 hour';
|
||
|
||
@override
|
||
String get chatDisappearing1d => '1 day';
|
||
|
||
@override
|
||
String get chatDisappearing1w => '1 week';
|
||
|
||
@override
|
||
String get chatDisappearingDescription =>
|
||
'New messages will be deleted for both you and the other person once the time is up.';
|
||
|
||
@override
|
||
String get chatDisappearingDisabled => 'Disappearing messages turned off';
|
||
|
||
@override
|
||
String chatDisappearingEnabled(String duration) {
|
||
return 'New messages will disappear after: $duration';
|
||
}
|
||
|
||
@override
|
||
String get attachmentGallery => 'Photo from gallery';
|
||
|
||
@override
|
||
String get attachmentTakePhoto => 'Take photo';
|
||
|
||
@override
|
||
String get attachmentDocument => 'Document';
|
||
|
||
@override
|
||
String attachmentTooLarge(int maxMb) {
|
||
return 'File is too large (max $maxMb MB)';
|
||
}
|
||
|
||
@override
|
||
String get attachmentKeepsMetadataTitle => 'Photo will include location';
|
||
|
||
@override
|
||
String get attachmentKeepsMetadataBody =>
|
||
'I can\'t remove metadata from this photo format (e.g. HEIC). It would be sent as the original, including where it was taken and details about the phone. Sending it via Gallery is safer, as metadata is removed there.';
|
||
|
||
@override
|
||
String get attachmentSendOriginal => 'Send original';
|
||
|
||
@override
|
||
String attachmentPickFailed(String error) {
|
||
return 'Picking attachment failed: $error';
|
||
}
|
||
|
||
@override
|
||
String attachmentSendFailed(String error) {
|
||
return 'Sending attachment failed: $error';
|
||
}
|
||
|
||
@override
|
||
String chatSendFailed(String error) {
|
||
return 'Sending failed: $error';
|
||
}
|
||
|
||
@override
|
||
String get chatMessageDeleted => 'Message deleted';
|
||
|
||
@override
|
||
String get chatEdited => 'edited';
|
||
|
||
@override
|
||
String get errorTrustRootChanged =>
|
||
'The relay\'s trust root has changed! Refusing to communicate.';
|
||
|
||
@override
|
||
String get errorRelayUnavailable => 'Relay unavailable (sender certificate)';
|
||
|
||
@override
|
||
String get errorNotYetRegistered =>
|
||
'Šepot is still connecting to the relay — try sending again in a moment.';
|
||
|
||
@override
|
||
String get errorContactLinkIncomplete =>
|
||
'This link is incomplete — the other person created it before connecting. Ask them for a new sepot:// link.';
|
||
|
||
@override
|
||
String errorAttachmentTooLarge(int maxMb) {
|
||
return 'Attachment is too large (max $maxMb MB)';
|
||
}
|
||
|
||
@override
|
||
String get errorGroupNeedsMember => 'A group needs at least 1 member';
|
||
|
||
@override
|
||
String get errorAttachmentUnavailable =>
|
||
'The attachment is no longer on this phone';
|
||
|
||
@override
|
||
String errorGroupMaxMembers(int maxMembers) {
|
||
return 'A group can have at most $maxMembers members';
|
||
}
|
||
|
||
@override
|
||
String errorMemberNoDeliveryAddress(String displayName) {
|
||
return '$displayName has no delivery address — ask them for a new link';
|
||
}
|
||
|
||
@override
|
||
String get errorContactNoDeliveryAddress =>
|
||
'This contact has no delivery address — ask them for a new sepot:// link';
|
||
|
||
@override
|
||
String get errorIdentityKeyMismatch =>
|
||
'The identity key from the relay does NOT match this contact — possible MITM! Message not sent.';
|
||
|
||
@override
|
||
String get settingsTitle => 'Settings';
|
||
|
||
@override
|
||
String get settingsSectionGeneral => 'General';
|
||
|
||
@override
|
||
String get settingsSectionSecurity => 'Security';
|
||
|
||
@override
|
||
String get settingsChangePinTitle => 'Change PIN';
|
||
|
||
@override
|
||
String get settingsChangePinSubtitle => '6-digit PIN for unlocking';
|
||
|
||
@override
|
||
String get settingsAutoLockTitle => 'Auto-lock';
|
||
|
||
@override
|
||
String get settingsAutoLock5min => 'After 5 minutes';
|
||
|
||
@override
|
||
String get settingsDecoyPinTitle => 'Duress PIN';
|
||
|
||
@override
|
||
String get settingsDecoyPinSetSubtitle => 'Set — opens an empty app';
|
||
|
||
@override
|
||
String get settingsDecoyPinUnsetSubtitle =>
|
||
'A second PIN that opens an empty app';
|
||
|
||
@override
|
||
String get settingsSectionNotifications => 'Notifications';
|
||
|
||
@override
|
||
String get settingsSectionConnection => 'Connection';
|
||
|
||
@override
|
||
String get settingsSectionPrivacy => 'Privacy';
|
||
|
||
@override
|
||
String get settingsReadReceiptsTitle => 'Read receipts';
|
||
|
||
@override
|
||
String get settingsReadReceiptsSubtitle =>
|
||
'Let others see when you\'ve read their messages (off by default)';
|
||
|
||
@override
|
||
String get settingsScreenSecurityTitle => 'Screen security';
|
||
|
||
@override
|
||
String get settingsScreenSecuritySubtitle =>
|
||
'Block screenshots and hide content in the app switcher';
|
||
|
||
@override
|
||
String get settingsSectionBackup => 'Key backup';
|
||
|
||
@override
|
||
String get settingsSeedPhraseTitle => 'Recovery phrase';
|
||
|
||
@override
|
||
String get settingsSeedPhraseSubtitle => '24 words to restore your identity';
|
||
|
||
@override
|
||
String get settingsBackupExportTitle => 'Back up history';
|
||
|
||
@override
|
||
String get settingsBackupExportSubtitle =>
|
||
'Encrypted file with your contacts and messages';
|
||
|
||
@override
|
||
String get settingsBackupImportTitle => 'Restore from backup';
|
||
|
||
@override
|
||
String get settingsBackupImportSubtitle =>
|
||
'Load a backup (only with your identity)';
|
||
|
||
@override
|
||
String get settingsSectionSafety => 'Safety';
|
||
|
||
@override
|
||
String get settingsReportAbuseTitle => 'Report abuse';
|
||
|
||
@override
|
||
String get settingsReportAbuseSubtitle =>
|
||
'Harassment, fraud, child endangerment';
|
||
|
||
@override
|
||
String get settingsChildSafetyTitle => 'Child safety standards';
|
||
|
||
@override
|
||
String get settingsChildSafetySubtitle => 'How we respond to child abuse';
|
||
|
||
@override
|
||
String get settingsSectionAbout => 'About';
|
||
|
||
@override
|
||
String get commonAppName => 'Šepot';
|
||
|
||
@override
|
||
String settingsVersion(String version) {
|
||
return 'Version $version';
|
||
}
|
||
|
||
@override
|
||
String get settingsLicenseTitle => 'License';
|
||
|
||
@override
|
||
String get settingsLicenseSubtitle => 'AGPL-3.0';
|
||
|
||
@override
|
||
String get settingsPrivacyPolicyTitle => 'Privacy policy';
|
||
|
||
@override
|
||
String get settingsPrivacyPolicySubtitle =>
|
||
'What we know about you (and what we don\'t)';
|
||
|
||
@override
|
||
String get settingsTermsTitle => 'Terms of use';
|
||
|
||
@override
|
||
String get settingsTermsSubtitle => 'sepot.cz/podminky';
|
||
|
||
@override
|
||
String get settingsDataDeletionTitle => 'Data deletion';
|
||
|
||
@override
|
||
String get settingsDataDeletionSubtitle => 'How to request erasure';
|
||
|
||
@override
|
||
String get settingsDeleteAllDataButton => 'Delete all data';
|
||
|
||
@override
|
||
String settingsLicenseBody(String supportEmail) {
|
||
return 'Šepot is distributed under the GNU Affero General Public License version 3 (AGPL-3.0). It uses the libsignal library, also AGPL-3.0.\n\nTo get the source code corresponding to this version, write to $supportEmail and we\'ll send it to you.';
|
||
}
|
||
|
||
@override
|
||
String get commonClose => 'Close';
|
||
|
||
@override
|
||
String get settingsIdCopied => 'ID copied';
|
||
|
||
@override
|
||
String settingsFingerprint(String fingerprint) {
|
||
return 'Fingerprint: $fingerprint';
|
||
}
|
||
|
||
@override
|
||
String get backupShareSubject => 'Šepot — encrypted backup';
|
||
|
||
@override
|
||
String backupExportFailed(String error) {
|
||
return 'Backup failed: $error';
|
||
}
|
||
|
||
@override
|
||
String backupRestoredCount(int count) {
|
||
String _temp0 = intl.Intl.pluralLogic(
|
||
count,
|
||
locale: localeName,
|
||
other: 'Restored $count conversations from the backup',
|
||
one: 'Restored 1 conversation from the backup',
|
||
);
|
||
return '$_temp0';
|
||
}
|
||
|
||
@override
|
||
String backupImportFailed(String error) {
|
||
return 'Restoring from backup failed: $error';
|
||
}
|
||
|
||
@override
|
||
String get settingsDecoyPinExplain =>
|
||
'Entering this PIN opens the app empty — without your contacts and messages. It must be different from your regular PIN.';
|
||
|
||
@override
|
||
String get commonConfirm => 'Confirm';
|
||
|
||
@override
|
||
String get commonSet => 'Set';
|
||
|
||
@override
|
||
String get settingsDecoyPinEnabled => 'Duress PIN set';
|
||
|
||
@override
|
||
String get settingsDecoyPinConflict =>
|
||
'The duress PIN must differ from your regular PIN';
|
||
|
||
@override
|
||
String get settingsDecoyPinDisabled => 'Duress PIN removed';
|
||
|
||
@override
|
||
String get settingsSeedPhraseNotFound => 'Recovery phrase not found';
|
||
|
||
@override
|
||
String get settingsSeedPhraseWarning =>
|
||
'These words are the only backup of your identity. Don\'t show them to anyone!';
|
||
|
||
@override
|
||
String settingsSeedWordChip(int index, String word) {
|
||
return '$index. $word';
|
||
}
|
||
|
||
@override
|
||
String get settingsAboutTagline => 'Šepot — Private Messenger';
|
||
|
||
@override
|
||
String get settingsAboutBody =>
|
||
'An open-source end-to-end encrypted messenger.\n\nCryptography:\n• X25519 (key exchange)\n• XChaCha20-Poly1305 (encryption)\n• Ed25519 (signatures)\n\n© 2026 ajtak.it';
|
||
|
||
@override
|
||
String get settingsDeleteAccountTitle => 'Delete account and all data?';
|
||
|
||
@override
|
||
String get settingsDeleteAccountBody =>
|
||
'This action cannot be undone. All messages, contacts and keys will be deleted from this device and the account will be deregistered from the server. If you don\'t have your recovery phrase, you\'ll lose your identity.';
|
||
|
||
@override
|
||
String get settingsDeleteAccountServerOffline =>
|
||
'The server is unreachable right now — data on this device has been deleted, but the server registration remains. Write to podpora@sepot.cz and we\'ll delete the rest.';
|
||
|
||
@override
|
||
String get settingsDeleteAllConfirm => 'Delete everything';
|
||
|
||
@override
|
||
String groupsCreateFailed(String error) {
|
||
return 'Couldn\'t create the group: $error';
|
||
}
|
||
|
||
@override
|
||
String get groupsNewGroupTitle => 'New group';
|
||
|
||
@override
|
||
String get groupsCreateAction => 'Create';
|
||
|
||
@override
|
||
String groupsMembersCounter(int selectedCount, int maxMembers) {
|
||
return 'Members ($selectedCount/$maxMembers)';
|
||
}
|
||
|
||
@override
|
||
String get groupsEmptyContactsHint =>
|
||
'Add some contacts first — a group is made of people you can already message.';
|
||
|
||
@override
|
||
String get groupsMemberMissingAddress =>
|
||
'Missing delivery address — ask them for a new link';
|
||
|
||
@override
|
||
String attachmentSizeBytes(int bytes) {
|
||
return '$bytes B';
|
||
}
|
||
|
||
@override
|
||
String attachmentSizeKb(String kilobytes) {
|
||
return '$kilobytes KB';
|
||
}
|
||
|
||
@override
|
||
String attachmentSizeMb(String megabytes) {
|
||
return '$megabytes MB';
|
||
}
|
||
|
||
@override
|
||
String get attachmentDownloadFailedTapToRetry =>
|
||
'Download failed — tap to retry';
|
||
|
||
@override
|
||
String get attachmentDownloadFailed => 'Download failed';
|
||
|
||
@override
|
||
String get attachmentDownloading => 'Downloading…';
|
||
|
||
@override
|
||
String get attachmentSharedFileFallbackName => 'file';
|
||
|
||
@override
|
||
String attachmentOpenFailed(String error) {
|
||
return 'Opening attachment failed: $error';
|
||
}
|
||
|
||
@override
|
||
String get commonFile => 'File';
|
||
|
||
@override
|
||
String get chatListNewConversation => 'New conversation';
|
||
|
||
@override
|
||
String get chatListReadReceiptPreview => 'Read';
|
||
|
||
@override
|
||
String get chatListDraft => 'Draft';
|
||
|
||
@override
|
||
String get notesTitle => 'Note to self';
|
||
|
||
@override
|
||
String get notesSubtitle => 'Only on this phone, encrypted';
|
||
|
||
@override
|
||
String get callVoice => 'Call';
|
||
|
||
@override
|
||
String get callVideo => 'Video call';
|
||
|
||
@override
|
||
String get callStatusRinging => 'Ringing…';
|
||
|
||
@override
|
||
String get callIncomingVoice => 'Incoming call';
|
||
|
||
@override
|
||
String get callIncomingVideo => 'Incoming video call';
|
||
|
||
@override
|
||
String get callStatusConnecting => 'Connecting…';
|
||
|
||
@override
|
||
String get callEnded => 'Call ended';
|
||
|
||
@override
|
||
String get callEndedBusy => 'Busy';
|
||
|
||
@override
|
||
String get callEndedRejected => 'Call declined';
|
||
|
||
@override
|
||
String get callEndedUnanswered => 'No answer';
|
||
|
||
@override
|
||
String get callEndedFailed => 'Couldn\'t connect';
|
||
|
||
@override
|
||
String get callEncrypted => 'End-to-end encrypted';
|
||
|
||
@override
|
||
String get callAccept => 'Accept';
|
||
|
||
@override
|
||
String get callReject => 'Decline';
|
||
|
||
@override
|
||
String get callMute => 'Mute';
|
||
|
||
@override
|
||
String get callSpeaker => 'Speaker';
|
||
|
||
@override
|
||
String get callCamera => 'Turn off camera';
|
||
|
||
@override
|
||
String get callSwitchCamera => 'Switch camera';
|
||
|
||
@override
|
||
String get callHangUp => 'Hang up';
|
||
|
||
@override
|
||
String get callLogMissed => 'Missed call';
|
||
|
||
@override
|
||
String get callLogUnanswered => 'Unanswered call';
|
||
|
||
@override
|
||
String get callLogRejected => 'Declined call';
|
||
|
||
@override
|
||
String get callLogBusy => 'Busy';
|
||
|
||
@override
|
||
String get callLogFailed => 'Call failed';
|
||
|
||
@override
|
||
String callLogVoice(String duration) {
|
||
return 'Call · $duration';
|
||
}
|
||
|
||
@override
|
||
String callLogVideo(String duration) {
|
||
return 'Video call · $duration';
|
||
}
|
||
|
||
@override
|
||
String get chatListTimeNow => 'now';
|
||
|
||
@override
|
||
String chatListTimeMinutes(int minutes) {
|
||
return '$minutes min';
|
||
}
|
||
|
||
@override
|
||
String get qrScanTitle => 'Scan QR code';
|
||
|
||
@override
|
||
String get qrScanInstruction => 'Point the camera at your contact\'s QR code';
|
||
|
||
@override
|
||
String get qrScanHint => 'The QR code contains the contact\'s public key';
|
||
|
||
@override
|
||
String get qrNewContactTitle => 'New contact';
|
||
|
||
@override
|
||
String qrContactAdded(String name) {
|
||
return '$name added';
|
||
}
|
||
|
||
@override
|
||
String get commonAdd => 'Add';
|
||
|
||
@override
|
||
String get onboardingWelcomeTitle => 'Welcome to Šepot';
|
||
|
||
@override
|
||
String get onboardingWelcomeSubtitle =>
|
||
'A private messenger with end-to-end encryption.\nNo phone number. No email.\nJust your keys.';
|
||
|
||
@override
|
||
String get onboardingStart => 'Get started';
|
||
|
||
@override
|
||
String get onboardingRestoreExisting =>
|
||
'I already have an account — restore from recovery phrase';
|
||
|
||
@override
|
||
String get onboardingEncryptionTitle => 'Your messages, your keys';
|
||
|
||
@override
|
||
String get onboardingFeatureSignalTitle => 'Signal protocol';
|
||
|
||
@override
|
||
String get onboardingFeatureSignalSubtitle =>
|
||
'X3DH + Double Ratchet, forward secrecy';
|
||
|
||
@override
|
||
String get onboardingFeaturePqTitle => 'Post-quantum protection';
|
||
|
||
@override
|
||
String get onboardingFeaturePqSubtitle =>
|
||
'Kyber (PQXDH) from the first message';
|
||
|
||
@override
|
||
String get onboardingFeatureLocalKeysTitle => 'Keys stay on your device';
|
||
|
||
@override
|
||
String get onboardingFeatureLocalKeysSubtitle => 'No server ever sees them';
|
||
|
||
@override
|
||
String get onboardingFeatureDisappearingSubtitle => 'Deleted automatically';
|
||
|
||
@override
|
||
String get commonContinue => 'Continue';
|
||
|
||
@override
|
||
String get onboardingIdentityTitle => 'Create your identity';
|
||
|
||
@override
|
||
String get onboardingIdentitySubtitle =>
|
||
'No email or phone. Just a name and cryptographic keys.';
|
||
|
||
@override
|
||
String get onboardingDisplayNameLabel => 'Display name';
|
||
|
||
@override
|
||
String get onboardingDisplayNameHint => 'e.g. John';
|
||
|
||
@override
|
||
String onboardingSeedPhraseWarning(int count) {
|
||
return 'Write down these $count words. They\'re the only backup of your keys!';
|
||
}
|
||
|
||
@override
|
||
String get onboardingSeedSavedConfirm =>
|
||
'I confirm I\'ve stored the phrase safely';
|
||
|
||
@override
|
||
String get onboardingGenerateKeys => 'Generate keys';
|
||
|
||
@override
|
||
String get verifyMismatchTitle => 'Numbers DO NOT match';
|
||
|
||
@override
|
||
String verifyMatchBody(String contactName) {
|
||
return 'The keys match. $contactName is a verified contact.';
|
||
}
|
||
|
||
@override
|
||
String get verifyMismatchBody =>
|
||
'The safety numbers don\'t match. Someone may be intercepting your connection (MITM), or you\'re scanning a different contact\'s code. Do NOT send sensitive messages and verify each other again over a different channel.';
|
||
|
||
@override
|
||
String get commonUnderstood => 'Got it';
|
||
|
||
@override
|
||
String get verifyManualConfirmTitle => 'Mark as verified?';
|
||
|
||
@override
|
||
String get verifyManualConfirmBody =>
|
||
'Confirm only if you\'ve compared the digits with the other person over another trusted channel (in person, on a call…) and they match.';
|
||
|
||
@override
|
||
String get verifyManualConfirmAction => 'They match — verify';
|
||
|
||
@override
|
||
String get verifyTitle => 'Verify contact';
|
||
|
||
@override
|
||
String get verifyContactVerifiedBanner => 'This contact is verified';
|
||
|
||
@override
|
||
String verifyIntro(String contactName) {
|
||
return 'Compare this number with $contactName. If it matches, no one is eavesdropping on your encryption. The fastest way is to scan each other\'s QR codes.';
|
||
}
|
||
|
||
@override
|
||
String get verifyScanButton => 'Scan their code';
|
||
|
||
@override
|
||
String get verifyManualButton => 'Digits match — mark manually';
|
||
|
||
@override
|
||
String get verifyUnverifyButton => 'Clear verification';
|
||
|
||
@override
|
||
String get verifyScanScreenTitle => 'Scan verification QR';
|
||
|
||
@override
|
||
String get reportTitle => 'Report';
|
||
|
||
@override
|
||
String get reportSubmitted => 'Report submitted';
|
||
|
||
@override
|
||
String get reportSubmittedChildSafety =>
|
||
'We handle these reports with priority. If a child is in immediate danger, call your local police or a child helpline.';
|
||
|
||
@override
|
||
String get reportSubmittedThanks =>
|
||
'Thanks. We\'ll look into it as soon as possible.';
|
||
|
||
@override
|
||
String get commonDone => 'Done';
|
||
|
||
@override
|
||
String get reportPanelE2eNotice =>
|
||
'Messages are end-to-end encrypted, so we can\'t see their content even now. Please describe in your own words what happened. Don\'t paste message content or links to it here — we\'re not allowed to store it and we don\'t need it to assess the report.';
|
||
|
||
@override
|
||
String get reportPanelCsamWarning =>
|
||
'Do NOT send us material depicting child abuse. Possessing it is a crime — for us too — and we don\'t need it for a report. It should go directly to the police or a dedicated child sexual abuse reporting hotline. Just tell us what happened — we\'ll block the account and pass the matter on.';
|
||
|
||
@override
|
||
String get reportPanelIpNotice =>
|
||
'Reports aren\'t sent through the relay — they go to our web server, which will see your IP address when you submit.';
|
||
|
||
@override
|
||
String get reportCategoryHeading => 'What the report is about';
|
||
|
||
@override
|
||
String get reportDescriptionHeading => 'What happened';
|
||
|
||
@override
|
||
String get reportAttachContactId => 'Attach the reported contact\'s ID';
|
||
|
||
@override
|
||
String reportAttachContactIdNamed(String contactName) {
|
||
return 'Attach $contactName\'s ID';
|
||
}
|
||
|
||
@override
|
||
String get reportReplyToHeading => 'How to reach you (optional)';
|
||
|
||
@override
|
||
String get reportReplyToHint => 'email, in case we need to follow up';
|
||
|
||
@override
|
||
String get reportSubmitButton => 'Submit report';
|
||
|
||
@override
|
||
String get contactsTitle => 'Contacts';
|
||
|
||
@override
|
||
String get contactsAddContact => 'Add contact';
|
||
|
||
@override
|
||
String get contactsSearchHint => 'Search contacts…';
|
||
|
||
@override
|
||
String get contactsEmpty => 'No contacts yet';
|
||
|
||
@override
|
||
String get contactsNoResults => 'No results';
|
||
|
||
@override
|
||
String get contactsShareCardTitle => 'Share your Šepot ID';
|
||
|
||
@override
|
||
String get contactsShareCardSubtitle => 'Show your QR code or send a link';
|
||
|
||
@override
|
||
String get contactsAddDialogPrompt => 'Paste the contact\'s share string:';
|
||
|
||
@override
|
||
String get contactsShareStringHint => 'Paste share string…';
|
||
|
||
@override
|
||
String get contactsInvalidShareString => 'Invalid share string';
|
||
|
||
@override
|
||
String contactsAdded(String name) {
|
||
return 'Contact $name added';
|
||
}
|
||
|
||
@override
|
||
String get verifyContactSubtitle => 'Compare safety numbers';
|
||
|
||
@override
|
||
String get contactsDeleteContact => 'Delete contact';
|
||
|
||
@override
|
||
String get pinConfirmTitle => 'Confirm PIN';
|
||
|
||
@override
|
||
String get pinSetupTitle => 'Set up a PIN';
|
||
|
||
@override
|
||
String get pinConfirmSubtitle => 'Enter the PIN again to confirm';
|
||
|
||
@override
|
||
String get pinSetupSubtitle => '6-digit PIN to unlock the app';
|
||
|
||
@override
|
||
String get pinSetupFailed => 'Setting the PIN failed. Try again.';
|
||
|
||
@override
|
||
String get pinMismatchRetry => 'PINs don\'t match. Try again.';
|
||
|
||
@override
|
||
String get pinChangeCurrentTitle => 'Enter your current PIN';
|
||
|
||
@override
|
||
String get pinChangeCurrentSubtitle =>
|
||
'We\'ll verify it by unlocking your key';
|
||
|
||
@override
|
||
String get pinChangeNewTitle => 'Enter a new PIN';
|
||
|
||
@override
|
||
String get pinChangeNewSubtitle => '6 digits';
|
||
|
||
@override
|
||
String get pinChangeConfirmTitle => 'Confirm the new PIN';
|
||
|
||
@override
|
||
String get pinChangeConfirmSubtitle => 'Enter it one more time';
|
||
|
||
@override
|
||
String get pinWrong => 'Wrong PIN.';
|
||
|
||
@override
|
||
String get pinChangeMustDiffer =>
|
||
'The new PIN must differ from the current one.';
|
||
|
||
@override
|
||
String get pinMismatch => 'PINs don\'t match.';
|
||
|
||
@override
|
||
String get pinDecoyConflict =>
|
||
'This PIN already belongs to duress mode. Choose a different one.';
|
||
|
||
@override
|
||
String get pinChangeFailed => 'Changing the PIN failed. Try again.';
|
||
|
||
@override
|
||
String get pinChanged => 'PIN changed';
|
||
|
||
@override
|
||
String get errorCryptoInitTitle => 'The encryption core failed to start';
|
||
|
||
@override
|
||
String get errorStartupTitle => 'Šepot failed to start';
|
||
|
||
@override
|
||
String get errorScreenNotRenderedTitle => 'This screen failed to render';
|
||
|
||
@override
|
||
String get errorStartupBody =>
|
||
'Something went wrong right at startup. Please send me this text (long-press and copy) — it will help me find the bug.';
|
||
|
||
@override
|
||
String get errorContactFooter => 'sepot.cz · get in touch';
|
||
|
||
@override
|
||
String get pinUnlockTitle => 'Unlock Šepot';
|
||
|
||
@override
|
||
String get pinEnterPin => 'Enter PIN';
|
||
|
||
@override
|
||
String get pinUnlockWithBiometrics => 'Unlock with biometrics';
|
||
|
||
@override
|
||
String get pinWrong2 => 'Wrong PIN';
|
||
|
||
@override
|
||
String get pinUnlockError => 'Unlock error';
|
||
|
||
@override
|
||
String get pushTitle => 'Push notifications';
|
||
|
||
@override
|
||
String get pushModeOffDesc => 'Messages arrive only after you open the app.';
|
||
|
||
@override
|
||
String get pushModeUp => 'UnifiedPush (no Google)';
|
||
|
||
@override
|
||
String get pushModeUpDesc =>
|
||
'De-Googled — needs the ntfy app (F-Droid/Play).';
|
||
|
||
@override
|
||
String get pushModeFcm => 'Google (FCM, default)';
|
||
|
||
@override
|
||
String get pushModeFcmDesc =>
|
||
'Reliable without an extra app. The device push token goes to Google; message content never does.';
|
||
|
||
@override
|
||
String pushSetupFailed(String error) {
|
||
return 'Setting up push failed: $error';
|
||
}
|
||
|
||
@override
|
||
String get pushHintOff =>
|
||
'Messages arrive only when you open Šepot — wake-ups aren’t set up.';
|
||
|
||
@override
|
||
String get pushHintFailed =>
|
||
'Wake-ups aren’t working; you’ll see messages only after opening Šepot.';
|
||
|
||
@override
|
||
String get pushRegistrationFailed =>
|
||
'Wake-ups aren’t arriving — the distributor refused registration. Try turning push off and on again.';
|
||
|
||
@override
|
||
String get pushNoDistributorTitle => 'No distributor';
|
||
|
||
@override
|
||
String get pushNoDistributorBody =>
|
||
'For de-Googled notifications, install a UnifiedPush distributor such as ntfy (F-Droid or Play). Then turn push on again.';
|
||
|
||
@override
|
||
String get commonOk => 'OK';
|
||
|
||
@override
|
||
String get pushPickDistributorTitle => 'Choose a distributor';
|
||
|
||
@override
|
||
String pushSubtitleUnifiedPush(String distributor) {
|
||
return 'UnifiedPush · $distributor';
|
||
}
|
||
|
||
@override
|
||
String get pushNoDistributorFallback => 'no distributor';
|
||
|
||
@override
|
||
String get pushSubtitleFcm => 'Google (FCM)';
|
||
|
||
@override
|
||
String get restoreErrorNameRequired => 'Enter a display name.';
|
||
|
||
@override
|
||
String restoreErrorWordCount(int wordCount, int requiredWords) {
|
||
String _temp0 = intl.Intl.pluralLogic(
|
||
wordCount,
|
||
locale: localeName,
|
||
other: 'The phrase has $wordCount words, $requiredWords are needed.',
|
||
one: 'The phrase has 1 word, $requiredWords are needed.',
|
||
);
|
||
return '$_temp0';
|
||
}
|
||
|
||
@override
|
||
String get restoreErrorInvalidPhrase =>
|
||
'The phrase isn\'t valid — check the words and their order.';
|
||
|
||
@override
|
||
String restoreErrorFailed(String error) {
|
||
return 'Restore failed: $error';
|
||
}
|
||
|
||
@override
|
||
String get restoreTitle => 'Restore account';
|
||
|
||
@override
|
||
String get restoreHeading => 'Enter your recovery phrase';
|
||
|
||
@override
|
||
String restoreIntro(int wordCount) {
|
||
return '$wordCount words from the backup created when you set up your account. This restores your identity (same SEP code — your contacts will still recognize you).';
|
||
}
|
||
|
||
@override
|
||
String get restoreHistoryWarning =>
|
||
'Message history won\'t be restored — it\'s stored only on the original device.';
|
||
|
||
@override
|
||
String get restorePhraseHint => 'word1 word2 word3 …';
|
||
|
||
@override
|
||
String restoreWordCountHelper(int wordCount, int requiredWords) {
|
||
return '$wordCount / $requiredWords words';
|
||
}
|
||
|
||
@override
|
||
String chatListArchivedCount(int count) {
|
||
return 'Archived ($count)';
|
||
}
|
||
|
||
@override
|
||
String get chatListEmptyTitle => 'No conversations yet';
|
||
|
||
@override
|
||
String get chatListEmptySubtitle => 'Add a contact and start whispering!';
|
||
|
||
@override
|
||
String get chatListUnmute => 'Unmute';
|
||
|
||
@override
|
||
String get chatListMute => 'Mute';
|
||
|
||
@override
|
||
String get chatListArchive => 'Archive';
|
||
|
||
@override
|
||
String get qrShareTitle => 'My Šepot ID';
|
||
|
||
@override
|
||
String get qrShareConnectingTitle => 'Connecting to the relay…';
|
||
|
||
@override
|
||
String get qrShareConnectingBody =>
|
||
'Your QR code and link will appear once Šepot connects for the first time. Just a moment — it only takes a few seconds.';
|
||
|
||
@override
|
||
String get qrIdentityNotFound => 'Identity not found';
|
||
|
||
@override
|
||
String get commonCopiedToClipboard => 'Copied to clipboard';
|
||
|
||
@override
|
||
String qrShareInviteMessage(String shareString) {
|
||
return 'Add me on Šepot!\n\n$shareString';
|
||
}
|
||
|
||
@override
|
||
String get commonShare => 'Share';
|
||
|
||
@override
|
||
String get qrShareInfo =>
|
||
'Your contact scans your QR code or pastes the share string into the app.';
|
||
|
||
@override
|
||
String get reportCategoryChildSafety => 'Child endangerment';
|
||
|
||
@override
|
||
String get reportCategoryChildSafetyHint =>
|
||
'Describe the situation in your own words. Don\'t paste message content or links to material.';
|
||
|
||
@override
|
||
String get reportCategoryHarassment => 'Harassment or threats';
|
||
|
||
@override
|
||
String get reportCategoryHarassmentHint =>
|
||
'Someone is intimidating, threatening or harassing you.';
|
||
|
||
@override
|
||
String get reportCategorySpam => 'Spam';
|
||
|
||
@override
|
||
String get reportCategorySpamHint => 'Unsolicited messages, bulk sending.';
|
||
|
||
@override
|
||
String get reportCategoryFraud => 'Fraud';
|
||
|
||
@override
|
||
String get reportCategoryFraudHint =>
|
||
'An attempt to trick you out of money, keys or personal data.';
|
||
|
||
@override
|
||
String get reportCategoryOther => 'Other';
|
||
|
||
@override
|
||
String get reportCategoryOtherHint => 'Something else we should know about.';
|
||
|
||
@override
|
||
String get reportErrorEmptyDescription => 'Please describe what happened.';
|
||
|
||
@override
|
||
String reportErrorConnection(String supportEmail) {
|
||
return 'Couldn\'t reach the server. Try again, or write to $supportEmail.';
|
||
}
|
||
|
||
@override
|
||
String reportErrorRateLimited(String supportEmail) {
|
||
return 'Too many reports came from your network. Try again in an hour, or write to $supportEmail.';
|
||
}
|
||
|
||
@override
|
||
String reportErrorServer(int statusCode, String supportEmail) {
|
||
return 'Submission failed (code $statusCode). Please write to $supportEmail.';
|
||
}
|
||
|
||
@override
|
||
String get settingsAutoLockNever => 'Never';
|
||
|
||
@override
|
||
String get settingsAutoLock1min => 'After 1 minute';
|
||
|
||
@override
|
||
String get settingsAutoLock15min => 'After 15 minutes';
|
||
|
||
@override
|
||
String torToggleFailed(String error) {
|
||
return 'Toggling Tor failed: $error';
|
||
}
|
||
|
||
@override
|
||
String get torConnectionTitle => 'Connect via Tor';
|
||
|
||
@override
|
||
String get torDialogBody =>
|
||
'Traffic to the server will go through the Tor network (hides your IP address). Requires the Orbot app installed and running with an active SOCKS proxy on port 9050.\n\nWithout Orbot running, messages won\'t be sent or received. The connection is usually slower.';
|
||
|
||
@override
|
||
String get commonTurnOn => 'Turn on';
|
||
|
||
@override
|
||
String get torSubtitleOff =>
|
||
'Direct encrypted connection (WSS). Turn on to hide your IP via Tor.';
|
||
|
||
@override
|
||
String get torStatusConnected => 'Connected via Tor (.onion).';
|
||
|
||
@override
|
||
String get torStatusConnecting => 'Connecting via Tor… (is Orbot running?)';
|
||
|
||
@override
|
||
String get torStatusWaiting => 'Via Tor — waiting for Orbot (SOCKS 9050).';
|
||
|
||
@override
|
||
String get biometricsPinRequiredFirst =>
|
||
'Set a PIN first — biometrics only complement it.';
|
||
|
||
@override
|
||
String get biometricsStorageLocked =>
|
||
'Storage is locked — unlock the app with your PIN.';
|
||
|
||
@override
|
||
String get biometricsNotAvailable => 'This device has no biometrics set up.';
|
||
|
||
@override
|
||
String get biometricsEnrollPromptReason =>
|
||
'Confirm enabling biometric unlock';
|
||
|
||
@override
|
||
String biometricsSetupFailed(String error) {
|
||
return 'Couldn\'t set up biometrics: $error';
|
||
}
|
||
|
||
@override
|
||
String get biometricsTileTitle => 'Biometrics';
|
||
|
||
@override
|
||
String get biometricsTileSubtitle =>
|
||
'Unlock with fingerprint / face (PIN stays as a backup)';
|
||
|
||
@override
|
||
String get backupErrorCorruptedFile => 'Corrupted backup file';
|
||
|
||
@override
|
||
String get backupErrorUnknownFormat => 'Unrecognized backup format';
|
||
|
||
@override
|
||
String get backupErrorWrongIdentity =>
|
||
'Can\'t decrypt this backup — does it belong to a different identity?';
|
||
|
||
@override
|
||
String attachmentSharedImageFilename(String ext) {
|
||
return 'sepot-image.$ext';
|
||
}
|
||
|
||
@override
|
||
String get attachmentDecryptFailed => 'Couldn\'t decrypt the attachment';
|
||
|
||
@override
|
||
String get pushActionOpen => 'Open';
|
||
|
||
@override
|
||
String get pushChannelMessagesName => 'Messages';
|
||
|
||
@override
|
||
String get pushChannelMessagesDescription =>
|
||
'Alerts about new messages (no content)';
|
||
|
||
@override
|
||
String pushNewMessageFrom(String senderName) {
|
||
return 'New message from $senderName';
|
||
}
|
||
|
||
@override
|
||
String get pushNewMessages => 'You have new messages';
|
||
|
||
@override
|
||
String get archiveTitle => 'Archived';
|
||
|
||
@override
|
||
String get archiveEmpty => 'No archived conversations';
|
||
|
||
@override
|
||
String get archiveUnarchive => 'Unarchive';
|
||
|
||
@override
|
||
String restoreErrorMnemonicWordCount(int count, int expected) {
|
||
return 'The phrase has $count words, expected $expected';
|
||
}
|
||
|
||
@override
|
||
String restoreErrorInvalidMnemonic(String message) {
|
||
return 'Invalid phrase: $message';
|
||
}
|
||
|
||
@override
|
||
String get contactsErrorAlreadyExists => 'Contact already exists';
|
||
|
||
@override
|
||
String get commonAppTagline => 'Private messenger';
|
||
|
||
@override
|
||
String get commonE2eBadgeCompact => 'E2E';
|
||
|
||
@override
|
||
String get commonE2eBadgeFull => 'End-to-end encrypted';
|
||
|
||
@override
|
||
String get photoPreviewCaptionHint => 'Add a caption…';
|
||
|
||
@override
|
||
String get photoPreviewDraw => 'Draw';
|
||
|
||
@override
|
||
String get photoPreviewAddText => 'Add text';
|
||
|
||
@override
|
||
String get photoPreviewRotate => 'Rotate';
|
||
|
||
@override
|
||
String get photoPreviewUndo => 'Undo';
|
||
|
||
@override
|
||
String get photoPreviewSend => 'Send';
|
||
|
||
@override
|
||
String get photoPreviewTextDialogTitle => 'Text on photo';
|
||
|
||
@override
|
||
String get photoPreviewRemoveText => 'Remove';
|
||
|
||
@override
|
||
String get photoPreviewDecodeFailed => 'Couldn\'t load the photo';
|
||
|
||
@override
|
||
String get chatActionInfo => 'Message info';
|
||
|
||
@override
|
||
String get messageInfoSent => 'Sent';
|
||
|
||
@override
|
||
String get messageInfoDelivered => 'Delivered';
|
||
|
||
@override
|
||
String get messageInfoRead => 'Read';
|
||
|
||
@override
|
||
String get messageInfoPending => 'not yet';
|
||
|
||
@override
|
||
String get messageInfoReadReceiptsOff =>
|
||
'You only see when people read your messages if you share read receipts yourself (Settings).';
|
||
|
||
@override
|
||
String chatStatusReadAt(String time) {
|
||
return 'Read $time';
|
||
}
|
||
|
||
@override
|
||
String chatStatusDeliveredAt(String time) {
|
||
return 'Delivered $time';
|
||
}
|
||
|
||
@override
|
||
String get groupsAddMembers => 'Add members';
|
||
|
||
@override
|
||
String get groupsAddMembersAction => 'Add';
|
||
|
||
@override
|
||
String groupsAddMembersFailed(String error) {
|
||
return 'Could not add members: $error';
|
||
}
|
||
|
||
@override
|
||
String get groupsNoContactsToAdd =>
|
||
'All your contacts are already in this group. Add someone new to your contacts via QR code first.';
|
||
|
||
@override
|
||
String get navChats => 'Chats';
|
||
|
||
@override
|
||
String get chatListNewChat => 'New chat';
|
||
|
||
@override
|
||
String get chatListSearchHint => 'Search chats and messages';
|
||
|
||
@override
|
||
String get chatFilterAll => 'All';
|
||
|
||
@override
|
||
String get chatFilterUnread => 'Unread';
|
||
|
||
@override
|
||
String get chatFilterGroups => 'Groups';
|
||
|
||
@override
|
||
String get chatFilterArchive => 'Archive';
|
||
|
||
@override
|
||
String get chatListNoResults => 'Nothing found.';
|
||
|
||
@override
|
||
String get chatListFilterEmpty => 'Nothing here yet.';
|
||
|
||
@override
|
||
String get chatListPin => 'Pin';
|
||
|
||
@override
|
||
String get chatListUnpin => 'Unpin';
|
||
|
||
@override
|
||
String get chatOpenProfile => 'View profile';
|
||
|
||
@override
|
||
String get groupsProfile => 'Group info';
|
||
|
||
@override
|
||
String get chatSearchHint => 'Search in chat';
|
||
|
||
@override
|
||
String get chatSearchNoMatches => 'None';
|
||
|
||
@override
|
||
String chatSearchCounter(int current, int total) {
|
||
return '$current of $total';
|
||
}
|
||
|
||
@override
|
||
String get chatSearchOlder => 'Older match';
|
||
|
||
@override
|
||
String get chatSearchNewer => 'Newer match';
|
||
|
||
@override
|
||
String chatUnreadDivider(int count) {
|
||
String _temp0 = intl.Intl.pluralLogic(
|
||
count,
|
||
locale: localeName,
|
||
other: '$count new messages',
|
||
one: '1 new message',
|
||
);
|
||
return '$_temp0';
|
||
}
|
||
|
||
@override
|
||
String get chatJumpToLatest => 'Jump to latest';
|
||
|
||
@override
|
||
String get chatAttach => 'Attach';
|
||
|
||
@override
|
||
String get chatSend => 'Send';
|
||
|
||
@override
|
||
String get chatRecordVoice => 'Record voice message';
|
||
|
||
@override
|
||
String get profileSharedMedia => 'Shared media';
|
||
|
||
@override
|
||
String get profileMessage => 'Message';
|
||
|
||
@override
|
||
String get profileSearch => 'Search';
|
||
|
||
@override
|
||
String get profileUnmute => 'Unmute';
|
||
|
||
@override
|
||
String get profileDisappearing => 'Disappear';
|
||
|
||
@override
|
||
String get profileCommonGroups => 'Groups in common';
|
||
|
||
@override
|
||
String get profileSafetyNumber => 'Safety number';
|
||
|
||
@override
|
||
String get profileSafetyNumberHint => 'Compare in person or by QR code';
|
||
|
||
@override
|
||
String get profileVerifiedInPerson => 'Verified in person';
|
||
|
||
@override
|
||
String get profileVerifyNow => 'Verify contact';
|
||
|
||
@override
|
||
String get profileAdd => 'Add';
|
||
|
||
@override
|
||
String profileGroupSubtitle(String members, String date) {
|
||
return 'Group · $members · created $date';
|
||
}
|
||
|
||
@override
|
||
String profileMembersOfMax(int count, int max) {
|
||
return '$count of $max';
|
||
}
|
||
|
||
@override
|
||
String get chatTyping => 'typing…';
|
||
|
||
@override
|
||
String chatTypingNamed(String name) {
|
||
return '$name is typing…';
|
||
}
|
||
|
||
@override
|
||
String get chatTypingSeveral => 'Several people are typing…';
|
||
|
||
@override
|
||
String get settingsTypingTitle => 'Typing indicators';
|
||
|
||
@override
|
||
String get settingsTypingSubtitle =>
|
||
'Mutual — if you don\'t share it, you don\'t see it (off by default)';
|
||
|
||
@override
|
||
String get pollAttach => 'Poll';
|
||
|
||
@override
|
||
String get pollCreateTitle => 'New poll';
|
||
|
||
@override
|
||
String get pollQuestion => 'Question';
|
||
|
||
@override
|
||
String pollOptionHint(int number) {
|
||
return 'Option $number';
|
||
}
|
||
|
||
@override
|
||
String get pollAddOption => 'Add option';
|
||
|
||
@override
|
||
String get pollRemoveOption => 'Remove option';
|
||
|
||
@override
|
||
String get pollAllowMultiple => 'Allow multiple answers';
|
||
|
||
@override
|
||
String get pollSingle => 'Poll';
|
||
|
||
@override
|
||
String get pollMulti => 'Poll, multiple choice';
|
||
|
||
@override
|
||
String pollVoters(int count) {
|
||
String _temp0 = intl.Intl.pluralLogic(
|
||
count,
|
||
locale: localeName,
|
||
other: '$count votes',
|
||
one: '1 vote',
|
||
zero: 'no votes yet',
|
||
);
|
||
return '$_temp0';
|
||
}
|
||
|
||
@override
|
||
String pollFallback(String question) {
|
||
return 'Poll: $question';
|
||
}
|
||
|
||
@override
|
||
String get pollFallbackUpdate => 'Update Šepot to vote.';
|
||
|
||
@override
|
||
String get profilePhotoEdit => 'Change profile photo';
|
||
|
||
@override
|
||
String get profilePhotoPick => 'Choose photo';
|
||
|
||
@override
|
||
String get profilePhotoRemove => 'Remove photo';
|
||
|
||
@override
|
||
String get profilePhotoHint =>
|
||
'Only people you chat with will see it — end-to-end encrypted like your messages. No location or photo metadata is sent.';
|
||
|
||
@override
|
||
String profilePhotoFailed(String error) {
|
||
return 'Could not set photo: $error';
|
||
}
|
||
}
|