mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-10-23 23:46:41 +00:00
Merge branch 'master' into ep/p2p-group-signing
This commit is contained in:
65 files changed
+1237
-697
No files matched your search
@@ -429,6 +429,7 @@ final class ChatModel: ObservableObject {
|
||||
// audio recording and playback
|
||||
@Published var stopPreviousRecPlay: URL? = nil // coordinates currently playing source
|
||||
@Published var draft: ComposeState?
|
||||
// chat id with chat scope, see draftChatId() - group chat and its support chats have the same chat id
|
||||
@Published var draftChatId: String?
|
||||
@Published var networkInfo = UserNetworkInfo(networkType: .other, online: true)
|
||||
// usage conditions
|
||||
|
||||
@@ -780,7 +780,7 @@ struct ChatView: View {
|
||||
}
|
||||
updateAvailableContent()
|
||||
}
|
||||
if chatModel.draftChatId == cInfo.id && !composeState.forwarding,
|
||||
if chatModel.draftChatId == draftChatId(cInfo.id, cInfo.groupChatScope()) && !composeState.forwarding,
|
||||
let draft = chatModel.draft {
|
||||
composeState = draft
|
||||
}
|
||||
|
||||
@@ -1548,7 +1548,7 @@ struct ComposeView: View {
|
||||
let wasForwarding = composeState.forwarding
|
||||
clearState(live: live)
|
||||
if wasForwarding,
|
||||
chatModel.draftChatId == chat.chatInfo.id,
|
||||
chatModel.draftChatId == draftChatId(chat.chatInfo.id, chat.chatInfo.groupChatScope()),
|
||||
let draft = chatModel.draft {
|
||||
composeState = draft
|
||||
}
|
||||
@@ -1851,12 +1851,12 @@ struct ComposeView: View {
|
||||
// Spec: spec/client/compose.md#saveCurrentDraft
|
||||
private func saveCurrentDraft() {
|
||||
chatModel.draft = composeState
|
||||
chatModel.draftChatId = chat.id
|
||||
chatModel.draftChatId = draftChatId(chat.id, chat.chatInfo.groupChatScope())
|
||||
}
|
||||
|
||||
// Spec: spec/client/compose.md#clearCurrentDraft
|
||||
private func clearCurrentDraft() {
|
||||
if chatModel.draftChatId == chat.id {
|
||||
if chatModel.draftChatId == draftChatId(chat.id, chat.chatInfo.groupChatScope()) {
|
||||
chatModel.draft = nil
|
||||
chatModel.draftChatId = nil
|
||||
}
|
||||
|
||||
@@ -649,7 +649,13 @@ struct ChatListSearchBar: View {
|
||||
// a typed name shows a row to connect to it (as on Android mobile): with the reachable toolbar it
|
||||
// replaces the tags above the search field; in top bar mode the tags stay and it moves below (end of VStack)
|
||||
if oneHandUI, let candidate = connectNameCandidate {
|
||||
connectByNameRow(candidate)
|
||||
ConnectByNameRow(
|
||||
name: candidate,
|
||||
searchText: $searchText,
|
||||
connectNameCandidate: $connectNameCandidate,
|
||||
searchFocussed: $searchFocussed,
|
||||
dismiss: false
|
||||
)
|
||||
} else {
|
||||
ScrollView([.horizontal], showsIndicators: false) { TagsView(parentSheet: $parentSheet, searchText: $searchText) }
|
||||
}
|
||||
@@ -688,7 +694,13 @@ struct ChatListSearchBar: View {
|
||||
}
|
||||
}
|
||||
if !oneHandUI, let candidate = connectNameCandidate {
|
||||
connectByNameRow(candidate)
|
||||
ConnectByNameRow(
|
||||
name: candidate,
|
||||
searchText: $searchText,
|
||||
connectNameCandidate: $connectNameCandidate,
|
||||
searchFocussed: $searchFocussed,
|
||||
dismiss: false
|
||||
)
|
||||
}
|
||||
}
|
||||
.onChange(of: searchFocussed) { sf in
|
||||
@@ -770,33 +782,6 @@ struct ChatListSearchBar: View {
|
||||
}
|
||||
}
|
||||
|
||||
// Row shown in place of the list tags when the search text is a SimpleX name. The @ icon marks a
|
||||
// contact name, the tag icon a channel/other name; tapping hides the keyboard, connects online, and
|
||||
// clears the field.
|
||||
private func connectByNameRow(_ name: String) -> some View {
|
||||
HStack(spacing: 4) {
|
||||
Image(systemName: name.hasPrefix("@") ? "at" : "number")
|
||||
.foregroundColor(theme.colors.primary)
|
||||
Text(String.localizedStringWithFormat(NSLocalizedString("Connect to %@", comment: "new chat action"), name))
|
||||
.foregroundColor(theme.colors.primary)
|
||||
Spacer()
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.contentShape(Rectangle())
|
||||
.onTapGesture {
|
||||
searchFocussed = false
|
||||
planAndConnect(
|
||||
name,
|
||||
theme: theme,
|
||||
dismiss: false,
|
||||
cleanup: {
|
||||
searchText = ""
|
||||
connectNameCandidate = nil
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private func connect(_ link: String) {
|
||||
planAndConnect(
|
||||
link,
|
||||
@@ -812,11 +797,47 @@ struct ChatListSearchBar: View {
|
||||
}
|
||||
}
|
||||
|
||||
// Row shown when the search text is a SimpleX name — in place of the list tags in the chat list, below
|
||||
// the search field in the new chat sheet. The @ icon marks a contact name, the tag icon a channel/other
|
||||
// name; tapping hides the keyboard, connects online, and clears the field.
|
||||
struct ConnectByNameRow: View {
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
var name: String
|
||||
@Binding var searchText: String
|
||||
@Binding var connectNameCandidate: String?
|
||||
@FocusState.Binding var searchFocussed: Bool
|
||||
var dismiss: Bool
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: 4) {
|
||||
Image(systemName: name.hasPrefix("@") ? "at" : "number")
|
||||
.foregroundColor(theme.colors.primary)
|
||||
Text(String.localizedStringWithFormat(NSLocalizedString("Connect to %@", comment: "new chat action"), name))
|
||||
.foregroundColor(theme.colors.primary)
|
||||
Spacer()
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.contentShape(Rectangle())
|
||||
.onTapGesture {
|
||||
searchFocussed = false
|
||||
planAndConnect(
|
||||
name,
|
||||
theme: theme,
|
||||
dismiss: dismiss,
|
||||
cleanup: {
|
||||
searchText = ""
|
||||
connectNameCandidate = nil
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Default top-level part used to complete a bare name typed in the search field (search field only;
|
||||
// the message parser and the wire format are unchanged).
|
||||
private let DEFAULT_NAME_TLD = "testing"
|
||||
// Shortest name that offers the button, so it is discoverable but does not flash on a single letter.
|
||||
private let MIN_NAME_LENGTH = 2
|
||||
// Shortest name that offers the button, so it is discoverable but does not flash on short prefixes.
|
||||
private let MIN_NAME_LENGTH = 5
|
||||
|
||||
private func isNameLabel(_ s: String) -> Bool {
|
||||
s.count >= 1 && s.count <= 63 && s.range(of: "^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$", options: .regularExpression) != nil
|
||||
|
||||
@@ -41,6 +41,8 @@ struct NewChatSheet: View {
|
||||
@State private var searchText = ""
|
||||
@State private var searchShowingSimplexLink = false
|
||||
@State private var searchChatFilteredBySimplexLink: String? = nil
|
||||
// when the search text is a SimpleX name, the string to connect to (with @/# preserved); nil otherwise
|
||||
@State private var connectNameCandidate: String? = nil
|
||||
@State private var alert: SomeAlert?
|
||||
|
||||
// Sheet height management
|
||||
@@ -81,15 +83,25 @@ struct NewChatSheet: View {
|
||||
|
||||
private func viewBody(_ showArchive: Bool) -> some View {
|
||||
List {
|
||||
HStack {
|
||||
VStack(spacing: 12) {
|
||||
ContactsListSearchBar(
|
||||
searchMode: $searchMode,
|
||||
searchFocussed: $searchFocussed,
|
||||
searchText: $searchText,
|
||||
searchShowingSimplexLink: $searchShowingSimplexLink,
|
||||
searchChatFilteredBySimplexLink: $searchChatFilteredBySimplexLink
|
||||
searchChatFilteredBySimplexLink: $searchChatFilteredBySimplexLink,
|
||||
connectNameCandidate: $connectNameCandidate
|
||||
)
|
||||
.frame(maxWidth: .infinity)
|
||||
if let candidate = connectNameCandidate {
|
||||
ConnectByNameRow(
|
||||
name: candidate,
|
||||
searchText: $searchText,
|
||||
connectNameCandidate: $connectNameCandidate,
|
||||
searchFocussed: $searchFocussed,
|
||||
dismiss: true
|
||||
)
|
||||
}
|
||||
}
|
||||
.listRowSeparator(.hidden)
|
||||
.listRowBackground(Color.clear)
|
||||
@@ -327,6 +339,7 @@ struct ContactsListSearchBar: View {
|
||||
@Binding var searchText: String
|
||||
@Binding var searchShowingSimplexLink: Bool
|
||||
@Binding var searchChatFilteredBySimplexLink: String?
|
||||
@Binding var connectNameCandidate: String?
|
||||
@State private var ignoreSearchTextChange = false
|
||||
@AppStorage(DEFAULT_SHOW_UNREAD_AND_FAVORITES) private var showUnreadAndFavorites = false
|
||||
|
||||
@@ -381,33 +394,32 @@ struct ContactsListSearchBar: View {
|
||||
if ignoreSearchTextChange {
|
||||
ignoreSearchTextChange = false
|
||||
} else {
|
||||
switch strConnectTarget(t.trimmingCharacters(in: .whitespaces)) {
|
||||
let s = t.trimmingCharacters(in: .whitespaces)
|
||||
switch strConnectTarget(s) {
|
||||
case let .link(text, _, linkText):
|
||||
searchFocussed = false
|
||||
ignoreSearchTextChange = true
|
||||
searchText = linkText
|
||||
searchShowingSimplexLink = true
|
||||
searchChatFilteredBySimplexLink = nil
|
||||
connectNameCandidate = nil
|
||||
connect(text)
|
||||
case let .name(text, _):
|
||||
searchFocussed = false
|
||||
planAndConnect(
|
||||
text,
|
||||
theme: theme,
|
||||
dismiss: true,
|
||||
cleanup: {
|
||||
searchText = ""
|
||||
searchFocussed = false
|
||||
default:
|
||||
// A name is resolved only when its "Connect to …" row is tapped, not on every keystroke.
|
||||
// The simplex-name filter is chat-list only: this contacts/deleted view is a scoped
|
||||
// subset, so a resolved chat id (channel, business, unlisted or active-only contact)
|
||||
// may not be present in it.
|
||||
let candidate = nameSearchCandidate(s)
|
||||
connectNameCandidate = candidate
|
||||
if candidate == nil {
|
||||
if t != "" {
|
||||
searchFocussed = true
|
||||
} else {
|
||||
connectProgressManager.cancelConnectProgress()
|
||||
}
|
||||
)
|
||||
case .none:
|
||||
if t != "" {
|
||||
searchFocussed = true
|
||||
} else {
|
||||
connectProgressManager.cancelConnectProgress()
|
||||
searchShowingSimplexLink = false
|
||||
searchChatFilteredBySimplexLink = nil
|
||||
}
|
||||
searchShowingSimplexLink = false
|
||||
searchChatFilteredBySimplexLink = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -449,7 +461,9 @@ struct DeletedChats: View {
|
||||
@State private var searchText = ""
|
||||
@State private var searchShowingSimplexLink = false
|
||||
@State private var searchChatFilteredBySimplexLink: String? = nil
|
||||
|
||||
// deleted contacts are not connected to by name, so this candidate only stops per-keystroke resolution
|
||||
@State private var connectNameCandidate: String? = nil
|
||||
|
||||
var body: some View {
|
||||
List {
|
||||
ContactsListSearchBar(
|
||||
@@ -457,7 +471,8 @@ struct DeletedChats: View {
|
||||
searchFocussed: $searchFocussed,
|
||||
searchText: $searchText,
|
||||
searchShowingSimplexLink: $searchShowingSimplexLink,
|
||||
searchChatFilteredBySimplexLink: $searchChatFilteredBySimplexLink
|
||||
searchChatFilteredBySimplexLink: $searchChatFilteredBySimplexLink,
|
||||
connectNameCandidate: $connectNameCandidate
|
||||
)
|
||||
.listRowSeparator(.hidden)
|
||||
.listRowBackground(Color.clear)
|
||||
|
||||
@@ -5702,10 +5702,6 @@ This is your link for group %@!</source>
|
||||
<source>Name not found</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
<target>Мрежа и сървъри</target>
|
||||
@@ -6826,6 +6822,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Public channels - speak freely 🚀</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Push notifications" xml:space="preserve">
|
||||
<source>Push notifications</source>
|
||||
<target>Push известия</target>
|
||||
@@ -8275,10 +8275,6 @@ copied message info</note>
|
||||
<source>SimpleX name not verified</source>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX one-time invitation" xml:space="preserve">
|
||||
<source>SimpleX one-time invitation</source>
|
||||
<target>Еднократна покана за SimpleX</target>
|
||||
@@ -8288,6 +8284,10 @@ copied message info</note>
|
||||
<source>SimpleX protocols reviewed by Trail of Bits.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX relay address" xml:space="preserve">
|
||||
<source>SimpleX relay address</source>
|
||||
<note>simplex link type</note>
|
||||
|
||||
@@ -5517,10 +5517,6 @@ This is your link for group %@!</source>
|
||||
<source>Name not found</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
<target>Síť a servery</target>
|
||||
@@ -6619,6 +6615,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Public channels - speak freely 🚀</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Push notifications" xml:space="preserve">
|
||||
<source>Push notifications</source>
|
||||
<target>Nabízená oznámení</target>
|
||||
@@ -8044,10 +8044,6 @@ copied message info</note>
|
||||
<source>SimpleX name not verified</source>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX one-time invitation" xml:space="preserve">
|
||||
<source>SimpleX one-time invitation</source>
|
||||
<target>Jednorázová pozvánka SimpleX</target>
|
||||
@@ -8057,6 +8053,10 @@ copied message info</note>
|
||||
<source>SimpleX protocols reviewed by Trail of Bits.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX relay address" xml:space="preserve">
|
||||
<source>SimpleX relay address</source>
|
||||
<note>simplex link type</note>
|
||||
|
||||
@@ -4927,7 +4927,7 @@ Fehler: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="How to register a test name" xml:space="preserve">
|
||||
<source>How to register a test name</source>
|
||||
<target>Einen Test-Namen registrieren</target>
|
||||
<target>Wie man einen Test-Namen registriert</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="How to use it" xml:space="preserve">
|
||||
@@ -6062,11 +6062,6 @@ Das ist Ihr Link für die Gruppe %@!</target>
|
||||
<target>Name wurde nicht gefunden</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<target>Namen für Ihren Kanal oder Ihr Unternehmen.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
<target>Netzwerk und Server</target>
|
||||
@@ -7322,6 +7317,11 @@ Aktivieren Sie es in den *Netzwerk und Server* Einstellungen.</target>
|
||||
<target>Öffentliche Kanäle – frei sprechen 🚀</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<target>Öffentliche Namen für Ihren Kanal oder Ihr Unternehmen.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Push notifications" xml:space="preserve">
|
||||
<source>Push notifications</source>
|
||||
<target>Push-Benachrichtigungen</target>
|
||||
@@ -8933,11 +8933,6 @@ copied message info</note>
|
||||
<target>SimpleX-Name ist nicht verifiziert</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<target>SimpleX-Namen (BETA)</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX one-time invitation" xml:space="preserve">
|
||||
<source>SimpleX one-time invitation</source>
|
||||
<target>SimpleX-Einmal-Einladung</target>
|
||||
@@ -8948,6 +8943,11 @@ copied message info</note>
|
||||
<target>Die SimpleX-Protokolle wurden von Trail of Bits überprüft.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<target>Öffentliche SimpleX-Namen (BETA)</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX relay address" xml:space="preserve">
|
||||
<source>SimpleX relay address</source>
|
||||
<target>SimpleX Relais-Adresse</target>
|
||||
|
||||
@@ -6062,11 +6062,6 @@ This is your link for group %@!</target>
|
||||
<target>Name not found</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<target>Public names for your channel or business.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
<target>Network & servers</target>
|
||||
@@ -7322,6 +7317,11 @@ Enable in *Network & servers* settings.</target>
|
||||
<target>Public channels - speak freely 🚀</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<target>Public names for your channel or business.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Push notifications" xml:space="preserve">
|
||||
<source>Push notifications</source>
|
||||
<target>Push notifications</target>
|
||||
@@ -8933,11 +8933,6 @@ copied message info</note>
|
||||
<target>SimpleX name not verified</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<target>SimpleX public names (BETA)</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX one-time invitation" xml:space="preserve">
|
||||
<source>SimpleX one-time invitation</source>
|
||||
<target>SimpleX one-time invitation</target>
|
||||
@@ -8948,6 +8943,11 @@ copied message info</note>
|
||||
<target>SimpleX protocols reviewed by Trail of Bits.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<target>SimpleX public names (BETA)</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX relay address" xml:space="preserve">
|
||||
<source>SimpleX relay address</source>
|
||||
<target>SimpleX relay address</target>
|
||||
|
||||
@@ -773,10 +773,12 @@ swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add contributors." xml:space="preserve">
|
||||
<source>Add contributors.</source>
|
||||
<target>Añade colaboradores.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add description" xml:space="preserve">
|
||||
<source>Add description</source>
|
||||
<target>Añadir descripción</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add friends" xml:space="preserve">
|
||||
@@ -1453,6 +1455,7 @@ en tu red</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better channels 📢" xml:space="preserve">
|
||||
<source>Better channels 📢</source>
|
||||
<target>Canales mejorados 📢</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better groups" xml:space="preserve">
|
||||
@@ -1800,6 +1803,7 @@ set passcode view</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Channel SimpleX name" xml:space="preserve">
|
||||
<source>Channel SimpleX name</source>
|
||||
<target>Nombre SimpleX del canal</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Channel display name" xml:space="preserve">
|
||||
@@ -2658,6 +2662,7 @@ This is your own one-time link!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Create web preview." xml:space="preserve">
|
||||
<source>Create web preview.</source>
|
||||
<target>Crea previsualizaciones web.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Create your address" xml:space="preserve">
|
||||
@@ -3377,6 +3382,7 @@ alert button</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Do not require signing messages." xml:space="preserve">
|
||||
<source>Do not require signing messages.</source>
|
||||
<target>No requerir la firma de mensajes.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Do not send history to new members." xml:space="preserve">
|
||||
@@ -3416,6 +3422,7 @@ alert button</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Don't save" xml:space="preserve">
|
||||
<source>Don't save</source>
|
||||
<target>No guardar</target>
|
||||
<note>alert action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Don't show again" xml:space="preserve">
|
||||
@@ -3501,6 +3508,7 @@ chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Easier to read." xml:space="preserve">
|
||||
<source>Easier to read.</source>
|
||||
<target>Fácil de leer.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Edit" xml:space="preserve">
|
||||
@@ -3515,6 +3523,7 @@ chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Edit description" xml:space="preserve">
|
||||
<source>Edit description</source>
|
||||
<target>Editar descripción</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Edit group profile" xml:space="preserve">
|
||||
@@ -3719,6 +3728,7 @@ chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Enter description (optional)" xml:space="preserve">
|
||||
<source>Enter description (optional)</source>
|
||||
<target>Introduce descripción (opcional)</target>
|
||||
<note>placeholder</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Enter group name…" xml:space="preserve">
|
||||
@@ -4148,6 +4158,7 @@ chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error sharing address" xml:space="preserve">
|
||||
<source>Error sharing address</source>
|
||||
<target>Error compartiendo dirección</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error sharing channel" xml:space="preserve">
|
||||
@@ -4375,10 +4386,12 @@ server test error</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File servers" xml:space="preserve">
|
||||
<source>File servers</source>
|
||||
<target>Servidores de archivos</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File servers: %@" xml:space="preserve">
|
||||
<source>File servers: %@</source>
|
||||
<target>Servidores de archivos: %@</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File status" xml:space="preserve">
|
||||
@@ -4684,6 +4697,7 @@ Error: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Get SimpleX name (BETA)" xml:space="preserve">
|
||||
<source>Get SimpleX name (BETA)</source>
|
||||
<target>Obtener nombre SimpleX (BETA)</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Get link" xml:space="preserve">
|
||||
@@ -4913,6 +4927,7 @@ Error: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="How to register a test name" xml:space="preserve">
|
||||
<source>How to register a test name</source>
|
||||
<target>Cómo registrar un nombre de prueba</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="How to use it" xml:space="preserve">
|
||||
@@ -5599,6 +5614,7 @@ This is your link for group %@!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Manage your relays." xml:space="preserve">
|
||||
<source>Manage your relays.</source>
|
||||
<target>Gestiona tus servidores.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Mark deleted for everyone" xml:space="preserve">
|
||||
@@ -5818,10 +5834,12 @@ This is your link for group %@!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message signing is not required." xml:space="preserve">
|
||||
<source>Message signing is not required.</source>
|
||||
<target>Los mensajes firmados no son obligatorios.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message signing is required." xml:space="preserve">
|
||||
<source>Message signing is required.</source>
|
||||
<target>Los mensajes firmados son obligatorios.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message source remains private." xml:space="preserve">
|
||||
@@ -6044,10 +6062,6 @@ This is your link for group %@!</source>
|
||||
<target>Nombre no encontrado</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
<target>Servidores y Redes</target>
|
||||
@@ -7303,6 +7317,11 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
|
||||
<target>Canales públicos - habla con libertad 🚀</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<target>Nombres públicos para tu canal o negocio.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Push notifications" xml:space="preserve">
|
||||
<source>Push notifications</source>
|
||||
<target>Notificaciones push</target>
|
||||
@@ -7602,6 +7621,7 @@ swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Remove name" xml:space="preserve">
|
||||
<source>Remove name</source>
|
||||
<target>Eliminar nombre</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Remove passphrase from keychain?" xml:space="preserve">
|
||||
@@ -7721,6 +7741,7 @@ swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Require signing messages." xml:space="preserve">
|
||||
<source>Require signing messages.</source>
|
||||
<target>Requerir la firma de mensajes.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Required" xml:space="preserve">
|
||||
@@ -7927,6 +7948,7 @@ chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Save SimpleX name?" xml:space="preserve">
|
||||
<source>Save SimpleX name?</source>
|
||||
<target>¿Guardar el nombre SimpleX?</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Save admission settings?" xml:space="preserve">
|
||||
@@ -8737,6 +8759,7 @@ chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show encryption" xml:space="preserve">
|
||||
<source>Show encryption</source>
|
||||
<target>Mostrar cifrado</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show last messages" xml:space="preserve">
|
||||
@@ -8771,27 +8794,33 @@ chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Sign message" xml:space="preserve">
|
||||
<source>Sign message</source>
|
||||
<target>Firmar mensaje</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Sign messages" xml:space="preserve">
|
||||
<source>Sign messages</source>
|
||||
<target>Firmar mensajes</target>
|
||||
<note>chat feature</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Signature missing" xml:space="preserve">
|
||||
<source>Signature missing</source>
|
||||
<target>Falta la firma</target>
|
||||
<note>alert title
|
||||
copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Signed" xml:space="preserve">
|
||||
<source>Signed</source>
|
||||
<target>Firmado</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Signed & verified" xml:space="preserve">
|
||||
<source>Signed & verified</source>
|
||||
<target>Firmado y verificado</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Signing proves you authored this message and can't be denied later." xml:space="preserve">
|
||||
<source>Signing proves you authored this message and can't be denied later.</source>
|
||||
<target>La firma prueba que eres el autor del mensaje sin posibilidad de repudio.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX" xml:space="preserve">
|
||||
@@ -8904,10 +8933,6 @@ copied message info</note>
|
||||
<target>Nombre SimpleX no verificado</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX one-time invitation" xml:space="preserve">
|
||||
<source>SimpleX one-time invitation</source>
|
||||
<target>Invitación SimpleX de un uso</target>
|
||||
@@ -8918,6 +8943,11 @@ copied message info</note>
|
||||
<target>Protocolos de SimpleX auditados por Trail of Bits.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<target>Nombres públicos SimpleX (BETA)</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX relay address" xml:space="preserve">
|
||||
<source>SimpleX relay address</source>
|
||||
<target>Dirección de servidor SimpleX</target>
|
||||
@@ -9443,6 +9473,7 @@ Puede ocurrir por algún bug o cuando la conexión está comprometida.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="The channel required this message to be signed, but the signature is missing." xml:space="preserve">
|
||||
<source>The channel required this message to be signed, but the signature is missing.</source>
|
||||
<target>El canal requiere que el mensaje esté firmado, pero falta la firma.</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="The code you scanned is not a SimpleX link QR code." xml:space="preserve">
|
||||
@@ -9832,6 +9863,7 @@ Se te pedirá que completes la autenticación antes de activar esta función.</t
|
||||
</trans-unit>
|
||||
<trans-unit id="To verify keys with this subscriber, compare (or scan) the code on your devices." xml:space="preserve">
|
||||
<source>To verify keys with this subscriber, compare (or scan) the code on your devices.</source>
|
||||
<target>Para verificar las claves con este suscriptor, compara (o escanea) el código en ambos dispositivos.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle incognito when connecting." xml:space="preserve">
|
||||
|
||||
@@ -5401,10 +5401,6 @@ This is your link for group %@!</source>
|
||||
<source>Name not found</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
<target>Verkko ja palvelimet</target>
|
||||
@@ -6499,6 +6495,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Public channels - speak freely 🚀</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Push notifications" xml:space="preserve">
|
||||
<source>Push notifications</source>
|
||||
<target>Push-ilmoitukset</target>
|
||||
@@ -7923,10 +7923,6 @@ copied message info</note>
|
||||
<source>SimpleX name not verified</source>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX one-time invitation" xml:space="preserve">
|
||||
<source>SimpleX one-time invitation</source>
|
||||
<target>SimpleX-kertakutsu</target>
|
||||
@@ -7936,6 +7932,10 @@ copied message info</note>
|
||||
<source>SimpleX protocols reviewed by Trail of Bits.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX relay address" xml:space="preserve">
|
||||
<source>SimpleX relay address</source>
|
||||
<note>simplex link type</note>
|
||||
|
||||
@@ -6017,10 +6017,6 @@ Voici votre lien pour le groupe %@ !</target>
|
||||
<source>Name not found</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
<target>Réseau et serveurs</target>
|
||||
@@ -7271,6 +7267,10 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
|
||||
<target>Les canaux publics – parlez librement 🚀</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Push notifications" xml:space="preserve">
|
||||
<source>Push notifications</source>
|
||||
<target>Notifications push</target>
|
||||
@@ -8857,10 +8857,6 @@ copied message info</note>
|
||||
<source>SimpleX name not verified</source>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX one-time invitation" xml:space="preserve">
|
||||
<source>SimpleX one-time invitation</source>
|
||||
<target>Invitation unique SimpleX</target>
|
||||
@@ -8871,6 +8867,10 @@ copied message info</note>
|
||||
<target>Protocoles SimpleX audité par Trail of Bits.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX relay address" xml:space="preserve">
|
||||
<source>SimpleX relay address</source>
|
||||
<target>Adresse relais SimpleX</target>
|
||||
|
||||
@@ -6062,11 +6062,6 @@ Ez a saját hivatkozása a(z) %@ nevű csoporthoz!</target>
|
||||
<target>Nem található a név</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<target>Nevek a csatornákhoz vagy az üzleti profilokhoz.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
<target>Hálózat és kiszolgálók</target>
|
||||
@@ -7322,6 +7317,11 @@ Engedélyezze a *Hálózat és kiszolgálók* menüben.</target>
|
||||
<target>Nyilvános csatornák – mondja el szabadon a véleményét 🚀</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<target>Nyilvános nevek a csatornákhoz vagy az üzleti profilokhoz.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Push notifications" xml:space="preserve">
|
||||
<source>Push notifications</source>
|
||||
<target>Leküldéses értesítések</target>
|
||||
@@ -8933,11 +8933,6 @@ copied message info</note>
|
||||
<target>Nincs ellenőrizve a SimpleX-név</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<target>SimpleX-nevek (béta)</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX one-time invitation" xml:space="preserve">
|
||||
<source>SimpleX one-time invitation</source>
|
||||
<target>Egyszer használható SimpleX meghívó</target>
|
||||
@@ -8948,6 +8943,11 @@ copied message info</note>
|
||||
<target>A SimpleX protokollokat a Trail of Bits auditálta.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<target>Nyilvános SimpleX-nevek (béta)</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX relay address" xml:space="preserve">
|
||||
<source>SimpleX relay address</source>
|
||||
<target>SimpleX-átjátszó címe</target>
|
||||
|
||||
@@ -6062,11 +6062,6 @@ Questo è il tuo link per il gruppo %@!</target>
|
||||
<target>Nome non trovato</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<target>Nomi per il tuo canale o per il lavoro.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
<target>Rete e server</target>
|
||||
@@ -7322,6 +7317,11 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
<target>Canali pubblici - parla liberamente 🚀</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<target>Nomi pubblici per il tuo canale o per il lavoro.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Push notifications" xml:space="preserve">
|
||||
<source>Push notifications</source>
|
||||
<target>Notifiche push</target>
|
||||
@@ -8933,11 +8933,6 @@ copied message info</note>
|
||||
<target>Nome SimpleX non verificato</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<target>Nomi SimpleX (BETA)</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX one-time invitation" xml:space="preserve">
|
||||
<source>SimpleX one-time invitation</source>
|
||||
<target>Invito SimpleX una tantum</target>
|
||||
@@ -8948,6 +8943,11 @@ copied message info</note>
|
||||
<target>Protocolli di SimpleX esaminati da Trail of Bits.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<target>Nomi pubblici SimpleX (BETA)</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX relay address" xml:space="preserve">
|
||||
<source>SimpleX relay address</source>
|
||||
<target>Indirizzo del relay SimpleX</target>
|
||||
|
||||
@@ -5519,10 +5519,6 @@ This is your link for group %@!</source>
|
||||
<source>Name not found</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
<target>ネットワークとサーバ</target>
|
||||
@@ -6620,6 +6616,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Public channels - speak freely 🚀</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Push notifications" xml:space="preserve">
|
||||
<source>Push notifications</source>
|
||||
<target>プッシュ通知</target>
|
||||
@@ -8036,10 +8036,6 @@ copied message info</note>
|
||||
<source>SimpleX name not verified</source>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX one-time invitation" xml:space="preserve">
|
||||
<source>SimpleX one-time invitation</source>
|
||||
<target>SimpleX使い捨て招待リンク</target>
|
||||
@@ -8049,6 +8045,10 @@ copied message info</note>
|
||||
<source>SimpleX protocols reviewed by Trail of Bits.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX relay address" xml:space="preserve">
|
||||
<source>SimpleX relay address</source>
|
||||
<note>simplex link type</note>
|
||||
|
||||
@@ -5858,10 +5858,6 @@ Dit is jouw link voor groep %@!</target>
|
||||
<source>Name not found</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
<target>Netwerk & servers</target>
|
||||
@@ -7058,6 +7054,10 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
|
||||
<source>Public channels - speak freely 🚀</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Push notifications" xml:space="preserve">
|
||||
<source>Push notifications</source>
|
||||
<target>Push meldingen</target>
|
||||
@@ -8601,10 +8601,6 @@ copied message info</note>
|
||||
<source>SimpleX name not verified</source>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX one-time invitation" xml:space="preserve">
|
||||
<source>SimpleX one-time invitation</source>
|
||||
<target>Eenmalige SimpleX uitnodiging</target>
|
||||
@@ -8615,6 +8611,10 @@ copied message info</note>
|
||||
<target>SimpleX-protocollen beoordeeld door Trail of Bits.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX relay address" xml:space="preserve">
|
||||
<source>SimpleX relay address</source>
|
||||
<note>simplex link type</note>
|
||||
|
||||
@@ -5907,10 +5907,6 @@ To jest twój link do grupy %@!</target>
|
||||
<source>Name not found</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
<target>Sieć i serwery</target>
|
||||
@@ -7123,6 +7119,10 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
|
||||
<source>Public channels - speak freely 🚀</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Push notifications" xml:space="preserve">
|
||||
<source>Push notifications</source>
|
||||
<target>Powiadomienia push</target>
|
||||
@@ -8687,10 +8687,6 @@ copied message info</note>
|
||||
<source>SimpleX name not verified</source>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX one-time invitation" xml:space="preserve">
|
||||
<source>SimpleX one-time invitation</source>
|
||||
<target>Zaproszenie jednorazowe SimpleX</target>
|
||||
@@ -8701,6 +8697,10 @@ copied message info</note>
|
||||
<target>Protokoły SimpleX sprawdzone przez Trail of Bits.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX relay address" xml:space="preserve">
|
||||
<source>SimpleX relay address</source>
|
||||
<note>simplex link type</note>
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="%1$@ supported SimpleX Chat. The badge expired on %2$@." xml:space="preserve">
|
||||
<source>%1$@ supported SimpleX Chat. The badge expired on %2$@.</source>
|
||||
<target>%1$@ поддерживал(а) SimpleX Chat. Срок действия значка истёк %2$@.</target>
|
||||
<note>badge alert</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@" xml:space="preserve">
|
||||
@@ -91,6 +92,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ invested in SimpleX Chat crowdfunding." xml:space="preserve">
|
||||
<source>%@ invested in SimpleX Chat crowdfunding.</source>
|
||||
<target>%@ инвестировал(а) в краудфандинг SimpleX Chat.</target>
|
||||
<note>badge alert</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ is connected!" xml:space="preserve">
|
||||
@@ -120,6 +122,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ supports SimpleX Chat." xml:space="preserve">
|
||||
<source>%@ supports SimpleX Chat.</source>
|
||||
<target>%@ поддерживает SimpleX Chat.</target>
|
||||
<note>badge alert</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ uploaded" xml:space="preserve">
|
||||
@@ -199,6 +202,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="%d owner" xml:space="preserve">
|
||||
<source>%d owner</source>
|
||||
<target>%d владелец</target>
|
||||
<note>channel owners count</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%d owners" xml:space="preserve">
|
||||
@@ -769,10 +773,12 @@ swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add contributors." xml:space="preserve">
|
||||
<source>Add contributors.</source>
|
||||
<target>Добавить соавторов.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add description" xml:space="preserve">
|
||||
<source>Add description</source>
|
||||
<target>Добавить описание</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add friends" xml:space="preserve">
|
||||
@@ -802,10 +808,12 @@ swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add relays" xml:space="preserve">
|
||||
<source>Add relays</source>
|
||||
<target>Добавить релеи</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add relays to restore message delivery." xml:space="preserve">
|
||||
<source>Add relays to restore message delivery.</source>
|
||||
<target>Добавить релеи для восстановления доставки сообщений.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
@@ -825,6 +833,7 @@ swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add this code to your webpage. It will display the preview of your channel / group." xml:space="preserve">
|
||||
<source>Add this code to your webpage. It will display the preview of your channel / group.</source>
|
||||
<target>Добавьте этот код на свой веб-сайт. Он отобразит предпросмотр вашего канала или группы.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
@@ -909,6 +918,7 @@ swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Advanced options" xml:space="preserve">
|
||||
<source>Advanced options</source>
|
||||
<target>Продвинутые настройки</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Advanced settings" xml:space="preserve">
|
||||
@@ -1023,6 +1033,7 @@ swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow anyone to embed" xml:space="preserve">
|
||||
<source>Allow anyone to embed</source>
|
||||
<target>Разрешить всем встраивать</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow calls only if your contact allows them." xml:space="preserve">
|
||||
@@ -1202,6 +1213,7 @@ swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Any webpage can show the preview." xml:space="preserve">
|
||||
<source>Any webpage can show the preview.</source>
|
||||
<target>Предпросмотр можно отобразить на любой веб-странице.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App build: %@" xml:space="preserve">
|
||||
@@ -1246,6 +1258,7 @@ swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App update required" xml:space="preserve">
|
||||
<source>App update required</source>
|
||||
<target>Необходимо обновление приложения</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App version" xml:space="preserve">
|
||||
@@ -1415,6 +1428,7 @@ swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Badge cannot be verified" xml:space="preserve">
|
||||
<source>Badge cannot be verified</source>
|
||||
<target>Не удалось проверить подлинность значка</target>
|
||||
<note>badge alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Be free in your network" xml:space="preserve">
|
||||
@@ -1441,6 +1455,7 @@ in your network</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better channels 📢" xml:space="preserve">
|
||||
<source>Better channels 📢</source>
|
||||
<target>Улучшенные каналы 📢</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better groups" xml:space="preserve">
|
||||
@@ -1682,10 +1697,12 @@ new chat action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Cancel and delete channel" xml:space="preserve">
|
||||
<source>Cancel and delete channel</source>
|
||||
<target>Отменить и удалить канал</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Cancel creating channel?" xml:space="preserve">
|
||||
<source>Cancel creating channel?</source>
|
||||
<target>Отменить создание канала?</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Cancel migration" xml:space="preserve">
|
||||
@@ -1765,6 +1782,7 @@ new chat action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Change role?" xml:space="preserve">
|
||||
<source>Change role?</source>
|
||||
<target>Изменить роль?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Change self-destruct mode" xml:space="preserve">
|
||||
@@ -1785,6 +1803,7 @@ set passcode view</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Channel SimpleX name" xml:space="preserve">
|
||||
<source>Channel SimpleX name</source>
|
||||
<target>SimpleX имя канала</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Channel display name" xml:space="preserve">
|
||||
@@ -1840,6 +1859,7 @@ alert subtitle</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Channel webpage" xml:space="preserve">
|
||||
<source>Channel webpage</source>
|
||||
<target>Веб-страница канала</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Channel will be deleted for all subscribers - this cannot be undone!" xml:space="preserve">
|
||||
@@ -1854,6 +1874,7 @@ alert subtitle</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Channel will start working with %d of %d relays. Continue?" xml:space="preserve">
|
||||
<source>Channel will start working with %1$d of %2$d relays. Continue?</source>
|
||||
<target>Канал начнёт работу с %1$d из %2$d релеев. Продолжить?</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Channels" xml:space="preserve">
|
||||
@@ -1888,6 +1909,7 @@ alert subtitle</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat data" xml:space="preserve">
|
||||
<source>Chat data</source>
|
||||
<target>Данные чата</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat database" xml:space="preserve">
|
||||
@@ -2269,6 +2291,7 @@ server test step</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to %@" xml:space="preserve">
|
||||
<source>Connect to %@</source>
|
||||
<target>Соединиться с %@</target>
|
||||
<note>new chat action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to desktop" xml:space="preserve">
|
||||
@@ -2382,6 +2405,7 @@ This is your own one-time link!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connection blocked: %@" xml:space="preserve">
|
||||
<source>Connection blocked: %@</source>
|
||||
<target>Соединение заблокировано: %@</target>
|
||||
<note>conn error description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connection error" xml:space="preserve">
|
||||
@@ -2548,6 +2572,7 @@ This is your own one-time link!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Copy code" xml:space="preserve">
|
||||
<source>Copy code</source>
|
||||
<target>Скопировать код</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Copy error" xml:space="preserve">
|
||||
@@ -2587,6 +2612,7 @@ This is your own one-time link!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Create a webpage to show your channel preview to visitors before they subscribe. Host it yourself or use any static hosting." xml:space="preserve">
|
||||
<source>Create a webpage to show your channel preview to visitors before they subscribe. Host it yourself or use any static hosting.</source>
|
||||
<target>Создайте веб-страницу, чтобы показывать предпросмотр Вашего канала посетителям до подписки. Хостите её сами или используйте любой статический хостинг.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Create file" xml:space="preserve">
|
||||
@@ -2636,6 +2662,7 @@ This is your own one-time link!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Create web preview." xml:space="preserve">
|
||||
<source>Create web preview.</source>
|
||||
<target>Создать веб-предпросмотр.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Create your address" xml:space="preserve">
|
||||
@@ -2984,6 +3011,7 @@ swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete from history" xml:space="preserve">
|
||||
<source>Delete from history</source>
|
||||
<target>Удалить из истории</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete group" xml:space="preserve">
|
||||
@@ -3354,6 +3382,7 @@ alert button</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Do not require signing messages." xml:space="preserve">
|
||||
<source>Do not require signing messages.</source>
|
||||
<target>Не требовать подпись сообщений.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Do not send history to new members." xml:space="preserve">
|
||||
@@ -3393,6 +3422,7 @@ alert button</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Don't save" xml:space="preserve">
|
||||
<source>Don't save</source>
|
||||
<target>Не сохранять</target>
|
||||
<note>alert action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Don't show again" xml:space="preserve">
|
||||
@@ -3478,6 +3508,7 @@ chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Easier to read." xml:space="preserve">
|
||||
<source>Easier to read.</source>
|
||||
<target>Легче для чтения.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Edit" xml:space="preserve">
|
||||
@@ -3492,6 +3523,7 @@ chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Edit description" xml:space="preserve">
|
||||
<source>Edit description</source>
|
||||
<target>Редактировать описание</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Edit group profile" xml:space="preserve">
|
||||
@@ -3696,6 +3728,7 @@ chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Enter description (optional)" xml:space="preserve">
|
||||
<source>Enter description (optional)</source>
|
||||
<target>Введите описание (необязательно)</target>
|
||||
<note>placeholder</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Enter group name…" xml:space="preserve">
|
||||
@@ -3740,6 +3773,7 @@ chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Enter webpage URL" xml:space="preserve">
|
||||
<source>Enter webpage URL</source>
|
||||
<target>Введите адрес страницы</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Enter welcome message…" xml:space="preserve">
|
||||
@@ -3794,6 +3828,7 @@ chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error adding relays" xml:space="preserve">
|
||||
<source>Error adding relays</source>
|
||||
<target>Ошибка добавления релеев</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error adding server" xml:space="preserve">
|
||||
@@ -3928,6 +3963,7 @@ chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error deleting message" xml:space="preserve">
|
||||
<source>Error deleting message</source>
|
||||
<target>Ошибка удаления сообщения</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error deleting old database" xml:space="preserve">
|
||||
@@ -4062,6 +4098,7 @@ chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error saving name" xml:space="preserve">
|
||||
<source>Error saving name</source>
|
||||
<target>Ошибка сохранения имени</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error saving passcode" xml:space="preserve">
|
||||
@@ -4121,6 +4158,7 @@ chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error sharing address" xml:space="preserve">
|
||||
<source>Error sharing address</source>
|
||||
<target>Ошибка отправки адреса</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error sharing channel" xml:space="preserve">
|
||||
@@ -4348,10 +4386,12 @@ server test error</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File servers" xml:space="preserve">
|
||||
<source>File servers</source>
|
||||
<target>Серверы файлов</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File servers: %@" xml:space="preserve">
|
||||
<source>File servers: %@</source>
|
||||
<target>Серверы файлов: %@</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File status" xml:space="preserve">
|
||||
@@ -4657,6 +4697,7 @@ Error: %2$@</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Get SimpleX name (BETA)" xml:space="preserve">
|
||||
<source>Get SimpleX name (BETA)</source>
|
||||
<target>Зарегистрировать SimpleX имя (BETA)</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Get link" xml:space="preserve">
|
||||
@@ -4771,6 +4812,7 @@ Error: %2$@</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Group webpage" xml:space="preserve">
|
||||
<source>Group webpage</source>
|
||||
<target>Веб-страница группы</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Group welcome message" xml:space="preserve">
|
||||
@@ -4800,6 +4842,7 @@ Error: %2$@</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Help & support" xml:space="preserve">
|
||||
<source>Help & support</source>
|
||||
<target>Помощь и поддержка</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Help admins moderating their groups." xml:space="preserve">
|
||||
@@ -4884,6 +4927,7 @@ Error: %2$@</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="How to register a test name" xml:space="preserve">
|
||||
<source>How to register a test name</source>
|
||||
<target>Как зарегистрировать тестовое имя</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="How to use it" xml:space="preserve">
|
||||
@@ -5292,6 +5336,7 @@ More improvements are coming soon!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="It will be shown to subscribers and used to allow loading the preview." xml:space="preserve">
|
||||
<source>It will be shown to subscribers and used to allow loading the preview.</source>
|
||||
<target>Адрес будет показан подписчикам и разрешит загрузку предпросмотра.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Italian interface" xml:space="preserve">
|
||||
@@ -5311,7 +5356,7 @@ More improvements are coming soon!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Join as %@" xml:space="preserve">
|
||||
<source>Join as %@</source>
|
||||
<target>Вступить как %s</target>
|
||||
<target>Вступить как %@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Join channel" xml:space="preserve">
|
||||
@@ -5321,6 +5366,7 @@ More improvements are coming soon!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Join channel %@" xml:space="preserve">
|
||||
<source>Join channel %@</source>
|
||||
<target>Вступить в канал %@</target>
|
||||
<note>new chat action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Join group" xml:space="preserve">
|
||||
@@ -5447,10 +5493,12 @@ This is your link for group %@!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Let people connect to you via name registered with your SimpleX address." xml:space="preserve">
|
||||
<source>Let people connect to you via name registered with your SimpleX address.</source>
|
||||
<target>Позвольте людям соединяться с Вами через имя, зарегистрированное для Вашего SimpleX адреса.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Let people join via name registered with this channel link." xml:space="preserve">
|
||||
<source>Let people join via name registered with this channel link.</source>
|
||||
<target>Позвольте людям вступать через имя, зарегистрированное для ссылки этого канала.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Let someone connect to you" xml:space="preserve">
|
||||
@@ -5565,6 +5613,7 @@ This is your link for group %@!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Manage your relays." xml:space="preserve">
|
||||
<source>Manage your relays.</source>
|
||||
<target>Управлять своими релеями.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Mark deleted for everyone" xml:space="preserve">
|
||||
@@ -5784,10 +5833,12 @@ This is your link for group %@!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message signing is not required." xml:space="preserve">
|
||||
<source>Message signing is not required.</source>
|
||||
<target>Подпись сообщений не обязательна.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message signing is required." xml:space="preserve">
|
||||
<source>Message signing is required.</source>
|
||||
<target>Подпись сообщений обязательна.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message source remains private." xml:space="preserve">
|
||||
@@ -5962,6 +6013,7 @@ This is your link for group %@!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="More privacy" xml:space="preserve">
|
||||
<source>More privacy</source>
|
||||
<target>Больше конфиденциальности</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="More reliable network connection." xml:space="preserve">
|
||||
@@ -6006,10 +6058,7 @@ This is your link for group %@!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Name not found" xml:space="preserve">
|
||||
<source>Name not found</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<target>Имя не найдено</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
@@ -6198,6 +6247,7 @@ The most secure encryption.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="No available relays" xml:space="preserve">
|
||||
<source>No available relays</source>
|
||||
<target>Нет доступных релеев</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No chat relays" xml:space="preserve">
|
||||
@@ -6327,6 +6377,7 @@ The most secure encryption.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="No relays" xml:space="preserve">
|
||||
<source>No relays</source>
|
||||
<target>Релеи отсутствуют</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No servers for private message routing." xml:space="preserve">
|
||||
@@ -6346,6 +6397,7 @@ The most secure encryption.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="No servers to resolve names." xml:space="preserve">
|
||||
<source>No servers to resolve names.</source>
|
||||
<target>Нет серверов для разрешения имён.</target>
|
||||
<note>servers warning</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No servers to send files." xml:space="preserve">
|
||||
@@ -6365,6 +6417,7 @@ The most secure encryption.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="No valid link" xml:space="preserve">
|
||||
<source>No valid link</source>
|
||||
<target>Нет действительной ссылки</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Nobody tracked your conversations. No one drew a map of where you'd been. Privacy was never a feature - it was the way of life." xml:space="preserve">
|
||||
@@ -6379,6 +6432,7 @@ The most secure encryption.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="None of your servers are set to resolve SimpleX names. Configure servers, or use a connection link." xml:space="preserve">
|
||||
<source>None of your servers are set to resolve SimpleX names. Configure servers, or use a connection link.</source>
|
||||
<target>Ни один из Ваших серверов не настроен для разрешения SimpleX имён. Настройте серверы или используйте ссылку для соединения.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Not a better lock on someone else's door. Not a nicer landlord that respects your privacy, but still keeps the record of all visitors. You are not a guest. You are home. No king can enter it - you are sovereign." xml:space="preserve">
|
||||
@@ -6608,6 +6662,7 @@ Requires compatible VPN.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Only your page above can show the preview." xml:space="preserve">
|
||||
<source>Only your page above can show the preview.</source>
|
||||
<target>Предпросмотр можно отобразить только на Вашей странице, указанной выше.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Open" xml:space="preserve">
|
||||
@@ -6801,6 +6856,7 @@ alert button</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Owners & contributors" xml:space="preserve">
|
||||
<source>Owners & contributors</source>
|
||||
<target>Владельцы и соавторы</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Ownership: you can run your own relays." xml:space="preserve">
|
||||
@@ -7260,6 +7316,11 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Публичные каналы - говорите свободно 🚀</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<target>Публичные имена для Вашего канала или бизнеса.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Push notifications" xml:space="preserve">
|
||||
<source>Push notifications</source>
|
||||
<target>Доставка уведомлений</target>
|
||||
@@ -7509,10 +7570,12 @@ swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Relay will be removed from channel - this cannot be undone!" xml:space="preserve">
|
||||
<source>Relay will be removed from channel - this cannot be undone!</source>
|
||||
<target>Релей будет удалён из канала - это нельзя отменить!</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Relays added: %@." xml:space="preserve">
|
||||
<source>Relays added: %@.</source>
|
||||
<target>Добавлены релеи: %@.</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reliability: many relays per channel." xml:space="preserve">
|
||||
@@ -7557,6 +7620,7 @@ swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Remove name" xml:space="preserve">
|
||||
<source>Remove name</source>
|
||||
<target>Удалить имя</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Remove passphrase from keychain?" xml:space="preserve">
|
||||
@@ -7566,10 +7630,12 @@ swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Remove relay" xml:space="preserve">
|
||||
<source>Remove relay</source>
|
||||
<target>Удалить релей</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Remove relay?" xml:space="preserve">
|
||||
<source>Remove relay?</source>
|
||||
<target>Удалить релей?</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Remove subscriber?" xml:space="preserve">
|
||||
@@ -7674,6 +7740,7 @@ swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Require signing messages." xml:space="preserve">
|
||||
<source>Require signing messages.</source>
|
||||
<target>Требовать подпись сообщений.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Required" xml:space="preserve">
|
||||
@@ -7723,6 +7790,7 @@ swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Resolver error: %@" xml:space="preserve">
|
||||
<source>Resolver error: %@</source>
|
||||
<target>Ошибка разрешения имени: %@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Restart the app to create a new chat profile" xml:space="preserve">
|
||||
@@ -7817,6 +7885,7 @@ swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Role will be changed to "%@". All subscribers will be notified." xml:space="preserve">
|
||||
<source>Role will be changed to "%@". All subscribers will be notified.</source>
|
||||
<target>Роль будет изменена на "%@". Все подписчики получат сообщение.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Role will be changed to "%@". The member will receive a new invitation." xml:space="preserve">
|
||||
@@ -7878,6 +7947,7 @@ chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Save SimpleX name?" xml:space="preserve">
|
||||
<source>Save SimpleX name?</source>
|
||||
<target>Сохранить SimpleX имя?</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Save admission settings?" xml:space="preserve">
|
||||
@@ -7897,6 +7967,7 @@ chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Save and notify members" xml:space="preserve">
|
||||
<source>Save and notify members</source>
|
||||
<target>Сохранить и уведомить членов группы</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Save and notify subscribers" xml:space="preserve">
|
||||
@@ -7971,6 +8042,7 @@ chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Save webpage settings?" xml:space="preserve">
|
||||
<source>Save webpage settings?</source>
|
||||
<target>Сохранить настройки веб-страницы?</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Save welcome message?" xml:space="preserve">
|
||||
@@ -8370,6 +8442,7 @@ chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server %@ does not support name resolution. Configure servers, or use a connection link." xml:space="preserve">
|
||||
<source>Server %@ does not support name resolution. Configure servers, or use a connection link.</source>
|
||||
<target>Сервер %@ не поддерживает разрешение имён. Настройте серверы или используйте ссылку для соединения.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server added to operator %@." xml:space="preserve">
|
||||
@@ -8685,6 +8758,7 @@ chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show encryption" xml:space="preserve">
|
||||
<source>Show encryption</source>
|
||||
<target>Показывать шифрование</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show last messages" xml:space="preserve">
|
||||
@@ -8719,27 +8793,33 @@ chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Sign message" xml:space="preserve">
|
||||
<source>Sign message</source>
|
||||
<target>Подписать сообщение</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Sign messages" xml:space="preserve">
|
||||
<source>Sign messages</source>
|
||||
<target>Подпись сообщений</target>
|
||||
<note>chat feature</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Signature missing" xml:space="preserve">
|
||||
<source>Signature missing</source>
|
||||
<target>Подпись отсутствует</target>
|
||||
<note>alert title
|
||||
copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Signed" xml:space="preserve">
|
||||
<source>Signed</source>
|
||||
<target>Подписано</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Signed & verified" xml:space="preserve">
|
||||
<source>Signed & verified</source>
|
||||
<target>Подписано и проверено</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Signing proves you authored this message and can't be denied later." xml:space="preserve">
|
||||
<source>Signing proves you authored this message and can't be denied later.</source>
|
||||
<target>Подпись доказывает, что Вы — автор этого сообщения, и это нельзя будет отрицать.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX" xml:space="preserve">
|
||||
@@ -8839,20 +8919,19 @@ copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX name" xml:space="preserve">
|
||||
<source>SimpleX name</source>
|
||||
<target>SimpleX имя</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX name error" xml:space="preserve">
|
||||
<source>SimpleX name error</source>
|
||||
<target>Ошибка SimpleX имени</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX name not verified" xml:space="preserve">
|
||||
<source>SimpleX name not verified</source>
|
||||
<target>SimpleX имя не проверено</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX one-time invitation" xml:space="preserve">
|
||||
<source>SimpleX one-time invitation</source>
|
||||
<target>SimpleX одноразовая ссылка</target>
|
||||
@@ -8863,6 +8942,11 @@ copied message info</note>
|
||||
<target>Аудит SimpleX протоколов от Trail of Bits.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<target>Публичные SimpleX имена (BETA)</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX relay address" xml:space="preserve">
|
||||
<source>SimpleX relay address</source>
|
||||
<target>Адрес релея SimpleX</target>
|
||||
@@ -8973,6 +9057,7 @@ report reason</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Status" xml:space="preserve">
|
||||
<source>Status</source>
|
||||
<target>Статус</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Stop" xml:space="preserve">
|
||||
@@ -9134,6 +9219,7 @@ Relay address was used to set up this relay for the channel.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Support the project" xml:space="preserve">
|
||||
<source>Support the project</source>
|
||||
<target>Поддержать проект</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch audio and video during the call." xml:space="preserve">
|
||||
@@ -9331,18 +9417,22 @@ It can happen because of some bug or when the connection is compromised.</source
|
||||
</trans-unit>
|
||||
<trans-unit id="The SimpleX name #%@ is registered without channel link. Add channel link to the name via the registration page." xml:space="preserve">
|
||||
<source>The SimpleX name #%@ is registered without channel link. Add channel link to the name via the registration page.</source>
|
||||
<target>SimpleX имя #%@ зарегистрировано без ссылки канала. Добавьте ссылку канала к имени на странице регистрации.</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="The SimpleX name %@ is registered, but it has no valid link." xml:space="preserve">
|
||||
<source>The SimpleX name %@ is registered, but it has no valid link.</source>
|
||||
<target>SimpleX имя %@ зарегистрировано, но не имеет действительной ссылки.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="The SimpleX name %@ is registered, but not added to profile. Please add it to your address or channel profile, if you are the owner." xml:space="preserve">
|
||||
<source>The SimpleX name %@ is registered, but not added to profile. Please add it to your address or channel profile, if you are the owner.</source>
|
||||
<target>SimpleX имя %@ зарегистрировано, но не добавлено в профиль. Пожалуйста, добавьте его в профиль Вашего адреса или канала, если Вы владелец.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="The SimpleX name @%@ is registered without SimpleX address. Add your SimpleX address to the name via the registration page." xml:space="preserve">
|
||||
<source>The SimpleX name @%@ is registered without SimpleX address. Add your SimpleX address to the name via the registration page.</source>
|
||||
<target>SimpleX имя @%@ зарегистрировано без SimpleX адреса. Добавьте Ваш SimpleX адрес к имени на странице регистрации.</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="The address will be short, and your profile will be shared via the address." xml:space="preserve">
|
||||
@@ -9377,10 +9467,12 @@ It can happen because of some bug or when the connection is compromised.</source
|
||||
</trans-unit>
|
||||
<trans-unit id="The badge is signed with a key that this version of the app does not recognize. Update the app to verify this badge." xml:space="preserve">
|
||||
<source>The badge is signed with a key that this version of the app does not recognize. Update the app to verify this badge.</source>
|
||||
<target>Этот значок подписан ключом, который неизвестен текущей версии приложения. Обновите приложение, чтобы проверить его подлинность.</target>
|
||||
<note>badge alert</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="The channel required this message to be signed, but the signature is missing." xml:space="preserve">
|
||||
<source>The channel required this message to be signed, but the signature is missing.</source>
|
||||
<target>Канал требует подпись сообщений, но у этого сообщения подпись отсутствует.</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="The code you scanned is not a SimpleX link QR code." xml:space="preserve">
|
||||
@@ -9467,7 +9559,7 @@ your contacts and groups.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="The same conditions will apply to operator **%@**." xml:space="preserve">
|
||||
<source>The same conditions will apply to operator **%@**.</source>
|
||||
<target>Те же условия будут действовать для оператора **%s**.</target>
|
||||
<target>Те же условия будут действовать для оператора **%@**.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="The second preset operator in the app!" xml:space="preserve">
|
||||
@@ -9542,6 +9634,7 @@ your contacts and groups.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="This SimpleX name is not registered. Please check the name." xml:space="preserve">
|
||||
<source>This SimpleX name is not registered. Please check the name.</source>
|
||||
<target>Это SimpleX имя не зарегистрировано. Пожалуйста, проверьте имя.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain." xml:space="preserve">
|
||||
@@ -9566,6 +9659,7 @@ your contacts and groups.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="This badge could not be verified and may not be genuine." xml:space="preserve">
|
||||
<source>This badge could not be verified and may not be genuine.</source>
|
||||
<target>Не удалось проверить подлинность этого значка. Возможно, он не является подлинным.</target>
|
||||
<note>badge alert</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="This chat is protected by end-to-end encryption." xml:space="preserve">
|
||||
@@ -9600,6 +9694,7 @@ your contacts and groups.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="This group requires a newer version of the app. Please update the app to join." xml:space="preserve">
|
||||
<source>This group requires a newer version of the app. Please update the app to join.</source>
|
||||
<target>Эта группа требует более новой версии приложения. Пожалуйста, обновите приложение, чтобы вступить.</target>
|
||||
<note>alert message
|
||||
alert subtitle</note>
|
||||
</trans-unit>
|
||||
@@ -9610,6 +9705,7 @@ alert subtitle</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="This is the last active relay. Removing it will prevent message delivery to subscribers." xml:space="preserve">
|
||||
<source>This is the last active relay. Removing it will prevent message delivery to subscribers.</source>
|
||||
<target>Это последний активный релей. После его удаления доставка сообщений подписчикам будет невозможна.</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="This is your link for channel %@!" xml:space="preserve">
|
||||
@@ -9726,6 +9822,7 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
</trans-unit>
|
||||
<trans-unit id="To resolve names" xml:space="preserve">
|
||||
<source>To resolve names</source>
|
||||
<target>Для разрешения имён</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." xml:space="preserve">
|
||||
@@ -9765,6 +9862,7 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
</trans-unit>
|
||||
<trans-unit id="To verify keys with this subscriber, compare (or scan) the code on your devices." xml:space="preserve">
|
||||
<source>To verify keys with this subscriber, compare (or scan) the code on your devices.</source>
|
||||
<target>Чтобы подтвердить ключи с этим подписчиком, сравните (или сканируйте) код на ваших устройствах.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle incognito when connecting." xml:space="preserve">
|
||||
@@ -9859,6 +9957,7 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Unconfirmed name" xml:space="preserve">
|
||||
<source>Unconfirmed name</source>
|
||||
<target>Неподтверждённое имя</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Undelivered messages" xml:space="preserve">
|
||||
@@ -9958,6 +10057,7 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Unverified badge" xml:space="preserve">
|
||||
<source>Unverified badge</source>
|
||||
<target>Неподтверждённый значок</target>
|
||||
<note>badge alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Up to 100 last messages are sent to new members." xml:space="preserve">
|
||||
@@ -10193,6 +10293,7 @@ alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Used chat relays do not support webpages." xml:space="preserve">
|
||||
<source>Used chat relays do not support webpages.</source>
|
||||
<target>Используемые чат-релеи не поддерживают веб-страницы.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User selection" xml:space="preserve">
|
||||
@@ -10217,6 +10318,7 @@ alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Verify SimpleX names" xml:space="preserve">
|
||||
<source>Verify SimpleX names</source>
|
||||
<target>Проверять SimpleX имена</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Verify code with desktop" xml:space="preserve">
|
||||
@@ -10246,6 +10348,7 @@ alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Verify name" xml:space="preserve">
|
||||
<source>Verify name</source>
|
||||
<target>Проверить имя</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Verify passphrase" xml:space="preserve">
|
||||
@@ -10410,10 +10513,12 @@ alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Webpage code" xml:space="preserve">
|
||||
<source>Webpage code</source>
|
||||
<target>Код веб-страницы</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Webpage settings were changed. If you save, the updated settings will be sent to subscribers." xml:space="preserve">
|
||||
<source>Webpage settings were changed. If you save, the updated settings will be sent to subscribers.</source>
|
||||
<target>Настройки веб-страницы были изменены. Если Вы сохраните их, обновлённые настройки будут отправлены подписчикам.</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Welcome %@!" xml:space="preserve">
|
||||
@@ -10640,6 +10745,7 @@ Repeat join request?</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can enable them later via app Your privacy settings." xml:space="preserve">
|
||||
<source>You can enable them later via app Your privacy settings.</source>
|
||||
<target>Вы можете включить их позже в настройках Конфиденциальности.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can give another try." xml:space="preserve">
|
||||
@@ -10704,6 +10810,7 @@ Repeat join request?</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can support SimpleX starting from v7 of the app." xml:space="preserve">
|
||||
<source>You can support SimpleX starting from v7 of the app.</source>
|
||||
<target>Вы можете поддержать SimpleX начиная с версии приложения v7.</target>
|
||||
<note>badge alert</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can turn on SimpleX Lock via Settings." xml:space="preserve">
|
||||
@@ -10899,6 +11006,7 @@ Repeat connection request?</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your SimpleX name" xml:space="preserve">
|
||||
<source>Your SimpleX name</source>
|
||||
<target>Ваше SimpleX имя</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your business contact" xml:space="preserve">
|
||||
@@ -11001,6 +11109,8 @@ To connect, ask your contact to create a new link.</source>
|
||||
<trans-unit id="Your new channel %@ is connected to %d of %d relays. If you cancel, the channel will be deleted - you can create it again." xml:space="preserve">
|
||||
<source>Your new channel %1$@ is connected to %2$d of %3$d relays.
|
||||
If you cancel, the channel will be deleted - you can create it again.</source>
|
||||
<target>Ваш новый канал %1$@ подключен к %2$d из %3$d релеев.
|
||||
Если Вы отмените, канал будет удалён - Вы сможете создать его снова.</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your preferences" xml:space="preserve">
|
||||
@@ -11127,6 +11237,7 @@ Relays can access channel messages.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="acknowledged roster" xml:space="preserve">
|
||||
<source>acknowledged roster</source>
|
||||
<target>подтверждённый список</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="active" xml:space="preserve">
|
||||
@@ -11397,6 +11508,7 @@ marked deleted chat item preview text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="contributor" xml:space="preserve">
|
||||
<source>contributor</source>
|
||||
<target>соавтор</target>
|
||||
<note>member role</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="creator" xml:space="preserve">
|
||||
@@ -11607,6 +11719,7 @@ pref value</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="https://" xml:space="preserve">
|
||||
<source>https://</source>
|
||||
<target>https://</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="iOS Keychain is used to securely store passphrase - it allows receiving push notifications." xml:space="preserve">
|
||||
@@ -12053,6 +12166,7 @@ last received msg: %2$@</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="subscriber" xml:space="preserve">
|
||||
<source>subscriber</source>
|
||||
<target>подписчик</target>
|
||||
<note>member role</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="this contact" xml:space="preserve">
|
||||
@@ -12572,6 +12686,7 @@ last received msg: %2$@</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can allow sharing in Your privacy / SimpleX Lock settings." xml:space="preserve">
|
||||
<source>You can allow sharing in Your privacy / SimpleX Lock settings.</source>
|
||||
<target>Вы можете разрешить отправку в настройках Конфиденциальность / Блокировка SimpleX.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
|
||||
@@ -5383,10 +5383,6 @@ This is your link for group %@!</source>
|
||||
<source>Name not found</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
<target>เครือข่ายและเซิร์ฟเวอร์</target>
|
||||
@@ -6478,6 +6474,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Public channels - speak freely 🚀</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Push notifications" xml:space="preserve">
|
||||
<source>Push notifications</source>
|
||||
<target>การแจ้งเตือนแบบทันที</target>
|
||||
@@ -7895,10 +7895,6 @@ copied message info</note>
|
||||
<source>SimpleX name not verified</source>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX one-time invitation" xml:space="preserve">
|
||||
<source>SimpleX one-time invitation</source>
|
||||
<target>คำเชิญ SimpleX แบบครั้งเดียว</target>
|
||||
@@ -7908,6 +7904,10 @@ copied message info</note>
|
||||
<source>SimpleX protocols reviewed by Trail of Bits.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX relay address" xml:space="preserve">
|
||||
<source>SimpleX relay address</source>
|
||||
<note>simplex link type</note>
|
||||
|
||||
@@ -5905,10 +5905,6 @@ Bu senin grup için bağlantın %@!</target>
|
||||
<source>Name not found</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
<target>Ağ & sunucular</target>
|
||||
@@ -7119,6 +7115,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Public channels - speak freely 🚀</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Push notifications" xml:space="preserve">
|
||||
<source>Push notifications</source>
|
||||
<target>Anında bildirimler</target>
|
||||
@@ -8677,10 +8677,6 @@ copied message info</note>
|
||||
<source>SimpleX name not verified</source>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX one-time invitation" xml:space="preserve">
|
||||
<source>SimpleX one-time invitation</source>
|
||||
<target>SimpleX tek kullanımlık davet</target>
|
||||
@@ -8691,6 +8687,10 @@ copied message info</note>
|
||||
<target>SimpleX protokolleri Trail of Bits tarafından incelenmiştir.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX relay address" xml:space="preserve">
|
||||
<source>SimpleX relay address</source>
|
||||
<note>simplex link type</note>
|
||||
|
||||
@@ -5921,10 +5921,6 @@ This is your link for group %@!</source>
|
||||
<source>Name not found</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
<target>Мережа та сервери</target>
|
||||
@@ -7130,6 +7126,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Public channels - speak freely 🚀</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Push notifications" xml:space="preserve">
|
||||
<source>Push notifications</source>
|
||||
<target>Push-сповіщення</target>
|
||||
@@ -8687,10 +8687,6 @@ copied message info</note>
|
||||
<source>SimpleX name not verified</source>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX one-time invitation" xml:space="preserve">
|
||||
<source>SimpleX one-time invitation</source>
|
||||
<target>Одноразове запрошення SimpleX</target>
|
||||
@@ -8701,6 +8697,10 @@ copied message info</note>
|
||||
<target>Протоколи SimpleX, розглянуті Trail of Bits.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX relay address" xml:space="preserve">
|
||||
<source>SimpleX relay address</source>
|
||||
<note>simplex link type</note>
|
||||
|
||||
@@ -6043,10 +6043,6 @@ This is your link for group %@!</source>
|
||||
<target>未找到名称</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
<target>网络和服务器</target>
|
||||
@@ -7302,6 +7298,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>公开频道 - 自由发言 🚀</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Public names for your channel or business." xml:space="preserve">
|
||||
<source>Public names for your channel or business.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Push notifications" xml:space="preserve">
|
||||
<source>Push notifications</source>
|
||||
<target>推送通知</target>
|
||||
@@ -8901,10 +8901,6 @@ copied message info</note>
|
||||
<target>SimpleX 名称未验证</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX one-time invitation" xml:space="preserve">
|
||||
<source>SimpleX one-time invitation</source>
|
||||
<target>SimpleX 一次性邀请</target>
|
||||
@@ -8915,6 +8911,10 @@ copied message info</note>
|
||||
<target>SimpleX 协议由 Trail of Bits 审阅。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX public names (BETA)" xml:space="preserve">
|
||||
<source>SimpleX public names (BETA)</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX relay address" xml:space="preserve">
|
||||
<source>SimpleX relay address</source>
|
||||
<target>SimpleX 中继地址</target>
|
||||
|
||||
@@ -106,3 +106,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Wrong database passphrase" = "Неправильный пароль базы данных";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You can allow sharing in Your privacy / SimpleX Lock settings." = "Вы можете разрешить отправку в настройках Конфиденциальность / Блокировка SimpleX.";
|
||||
|
||||
@@ -2081,7 +2081,7 @@
|
||||
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 344;
|
||||
CURRENT_PROJECT_VERSION = 345;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
@@ -2131,7 +2131,7 @@
|
||||
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 344;
|
||||
CURRENT_PROJECT_VERSION = 345;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
@@ -2173,7 +2173,7 @@
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 344;
|
||||
CURRENT_PROJECT_VERSION = 345;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
@@ -2193,7 +2193,7 @@
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 344;
|
||||
CURRENT_PROJECT_VERSION = 345;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
@@ -2218,7 +2218,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 344;
|
||||
CURRENT_PROJECT_VERSION = 345;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = s;
|
||||
@@ -2255,7 +2255,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 344;
|
||||
CURRENT_PROJECT_VERSION = 345;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
ENABLE_CODE_COVERAGE = NO;
|
||||
@@ -2292,7 +2292,7 @@
|
||||
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
|
||||
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 344;
|
||||
CURRENT_PROJECT_VERSION = 345;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
@@ -2343,7 +2343,7 @@
|
||||
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
|
||||
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 344;
|
||||
CURRENT_PROJECT_VERSION = 345;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
@@ -2397,7 +2397,7 @@
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 344;
|
||||
CURRENT_PROJECT_VERSION = 345;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
@@ -2431,7 +2431,7 @@
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 344;
|
||||
CURRENT_PROJECT_VERSION = 345;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
|
||||
@@ -2137,6 +2137,14 @@ public func sameChatScope(_ scope1: GroupChatScope, _ scope2: GroupChatScope) ->
|
||||
}
|
||||
}
|
||||
|
||||
public func draftChatId(_ chatId: ChatId?, _ scope: GroupChatScope?) -> ChatId? {
|
||||
guard let chatId, let scope else { return chatId }
|
||||
return switch scope {
|
||||
case let .memberSupport(groupMemberId_): "\(chatId) support:\(groupMemberId_?.description ?? "")"
|
||||
case .reports: "\(chatId) reports"
|
||||
}
|
||||
}
|
||||
|
||||
public enum GroupChatScopeInfo: Decodable, Hashable {
|
||||
case memberSupport(groupMember_: GroupMember?)
|
||||
case reports // surrogate scope used for matching new items to opened Reports "chat scope" in UI, this type is not present in backend
|
||||
|
||||
@@ -3256,7 +3256,7 @@ servers warning */
|
||||
"How to" = "Anleitung";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"How to register a test name" = "Einen Test-Namen registrieren";
|
||||
"How to register a test name" = "Wie man einen Test-Namen registriert";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"How to use it" = "Wie man SimpleX nutzt";
|
||||
@@ -4029,9 +4029,6 @@ servers warning */
|
||||
/* No comment provided by engineer. */
|
||||
"Name not found" = "Name wurde nicht gefunden";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Names for your channel or business." = "Namen für Ihren Kanal oder Ihr Unternehmen.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Network & servers" = "Netzwerk und Server";
|
||||
|
||||
@@ -4837,6 +4834,9 @@ alert title */
|
||||
/* No comment provided by engineer. */
|
||||
"Public channels - speak freely 🚀" = "Öffentliche Kanäle – frei sprechen 🚀";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Public names for your channel or business." = "Öffentliche Namen für Ihren Kanal oder Ihr Unternehmen.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Push notifications" = "Push-Benachrichtigungen";
|
||||
|
||||
@@ -5893,15 +5893,15 @@ copied message info */
|
||||
/* alert title */
|
||||
"SimpleX name not verified" = "SimpleX-Name ist nicht verifiziert";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX names (BETA)" = "SimpleX-Namen (BETA)";
|
||||
|
||||
/* simplex link type */
|
||||
"SimpleX one-time invitation" = "SimpleX-Einmal-Einladung";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX protocols reviewed by Trail of Bits." = "Die SimpleX-Protokolle wurden von Trail of Bits überprüft.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX public names (BETA)" = "Öffentliche SimpleX-Namen (BETA)";
|
||||
|
||||
/* simplex link type */
|
||||
"SimpleX relay address" = "SimpleX Relais-Adresse";
|
||||
|
||||
|
||||
@@ -487,6 +487,12 @@ swipe action */
|
||||
/* No comment provided by engineer. */
|
||||
"Add address to your profile, so that your SimpleX contacts can share it with other people. Profile update will be sent to your SimpleX contacts." = "Añade la dirección a tu perfil para que tus contactos SimpleX puedan compartirla con otros. La actualización del perfil se enviará a tus contactos SimpleX.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add contributors." = "Añade colaboradores.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add description" = "Añadir descripción";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add friends" = "Añadir amigos";
|
||||
|
||||
@@ -931,6 +937,9 @@ swipe action */
|
||||
/* No comment provided by engineer. */
|
||||
"Better calls" = "Llamadas mejoradas";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better channels 📢" = "Canales mejorados 📢";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better groups" = "Grupos mejorados";
|
||||
|
||||
@@ -1221,6 +1230,9 @@ alert subtitle */
|
||||
/* alert message */
|
||||
"Channel profile was changed. If you save it, the updated profile will be sent to channel subscribers." = "El perfil del canal ha sido modificado. Si lo guardas, el perfil actualizado será enviado a los suscriptores.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Channel SimpleX name" = "Nombre SimpleX del canal";
|
||||
|
||||
/* alert title */
|
||||
"Channel temporarily unavailable" = "Canales no disponibles temporalmente";
|
||||
|
||||
@@ -1766,6 +1778,9 @@ server test step */
|
||||
/* No comment provided by engineer. */
|
||||
"Create SimpleX address" = "Crear dirección SimpleX";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Create web preview." = "Crea previsualizaciones web.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Create your address" = "Crea tu dirección";
|
||||
|
||||
@@ -2228,6 +2243,9 @@ alert button */
|
||||
/* No comment provided by engineer. */
|
||||
"Do it later" = "Hacer más tarde";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Do not require signing messages." = "No requerir la firma de mensajes.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Do not send history to new members." = "No se envía el historial a los miembros nuevos.";
|
||||
|
||||
@@ -2258,6 +2276,9 @@ alert button */
|
||||
/* No comment provided by engineer. */
|
||||
"Don't miss important messages." = "No pierdas los mensajes importantes.";
|
||||
|
||||
/* alert action */
|
||||
"Don't save" = "No guardar";
|
||||
|
||||
/* alert action */
|
||||
"Don't show again" = "No volver a mostrar";
|
||||
|
||||
@@ -2316,12 +2337,18 @@ chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Easier to invite your friends 👋" = "Invitar a tus amigos es más fácil 👋";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Easier to read." = "Fácil de leer.";
|
||||
|
||||
/* chat item action */
|
||||
"Edit" = "Editar";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Edit channel profile" = "Editar perfil del canal";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Edit description" = "Editar descripción";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Edit group profile" = "Editar perfil de grupo";
|
||||
|
||||
@@ -2478,6 +2505,9 @@ chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Enter correct passphrase." = "Introduce la contraseña correcta.";
|
||||
|
||||
/* placeholder */
|
||||
"Enter description (optional)" = "Introduce descripción (opcional)";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Enter group name…" = "Nombre del grupo…";
|
||||
|
||||
@@ -2739,6 +2769,9 @@ chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Error setting delivery receipts!" = "¡Error al configurar confirmaciones de entrega!";
|
||||
|
||||
/* alert title */
|
||||
"Error sharing address" = "Error compartiendo dirección";
|
||||
|
||||
/* alert title */
|
||||
"Error sharing channel" = "Error al compartir el canal";
|
||||
|
||||
@@ -2881,6 +2914,12 @@ server test error */
|
||||
/* file error text */
|
||||
"File server error: %@" = "Error del servidor de archivos: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"File servers" = "Servidores de archivos";
|
||||
|
||||
/* copied message info */
|
||||
"File servers: %@" = "Servidores de archivos: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"File status" = "Estado del archivo";
|
||||
|
||||
@@ -3066,6 +3105,9 @@ servers warning */
|
||||
/* No comment provided by engineer. */
|
||||
"Get notified when mentioned." = "Las menciones ahora se notifican.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Get SimpleX name (BETA)" = "Obtener nombre SimpleX (BETA)";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Get started" = "Empezar";
|
||||
|
||||
@@ -3213,6 +3255,9 @@ servers warning */
|
||||
/* No comment provided by engineer. */
|
||||
"How to" = "Cómo";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"How to register a test name" = "Cómo registrar un nombre de prueba";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"How to use it" = "Guía de uso";
|
||||
|
||||
@@ -3675,6 +3720,9 @@ servers warning */
|
||||
/* No comment provided by engineer. */
|
||||
"Make sure WebRTC ICE server addresses are in correct format, line separated and are not duplicated." = "Asegúrate de que las direcciones del servidor WebRTC ICE tienen el formato correcto, están separadas por líneas y no duplicadas.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Manage your relays." = "Gestiona tus servidores.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Mark deleted for everyone" = "Marcar como eliminado para todos";
|
||||
|
||||
@@ -3825,6 +3873,12 @@ servers warning */
|
||||
/* No comment provided by engineer. */
|
||||
"Message shape" = "Forma del mensaje";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Message signing is not required." = "Los mensajes firmados no son obligatorios.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Message signing is required." = "Los mensajes firmados son obligatorios.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Message source remains private." = "El autor del mensaje se mantiene privado.";
|
||||
|
||||
@@ -4780,6 +4834,9 @@ alert title */
|
||||
/* No comment provided by engineer. */
|
||||
"Public channels - speak freely 🚀" = "Canales públicos - habla con libertad 🚀";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Public names for your channel or business." = "Nombres públicos para tu canal o negocio.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Push notifications" = "Notificaciones push";
|
||||
|
||||
@@ -4977,6 +5034,9 @@ swipe action */
|
||||
/* alert title */
|
||||
"Remove member?" = "¿Expulsar miembro?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Remove name" = "Eliminar nombre";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Remove passphrase from keychain?" = "¿Eliminar contraseña de Keychain?";
|
||||
|
||||
@@ -5085,6 +5145,9 @@ swipe action */
|
||||
/* chat list item title */
|
||||
"requested to connect" = "solicitado para conectar";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Require signing messages." = "Requerir la firma de mensajes.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Required" = "Obligatorio";
|
||||
|
||||
@@ -5261,6 +5324,9 @@ chat item action */
|
||||
/* alert title */
|
||||
"Save servers?" = "¿Guardar servidores?";
|
||||
|
||||
/* alert title */
|
||||
"Save SimpleX name?" = "¿Guardar el nombre SimpleX?";
|
||||
|
||||
/* alert title */
|
||||
"Save webpage settings?" = "¿Guardar la configuración web?";
|
||||
|
||||
@@ -5721,6 +5787,9 @@ chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Show developer options" = "Mostrar opciones de desarrollador";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Show encryption" = "Mostrar cifrado";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Show last messages" = "Mostrar último mensaje";
|
||||
|
||||
@@ -5739,6 +5808,25 @@ chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Show:" = "Muestra:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Sign message" = "Firmar mensaje";
|
||||
|
||||
/* chat feature */
|
||||
"Sign messages" = "Firmar mensajes";
|
||||
|
||||
/* alert title
|
||||
copied message info */
|
||||
"Signature missing" = "Falta la firma";
|
||||
|
||||
/* copied message info */
|
||||
"Signed" = "Firmado";
|
||||
|
||||
/* copied message info */
|
||||
"Signed & verified" = "Firmado y verificado";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Signing proves you authored this message and can't be denied later." = "La firma prueba que eres el autor del mensaje sin posibilidad de repudio.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX" = "SimpleX";
|
||||
|
||||
@@ -5811,6 +5899,9 @@ chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX protocols reviewed by Trail of Bits." = "Protocolos de SimpleX auditados por Trail of Bits.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX public names (BETA)" = "Nombres públicos SimpleX (BETA)";
|
||||
|
||||
/* simplex link type */
|
||||
"SimpleX relay address" = "Dirección de servidor SimpleX";
|
||||
|
||||
@@ -6125,6 +6216,9 @@ server test failure */
|
||||
/* badge alert */
|
||||
"The badge is signed with a key that this version of the app does not recognize. Update the app to verify this badge." = "La insignia está firmada con una clave que esta versión de la app no reconoce. Actualiza la app para verificar la insignia.";
|
||||
|
||||
/* alert message */
|
||||
"The channel required this message to be signed, but the signature is missing." = "El canal requiere que el mensaje esté firmado, pero falta la firma.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"The code you scanned is not a SimpleX link QR code." = "El código QR escaneado no es un enlace de SimpleX.";
|
||||
|
||||
@@ -6372,6 +6466,9 @@ alert subtitle */
|
||||
/* No comment provided by engineer. */
|
||||
"To verify end-to-end encryption with your contact compare (or scan) the code on your devices." = "Para verificar el cifrado de extremo a extremo con tu contacto, compara (o escanea) el código en ambos dispositivos.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To verify keys with this subscriber, compare (or scan) the code on your devices." = "Para verificar las claves con este suscriptor, compara (o escanea) el código en ambos dispositivos.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Toggle incognito when connecting." = "Activa incógnito al conectar.";
|
||||
|
||||
|
||||
@@ -4029,9 +4029,6 @@ servers warning */
|
||||
/* No comment provided by engineer. */
|
||||
"Name not found" = "Nem található a név";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Names for your channel or business." = "Nevek a csatornákhoz vagy az üzleti profilokhoz.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Network & servers" = "Hálózat és kiszolgálók";
|
||||
|
||||
@@ -4837,6 +4834,9 @@ alert title */
|
||||
/* No comment provided by engineer. */
|
||||
"Public channels - speak freely 🚀" = "Nyilvános csatornák – mondja el szabadon a véleményét 🚀";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Public names for your channel or business." = "Nyilvános nevek a csatornákhoz vagy az üzleti profilokhoz.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Push notifications" = "Leküldéses értesítések";
|
||||
|
||||
@@ -5893,15 +5893,15 @@ copied message info */
|
||||
/* alert title */
|
||||
"SimpleX name not verified" = "Nincs ellenőrizve a SimpleX-név";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX names (BETA)" = "SimpleX-nevek (béta)";
|
||||
|
||||
/* simplex link type */
|
||||
"SimpleX one-time invitation" = "Egyszer használható SimpleX meghívó";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX protocols reviewed by Trail of Bits." = "A SimpleX protokollokat a Trail of Bits auditálta.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX public names (BETA)" = "Nyilvános SimpleX-nevek (béta)";
|
||||
|
||||
/* simplex link type */
|
||||
"SimpleX relay address" = "SimpleX-átjátszó címe";
|
||||
|
||||
|
||||
@@ -4029,9 +4029,6 @@ servers warning */
|
||||
/* No comment provided by engineer. */
|
||||
"Name not found" = "Nome non trovato";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Names for your channel or business." = "Nomi per il tuo canale o per il lavoro.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Network & servers" = "Rete e server";
|
||||
|
||||
@@ -4837,6 +4834,9 @@ alert title */
|
||||
/* No comment provided by engineer. */
|
||||
"Public channels - speak freely 🚀" = "Canali pubblici - parla liberamente 🚀";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Public names for your channel or business." = "Nomi pubblici per il tuo canale o per il lavoro.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Push notifications" = "Notifiche push";
|
||||
|
||||
@@ -5893,15 +5893,15 @@ copied message info */
|
||||
/* alert title */
|
||||
"SimpleX name not verified" = "Nome SimpleX non verificato";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX names (BETA)" = "Nomi SimpleX (BETA)";
|
||||
|
||||
/* simplex link type */
|
||||
"SimpleX one-time invitation" = "Invito SimpleX una tantum";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX protocols reviewed by Trail of Bits." = "Protocolli di SimpleX esaminati da Trail of Bits.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX public names (BETA)" = "Nomi pubblici SimpleX (BETA)";
|
||||
|
||||
/* simplex link type */
|
||||
"SimpleX relay address" = "Indirizzo del relay SimpleX";
|
||||
|
||||
|
||||
@@ -118,6 +118,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"%@ downloaded" = "%@ загружено";
|
||||
|
||||
/* badge alert */
|
||||
"%@ invested in SimpleX Chat crowdfunding." = "%@ инвестировал(а) в краудфандинг SimpleX Chat.";
|
||||
|
||||
/* notification title */
|
||||
"%@ is connected!" = "Установлено соединение с %@!";
|
||||
|
||||
@@ -133,6 +136,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"%@ servers" = "%@ серверы";
|
||||
|
||||
/* badge alert */
|
||||
"%@ supports SimpleX Chat." = "%@ поддерживает SimpleX Chat.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ uploaded" = "%@ загружено";
|
||||
|
||||
@@ -151,6 +157,9 @@
|
||||
/* copied message info */
|
||||
"%@:" = "%@:";
|
||||
|
||||
/* badge alert */
|
||||
"%1$@ supported SimpleX Chat. The badge expired on %2$@." = "%1$@ поддерживал(а) SimpleX Chat. Срок действия значка истёк %2$@.";
|
||||
|
||||
/* time interval */
|
||||
"%d days" = "%d дней";
|
||||
|
||||
@@ -178,6 +187,9 @@
|
||||
/* time interval */
|
||||
"%d months" = "%d мес";
|
||||
|
||||
/* channel owners count */
|
||||
"%d owner" = "%d владелец";
|
||||
|
||||
/* channel owners count */
|
||||
"%d owners" = "%d владельцев";
|
||||
|
||||
@@ -454,6 +466,9 @@ swipe action */
|
||||
/* No comment provided by engineer. */
|
||||
"Acknowledged" = "Подтверждено";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"acknowledged roster" = "подтверждённый список";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Acknowledgement errors" = "Ошибки подтверждения";
|
||||
|
||||
@@ -472,6 +487,12 @@ swipe action */
|
||||
/* No comment provided by engineer. */
|
||||
"Add address to your profile, so that your SimpleX contacts can share it with other people. Profile update will be sent to your SimpleX contacts." = "Добавьте адрес в свой профиль, чтобы Ваши SimpleX контакты могли поделиться им. Профиль будет отправлен Вашим SimpleX контактам.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add contributors." = "Добавить соавторов.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add description" = "Добавить описание";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add friends" = "Добавить друзей";
|
||||
|
||||
@@ -487,6 +508,12 @@ swipe action */
|
||||
/* No comment provided by engineer. */
|
||||
"Add relay" = "Добавить релей";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add relays" = "Добавить релеи";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add relays to restore message delivery." = "Добавить релеи для восстановления доставки сообщений.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add server" = "Добавить сервер";
|
||||
|
||||
@@ -496,6 +523,9 @@ swipe action */
|
||||
/* No comment provided by engineer. */
|
||||
"Add team members" = "Добавить сотрудников";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add this code to your webpage. It will display the preview of your channel / group." = "Добавьте этот код на свой веб-сайт. Он отобразит предпросмотр вашего канала или группы.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add to another device" = "Добавить на другое устройство";
|
||||
|
||||
@@ -550,6 +580,9 @@ swipe action */
|
||||
/* No comment provided by engineer. */
|
||||
"Advanced network settings" = "Настройки сети";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Advanced options" = "Продвинутые настройки";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Advanced settings" = "Дополнительные настройки";
|
||||
|
||||
@@ -628,6 +661,9 @@ swipe action */
|
||||
/* No comment provided by engineer. */
|
||||
"Allow" = "Разрешить";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Allow anyone to embed" = "Разрешить всем встраивать";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Allow calls only if your contact allows them." = "Разрешить звонки, только если их разрешает Ваш контакт.";
|
||||
|
||||
@@ -739,6 +775,9 @@ swipe action */
|
||||
/* No comment provided by engineer. */
|
||||
"Answer call" = "Принять звонок";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Any webpage can show the preview." = "Предпросмотр можно отобразить на любой веб-странице.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"App build: %@" = "Сборка приложения: %@";
|
||||
|
||||
@@ -763,6 +802,9 @@ swipe action */
|
||||
/* No comment provided by engineer. */
|
||||
"App session" = "Сессия приложения";
|
||||
|
||||
/* alert title */
|
||||
"App update required" = "Необходимо обновление приложения";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"App version" = "Версия приложения";
|
||||
|
||||
@@ -880,6 +922,9 @@ swipe action */
|
||||
/* No comment provided by engineer. */
|
||||
"Bad message ID" = "Ошибка ID сообщения";
|
||||
|
||||
/* badge alert title */
|
||||
"Badge cannot be verified" = "Не удалось проверить подлинность значка";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Be free\nin your network" = "Будь свободен\nв своей сети";
|
||||
|
||||
@@ -892,6 +937,9 @@ swipe action */
|
||||
/* No comment provided by engineer. */
|
||||
"Better calls" = "Улучшенные звонки";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better channels 📢" = "Улучшенные каналы 📢";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better groups" = "Улучшенные группы";
|
||||
|
||||
@@ -1066,6 +1114,12 @@ alert button
|
||||
new chat action */
|
||||
"Cancel" = "Отменить";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Cancel and delete channel" = "Отменить и удалить канал";
|
||||
|
||||
/* alert title */
|
||||
"Cancel creating channel?" = "Отменить создание канала?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Cancel migration" = "Отменить миграцию";
|
||||
|
||||
@@ -1114,6 +1168,9 @@ new chat action */
|
||||
/* No comment provided by engineer. */
|
||||
"Change role" = "Поменять роль";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Change role?" = "Изменить роль?";
|
||||
|
||||
/* authentication reason */
|
||||
"Change self-destruct mode" = "Изменить режим самоуничтожения";
|
||||
|
||||
@@ -1173,15 +1230,24 @@ alert subtitle */
|
||||
/* alert message */
|
||||
"Channel profile was changed. If you save it, the updated profile will be sent to channel subscribers." = "Профиль канала был изменен. Если Вы сохраните его, обновлённый профиль будет отправлен подписчикам канала.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Channel SimpleX name" = "SimpleX имя канала";
|
||||
|
||||
/* alert title */
|
||||
"Channel temporarily unavailable" = "Канал временно недоступен";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Channel webpage" = "Веб-страница канала";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Channel will be deleted for all subscribers - this cannot be undone!" = "Канал будет удалён для всех подписчиков - это нельзя отменить!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Channel will be deleted for you - this cannot be undone!" = "Канал будет удалён для Вас - это нельзя отменить!";
|
||||
|
||||
/* alert message */
|
||||
"Channel will start working with %d of %d relays. Continue?" = "Канал начнёт работу с %1$d из %2$d релеев. Продолжить?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Channels" = "Каналы";
|
||||
|
||||
@@ -1200,6 +1266,9 @@ alert subtitle */
|
||||
/* No comment provided by engineer. */
|
||||
"Chat console" = "Консоль";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat data" = "Данные чата";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat database" = "Архив чата";
|
||||
|
||||
@@ -1433,6 +1502,9 @@ server test step */
|
||||
/* No comment provided by engineer. */
|
||||
"Connect faster! 🚀" = "Соединяйтесь быстрее! 🚀";
|
||||
|
||||
/* new chat action */
|
||||
"Connect to %@" = "Соединиться с %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Connect to desktop" = "Подключиться к компьютеру";
|
||||
|
||||
@@ -1523,6 +1595,9 @@ server test step */
|
||||
/* No comment provided by engineer. */
|
||||
"Connection blocked" = "Соединение заблокировано";
|
||||
|
||||
/* conn error description */
|
||||
"Connection blocked: %@" = "Соединение заблокировано: %@";
|
||||
|
||||
/* alert title */
|
||||
"Connection error" = "Ошибка соединения";
|
||||
|
||||
@@ -1640,12 +1715,18 @@ server test step */
|
||||
/* No comment provided by engineer. */
|
||||
"Contribute" = "Внести свой вклад";
|
||||
|
||||
/* member role */
|
||||
"contributor" = "соавтор";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Conversation deleted!" = "Разговор удалён!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Copy" = "Копировать";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Copy code" = "Скопировать код";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Copy error" = "Скопировать ошибку";
|
||||
|
||||
@@ -1664,6 +1745,9 @@ server test step */
|
||||
/* No comment provided by engineer. */
|
||||
"Create a group using a random profile." = "Создайте группу, используя случайный профиль.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Create a webpage to show your channel preview to visitors before they subscribe. Host it yourself or use any static hosting." = "Создайте веб-страницу, чтобы показывать предпросмотр Вашего канала посетителям до подписки. Хостите её сами или используйте любой статический хостинг.";
|
||||
|
||||
/* server test step */
|
||||
"Create file" = "Создание файла";
|
||||
|
||||
@@ -1694,6 +1778,9 @@ server test step */
|
||||
/* No comment provided by engineer. */
|
||||
"Create SimpleX address" = "Создать адрес SimpleX";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Create web preview." = "Создать веб-предпросмотр.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Create your address" = "Создайте Ваш адрес";
|
||||
|
||||
@@ -1921,6 +2008,9 @@ swipe action */
|
||||
/* No comment provided by engineer. */
|
||||
"Delete for me" = "Удалить для меня";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Delete from history" = "Удалить из истории";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Delete group" = "Удалить группу";
|
||||
|
||||
@@ -2153,6 +2243,9 @@ alert button */
|
||||
/* No comment provided by engineer. */
|
||||
"Do it later" = "Отложить";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Do not require signing messages." = "Не требовать подпись сообщений.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Do not send history to new members." = "Не отправлять историю новым членам.";
|
||||
|
||||
@@ -2183,6 +2276,9 @@ alert button */
|
||||
/* No comment provided by engineer. */
|
||||
"Don't miss important messages." = "Не пропустите важные сообщения.";
|
||||
|
||||
/* alert action */
|
||||
"Don't save" = "Не сохранять";
|
||||
|
||||
/* alert action */
|
||||
"Don't show again" = "Не показывать";
|
||||
|
||||
@@ -2241,12 +2337,18 @@ chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Easier to invite your friends 👋" = "Проще пригласить друзей 👋";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Easier to read." = "Легче для чтения.";
|
||||
|
||||
/* chat item action */
|
||||
"Edit" = "Редактировать";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Edit channel profile" = "Редактировать профиль канала";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Edit description" = "Редактировать описание";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Edit group profile" = "Редактировать профиль группы";
|
||||
|
||||
@@ -2403,6 +2505,9 @@ chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Enter correct passphrase." = "Введите правильный пароль.";
|
||||
|
||||
/* placeholder */
|
||||
"Enter description (optional)" = "Введите описание (необязательно)";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Enter group name…" = "Введите имя группы…";
|
||||
|
||||
@@ -2430,6 +2535,9 @@ chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Enter this device name…" = "Введите имя этого устройства…";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Enter webpage URL" = "Введите адрес страницы";
|
||||
|
||||
/* placeholder */
|
||||
"Enter welcome message…" = "Введите приветственное сообщение…";
|
||||
|
||||
@@ -2463,6 +2571,9 @@ chat item action */
|
||||
/* alert title */
|
||||
"Error adding relay" = "Ошибка добавления релея";
|
||||
|
||||
/* alert title */
|
||||
"Error adding relays" = "Ошибка добавления релеев";
|
||||
|
||||
/* alert title */
|
||||
"Error adding server" = "Ошибка добавления сервера";
|
||||
|
||||
@@ -2541,6 +2652,9 @@ chat item action */
|
||||
/* alert title */
|
||||
"Error deleting database" = "Ошибка при удалении данных чата";
|
||||
|
||||
/* alert title */
|
||||
"Error deleting message" = "Ошибка удаления сообщения";
|
||||
|
||||
/* alert title */
|
||||
"Error deleting old database" = "Ошибка при удалении предыдущей версии данных чата";
|
||||
|
||||
@@ -2619,6 +2733,9 @@ chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Error saving ICE servers" = "Ошибка при сохранении ICE-серверов";
|
||||
|
||||
/* alert title */
|
||||
"Error saving name" = "Ошибка сохранения имени";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error saving passcode" = "Ошибка сохранения кода";
|
||||
|
||||
@@ -2652,6 +2769,9 @@ chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Error setting delivery receipts!" = "Ошибка настроек отчётов о доставке!";
|
||||
|
||||
/* alert title */
|
||||
"Error sharing address" = "Ошибка отправки адреса";
|
||||
|
||||
/* alert title */
|
||||
"Error sharing channel" = "Ошибка при публикации канала";
|
||||
|
||||
@@ -2794,6 +2914,12 @@ server test error */
|
||||
/* file error text */
|
||||
"File server error: %@" = "Ошибка сервера файлов: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"File servers" = "Серверы файлов";
|
||||
|
||||
/* copied message info */
|
||||
"File servers: %@" = "Серверы файлов: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"File status" = "Статус файла";
|
||||
|
||||
@@ -2979,6 +3105,9 @@ servers warning */
|
||||
/* No comment provided by engineer. */
|
||||
"Get notified when mentioned." = "Уведомления, когда Вас упомянули.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Get SimpleX name (BETA)" = "Зарегистрировать SimpleX имя (BETA)";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Get started" = "Начать";
|
||||
|
||||
@@ -3054,6 +3183,9 @@ servers warning */
|
||||
/* alert message */
|
||||
"Group profile was changed. If you save it, the updated profile will be sent to group members." = "Профиль группы изменен. Если Вы сохраните его, новый профиль будет отправлен членам группы.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Group webpage" = "Веб-страница группы";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Group welcome message" = "Приветственное сообщение группы";
|
||||
|
||||
@@ -3069,6 +3201,9 @@ servers warning */
|
||||
/* No comment provided by engineer. */
|
||||
"Help" = "Помощь";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Help & support" = "Помощь и поддержка";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Help admins moderating their groups." = "Помогайте админам модерировать их группы.";
|
||||
|
||||
@@ -3120,12 +3255,18 @@ servers warning */
|
||||
/* No comment provided by engineer. */
|
||||
"How to" = "Инфо";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"How to register a test name" = "Как зарегистрировать тестовое имя";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"How to use it" = "Как использовать";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"How to use your servers" = "Как использовать серверы";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"https://" = "https://";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Hungarian interface" = "Венгерский интерфейс";
|
||||
|
||||
@@ -3405,6 +3546,9 @@ servers warning */
|
||||
/* No comment provided by engineer. */
|
||||
"It seems like you are already connected via this link. If it is not the case, there was an error (%@)." = "Возможно, Вы уже соединились через эту ссылку. Если это не так, то это ошибка (%@).";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"It will be shown to subscribers and used to allow loading the preview." = "Адрес будет показан подписчикам и разрешит загрузку предпросмотра.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Italian interface" = "Итальянский интерфейс";
|
||||
|
||||
@@ -3418,11 +3562,14 @@ servers warning */
|
||||
"Join" = "Вступить";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Join as %@" = "Вступить как %s";
|
||||
"Join as %@" = "Вступить как %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Join channel" = "Вступить в канал";
|
||||
|
||||
/* new chat action */
|
||||
"Join channel %@" = "Вступить в канал %@";
|
||||
|
||||
/* new chat sheet title */
|
||||
"Join group" = "Вступить в группу";
|
||||
|
||||
@@ -3495,6 +3642,12 @@ servers warning */
|
||||
/* No comment provided by engineer. */
|
||||
"Less traffic on mobile networks." = "Меньше трафик в мобильных сетях.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Let people connect to you via name registered with your SimpleX address." = "Позвольте людям соединяться с Вами через имя, зарегистрированное для Вашего SimpleX адреса.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Let people join via name registered with this channel link." = "Позвольте людям вступать через имя, зарегистрированное для ссылки этого канала.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Let someone connect to you" = "Дайте собеседнику Вашу ссылку";
|
||||
|
||||
@@ -3567,6 +3720,9 @@ servers warning */
|
||||
/* No comment provided by engineer. */
|
||||
"Make sure WebRTC ICE server addresses are in correct format, line separated and are not duplicated." = "Пожалуйста, проверьте, что адреса WebRTC ICE-серверов имеют правильный формат, каждый адрес на отдельной строке и не повторяется.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Manage your relays." = "Управлять своими релеями.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Mark deleted for everyone" = "Пометить как удалённое для всех";
|
||||
|
||||
@@ -3717,6 +3873,12 @@ servers warning */
|
||||
/* No comment provided by engineer. */
|
||||
"Message shape" = "Форма сообщений";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Message signing is not required." = "Подпись сообщений не обязательна.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Message signing is required." = "Подпись сообщений обязательна.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Message source remains private." = "Источник сообщения остаётся конфиденциальным.";
|
||||
|
||||
@@ -3837,6 +3999,9 @@ servers warning */
|
||||
/* No comment provided by engineer. */
|
||||
"More improvements are coming soon!" = "Дополнительные улучшения скоро!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"More privacy" = "Больше конфиденциальности";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"More reliable network connection." = "Более надёжное соединение с сетью.";
|
||||
|
||||
@@ -3861,6 +4026,9 @@ servers warning */
|
||||
/* swipe action */
|
||||
"Name" = "Имя";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Name not found" = "Имя не найдено";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Network & servers" = "Сеть и серверы";
|
||||
|
||||
@@ -3981,6 +4149,9 @@ servers warning */
|
||||
/* Authentication unavailable */
|
||||
"No app password" = "Нет кода доступа";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No available relays" = "Нет доступных релеев";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No chat relays" = "Нет чат-релеев";
|
||||
|
||||
@@ -4059,6 +4230,9 @@ servers warning */
|
||||
/* No comment provided by engineer. */
|
||||
"No received or sent files" = "Нет полученных или отправленных файлов";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No relays" = "Релеи отсутствуют";
|
||||
|
||||
/* servers error */
|
||||
"No servers for private message routing." = "Нет серверов для доставки сообщений.";
|
||||
|
||||
@@ -4068,6 +4242,9 @@ servers warning */
|
||||
/* servers error */
|
||||
"No servers to receive messages." = "Нет серверов для приёма сообщений.";
|
||||
|
||||
/* servers warning */
|
||||
"No servers to resolve names." = "Нет серверов для разрешения имён.";
|
||||
|
||||
/* servers error */
|
||||
"No servers to send files." = "Нет серверов для отправки файлов.";
|
||||
|
||||
@@ -4083,12 +4260,18 @@ servers warning */
|
||||
/* No comment provided by engineer. */
|
||||
"No unread chats" = "Нет непрочитанных чатов";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No valid link" = "Нет действительной ссылки";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Nobody tracked your conversations. No one drew a map of where you'd been. Privacy was never a feature - it was the way of life." = "Никто не отслеживал ваши разговоры. Никто не составлял карту ваших перемещений. Конфиденциальность не была функцией - это был образ жизни.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Non-profit governance" = "Некоммерческое управление";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"None of your servers are set to resolve SimpleX names. Configure servers, or use a connection link." = "Ни один из Ваших серверов не настроен для разрешения SimpleX имён. Настройте серверы или используйте ссылку для соединения.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Not a better lock on someone else's door. Not a nicer landlord that respects your privacy, but still keeps the record of all visitors. You are not a guest. You are home. No king can enter it - you are sovereign." = "Не более надёжный замок на чужой двери. Не более вежливый хозяин, который уважает вашу частную жизнь, но всё равно ведёт учёт всех посетителей. Вы не гость. Вы у себя дома. Ни один король не войдёт в ваш дом - вы суверенны.";
|
||||
|
||||
@@ -4241,6 +4424,9 @@ new chat action */
|
||||
/* No comment provided by engineer. */
|
||||
"Only your contact can send voice messages." = "Только Ваш контакт может отправлять голосовые сообщения.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Only your page above can show the preview." = "Предпросмотр можно отобразить только на Вашей странице, указанной выше.";
|
||||
|
||||
/* alert action
|
||||
alert button */
|
||||
"Open" = "Открыть";
|
||||
@@ -4362,6 +4548,9 @@ alert button */
|
||||
/* feature role */
|
||||
"owners" = "владельцы";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Owners & contributors" = "Владельцы и соавторы";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Ownership: you can run your own relays." = "Владение: Вы можете запустить свои собственные релеи.";
|
||||
|
||||
@@ -4645,6 +4834,9 @@ alert title */
|
||||
/* No comment provided by engineer. */
|
||||
"Public channels - speak freely 🚀" = "Публичные каналы - говорите свободно 🚀";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Public names for your channel or business." = "Публичные имена для Вашего канала или бизнеса.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Push notifications" = "Доставка уведомлений";
|
||||
|
||||
@@ -4812,6 +5004,12 @@ swipe action */
|
||||
/* No comment provided by engineer. */
|
||||
"Relay test failed!" = "Тест релея не пройден!";
|
||||
|
||||
/* alert message */
|
||||
"Relay will be removed from channel - this cannot be undone!" = "Релей будет удалён из канала - это нельзя отменить!";
|
||||
|
||||
/* alert message */
|
||||
"Relays added: %@." = "Добавлены релеи: %@.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reliability: many relays per channel." = "Надёжность: несколько релеев на каждый канал.";
|
||||
|
||||
@@ -4836,9 +5034,18 @@ swipe action */
|
||||
/* alert title */
|
||||
"Remove member?" = "Удалить члена группы?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Remove name" = "Удалить имя";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Remove passphrase from keychain?" = "Удалить пароль из Keychain?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Remove relay" = "Удалить релей";
|
||||
|
||||
/* alert title */
|
||||
"Remove relay?" = "Удалить релей?";
|
||||
|
||||
/* alert title */
|
||||
"Remove subscriber?" = "Удалить подписчика?";
|
||||
|
||||
@@ -4938,6 +5145,9 @@ swipe action */
|
||||
/* chat list item title */
|
||||
"requested to connect" = "запрошено соединение";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Require signing messages." = "Требовать подпись сообщений.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Required" = "Обязательно";
|
||||
|
||||
@@ -4965,6 +5175,9 @@ swipe action */
|
||||
/* No comment provided by engineer. */
|
||||
"Reset to user theme" = "Сбросить на тему пользователя";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Resolver error: %@" = "Ошибка разрешения имени: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Restart the app to create a new chat profile" = "Перезапустите приложение, чтобы создать новый профиль";
|
||||
|
||||
@@ -5025,6 +5238,9 @@ swipe action */
|
||||
/* No comment provided by engineer. */
|
||||
"Role will be changed to \"%@\". All group members will be notified." = "Роль члена будет изменена на \"%@\". Все члены группы получат уведомление.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Role will be changed to \"%@\". All subscribers will be notified." = "Роль будет изменена на \"%@\". Все подписчики получат сообщение.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Role will be changed to \"%@\". The member will receive a new invitation." = "Роль члена будет изменена на \"%@\". Будет отправлено новое приглашение.";
|
||||
|
||||
@@ -5063,6 +5279,9 @@ chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Save and notify group members" = "Сохранить и уведомить членов группы";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Save and notify members" = "Сохранить и уведомить членов группы";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Save and notify subscribers" = "Сохранить и уведомить подписчиков";
|
||||
|
||||
@@ -5105,6 +5324,12 @@ chat item action */
|
||||
/* alert title */
|
||||
"Save servers?" = "Сохранить серверы?";
|
||||
|
||||
/* alert title */
|
||||
"Save SimpleX name?" = "Сохранить SimpleX имя?";
|
||||
|
||||
/* alert title */
|
||||
"Save webpage settings?" = "Сохранить настройки веб-страницы?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Save welcome message?" = "Сохранить приветственное сообщение?";
|
||||
|
||||
@@ -5363,6 +5588,9 @@ chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Server" = "Сервер";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Server %@ does not support name resolution. Configure servers, or use a connection link." = "Сервер %@ не поддерживает разрешение имён. Настройте серверы или используйте ссылку для соединения.";
|
||||
|
||||
/* alert message */
|
||||
"Server added to operator %@." = "Сервер добавлен к оператору %@.";
|
||||
|
||||
@@ -5559,6 +5787,9 @@ chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Show developer options" = "Показать опции для разработчиков";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Show encryption" = "Показывать шифрование";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Show last messages" = "Показывать последние сообщения";
|
||||
|
||||
@@ -5577,6 +5808,25 @@ chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Show:" = "Показать:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Sign message" = "Подписать сообщение";
|
||||
|
||||
/* chat feature */
|
||||
"Sign messages" = "Подпись сообщений";
|
||||
|
||||
/* alert title
|
||||
copied message info */
|
||||
"Signature missing" = "Подпись отсутствует";
|
||||
|
||||
/* copied message info */
|
||||
"Signed" = "Подписано";
|
||||
|
||||
/* copied message info */
|
||||
"Signed & verified" = "Подписано и проверено";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Signing proves you authored this message and can't be denied later." = "Подпись доказывает, что Вы — автор этого сообщения, и это нельзя будет отрицать.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX" = "SimpleX";
|
||||
|
||||
@@ -5634,12 +5884,24 @@ chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX Lock turned on" = "Блокировка SimpleX включена";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX name" = "SimpleX имя";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX name error" = "Ошибка SimpleX имени";
|
||||
|
||||
/* alert title */
|
||||
"SimpleX name not verified" = "SimpleX имя не проверено";
|
||||
|
||||
/* simplex link type */
|
||||
"SimpleX one-time invitation" = "SimpleX одноразовая ссылка";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX protocols reviewed by Trail of Bits." = "Аудит SimpleX протоколов от Trail of Bits.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX public names (BETA)" = "Публичные SimpleX имена (BETA)";
|
||||
|
||||
/* simplex link type */
|
||||
"SimpleX relay address" = "Адрес релея SimpleX";
|
||||
|
||||
@@ -5716,6 +5978,9 @@ report reason */
|
||||
/* No comment provided by engineer. */
|
||||
"Statistics" = "Статистика";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Status" = "Статус";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Stop" = "Остановить";
|
||||
|
||||
@@ -5764,6 +6029,9 @@ report reason */
|
||||
/* No comment provided by engineer. */
|
||||
"Subscribed" = "Подписано";
|
||||
|
||||
/* member role */
|
||||
"subscriber" = "подписчик";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Subscriber" = "Подписчик";
|
||||
|
||||
@@ -5812,6 +6080,9 @@ report reason */
|
||||
/* No comment provided by engineer. */
|
||||
"Subscriptions ignored" = "Подписок игнорировано";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Support the project" = "Поддержать проект";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Switch audio and video during the call." = "Переключайте звук и видео во время звонка.";
|
||||
|
||||
@@ -5942,6 +6213,12 @@ server test failure */
|
||||
/* No comment provided by engineer. */
|
||||
"The attempt to change database passphrase was not completed." = "Попытка поменять пароль базы данных не была завершена.";
|
||||
|
||||
/* badge alert */
|
||||
"The badge is signed with a key that this version of the app does not recognize. Update the app to verify this badge." = "Этот значок подписан ключом, который неизвестен текущей версии приложения. Обновите приложение, чтобы проверить его подлинность.";
|
||||
|
||||
/* alert message */
|
||||
"The channel required this message to be signed, but the signature is missing." = "Канал требует подпись сообщений, но у этого сообщения подпись отсутствует.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"The code you scanned is not a SimpleX link QR code." = "Этот QR-код не является SimpleX-ccылкой.";
|
||||
|
||||
@@ -5994,7 +6271,7 @@ server test failure */
|
||||
"The oldest human freedom - to speak to another person without being watched - built on infrastructure that cannot betray it." = "Древнейшая человеческая свобода - говорить с другим человеком без слежки - построенная на инфраструктуре, которая не может её предать.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"The same conditions will apply to operator **%@**." = "Те же условия будут действовать для оператора **%s**.";
|
||||
"The same conditions will apply to operator **%@**." = "Те же условия будут действовать для оператора **%@**.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"The second preset operator in the app!" = "Второй оператор серверов в приложении!";
|
||||
@@ -6014,6 +6291,18 @@ server test failure */
|
||||
/* No comment provided by engineer. */
|
||||
"The servers for new files of your current chat profile **%@**." = "Серверы для новых файлов Вашего текущего профиля **%@**.";
|
||||
|
||||
/* alert message */
|
||||
"The SimpleX name @%@ is registered without SimpleX address. Add your SimpleX address to the name via the registration page." = "SimpleX имя @%@ зарегистрировано без SimpleX адреса. Добавьте Ваш SimpleX адрес к имени на странице регистрации.";
|
||||
|
||||
/* alert message */
|
||||
"The SimpleX name #%@ is registered without channel link. Add channel link to the name via the registration page." = "SimpleX имя #%@ зарегистрировано без ссылки канала. Добавьте ссылку канала к имени на странице регистрации.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"The SimpleX name %@ is registered, but it has no valid link." = "SimpleX имя %@ зарегистрировано, но не имеет действительной ссылки.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"The SimpleX name %@ is registered, but not added to profile. Please add it to your address or channel profile, if you are the owner." = "SimpleX имя %@ зарегистрировано, но не добавлено в профиль. Пожалуйста, добавьте его в профиль Вашего адреса или канала, если Вы владелец.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"The text you pasted is not a SimpleX link." = "Вставленный текст не является SimpleX-ссылкой.";
|
||||
|
||||
@@ -6050,6 +6339,9 @@ server test failure */
|
||||
/* No comment provided by engineer. */
|
||||
"This action cannot be undone - your profile, contacts, messages and files will be irreversibly lost." = "Это действие нельзя отменить - Ваш профиль, контакты, сообщения и файлы будут безвозвратно утеряны.";
|
||||
|
||||
/* badge alert */
|
||||
"This badge could not be verified and may not be genuine." = "Не удалось проверить подлинность этого значка. Возможно, он не является подлинным.";
|
||||
|
||||
/* E2EE info chat item */
|
||||
"This chat is protected by end-to-end encryption." = "Чат защищён сквозным шифрованием.";
|
||||
|
||||
@@ -6071,9 +6363,16 @@ server test failure */
|
||||
/* No comment provided by engineer. */
|
||||
"This group no longer exists." = "Эта группа больше не существует.";
|
||||
|
||||
/* alert message
|
||||
alert subtitle */
|
||||
"This group requires a newer version of the app. Please update the app to join." = "Эта группа требует более новой версии приложения. Пожалуйста, обновите приложение, чтобы вступить.";
|
||||
|
||||
/* alert message */
|
||||
"This is a chat relay address, it cannot be used to connect." = "Это адрес чат-релея, с ним нельзя соединиться.";
|
||||
|
||||
/* alert message */
|
||||
"This is the last active relay. Removing it will prevent message delivery to subscribers." = "Это последний активный релей. После его удаления доставка сообщений подписчикам будет невозможна.";
|
||||
|
||||
/* new chat action */
|
||||
"This is your link for channel %@!" = "Это ваша ссылка на канал %@!";
|
||||
|
||||
@@ -6092,6 +6391,9 @@ server test failure */
|
||||
/* No comment provided by engineer. */
|
||||
"This setting is for your current profile **%@**." = "Эта настройка применяется к Вашему текущему профилю чата **%@**.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"This SimpleX name is not registered. Please check the name." = "Это SimpleX имя не зарегистрировано. Пожалуйста, проверьте имя.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Time to disappear is set only for new contacts." = "Время удаления устанавливается только для новых контактов.";
|
||||
|
||||
@@ -6140,6 +6442,9 @@ server test failure */
|
||||
/* No comment provided by engineer. */
|
||||
"To record voice message please grant permission to use Microphone." = "Для записи голосового сообщения, пожалуйста разрешите доступ к микрофону.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To resolve names" = "Для разрешения имён";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." = "Чтобы показать Ваш скрытый профиль, введите его пароль в поле поиска на странице **Ваши профили чата**.";
|
||||
|
||||
@@ -6161,6 +6466,9 @@ server test failure */
|
||||
/* No comment provided by engineer. */
|
||||
"To verify end-to-end encryption with your contact compare (or scan) the code on your devices." = "Чтобы подтвердить безопасность сквозного шифрования с Вашим контактом сравните (или сканируйте) код на ваших устройствах.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To verify keys with this subscriber, compare (or scan) the code on your devices." = "Чтобы подтвердить ключи с этим подписчиком, сравните (или сканируйте) код на ваших устройствах.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Toggle incognito when connecting." = "Установите режим Инкогнито при соединении.";
|
||||
|
||||
@@ -6218,6 +6526,9 @@ server test failure */
|
||||
/* rcv group event chat item */
|
||||
"unblocked %@" = "%@ разблокирован";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Unconfirmed name" = "Неподтверждённое имя";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Undelivered messages" = "Недоставленные сообщения";
|
||||
|
||||
@@ -6287,6 +6598,9 @@ server test failure */
|
||||
/* conn error description */
|
||||
"Unsupported connection link" = "Ссылка не поддерживается";
|
||||
|
||||
/* badge alert title */
|
||||
"Unverified badge" = "Неподтверждённый значок";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Up to 100 last messages are sent to new members." = "До 100 последних сообщений отправляются новым членам.";
|
||||
|
||||
@@ -6435,6 +6749,9 @@ alert title */
|
||||
/* No comment provided by engineer. */
|
||||
"Use web port" = "Использовать веб-порт";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Used chat relays do not support webpages." = "Используемые чат-релеи не поддерживают веб-страницы.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"User selection" = "Выбор пользователя";
|
||||
|
||||
@@ -6465,12 +6782,18 @@ alert title */
|
||||
/* No comment provided by engineer. */
|
||||
"Verify database passphrase" = "Проверка пароля базы данных";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Verify name" = "Проверить имя";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Verify passphrase" = "Проверить пароль";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Verify security code" = "Подтвердить код безопасности";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Verify SimpleX names" = "Проверять SimpleX имена";
|
||||
|
||||
/* relay hostname */
|
||||
"via %@" = "через %@";
|
||||
|
||||
@@ -6588,6 +6911,12 @@ alert title */
|
||||
/* No comment provided by engineer. */
|
||||
"We made connecting simpler for new users." = "Мы упростили подключение для новых пользователей.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Webpage code" = "Код веб-страницы";
|
||||
|
||||
/* alert message */
|
||||
"Webpage settings were changed. If you save, the updated settings will be sent to subscribers." = "Настройки веб-страницы были изменены. Если Вы сохраните их, обновлённые настройки будут отправлены подписчикам.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"WebRTC ICE servers" = "WebRTC ICE-серверы";
|
||||
|
||||
@@ -6747,6 +7076,9 @@ alert title */
|
||||
/* No comment provided by engineer. */
|
||||
"You can enable later via Settings" = "Вы можете включить их позже в Настройках";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You can enable them later via app Your privacy settings." = "Вы можете включить их позже в настройках Конфиденциальности.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You can give another try." = "Вы можете попробовать ещё раз.";
|
||||
|
||||
@@ -6783,6 +7115,9 @@ alert title */
|
||||
/* No comment provided by engineer. */
|
||||
"You can still view conversation with %@ in the list of chats." = "Вы по-прежнему можете просмотреть разговор с %@ в списке чатов.";
|
||||
|
||||
/* badge alert */
|
||||
"You can support SimpleX starting from v7 of the app." = "Вы можете поддержать SimpleX начиная с версии приложения v7.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You can turn on SimpleX Lock via Settings." = "Вы можете включить Блокировку SimpleX через Настройки.";
|
||||
|
||||
@@ -6978,6 +7313,9 @@ alert title */
|
||||
/* No comment provided by engineer. */
|
||||
"Your network" = "Ваша сеть";
|
||||
|
||||
/* alert message */
|
||||
"Your new channel %@ is connected to %d of %d relays.\nIf you cancel, the channel will be deleted - you can create it again." = "Ваш новый канал %1$@ подключен к %2$d из %3$d релеев.\nЕсли Вы отмените, канал будет удалён - Вы сможете создать его снова.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Your preferences" = "Ваши предпочтения";
|
||||
|
||||
@@ -7026,3 +7364,6 @@ alert title */
|
||||
/* No comment provided by engineer. */
|
||||
"Your SimpleX address" = "Ваш адрес SimpleX";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Your SimpleX name" = "Ваше SimpleX имя";
|
||||
|
||||
@@ -202,6 +202,7 @@ object ChatModel {
|
||||
val migrationState: MutableState<MigrationToState?> by lazy { mutableStateOf(MigrationToDeviceState.makeMigrationState()) }
|
||||
|
||||
var draft = mutableStateOf(null as ComposeState?)
|
||||
// chat id with chat scope, see draftChatId() - group chat and its support chats have the same chat id
|
||||
var draftChatId = mutableStateOf(null as String?)
|
||||
|
||||
// working with external intents or internal forwarding of chat items
|
||||
@@ -1259,6 +1260,12 @@ fun sameChatScope(scope1: GroupChatScope, scope2: GroupChatScope) =
|
||||
&& scope2 is GroupChatScope.MemberSupport
|
||||
&& scope1.groupMemberId_ == scope2.groupMemberId_
|
||||
|
||||
fun draftChatId(chatId: String?, scope: GroupChatScope?): String? =
|
||||
if (chatId == null || scope == null) chatId
|
||||
else when (scope) {
|
||||
is GroupChatScope.MemberSupport -> "$chatId support:${scope.groupMemberId_ ?: ""}"
|
||||
}
|
||||
|
||||
@Serializable
|
||||
sealed class GroupChatScopeInfo {
|
||||
@Serializable @SerialName("memberSupport") data class MemberSupport(val groupMember_: GroupMember?) : GroupChatScopeInfo()
|
||||
|
||||
+1
-1
@@ -135,7 +135,7 @@ fun ChatView(
|
||||
val draft = chatModel.draft.value
|
||||
val sharedContent = chatModel.sharedContent.value
|
||||
mutableStateOf(
|
||||
if (chatModel.draftChatId.value == staleChatId.value && draft != null && (sharedContent !is SharedContent.Forward || sharedContent.fromChatInfo.id == staleChatId.value)) {
|
||||
if (chatModel.draftChatId.value == draftChatId(staleChatId.value, chatsCtx.groupScopeInfo?.toChatScope()) && draft != null && (sharedContent !is SharedContent.Forward || sharedContent.fromChatInfo.id == staleChatId.value)) {
|
||||
draft
|
||||
} else {
|
||||
ComposeState(useLinkPreviews = useLinkPreviews)
|
||||
|
||||
+20
-6
@@ -394,6 +394,8 @@ fun ComposeView(
|
||||
focusRequester: FocusRequester?,
|
||||
) {
|
||||
val cancelledLinks = rememberSaveable { mutableSetOf<String>() }
|
||||
val chatScope = remember(chatsCtx) { chatsCtx.groupScopeInfo?.toChatScope() }
|
||||
val scopeChatId = remember { chat.id }
|
||||
fun isSimplexLink(link: String): Boolean =
|
||||
link.startsWith("https://simplex.chat", true) || link.startsWith("http://simplex.chat", true)
|
||||
|
||||
@@ -489,14 +491,14 @@ fun ComposeView(
|
||||
}
|
||||
|
||||
fun clearPrevDraft(prevChatId: String?) {
|
||||
if (chatModel.draftChatId.value == prevChatId) {
|
||||
if (chatModel.draftChatId.value == draftChatId(prevChatId, chatScope)) {
|
||||
chatModel.draft.value = null
|
||||
chatModel.draftChatId.value = null
|
||||
}
|
||||
}
|
||||
|
||||
fun clearCurrentDraft() {
|
||||
if (chatModel.draftChatId.value == chat.id) {
|
||||
if (chatModel.draftChatId.value == draftChatId(chat.id, chatScope)) {
|
||||
chatModel.draft.value = null
|
||||
chatModel.draftChatId.value = null
|
||||
}
|
||||
@@ -936,7 +938,7 @@ fun ComposeView(
|
||||
composeState.value = lastFailed
|
||||
}
|
||||
val draft = chatModel.draft.value
|
||||
if (wasForwarding && chatModel.draftChatId.value == chat.chatInfo.id && forwardingFromChatId != chat.chatInfo.id && draft != null) {
|
||||
if (wasForwarding && chatModel.draftChatId.value == draftChatId(chat.chatInfo.id, chatScope) && forwardingFromChatId != chat.chatInfo.id && draft != null) {
|
||||
composeState.value = draft
|
||||
} else {
|
||||
clearCurrentDraft()
|
||||
@@ -1326,10 +1328,10 @@ fun ComposeView(
|
||||
}
|
||||
if (saveLastDraft) {
|
||||
chatModel.draft.value = composeState.value
|
||||
chatModel.draftChatId.value = prevChatId
|
||||
chatModel.draftChatId.value = draftChatId(prevChatId, chatScope)
|
||||
}
|
||||
composeState.value = ComposeState(useLinkPreviews = useLinkPreviews)
|
||||
} else if (chatModel.draftChatId.value == chatModel.chatId.value && chatModel.draft.value != null) {
|
||||
} else if (chatModel.draftChatId.value == draftChatId(chatModel.chatId.value, chatScope) && chatModel.draft.value != null) {
|
||||
composeState.value = chatModel.draft.value ?: ComposeState(useLinkPreviews = useLinkPreviews)
|
||||
} else {
|
||||
clearPrevDraft(prevChatId)
|
||||
@@ -1359,11 +1361,23 @@ fun ComposeView(
|
||||
onDispose {
|
||||
if (chatModel.sharedContent.value is SharedContent.Forward && saveLastDraft && !composeState.value.empty) {
|
||||
chatModel.draft.value = composeState.value
|
||||
chatModel.draftChatId.value = currentChatId.value
|
||||
chatModel.draftChatId.value = draftChatId(currentChatId.value, chatScope)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// support chat is closed without changing chat id, and then `KeyChangeEffect(chatModel.chatId.value)` doesn't save the draft
|
||||
DisposableEffect(Unit) {
|
||||
onDispose {
|
||||
val cs = composeState.value
|
||||
// chat change is handled by KeyChangeEffect, unfinished voice recording should not replace the saved draft
|
||||
if (chatScope == null || chatModel.chatId.value != scopeChatId || (cs.preview is ComposePreview.VoicePreview && !cs.preview.finished)) return@onDispose
|
||||
if (saveLastDraft && !cs.empty) {
|
||||
chatModel.draft.value = cs
|
||||
chatModel.draftChatId.value = draftChatId(scopeChatId, chatScope)
|
||||
} else clearPrevDraft(scopeChatId)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SendMsgView_(
|
||||
|
||||
+2
-2
@@ -1039,8 +1039,8 @@ private fun BoxScope.ChatList(searchText: MutableState<TextFieldValue>, listStat
|
||||
// Default top-level part used to complete a bare name typed in the search field (search field only;
|
||||
// the message parser and the wire format are unchanged).
|
||||
private const val DEFAULT_NAME_TLD = "testing"
|
||||
// Shortest name that offers the button, so it is discoverable but does not flash on a single letter.
|
||||
private const val MIN_NAME_LENGTH = 2
|
||||
// Shortest name that offers the button, so it is discoverable but does not flash on short prefixes.
|
||||
private const val MIN_NAME_LENGTH = 5
|
||||
// Wait this long after the last keystroke before the local name search runs.
|
||||
internal const val NAME_SEARCH_DEBOUNCE_MS = 300L
|
||||
|
||||
|
||||
@@ -2985,7 +2985,7 @@
|
||||
<string name="signature_missing_alert_desc">Der Kanal verlangt für diese Nachricht eine Signatur, welche aber fehlt.</string>
|
||||
<string name="channel_simplex_name">Im Kanal genutzter SimpleX-Name</string>
|
||||
<string name="get_simplex_name_beta">SimpleX-Name erhalten (BETA)</string>
|
||||
<string name="register_test_name">Einen Test-Namen registrieren</string>
|
||||
<string name="register_test_name">Wie man einen Test-Namen registriert</string>
|
||||
<string name="remove_name">Name entfernen</string>
|
||||
<string name="save_simplex_name_question">SimpleX-Name speichern?</string>
|
||||
<string name="add_description">Beschreibung hinzufügen</string>
|
||||
@@ -2999,8 +2999,8 @@
|
||||
<string name="v7_0_channels_previews">Eine Web-Vorschau erstellen.</string>
|
||||
<string name="v7_0_channels_wider_messages">Einfacher zu lesen.</string>
|
||||
<string name="v7_0_channels_relays">Ihre Relais verwalten.</string>
|
||||
<string name="v7_0_simplex_names_descr">Namen für Ihren Kanal oder Ihr Unternehmen.</string>
|
||||
<string name="v7_0_simplex_names">SimpleX-Namen (BETA)</string>
|
||||
<string name="v7_0_simplex_names_descr">Öffentliche Namen für Ihren Kanal oder Ihr Unternehmen.</string>
|
||||
<string name="v7_0_simplex_names">Öffentliche SimpleX-Namen (BETA)</string>
|
||||
<string name="info_row_file_servers">Datei-Server</string>
|
||||
<string name="share_text_file_servers">Datei-Server: %s</string>
|
||||
</resources>
|
||||
@@ -152,7 +152,7 @@
|
||||
<string name="delete_after">Eliminar en</string>
|
||||
<string name="ttl_sec">%d seg</string>
|
||||
<string name="contact_already_exists">El contácto ya existe</string>
|
||||
<string name="connection_error_auth">Error de conexión (Autenticación)</string>
|
||||
<string name="connection_error_auth">Enlace de conexión eliminado</string>
|
||||
<string name="for_me_only">Eliminar para mí</string>
|
||||
<string name="icon_descr_server_status_disconnected">Desconectado</string>
|
||||
<string name="icon_descr_server_status_connected">Conectado</string>
|
||||
@@ -569,7 +569,7 @@
|
||||
<string name="smp_servers_invalid_address">¡Dirección de servidor no válida!</string>
|
||||
<string name="make_private_connection">Establecer una conexión privada</string>
|
||||
<string name="network_error_desc">Comprueba tu conexión de red con %1$s e inténtalo de nuevo.</string>
|
||||
<string name="sender_may_have_deleted_the_connection_request">El remitente puede haber eliminado la solicitud de conexión.</string>
|
||||
<string name="sender_may_have_deleted_the_connection_request">El remitente ha eliminado la solicitud de conexión.</string>
|
||||
<string name="error_smp_test_certificate">La huella en la dirección del servidor no coincide con el certificado.</string>
|
||||
<string name="reply_verb">Responder</string>
|
||||
<string name="save_passphrase_in_keychain">Guardar contraseña en Keystore</string>
|
||||
@@ -692,7 +692,7 @@
|
||||
<string name="save_and_notify_contact">Guardar y notificar contacto</string>
|
||||
<string name="save_preferences_question">¿Guardar preferencias\?</string>
|
||||
<string name="save_and_notify_group_members">Guardar y notificar grupo</string>
|
||||
<string name="connection_error_auth_desc">A menos que tu contacto haya eliminado la conexión o el enlace se haya usado, podría ser un error. Por favor, notifícalo. \nPara conectarte pide a tu contacto que cree otro enlace y comprueba la conexión de red.</string>
|
||||
<string name="connection_error_auth_desc">Tu contacto ha eliminado el enlace, o era un enlace de un solo uso que ya se ha usado.\nPara conectarte pide a tu contacto que cree otro enlace.</string>
|
||||
<string name="periodic_notifications_desc">La aplicación recoge nuevos mensajes periódicamente lo que consume un pequeño porcentaje de batería al día. La aplicación no usa notificaciones push por tanto los datos de tu dispositivo no se envían a los servidores push.</string>
|
||||
<string name="la_notice_title_simplex_lock">Bloqueo SimpleX</string>
|
||||
<string name="auth_unlock">Desbloquear</string>
|
||||
@@ -2906,8 +2906,8 @@
|
||||
<string name="info_row_signed">Firmado</string>
|
||||
<string name="info_row_signed_verified">Firmado y verificado</string>
|
||||
<string name="sign_messages">Firmar mensajes</string>
|
||||
<string name="require_message_signatures">Se requieren mensajes firmados.</string>
|
||||
<string name="do_not_require_message_signatures">No se requieren mensajes firmados.</string>
|
||||
<string name="require_message_signatures">Requerir la firma de mensajes.</string>
|
||||
<string name="do_not_require_message_signatures">No requerir la firma de mensajes.</string>
|
||||
<string name="message_signatures_are_required">Los mensajes firmados son obligatorios.</string>
|
||||
<string name="message_signatures_are_not_required">Los mensajes firmados no son obligatorios.</string>
|
||||
<string name="show_signature">Mostrar firma</string>
|
||||
@@ -2915,11 +2915,20 @@
|
||||
<string name="signature_missing_alert_title">Falta la firma</string>
|
||||
<string name="signature_missing_alert_desc">El canal requiere que el mensaje esté firmado, pero falta la firma.</string>
|
||||
<string name="channel_simplex_name">Nombre SimpleX del canal</string>
|
||||
<string name="register_test_name">Registrar nombre para pruebas</string>
|
||||
<string name="register_test_name">Cómo registrar un nombre de prueba</string>
|
||||
<string name="add_description">Añadir descripción</string>
|
||||
<string name="profile_description__field">Descripción</string>
|
||||
<string name="edit_description">Editar descripción</string>
|
||||
<string name="enter_description_optional">Introduce descripción (opcional)</string>
|
||||
<string name="error_sharing_address">Error compartiendo dirección</string>
|
||||
<string name="to_verify_channel_member_key">Para verificar la clave con el suscriptor, compara (o escanea) el código en tu dispositivo.</string>
|
||||
<string name="to_verify_channel_member_key">Para verificar las claves con este suscriptor, compara (o escanea) el código en ambos dispositivos.</string>
|
||||
<string name="v7_0_channels_contributors">Añade colaboradores.</string>
|
||||
<string name="v7_0_channels">Canales mejorados 📢</string>
|
||||
<string name="v7_0_channels_previews">Crea previsualizaciones web.</string>
|
||||
<string name="v7_0_channels_wider_messages">Fácil de leer.</string>
|
||||
<string name="info_row_file_servers">Servidores de archivos</string>
|
||||
<string name="share_text_file_servers">Servidores de archivos: %s</string>
|
||||
<string name="v7_0_channels_relays">Gestiona tus servidores.</string>
|
||||
<string name="v7_0_simplex_names_descr">Nombres públicos para tu canal o negocio.</string>
|
||||
<string name="v7_0_simplex_names">Nombres públicos SimpleX (BETA)</string>
|
||||
</resources>
|
||||
@@ -2895,8 +2895,8 @@
|
||||
<string name="v7_0_channels_previews">Előnézet készítése a weboldalakhoz.</string>
|
||||
<string name="v7_0_channels_wider_messages">Könnyebb olvashatóság.</string>
|
||||
<string name="v7_0_channels_relays">Saját átjátszók kezelése.</string>
|
||||
<string name="v7_0_simplex_names_descr">Nevek a csatornákhoz vagy az üzleti profilokhoz.</string>
|
||||
<string name="v7_0_simplex_names">SimpleX-nevek (béta)</string>
|
||||
<string name="v7_0_simplex_names_descr">Nyilvános nevek a csatornákhoz vagy az üzleti profilokhoz.</string>
|
||||
<string name="v7_0_simplex_names">Nyilvános SimpleX-nevek (béta)</string>
|
||||
<string name="info_row_file_servers">Fájlkiszolgálók</string>
|
||||
<string name="share_text_file_servers">Fájlkiszolgálók: %s</string>
|
||||
</resources>
|
||||
@@ -2929,8 +2929,8 @@
|
||||
<string name="v7_0_channels_previews">Crea un\'anteprima web.</string>
|
||||
<string name="v7_0_channels_wider_messages">Lettura più facile.</string>
|
||||
<string name="v7_0_channels_relays">Gestisci i tuoi relay.</string>
|
||||
<string name="v7_0_simplex_names_descr">Nomi per il tuo canale o per il lavoro.</string>
|
||||
<string name="v7_0_simplex_names">Nomi SimpleX (BETA)</string>
|
||||
<string name="v7_0_simplex_names_descr">Nomi pubblici per il tuo canale o per il lavoro.</string>
|
||||
<string name="v7_0_simplex_names">Nomi pubblici SimpleX (BETA)</string>
|
||||
<string name="v7_0_channels_contributors">Aggiungi collaboratori.</string>
|
||||
<string name="info_row_file_servers">Server di file</string>
|
||||
<string name="share_text_file_servers">Server di file: %s</string>
|
||||
|
||||
@@ -1670,7 +1670,6 @@
|
||||
<string name="agent_internal_error_title">Внутренняя ошибка</string>
|
||||
<string name="clear_note_folder_question">Очистить личные заметки?</string>
|
||||
<string name="new_chat">Новый чат</string>
|
||||
<string name="new_chat">Новое сообщение</string>
|
||||
<string name="or_scan_qr_code">Или отсканируйте QR-код</string>
|
||||
<string name="you_can_view_invitation_link_again">Вы можете увидеть ссылку-приглашение снова открыв соединение.</string>
|
||||
<string name="show_slow_api_calls">Показывать медленные вызовы API</string>
|
||||
@@ -2915,4 +2914,96 @@
|
||||
<string name="relay_bar_no_relays">Релеи отсутствуют</string>
|
||||
<string name="no_relays_selected">Релеи не выбраны</string>
|
||||
<string name="tray_tooltip_unread">SimpleX - %d непрочитанных сообщений</string>
|
||||
<string name="v7_0_channels_contributors">Добавить соавторов.</string>
|
||||
<string name="add_description">Добавить описание</string>
|
||||
<string name="v7_0_channels">Улучшенные каналы 📢</string>
|
||||
<string name="channel_simplex_name">SimpleX имя канала</string>
|
||||
<string name="connect_plan_connect_to_name">Соединиться с %s</string>
|
||||
<string name="webpage_info">Создайте веб-страницу, чтобы показывать предпросмотр Вашего канала посетителям до подписки. Хостите её сами или используйте любой статический хостинг.</string>
|
||||
<string name="v7_0_channels_previews">Создать веб-предпросмотр.</string>
|
||||
<string name="profile_description__field">Описание</string>
|
||||
<string name="do_not_require_message_signatures">Не требовать подпись сообщений.</string>
|
||||
<string name="v7_0_channels_wider_messages">Легче для чтения.</string>
|
||||
<string name="edit_description">Редактировать описание</string>
|
||||
<string name="enter_description_optional">Введите описание (необязательно)</string>
|
||||
<string name="enter_webpage_url">Введите адрес страницы</string>
|
||||
<string name="error_adding_relays">Ошибка добавления релеев</string>
|
||||
<string name="error_deleting_message">Ошибка удаления сообщения</string>
|
||||
<string name="error_saving_simplex_name">Ошибка сохранения имени</string>
|
||||
<string name="error_sharing_address">Ошибка отправки адреса</string>
|
||||
<string name="info_row_file_servers">Серверы файлов</string>
|
||||
<string name="share_text_file_servers">Серверы файлов: %s</string>
|
||||
<string name="from_history">Из истории</string>
|
||||
<string name="get_simplex_name_beta">Зарегистрировать SimpleX имя (BETA)</string>
|
||||
<string name="group_webpage">Веб-страница группы</string>
|
||||
<string name="help_and_support">Помощь и поддержка</string>
|
||||
<string name="register_test_name">Как зарегистрировать тестовое имя</string>
|
||||
<string name="web_page_url_placeholder">https://</string>
|
||||
<string name="close_behavior_dialog_text">Если Вы выберете Закрыть, сообщения не будут доставляться.\nВы можете изменить это позже в настройках Интерфейса.</string>
|
||||
<string name="webpage_url_footer">Адрес будет показан подписчикам и разрешит загрузку предпросмотра.</string>
|
||||
<string name="connect_plan_join_name">Вступить в канал %s</string>
|
||||
<string name="unsupported_channel_name">Неподдерживаемое имя канала</string>
|
||||
<string name="unsupported_contact_name">Неподдерживаемое имя контакта</string>
|
||||
<string name="please_upgrade_the_app">Пожалуйста, обновите приложение.</string>
|
||||
<string name="simplex_name_error">Ошибка SimpleX имени</string>
|
||||
<string name="simplex_name_no_servers_desc">Ни один из Ваших серверов не настроен для разрешения SimpleX имён. Настройте серверы или используйте ссылку для соединения.</string>
|
||||
<string name="simplex_name_server_no_resolver_desc">Сервер %1$s не поддерживает разрешение имён. Настройте серверы или используйте ссылку для соединения.</string>
|
||||
<string name="simplex_name_not_found">Имя не найдено</string>
|
||||
<string name="simplex_name_not_found_desc">Это SimpleX имя не зарегистрировано. Пожалуйста, проверьте имя.</string>
|
||||
<string name="simplex_name_resolver_error_desc">Ошибка разрешения имени: %1$s</string>
|
||||
<string name="simplex_name_no_valid_link">Нет действительной ссылки</string>
|
||||
<string name="simplex_name_no_valid_link_desc">SimpleX имя %1$s зарегистрировано, но не имеет действительной ссылки.</string>
|
||||
<string name="simplex_name_unconfirmed">Неподтверждённое имя</string>
|
||||
<string name="simplex_name_unconfirmed_desc">SimpleX имя %1$s зарегистрировано, но не добавлено в профиль. Пожалуйста, добавьте его в профиль Вашего адреса или канала, если Вы владелец.</string>
|
||||
<string name="group_link_requires_newer_version">Эта группа требует более новой версии приложения. Пожалуйста, обновите приложение, чтобы вступить.</string>
|
||||
<string name="save_simplex_name_question">Сохранить SimpleX имя?</string>
|
||||
<string name="remove_name">Удалить имя</string>
|
||||
<string name="sign_message">Подписать сообщение</string>
|
||||
<string name="sign_message_desc">Подпись доказывает, что Вы — автор этого сообщения, и это нельзя будет отрицать.</string>
|
||||
<string name="info_row_signed">Подписано</string>
|
||||
<string name="info_row_signed_verified">Подписано и проверено</string>
|
||||
<string name="sign_messages">Подпись сообщений</string>
|
||||
<string name="require_message_signatures">Требовать подпись сообщений.</string>
|
||||
<string name="message_signatures_are_required">Подпись сообщений обязательна.</string>
|
||||
<string name="message_signatures_are_not_required">Подпись сообщений не обязательна.</string>
|
||||
<string name="show_signature">Показывать подпись</string>
|
||||
<string name="show_encryption">Показывать шифрование</string>
|
||||
<string name="signature_missing_alert_title">Подпись отсутствует</string>
|
||||
<string name="signature_missing_alert_desc">Канал требует подпись сообщений, но у этого сообщения подпись отсутствует.</string>
|
||||
<string name="verify_simplex_name_action">Проверить имя</string>
|
||||
<string name="verify_simplex_names">Проверять SimpleX имена</string>
|
||||
<string name="simplex_name_not_verified">SimpleX имя не проверено</string>
|
||||
<string name="simplex_name">SimpleX имя</string>
|
||||
<string name="your_simplex_name">Ваше SimpleX имя</string>
|
||||
<string name="set_simplex_name">Установить SimpleX имя</string>
|
||||
<string name="simplex_name_owner_no_channel_link">SimpleX имя %1$s зарегистрировано без ссылки канала. Добавьте ссылку канала к имени на странице регистрации.</string>
|
||||
<string name="simplex_name_owner_no_address">SimpleX имя %1$s зарегистрировано без SimpleX адреса. Добавьте Ваш SimpleX адрес к имени на странице регистрации.</string>
|
||||
<string name="set_user_simplex_name_footer">Позвольте людям соединяться с Вами через имя, зарегистрированное для Вашего SimpleX адреса.</string>
|
||||
<string name="set_channel_simplex_name_footer">Позвольте людям вступать через имя, зарегистрированное для ссылки этого канала.</string>
|
||||
<string name="to_verify_channel_member_key">Чтобы подтвердить ключи с этим подписчиком, сравните (или сканируйте) код на ваших устройствах.</string>
|
||||
<string name="settings_section_title_support_project">Поддержать проект</string>
|
||||
<string name="more_privacy">Больше конфиденциальности</string>
|
||||
<string name="webpage_code">Код веб-страницы</string>
|
||||
<string name="relays_no_web_support">Используемые чат-релеи не поддерживают веб-страницы.</string>
|
||||
<string name="embed_only_your_page">Предпросмотр можно отобразить только на Вашей странице, указанной выше.</string>
|
||||
<string name="member_role_will_be_changed_with_notification_channel">Роль будет изменена на "%s". Все в канале получат сообщение.</string>
|
||||
<string name="operator_use_for_names">Для разрешения имён</string>
|
||||
<string name="v7_0_simplex_names">Публичные SimpleX имена (BETA)</string>
|
||||
<string name="v7_0_simplex_names_descr">Публичные имена для Вашего канала или бизнеса.</string>
|
||||
<string name="v7_0_channels_relays">Управлять своими релеями.</string>
|
||||
<string name="relay_conn_status_removed">удалён</string>
|
||||
<string name="relay_status_rejected">отклонён</string>
|
||||
<string name="member_info_status">Статус</string>
|
||||
<string name="member_info_relay_status_rejected_by_operator">отклонён оператором релея</string>
|
||||
<string name="relay_will_be_removed_from_channel">Релей будет удалён из канала - это нельзя отменить!</string>
|
||||
<string name="last_active_relay_warning">Это последний активный релей. После его удаления доставка сообщений подписчикам будет невозможна.</string>
|
||||
<string name="cancel_channel_alert_msg">Ваш новый канал %1$s подключен к %2$d из %3$d релеев.\nЕсли Вы отмените, канал будет удалён - Вы сможете создать его снова.</string>
|
||||
<string name="no_available_relays">Нет доступных релеев</string>
|
||||
<string name="relays_added_format">Добавлены релеи: %1$s.</string>
|
||||
<string name="select_relays">Выберите релеи</string>
|
||||
<string name="close_behavior_dialog_title">Свернуть в трей?</string>
|
||||
<string name="close_behavior_dialog_minimize">Свернуть в трей</string>
|
||||
<string name="tray_show">Показать SimpleX</string>
|
||||
<string name="tray_quit">Выйти из SimpleX</string>
|
||||
<string name="tray_tooltip">SimpleX</string>
|
||||
</resources>
|
||||
@@ -2889,7 +2889,7 @@
|
||||
<string name="get_simplex_name_beta">获得 SimpleX 名称 (测试)</string>
|
||||
<string name="message_signatures_are_not_required">不要求消息签名。</string>
|
||||
<string name="message_signatures_are_required">要求消息签名。</string>
|
||||
<string name="register_test_name">注册测试名</string>
|
||||
<string name="register_test_name">如何注册测试名</string>
|
||||
<string name="remove_name">删除名称</string>
|
||||
<string name="require_message_signatures">要求消息签名。</string>
|
||||
<string name="save_simplex_name_question">保存 SimpleX 名称?</string>
|
||||
@@ -2913,8 +2913,8 @@
|
||||
<string name="v7_0_channels_previews">创建 web 预览。</string>
|
||||
<string name="v7_0_channels_wider_messages">更易阅读。</string>
|
||||
<string name="v7_0_channels_relays">管理你的中继。</string>
|
||||
<string name="v7_0_simplex_names_descr">你的频道或企业的名称。</string>
|
||||
<string name="v7_0_simplex_names">SimpleX 名称 (测试)</string>
|
||||
<string name="v7_0_simplex_names_descr">你的频道或企业的公开名称。</string>
|
||||
<string name="v7_0_simplex_names">SimpleX 公开名称 (测试)</string>
|
||||
<string name="info_row_file_servers">文件服务器</string>
|
||||
<string name="share_text_file_servers">文件服务器:%s</string>
|
||||
</resources>
|
||||
@@ -24,13 +24,13 @@ android.nonTransitiveRClass=true
|
||||
kotlin.mpp.androidSourceSetLayoutVersion=2
|
||||
kotlin.jvm.target=11
|
||||
|
||||
android.version_name=7.0-beta.6
|
||||
android.version_code=365
|
||||
android.version_name=7.0
|
||||
android.version_code=366
|
||||
|
||||
android.bundle=false
|
||||
|
||||
desktop.version_name=7.0-beta.6
|
||||
desktop.version_code=154
|
||||
desktop.version_name=7.0
|
||||
desktop.version_code=155
|
||||
|
||||
kotlin.version=2.1.20
|
||||
gradle.plugin.version=8.7.0
|
||||
|
||||
@@ -61,7 +61,6 @@ This file is generated automatically.
|
||||
- [ContactConnecting](#contactconnecting)
|
||||
- [BusinessLinkConnecting](#businesslinkconnecting)
|
||||
- [JoinedGroupMemberConnecting](#joinedgroupmemberconnecting)
|
||||
- [SentGroupInvitation](#sentgroupinvitation)
|
||||
- [GroupLinkConnecting](#grouplinkconnecting)
|
||||
|
||||
[Network connection events](#network-connection-events)
|
||||
@@ -701,20 +700,6 @@ Group member is announced to the group and will be connecting to bot.
|
||||
---
|
||||
|
||||
|
||||
### SentGroupInvitation
|
||||
|
||||
Sent when another user joins group via bot's link.
|
||||
|
||||
**Record type**:
|
||||
- type: "sentGroupInvitation"
|
||||
- user: [User](./TYPES.md#user)
|
||||
- groupInfo: [GroupInfo](./TYPES.md#groupinfo)
|
||||
- contact: [Contact](./TYPES.md#contact)
|
||||
- member: [GroupMember](./TYPES.md#groupmember)
|
||||
|
||||
---
|
||||
|
||||
|
||||
### GroupLinkConnecting
|
||||
|
||||
Sent when bot joins group via another user link.
|
||||
|
||||
@@ -133,7 +133,6 @@ chatEventsDocsData =
|
||||
("CEvtContactConnecting", "Contact confirmed connection.\n\nSent when contact started connecting via bot's 1-time invitation link or when bot connects to another SimpleX address."), -- CONF
|
||||
("CEvtBusinessLinkConnecting", "Contact confirmed connection.\n\nSent when bot connects to another business address."), -- CONF
|
||||
("CEvtJoinedGroupMemberConnecting", "Group member is announced to the group and will be connecting to bot."), -- MSG
|
||||
("CEvtSentGroupInvitation", "Sent when another user joins group via bot's link."), -- INV
|
||||
("CEvtGroupLinkConnecting", "Sent when bot joins group via another user link.") -- CONF
|
||||
],
|
||||
[]
|
||||
|
||||
@@ -46,7 +46,6 @@ export type ChatEvent =
|
||||
| CEvt.ContactConnecting
|
||||
| CEvt.BusinessLinkConnecting
|
||||
| CEvt.JoinedGroupMemberConnecting
|
||||
| CEvt.SentGroupInvitation
|
||||
| CEvt.GroupLinkConnecting
|
||||
| CEvt.HostConnected
|
||||
| CEvt.HostDisconnected
|
||||
@@ -99,7 +98,6 @@ export namespace CEvt {
|
||||
| "contactConnecting"
|
||||
| "businessLinkConnecting"
|
||||
| "joinedGroupMemberConnecting"
|
||||
| "sentGroupInvitation"
|
||||
| "groupLinkConnecting"
|
||||
| "hostConnected"
|
||||
| "hostDisconnected"
|
||||
@@ -430,14 +428,6 @@ export namespace CEvt {
|
||||
member: T.GroupMember
|
||||
}
|
||||
|
||||
export interface SentGroupInvitation extends Interface {
|
||||
type: "sentGroupInvitation"
|
||||
user: T.User
|
||||
groupInfo: T.GroupInfo
|
||||
contact: T.Contact
|
||||
member: T.GroupMember
|
||||
}
|
||||
|
||||
export interface GroupLinkConnecting extends Interface {
|
||||
type: "groupLinkConnecting"
|
||||
user: T.User
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "simplex-chat",
|
||||
"version": "7.0.0-beta.5",
|
||||
"version": "7.0.0",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"files": [
|
||||
|
||||
@@ -4,7 +4,7 @@ const path = require('path');
|
||||
const extract = require('extract-zip');
|
||||
|
||||
const GITHUB_REPO = 'simplex-chat/simplex-chat-libs';
|
||||
const RELEASE_TAG = 'v7.0.0-beta.5';
|
||||
const RELEASE_TAG = 'v7.0.0';
|
||||
const BACKEND = (process.env.SIMPLEX_BACKEND || process.env.npm_config_simplex_backend || 'sqlite').toLowerCase();
|
||||
|
||||
if (BACKEND !== 'sqlite' && BACKEND !== 'postgres') {
|
||||
|
||||
@@ -5,5 +5,5 @@ Bump both together for normal releases. For wrapper-only fixes use a PEP 440
|
||||
post-release: __version__ = "6.5.2.post1", LIBS_VERSION unchanged.
|
||||
"""
|
||||
|
||||
__version__ = "7.0.0b5" # PEP 440 — read by hatchling for wheel metadata
|
||||
LIBS_VERSION = "7.0.0-beta.5" # simplex-chat-libs release tag (no 'v' prefix)
|
||||
__version__ = "7.0.0" # PEP 440 — read by hatchling for wheel metadata
|
||||
LIBS_VERSION = "7.0.0" # simplex-chat-libs release tag (no 'v' prefix)
|
||||
@@ -281,13 +281,6 @@ class JoinedGroupMemberConnecting(TypedDict):
|
||||
hostMember: "T.GroupMember"
|
||||
member: "T.GroupMember"
|
||||
|
||||
class SentGroupInvitation(TypedDict):
|
||||
type: Literal["sentGroupInvitation"]
|
||||
user: "T.User"
|
||||
groupInfo: "T.GroupInfo"
|
||||
contact: "T.Contact"
|
||||
member: "T.GroupMember"
|
||||
|
||||
class GroupLinkConnecting(TypedDict):
|
||||
type: Literal["groupLinkConnecting"]
|
||||
user: "T.User"
|
||||
@@ -367,7 +360,6 @@ ChatEvent = (
|
||||
| ContactConnecting
|
||||
| BusinessLinkConnecting
|
||||
| JoinedGroupMemberConnecting
|
||||
| SentGroupInvitation
|
||||
| GroupLinkConnecting
|
||||
| HostConnected
|
||||
| HostDisconnected
|
||||
@@ -377,7 +369,7 @@ ChatEvent = (
|
||||
| ChatErrors
|
||||
)
|
||||
|
||||
ChatEvent_Tag = Literal["contactConnected", "contactUpdated", "contactDeletedByContact", "receivedContactRequest", "newMemberContactReceivedInv", "contactSndReady", "newChatItems", "chatItemReaction", "chatItemsDeleted", "chatItemUpdated", "groupChatItemsDeleted", "chatItemsStatusesUpdated", "receivedGroupInvitation", "userJoinedGroup", "groupUpdated", "joinedGroupMember", "memberRole", "deletedMember", "leftMember", "deletedMemberUser", "groupDeleted", "connectedToGroupMember", "memberAcceptedByOther", "memberBlockedForAll", "groupMemberUpdated", "groupLinkDataUpdated", "groupRelayUpdated", "rcvFileDescrReady", "rcvFileComplete", "sndFileCompleteXFTP", "rcvFileStart", "rcvFileSndCancelled", "rcvFileAccepted", "rcvFileError", "rcvFileWarning", "sndFileError", "sndFileWarning", "acceptingContactRequest", "acceptingBusinessRequest", "contactConnecting", "businessLinkConnecting", "joinedGroupMemberConnecting", "sentGroupInvitation", "groupLinkConnecting", "hostConnected", "hostDisconnected", "subscriptionStatus", "messageError", "chatError", "chatErrors"]
|
||||
ChatEvent_Tag = Literal["contactConnected", "contactUpdated", "contactDeletedByContact", "receivedContactRequest", "newMemberContactReceivedInv", "contactSndReady", "newChatItems", "chatItemReaction", "chatItemsDeleted", "chatItemUpdated", "groupChatItemsDeleted", "chatItemsStatusesUpdated", "receivedGroupInvitation", "userJoinedGroup", "groupUpdated", "joinedGroupMember", "memberRole", "deletedMember", "leftMember", "deletedMemberUser", "groupDeleted", "connectedToGroupMember", "memberAcceptedByOther", "memberBlockedForAll", "groupMemberUpdated", "groupLinkDataUpdated", "groupRelayUpdated", "rcvFileDescrReady", "rcvFileComplete", "sndFileCompleteXFTP", "rcvFileStart", "rcvFileSndCancelled", "rcvFileAccepted", "rcvFileError", "rcvFileWarning", "sndFileError", "sndFileWarning", "acceptingContactRequest", "acceptingBusinessRequest", "contactConnecting", "businessLinkConnecting", "joinedGroupMemberConnecting", "groupLinkConnecting", "hostConnected", "hostDisconnected", "subscriptionStatus", "messageError", "chatError", "chatErrors"]
|
||||
|
||||
|
||||
class OnEventDecorator(Protocol):
|
||||
@@ -640,12 +632,6 @@ class OnEventDecorator(Protocol):
|
||||
Callable[["JoinedGroupMemberConnecting"], Awaitable[None]],
|
||||
]: ...
|
||||
|
||||
@overload
|
||||
def __call__(self, event: Literal["sentGroupInvitation"], /) -> Callable[
|
||||
[Callable[["SentGroupInvitation"], Awaitable[None]]],
|
||||
Callable[["SentGroupInvitation"], Awaitable[None]],
|
||||
]: ...
|
||||
|
||||
@overload
|
||||
def __call__(self, event: Literal["groupLinkConnecting"], /) -> Callable[
|
||||
[Callable[["GroupLinkConnecting"], Awaitable[None]]],
|
||||
|
||||
@@ -38,6 +38,23 @@
|
||||
</description>
|
||||
|
||||
<releases>
|
||||
<release version="7.0.0" date="2026-07-28">
|
||||
<url type="details">https://simplex.chat/blog/20260722-simplex-public-names.html</url>
|
||||
<description>
|
||||
<p>New in v7.0.</p>
|
||||
<p>SimpleX public names for channels and businesses (BETA).</p>
|
||||
<p>Better channels:</p>
|
||||
<ul>
|
||||
<li>Promote subscribers to contributors.</li>
|
||||
<li>Publish your channel on your website.</li>
|
||||
<li>Verify security code with contributors.</li>
|
||||
<li>Wider messages, easier to read.</li>
|
||||
<li>Host your own chat relays.</li>
|
||||
</ul>
|
||||
<p>Add a longer description to your profile.</p>
|
||||
<p>Simplified app settings.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="6.5.6" date="2026-06-22">
|
||||
<url type="details">https://simplex.chat/blog/20260430-simplex-channels-v6-5-consortium-crowdfunding-freedom-of-speech.html</url>
|
||||
<description>
|
||||
|
||||
@@ -118,9 +118,14 @@ check_apk() {
|
||||
verify_apk() {
|
||||
apk_name="$1"
|
||||
|
||||
# Release APKs are packaged by AGP (gradle :android:assembleRelease; AGP version is
|
||||
# gradle.plugin.version in apps/multiplatform/gradle.properties), which zero-pads ZIP
|
||||
# alignment. Do NOT add --pad-like-apksigner (standalone apksigner >= 35.0.0-rc1 uses
|
||||
# the 0xd935 extra-field padding) unless AGP is bumped to a packager that uses it —
|
||||
# otherwise apksigcopier aborts with "APK Signing Block offset < central directory offset".
|
||||
# https://github.com/obfusk/apksigcopier?tab=readme-ov-file#what-about-signatures-made-by-apksigner-from-build-tools--3500-rc1
|
||||
docker exec "${CONTAINER_NAME}" repro-apk zipalign --page-size 16 --pad-like-apksigner --replace "${DOCKER_PATH_VERIFY}/${apk_name}.${SUFFIX_BUILT}" \
|
||||
"${DOCKER_PATH_VERIFY}/${apk_name}.aligned"
|
||||
docker exec "${CONTAINER_NAME}" repro-apk zipalign --page-size 16 --replace "${DOCKER_PATH_VERIFY}/${apk_name}.${SUFFIX_BUILT}" \
|
||||
"${DOCKER_PATH_VERIFY}/${apk_name}.aligned"
|
||||
docker exec "${CONTAINER_NAME}" mv "${DOCKER_PATH_VERIFY}/${apk_name}.aligned" \
|
||||
"${DOCKER_PATH_VERIFY}/${apk_name}.${SUFFIX_BUILT}"
|
||||
|
||||
|
||||
@@ -937,7 +937,6 @@ data ChatEvent
|
||||
| CEvtUserAcceptedGroupSent {user :: User, groupInfo :: GroupInfo, hostContact :: Maybe Contact} -- there is the same command response
|
||||
| CEvtGroupLinkConnecting {user :: User, groupInfo :: GroupInfo, hostMember :: GroupMember}
|
||||
| CEvtBusinessLinkConnecting {user :: User, groupInfo :: GroupInfo, hostMember :: GroupMember, fromContact :: Contact}
|
||||
| CEvtSentGroupInvitation {user :: User, groupInfo :: GroupInfo, contact :: Contact, member :: GroupMember} -- there is the same command response
|
||||
| CEvtContactUpdated {user :: User, fromContact :: Contact, toContact :: Contact}
|
||||
| CEvtGroupMemberUpdated {user :: User, groupInfo :: GroupInfo, fromMember :: GroupMember, toMember :: GroupMember}
|
||||
| CEvtContactDeletedByContact {user :: User, contact :: Contact}
|
||||
|
||||
@@ -1667,8 +1667,8 @@ processChatCommand cxt nm = \case
|
||||
pure $ CRChatRelayTestResult user (Just relayProfile) (Just $ RelayTestFailure step e)
|
||||
lift (withAgent' $ \a -> connRequestPQSupport a PQSupportOff cReq) >>= \case
|
||||
Nothing -> failWithProfile RTSConnect (ChatError $ CERelayTestError "invalid connection request")
|
||||
Just (agentV, _) -> do
|
||||
let chatV = agentToChatVersion agentV
|
||||
Just _ -> do
|
||||
let chatV = initialChatVersion
|
||||
subMode <- chatReadVar subscriptionMode
|
||||
connId <- withAgent $ \a -> prepareConnectionToJoin a (aUserId user) True cReq PQSupportOff
|
||||
conn@Connection {connId = testCId} <- withFastStore $ \db ->
|
||||
@@ -3285,7 +3285,7 @@ processChatCommand cxt nm = \case
|
||||
unless (groupFeatureUserAllowed SGFDirectMessages g) $ throwCmdError "direct messages not allowed"
|
||||
case memberConn m of
|
||||
Just mConn@Connection {peerChatVRange} -> do
|
||||
unless (maxVersion peerChatVRange >= groupDirectInvVersion) $ throwChatError CEPeerChatVRangeIncompatible
|
||||
unless (maxVersion peerChatVRange >= initialChatVersion) $ throwChatError CEPeerChatVRangeIncompatible
|
||||
when (isJust $ memberContactId m) $ throwCmdError "member contact already exists"
|
||||
subMode <- chatReadVar subscriptionMode
|
||||
-- TODO PQ should negotitate contact connection with PQSupportOn?
|
||||
@@ -3729,15 +3729,15 @@ processChatCommand cxt nm = \case
|
||||
lift (withAgent' $ \a -> connRequestPQSupport a PQSupportOn cReq) >>= \case
|
||||
Nothing -> throwChatError CEInvalidConnReq
|
||||
-- TODO PQ the error above should be CEIncompatibleConnReqVersion, also the same API should be called in Plan
|
||||
Just (agentV, pqSup') -> do
|
||||
let chatV = agentToChatVersion agentV
|
||||
Just (_, pqSup') -> do
|
||||
let chatV = initialChatVersion
|
||||
withFastStore' (\db -> getConnectionEntityByConnReq db cxt user cReqs) >>= \case
|
||||
Nothing -> joinNewConn chatV
|
||||
Just (RcvDirectMsgConnection conn@Connection {connStatus, contactConnInitiated, customUserProfileId} _ct_)
|
||||
| connStatus == ConnNew && contactConnInitiated -> joinNewConn chatV -- own connection link
|
||||
| connStatus == ConnPrepared -> do -- retrying join after error
|
||||
localIncognitoProfile <- forM customUserProfileId $ \pId -> withFastStore $ \db -> getProfileById db userId pId
|
||||
joinPreparedConn conn (fromLocalProfile <$> localIncognitoProfile) chatV
|
||||
joinPreparedConn conn (fromLocalProfile <$> localIncognitoProfile)
|
||||
Just ent -> throwCmdError $ "connection is not RcvDirectMsgConnection: " <> show (connEntityInfo ent)
|
||||
where
|
||||
joinNewConn chatV = do
|
||||
@@ -3746,10 +3746,10 @@ processChatCommand cxt nm = \case
|
||||
connId <- withAgent $ \a -> prepareConnectionToJoin a (aUserId user) True cReq pqSup'
|
||||
let ccLink = CCLink cReq $ serverShortLink <$> sLnk_
|
||||
conn <- withFastStore' $ \db -> createDirectConnection' db userId connId ccLink contactId_ ConnPrepared incognitoProfile subMode chatV pqSup'
|
||||
joinPreparedConn conn incognitoProfile chatV
|
||||
joinPreparedConn conn incognitoProfile chatV = do
|
||||
joinPreparedConn conn incognitoProfile
|
||||
joinPreparedConn conn incognitoProfile = do
|
||||
profileToSend <- presentUserBadge user incognitoProfile $ userProfileDirect user incognitoProfile Nothing True
|
||||
dm <- encodeConnInfoPQ pqSup' chatV $ XInfo profileToSend Nothing
|
||||
dm <- encodeConnInfoPQ pqSup' $ XInfo profileToSend Nothing
|
||||
sqSecured <- withAgent $ \a -> joinConnection a nm (aUserId user) (aConnId conn) True cReq dm pqSup' subMode
|
||||
let newStatus = if sqSecured then ConnSndReady else ConnJoined
|
||||
conn' <- withFastStore' $ \db -> updateConnectionStatusFromTo db conn ConnPrepared newStatus
|
||||
@@ -3892,14 +3892,14 @@ processChatCommand cxt nm = \case
|
||||
-- 2) toggle enabled, address doesn't support PQ - PQSupportOn but without compression, with version range indicating support
|
||||
lift (withAgent' $ \a -> connRequestPQSupport a pqSup cReq) >>= \case
|
||||
Nothing -> throwChatError CEInvalidConnReq
|
||||
Just (agentV, _) -> do
|
||||
let chatV = agentToChatVersion agentV
|
||||
Just _ -> do
|
||||
let chatV = initialChatVersion
|
||||
connId <- withAgent $ \a -> prepareConnectionToJoin a (aUserId user) True cReq pqSup
|
||||
pure (connId, chatV)
|
||||
mkXContactId :: Maybe XContactId -> CM XContactId
|
||||
mkXContactId = maybe (XContactId <$> drgRandomBytes 16) pure
|
||||
joinContact :: User -> Connection -> ConnReqContact -> Maybe Profile -> XContactId -> Maybe SharedMsgId -> Maybe (SharedMsgId, MsgContent) -> Maybe (Maybe GroupInfo) -> Maybe MemberId -> PQSupport -> CM Connection
|
||||
joinContact user conn@Connection {connChatVersion = chatV} cReq incognitoProfile xContactId welcomeSharedMsgId msg_ gInfo_ relayMemberId_ pqSup = do
|
||||
joinContact user conn cReq incognitoProfile xContactId welcomeSharedMsgId msg_ gInfo_ relayMemberId_ pqSup = do
|
||||
-- gInfo_ is Maybe (Maybe GroupInfo), where Just Nothing means "some unknown group", e.g. when joining via link without profile
|
||||
profileToSend <-
|
||||
presentUserBadge user incognitoProfile $ case gInfo_ of
|
||||
@@ -3912,9 +3912,9 @@ processChatCommand cxt nm = \case
|
||||
Nothing -> throwChatError $ CEInternalError "relay group join without target relay memberId"
|
||||
| otherwise -> do
|
||||
gInfo' <- ensureUserMemberKey gInfo
|
||||
encodeConnInfoPQ pqSup chatV $ XContact profileToSend (groupMemberKey gInfo') (Just xContactId) welcomeSharedMsgId msg_
|
||||
encodeConnInfoPQ pqSup $ XContact profileToSend (groupMemberKey gInfo') (Just xContactId) welcomeSharedMsgId msg_
|
||||
_ ->
|
||||
encodeConnInfoPQ pqSup chatV $ XContact profileToSend Nothing (Just xContactId) welcomeSharedMsgId msg_
|
||||
encodeConnInfoPQ pqSup $ XContact profileToSend Nothing (Just xContactId) welcomeSharedMsgId msg_
|
||||
subMode <- chatReadVar subscriptionMode
|
||||
void $ withAgent $ \a -> joinConnection a nm (aUserId user) (aConnId conn) True cReq dm pqSup subMode
|
||||
withFastStore' $ \db -> updateConnectionStatusFromTo db conn ConnPrepared ConnJoined
|
||||
@@ -4222,8 +4222,8 @@ processChatCommand cxt nm = \case
|
||||
(FixedLinkData {linkConnReq = cReq}, _cData) <- getShortLinkConnReq nm user address
|
||||
lift (withAgent' $ \a -> connRequestPQSupport a PQSupportOff cReq) >>= \case
|
||||
Nothing -> throwChatError CEInvalidConnReq
|
||||
Just (agentV, _) -> do
|
||||
let chatV = agentToChatVersion agentV
|
||||
Just _ -> do
|
||||
let chatV = initialChatVersion
|
||||
gVar <- asks random
|
||||
subMode <- chatReadVar subscriptionMode
|
||||
connId <- withAgent $ \a -> prepareConnectionToJoin a (aUserId user) True cReq PQSupportOff
|
||||
|
||||
@@ -40,7 +40,7 @@ import Data.Foldable (foldr')
|
||||
import Data.Functor (($>))
|
||||
import Data.Functor.Identity
|
||||
import Data.Int (Int64)
|
||||
import Data.List (find, foldl', mapAccumL, partition)
|
||||
import Data.List (foldl', mapAccumL, partition)
|
||||
import Data.List.NonEmpty (NonEmpty (..), (<|))
|
||||
import qualified Data.List.NonEmpty as L
|
||||
import Data.Map.Strict (Map)
|
||||
@@ -918,7 +918,7 @@ acceptContactRequest nm user@User {userId} UserContactRequest {agentInvitationId
|
||||
incognitoProfile <- forM customUserProfileId $ \pId -> withFastStore $ \db -> getProfileById db userId pId
|
||||
pure (ct, conn, ExistingIncognito <$> incognitoProfile)
|
||||
profileToSend <- presentUserBadge user incognitoProfile $ userProfileDirect user (fromIncognitoProfile <$> incognitoProfile) (Just ct) True
|
||||
dm <- encodeConnInfoPQ pqSup' chatV $ XInfo profileToSend Nothing
|
||||
dm <- encodeConnInfoPQ pqSup' $ XInfo profileToSend Nothing
|
||||
(ct,conn,) <$> withAgent (\a -> acceptContact a nm (aUserId user) (aConnId conn) True invId dm pqSup' subMode)
|
||||
|
||||
acceptContactRequestAsync :: User -> Int64 -> Contact -> UserContactRequest -> Maybe IncognitoProfile -> CM Contact
|
||||
@@ -939,7 +939,7 @@ acceptContactRequestAsync
|
||||
Connection {connId} <- liftIO $ createAcceptedContactConn db user (Just uclId) contactId acId chatV cReqChatVRange cReqPQSup incognitoProfile subMode currentTs
|
||||
liftIO $ setCommandConnId db user cmdId connId
|
||||
getContact db cxt user contactId
|
||||
agentAcceptContactAsync cmdId acId True cReqInvId (XInfo profileToSend Nothing) cReqPQSup chatV subMode
|
||||
agentAcceptContactAsync cmdId acId True cReqInvId (XInfo profileToSend Nothing) cReqPQSup subMode
|
||||
pure ct'
|
||||
|
||||
acceptGroupJoinRequestAsync :: User -> Int64 -> GroupInfo -> InvitationId -> VersionRangeChat -> Profile -> Maybe XContactId -> Maybe MemberId -> Maybe SharedMsgId -> GroupAcceptance -> GroupMemberRole -> Maybe IncognitoProfile -> Maybe MemberKey -> Maybe GroupMember -> CM GroupMember
|
||||
@@ -992,7 +992,7 @@ acceptGroupJoinRequestAsync
|
||||
m <- withStore $ \db -> do
|
||||
liftIO $ createJoiningMemberConnection db user uclId (cmdId, acId) chatV cReqChatVRange groupMemberId subMode
|
||||
getGroupMemberById db cxt user groupMemberId
|
||||
agentAcceptContactAsync cmdId acId True cReqInvId msg PQSupportOff chatV subMode
|
||||
agentAcceptContactAsync cmdId acId True cReqInvId msg PQSupportOff subMode
|
||||
pure m
|
||||
|
||||
acceptGroupJoinSendRejectAsync :: User -> Int64 -> GroupInfo -> InvitationId -> VersionRangeChat -> Profile -> Maybe XContactId -> GroupRejectionReason -> CM GroupMember
|
||||
@@ -1024,7 +1024,7 @@ acceptGroupJoinSendRejectAsync
|
||||
m <- withStore $ \db -> do
|
||||
liftIO $ createJoiningMemberConnection db user uclId (cmdId, acId) chatV cReqChatVRange groupMemberId subMode
|
||||
getGroupMemberById db cxt user groupMemberId
|
||||
agentAcceptContactAsync cmdId acId False cReqInvId msg PQSupportOff chatV subMode
|
||||
agentAcceptContactAsync cmdId acId False cReqInvId msg PQSupportOff subMode
|
||||
pure m
|
||||
|
||||
acceptBusinessJoinRequestAsync :: User -> Int64 -> GroupInfo -> GroupMember -> UserContactRequest -> CM (GroupInfo, GroupMember)
|
||||
@@ -1058,7 +1058,7 @@ acceptBusinessJoinRequestAsync
|
||||
withStore' $ \db -> do
|
||||
forM_ xContactId $ \xcId -> setBusinessChatAcceptedXContactId db gInfo xcId
|
||||
createJoiningMemberConnection db user uclId (cmdId, acId) chatV cReqChatVRange groupMemberId subMode
|
||||
agentAcceptContactAsync cmdId acId True cReqInvId msg PQSupportOff chatV subMode
|
||||
agentAcceptContactAsync cmdId acId True cReqInvId msg PQSupportOff subMode
|
||||
let cd = CDGroupSnd gInfo Nothing
|
||||
-- TODO [short links] move to profileContactRequest?
|
||||
createInternalChatItem user cd (CISndGroupE2EEInfo $ e2eInfoGroup gInfo) Nothing
|
||||
@@ -1087,7 +1087,7 @@ acceptRelayJoinRequestAsync
|
||||
gInfo' <- liftIO $ updateRelayOwnStatusFromTo db gInfo RSInvited RSAccepted
|
||||
ownerMember' <- getGroupMemberById db cxt user groupMemberId
|
||||
pure (gInfo', ownerMember')
|
||||
agentAcceptContactAsync cmdId acId True cReqInvId msg PQSupportOff chatV subMode
|
||||
agentAcceptContactAsync cmdId acId True cReqInvId msg PQSupportOff subMode
|
||||
pure r
|
||||
|
||||
rejectRelayInvitationAsync
|
||||
@@ -1111,7 +1111,7 @@ rejectRelayInvitationAsync user uclId cxt groupRelayInv invId reqChatVRange init
|
||||
(cmdId, acId) <- prepareAgentAccept user False invId PQSupportOff
|
||||
withStore' $ \db ->
|
||||
createJoiningMemberConnection db user uclId (cmdId, acId) chatV reqChatVRange groupMemberId subMode
|
||||
agentAcceptContactAsync cmdId acId False invId msg PQSupportOff chatV subMode
|
||||
agentAcceptContactAsync cmdId acId False invId msg PQSupportOff subMode
|
||||
|
||||
businessGroupProfile :: Profile -> GroupPreferences -> GroupProfile
|
||||
businessGroupProfile Profile {displayName, fullName, shortDescr, description, image} groupPreferences =
|
||||
@@ -1155,7 +1155,7 @@ shouldIntroduce m vec mem =
|
||||
|
||||
introduceMember :: User -> GroupInfo -> GroupMember -> [GroupMember] -> Maybe MsgScope -> CM ()
|
||||
introduceMember _ _ GroupMember {activeConn = Nothing} _ _ = throwChatError $ CEInternalError "member connection not active"
|
||||
introduceMember user gInfo@GroupInfo {groupId} toMember@GroupMember {activeConn = Just conn} introduceToMembers msgScope = do
|
||||
introduceMember user gInfo toMember@GroupMember {activeConn = Just conn} introduceToMembers msgScope = do
|
||||
void . sendGroupMessage' user gInfo introduceToMembers $ XGrpMemNew (memberInfo gInfo toMember) msgScope
|
||||
sendIntroductions introduceToMembers
|
||||
where
|
||||
@@ -1163,13 +1163,9 @@ introduceMember user gInfo@GroupInfo {groupId} toMember@GroupMember {activeConn
|
||||
updateToMemberVector reMembers
|
||||
updateReMembersVectors reMembers
|
||||
shuffledReMembers <- liftIO $ shuffleMembers reMembers
|
||||
if toMember `supportsVersion` batchSendVersion
|
||||
then do
|
||||
let events = map (memberIntroEvt gInfo) shuffledReMembers
|
||||
forM_ (L.nonEmpty events) $ \events' ->
|
||||
sendGroupMemberMessages user gInfo conn events'
|
||||
else forM_ shuffledReMembers $ \reMember ->
|
||||
void $ sendDirectMemberMessage conn (memberIntroEvt gInfo reMember) groupId
|
||||
let events = map (memberIntroEvt gInfo) shuffledReMembers
|
||||
forM_ (L.nonEmpty events) $ \events' ->
|
||||
sendGroupMemberMessages user gInfo conn events'
|
||||
updateToMemberVector :: [GroupMember] -> CM ()
|
||||
updateToMemberVector reMembers = do
|
||||
let relations = map (\GroupMember {indexInGroup} -> (indexInGroup, (IDReferencedIntroduced, MRIntroduced))) reMembers
|
||||
@@ -1315,20 +1311,19 @@ buildGroupRoster mods = take maxGroupRosterSize $ mapMaybe rosterMember mods
|
||||
|
||||
sendHistory :: User -> GroupInfo -> GroupMember -> CM ()
|
||||
sendHistory _ _ GroupMember {activeConn = Nothing} = throwChatError $ CEInternalError "member connection not active"
|
||||
sendHistory user gInfo@GroupInfo {membership} m@GroupMember {activeConn = Just conn} =
|
||||
when (m `supportsVersion` batchSendVersion) $ do
|
||||
(errs, items) <- partitionEithers <$> withStore' (\db -> getGroupHistoryItems db user gInfo m 100)
|
||||
(errs', fwdMsgsByItem) <- partitionEithers <$> mapM (tryAllErrors . itemForwardMsgs) items
|
||||
let errors = map ChatErrorStore errs <> errs'
|
||||
unless (null errors) $ toView $ CEvtChatErrors errors
|
||||
-- signed items keep the author's original bytes/signature, unsigned are re-encoded; the welcome message
|
||||
-- (regular groups only; never channels) is an authored element -- all batch together in order.
|
||||
let fwdEls = map (uncurry encodeFwdElement) (concat fwdMsgsByItem)
|
||||
welcomeEl <- welcomeElement
|
||||
let (batches, dropped) = batchElements maxEncodedMsgLength (fwdEls <> maybe [] (: []) welcomeEl)
|
||||
when (dropped > 0) $ toView $ CEvtChatErrors [ChatError $ CEInternalError ("sendHistory: dropped " <> show dropped <> " oversized history messages")]
|
||||
forM_ batches $ \body ->
|
||||
void $ withAgent $ \a -> sendMessages a [(aConnId conn, PQEncOff, MsgFlags False, VRValue Nothing body)]
|
||||
sendHistory user gInfo@GroupInfo {membership} m@GroupMember {activeConn = Just conn} = do
|
||||
(errs, items) <- partitionEithers <$> withStore' (\db -> getGroupHistoryItems db user gInfo m 100)
|
||||
(errs', fwdMsgsByItem) <- partitionEithers <$> mapM (tryAllErrors . itemForwardMsgs) items
|
||||
let errors = map ChatErrorStore errs <> errs'
|
||||
unless (null errors) $ toView $ CEvtChatErrors errors
|
||||
-- signed items keep the author's original bytes/signature, unsigned are re-encoded; the welcome message
|
||||
-- (regular groups only; never channels) is an authored element -- all batch together in order.
|
||||
let fwdEls = map (uncurry encodeFwdElement) (concat fwdMsgsByItem)
|
||||
welcomeEl <- welcomeElement
|
||||
let (batches, dropped) = batchElements maxEncodedMsgLength (fwdEls <> maybe [] (: []) welcomeEl)
|
||||
when (dropped > 0) $ toView $ CEvtChatErrors [ChatError $ CEInternalError ("sendHistory: dropped " <> show dropped <> " oversized history messages")]
|
||||
forM_ batches $ \body ->
|
||||
void $ withAgent $ \a -> sendMessages a [(aConnId conn, PQEncOff, MsgFlags False, VRValue Nothing body)]
|
||||
where
|
||||
welcomeElement :: CM (Maybe ByteString)
|
||||
welcomeElement = case descrEvent_ of
|
||||
@@ -1347,10 +1342,9 @@ sendHistory user gInfo@GroupInfo {membership} m@GroupMember {activeConn = Just c
|
||||
-- in channels sendHistory runs on the relay, which cannot author XMsgNew (GRRelay < GRObserver);
|
||||
-- the welcome message reaches new members via the channel link data instead
|
||||
| useRelays' gInfo = Nothing
|
||||
| m `supportsVersion` groupHistoryIncludeWelcomeVersion = do
|
||||
| otherwise = do
|
||||
let GroupInfo {groupProfile = GroupProfile {description}} = gInfo
|
||||
fmap (\descr -> XMsgNew $ mcSimple (MCText descr)) description
|
||||
| otherwise = Nothing
|
||||
itemForwardMsgs :: (CChatItem 'CTGroup, (Maybe SignedMsg, Maybe GroupMemberId)) -> CM [(GrpMsgForward, VerifiedMsg 'Json)]
|
||||
itemForwardMsgs (cci, (signedMsg_, signedByGMId_)) = case cci of
|
||||
(CChatItem SMDRcv ci@ChatItem {content = CIRcvMsgContent mc, file})
|
||||
@@ -1714,7 +1708,7 @@ updatePeerChatVRange conn@Connection {connId, connChatVersion = v, peerChatVRang
|
||||
pure conn {connChatVersion = v', peerChatVRange = msgVRange}
|
||||
else pure conn
|
||||
-- TODO v6.0 remove/review: for contacts only version upgrade should trigger enabling PQ support/encryption
|
||||
if connType == ConnContact && v' >= pqEncryptionCompressionVersion && (pqSupport /= PQSupportOn || pqEncryption /= PQEncOn)
|
||||
if connType == ConnContact && (pqSupport /= PQSupportOn || pqEncryption /= PQEncOn)
|
||||
then do
|
||||
withStore' $ \db -> updateConnSupportPQ db connId PQSupportOn PQEncOn
|
||||
pure conn' {pqSupport = PQSupportOn, pqEncryption = PQEncOn}
|
||||
@@ -2118,14 +2112,6 @@ deleteSupportChatIfExists db user gInfo m = do
|
||||
|
||||
sendDirectContactMessages :: MsgEncodingI e => User -> Contact -> NonEmpty (ChatMsgEvent e) -> CM [Either ChatError SndMessage]
|
||||
sendDirectContactMessages user ct events = do
|
||||
Connection {connChatVersion = v} <- liftEither $ contactSendConn_ ct
|
||||
if v >= batchSend2Version
|
||||
then sendDirectContactMessages' user ct events
|
||||
else forM (L.toList events) $ \evt ->
|
||||
(Right . fst <$> sendDirectContactMessage user ct evt) `catchAllErrors` \e -> pure (Left e)
|
||||
|
||||
sendDirectContactMessages' :: MsgEncodingI e => User -> Contact -> NonEmpty (ChatMsgEvent e) -> CM [Either ChatError SndMessage]
|
||||
sendDirectContactMessages' user ct events = do
|
||||
conn@Connection {connId} <- liftEither $ contactSendConn_ ct
|
||||
let idsEvts = L.map (ConnectionId connId,Nothing,) events
|
||||
msgFlags = MsgFlags {notification = any (hasNotification . toCMEventTag) events}
|
||||
@@ -2281,17 +2267,15 @@ batchSndMessagesJSON :: BatchMode -> NonEmpty (Either ChatError SndMessage) -> [
|
||||
batchSndMessagesJSON mode = batchMessages mode maxEncodedMsgLength . L.toList
|
||||
|
||||
encodeConnInfo :: MsgEncodingI e => ChatMsgEvent e -> CM ByteString
|
||||
encodeConnInfo chatMsgEvent = do
|
||||
cxt <- chatStoreCxt
|
||||
encodeConnInfoPQ PQSupportOff (maxVersion (vr cxt)) chatMsgEvent
|
||||
encodeConnInfo = encodeConnInfoPQ PQSupportOff
|
||||
|
||||
encodeConnInfoPQ :: MsgEncodingI e => PQSupport -> VersionChat -> ChatMsgEvent e -> CM ByteString
|
||||
encodeConnInfoPQ pqSup v chatMsgEvent = do
|
||||
encodeConnInfoPQ :: MsgEncodingI e => PQSupport -> ChatMsgEvent e -> CM ByteString
|
||||
encodeConnInfoPQ pqSup chatMsgEvent = do
|
||||
cxt <- chatStoreCxt
|
||||
let info = ChatMessage {chatVRange = vr cxt, msgId = Nothing, chatMsgEvent}
|
||||
case encodeChatMessage maxEncodedInfoLength info of
|
||||
ECMEncoded connInfo -> case pqSup of
|
||||
PQSupportOn | v >= pqEncryptionCompressionVersion && B.length connInfo > maxCompressedInfoLength -> do
|
||||
PQSupportOn | B.length connInfo > maxCompressedInfoLength -> do
|
||||
let connInfo' = compressedBatchMsgBody_ connInfo
|
||||
when (B.length connInfo' > maxCompressedInfoLength) $ throwChatError $ CEException "large compressed info"
|
||||
pure connInfo'
|
||||
@@ -2353,7 +2337,7 @@ deliverMessagesB msgReqs = do
|
||||
lift . withStoreBatch $ \db -> L.map (bindRight $ createDelivery db) sent
|
||||
where
|
||||
connSupportsPQ = \case
|
||||
Right (Connection {pqSupport = PQSupportOn, connChatVersion = v}, _, _) -> v >= pqEncryptionCompressionVersion
|
||||
Right (Connection {pqSupport = PQSupportOn}, _, _) -> True
|
||||
_ -> False
|
||||
compressBodies =
|
||||
forME msgReqs $ \(conn, msgFlags, (mbr, msgIds)) -> runExceptT $ do
|
||||
@@ -2490,7 +2474,7 @@ sendGroupSignedMessages user gInfo' scope asGroup members signedEvents = do
|
||||
|
||||
sendGroupProfileUpdate :: User -> GroupInfo -> Maybe GroupChatScope -> ShowGroupAsSender -> [GroupMember] -> CM ()
|
||||
sendGroupProfileUpdate user gInfo scope asGroup members
|
||||
| shouldSendProfileUpdate = sendProfileUpdate (filter (`supportsVersion` memberProfileUpdateVersion) members) `catchAllErrors` eToView
|
||||
| shouldSendProfileUpdate = sendProfileUpdate `catchAllErrors` eToView
|
||||
| not (useRelays' gInfo) = sendProfileAndKey (filter memberNeedsKey members) `catchAllErrors` eToView
|
||||
| otherwise = pure ()
|
||||
where
|
||||
@@ -2510,12 +2494,12 @@ sendGroupProfileUpdate user gInfo scope asGroup members
|
||||
profile <- presentUserBadge user incognitoProfile $ userProfileInGroup user gInfo (fromLocalProfile <$> incognitoProfile)
|
||||
(_, GroupSndResult {sentTo, pending, forwarded}) <- sendGroupMessages_ user gInfo members' False [XInfo profile (groupMemberKey gInfo)]
|
||||
pure $ [mId | (mId, _, Right _) <- sentTo] <> map (\(mId, _, _) -> mId) pending <> map groupMemberId' forwarded
|
||||
sendProfileUpdate members' = unless (null members') $ do
|
||||
delivered <- sendProfile_ members'
|
||||
sendProfileUpdate = unless (null members) $ do
|
||||
delivered <- sendProfile_ members
|
||||
currentTs <- liftIO getCurrentTime
|
||||
withStore' $ \db -> do
|
||||
updateUserMemberProfileSentAt db user gInfo currentTs
|
||||
let keyIds = S.fromList [groupMemberId' m | m <- members', memberNeedsKey m]
|
||||
let keyIds = S.fromList [groupMemberId' m | m <- members, memberNeedsKey m]
|
||||
delivered' = filter (`S.member` keyIds) delivered
|
||||
unless (useRelays' gInfo || null delivered') $ setMembersMemberKeySent db delivered'
|
||||
sendProfileAndKey members' = unless (null members') $ do
|
||||
@@ -2538,12 +2522,12 @@ sendGroupSignedMessages_ gInfo@GroupInfo {groupId} recipientMembers signedEvents
|
||||
sndMsgs_ <- lift $ createSndMessages idsEvts
|
||||
recipientMembers' <- liftIO $ shuffleMembers recipientMembers
|
||||
let msgFlags = MsgFlags {notification = any (hasNotification . toCMEventTag) events}
|
||||
(toSendSeparate, toSendBatched, toPending, forwarded, _, dups) =
|
||||
foldr' (addMember recipientMembers') ([], [], [], [], S.empty, 0 :: Int) recipientMembers'
|
||||
(toSend, toPending, forwarded, _, dups) =
|
||||
foldr' (addMember recipientMembers') ([], [], [], S.empty, 0 :: Int) recipientMembers'
|
||||
when (dups /= 0) $ logError $ "sendGroupMessages_: " <> tshow dups <> " duplicate members"
|
||||
-- TODO PQ either somehow ensure that group members connections cannot have pqSupport/pqEncryption or pass Off's here
|
||||
-- Deliver to toSend members
|
||||
let (sendToMemIds, msgReqs) = prepareMsgReqs msgFlags sndMsgs_ toSendSeparate toSendBatched
|
||||
let (sendToMemIds, msgReqs) = prepareMsgReqs msgFlags sndMsgs_ toSend
|
||||
delivered <- maybe (pure []) (fmap L.toList . deliverMessagesB) $ L.nonEmpty msgReqs
|
||||
when (length delivered /= length sendToMemIds) $ logError "sendGroupMessages_: sendToMemIds and delivered length mismatch"
|
||||
-- Save as pending for toPending members
|
||||
@@ -2563,33 +2547,27 @@ sendGroupSignedMessages_ gInfo@GroupInfo {groupId} recipientMembers signedEvents
|
||||
liftM2 (<>) (shuffle adminMs) (shuffle otherMs)
|
||||
where
|
||||
isAdmin GroupMember {memberRole} = memberRole >= GRAdmin
|
||||
addMember members m acc@(toSendSeparate, toSendBatched, pending, forwarded, !mIds, !dups) =
|
||||
addMember members m acc@(toSend, pending, forwarded, !mIds, !dups) =
|
||||
case memberSendAction gInfo events members m of
|
||||
Just a
|
||||
| mId `S.member` mIds -> (toSendSeparate, toSendBatched, pending, forwarded, mIds, dups + 1)
|
||||
| mId `S.member` mIds -> (toSend, pending, forwarded, mIds, dups + 1)
|
||||
| otherwise -> case a of
|
||||
MSASend conn -> ((m, conn) : toSendSeparate, toSendBatched, pending, forwarded, mIds', dups)
|
||||
MSASendBatched conn -> (toSendSeparate, (m, conn) : toSendBatched, pending, forwarded, mIds', dups)
|
||||
MSAPending -> (toSendSeparate, toSendBatched, m : pending, forwarded, mIds', dups)
|
||||
MSAForwarded -> (toSendSeparate, toSendBatched, pending, m : forwarded, mIds', dups)
|
||||
MSASend conn -> ((m, conn) : toSend, pending, forwarded, mIds', dups)
|
||||
MSAPending -> (toSend, m : pending, forwarded, mIds', dups)
|
||||
MSAForwarded -> (toSend, pending, m : forwarded, mIds', dups)
|
||||
Nothing -> acc
|
||||
where
|
||||
mId = groupMemberId' m
|
||||
mIds' = S.insert mId mIds
|
||||
prepareMsgReqs :: MsgFlags -> NonEmpty (Either ChatError SndMessage) -> [(GroupMember, Connection)] -> [(GroupMember, Connection)] -> ([GroupMemberId], [Either ChatError ChatMsgReq])
|
||||
prepareMsgReqs msgFlags msgs toSendSeparate toSendBatched =
|
||||
batchReqs BMBinary msgs binSep binBtch <> batchReqs BMJson msgs jsonSep jsonBtch
|
||||
prepareMsgReqs :: MsgFlags -> NonEmpty (Either ChatError SndMessage) -> [(GroupMember, Connection)] -> ([GroupMemberId], [Either ChatError ChatMsgReq])
|
||||
prepareMsgReqs msgFlags msgs toSend =
|
||||
let (toSendBin, toSendJson) = partition useBinary toSend
|
||||
useBinary (m, _) = useRelays' gInfo || m `supportsVersion` relayWebCapVersion
|
||||
in batchReqs BMBinary msgs toSendBin <> batchReqs BMJson msgs toSendJson
|
||||
where
|
||||
toBinary (m, _) = useRelays' gInfo || m `supportsVersion` relayWebCapVersion
|
||||
(binSep, jsonSep) = partition toBinary toSendSeparate
|
||||
(binBtch, jsonBtch) = partition toBinary toSendBatched
|
||||
batchReqs _ _ [] [] = ([], [])
|
||||
batchReqs mode msgs' sep btch = case L.nonEmpty (batchSndMessagesJSON mode msgs') of
|
||||
Just batched ->
|
||||
let lenMsgs = length msgs'
|
||||
(memsSep, mreqsSep) = foldMembers lenMsgs sndMessageMBR msgs' sep
|
||||
(memsBtch, mreqsBtch) = foldMembers (length batched + lenMsgs) msgBatchMBR batched btch
|
||||
in (memsSep <> memsBtch, mreqsSep <> mreqsBtch)
|
||||
batchReqs _ [] [] = ([], [])
|
||||
batchReqs mode msgs' toSend' = case L.nonEmpty (batchSndMessagesJSON mode msgs') of
|
||||
Just batched -> foldMembers (length batched + length msgs') msgBatchMBR batched toSend'
|
||||
Nothing -> ([], [])
|
||||
foldMembers :: forall a. Int -> (Maybe Int -> Int -> a -> (ValueOrRef MsgBody, [MessageId])) -> NonEmpty (Either ChatError a) -> [(GroupMember, Connection)] -> ([GroupMemberId], [Either ChatError ChatMsgReq])
|
||||
foldMembers lastRef mkMb mbs mems = snd $ foldr' foldMsgBodies (lastMemIdx_, ([], [])) mems
|
||||
@@ -2603,8 +2581,6 @@ sendGroupSignedMessages_ gInfo@GroupInfo {groupId} recipientMembers signedEvents
|
||||
addBody mb (i, (memIds, reqs)) =
|
||||
let req = (conn,msgFlags,) . mkMb memIdx_ i <$> mb
|
||||
in (i - 1, (groupMemberId : memIds, req : reqs))
|
||||
sndMessageMBR :: Maybe Int -> Int -> SndMessage -> (ValueOrRef MsgBody, [MessageId])
|
||||
sndMessageMBR memIdx_ i SndMessage {msgId, msgBody} = (vrValue_ memIdx_ i msgBody, [msgId])
|
||||
msgBatchMBR :: Maybe Int -> Int -> MsgBatch -> (ValueOrRef MsgBody, [MessageId])
|
||||
msgBatchMBR memIdx_ i (MsgBatch batchBody sndMsgs) = (vrValue_ memIdx_ i batchBody, map (\SndMessage {msgId} -> msgId) sndMsgs)
|
||||
vrValue_ memIdx_ i v = case memIdx_ of
|
||||
@@ -2625,31 +2601,26 @@ sendGroupSignedMessages_ gInfo@GroupInfo {groupId} recipientMembers signedEvents
|
||||
createPendingMsg db (groupMemberId, msgId) =
|
||||
createPendingGroupMessage db groupMemberId msgId $> Right ()
|
||||
|
||||
data MemberSendAction = MSASend Connection | MSASendBatched Connection | MSAPending | MSAForwarded
|
||||
data MemberSendAction = MSASend Connection | MSAPending | MSAForwarded
|
||||
|
||||
memberSendAction :: GroupInfo -> NonEmpty (ChatMsgEvent e) -> [GroupMember] -> GroupMember -> Maybe MemberSendAction
|
||||
memberSendAction gInfo@GroupInfo {membership} events members m@GroupMember {memberRole, memberStatus}
|
||||
memberSendAction gInfo@GroupInfo {membership} events members m@GroupMember {memberStatus}
|
||||
-- groups with relays require newer version - we don't need to check member version for batching and forwarding support
|
||||
| useRelays' gInfo =
|
||||
if
|
||||
-- if user is chat relay, send to all non chat relay members
|
||||
| isRelay membership && not (isRelay m) -> MSASendBatched . snd <$> readyMemberConn m
|
||||
| isRelay membership && not (isRelay m) -> MSASend . snd <$> readyMemberConn m
|
||||
-- if user is not chat relay, send only to chat relays
|
||||
| not (isRelay membership) && isRelay m -> MSASendBatched . snd <$> readyMemberConn m
|
||||
| not (isRelay membership) && isRelay m -> MSASend . snd <$> readyMemberConn m
|
||||
| otherwise -> Nothing -- TODO [relays] MSAForwarded to create GSSForwarded snd statuses?
|
||||
| otherwise = case memberConn m of
|
||||
Nothing -> pendingOrForwarded
|
||||
Just conn@Connection {connStatus}
|
||||
| connDisabled conn || connStatus == ConnDeleted || isConnFailed connStatus || memberStatus == GSMemRejected -> Nothing
|
||||
| connInactive conn -> Just MSAPending
|
||||
| connStatus == ConnSndReady || connStatus == ConnReady -> sendBatchedOrSeparate conn
|
||||
| connStatus == ConnSndReady || connStatus == ConnReady -> Just (MSASend conn)
|
||||
| otherwise -> pendingOrForwarded
|
||||
where
|
||||
sendBatchedOrSeparate conn
|
||||
-- admin doesn't support batch forwarding - send messages separately so that admin can forward one by one
|
||||
| memberRole >= GRAdmin && not (m `supportsVersion` batchSend2Version) = Just (MSASend conn)
|
||||
-- either member is not admin, or admin supports batched forwarding
|
||||
| otherwise = Just (MSASendBatched conn)
|
||||
pendingOrForwarded = case memberCategory m of
|
||||
GCUserMember -> Nothing -- shouldn't happen
|
||||
GCInviteeMember -> Just MSAPending
|
||||
@@ -2658,18 +2629,14 @@ memberSendAction gInfo@GroupInfo {membership} events members m@GroupMember {memb
|
||||
GCPostMember -> forwardSupportedOrPending (invitedByGroupMemberId m)
|
||||
where
|
||||
forwardSupportedOrPending invitingMemberId_
|
||||
| membersSupport && all isForwardedGroupMsg events = Just MSAForwarded
|
||||
| hasInvitingMember && all isForwardedGroupMsg events = Just MSAForwarded
|
||||
| any isXGrpMsgForward events = Nothing
|
||||
| otherwise = Just MSAPending
|
||||
where
|
||||
membersSupport =
|
||||
m `supportsVersion` groupForwardVersion && invitingMemberSupportsForward
|
||||
invitingMemberSupportsForward = case invitingMemberId_ of
|
||||
hasInvitingMember = case invitingMemberId_ of
|
||||
Just invMemberId ->
|
||||
-- can be optimized for large groups by replacing [GroupMember] with Map GroupMemberId GroupMember
|
||||
case find (\m' -> groupMemberId' m' == invMemberId) members of
|
||||
Just invitingMember -> invitingMember `supportsVersion` groupForwardVersion
|
||||
Nothing -> False
|
||||
any (\m' -> groupMemberId' m' == invMemberId) members
|
||||
Nothing -> False
|
||||
isXGrpMsgForward event = case event of
|
||||
XGrpMsgForward {} -> True
|
||||
@@ -2694,7 +2661,6 @@ sendGroupMemberMessage gInfo@GroupInfo {groupId} m@GroupMember {groupMemberId} c
|
||||
messageMember :: SndMessage -> CM ()
|
||||
messageMember SndMessage {msgId, msgBody} = forM_ (memberSendAction gInfo (chatMsgEvent :| []) [m] m) $ \case
|
||||
MSASend conn -> void $ deliverMessage conn (toCMEventTag chatMsgEvent) msgBody msgId
|
||||
MSASendBatched conn -> void $ deliverMessage conn (toCMEventTag chatMsgEvent) msgBody msgId
|
||||
MSAPending -> withStore' $ \db -> createPendingGroupMessage db groupMemberId msgId
|
||||
MSAForwarded -> pure ()
|
||||
|
||||
@@ -2715,7 +2681,9 @@ sendPendingGroupMessages user gInfo GroupMember {groupMemberId} conn = do
|
||||
|
||||
saveDirectRcvMSG :: forall e. MsgEncodingI e => Connection -> MsgMeta -> ChatMessage e -> CM (Connection, RcvMessage)
|
||||
saveDirectRcvMSG conn@Connection {connId} agentMsgMeta chatMsg@ChatMessage {chatVRange, msgId = sharedMsgId_, chatMsgEvent} = do
|
||||
conn' <- updatePeerChatVRange conn chatVRange
|
||||
conn' <- case encoding @e of
|
||||
SJson -> updatePeerChatVRange conn chatVRange
|
||||
SBinary -> pure conn
|
||||
let agentMsgId = fst $ recipient agentMsgMeta
|
||||
brokerTs = metaBrokerTs agentMsgMeta
|
||||
newMsg = NewRcvMessage {chatMsgEvent, verifiedMsg = VMUnsigned chatMsg, brokerTs}
|
||||
@@ -2913,8 +2881,8 @@ joinAgentConnectionAsync cmdId updateConn connId enableNtfs cReqUri cInfo subMod
|
||||
withAgent $ \a -> joinConnectionAsync a (aCorrId cmdId) updateConn connId enableNtfs cReqUri cInfo PQSupportOff subMode
|
||||
|
||||
allowAgentConnectionAsync :: MsgEncodingI e => User -> Connection -> ConfirmationId -> ChatMsgEvent e -> CM ()
|
||||
allowAgentConnectionAsync user conn@Connection {pqSupport, connChatVersion} confId msg = do
|
||||
dm <- encodeConnInfoPQ pqSupport connChatVersion msg
|
||||
allowAgentConnectionAsync user conn@Connection {pqSupport} confId msg = do
|
||||
dm <- encodeConnInfoPQ pqSupport msg
|
||||
allowAgentConnectionInfo user conn confId dm
|
||||
|
||||
allowAgentConnectionInfo :: User -> Connection -> ConfirmationId -> ByteString -> CM ()
|
||||
@@ -2929,9 +2897,9 @@ prepareAgentAccept user enableNtfs invId pqSup = do
|
||||
connId <- withAgent $ \a -> prepareConnectionToAccept a (aUserId user) enableNtfs invId pqSup
|
||||
pure (cmdId, connId)
|
||||
|
||||
agentAcceptContactAsync :: MsgEncodingI e => CommandId -> ConnId -> Bool -> InvitationId -> ChatMsgEvent e -> PQSupport -> VersionChat -> SubscriptionMode -> CM ()
|
||||
agentAcceptContactAsync cmdId connId enableNtfs invId msg pqSup chatV subMode = do
|
||||
dm <- encodeConnInfoPQ pqSup chatV msg
|
||||
agentAcceptContactAsync :: MsgEncodingI e => CommandId -> ConnId -> Bool -> InvitationId -> ChatMsgEvent e -> PQSupport -> SubscriptionMode -> CM ()
|
||||
agentAcceptContactAsync cmdId connId enableNtfs invId msg pqSup subMode = do
|
||||
dm <- encodeConnInfoPQ pqSup msg
|
||||
withAgent $ \a -> acceptContactAsync a (aCorrId cmdId) connId enableNtfs invId dm pqSup subMode
|
||||
|
||||
deleteAgentConnectionAsync :: ConnId -> CM ()
|
||||
|
||||
@@ -439,7 +439,7 @@ processAgentMessageConn cxt user@User {userId} corrId agentConnId agentMessage =
|
||||
when (pq /= pq') $ messageWarning "processINFOpqSupport: unexpected pqSupport change"
|
||||
|
||||
processDirectMessage :: AEvent e -> ConnectionEntity -> Connection -> Maybe Contact -> CM ()
|
||||
processDirectMessage agentMsg connEntity conn@Connection {connId, connChatVersion, peerChatVRange, viaUserContactLink, customUserProfileId, connectionCode} = \case
|
||||
processDirectMessage agentMsg connEntity conn@Connection {connId, viaUserContactLink, customUserProfileId, connectionCode} = \case
|
||||
Nothing -> case agentMsg of
|
||||
CONF confId pqSupport _ connInfo -> do
|
||||
chatRelayTests_ <- asks chatRelayTests
|
||||
@@ -642,19 +642,6 @@ processAgentMessageConn cxt user@User {userId} corrId agentConnId agentMessage =
|
||||
when (contactConnInitiated conn') $ do
|
||||
probeMatchingMembers ct' (contactConnIncognito ct')
|
||||
withStore' $ \db -> resetContactConnInitiated db user conn'
|
||||
forM_ viaUserContactLink $ \userContactLinkId -> do
|
||||
(ucl, gli_) <- withStore $ \db -> getUserContactLinkById db userId userContactLinkId
|
||||
-- let UserContactLink {addressSettings = AddressSettings {autoReply}} = ucl
|
||||
when (connChatVersion < batchSend2Version) $ forM_ (autoReply $ addressSettings ucl) $ \mc -> sendAutoReply ct' mc Nothing -- old versions only
|
||||
-- TODO REMOVE LEGACY vvv
|
||||
forM_ gli_ $ \GroupLinkInfo {groupId, memberRole = gLinkMemRole} -> do
|
||||
groupInfo <- withStore $ \db -> getGroupInfo db cxt user groupId
|
||||
subMode <- chatReadVar subscriptionMode
|
||||
groupConnIds@(cmdId, grpConnId) <- prepareAgentCreation user CFCreateConnGrpInv True SCMInvitation
|
||||
gVar <- asks random
|
||||
withStore $ \db -> createNewContactMemberAsync db gVar user groupInfo ct' gLinkMemRole groupConnIds connChatVersion peerChatVRange subMode
|
||||
withAgent $ \a -> createConnectionAsync a (aCorrId cmdId) grpConnId True SCMInvitation CR.IKPQOff subMode
|
||||
-- TODO REMOVE LEGACY ^^^
|
||||
SENT msgId proxy -> do
|
||||
void $ continueSending connEntity conn
|
||||
sentMsgDeliveryEvent conn msgId
|
||||
@@ -705,7 +692,7 @@ processAgentMessageConn cxt user@User {userId} corrId agentConnId agentMessage =
|
||||
when (corrId /= "") $ withCompletedCommand conn agentMsg $ \_cmdData ->
|
||||
when (directOrUsed ct && sqSecured) $ do
|
||||
toView $ CEvtContactSndReady user ct
|
||||
when (connChatVersion >= batchSend2Version) $ forM_ viaUserContactLink $ \userContactLinkId -> do
|
||||
forM_ viaUserContactLink $ \userContactLinkId -> do
|
||||
(ucl, _) <- withStore $ \db -> getUserContactLinkById db userId userContactLinkId
|
||||
forM_ (autoReply $ addressSettings ucl) $ \mc -> do
|
||||
connReq_ <- pure (contactRequestId' ct) $>>= \connReqId -> withStore' (\db -> getContactRequest' db user connReqId)
|
||||
@@ -740,53 +727,18 @@ processAgentMessageConn cxt user@User {userId} corrId agentConnId agentMessage =
|
||||
toView $ CEvtNewChatItems user [AChatItem SCTDirect SMDSnd (DirectChat ct) ci]
|
||||
|
||||
processGroupMessage :: AEvent e -> ConnectionEntity -> Connection -> GroupInfo -> GroupMember -> CM ()
|
||||
processGroupMessage agentMsg connEntity conn@Connection {connId, connChatVersion, customUserProfileId, connectionCode} gInfo@GroupInfo {groupId, groupProfile, membership, chatSettings} m = case agentMsg of
|
||||
processGroupMessage agentMsg connEntity conn@Connection {connId, customUserProfileId, connectionCode} gInfo@GroupInfo {groupId, groupProfile, membership, chatSettings} m = case agentMsg of
|
||||
INV (ACR _ cReq) ->
|
||||
withCompletedCommand conn agentMsg $ \CommandData {cmdFunction} ->
|
||||
case cReq of
|
||||
groupConnReq@(CRInvitationUri _ _) -> case cmdFunction of
|
||||
-- [async agent commands] XGrpMemIntro continuation on receiving INV
|
||||
CFCreateConnGrpMemInv
|
||||
| maxVersion (peerChatVRange conn) >= groupDirectInvVersion -> sendWithoutDirectCReq
|
||||
| otherwise -> messageError "processGroupMessage INV: member chat version range incompatible"
|
||||
where
|
||||
sendWithoutDirectCReq = do
|
||||
let GroupMember {groupMemberId, memberId} = m
|
||||
hostConnId <- withStore $ \db -> do
|
||||
liftIO $ setConnConnReqInv db user connId cReq
|
||||
getHostConnId db user groupId
|
||||
sendXGrpMemInv hostConnId Nothing XGrpMemIntroCont {groupId, groupMemberId, memberId, groupConnReq}
|
||||
-- TODO REMOVE LEGACY vvv
|
||||
-- [async agent commands] group link auto-accept continuation on receiving INV
|
||||
CFCreateConnGrpInv -> do
|
||||
(ct, groupLinkId) <- withStore $ \db -> do
|
||||
ct <- getContactViaMember db cxt user m
|
||||
liftIO $ setNewContactMemberConnRequest db user m cReq
|
||||
liftIO $ (ct,) <$> getGroupLinkId db user gInfo
|
||||
if memberRole' membership >= GRAdmin
|
||||
then do
|
||||
sendGrpInvitation ct m groupLinkId
|
||||
toView $ CEvtSentGroupInvitation user gInfo ct m
|
||||
else messageError "processGroupMessage: group link host no longer has admin role"
|
||||
where
|
||||
sendGrpInvitation :: Contact -> GroupMember -> Maybe GroupLinkId -> CM ()
|
||||
sendGrpInvitation ct GroupMember {memberId, memberRole = memRole} groupLinkId = do
|
||||
let currentMemCount = fromIntegral $ currentMembers $ groupSummary gInfo
|
||||
GroupMember {memberRole = userRole, memberId = userMemberId} = membership
|
||||
groupInv =
|
||||
GroupInvitation
|
||||
{ fromMember = MemberIdRole userMemberId userRole,
|
||||
invitedMember = MemberIdRole memberId memRole,
|
||||
connRequest = cReq,
|
||||
groupProfile,
|
||||
business = Nothing,
|
||||
groupLinkId = groupLinkId,
|
||||
groupSize = Just currentMemCount
|
||||
}
|
||||
(_msg, _) <- sendDirectContactMessage user ct $ XGrpInv groupInv
|
||||
-- we could link chat item with sent group invitation message (_msg)
|
||||
createInternalChatItem user (CDGroupRcv gInfo Nothing m) (CIRcvGroupEvent RGEInvitedViaGroupLink) Nothing
|
||||
-- TODO REMOVE LEGACY ^^^
|
||||
CFCreateConnGrpMemInv -> do
|
||||
let GroupMember {groupMemberId, memberId} = m
|
||||
hostConnId <- withStore $ \db -> do
|
||||
liftIO $ setConnConnReqInv db user connId cReq
|
||||
getHostConnId db user groupId
|
||||
sendXGrpMemInv hostConnId Nothing XGrpMemIntroCont {groupId, groupMemberId, memberId, groupConnReq}
|
||||
_ -> throwChatError $ CECommandError "unexpected cmdFunction"
|
||||
CRContactUri _ -> throwChatError $ CECommandError "unexpected ConnectionRequestUri type"
|
||||
CONF confId _pqSupport _ connInfo -> do
|
||||
@@ -961,7 +913,6 @@ processAgentMessageConn cxt user@User {userId} corrId agentConnId agentMessage =
|
||||
toView $ CEvtJoinedGroupMember user gInfo'' m' {memberStatus = mStatus}
|
||||
let Connection {viaUserContactLink} = conn
|
||||
when (isJust viaUserContactLink && isNothing (memberContactId m')) $ sendXGrpLinkMem gInfo'' m'
|
||||
when (connChatVersion < batchSend2Version) $ getAutoReplyMsg >>= mapM_ (\mc -> sendGroupAutoReply mc Nothing)
|
||||
if useRelays' gInfo''
|
||||
then do
|
||||
introduceInChannel cxt user gInfo'' m'
|
||||
@@ -1231,7 +1182,7 @@ processAgentMessageConn cxt user@User {userId} corrId agentConnId agentMessage =
|
||||
JOINED sqSecured ->
|
||||
-- [async agent commands] continuation on receiving JOINED
|
||||
when (corrId /= "") $ withCompletedCommand conn agentMsg $ \_cmdData ->
|
||||
when (sqSecured && connChatVersion >= batchSend2Version) $ do
|
||||
when (sqSecured) $ do
|
||||
mc_ <- getAutoReplyMsg
|
||||
forM_ mc_ $ \mc -> do
|
||||
connReq_ <- withStore' $ \db -> getBusinessContactRequest db user groupId
|
||||
@@ -1252,8 +1203,8 @@ processAgentMessageConn cxt user@User {userId} corrId agentConnId agentMessage =
|
||||
let pqSup = PQSupportOff
|
||||
lift (withAgent' $ \a -> connRequestPQSupport a pqSup cReq) >>= \case
|
||||
Nothing -> throwChatError CEInvalidConnReq
|
||||
Just (agentV, _) -> do
|
||||
let chatV = agentToChatVersion agentV
|
||||
Just _ -> do
|
||||
let chatV = initialChatVersion
|
||||
groupLinkId = crClientData >>= decodeJSON >>= \(CRDataGroup gli) -> Just gli
|
||||
cReqHash = contactCReqHash $ CRContactUri crData {crScheme = SSSimplex}
|
||||
-- Update connection with data derived from cReq, now available after getConnShortLinkAsync
|
||||
@@ -1626,15 +1577,12 @@ processAgentMessageConn cxt user@User {userId} corrId agentConnId agentMessage =
|
||||
| otherwise -> do
|
||||
acceptMember_ <- asks $ acceptMember . chatHooks . config
|
||||
maybe (pure $ Right (GAAccepted, gLinkMemRole)) (\am -> liftIO $ am gInfo gli p) acceptMember_ >>= \case
|
||||
Right (acceptance, useRole)
|
||||
| v < groupFastLinkJoinVersion ->
|
||||
messageError "processContactConnMessage: chat version range incompatible for accepting group join request"
|
||||
| otherwise -> do
|
||||
let profileMode = ExistingIncognito <$> incognitoMembershipProfile gInfo
|
||||
mem <- acceptGroupJoinRequestAsync user uclId gInfo invId chatVRange p xContactId_ Nothing welcomeMsgId_ acceptance useRole profileMode memberKey_ Nothing
|
||||
(gInfo', mem', scopeInfo) <- mkGroupChatScope gInfo mem
|
||||
createInternalChatItem user (CDGroupRcv gInfo' scopeInfo mem') (CIRcvGroupEvent RGEInvitedViaGroupLink) Nothing
|
||||
toView $ CEvtAcceptingGroupJoinRequestMember user gInfo' mem'
|
||||
Right (acceptance, useRole) -> do
|
||||
let profileMode = ExistingIncognito <$> incognitoMembershipProfile gInfo
|
||||
mem <- acceptGroupJoinRequestAsync user uclId gInfo invId chatVRange p xContactId_ Nothing welcomeMsgId_ acceptance useRole profileMode memberKey_ Nothing
|
||||
(gInfo', mem', scopeInfo) <- mkGroupChatScope gInfo mem
|
||||
createInternalChatItem user (CDGroupRcv gInfo' scopeInfo mem') (CIRcvGroupEvent RGEInvitedViaGroupLink) Nothing
|
||||
toView $ CEvtAcceptingGroupJoinRequestMember user gInfo' mem'
|
||||
Left rjctReason
|
||||
| v < groupJoinRejectVersion ->
|
||||
messageWarning $ "processContactConnMessage (group " <> groupName' gInfo <> "): joining of " <> displayName <> " is blocked"
|
||||
@@ -1665,7 +1613,7 @@ processAgentMessageConn cxt user@User {userId} corrId agentConnId agentMessage =
|
||||
withStore $ \db -> do
|
||||
Connection {connId = testCId} <- createRelayTestConnection db cxt user acId ConnAccepted chatV subMode
|
||||
liftIO $ setCommandConnId db user cmdId testCId
|
||||
agentAcceptContactAsync cmdId acId True invId msg PQSupportOff chatV subMode
|
||||
agentAcceptContactAsync cmdId acId True invId msg PQSupportOff subMode
|
||||
| otherwise = messageError "relay test sent to non-relay link"
|
||||
where
|
||||
User {userChatRelay} = user
|
||||
@@ -2843,10 +2791,8 @@ processAgentMessageConn cxt user@User {userId} corrId agentConnId agentMessage =
|
||||
|
||||
maybeCreateGroupDescrLocal :: GroupInfo -> GroupMember -> CM ()
|
||||
maybeCreateGroupDescrLocal gInfo@GroupInfo {groupProfile = GroupProfile {description}} m =
|
||||
unless expectHistory $ forM_ description $ \descr ->
|
||||
unless (groupFeatureAllowed SGFHistory gInfo) $ forM_ description $ \descr ->
|
||||
createInternalChatItem user (CDGroupRcv gInfo Nothing m) (CIRcvMsgContent $ MCText descr) Nothing
|
||||
where
|
||||
expectHistory = groupFeatureAllowed SGFHistory gInfo && m `supportsVersion` groupHistoryIncludeWelcomeVersion
|
||||
|
||||
processMemberProfileUpdate :: GroupInfo -> GroupMember -> Profile -> Maybe (RcvMessage, UTCTime) -> CM GroupMember
|
||||
processMemberProfileUpdate gInfo m@GroupMember {memberProfile = p, memberContactId} p' msgTs_
|
||||
@@ -3244,16 +3190,14 @@ processAgentMessageConn cxt user@User {userId} corrId agentConnId agentMessage =
|
||||
when (memberRole < GRAdmin) $ throwChatError (CEGroupContactRole c)
|
||||
case memChatVRange of
|
||||
Nothing -> messageError "x.grp.mem.intro: member chat version range incompatible"
|
||||
Just (ChatVersionRange mcvr)
|
||||
| maxVersion mcvr >= groupDirectInvVersion -> do
|
||||
subMode <- chatReadVar subscriptionMode
|
||||
groupConnIds@(cmdId, connId) <- prepareAgentCreation user CFCreateConnGrpMemInv (chatHasNtfs chatSettings) SCMInvitation
|
||||
let chatV = maybe (minVersion (vr cxt)) (\peerVR -> vr cxt `peerConnChatVersion` fromChatVRange peerVR) memChatVRange
|
||||
void $ withStore $ \db -> do
|
||||
reMember <- createIntroReMember db cxt user gInfo memInfo memRestrictions
|
||||
createIntroReMemberConn db user m reMember chatV memInfo groupConnIds subMode
|
||||
withAgent $ \a -> createConnectionAsync a (aCorrId cmdId) connId (chatHasNtfs chatSettings) SCMInvitation CR.IKPQOff subMode
|
||||
| otherwise -> messageError "x.grp.mem.intro: member chat version range incompatible"
|
||||
Just _ -> do
|
||||
subMode <- chatReadVar subscriptionMode
|
||||
groupConnIds@(cmdId, connId) <- prepareAgentCreation user CFCreateConnGrpMemInv (chatHasNtfs chatSettings) SCMInvitation
|
||||
let chatV = maybe (minVersion (vr cxt)) (\peerVR -> vr cxt `peerConnChatVersion` fromChatVRange peerVR) memChatVRange
|
||||
void $ withStore $ \db -> do
|
||||
reMember <- createIntroReMember db cxt user gInfo memInfo memRestrictions
|
||||
createIntroReMemberConn db user m reMember chatV memInfo groupConnIds subMode
|
||||
withAgent $ \a -> createConnectionAsync a (aCorrId cmdId) connId (chatHasNtfs chatSettings) SCMInvitation CR.IKPQOff subMode
|
||||
_ -> messageError "x.grp.mem.intro can be only sent by host member"
|
||||
|
||||
sendXGrpMemInv :: Int64 -> Maybe ConnReqInvitation -> XGrpMemIntroCont -> CM ()
|
||||
|
||||
@@ -56,7 +56,6 @@ import Simplex.Chat.Types
|
||||
import Simplex.Chat.Types.Preferences
|
||||
import Simplex.Chat.Types.Shared
|
||||
import qualified Simplex.FileTransfer.Description as FD
|
||||
import Simplex.Messaging.Agent.Protocol (VersionSMPA, pqdrSMPAgentVersion)
|
||||
import Simplex.Messaging.Agent.Store.DB (blobFieldDecoder, fromTextField_)
|
||||
import Simplex.Messaging.Compression (Compressed, compress1, decompress1, decompressedSize)
|
||||
import qualified Simplex.Messaging.Crypto as C
|
||||
@@ -99,38 +98,6 @@ supportedChatVRange :: VersionRangeChat
|
||||
supportedChatVRange = mkVersionRange initialChatVersion currentChatVersion
|
||||
{-# INLINE supportedChatVRange #-}
|
||||
|
||||
-- version range that supports skipping establishing direct connections in a group and establishing direct connection via x.grp.direct.inv
|
||||
groupDirectInvVersion :: VersionChat
|
||||
groupDirectInvVersion = VersionChat 2
|
||||
|
||||
-- version range that supports joining group via group link without creating direct contact
|
||||
groupFastLinkJoinVersion :: VersionChat
|
||||
groupFastLinkJoinVersion = VersionChat 3
|
||||
|
||||
-- version range that supports group forwarding
|
||||
groupForwardVersion :: VersionChat
|
||||
groupForwardVersion = VersionChat 4
|
||||
|
||||
-- version range that supports batch sending in groups
|
||||
batchSendVersion :: VersionChat
|
||||
batchSendVersion = VersionChat 5
|
||||
|
||||
-- version range that supports sending group welcome message in group history
|
||||
groupHistoryIncludeWelcomeVersion :: VersionChat
|
||||
groupHistoryIncludeWelcomeVersion = VersionChat 6
|
||||
|
||||
-- version range that supports sending member profile updates to groups
|
||||
memberProfileUpdateVersion :: VersionChat
|
||||
memberProfileUpdateVersion = VersionChat 7
|
||||
|
||||
-- version range that supports compressing messages and PQ e2e encryption
|
||||
pqEncryptionCompressionVersion :: VersionChat
|
||||
pqEncryptionCompressionVersion = VersionChat 8
|
||||
|
||||
-- version range that supports batch sending in direct connections, and forwarding batched messages in groups
|
||||
batchSend2Version :: VersionChat
|
||||
batchSend2Version = VersionChat 9
|
||||
|
||||
-- supports differentiating business chats when joining contact addresses
|
||||
businessChatsVersion :: VersionChat
|
||||
businessChatsVersion = VersionChat 10
|
||||
@@ -172,11 +139,6 @@ groupRosterVersion = VersionChat 19
|
||||
groupMemberKeyVersion :: VersionChat
|
||||
groupMemberKeyVersion = VersionChat 20
|
||||
|
||||
agentToChatVersion :: VersionSMPA -> VersionChat
|
||||
agentToChatVersion v
|
||||
| v < pqdrSMPAgentVersion = initialChatVersion
|
||||
| otherwise = pqEncryptionCompressionVersion
|
||||
|
||||
data ConnectionEntity
|
||||
= RcvDirectMsgConnection {entityConnection :: Connection, contact :: Maybe Contact}
|
||||
| RcvGroupMsgConnection {entityConnection :: Connection, groupInfo :: GroupInfo, groupMember :: GroupMember}
|
||||
|
||||
@@ -27,7 +27,6 @@ module Simplex.Chat.Store.Groups
|
||||
getGroupLinkConnection,
|
||||
deleteGroupLink,
|
||||
getGroupLink,
|
||||
getGroupLinkId,
|
||||
setGroupLinkMemberRole,
|
||||
setGroupLinkShortLink,
|
||||
createNewGroup,
|
||||
@@ -132,13 +131,11 @@ module Simplex.Chat.Store.Groups
|
||||
getRelayServedGroups,
|
||||
getRelayPublishableGroups,
|
||||
getRelayInactiveGroups,
|
||||
createNewContactMemberAsync,
|
||||
createJoiningMember,
|
||||
getMemberJoinRequest,
|
||||
createJoiningMemberConnection,
|
||||
createBusinessRequestGroup,
|
||||
getContactViaMember,
|
||||
setNewContactMemberConnRequest,
|
||||
getMemberInvitation,
|
||||
createMemberConnection,
|
||||
createMemberConnectionAsync,
|
||||
@@ -357,11 +354,6 @@ getGroupLink db User {userId} gInfo@GroupInfo {groupId} =
|
||||
acceptMemberRole = fromMaybe GRMember mRole_
|
||||
}
|
||||
|
||||
getGroupLinkId :: DB.Connection -> User -> GroupInfo -> IO (Maybe GroupLinkId)
|
||||
getGroupLinkId db User {userId} GroupInfo {groupId} =
|
||||
fmap join . maybeFirstRow fromOnly $
|
||||
DB.query db "SELECT group_link_id FROM user_contact_links WHERE user_id = ? AND group_id = ? LIMIT 1" (userId, groupId)
|
||||
|
||||
setGroupLinkMemberRole :: DB.Connection -> User -> GroupLink -> GroupMemberRole -> IO GroupLink
|
||||
setGroupLinkMemberRole db User {userId} gLnk@GroupLink{userContactLinkId} memberRole = do
|
||||
DB.execute db "UPDATE user_contact_links SET group_link_member_role = ? WHERE user_id = ? AND user_contact_link_id = ?" (memberRole, userId, userContactLinkId)
|
||||
@@ -2071,33 +2063,6 @@ getRelayInactiveGroups db cxt User {userId, userContactId} ttl = do
|
||||
)
|
||||
(userId, userContactId, RSInactive, cutoffTs)
|
||||
|
||||
createNewContactMemberAsync :: DB.Connection -> TVar ChaChaDRG -> User -> GroupInfo -> Contact -> GroupMemberRole -> (CommandId, ConnId) -> VersionChat -> VersionRangeChat -> SubscriptionMode -> ExceptT StoreError IO ()
|
||||
createNewContactMemberAsync db gVar user@User {userId, userContactId} GroupInfo {groupId, membership} Contact {contactId, localDisplayName, profile} memberRole (cmdId, agentConnId) chatV peerChatVRange subMode =
|
||||
createWithRandomId' db gVar $ \memId -> runExceptT $ do
|
||||
createdAt <- liftIO getCurrentTime
|
||||
insertMember_ (MemberId memId) createdAt
|
||||
groupMemberId <- liftIO $ insertedRowId db
|
||||
Connection {connId} <- liftIO $ createMemberConnection_ db userId groupMemberId agentConnId chatV peerChatVRange Nothing 0 createdAt subMode
|
||||
liftIO $ setCommandConnId db user cmdId connId
|
||||
where
|
||||
VersionRange minV maxV = peerChatVRange
|
||||
insertMember_ memberId createdAt = do
|
||||
indexInGroup <- getUpdateNextIndexInGroup_ db groupId
|
||||
liftIO $
|
||||
DB.execute
|
||||
db
|
||||
[sql|
|
||||
INSERT INTO group_members
|
||||
( group_id, index_in_group, member_id, member_role, member_category, member_status, member_relations_vector, invited_by, invited_by_group_member_id,
|
||||
user_id, local_display_name, contact_id, contact_profile_id, created_at, updated_at,
|
||||
peer_chat_min_version, peer_chat_max_version)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
|
||||
|]
|
||||
( (groupId, indexInGroup, memberId, memberRole, GCInviteeMember, GSMemInvited, Binary B.empty, fromInvitedBy userContactId IBUser, groupMemberId' membership)
|
||||
:. (userId, localDisplayName, contactId, localProfileId profile, createdAt, createdAt)
|
||||
:. (minV, maxV)
|
||||
)
|
||||
|
||||
createJoiningMember :: DB.Connection -> StoreCxt -> TVar ChaChaDRG -> User -> GroupInfo -> VersionRangeChat -> Profile -> Maybe XContactId -> Maybe MemberId -> Maybe SharedMsgId -> GroupMemberRole -> GroupMemberStatus -> Maybe MemberKey -> ExceptT StoreError IO (GroupMemberId, MemberId)
|
||||
createJoiningMember
|
||||
db
|
||||
@@ -2257,11 +2222,6 @@ getContactViaMember db cxt user@User {userId} GroupMember {groupMemberId} = do
|
||||
(userId, groupMemberId)
|
||||
getContact db cxt user contactId
|
||||
|
||||
setNewContactMemberConnRequest :: DB.Connection -> User -> GroupMember -> ConnReqInvitation -> IO ()
|
||||
setNewContactMemberConnRequest db User {userId} GroupMember {groupMemberId} connRequest = do
|
||||
currentTs <- getCurrentTime
|
||||
DB.execute db "UPDATE group_members SET sent_inv_queue_info = ?, updated_at = ? WHERE user_id = ? AND group_member_id = ?" (connRequest, currentTs, userId, groupMemberId)
|
||||
|
||||
getMemberInvitation :: DB.Connection -> User -> Int64 -> IO (Maybe ConnReqInvitation)
|
||||
getMemberInvitation db User {userId} groupMemberId =
|
||||
fmap join . maybeFirstRow fromOnly $
|
||||
|
||||
@@ -4767,13 +4767,6 @@ Query:
|
||||
|
||||
Plan:
|
||||
|
||||
Query:
|
||||
INSERT INTO chat_item_moderations
|
||||
(group_id, moderator_member_id, item_member_id, shared_msg_id, created_by_msg_id, moderated_at)
|
||||
VALUES (?,?,?,?,?,?)
|
||||
|
||||
Plan:
|
||||
|
||||
Query:
|
||||
INSERT INTO chat_item_versions (chat_item_id, msg_content, item_version_ts)
|
||||
VALUES (?,?,?)
|
||||
@@ -6477,10 +6470,6 @@ Query: DELETE FROM chat_item_mentions WHERE chat_item_id = ?
|
||||
Plan:
|
||||
SEARCH chat_item_mentions USING COVERING INDEX idx_chat_item_mentions_chat_item_id (chat_item_id=?)
|
||||
|
||||
Query: DELETE FROM chat_item_moderations WHERE group_id = ? AND item_member_id = ? AND shared_msg_id = ?
|
||||
Plan:
|
||||
SEARCH chat_item_moderations USING COVERING INDEX idx_chat_item_moderations_group (group_id=? AND item_member_id=? AND shared_msg_id=?)
|
||||
|
||||
Query: DELETE FROM chat_item_reactions WHERE contact_id = ?
|
||||
Plan:
|
||||
SEARCH chat_item_reactions USING COVERING INDEX idx_chat_item_reactions_contact_id (contact_id=?)
|
||||
|
||||
@@ -2077,7 +2077,7 @@ instance TextEncoding CommandStatus where
|
||||
|
||||
data CommandFunction
|
||||
= CFCreateConnGrpMemInv
|
||||
| CFCreateConnGrpInv
|
||||
| CFCreateConnGrpInv -- deprecated
|
||||
| CFCreateConnFileInvDirect -- deprecated
|
||||
| CFCreateConnFileInvGroup -- deprecated
|
||||
| CFJoinConn
|
||||
@@ -2210,7 +2210,7 @@ peerConnChatVersion _local@(VersionRange lmin lmax) _peer@(VersionRange rmin rma
|
||||
| otherwise = rmax
|
||||
|
||||
initialChatVersion :: VersionChat
|
||||
initialChatVersion = VersionChat 1
|
||||
initialChatVersion = VersionChat 9
|
||||
|
||||
chatInitialVRange :: VersionRangeChat
|
||||
chatInitialVRange = versionToRange initialChatVersion
|
||||
|
||||
@@ -445,7 +445,6 @@ chatEventToView hu ChatConfig {logLevel, showReactions, showReceipts, testView}
|
||||
CEvtGroupChatItemsDeleted u g ciIds byUser member_ -> ttyUser u $ viewGroupChatItemsDeleted g ciIds byUser member_
|
||||
CEvtChatItemDeletedNotFound u Contact {localDisplayName = c} _ -> ttyUser u [ttyFrom $ c <> "> [deleted - original message not found]"]
|
||||
CEvtUserAcceptedGroupSent u _g _ -> ttyUser u [] -- [ttyGroup' g <> ": joining the group..."]
|
||||
CEvtSentGroupInvitation u g c _ -> ttyUser u $ viewSentGroupInvitation g c
|
||||
CEvtContactDeletedByContact u c -> ttyUser u [ttyFullContact c <> " deleted contact with you"]
|
||||
CEvtAcceptingContactRequest u c -> ttyUser u $ viewAcceptingContactRequest c
|
||||
CEvtAcceptingBusinessRequest u g -> ttyUser u $ viewAcceptingBusinessRequest g
|
||||
|
||||
+4
-21
@@ -37,7 +37,6 @@ import Simplex.Chat.Library.Commands
|
||||
import Simplex.Chat.Operators
|
||||
import Simplex.Chat.Options
|
||||
import Simplex.Chat.Options.DB
|
||||
import Simplex.Chat.Protocol (currentChatVersion, pqEncryptionCompressionVersion)
|
||||
import Simplex.Chat.Store
|
||||
import Simplex.Chat.Store.Profiles
|
||||
import Simplex.Chat.Terminal
|
||||
@@ -51,7 +50,7 @@ import Simplex.FileTransfer.Server.Store
|
||||
import Simplex.FileTransfer.Transport (alpnSupportedXFTPhandshakes, supportedFileServerVRange)
|
||||
import Simplex.Messaging.Agent (disposeAgentClient)
|
||||
import Simplex.Messaging.Agent.Env.SQLite
|
||||
import Simplex.Messaging.Agent.Protocol (currentSMPAgentVersion, duplexHandshakeSMPAgentVersion, pqdrSMPAgentVersion, supportedSMPAgentVRange)
|
||||
import Simplex.Messaging.Agent.Protocol (duplexHandshakeSMPAgentVersion, pqdrSMPAgentVersion, supportedSMPAgentVRange)
|
||||
import Simplex.Messaging.Agent.RetryInterval
|
||||
import Simplex.Messaging.Agent.Store.Entity (SDBStored (..))
|
||||
import Simplex.Messaging.Agent.Store.Interface (closeDBStore)
|
||||
@@ -232,21 +231,12 @@ testAgentCfgVPrev =
|
||||
smpCfg = (smpCfg testAgentCfg) {serverVRange = prevRange $ serverVRange $ smpCfg testAgentCfg}
|
||||
}
|
||||
|
||||
testAgentCfgVNext :: AgentConfig
|
||||
testAgentCfgVNext =
|
||||
testAgentCfg
|
||||
{ smpClientVRange = nextRange $ smpClientVRange testAgentCfg,
|
||||
smpAgentVRange = mkVersionRange duplexHandshakeSMPAgentVersion $ max pqdrSMPAgentVersion currentSMPAgentVersion,
|
||||
e2eEncryptVRange = mkVersionRange CR.kdfX3DHE2EEncryptVersion $ max CR.pqRatchetE2EEncryptVersion CR.currentE2EEncryptVersion,
|
||||
smpCfg = (smpCfg testAgentCfg) {serverVRange = nextRange $ serverVRange $ smpCfg testAgentCfg}
|
||||
}
|
||||
|
||||
testAgentCfgV1 :: AgentConfig
|
||||
testAgentCfgV1 =
|
||||
testAgentCfg
|
||||
{ smpClientVRange = v1Range,
|
||||
smpAgentVRange = versionToRange duplexHandshakeSMPAgentVersion,
|
||||
e2eEncryptVRange = versionToRange CR.kdfX3DHE2EEncryptVersion,
|
||||
smpAgentVRange = mkVersionRange duplexHandshakeSMPAgentVersion pqdrSMPAgentVersion,
|
||||
e2eEncryptVRange = mkVersionRange CR.kdfX3DHE2EEncryptVersion CR.pqRatchetE2EEncryptVersion,
|
||||
smpCfg = (smpCfg testAgentCfg) {serverVRange = versionToRange minClientSMPRelayVersion}
|
||||
}
|
||||
|
||||
@@ -257,17 +247,10 @@ testCfgVPrev =
|
||||
agentConfig = testAgentCfgVPrev
|
||||
}
|
||||
|
||||
testCfgVNext :: ChatConfig
|
||||
testCfgVNext =
|
||||
testCfg
|
||||
{ chatVRange = mkVersionRange initialChatVersion $ max pqEncryptionCompressionVersion currentChatVersion,
|
||||
agentConfig = testAgentCfgVNext
|
||||
}
|
||||
|
||||
testCfgV1 :: ChatConfig
|
||||
testCfgV1 =
|
||||
testCfg
|
||||
{ chatVRange = v1Range,
|
||||
{ chatVRange = chatInitialVRange,
|
||||
agentConfig = testAgentCfgV1
|
||||
}
|
||||
|
||||
|
||||
@@ -3323,17 +3323,17 @@ testUpdatePeerChatVRange ps =
|
||||
cfg11 = testCfg {chatVRange = vr11} :: ChatConfig
|
||||
|
||||
vr11 :: VersionRangeChat
|
||||
vr11 = mkVersionRange (VersionChat 1) (VersionChat 1)
|
||||
vr11 = mkVersionRange (VersionChat 9) (VersionChat 9)
|
||||
|
||||
contactInfoChatVRange :: TestCC -> VersionRangeChat -> IO ()
|
||||
contactInfoChatVRange cc (VersionRange minVer maxVer) = do
|
||||
contactInfoChatVRange cc vr = do
|
||||
cc <## "contact ID: 2"
|
||||
cc <## "receiving messages via: localhost"
|
||||
cc <## "sending messages via: localhost"
|
||||
cc <## "you've shared main profile with this contact"
|
||||
cc <## "connection not verified, use /code command to see security code"
|
||||
cc <## "quantum resistant end-to-end encryption"
|
||||
cc <## ("peer chat protocol version range: (" <> show minVer <> ", " <> show maxVer <> ")")
|
||||
cc <## ("peer chat protocol version range: " <> vRangeStr vr)
|
||||
|
||||
testLinkContentFilter :: HasCallStack => TestParams -> IO ()
|
||||
testLinkContentFilter =
|
||||
|
||||
@@ -97,8 +97,8 @@ chatGroupTests = do
|
||||
it "moderate own message (should process as deletion)" testGroupModerateOwn
|
||||
it "moderate multiple messages" testGroupModerateMultiple
|
||||
it "moderate message of another group member (full delete)" testGroupModerateFullDelete
|
||||
it "moderate message that arrives after the event of moderation" testGroupDelayedModeration
|
||||
it "moderate message that arrives after the event of moderation (full delete)" testGroupDelayedModerationFullDelete
|
||||
xit "moderate message that arrives after the event of moderation" testGroupDelayedModeration
|
||||
xit "moderate message that arrives after the event of moderation (full delete)" testGroupDelayedModerationFullDelete
|
||||
it "remove member with messages (full deletion is enabled)" testDeleteMemberWithMessages
|
||||
it "remove member with messages mark deleted" testDeleteMemberMarkMessagesDeleted
|
||||
it "remove member - delete messages of left/removed members" testDeleteMemberMessagesLeftRemoved
|
||||
@@ -2990,7 +2990,7 @@ testGroupLinkMemberRole =
|
||||
bob <## "#team: you joined the group"
|
||||
]
|
||||
|
||||
threadDelay 100000
|
||||
threadDelay 250000
|
||||
|
||||
alice ##> "/ms team"
|
||||
alice
|
||||
|
||||
@@ -26,7 +26,7 @@ import qualified Data.Map.Strict as M
|
||||
import Simplex.Chat.Badges (BadgeCredential, BadgeInfo (..), BadgePurchase (..), BadgeRequest (..), BadgeType (..), generateMasterKey, issueBadge, verifyPayment)
|
||||
import Simplex.Chat.Controller (ChatConfig (..), ChatController (..), ChatHooks (..), defaultChatHooks, mkStoreCxt)
|
||||
import Simplex.Chat.Options (ChatOpts (..), CoreChatOpts (..))
|
||||
import Simplex.Chat.Protocol (LinkOwnerSig, MsgChatLink (..), MsgContent (..), currentChatVersion)
|
||||
import Simplex.Chat.Protocol (LinkOwnerSig, MsgChatLink (..), MsgContent (..))
|
||||
import Simplex.Chat.Store.Shared (createContact)
|
||||
import Simplex.Chat.Types (ConnStatus (..), Profile (..), GroupRejectionReason (..), profileFromName)
|
||||
import qualified Simplex.Messaging.Crypto as C
|
||||
@@ -3040,7 +3040,7 @@ testSetUITheme =
|
||||
a <## "you've shared main profile with this contact"
|
||||
a <## "connection not verified, use /code command to see security code"
|
||||
a <## "quantum resistant end-to-end encryption"
|
||||
a <## ("peer chat protocol version range: (Version 1, " <> show currentChatVersion <> ")")
|
||||
a <## currentChatVRangeInfo
|
||||
groupInfo a = do
|
||||
a <## "group ID: 1"
|
||||
a <## "current members: 1"
|
||||
|
||||
@@ -127,9 +127,9 @@ versionTestMatrix2 runTest = do
|
||||
it "prev" $ runTestCfg2 testCfgVPrev testCfgVPrev (runTest False True)
|
||||
it "prev to curr" $ runTestCfg2 testCfg testCfgVPrev (runTest False True)
|
||||
it "curr to prev" $ runTestCfg2 testCfgVPrev testCfg (runTest False True)
|
||||
it "old (1st supported)" $ testChatCfg2 testCfgV1 aliceProfile bobProfile (runTest False False)
|
||||
it "old to curr" $ runTestCfg2 testCfg testCfgV1 (runTest False True)
|
||||
it "curr to old" $ runTestCfg2 testCfgV1 testCfg (runTest False False)
|
||||
it "old (1st supported)" $ testChatCfg2 testCfgV1 aliceProfile bobProfile (runTest True False)
|
||||
it "old to curr" $ runTestCfg2 testCfg testCfgV1 (runTest True True)
|
||||
it "curr to old" $ runTestCfg2 testCfgV1 testCfg (runTest True False)
|
||||
|
||||
versionTestMatrix3 :: (HasCallStack => TestCC -> TestCC -> TestCC -> IO ()) -> SpecWith TestParams
|
||||
versionTestMatrix3 runTest = do
|
||||
|
||||
+59
-59
@@ -135,64 +135,64 @@ shortLinkDataTests = describe "Short link data encoding/decoding" $ do
|
||||
decodeChatMessageTest :: Spec
|
||||
decodeChatMessageTest = describe "Chat message encoding/decoding" $ do
|
||||
it "x.msg.new simple text" $
|
||||
"{\"v\":\"1\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello\",\"type\":\"text\"}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello\",\"type\":\"text\"}}}"
|
||||
#==# XMsgNew (mcSimple (MCText "hello"))
|
||||
it "x.msg.new simple text - timed message TTL" $
|
||||
"{\"v\":\"1\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello\",\"type\":\"text\"},\"ttl\":3600}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello\",\"type\":\"text\"},\"ttl\":3600}}"
|
||||
#==# XMsgNew ((mcSimple (MCText "hello")) {ttl = Just 3600})
|
||||
it "x.msg.new simple text - live message" $
|
||||
"{\"v\":\"1\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello\",\"type\":\"text\"},\"live\":true}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello\",\"type\":\"text\"},\"live\":true}}"
|
||||
#==# XMsgNew ((mcSimple (MCText "hello")) {live = Just True})
|
||||
it "x.msg.new simple link" $
|
||||
"{\"v\":\"1\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"https://simplex.chat\",\"type\":\"link\",\"preview\":{\"description\":\"SimpleX Chat\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgA\",\"title\":\"SimpleX Chat\",\"uri\":\"https://simplex.chat\"}}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"https://simplex.chat\",\"type\":\"link\",\"preview\":{\"description\":\"SimpleX Chat\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgA\",\"title\":\"SimpleX Chat\",\"uri\":\"https://simplex.chat\"}}}}"
|
||||
#==# XMsgNew (mcSimple (MCLink "https://simplex.chat" $ LinkPreview {uri = "https://simplex.chat", title = "SimpleX Chat", description = "SimpleX Chat", image = ImageData "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgA", content = Nothing}))
|
||||
it "x.msg.new simple image" $
|
||||
"{\"v\":\"1\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"\",\"type\":\"image\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\"}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"\",\"type\":\"image\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\"}}}"
|
||||
#==# XMsgNew (mcSimple (MCImage "" $ ImageData "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII="))
|
||||
it "x.msg.new simple image with text" $
|
||||
"{\"v\":\"1\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"here's an image\",\"type\":\"image\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\"}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"here's an image\",\"type\":\"image\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\"}}}"
|
||||
#==# XMsgNew (mcSimple (MCImage "here's an image" $ ImageData "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII="))
|
||||
it "x.msg.new chat message" $
|
||||
"{\"v\":\"1\",\"msgId\":\"AQIDBA==\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello\",\"type\":\"text\"}}}"
|
||||
"{\"v\":\"9\",\"msgId\":\"AQIDBA==\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello\",\"type\":\"text\"}}}"
|
||||
##==## ChatMessage chatInitialVRange (Just $ SharedMsgId "\1\2\3\4") (XMsgNew (mcSimple (MCText "hello")))
|
||||
it "x.msg.new chat message with chat version range" $
|
||||
"{\"v\":\"1-19\",\"msgId\":\"AQIDBA==\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello\",\"type\":\"text\"}}}"
|
||||
"{\"v\":\"9-19\",\"msgId\":\"AQIDBA==\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello\",\"type\":\"text\"}}}"
|
||||
##==## ChatMessage supportedChatVRange (Just $ SharedMsgId "\1\2\3\4") (XMsgNew (mcSimple (MCText "hello")))
|
||||
it "x.msg.new quote" $
|
||||
"{\"v\":\"1\",\"msgId\":\"AQIDBA==\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello to you too\",\"type\":\"text\"},\"quote\":{\"content\":{\"text\":\"hello there!\",\"type\":\"text\"},\"msgRef\":{\"msgId\":\"BQYHCA==\",\"sent\":true,\"sentAt\":\"1970-01-01T00:00:01.000000001Z\"}}}}"
|
||||
"{\"v\":\"9\",\"msgId\":\"AQIDBA==\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello to you too\",\"type\":\"text\"},\"quote\":{\"content\":{\"text\":\"hello there!\",\"type\":\"text\"},\"msgRef\":{\"msgId\":\"BQYHCA==\",\"sent\":true,\"sentAt\":\"1970-01-01T00:00:01.000000001Z\"}}}}"
|
||||
##==## ChatMessage
|
||||
chatInitialVRange
|
||||
(Just $ SharedMsgId "\1\2\3\4")
|
||||
(XMsgNew (mcQuote quotedMsg (MCText "hello to you too")))
|
||||
it "x.msg.new quote - timed message TTL" $
|
||||
"{\"v\":\"1\",\"msgId\":\"AQIDBA==\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello to you too\",\"type\":\"text\"},\"quote\":{\"content\":{\"text\":\"hello there!\",\"type\":\"text\"},\"msgRef\":{\"msgId\":\"BQYHCA==\",\"sent\":true,\"sentAt\":\"1970-01-01T00:00:01.000000001Z\"}},\"ttl\":3600}}"
|
||||
"{\"v\":\"9\",\"msgId\":\"AQIDBA==\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello to you too\",\"type\":\"text\"},\"quote\":{\"content\":{\"text\":\"hello there!\",\"type\":\"text\"},\"msgRef\":{\"msgId\":\"BQYHCA==\",\"sent\":true,\"sentAt\":\"1970-01-01T00:00:01.000000001Z\"}},\"ttl\":3600}}"
|
||||
##==## ChatMessage
|
||||
chatInitialVRange
|
||||
(Just $ SharedMsgId "\1\2\3\4")
|
||||
(XMsgNew ((mcQuote quotedMsg (MCText "hello to you too")) {ttl = Just 3600}))
|
||||
it "x.msg.new quote - live message" $
|
||||
"{\"v\":\"1\",\"msgId\":\"AQIDBA==\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello to you too\",\"type\":\"text\"},\"quote\":{\"content\":{\"text\":\"hello there!\",\"type\":\"text\"},\"msgRef\":{\"msgId\":\"BQYHCA==\",\"sent\":true,\"sentAt\":\"1970-01-01T00:00:01.000000001Z\"}},\"live\":true}}"
|
||||
"{\"v\":\"9\",\"msgId\":\"AQIDBA==\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello to you too\",\"type\":\"text\"},\"quote\":{\"content\":{\"text\":\"hello there!\",\"type\":\"text\"},\"msgRef\":{\"msgId\":\"BQYHCA==\",\"sent\":true,\"sentAt\":\"1970-01-01T00:00:01.000000001Z\"}},\"live\":true}}"
|
||||
##==## ChatMessage
|
||||
chatInitialVRange
|
||||
(Just $ SharedMsgId "\1\2\3\4")
|
||||
(XMsgNew ((mcQuote quotedMsg (MCText "hello to you too")) {live = Just True}))
|
||||
it "x.msg.new forward" $
|
||||
"{\"v\":\"1\",\"msgId\":\"AQIDBA==\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello\",\"type\":\"text\"},\"forward\":true}}"
|
||||
"{\"v\":\"9\",\"msgId\":\"AQIDBA==\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello\",\"type\":\"text\"},\"forward\":true}}"
|
||||
##==## ChatMessage chatInitialVRange (Just $ SharedMsgId "\1\2\3\4") (XMsgNew $ mcForward (MCText "hello"))
|
||||
it "x.msg.new forward - timed message TTL" $
|
||||
"{\"v\":\"1\",\"msgId\":\"AQIDBA==\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello\",\"type\":\"text\"},\"forward\":true,\"ttl\":3600}}"
|
||||
"{\"v\":\"9\",\"msgId\":\"AQIDBA==\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello\",\"type\":\"text\"},\"forward\":true,\"ttl\":3600}}"
|
||||
##==## ChatMessage chatInitialVRange (Just $ SharedMsgId "\1\2\3\4") (XMsgNew $ (mcForward (MCText "hello")) {ttl = Just 3600})
|
||||
it "x.msg.new forward - live message" $
|
||||
"{\"v\":\"1\",\"msgId\":\"AQIDBA==\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello\",\"type\":\"text\"},\"forward\":true,\"live\":true}}"
|
||||
"{\"v\":\"9\",\"msgId\":\"AQIDBA==\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello\",\"type\":\"text\"},\"forward\":true,\"live\":true}}"
|
||||
##==## ChatMessage chatInitialVRange (Just $ SharedMsgId "\1\2\3\4") (XMsgNew $ (mcForward (MCText "hello")) {live = Just True})
|
||||
it "x.msg.new simple text with file" $
|
||||
"{\"v\":\"1\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello\",\"type\":\"text\"},\"file\":{\"fileSize\":12345,\"fileName\":\"photo.jpg\"}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello\",\"type\":\"text\"},\"file\":{\"fileSize\":12345,\"fileName\":\"photo.jpg\"}}}"
|
||||
#==# XMsgNew ((mcSimple (MCText "hello")) {file = Just FileInvitation {fileName = "photo.jpg", fileSize = 12345, fileDigest = Nothing, fileConnReq = Nothing, fileInline = Nothing, fileDescr = Nothing}})
|
||||
it "x.msg.new simple file with file" $
|
||||
"{\"v\":\"1\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"\",\"type\":\"file\"},\"file\":{\"fileSize\":12345,\"fileName\":\"file.txt\"}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"\",\"type\":\"file\"},\"file\":{\"fileSize\":12345,\"fileName\":\"file.txt\"}}}"
|
||||
#==# XMsgNew ((mcSimple (MCFile "")) {file = Just FileInvitation {fileName = "file.txt", fileSize = 12345, fileDigest = Nothing, fileConnReq = Nothing, fileInline = Nothing, fileDescr = Nothing}})
|
||||
it "x.msg.new quote with file" $
|
||||
"{\"v\":\"1\",\"msgId\":\"AQIDBA==\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello to you too\",\"type\":\"text\"},\"file\":{\"fileSize\":12345,\"fileName\":\"photo.jpg\"},\"quote\":{\"content\":{\"text\":\"hello there!\",\"type\":\"text\"},\"msgRef\":{\"msgId\":\"BQYHCA==\",\"sent\":true,\"sentAt\":\"1970-01-01T00:00:01.000000001Z\"}}}}"
|
||||
"{\"v\":\"9\",\"msgId\":\"AQIDBA==\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello to you too\",\"type\":\"text\"},\"file\":{\"fileSize\":12345,\"fileName\":\"photo.jpg\"},\"quote\":{\"content\":{\"text\":\"hello there!\",\"type\":\"text\"},\"msgRef\":{\"msgId\":\"BQYHCA==\",\"sent\":true,\"sentAt\":\"1970-01-01T00:00:01.000000001Z\"}}}}"
|
||||
##==## ChatMessage
|
||||
chatInitialVRange
|
||||
(Just $ SharedMsgId "\1\2\3\4")
|
||||
@@ -201,134 +201,134 @@ decodeChatMessageTest = describe "Chat message encoding/decoding" $ do
|
||||
{file = Just FileInvitation {fileName = "photo.jpg", fileSize = 12345, fileDigest = Nothing, fileConnReq = Nothing, fileInline = Nothing, fileDescr = Nothing}}
|
||||
)
|
||||
it "x.msg.new report" $
|
||||
"{\"v\":\"1\",\"msgId\":\"AQIDBA==\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"\",\"reason\":\"spam\",\"type\":\"report\"},\"quote\":{\"content\":{\"text\":\"hello there!\",\"type\":\"text\"},\"msgRef\":{\"msgId\":\"BQYHCA==\",\"sent\":true,\"sentAt\":\"1970-01-01T00:00:01.000000001Z\"}}}}"
|
||||
"{\"v\":\"9\",\"msgId\":\"AQIDBA==\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"\",\"reason\":\"spam\",\"type\":\"report\"},\"quote\":{\"content\":{\"text\":\"hello there!\",\"type\":\"text\"},\"msgRef\":{\"msgId\":\"BQYHCA==\",\"sent\":true,\"sentAt\":\"1970-01-01T00:00:01.000000001Z\"}}}}"
|
||||
##==## ChatMessage
|
||||
chatInitialVRange
|
||||
(Just $ SharedMsgId "\1\2\3\4")
|
||||
(XMsgNew (mcQuote quotedMsg (MCReport "" RRSpam)))
|
||||
it "x.msg.new forward with file" $
|
||||
"{\"v\":\"1\",\"msgId\":\"AQIDBA==\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello\",\"type\":\"text\"},\"file\":{\"fileSize\":12345,\"fileName\":\"photo.jpg\"},\"forward\":true}}"
|
||||
"{\"v\":\"9\",\"msgId\":\"AQIDBA==\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello\",\"type\":\"text\"},\"file\":{\"fileSize\":12345,\"fileName\":\"photo.jpg\"},\"forward\":true}}"
|
||||
##==## ChatMessage chatInitialVRange (Just $ SharedMsgId "\1\2\3\4") (XMsgNew $ (mcForward (MCText "hello")) {file = Just FileInvitation {fileName = "photo.jpg", fileSize = 12345, fileDigest = Nothing, fileConnReq = Nothing, fileInline = Nothing, fileDescr = Nothing}})
|
||||
it "x.msg.update" $
|
||||
"{\"v\":\"1\",\"event\":\"x.msg.update\",\"params\":{\"msgId\":\"AQIDBA==\", \"content\":{\"text\":\"hello\",\"type\":\"text\"}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.msg.update\",\"params\":{\"msgId\":\"AQIDBA==\", \"content\":{\"text\":\"hello\",\"type\":\"text\"}}}"
|
||||
#==# XMsgUpdate (SharedMsgId "\1\2\3\4") (MCText "hello") [] Nothing Nothing Nothing Nothing
|
||||
it "x.msg.del" $
|
||||
"{\"v\":\"1\",\"event\":\"x.msg.del\",\"params\":{\"msgId\":\"AQIDBA==\"}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.msg.del\",\"params\":{\"msgId\":\"AQIDBA==\"}}"
|
||||
#==# XMsgDel (SharedMsgId "\1\2\3\4") Nothing Nothing False
|
||||
it "x.msg.deleted" $
|
||||
"{\"v\":\"1\",\"event\":\"x.msg.deleted\",\"params\":{}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.msg.deleted\",\"params\":{}}"
|
||||
#==# XMsgDeleted
|
||||
it "x.file" $
|
||||
"{\"v\":\"1\",\"event\":\"x.file\",\"params\":{\"file\":{\"fileConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-4%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\",\"fileSize\":12345,\"fileName\":\"photo.jpg\"}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.file\",\"params\":{\"file\":{\"fileConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-4%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\",\"fileSize\":12345,\"fileName\":\"photo.jpg\"}}}"
|
||||
#==# XFile FileInvitation {fileName = "photo.jpg", fileSize = 12345, fileDigest = Nothing, fileConnReq = Just testConnReq, fileInline = Nothing, fileDescr = Nothing}
|
||||
it "x.file without file invitation" $
|
||||
"{\"v\":\"1\",\"event\":\"x.file\",\"params\":{\"file\":{\"fileSize\":12345,\"fileName\":\"photo.jpg\"}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.file\",\"params\":{\"file\":{\"fileSize\":12345,\"fileName\":\"photo.jpg\"}}}"
|
||||
#==# XFile FileInvitation {fileName = "photo.jpg", fileSize = 12345, fileDigest = Nothing, fileConnReq = Nothing, fileInline = Nothing, fileDescr = Nothing}
|
||||
it "x.file.acpt" $
|
||||
"{\"v\":\"1\",\"event\":\"x.file.acpt\",\"params\":{\"fileName\":\"photo.jpg\"}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.file.acpt\",\"params\":{\"fileName\":\"photo.jpg\"}}"
|
||||
#==# XFileAcpt "photo.jpg"
|
||||
it "x.file.acpt.inv" $
|
||||
"{\"v\":\"1\",\"event\":\"x.file.acpt.inv\",\"params\":{\"msgId\":\"AQIDBA==\",\"fileName\":\"photo.jpg\",\"fileConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-4%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\"}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.file.acpt.inv\",\"params\":{\"msgId\":\"AQIDBA==\",\"fileName\":\"photo.jpg\",\"fileConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-4%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\"}}"
|
||||
#==# XFileAcptInv (SharedMsgId "\1\2\3\4") (Just testConnReq) "photo.jpg"
|
||||
it "x.file.acpt.inv" $
|
||||
"{\"v\":\"1\",\"event\":\"x.file.acpt.inv\",\"params\":{\"msgId\":\"AQIDBA==\",\"fileName\":\"photo.jpg\"}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.file.acpt.inv\",\"params\":{\"msgId\":\"AQIDBA==\",\"fileName\":\"photo.jpg\"}}"
|
||||
#==# XFileAcptInv (SharedMsgId "\1\2\3\4") Nothing "photo.jpg"
|
||||
it "x.file.cancel" $
|
||||
"{\"v\":\"1\",\"event\":\"x.file.cancel\",\"params\":{\"msgId\":\"AQIDBA==\"}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.file.cancel\",\"params\":{\"msgId\":\"AQIDBA==\"}}"
|
||||
#==# XFileCancel (SharedMsgId "\1\2\3\4")
|
||||
it "x.info" $
|
||||
"{\"v\":\"1\",\"event\":\"x.info\",\"params\":{\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.info\",\"params\":{\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}"
|
||||
#==# XInfo testProfile Nothing
|
||||
it "x.info with empty full name" $
|
||||
"{\"v\":\"1\",\"event\":\"x.info\",\"params\":{\"profile\":{\"fullName\":\"\",\"displayName\":\"alice\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.info\",\"params\":{\"profile\":{\"fullName\":\"\",\"displayName\":\"alice\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}"
|
||||
#==# XInfo Profile {displayName = "alice", fullName = "", shortDescr = Nothing, description = Nothing, image = Nothing, contactLink = Nothing, peerType = Nothing, preferences = testChatPreferences, badge = Nothing, contactDomain = Nothing} Nothing
|
||||
it "x.contact with xContactId" $
|
||||
"{\"v\":\"1\",\"event\":\"x.contact\",\"params\":{\"contactReqId\":\"AQIDBA==\",\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.contact\",\"params\":{\"contactReqId\":\"AQIDBA==\",\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}"
|
||||
#==# XContact testProfile Nothing (Just $ XContactId "\1\2\3\4") Nothing Nothing
|
||||
it "x.contact without XContactId" $
|
||||
"{\"v\":\"1\",\"event\":\"x.contact\",\"params\":{\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.contact\",\"params\":{\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}"
|
||||
#==# XContact testProfile Nothing Nothing Nothing Nothing
|
||||
it "x.contact with content null" $
|
||||
"{\"v\":\"1\",\"event\":\"x.contact\",\"params\":{\"content\":null,\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.contact\",\"params\":{\"content\":null,\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}"
|
||||
==# XContact testProfile Nothing Nothing Nothing Nothing
|
||||
it "x.contact with content" $
|
||||
"{\"v\":\"1\",\"event\":\"x.contact\",\"params\":{\"msgId\":\"AQIDBA==\",\"content\":{\"text\":\"hello\",\"type\":\"text\"},\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.contact\",\"params\":{\"msgId\":\"AQIDBA==\",\"content\":{\"text\":\"hello\",\"type\":\"text\"},\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}"
|
||||
==# XContact testProfile Nothing Nothing Nothing (Just (SharedMsgId "\1\2\3\4", MCText {text = "hello"}))
|
||||
it "x.grp.inv" $
|
||||
"{\"v\":\"1\",\"event\":\"x.grp.inv\",\"params\":{\"groupInvitation\":{\"connRequest\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-4%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\",\"invitedMember\":{\"memberRole\":\"member\",\"memberId\":\"BQYHCA==\"},\"groupProfile\":{\"fullName\":\"Team\",\"displayName\":\"team\",\"groupPreferences\":{\"reactions\":{\"enable\":\"on\"},\"voice\":{\"enable\":\"on\"}}},\"fromMember\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\"}}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.grp.inv\",\"params\":{\"groupInvitation\":{\"connRequest\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-4%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\",\"invitedMember\":{\"memberRole\":\"member\",\"memberId\":\"BQYHCA==\"},\"groupProfile\":{\"fullName\":\"Team\",\"displayName\":\"team\",\"groupPreferences\":{\"reactions\":{\"enable\":\"on\"},\"voice\":{\"enable\":\"on\"}}},\"fromMember\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\"}}}}"
|
||||
#==# XGrpInv GroupInvitation {fromMember = MemberIdRole (MemberId "\1\2\3\4") GRAdmin, invitedMember = MemberIdRole (MemberId "\5\6\7\8") GRMember, connRequest = testConnReq, groupProfile = testGroupProfile, business = Nothing, groupLinkId = Nothing, groupSize = Nothing}
|
||||
it "x.grp.inv with group link id" $
|
||||
"{\"v\":\"1\",\"event\":\"x.grp.inv\",\"params\":{\"groupInvitation\":{\"connRequest\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-4%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\",\"invitedMember\":{\"memberRole\":\"member\",\"memberId\":\"BQYHCA==\"},\"groupProfile\":{\"fullName\":\"Team\",\"displayName\":\"team\",\"groupPreferences\":{\"reactions\":{\"enable\":\"on\"},\"voice\":{\"enable\":\"on\"}}},\"fromMember\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\"}, \"groupLinkId\":\"AQIDBA==\"}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.grp.inv\",\"params\":{\"groupInvitation\":{\"connRequest\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-4%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\",\"invitedMember\":{\"memberRole\":\"member\",\"memberId\":\"BQYHCA==\"},\"groupProfile\":{\"fullName\":\"Team\",\"displayName\":\"team\",\"groupPreferences\":{\"reactions\":{\"enable\":\"on\"},\"voice\":{\"enable\":\"on\"}}},\"fromMember\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\"}, \"groupLinkId\":\"AQIDBA==\"}}}"
|
||||
#==# XGrpInv GroupInvitation {fromMember = MemberIdRole (MemberId "\1\2\3\4") GRAdmin, invitedMember = MemberIdRole (MemberId "\5\6\7\8") GRMember, connRequest = testConnReq, groupProfile = testGroupProfile, business = Nothing, groupLinkId = Just $ GroupLinkId "\1\2\3\4", groupSize = Nothing}
|
||||
it "x.grp.acpt without incognito profile" $
|
||||
"{\"v\":\"1\",\"event\":\"x.grp.acpt\",\"params\":{\"memberId\":\"AQIDBA==\"}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.grp.acpt\",\"params\":{\"memberId\":\"AQIDBA==\"}}"
|
||||
#==# XGrpAcpt (MemberId "\1\2\3\4")
|
||||
it "x.grp.mem.new" $
|
||||
"{\"v\":\"1\",\"event\":\"x.grp.mem.new\",\"params\":{\"memberInfo\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\",\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.grp.mem.new\",\"params\":{\"memberInfo\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\",\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}}"
|
||||
#==# XGrpMemNew MemberInfo {memberId = MemberId "\1\2\3\4", memberRole = GRAdmin, v = Nothing, profile = testProfile, memberKey = Nothing} Nothing
|
||||
it "x.grp.mem.new with member chat version range" $
|
||||
"{\"v\":\"1\",\"event\":\"x.grp.mem.new\",\"params\":{\"memberInfo\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\",\"v\":\"1-19\",\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.grp.mem.new\",\"params\":{\"memberInfo\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\",\"v\":\"9-19\",\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}}"
|
||||
#==# XGrpMemNew MemberInfo {memberId = MemberId "\1\2\3\4", memberRole = GRAdmin, v = Just $ ChatVersionRange supportedChatVRange, profile = testProfile, memberKey = Nothing} Nothing
|
||||
it "x.grp.mem.intro" $
|
||||
"{\"v\":\"1\",\"event\":\"x.grp.mem.intro\",\"params\":{\"memberInfo\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\",\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.grp.mem.intro\",\"params\":{\"memberInfo\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\",\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}}"
|
||||
#==# XGrpMemIntro MemberInfo {memberId = MemberId "\1\2\3\4", memberRole = GRAdmin, v = Nothing, profile = testProfile, memberKey = Nothing} Nothing
|
||||
it "x.grp.mem.intro with member chat version range" $
|
||||
"{\"v\":\"1\",\"event\":\"x.grp.mem.intro\",\"params\":{\"memberInfo\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\",\"v\":\"1-19\",\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.grp.mem.intro\",\"params\":{\"memberInfo\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\",\"v\":\"9-19\",\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}}"
|
||||
#==# XGrpMemIntro MemberInfo {memberId = MemberId "\1\2\3\4", memberRole = GRAdmin, v = Just $ ChatVersionRange supportedChatVRange, profile = testProfile, memberKey = Nothing} Nothing
|
||||
it "x.grp.mem.intro with member restrictions" $
|
||||
"{\"v\":\"1\",\"event\":\"x.grp.mem.intro\",\"params\":{\"memberRestrictions\":{\"restriction\":\"blocked\"},\"memberInfo\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\",\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.grp.mem.intro\",\"params\":{\"memberRestrictions\":{\"restriction\":\"blocked\"},\"memberInfo\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\",\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}}"
|
||||
#==# XGrpMemIntro MemberInfo {memberId = MemberId "\1\2\3\4", memberRole = GRAdmin, v = Nothing, profile = testProfile, memberKey = Nothing} (Just MemberRestrictions {restriction = MRSBlocked})
|
||||
it "x.grp.mem.inv" $
|
||||
"{\"v\":\"1\",\"event\":\"x.grp.mem.inv\",\"params\":{\"memberId\":\"AQIDBA==\",\"memberIntro\":{\"directConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-4%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\",\"groupConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-4%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\"}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.grp.mem.inv\",\"params\":{\"memberId\":\"AQIDBA==\",\"memberIntro\":{\"directConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-4%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\",\"groupConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-4%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\"}}}"
|
||||
#==# XGrpMemInv (MemberId "\1\2\3\4") IntroInvitation {groupConnReq = testConnReq, directConnReq = Just testConnReq}
|
||||
it "x.grp.mem.inv w/t directConnReq" $
|
||||
"{\"v\":\"1\",\"event\":\"x.grp.mem.inv\",\"params\":{\"memberId\":\"AQIDBA==\",\"memberIntro\":{\"groupConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-4%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\"}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.grp.mem.inv\",\"params\":{\"memberId\":\"AQIDBA==\",\"memberIntro\":{\"groupConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-4%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\"}}}"
|
||||
#==# XGrpMemInv (MemberId "\1\2\3\4") IntroInvitation {groupConnReq = testConnReq, directConnReq = Nothing}
|
||||
it "x.grp.mem.fwd" $
|
||||
"{\"v\":\"1\",\"event\":\"x.grp.mem.fwd\",\"params\":{\"memberIntro\":{\"directConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-4%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\",\"groupConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-4%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\"},\"memberInfo\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\",\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.grp.mem.fwd\",\"params\":{\"memberIntro\":{\"directConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-4%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\",\"groupConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-4%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\"},\"memberInfo\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\",\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}}"
|
||||
#==# XGrpMemFwd MemberInfo {memberId = MemberId "\1\2\3\4", memberRole = GRAdmin, v = Nothing, profile = testProfile, memberKey = Nothing} IntroInvitation {groupConnReq = testConnReq, directConnReq = Just testConnReq}
|
||||
it "x.grp.mem.fwd with member chat version range and w/t directConnReq" $
|
||||
"{\"v\":\"1\",\"event\":\"x.grp.mem.fwd\",\"params\":{\"memberIntro\":{\"groupConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-4%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\"},\"memberInfo\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\",\"v\":\"1-19\",\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.grp.mem.fwd\",\"params\":{\"memberIntro\":{\"groupConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-4%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\"},\"memberInfo\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\",\"v\":\"9-19\",\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}}"
|
||||
#==# XGrpMemFwd MemberInfo {memberId = MemberId "\1\2\3\4", memberRole = GRAdmin, v = Just $ ChatVersionRange supportedChatVRange, profile = testProfile, memberKey = Nothing} IntroInvitation {groupConnReq = testConnReq, directConnReq = Nothing}
|
||||
it "x.grp.mem.info" $
|
||||
"{\"v\":\"1\",\"event\":\"x.grp.mem.info\",\"params\":{\"memberId\":\"AQIDBA==\",\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.grp.mem.info\",\"params\":{\"memberId\":\"AQIDBA==\",\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}"
|
||||
#==# XGrpMemInfo (MemberId "\1\2\3\4") testProfile
|
||||
it "x.grp.mem.con" $
|
||||
"{\"v\":\"1\",\"event\":\"x.grp.mem.con\",\"params\":{\"memberId\":\"AQIDBA==\"}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.grp.mem.con\",\"params\":{\"memberId\":\"AQIDBA==\"}}"
|
||||
#==# XGrpMemCon (MemberId "\1\2\3\4")
|
||||
it "x.grp.mem.con.all" $
|
||||
"{\"v\":\"1\",\"event\":\"x.grp.mem.con.all\",\"params\":{\"memberId\":\"AQIDBA==\"}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.grp.mem.con.all\",\"params\":{\"memberId\":\"AQIDBA==\"}}"
|
||||
#==# XGrpMemConAll (MemberId "\1\2\3\4")
|
||||
it "x.grp.mem.del" $
|
||||
"{\"v\":\"1\",\"event\":\"x.grp.mem.del\",\"params\":{\"memberId\":\"AQIDBA==\"}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.grp.mem.del\",\"params\":{\"memberId\":\"AQIDBA==\"}}"
|
||||
#==# XGrpMemDel (MemberId "\1\2\3\4") False Nothing
|
||||
it "x.grp.leave" $
|
||||
"{\"v\":\"1\",\"event\":\"x.grp.leave\",\"params\":{}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.grp.leave\",\"params\":{}}"
|
||||
==# XGrpLeave
|
||||
it "x.grp.del" $
|
||||
"{\"v\":\"1\",\"event\":\"x.grp.del\",\"params\":{}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.grp.del\",\"params\":{}}"
|
||||
==# XGrpDel
|
||||
it "x.grp.direct.inv" $
|
||||
"{\"v\":\"1\",\"event\":\"x.grp.direct.inv\",\"params\":{\"connReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-4%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\", \"content\":{\"text\":\"hello\",\"type\":\"text\"}}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.grp.direct.inv\",\"params\":{\"connReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-4%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\", \"content\":{\"text\":\"hello\",\"type\":\"text\"}}}"
|
||||
#==# XGrpDirectInv testConnReq (Just $ MCText "hello") Nothing
|
||||
it "x.grp.direct.inv without content" $
|
||||
"{\"v\":\"1\",\"event\":\"x.grp.direct.inv\",\"params\":{\"connReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-4%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\"}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.grp.direct.inv\",\"params\":{\"connReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-4%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\"}}"
|
||||
#==# XGrpDirectInv testConnReq Nothing Nothing
|
||||
-- it "x.grp.msg.forward"
|
||||
-- $ "{\"v\":\"1\",\"event\":\"x.grp.msg.forward\",\"params\":{\"msgForward\":{\"memberId\":\"AQIDBA==\",\"msg\":\"{\"v\":\"1\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello\",\"type\":\"text\"}}}\",\"msgTs\":\"1970-01-01T00:00:01.000000001Z\"}}}"
|
||||
-- $ "{\"v\":\"9\",\"event\":\"x.grp.msg.forward\",\"params\":{\"msgForward\":{\"memberId\":\"AQIDBA==\",\"msg\":\"{\"v\":\"9\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello\",\"type\":\"text\"}}}\",\"msgTs\":\"1970-01-01T00:00:01.000000001Z\"}}}"
|
||||
-- #==# XGrpMsgForward
|
||||
-- (MemberId "\1\2\3\4")
|
||||
-- (ChatMessage chatInitialVRange (Just $ SharedMsgId "\1\2\3\4") (XMsgNew (mcSimple (MCText "hello"))))
|
||||
-- (systemToUTCTime $ MkSystemTime 1 1)
|
||||
it "x.info.probe" $
|
||||
"{\"v\":\"1\",\"event\":\"x.info.probe\",\"params\":{\"probe\":\"AQIDBA==\"}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.info.probe\",\"params\":{\"probe\":\"AQIDBA==\"}}"
|
||||
#==# XInfoProbe (Probe "\1\2\3\4")
|
||||
it "x.info.probe.check" $
|
||||
"{\"v\":\"1\",\"event\":\"x.info.probe.check\",\"params\":{\"probeHash\":\"AQIDBA==\"}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.info.probe.check\",\"params\":{\"probeHash\":\"AQIDBA==\"}}"
|
||||
#==# XInfoProbeCheck (ProbeHash "\1\2\3\4")
|
||||
it "x.info.probe.ok" $
|
||||
"{\"v\":\"1\",\"event\":\"x.info.probe.ok\",\"params\":{\"probe\":\"AQIDBA==\"}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.info.probe.ok\",\"params\":{\"probe\":\"AQIDBA==\"}}"
|
||||
#==# XInfoProbeOk (Probe "\1\2\3\4")
|
||||
it "x.ok" $
|
||||
"{\"v\":\"1\",\"event\":\"x.ok\",\"params\":{}}"
|
||||
"{\"v\":\"9\",\"event\":\"x.ok\",\"params\":{}}"
|
||||
==# XOk
|
||||
Reference in new issue
Block a user