diff --git a/CHANGES.md b/CHANGES.md
index 3484fcf48f..35fea8834a 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,3 +1,50 @@
+## Changes in 1.10.2 (2023-02-10)
+
+đ Bugfixes
+
+- Fixes #7350 - Fix green dot only to appear for marked action ([#7530](https://github.com/vector-im/element-ios/issues/7530))
+
+
+## Changes in 1.10.1 (2023-02-07)
+
+âš Features
+
+- Add mark as unread option for rooms ([#7253](https://github.com/vector-im/element-ios/issues/7253))
+
+đ Improvements
+
+- Polls: add logic for fetching poll histories in rooms. ([#7293](https://github.com/vector-im/element-ios/pull/7293))
+- Poll: add a feature to load more polls in the poll history. ([#7303](https://github.com/vector-im/element-ios/pull/7303))
+- CryptoV2: Generate Crypto SDK store key ([#7310](https://github.com/vector-im/element-ios/pull/7310))
+- Poll: added poll detail in poll list hisotry with navigation to timeline ([#7314](https://github.com/vector-im/element-ios/pull/7314))
+- Backup: Display backup import progress ([#7319](https://github.com/vector-im/element-ios/pull/7319))
+- Polls: sync push rules with the one of normal messages. ([#7320](https://github.com/vector-im/element-ios/pull/7320))
+- CryptoV2: Reset Crypto SDK on logout ([#7323](https://github.com/vector-im/element-ios/pull/7323))
+- Polls: add error handling when syncing push rules with the ones of normal messages. ([#7324](https://github.com/vector-im/element-ios/pull/7324))
+- CryptoV2: Refresh notification service on crypto change ([#7332](https://github.com/vector-im/element-ios/pull/7332))
+- CryptoV2: Enable Crypto SDK for production ([#7333](https://github.com/vector-im/element-ios/pull/7333))
+- Polls: add automatic synchronization logic for poll push rules. ([#7335](https://github.com/vector-im/element-ios/pull/7335))
+- Polls: update poll history UI. ([#7341](https://github.com/vector-im/element-ios/pull/7341))
+- Upgrade MatrixSDK version ([v0.25.1](https://github.com/matrix-org/matrix-ios-sdk/releases/tag/v0.25.1)).
+- Hide the presence info if the presence status is unknown. ([#6597](https://github.com/vector-im/element-ios/issues/6597))
+- Inform the user about decryption errors during a voice broadcast. ([#7189](https://github.com/vector-im/element-ios/issues/7189))
+- App Layout: Removed the onboarding flow ([#7298](https://github.com/vector-im/element-ios/issues/7298))
+- Improve error handling during a voice broadcast playback. ([#7311](https://github.com/vector-im/element-ios/issues/7311))
+- Labs: Rich text editor: enable list items indentation ([#7316](https://github.com/vector-im/element-ios/issues/7316))
+
+
+## Changes in 1.10.0 (2023-02-02)
+
+đ Improvements
+
+- CryptoV2: Generate Crypto SDK store key ([#7310](https://github.com/vector-im/element-ios/pull/7310))
+- Backup: Display backup import progress ([#7319](https://github.com/vector-im/element-ios/pull/7319))
+- CryptoV2: Reset Crypto SDK on logout ([#7323](https://github.com/vector-im/element-ios/pull/7323))
+- CryptoV2: Refresh notification service on crypto change ([#7332](https://github.com/vector-im/element-ios/pull/7332))
+- CryptoV2: Enable Crypto SDK for production ([#7333](https://github.com/vector-im/element-ios/pull/7333))
+- Upgrade MatrixSDK version ([v0.25.0](https://github.com/matrix-org/matrix-ios-sdk/releases/tag/v0.25.0)).
+
+
## Changes in 1.9.17 (2023-01-26)
đ Improvements
diff --git a/Config/BuildSettings.swift b/Config/BuildSettings.swift
index d267cc6783..c087337e1a 100644
--- a/Config/BuildSettings.swift
+++ b/Config/BuildSettings.swift
@@ -406,7 +406,7 @@ final class BuildSettings: NSObject {
// MARK: - Polls
- static let pollsEnabled = false // Currently disabled in Tchap.
+ static let pollsEnabled = false //true : Currently disabled in Tchap.
static var pollsHistoryEnabled: Bool = false
// MARK: - Location Sharing
diff --git a/Config/CommonConfiguration.swift b/Config/CommonConfiguration.swift
index 840f381d03..a19fab4278 100644
--- a/Config/CommonConfiguration.swift
+++ b/Config/CommonConfiguration.swift
@@ -93,11 +93,14 @@ class CommonConfiguration: NSObject, Configurable {
sdkOptions.enableNewClientInformationFeature = RiotSettings.shared.enableClientInformationFeature
- #if DEBUG
if sdkOptions.isCryptoSDKAvailable {
- sdkOptions.enableCryptoSDK = RiotSettings.shared.enableCryptoSDK
+ let isEnabled = RiotSettings.shared.enableCryptoSDK
+ MXLog.debug("[CommonConfiguration] Crypto SDK is \(isEnabled ? "enabled" : "disabled")")
+ sdkOptions.enableCryptoSDK = isEnabled
+ sdkOptions.enableStartupProgress = isEnabled
+ } else {
+ MXLog.debug("[CommonConfiguration] Crypto SDK is not available)")
}
- #endif
}
private func makeASCIIUserAgent() -> String? {
diff --git a/Config/CryptoSDKConfiguration.swift b/Config/CryptoSDKConfiguration.swift
new file mode 100644
index 0000000000..3c922e5473
--- /dev/null
+++ b/Config/CryptoSDKConfiguration.swift
@@ -0,0 +1,42 @@
+//
+// Copyright 2023 New Vector Ltd
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+import Foundation
+
+/// Configuration for enabling / disabling Matrix Crypto SDK
+@objcMembers class CryptoSDKConfiguration: NSObject {
+ static let shared = CryptoSDKConfiguration()
+
+ func enable() {
+ guard MXSDKOptions.sharedInstance().isCryptoSDKAvailable else {
+ return
+ }
+
+ RiotSettings.shared.enableCryptoSDK = true
+ MXSDKOptions.sharedInstance().enableCryptoSDK = true
+ MXSDKOptions.sharedInstance().enableStartupProgress = true
+
+ MXLog.debug("[CryptoSDKConfiguration] enabling Crypto SDK")
+ }
+
+ func disable() {
+ RiotSettings.shared.enableCryptoSDK = false
+ MXSDKOptions.sharedInstance().enableCryptoSDK = false
+ MXSDKOptions.sharedInstance().enableStartupProgress = false
+
+ MXLog.debug("[CryptoSDKConfiguration] disabling Crypto SDK")
+ }
+}
diff --git a/Podfile b/Podfile
index 6277e49019..b444deb843 100644
--- a/Podfile
+++ b/Podfile
@@ -16,7 +16,7 @@ use_frameworks!
# - `{ :specHash => {sdk spec hash}` to depend on specific pod options (:git => âŠ, :podspec => âŠ) for MatrixSDK repo. Used by Fastfile during CI
#
# Warning: our internal tooling depends on the name of this variable name, so be sure not to change it
-$matrixSDKVersion = '= 0.24.8'
+$matrixSDKVersion = '= 0.25.1'
# $matrixSDKVersion = :local
# $matrixSDKVersion = { :branch => 'develop'}
# $matrixSDKVersion = { :specHash => { git: 'https://git.io/fork123', branch: 'fix' } }
@@ -53,8 +53,6 @@ end
def import_MatrixKit_pods
pod 'libPhoneNumber-iOS', '~> 0.9.13'
- pod 'DTCoreText', '1.6.26'
- #pod 'DTCoreText/Extension', '~> 1.6.25'
pod 'Down', '~> 0.11.0'
end
@@ -80,7 +78,7 @@ end
abstract_target 'TchapPods' do
- pod 'GBDeviceInfo', '~> 6.6.0'
+ pod 'GBDeviceInfo', '~> 7.1.0'
pod 'Reusable', '~> 4.1'
pod 'KeychainAccess', '~> 4.2.2'
pod 'WeakDictionary', '~> 2.0'
@@ -98,7 +96,7 @@ abstract_target 'TchapPods' do
# Tools
pod 'SwiftGen', '~> 6.3'
- pod 'SwiftLint', '~> 0.44.0'
+ pod 'SwiftLint', '~> 0.49.1'
target "Tchap" do
import_MatrixSDK
diff --git a/Podfile.lock b/Podfile.lock
index 9dfa9b45cd..a15dc495dc 100644
--- a/Podfile.lock
+++ b/Podfile.lock
@@ -21,28 +21,11 @@ PODS:
- Down (0.11.0)
- DSBottomSheet (0.3.0)
- DSWaveformImage (6.1.1)
- - DTCoreText (1.6.26):
- - DTCoreText/Core (= 1.6.26)
- - DTFoundation/Core (~> 1.7.5)
- - DTFoundation/DTAnimatedGIF (~> 1.7.5)
- - DTFoundation/DTHTMLParser (~> 1.7.5)
- - DTFoundation/UIKit (~> 1.7.5)
- - DTCoreText/Core (1.6.26):
- - DTFoundation/Core (~> 1.7.5)
- - DTFoundation/DTAnimatedGIF (~> 1.7.5)
- - DTFoundation/DTHTMLParser (~> 1.7.5)
- - DTFoundation/UIKit (~> 1.7.5)
- - DTFoundation/Core (1.7.18)
- - DTFoundation/DTAnimatedGIF (1.7.18)
- - DTFoundation/DTHTMLParser (1.7.18):
- - DTFoundation/Core
- - DTFoundation/UIKit (1.7.18):
- - DTFoundation/Core
- FLEX (4.5.0)
- FlowCommoniOS (1.12.2)
- - GBDeviceInfo (6.6.0):
- - GBDeviceInfo/Core (= 6.6.0)
- - GBDeviceInfo/Core (6.6.0)
+ - GBDeviceInfo (7.1.0):
+ - GBDeviceInfo/Core (= 7.1.0)
+ - GBDeviceInfo/Core (7.1.0)
- GZIP (1.3.0)
- Introspect (0.1.4)
- JitsiMeetSDK (5.0.2)
@@ -55,22 +38,20 @@ PODS:
- LoggerAPI (1.9.200):
- Logging (~> 1.1)
- Logging (1.4.0)
- - MatrixSDK (0.24.8):
- - MatrixSDK/Core (= 0.24.8)
- - MatrixSDK/Core (0.24.8):
+ - MatrixSDK (0.25.1):
+ - MatrixSDK/Core (= 0.25.1)
+ - MatrixSDK/Core (0.25.1):
- AFNetworking (~> 4.0.0)
- GZIP (~> 1.3.0)
- libbase58 (~> 0.1.4)
- - MatrixSDK/CryptoSDK
+ - MatrixSDKCrypto (= 0.2.0)
- OLMKit (~> 3.2.5)
- Realm (= 10.27.0)
- SwiftyBeaver (= 1.9.5)
- - MatrixSDK/CryptoSDK (0.24.8):
- - MatrixSDKCrypto (= 0.1.8)
- - MatrixSDK/JingleCallStack (0.24.8):
+ - MatrixSDK/JingleCallStack (0.25.1):
- JitsiMeetSDK (= 5.0.2)
- MatrixSDK/Core
- - MatrixSDKCrypto (0.1.8)
+ - MatrixSDKCrypto (0.2.0)
- OLMKit (3.2.12):
- OLMKit/olmc (= 3.2.12)
- OLMKit/olmcpp (= 3.2.12)
@@ -99,7 +80,7 @@ PODS:
- BlueRSA (~> 1.0)
- KituraContracts (~> 1.2)
- LoggerAPI (~> 1.7)
- - SwiftLint (0.44.0)
+ - SwiftLint (0.49.1)
- SwiftyBeaver (1.9.5)
- UICollectionViewLeftAlignedLayout (1.0.2)
- UICollectionViewRightAlignedLayout (0.0.3)
@@ -114,16 +95,15 @@ DEPENDENCIES:
- Down (~> 0.11.0)
- DSBottomSheet (~> 0.3)
- DSWaveformImage (~> 6.1.1)
- - DTCoreText (= 1.6.26)
- FLEX (~> 4.5.0)
- FlowCommoniOS (~> 1.12.0)
- - GBDeviceInfo (~> 6.6.0)
+ - GBDeviceInfo (~> 7.1.0)
- Introspect (~> 0.1)
- KeychainAccess (~> 4.2.2)
- KTCenterFlowLayout (~> 1.3.1)
- libPhoneNumber-iOS (~> 0.9.13)
- - MatrixSDK (= 0.24.8)
- - MatrixSDK/JingleCallStack (= 0.24.8)
+ - MatrixSDK (= 0.25.1)
+ - MatrixSDK/JingleCallStack (= 0.25.1)
- OLMKit
- PostHog (~> 1.4.4)
- ReadMoreTextView (~> 3.0.1)
@@ -134,7 +114,7 @@ DEPENDENCIES:
- SwiftBase32 (~> 0.9.0)
- SwiftGen (~> 6.3)
- SwiftJWT (~> 3.6.200)
- - SwiftLint (~> 0.44.0)
+ - SwiftLint (~> 0.49.1)
- UICollectionViewLeftAlignedLayout (~> 1.0.2)
- UICollectionViewRightAlignedLayout (~> 0.0.3)
- WeakDictionary (~> 2.0)
@@ -150,8 +130,6 @@ SPEC REPOS:
- Down
- DSBottomSheet
- DSWaveformImage
- - DTCoreText
- - DTFoundation
- FLEX
- FlowCommoniOS
- GBDeviceInfo
@@ -205,11 +183,9 @@ SPEC CHECKSUMS:
Down: b6ba1bc985c9d2f4e15e3b293d2207766fa12612
DSBottomSheet: ca0ac37eb5af2dd54663f86b84382ed90a59be2a
DSWaveformImage: 3c718a0cf99291887ee70d1d0c18d80101d3d9ce
- DTCoreText: ec749e013f2e1f76de5e7c7634642e600a7467ce
- DTFoundation: a53f8cda2489208cbc71c648be177f902ee17536
FLEX: e51461dd6f0bfb00643c262acdfea5d5d12c596b
FlowCommoniOS: ca92071ab526dc89905495a37844fd7e78d1a7f2
- GBDeviceInfo: ed0db16230d2fa280e1cbb39a5a7f60f6946aaec
+ GBDeviceInfo: 5d62fa85bdcce3ed288d83c28789adf1173e4376
GZIP: 416858efbe66b41b206895ac6dfd5493200d95b3
Introspect: b62c4dd2063072327c21d618ef2bedc3c87bc366
JitsiMeetSDK: edcac8e2b92ee0c7f3e75bd0aefefbe9faccfc93
@@ -220,8 +196,8 @@ SPEC CHECKSUMS:
libPhoneNumber-iOS: 0a32a9525cf8744fe02c5206eb30d571e38f7d75
LoggerAPI: ad9c4a6f1e32f518fdb43a1347ac14d765ab5e3d
Logging: beeb016c9c80cf77042d62e83495816847ef108b
- MatrixSDK: cf1c1b2a9742f7f4fad21e94bd94cd8f13c47369
- MatrixSDKCrypto: 862d9b4dbb6861da030943f5a18c39258ed7345b
+ MatrixSDK: 823c5c2ef8b8a769c30fa62e1be8ec801e6312e7
+ MatrixSDKCrypto: e1ef22aae76b5a6f030ace21a47be83864f4ff44
OLMKit: da115f16582e47626616874e20f7bb92222c7a51
PostHog: 4b6321b521569092d4ef3a02238d9435dbaeb99f
ReadMoreTextView: 19147adf93abce6d7271e14031a00303fe28720d
@@ -233,7 +209,7 @@ SPEC CHECKSUMS:
SwiftBase32: 9399c25a80666dc66b51e10076bf591e3bbb8f17
SwiftGen: 1366a7f71aeef49954ca5a63ba4bef6b0f24138c
SwiftJWT: 88c412708f58c169d431d344c87bc79a87c830ae
- SwiftLint: e96c0a8c770c7ebbc4d36c55baf9096bb65c4584
+ SwiftLint: 32ee33ded0636d0905ef6911b2b67bbaeeedafa5
SwiftyBeaver: 84069991dd5dca07d7069100985badaca7f0ce82
UICollectionViewLeftAlignedLayout: 830bf6fa5bab9f9b464f62e3384f9d2e00b3c0f6
UICollectionViewRightAlignedLayout: 823eef8c567eba4a44c21bc2ffcb0d0d5f361e2d
@@ -241,6 +217,6 @@ SPEC CHECKSUMS:
zxcvbn-ios: fef98b7c80f1512ff0eec47ac1fa399fc00f7e3c
ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb
-PODFILE CHECKSUM: 3c76918930e030ea0488d550923cceb09992573a
+PODFILE CHECKSUM: 121cfa9efcd7fe9e78d7201f9153d8bad9f33f0c
COCOAPODS: 1.11.3
diff --git a/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved
index 34484b0a74..1e81323700 100644
--- a/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved
+++ b/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved
@@ -9,6 +9,24 @@
"version" : "4.7.0"
}
},
+ {
+ "identity" : "dtcoretext",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/Cocoanetics/DTCoreText",
+ "state" : {
+ "revision" : "9d2d4d2296e5d2d852a7d3c592b817d913a5d020",
+ "version" : "1.6.27"
+ }
+ },
+ {
+ "identity" : "dtfoundation",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/Cocoanetics/DTFoundation.git",
+ "state" : {
+ "revision" : "76062513434421cb6c8a1ae1d4f8368a7ebc2da3",
+ "version" : "1.7.18"
+ }
+ },
{
"identity" : "maplibre-gl-native-distribution",
"kind" : "remoteSourceControl",
@@ -23,8 +41,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/matrix-org/matrix-wysiwyg-composer-swift",
"state" : {
- "revision" : "6927cb878376136c4a03d919b689af8dfbdad080",
- "version" : "0.19.0"
+ "revision" : "3f72aeab7d7e04b52ff3f735ab79a75993f97ef2",
+ "version" : "0.22.0"
}
},
{
diff --git a/Riot/Assets/Images.xcassets/AllChatsOnboarding/Contents.json b/Riot/Assets/Images.xcassets/AllChatsOnboarding/Contents.json
deleted file mode 100644
index 73c00596a7..0000000000
--- a/Riot/Assets/Images.xcassets/AllChatsOnboarding/Contents.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "info" : {
- "author" : "xcode",
- "version" : 1
- }
-}
diff --git a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding1.imageset/Contents.json b/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding1.imageset/Contents.json
deleted file mode 100644
index d6a6b5903f..0000000000
--- a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding1.imageset/Contents.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "images" : [
- {
- "filename" : "all_chats_onboarding1.png",
- "idiom" : "universal",
- "scale" : "1x"
- },
- {
- "filename" : "all_chats_onboarding1@2x.png",
- "idiom" : "universal",
- "scale" : "2x"
- },
- {
- "filename" : "all_chats_onboarding1@3x.png",
- "idiom" : "universal",
- "scale" : "3x"
- }
- ],
- "info" : {
- "author" : "xcode",
- "version" : 1
- }
-}
diff --git a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding1.imageset/all_chats_onboarding1.png b/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding1.imageset/all_chats_onboarding1.png
deleted file mode 100644
index 95fb854c70..0000000000
Binary files a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding1.imageset/all_chats_onboarding1.png and /dev/null differ
diff --git a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding1.imageset/all_chats_onboarding1@2x.png b/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding1.imageset/all_chats_onboarding1@2x.png
deleted file mode 100644
index 40c13c07a2..0000000000
Binary files a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding1.imageset/all_chats_onboarding1@2x.png and /dev/null differ
diff --git a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding1.imageset/all_chats_onboarding1@3x.png b/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding1.imageset/all_chats_onboarding1@3x.png
deleted file mode 100644
index 8cb11ba5de..0000000000
Binary files a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding1.imageset/all_chats_onboarding1@3x.png and /dev/null differ
diff --git a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/Contents.json b/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/Contents.json
deleted file mode 100644
index 99aa89f84e..0000000000
--- a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/Contents.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "images" : [
- {
- "filename" : "all_chats_onboarding2.png",
- "idiom" : "universal",
- "scale" : "1x"
- },
- {
- "filename" : "all_chats_onboarding2@2x.png",
- "idiom" : "universal",
- "scale" : "2x"
- },
- {
- "filename" : "all_chats_onboarding2@3x.png",
- "idiom" : "universal",
- "scale" : "3x"
- }
- ],
- "info" : {
- "author" : "xcode",
- "version" : 1
- },
- "properties" : {
- "preserves-vector-representation" : true
- }
-}
diff --git a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/all_chats_onboarding2.png b/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/all_chats_onboarding2.png
deleted file mode 100644
index 119903ee62..0000000000
Binary files a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/all_chats_onboarding2.png and /dev/null differ
diff --git a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/all_chats_onboarding2@2x.png b/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/all_chats_onboarding2@2x.png
deleted file mode 100644
index 5e33559acc..0000000000
Binary files a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/all_chats_onboarding2@2x.png and /dev/null differ
diff --git a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/all_chats_onboarding2@3x.png b/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/all_chats_onboarding2@3x.png
deleted file mode 100644
index b36afc8797..0000000000
Binary files a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/all_chats_onboarding2@3x.png and /dev/null differ
diff --git a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding3.imageset/Contents.json b/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding3.imageset/Contents.json
deleted file mode 100644
index fd0b40307f..0000000000
--- a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding3.imageset/Contents.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "images" : [
- {
- "filename" : "all_chats_onboarding3.png",
- "idiom" : "universal",
- "scale" : "1x"
- },
- {
- "filename" : "all_chats_onboarding3@2x.png",
- "idiom" : "universal",
- "scale" : "2x"
- },
- {
- "filename" : "all_chats_onboarding3@3x.png",
- "idiom" : "universal",
- "scale" : "3x"
- }
- ],
- "info" : {
- "author" : "xcode",
- "version" : 1
- }
-}
diff --git a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding3.imageset/all_chats_onboarding3.png b/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding3.imageset/all_chats_onboarding3.png
deleted file mode 100644
index 274db9f569..0000000000
Binary files a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding3.imageset/all_chats_onboarding3.png and /dev/null differ
diff --git a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding3.imageset/all_chats_onboarding3@2x.png b/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding3.imageset/all_chats_onboarding3@2x.png
deleted file mode 100644
index 6c2ae7bbfc..0000000000
Binary files a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding3.imageset/all_chats_onboarding3@2x.png and /dev/null differ
diff --git a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding3.imageset/all_chats_onboarding3@3x.png b/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding3.imageset/all_chats_onboarding3@3x.png
deleted file mode 100644
index 8bb136ca16..0000000000
Binary files a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding3.imageset/all_chats_onboarding3@3x.png and /dev/null differ
diff --git a/Riot/Assets/de.lproj/Vector.strings b/Riot/Assets/de.lproj/Vector.strings
index bb52fc5ea0..dc6a2b333c 100644
--- a/Riot/Assets/de.lproj/Vector.strings
+++ b/Riot/Assets/de.lproj/Vector.strings
@@ -2457,9 +2457,7 @@
"all_chats_all_filter" = "Alle";
"all_chats_edit_layout_show_filters" = "Filter anzeigen";
"all_chats_edit_menu_leave_space" = "%@ verlassen";
-"all_chats_onboarding_page_title3" = "RĂŒckmeldung geben";
"room_invites_empty_view_information" = "Hier erscheinen deine Einladungen.";
-"all_chats_onboarding_try_it" = "Probiere es aus";
"threads_discourage_information_1" = "Dein Heimserver unterstĂŒtzt aktuell keine Threads, weshalb diese Funktion unzuverlĂ€ssig sein könnte. Manche Thread-Nachrichten könnten nicht zuverlĂ€ssig verfĂŒgbar sein. ";
"all_chats_nothing_found_placeholder_title" = "Nichts gefunden.";
"spaces_create_subspace_title" = "Sub-Space erstellen";
@@ -2475,16 +2473,10 @@
"room_access_settings_screen_private_message" = "Nur sichtbar und betretbar fĂŒr eingeladene Personen.";
"location_sharing_allow_background_location_message" = "Wenn du deinen Echtzeit-Standort freigeben möchtest, benötigt Element den Standortzugriff auch im Hintergrund. Um den Zugriff zu gewĂ€hren, tippe auf Einstellungen > Standort und wĂ€hle âImmerâ";
"space_selector_empty_view_information" = "Spaces sind eine neue Möglichkeit, RÀume und Personen zu gruppieren. Erstelle einen Space, um zu beginnen.";
-"all_chats_onboarding_title" = "Was ist neu";
-"all_chats_onboarding_page_message3" = "DrĂŒcke auf dein Profil um uns Wissen zu lassen, was du denkst.";
-"all_chats_onboarding_page_message2" = "Greife auf deine Spaces (unten links) schneller und einfacher denn je zu.";
-"all_chats_onboarding_page_title2" = "Auf Spaces zugreifen";
-"all_chats_onboarding_page_message1" = "Um dein Element zu vereinfachen, sind Tabs nun optional. Verwalte sie mit dem MenĂŒ oben rechts.";
"all_chats_empty_view_information" = "Die Komplettlösung fĂŒr sichere Kommunikation unter Freunden, in Gruppen oder in Organisationen. Erstelle eine Unterhaltung oder trete einem bestehenden Raum bei, um loszulegen.";
"all_chats_empty_space_information" = "Spaces sind eine neue Möglichkeit, RĂ€ume und Personen zu gruppieren. FĂŒge einen bestehenden Raum hinzu oder erstelle einen neuen mit der SchaltflĂ€che unten rechts.";
"all_chats_edit_layout_sorting_options_title" = "Sortiere deine Nachrichten nach";
"space_detail_nav_title" = "Space-Details";
-"all_chats_onboarding_page_title1" = "Willkommen in einer neuen Ăbersicht!";
"all_chats_edit_menu_space_settings" = "Space-Einstellungen";
"all_chats_user_menu_settings" = "Nutzereinstellungen";
"room_recents_recently_viewed_section" = "KĂŒrzlich angesehen";
@@ -2722,12 +2714,24 @@
"wysiwyg_composer_format_action_quote" = "Zitat umschalten";
"wysiwyg_composer_format_action_ordered_list" = "Nummerierte Liste umschalten";
"wysiwyg_composer_format_action_unordered_list" = "Unsortierte Liste umschalten";
-"voice_broadcast_recorder_connection_error" = "Verbindungsfehler â Aufzeichnung pausiert";
+"voice_broadcast_recorder_connection_error" = "Verbindungsfehler â Aufnahme pausiert";
"poll_timeline_reply_ended_poll" = "Beendete Umfrage";
// MARK: - Launch loading
"launch_loading_migrating_data" = "Migriere Daten\n%@ %%";
-"settings_labs_disable_crypto_sdk" = "Krypto-SDK ist aktiviert. Zum Deaktivieren, bitte die App neu installieren";
-"settings_labs_confirm_crypto_sdk" = "Dies kann nicht rĂŒckgĂ€ngig gemacht werden";
-"settings_labs_enable_crypto_sdk" = "Rust-basiertes Krypto-SDK aktivieren";
+"settings_labs_disable_crypto_sdk" = "Rust-Ende-zu-Ende-VerschlĂŒsselung (zum Deaktivieren abmelden)";
+"settings_labs_confirm_crypto_sdk" = "Bitte beachte, dass diese Funktion noch experimentell ist, womöglich nicht wie erwartet funktioniert und unerwĂŒnschte Nebeneffekte haben kann. Melde dich zum deaktivieren einfach ab und erneut an. Nutze diese Funktion nach eigenem Ermessen und mit Vorsicht.";
+"settings_labs_enable_crypto_sdk" = "Rust-Ende-zu-Ende-VerschlĂŒsselung";
+"poll_history_no_past_poll_period_text" = "FĂŒr die vergangenen %@ Tage sind keine beendeten Umfragen verfĂŒgbar. Lade weitere Umfragen, um die der vorherigen Monate zu sehen";
+"poll_history_no_active_poll_period_text" = "FĂŒr die vergangenen %@ Tage sind keine aktiven Umfragen verfĂŒgbar. Lade weitere Umfragen, um die der vorherigen Monate zu sehen";
+"poll_history_load_more" = "Weitere Umfragen laden";
+"poll_history_loading_text" = "Zeige Umfragen an";
+"poll_history_fetching_error" = "Fehler beim Laden der Umfragen.";
+"key_backup_recover_from_private_key_progress" = "%@%Â % abgeschlossen";
+"voice_broadcast_playback_unable_to_decrypt" = "EntschlĂŒsseln der SprachĂŒbertragung nicht möglich.";
+"home_context_menu_mark_as_unread" = "Als ungelesen markieren";
+"wysiwyg_composer_format_action_un_indent" = "EinrĂŒckung verringern";
+"wysiwyg_composer_format_action_indent" = "EinrĂŒckung erhöhen";
+"settings_push_rules_error" = "Ein Fehler ist wÀhrend der Aktualisierung deiner Benachrichtigungseinstellungen aufgetreten. Bitte versuche die Option erneut umzuschalten.";
+"poll_history_detail_view_in_timeline" = "Umfrage in Verlauf anzeigen";
diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings
index 48610ec877..5a1201b378 100644
--- a/Riot/Assets/en.lproj/Vector.strings
+++ b/Riot/Assets/en.lproj/Vector.strings
@@ -761,6 +761,7 @@ Tap the + to start adding people.";
"settings_your_keywords" = "Your Keywords";
"settings_new_keyword" = "Add new Keyword";
"settings_mentions_and_keywords_encryption_notice" = "You wonât get notifications for mentions & keywords in encrypted rooms on mobile.";
+"settings_push_rules_error" = "An error occurred when updating your notification preferences. Please try to toggle your option again.";
"settings_enable_callkit" = "Integrated calling";
"settings_callkit_info" = "Receive incoming calls on your lock screen. See your %@ calls in the system's call history. If iCloud is enabled, this call history will be shared with Apple.";
@@ -806,9 +807,9 @@ Tap the + to start adding people.";
"settings_labs_enable_new_app_layout" = "New Application Layout";
"settings_labs_enable_wysiwyg_composer" = "Try out the rich text editor";
"settings_labs_enable_voice_broadcast" = "Voice broadcast";
-"settings_labs_enable_crypto_sdk" = "Enable new rust-based Crypto SDK";
-"settings_labs_confirm_crypto_sdk" = "This action cannot be undone";
-"settings_labs_disable_crypto_sdk" = "Crypto SDK is enabled. To disable please reinstall the app";
+"settings_labs_enable_crypto_sdk" = "Rust end-to-end encryption";
+"settings_labs_confirm_crypto_sdk" = "Please be advised that as this feature is still in its experimental stage, it may not function as expected and could potentially have unintended consequences. To revert the feature, simply log out and log back in. Use at your own discretion and with caution.";
+"settings_labs_disable_crypto_sdk" = "Rust end-to-end encryption (log out to disable)";
"settings_version" = "Version %@";
"settings_olm_version" = "Olm Version %@";
@@ -1471,6 +1472,7 @@ Tap the + to start adding people.";
// Recover from private key
"key_backup_recover_from_private_key_info" = "Restoring backupâŠ";
+"key_backup_recover_from_private_key_progress" = "%@%% Complete";
// Recover from passphrase
@@ -2001,6 +2003,7 @@ Tap the + to start adding people.";
"home_context_menu_normal_priority" = "Normal priority";
"home_context_menu_leave" = "Leave";
"home_context_menu_mark_as_read" = "Mark as read";
+"home_context_menu_mark_as_unread" = "Mark as unread";
"home_syncing" = "Syncing";
// MARK: - Favourites
@@ -2227,6 +2230,7 @@ Tap the + to start adding people.";
"voice_broadcast_connection_error_title" = "Connection error";
"voice_broadcast_connection_error_message" = "Unfortunately weâre unable to start a recording right now. Please try again later.";
"voice_broadcast_recorder_connection_error" = "Connection error - Recording paused";
+"voice_broadcast_playback_unable_to_decrypt" = "Unable to decrypt this voice broadcast.";
// MARK: - Version check
@@ -2279,15 +2283,6 @@ Tap the + to start adding people.";
"all_chats_edit_menu_leave_space" = "Leave %@";
"all_chats_edit_menu_space_settings" = "Space settings";
-"all_chats_onboarding_page_title1" = "Welcome to a new view!";
-"all_chats_onboarding_page_message1" = "To simplify your Element, tabs are now optional. Manage them using the top-right menu.";
-"all_chats_onboarding_page_title2" = "Access Spaces";
-"all_chats_onboarding_page_message2" = "Access your Spaces (bottom-left) faster and easier than ever before.";
-"all_chats_onboarding_page_title3" = "Give Feedback";
-"all_chats_onboarding_page_message3" = "Tap your profile to let us know what you think.";
-"all_chats_onboarding_title" = "What's new";
-"all_chats_onboarding_try_it" = "Try it out";
-
// MARK: - Room invites
"room_invites_empty_view_title" = "Nothing new.";
@@ -2306,10 +2301,16 @@ Tap the + to start adding people.";
// MARK: - Polls history
"poll_history_title" = "Poll history";
+"poll_history_loading_text" = "Displaying polls";
"poll_history_active_segment_title" = "Active polls";
"poll_history_past_segment_title" = "Past polls";
"poll_history_no_active_poll_text" = "There are no active polls in this room";
"poll_history_no_past_poll_text" = "There are no past polls in this room";
+"poll_history_no_active_poll_period_text" = "There are no active polls for the past %@ days. Load more polls to view polls for previous months";
+"poll_history_no_past_poll_period_text" = "There are no past polls for the past %@ days. Load more polls to view polls for previous months";
+"poll_history_detail_view_in_timeline" = "View poll in timeline";
+"poll_history_load_more" = "Load more polls";
+"poll_history_fetching_error" = "Error fetching polls.";
// MARK: - Polls
@@ -2585,8 +2586,8 @@ To enable access, tap Settings> Location and select Always";
"wysiwyg_composer_format_action_ordered_list" = "Toggle numbered list";
"wysiwyg_composer_format_action_code_block" = "Toggle code block";
"wysiwyg_composer_format_action_quote" = "Toggle quote";
-
-
+"wysiwyg_composer_format_action_indent" = "Increase indentation";
+"wysiwyg_composer_format_action_un_indent" = "Decrease indentation";
// Links
"wysiwyg_composer_link_action_text" = "Text";
diff --git a/Riot/Assets/et.lproj/Vector.strings b/Riot/Assets/et.lproj/Vector.strings
index 71ea69ebf2..04a4197ccd 100644
--- a/Riot/Assets/et.lproj/Vector.strings
+++ b/Riot/Assets/et.lproj/Vector.strings
@@ -1473,7 +1473,7 @@
// Mark: - Polls
-"poll_edit_form_create_poll" = "Koosta ĂŒks kĂŒsitlus";
+"poll_edit_form_create_poll" = "Loo selline kĂŒsitlus";
"settings_discovery_accept_terms" = "NÔustu isikutuvastusserveri tingimustega";
"poll_timeline_not_closed_action" = "Sobib";
"poll_timeline_not_closed_subtitle" = "Palun proovi uuesti";
@@ -1548,9 +1548,9 @@
// Onboarding
"onboarding_splash_register_button_title" = "Loo kasutajakonto";
"poll_edit_form_poll_type_closed_description" = "Tulemusi kuvame vaid siis, kui kĂŒsitlus on lĂ”ppenud";
-"poll_edit_form_poll_type_closed" = "KĂŒsitlus on lĂ”ppenud";
+"poll_edit_form_poll_type_closed" = "Suletud valikutega kĂŒsitlus";
"poll_edit_form_poll_type_open_description" = "Osalejad nÀevad tulemusi peale oma valiku salvestamist";
-"poll_edit_form_poll_type_open" = "Ava kĂŒsitlus";
+"poll_edit_form_poll_type_open" = "Avatud valikutega kĂŒsitlus";
"poll_edit_form_update_failure_subtitle" = "Palun proovi uuesti";
"poll_edit_form_update_failure_title" = "KĂŒsitluse muutmine ei Ă”nnestunud";
"poll_edit_form_poll_type" = "KĂŒsitluse tĂŒĂŒp";
@@ -2417,14 +2417,6 @@
// Mark: - Room invites
"room_invites_empty_view_title" = "Uut teavet ei leidu.";
-"all_chats_onboarding_try_it" = "Proovi nĂŒĂŒd";
-"all_chats_onboarding_title" = "Mida on meil uut";
-"all_chats_onboarding_page_message3" = "Kui soovid meile teada anda oma arvamustest, siis klÔpsi oma profiili ikooni.";
-"all_chats_onboarding_page_title3" = "Jaga tagasisidet";
-"all_chats_onboarding_page_message2" = "Kogukonnad leiad alt vasakult kiiremini ja lihtsamini, kui varem.";
-"all_chats_onboarding_page_title2" = "LigipÀÀs kogukondadele";
-"all_chats_onboarding_page_message1" = "Et Element'i kasutamine oleks lihtsam, siis kaardid on nĂŒĂŒd valikulised. Neid saad hallata ĂŒlal paremal avanevast menĂŒĂŒst.";
-"all_chats_onboarding_page_title1" = "Meie liidesel on nĂŒĂŒd uus vaade!";
"all_chats_nothing_found_placeholder_message" = "Proovi muuta oma otsingut.";
"all_chats_nothing_found_placeholder_title" = "Mitte midagi ei leidu.";
"all_chats_empty_unreads_placeholder_message" = "Kui sul on lugemata sÔnumeid, siis nad on siit leitavad.";
@@ -2666,6 +2658,18 @@
// MARK: - Launch loading
"launch_loading_migrating_data" = "TĂ”stame andmeid ĂŒmber\n%@ %%";
-"settings_labs_disable_crypto_sdk" = "Uus Crypto SDK on kasutusel. Tema vĂ€ljalĂŒlitamiseks palun paigalda rakendus uuesti";
-"settings_labs_confirm_crypto_sdk" = "Seda toimingut ei saa tagasi pöörata";
-"settings_labs_enable_crypto_sdk" = "VÔta kasutusele uus Rust-keelel pÔhinev Crypto SDK";
+"settings_labs_disable_crypto_sdk" = "Rust'i-pĂ”hine lĂ€biv krĂŒptimine (vĂ€ljalĂŒlitamiseks pead vĂ€lja logima)";
+"settings_labs_confirm_crypto_sdk" = "Palun arvesta, et see funktsionaalsus on alles katseline ja ei pruugi toimida eesmĂ€rgipĂ€raselt. Kui ta juba on kasutusel, siis vĂ€ljalĂŒlitamiseks pead hiljem korraks vĂ”rgust vĂ€lja logima. JĂ€tka ettevaatlikult ja omal Ă€ranĂ€gemisel.";
+"settings_labs_enable_crypto_sdk" = "Rust'i-pĂ”hine lĂ€biv krĂŒptimine";
+"poll_history_load_more" = "Laadi veel kĂŒsitlusi";
+"poll_history_no_active_poll_period_text" = "Möödunud %@ pĂ€eva jooksul polnud ĂŒhtegi toimumas olnud kĂŒsitlust. Varasemate kuude vaatamiseks laadi veel kĂŒsitlusi";
+"poll_history_no_past_poll_period_text" = "Möödunud %@ pĂ€eva jooksul polnud ĂŒhtegi lĂ”ppenud kĂŒsitlust. Varasemate kuude vaatamiseks laadi veel kĂŒsitlusi";
+"poll_history_loading_text" = "KĂŒsitluste kuvamise ootel";
+"poll_history_fetching_error" = "Viga kĂŒsitluste laadimisel.";
+"key_backup_recover_from_private_key_progress" = "%@%% tehtud";
+"voice_broadcast_playback_unable_to_decrypt" = "Selle ringhÀÀlingukĂ”ne dekrĂŒptimine ei Ă”nnestu.";
+"home_context_menu_mark_as_unread" = "MĂ€rgi mitteloetuks";
+"wysiwyg_composer_format_action_un_indent" = "VĂ€henda taandrida";
+"wysiwyg_composer_format_action_indent" = "Suurenda taandrida";
+"settings_push_rules_error" = "Teavituste eelistuste muutmisel tekkis viga. Palun proovi sama valikut uuesti sisse/vĂ€lja lĂŒlitada.";
+"poll_history_detail_view_in_timeline" = "NĂ€ita kĂŒsitlust ajajoonel";
diff --git a/Riot/Assets/fr.lproj/Localizable.strings b/Riot/Assets/fr.lproj/Localizable.strings
index 64f1ed5138..aae0fdf791 100644
--- a/Riot/Assets/fr.lproj/Localizable.strings
+++ b/Riot/Assets/fr.lproj/Localizable.strings
@@ -118,3 +118,6 @@
/* New file message from a specific person, not referencing a room. */
"LOCATION_FROM_USER" = "%@ a partagé sa localisation";
+
+/* New voice broadcast from a specific person, not referencing a room. */
+"VOICE_BROADCAST_FROM_USER" = "%@ a lancé une diffusion vocale";
diff --git a/Riot/Assets/fr.lproj/Vector.strings b/Riot/Assets/fr.lproj/Vector.strings
index 35a557929b..6afc58ce22 100644
--- a/Riot/Assets/fr.lproj/Vector.strings
+++ b/Riot/Assets/fr.lproj/Vector.strings
@@ -104,7 +104,7 @@
"room_recents_no_conversation" = "Aucun salon";
"room_recents_low_priority_section" = "PRIORITĂ BASSE";
"room_recents_invites_section" = "INVITATIONS";
-"room_recents_start_chat_with" = "Commencer une discussion";
+"room_recents_start_chat_with" = "Nouveau message direct";
"room_recents_create_empty_room" = "Créer un salon";
"room_recents_join_room" = "Rejoindre le salon";
"room_recents_join_room_title" = "Rejoindre un salon";
@@ -168,22 +168,22 @@
"room_participants_unknown" = "Inconnu";
"room_participants_idle" = "Inactif";
"room_participants_now" = "maintenant";
-"room_participants_ago" = "d'inactivité";
-"room_participants_action_section_admin_tools" = "Outils d'administration";
-"room_participants_action_section_direct_chats" = "Discussions directes";
-"room_participants_action_section_devices" = "Appareils";
+"room_participants_ago" = "dâinactivitĂ©";
+"room_participants_action_section_admin_tools" = "Outils dâadministration";
+"room_participants_action_section_direct_chats" = "Messages directs";
+"room_participants_action_section_devices" = "Sessions";
"room_participants_action_section_other" = "Options";
"room_participants_action_invite" = "Inviter";
"room_participants_action_leave" = "Quitter ce salon";
"room_participants_action_remove" = "Exclure de ce salon";
-"room_participants_action_ban" = "Bannir de ce salon";
+"room_participants_action_ban" = "Interdire lâaccĂšs au salon (dĂ©finitif)";
"room_participants_action_unban" = "RĂ©voquer le bannissement";
"room_participants_action_ignore" = "Masquer tous les messages de cet utilisateur";
"room_participants_action_unignore" = "Afficher tous les messages de cet utilisateur";
"room_participants_action_set_default_power_level" = "RĂ©trograder en utilisateur normal";
"room_participants_action_set_moderator" = "Nommer modérateur";
"room_participants_action_set_admin" = "Nommer administrateur";
-"room_participants_action_start_new_chat" = "Commencer une nouvelle discussion";
+"room_participants_action_start_new_chat" = "Nouveau message direct";
"room_participants_action_start_voice_call" = "Commencer un appel audio";
"room_participants_action_start_video_call" = "Commencer un appel vidéo";
"room_participants_action_mention" = "Mentionner";
@@ -406,16 +406,16 @@
"directory_server_picker_title" = "Sélectionner un répertoire";
"directory_server_all_rooms" = "Tous les salons sur le serveur %@";
"directory_server_all_native_rooms" = "Tous les salons Matrix natifs";
-"directory_server_type_homeserver" = "Saisir un serveur dâaccueil pour lister ses salons publics";
+"directory_server_type_homeserver" = "Saisir un serveur dâaccueil pour lister ses forums";
"directory_server_placeholder" = "matrix.org";
// Others
"you" = "Vous";
"today" = "Aujourdâhui";
"yesterday" = "Hier";
"network_offline_prompt" = "La connexion Internet semble ĂȘtre hors-ligne.";
-"public_room_section_title" = "Salons forums (sur %@) :";
-"bug_report_prompt" = "L'application s'est terminée brusquement la derniÚre fois. Voulez-vous envoyer un rapport d'erreur ?";
-"rage_shake_prompt" = "Vous semblez secouer le téléphone avec frustration. Souhaitez-vous soumettre un rapport d'erreur ?";
+"public_room_section_title" = "Forums (sur %@)Â :";
+"bug_report_prompt" = "Lâapplication sâest arrĂȘtĂ©e brusquement la derniĂšre fois. Voulez-vous envoyer un rapport dâanomalie ?";
+"rage_shake_prompt" = "Vous semblez secouer le tĂ©lĂ©phone avec frustration. Souhaitez-vous soumettre un rapport dâanomalie ?";
"do_not_ask_again" = "Ne plus demander";
"camera_access_not_granted" = "%@ nâa pas la permission pour utiliser lâappareil photo, veuillez modifier les options de confidentialitĂ©";
"large_badge_value_k_format" = "%.1fK";
@@ -1343,7 +1343,7 @@
"room_details_room_name_for_dm" = "Nom";
"room_details_photo_for_dm" = "Photo";
"room_details_title_for_dm" = "DĂ©tails";
-"settings_show_NSFW_public_rooms" = "Afficher les salons publics au contenu choquant";
+"settings_show_NSFW_public_rooms" = "Afficher les forums au contenu choquant";
"external_link_confirmation_message" = "Le lien %@ vous emmĂšne vers un autre site : %@\n\nĂtes vous sĂ»r de vouloir poursuivre ?";
"external_link_confirmation_title" = "Inspectez ce lien";
"room_open_dialpad" = "Pavé de numérotation";
@@ -1750,7 +1750,7 @@
"set_default_power_level" = "RĂ©initialiser le rang";
"set_moderator" = "Nommer modérateur";
"set_admin" = "Nommer administrateur";
-"start_chat" = "Nouvelle conversation privée";
+"start_chat" = "Nouveau message direct";
"start_voice_call" = "Commencer un appel audio";
"start_video_call" = "Commencer un appel vidéo";
"mention" = "Mentionner";
@@ -1986,8 +1986,8 @@
"membership_ban" = "Banni";
"num_members_one" = "%@ utilisateur";
"num_members_other" = "%@ utilisateurs";
-"kick" = "Expulser";
-"ban" = "Bannir";
+"kick" = "Retirer du salon (réversible)";
+"ban" = "Interdire lâaccĂšs au salon (dĂ©finitif)";
"unban" = "RĂ©voquer le bannissement";
"message_unsaved_changes" = "Il y a des modifications non enregistrées. Quitter les annulera.";
// Login Screen
@@ -2467,7 +2467,6 @@
"room_access_space_chooser_other_spaces_section_info" = "Ce sont probablement des choses auxquelles les autres admins de %@ participent.";
"authentication_choose_password_not_verified_message" = "Vérifiez votre boßte de réception";
"authentication_choose_password_not_verified_title" = "Email non vérifié";
-"all_chats_onboarding_page_title3" = "Donner mon avis";
// MARK: User sessions management
@@ -2487,20 +2486,13 @@
// Mark: - Room invites
"room_invites_empty_view_title" = "Rien de neuf.";
-"all_chats_onboarding_try_it" = "Essayez";
-"all_chats_onboarding_title" = "Quoi de neuf";
-"all_chats_onboarding_page_message3" = "Appuyez sur votre profil pour nous faire vos retours.";
-"all_chats_onboarding_page_message2" = "AccĂ©dez Ă vos espaces (en bas Ă gauche) plus rapidement et facilement quâavant.";
-"all_chats_onboarding_page_title2" = "Accéder aux espaces";
-"all_chats_onboarding_page_message1" = "Pour simplifier Element, les onglets sont désormais facultatifs. Gérez les depuis le menu en haut à droite.";
-"all_chats_onboarding_page_title1" = "Bienvenu dans une nouvelle vue !";
"all_chats_edit_menu_space_settings" = "ParamĂštres de lâespace";
"all_chats_edit_menu_leave_space" = "Quitter %@";
"all_chats_user_menu_settings" = "ParamĂštres utilisateur";
"room_recents_recently_viewed_section" = "RĂ©cemment vus";
"all_chats_nothing_found_placeholder_message" = "Essayez dâaffiner votre recherche.";
"all_chats_nothing_found_placeholder_title" = "Aucun résultat.";
-"all_chats_empty_unreads_placeholder_message" = "C'est ici que vos messages non-lus sâafficheront lorsque vous en aurez.";
+"all_chats_empty_unreads_placeholder_message" = "C'est ici que vos messages non lus sâafficheront lorsque vous en aurez.";
"all_chats_empty_list_placeholder_title" = "Plus rien Ă voir.";
"all_chats_empty_view_information" = "La messagerie sécurisée tout en un pour les équipes, les amis, et les organisations. Créez une discussion ou rejoignez un salon pour démarrer.";
"all_chats_empty_space_information" = "Les espaces sont un nouveau moyen de grouper les salons et les gens. Ajoutez un salon, ou crĂ©ez en un nouveau Ă lâaide du bouton en bas Ă droite.";
@@ -2516,14 +2508,14 @@
"all_chats_edit_layout_add_filters_title" = "Filtrez vos messages";
"all_chats_edit_layout_add_section_message" = "Ăpinglez des sections Ă lâaccueil pour y accĂ©der plus rapidement";
"all_chats_edit_layout_add_section_title" = "Ajouter une section Ă lâaccueil";
-"all_chats_edit_layout_unreads" = "Non-lus";
+"all_chats_edit_layout_unreads" = "Non lus";
"all_chats_edit_layout_recents" = "RĂ©cents";
"all_chats_edit_layout" = "PrĂ©fĂ©rences dâagencement";
"all_chats_section_title" = "Discussions";
// Mark: - All Chats
-"all_chats_title" = "Tous mes chats";
+"all_chats_title" = "Accueil";
"spaces_subspace_creation_visibility_message" = "Lâespace crĂ©Ă© sera ajoutĂ© Ă %@.";
"spaces_subspace_creation_visibility_title" = "Quel type de sous-espace voulez-vous créer ?";
"spaces_explore_rooms_format" = "Parcourir %@";
@@ -2564,7 +2556,7 @@
"device_name_desktop" = "%@ Bureau";
"user_inactive_session_item_with_date" = "Inactif depuis 90 jours ou plus (%@)";
"user_inactive_session_item" = "Inactif depuis 90 jours ou plus";
-"user_session_item_details" = "%@ · DerniÚre activité %@";
+"user_session_item_details" = "%1$@ · %2$@";
// First item is client name and second item is session display name
"user_session_name" = "%@Â : %@";
@@ -2641,6 +2633,139 @@
"manage_session_name_info" = "Gardez en tĂȘte que les noms des sessions sont aussi visibles par les personnes avec qui vous communiquez. %@";
"manage_session_name_hint" = "Personnaliser les noms des sessions peut vous aider Ă reconnaĂźtre vos appareils plus facilement.";
"settings_labs_enable_wysiwyg_composer" = "Essayez le compositeur de messages visuel";
+"settings_labs_enable_voice_broadcast" = "Diffusion vocale";
+"wysiwyg_composer_format_action_un_indent" = "Diminuer le retrait";
+"wysiwyg_composer_format_action_indent" = "Augmenter le retrait";
+"wysiwyg_composer_format_action_code_block" = "Bloc de code";
+"wysiwyg_composer_start_action_stickers" = "Autocollants";
+"user_session_rename_session_title" = "Renommer les sessions";
+"user_session_verified_session_description" = "Les sessions vĂ©rifiĂ©es sont toutes celles oĂč vous vous ĂȘtes connectĂ© Ă Element grĂące Ă vos identifiants ou celles pour lesquelles vous avez confirmĂ© votre identitĂ© Ă l'aide d'une autre session.\n\nCela signifie que vous ĂȘtes en possession de toutes les clĂ©s requises pour dĂ©chiffrer vos messages et montrer aux autres utilisateurs que vous faites confiance Ă cette session.";
+"poll_history_loading_text" = "Afficher les sondages";
+"voice_message_broadcast_in_progress_title" = "Impossible de démarrer l'enregistrement vocal";
+"home_context_menu_mark_as_unread" = "Marquer comme non lu";
+"launch_loading_processing_response" = "Traitement des données\n%@ %%";
+"notice_voice_broadcast_ended_by_you" = "Vous avez terminé une diffusion vocale.";
+"notice_voice_broadcast_ended" = "%@ a terminé une diffusion vocale.";
+"notice_voice_broadcast_live" = "Diffusion en direct";
+"deselect_all" = "Tout désélectionner";
+"wysiwyg_composer_link_action_edit_title" = "Modifier le lien";
+"wysiwyg_composer_link_action_create_title" = "Créer un lien";
+"wysiwyg_composer_link_action_link" = "Lien";
+
+// Links
+"wysiwyg_composer_link_action_text" = "Texte";
+"wysiwyg_composer_format_action_quote" = "Citation";
+"wysiwyg_composer_format_action_ordered_list" = "Liste numérique";
+"wysiwyg_composer_format_action_unordered_list" = "Liste Ă puces";
+"wysiwyg_composer_format_action_inline_code" = "Formater comme code informatique";
+"wysiwyg_composer_format_action_link" = "Formater comme lien";
+"wysiwyg_composer_format_action_strikethrough" = "Souligner";
+"wysiwyg_composer_format_action_underline" = "Barrer";
+"wysiwyg_composer_format_action_italic" = "Mettre en italique";
+
+// Formatting Actions
+"wysiwyg_composer_format_action_bold" = "Mettre en caractĂšres gras";
+"wysiwyg_composer_start_action_voice_broadcast" = "Diffusion vocale";
+"wysiwyg_composer_start_action_text_formatting" = "Formatage du texte";
+"wysiwyg_composer_start_action_camera" = "Appareil photo";
+"wysiwyg_composer_start_action_location" = "Position";
+"wysiwyg_composer_start_action_polls" = "Sondages";
+"wysiwyg_composer_start_action_attachments" = "PiĂšces jointes";
+
+
+// MARK: - WYSIWYG Composer
+
+// Send Media Actions
+"wysiwyg_composer_start_action_media_picker" = "Galerie photo";
+"user_session_details_last_activity" = "DerniÚre activité";
+"user_session_item_details_last_activity" = "DerniÚre activité %@";
+"user_other_session_menu_sign_out_sessions" = "DĂ©connecter %@ sessions";
+"user_other_session_selected_count" = "%@ sélectionnées";
+"user_other_session_menu_select_sessions" = "SĂ©lectionnez des sessions";
+"user_other_session_clear_filter" = "Effacer les filtres";
+"user_other_session_no_unverified_sessions" = "Aucune session non vérifiée trouvée.";
+"user_other_session_no_verified_sessions" = "Aucune session vérifiée trouvée.";
+"user_other_session_no_inactive_sessions" = "Aucune session inactive trouvée.";
+"user_other_session_filter_menu_inactive" = "Inactives";
+"user_other_session_filter_menu_unverified" = "Non vérifiées";
+"user_other_session_filter_menu_verified" = "Vérifiées";
+"user_other_session_filter_menu_all" = "Toutes les sessions";
+"user_other_session_filter" = "Filtrer";
+"user_other_session_verified_sessions_header_subtitle" = "Pour augmenter la sécurité, veuillez déconnecter toutes les sessions qui vous semblent inconnues ou que vous n'utilisez plus.";
+"user_other_session_current_session_details" = "Votre session actuelle";
+"user_other_session_security_recommendation_title" = "Autres sessions";
+"user_session_rename_session_description" = "D'autres utilisateurs des conversations et salons que vous rejoignez peuvent consulter la liste complĂšte de vos session.\n\nCela leur permet de confirmer qu'ils communiquent bien avec vous, mais cela signifie Ă©galement qu'ils verront le nom que vous donnez Ă vos sessions.";
+"user_session_inactive_session_description" = "Les sessions inactives sont celles qui n'ont pas Ă©tĂ© utilisĂ©es depuis un certain temps, mais qui continuent de recevoir des clĂ©s de chiffrement.\n\nĂliminer ces sessions inactives augmente la sĂ©curitĂ© et les performances, et facilite l'identification de nouvelles connexions suspectes.";
+"user_session_inactive_session_title" = "Sessions inactives";
+"user_session_permanently_unverified_session_description" = "Cette session de prend pas en charge le chiffrement et ne peut donc ĂȘtre vĂ©rifiĂ©e.\n\nVous ne pourrez pas intervenir dans les salons oĂč le chiffrement est activĂ© en utilisant cette session.\n\nPour une sĂ©curitĂ© et confidentialitĂ© optimale, il est recommandĂ© d'utiliser des clients Matrix qui prennent en charge le chiffrement.";
+"user_session_unverified_session_description" = "Les sessions non vérifiez sont celles qui sont connectées avec vos identifiants, mais qui n'ont pas passé les vérifications croisées.\n\nVous devriez passer en revue ces sessions car elles pourraient témoigner d'un usage malicieux de votre compte.";
+"user_session_unverified_session_title" = "Session non vérifiée";
+"user_session_verified_session_title" = "Sessions vérifiées";
+"user_session_got_it" = "Entendu";
+"user_other_session_verified_additional_info" = "Cette session est prĂȘte Ă l'Ă©change de messages.";
+"user_other_session_permanently_unverified_additional_info" = "Cette session ne prend pas en charge le chiffrement et ne peut donc ĂȘtre vĂ©rifiĂ©e.";
+"user_other_session_unverified_additional_info" = "Vérifier ou déconnecter cette session pour une sécurité et une fiabilité accrue.";
+"user_session_verification_unknown_additional_info" = "Vérifier la session actuelle pour révéler l'état de vérification de cette session.";
+"user_session_verification_unknown_short" = "Inconnu";
+"user_session_verification_unknown" = "Ătat de vĂ©rification inconnu";
+"user_sessions_hide_location_info" = "Masquer l'adresse IP";
+"user_sessions_show_location_info" = "Montrer l'adresse IP";
+"poll_timeline_reply_ended_poll" = "Sondage terminé";
+"poll_timeline_ended_text" = "Sondage clos";
+"poll_timeline_decryption_error" = "Des erreurs de dĂ©chiffrement pourrait empĂȘcher certains votes d'ĂȘtre comptabilisĂ©s";
+"poll_history_fetching_error" = "Erreur au cours de la récupération des sondages.";
+"poll_history_load_more" = "Charger plus de sondages";
+"poll_history_no_past_poll_period_text" = "Il n'y a pas eu de sondages les %@ derniers jours. Veuillez charger plus de sondages pour consulter les sondages des mois antérieurs";
+"poll_history_no_active_poll_period_text" = "Il n'y a pas eu de sondages depuis %@ jours. Veuillez charger plus de sondages pour consulter les sondages des mois antérieurs";
+"poll_history_detail_view_in_timeline" = "Consulter la chronologie des sondages";
+"poll_history_no_past_poll_text" = "Il n'y a pas de sondage précédent dans ce salon";
+"poll_history_no_active_poll_text" = "Il n'y a aucun sondage en cours dans ce salon";
+"poll_history_past_segment_title" = "Sondages précédents";
+"poll_history_active_segment_title" = "Sondages en cours";
+
+// MARK: - Polls history
+
+"poll_history_title" = "Historique des sondages";
+"voice_broadcast_playback_unable_to_decrypt" = "Impossible de déchiffrer cette diffusion vocale.";
+"voice_broadcast_recorder_connection_error" = "Erreur de connexion - Enregistrement interrompu";
+"voice_broadcast_connection_error_message" = "Nous sommes malheureusement dans l'impossibilité de démarrer un enregistrement maintenant. Veuillez réessayer plus tard.";
+"voice_broadcast_connection_error_title" = "Erreur de connexion";
+"voice_broadcast_voip_cannot_start_description" = "Vous ne pouvez pas démarrer d'appel car vous enregistrez déjà une diffusion en direct. Veuillez interrompre votre diffusion pour lancer un appel.";
+"voice_broadcast_voip_cannot_start_title" = "Impossible de démarrer l'appel";
+"voice_broadcast_stop_alert_agree_button" = "Oui, terminer";
+"voice_broadcast_stop_alert_description" = "Ătes vous sĂ»r de vouloir interrompre votre diffusion vocale ? Cela mettra fin Ă la diffusion et rendra l'enregistrement disponible dans le salon.";
+"voice_broadcast_stop_alert_title" = "ArrĂȘter la diffusion vocale ?";
+"voice_broadcast_buffering" = "Mise en mémoire tampon...";
+"voice_broadcast_time_left" = "%@ restant";
+"voice_broadcast_tile" = "Diffusion vocale";
+"voice_broadcast_live" = "En direct";
+"voice_broadcast_playback_lock_screen_placeholder" = "Diffusion vocale";
+"voice_broadcast_playback_loading_error" = "Impossible de lire cette diffusion vocale.";
+"voice_broadcast_blocked_by_someone_else_message" = "Quelqu'un d'autre est déjà en train d'enregistrer une diffusion vocale. Veuillez attendre la fin de la leur pour en démarrer une nouvelle.";
+"voice_broadcast_already_in_progress_message" = "Vous ĂȘtes dĂ©jĂ en train d'enregistrer une diffusion vocale. Veuillez y mettre fin avant d'en dĂ©marrer une nouvelle.";
+"voice_broadcast_permission_denied_message" = "Vous n'avez pas les autorisations nécessaires pour démarrer une diffusion vocal dans ce salon. Contactez un administrateur pour qu'il vous octroie la permission.";
+
+// MARK: - Voice Broadcast
+"voice_broadcast_unauthorized_title" = "Impossible de démarrer une nouvelle diffusion vocale";
+"voice_message_broadcast_in_progress_message" = "Vous ne pouvez pas démarrer d'enregistrement vocal car vous diffusez en direct. Veuillez interrompre votre diffusion pour démarrer l'enregistrement vocal";
+"launch_loading_server_syncing_nth_attempt" = "Synchronisation avec le serveur\n(%@ tentatives)";
+"launch_loading_server_syncing" = "Synchronisation avec le serveur";
+
+// MARK: - Launch loading
+
+"launch_loading_migrating_data" = "Migration des données\n%@ %%";
+"key_backup_recover_from_private_key_progress" = "%@%% Fini";
+"room_details_polls" = "Historique des sondages";
+"settings_labs_disable_crypto_sdk" = "Chiffrement de bout en bout avec Rust (se déconnecter pour désactiver)";
+"settings_labs_confirm_crypto_sdk" = "Cette option activera le nouveau moteur de chiffrement de bout en bout, plus rapide et plus fiable, écrit en Rust. Une fois activé vous devrez vous déconnecter pour le désactiver. Voulez-vous continuer ?";
+"settings_labs_enable_crypto_sdk" = "Chiffrement de bout en bout en Rust";
+"settings_push_rules_error" = "Nous avons rencontré une erreur lors de la mise à jours de vos préférences de notification. Veuillez réactiver l'option.";
+"password_policy_pwd_in_dict_error" = "Ce mot de passe a été trouvé dans un dictionnaire, et son usage n'est donc pas autorisé.";
+"password_policy_weak_pwd_error" = "Ce mot de passe est trop faible. Il doit contenir au moins 8 caractÚres, dont au moins une majuscule, une minuscule, un chiffre et un caractÚre spécial.";
+
+// MARK: Password policy errors
+"password_policy_too_short_pwd_error" = "Mot de passe trop court";
+"accessibility_selected" = "sélectionné";
// Tchap: override some MatrixKit strings
"attachment_e2e_keys_file_prompt" = "Ce fichier contient des clés Tchap exportées d'un client Tchap.\nVoulez-vous voir le contenu du fichier ou importer les clés qu'il contient ?"; // Tchap
diff --git a/Riot/Assets/hu.lproj/Vector.strings b/Riot/Assets/hu.lproj/Vector.strings
index 6dd053e547..a10998eb79 100644
--- a/Riot/Assets/hu.lproj/Vector.strings
+++ b/Riot/Assets/hu.lproj/Vector.strings
@@ -2467,14 +2467,6 @@
// Mark: - Room invites
"room_invites_empty_view_title" = "Semmi Ășj.";
-"all_chats_onboarding_try_it" = "PrĂłbĂĄld ki";
-"all_chats_onboarding_title" = "ĂjdonsĂĄgok";
-"all_chats_onboarding_page_message3" = "Koppints a profilodra Ă©s mond el mit gondolsz.";
-"all_chats_onboarding_page_title3" = "Visszajelzés adåsa";
-"all_chats_onboarding_page_message2" = "A terekhez való hozzåférés (balra lent) gyorsabb és egyszerƱbb mint valaha.";
-"all_chats_onboarding_page_title2" = "Hozzåférés a terekhez";
-"all_chats_onboarding_page_message1" = "Element egyszerƱsĂtĂ©sĂ©hez a lapok mostantĂłl vĂĄlaszthatĂłk. BeĂĄllĂtani a jobb felsĆ menĂŒbĆl lehet.";
-"all_chats_onboarding_page_title1" = "Ădv az Ășj kinĂ©zetben!";
"all_chats_nothing_found_placeholder_message" = "PrĂłbĂĄld meg a keresĂ©st mĂłdosĂtani.";
"all_chats_nothing_found_placeholder_title" = "Nincs talĂĄlat.";
"all_chats_empty_unreads_placeholder_message" = "Ez az a hely ahol az olvasatlan ĂŒzeneteid megjelennek, ha lesznek.";
@@ -2710,3 +2702,18 @@
"voice_broadcast_connection_error_message" = "Sajnos most nem lehet elindĂtani a felvĂ©telt. PrĂłbĂĄlja meg kĂ©sĆbb.";
"voice_broadcast_connection_error_title" = "Kapcsolat hiba";
"voice_broadcast_playback_lock_screen_placeholder" = "Hang közvetĂtĂ©s";
+"poll_history_load_more" = "Még több szavazås betöltése";
+"poll_history_no_past_poll_period_text" = "%@ napja nincs aktĂv szavazĂĄs. TovĂĄbbi szavazĂĄsok betöltĂ©se az elĆzĆ havi szavazĂĄsok megjelenĂtĂ©sĂ©hez";
+"poll_history_no_active_poll_period_text" = "%@ napja nincs aktĂv szavazĂĄs. TovĂĄbbi szavazĂĄsok betöltĂ©se az elĆzĆ havi szavazĂĄsok megjelenĂtĂ©sĂ©hez";
+"poll_history_loading_text" = "SzavazĂĄsok megjelenĂtĂ©se";
+
+// MARK: - Launch loading
+
+"launch_loading_migrating_data" = "Adatok migrĂĄlĂĄsa\n%@ %%";
+"settings_labs_disable_crypto_sdk" = "VĂ©gpontok közötti titkosĂtĂĄs 2.0 (kikapcsolĂĄshoz kijelentkezĂ©s szĂŒksĂ©ges)";
+"settings_labs_confirm_crypto_sdk" = "Ezzel az opciĂłval egy gyorsabb Ă©s megbĂzhatĂłbb vĂ©gponttĂłl vĂ©gponting titkosĂtĂł motor kerĂŒl engedĂ©lyezĂ©sre ami Rustban lett megĂrva. BekapcsolĂĄs utĂĄn a kikapcsolĂĄsĂĄhoz ki kell jelentkezni. Folytatod?";
+"settings_labs_enable_crypto_sdk" = "Az Ășj Rust alapĂș TitkosĂtĂĄsi SDK engedĂ©lyezĂ©se";
+"home_context_menu_mark_as_unread" = "Olvasatlannak jelöl";
+"poll_history_fetching_error" = "Szavazås betöltési hiba.";
+"voice_broadcast_playback_unable_to_decrypt" = "A hang közvetĂtĂ©s nem fejthetĆ vissza.";
+"key_backup_recover_from_private_key_progress" = "%@%% kész";
diff --git a/Riot/Assets/id.lproj/Vector.strings b/Riot/Assets/id.lproj/Vector.strings
index 508d3eb7d1..0120b2b5a9 100644
--- a/Riot/Assets/id.lproj/Vector.strings
+++ b/Riot/Assets/id.lproj/Vector.strings
@@ -2672,14 +2672,6 @@
// Mark: - Room invites
"room_invites_empty_view_title" = "Belum ada yang baru.";
-"all_chats_onboarding_try_it" = "Coba";
-"all_chats_onboarding_title" = "Apa yang baru";
-"all_chats_onboarding_page_message3" = "Ketuk profil Anda untuk memberi tahu kami bagaimana menurut Anda.";
-"all_chats_onboarding_page_title3" = "Berikan Masukan";
-"all_chats_onboarding_page_message2" = "Akses Space Anda (di kiri bawah) dengan lebih cepat dan lebih mudah dari sebelumnya.";
-"all_chats_onboarding_page_title2" = "Akses Space";
-"all_chats_onboarding_page_message1" = "Untuk membuat Element Anda lebih sederhana, fitur tab sekarang opsional. Kelola menggunakan menu kanan atas.";
-"all_chats_onboarding_page_title1" = "Selamat datang di tampilan yang baru!";
"all_chats_nothing_found_placeholder_message" = "Coba atur pencarian Anda.";
"all_chats_nothing_found_placeholder_title" = "Tidak ada yang ditemukan.";
"all_chats_empty_unreads_placeholder_message" = "Ini di mana pesan Anda yang belum dibaca akan ditampilkan, ketika Anda menerimanya.";
@@ -2921,6 +2913,18 @@
// MARK: - Launch loading
"launch_loading_migrating_data" = "Memigrasikan data\n%@ %%";
-"settings_labs_disable_crypto_sdk" = "SDK Kripto diaktifkan. Untuk menonaktifkan, mohon memasang ulang aplikasi";
-"settings_labs_confirm_crypto_sdk" = "Tindakan ini tidak dapat diurungkan";
-"settings_labs_enable_crypto_sdk" = "Aktifkan SDK Kripto baru berbasis Rust";
+"settings_labs_disable_crypto_sdk" = "Enkripsi ujung ke ujung Rust (keluar dari akun untuk menonaktifkan)";
+"settings_labs_confirm_crypto_sdk" = "Ketahui bahwa fitur ini masih dalam masa eksperimental, ini mungkin tidak berfungsi seperti yang diharapkan dan dapat memiliki konsekuensi yang tidak terduga. Untuk mengembalikan fitur, cukup keluar dari akun dan masuk kembali ke akun. Gunakan dengan pengetahuan dan risiko Anda.";
+"settings_labs_enable_crypto_sdk" = "Enkripsi ujung ke ujung Rust";
+"poll_history_load_more" = "Muat lebih banyak pemungutan suara";
+"poll_history_no_active_poll_period_text" = "Tidak ada pemungutan suara terakhir untuk %@ hari sebelumnya. Muat lebih banyak pemungutan suara untuk bulan sebelumnya";
+"poll_history_no_past_poll_period_text" = "Tidak ada pemungutan suara untuk %@ hari sebelumnya. Muat lebih banyak pemungutan suara untuk melihat pemungutan suara untuk bulan sebelumnya";
+"poll_history_loading_text" = "Menampilkan pemungutan suara";
+"poll_history_fetching_error" = "Terjadi kesalahan mendapatkan pemungutan suara.";
+"key_backup_recover_from_private_key_progress" = "%@%% Selesai";
+"voice_broadcast_playback_unable_to_decrypt" = "Tidak dapat mendekripsi siaran suara ini.";
+"home_context_menu_mark_as_unread" = "Tandai sebagai belum dibaca";
+"wysiwyg_composer_format_action_un_indent" = "Kurangi indentasi";
+"wysiwyg_composer_format_action_indent" = "Tambahkan indentasi";
+"poll_history_detail_view_in_timeline" = "Tampilkan pemungutan suara dalam lini masa";
+"settings_push_rules_error" = "Sebuah kesalahan terjadi ketika memperbarui preferensi notifikasi Anda. Silakan alih ulang opsi Anda.";
diff --git a/Riot/Assets/is.lproj/Vector.strings b/Riot/Assets/is.lproj/Vector.strings
index 10722ec1b8..1a0e5981e2 100644
--- a/Riot/Assets/is.lproj/Vector.strings
+++ b/Riot/Assets/is.lproj/Vector.strings
@@ -2132,7 +2132,6 @@
"user_sessions_overview_title" = "Setur";
"space_selector_create_space" = "BĂșa til svĂŠĂ°i";
-"all_chats_onboarding_try_it" = "PrĂłfaĂ°u ĂŸaĂ°";
"all_chats_edit_menu_space_settings" = "Stillingar svĂŠĂ°is";
"all_chats_edit_menu_leave_space" = "Yfirgefa %@";
"room_recents_recently_viewed_section" = "NĂœlega skoĂ°aĂ°";
@@ -2234,7 +2233,6 @@
// Mark: - Room invites
"room_invites_empty_view_title" = "Ekkert nĂœtt.";
-"all_chats_onboarding_page_title1" = "Velkomin Ă nĂœja sĂœn!";
"all_chats_nothing_found_placeholder_message" = "Reyndu aĂ° aĂ°laga leitina ĂŸĂna.";
"all_chats_edit_layout_alphabetical_order" = "RaĂ°a A-Ă";
"all_chats_edit_layout_activity_order" = "RaĂ°a eftir virkni";
@@ -2330,9 +2328,6 @@
// Mark: - Space Selector
"space_selector_title" = "SvĂŠĂ°in mĂn";
-"all_chats_onboarding_title" = "HvaĂ° er nĂœtt";
-"all_chats_onboarding_page_title3" = "Gefðu umsögn";
-"all_chats_onboarding_page_title2" = "AĂ°gangur aĂ° svĂŠĂ°um";
"all_chats_user_menu_settings" = "Notandastillingar";
"all_chats_edit_layout_pin_spaces_title" = "Festu svĂŠĂ°in ĂŸĂn";
diff --git a/Riot/Assets/it.lproj/Vector.strings b/Riot/Assets/it.lproj/Vector.strings
index 8dbc7f07a3..8d1cc83f06 100644
--- a/Riot/Assets/it.lproj/Vector.strings
+++ b/Riot/Assets/it.lproj/Vector.strings
@@ -2445,14 +2445,6 @@
// Mark: - Room invites
"room_invites_empty_view_title" = "Niente di nuovo.";
-"all_chats_onboarding_try_it" = "Provalo";
-"all_chats_onboarding_title" = "NovitĂ ";
-"all_chats_onboarding_page_message3" = "Tocca il tuo profilo per farci sapere cosa ne pensi.";
-"all_chats_onboarding_page_title3" = "Invia un feedback";
-"all_chats_onboarding_page_message2" = "Accedi ai tuoi spazi (in basso a sinistra) piĂč velocemente e piĂč facilmente che mai.";
-"all_chats_onboarding_page_title2" = "Accedi agli spazi";
-"all_chats_onboarding_page_message1" = "Per semplificare Element, le schede ora sono opzionali. Gestiscile usando il menu in alto a destra.";
-"all_chats_onboarding_page_title1" = "Benvenuti ad una nuova panoramica!";
"all_chats_nothing_found_placeholder_message" = "Prova a cambiare la tua ricerca.";
"all_chats_nothing_found_placeholder_title" = "Non Ăš stato trovato niente.";
"all_chats_empty_unreads_placeholder_message" = "Qui Ăš dove verranno mostrati i messaggi non letti, quando ne avrai qualcuno.";
@@ -2690,3 +2682,22 @@
"voice_broadcast_recorder_connection_error" = "Errore di connessione - Registrazione in pausa";
"voice_broadcast_connection_error_message" = "Sfortunatamente non riusciamo ad iniziare una registrazione al momento. Riprova piĂč tardi.";
"voice_broadcast_connection_error_title" = "Errore di connessione";
+"poll_history_load_more" = "Carica piĂč sondaggi";
+"poll_history_no_past_poll_period_text" = "Non ci sono sondaggi passati negli ultimi %@ giorni. Carica piĂč sondaggi per vedere quelli dei mesi precedenti";
+"poll_history_no_active_poll_period_text" = "Non ci sono sondaggi attivi negli ultimi %@ giorni. Carica piĂč sondaggi per vedere quelli dei mesi precedenti";
+"poll_history_loading_text" = "Visualizzazione sondaggi";
+
+// MARK: - Launch loading
+
+"launch_loading_migrating_data" = "Migrazione dati\n%@ %%";
+"settings_labs_disable_crypto_sdk" = "Crittografia end-to-end Rust (disconnettiti per disattivarla)";
+"settings_labs_confirm_crypto_sdk" = "Si noti che questa funzione, essendo ancora in fase sperimentale, potrebbe non funzionare come previsto e potrebbe avere conseguenze indesiderate. Per disattivare la funzione, Ăš sufficiente disconnettersi e riaccedere. Utilizzare a propria discrezione e con cautela.";
+"settings_labs_enable_crypto_sdk" = "Crittografia end-to-end Rust";
+"wysiwyg_composer_format_action_un_indent" = "Diminuisci indentazione";
+"wysiwyg_composer_format_action_indent" = "Aumenta indentazione";
+"poll_history_fetching_error" = "Errore di recupero dei sondaggi.";
+"voice_broadcast_playback_unable_to_decrypt" = "Impossibile decifrare questa trasmissione vocale.";
+"home_context_menu_mark_as_unread" = "Segna come non letto";
+"key_backup_recover_from_private_key_progress" = "%@%% Completato";
+"poll_history_detail_view_in_timeline" = "Vedi sondaggio nella linea temporale";
+"settings_push_rules_error" = "Si Ăš verificato un errore aggiornando le tue preferenze di notifica. Prova ad attivare/disattivare di nuovo l'opzione.";
diff --git a/Riot/Assets/ja.lproj/InfoPlist.strings b/Riot/Assets/ja.lproj/InfoPlist.strings
index d99e8eb801..cae22a1090 100644
--- a/Riot/Assets/ja.lproj/InfoPlist.strings
+++ b/Riot/Assets/ja.lproj/InfoPlist.strings
@@ -1,9 +1,9 @@
// Permissions usage explanations
-"NSCameraUsageDescription" = "ă«ăĄă©ăŻăăăăȘé話ăćçæźćœ±ăćç»æźćœ±ă«äœżçšăăăŸăă";
-"NSPhotoLibraryUsageDescription" = "ăă©ăă©ă€ăă©ăȘăŻăćçăćç»ăźé俥ă«äœżçšăăăŸăă";
+"NSCameraUsageDescription" = "ă«ăĄă©ăŻăăăăȘé話ăćçăćç»ăźæźćœ±ăšăąăăăăŒăă«äœżçšăăăŸăă";
+"NSPhotoLibraryUsageDescription" = "ăă©ăăžăźăąăŻă»ăčăèš±ćŻăăăšăćçăćç»ăă©ă€ăă©ăȘăŒăăăąăăăăŒăă§ăăăăă«ăȘăăŸăă";
"NSMicrophoneUsageDescription" = "ElementăŻé話ăćç»æźćœ±ăăă€ăčăĄăă»ăŒăžăźéČéłă«ăă€ăŻăžăźăąăŻă»ăčăćż
èŠăšăăŠăăŸăă";
-"NSContactsUsageDescription" = "ElementăŻăăăȘăăéŁç”Ąć
ăăăŁăăă«æćŸ
ă§ăăăăă«ăéŁç”Ąć
ăèĄšç€șăăŸăă";
+"NSContactsUsageDescription" = "ăăȘăăźIDă”ăŒăăŒă«ć
±æăăăMatrixă§éŁç”Ąć
ăçșèŠăăăźă«äœżçšăăăŸăă";
"NSCalendarsUsageDescription" = "äșćźăăăŠăăăăŒăăŁăłă°ăăąăăȘă§çąșèȘăăăăšăă§ăăŸăă";
"NSFaceIDUsageDescription" = "Face IDăŻăąăăȘăžăźăąăŻă»ăčă«äœżçšăăăŸăă";
"NSLocationWhenInUseUsageDescription" = "äœçœźæ
ć ±ăć
±æăăéă«ăŻăć°ćłăèĄšç€șăăăăăźăąăŻă»ăčăElementă«ä»äžăăćż
èŠăăăăŸăă";
-"NSLocationAlwaysAndWhenInUseUsageDescription" = "ăăȘăăä»ăźäșșă«äœçœźăć
±æăăăšăăElementăŻć°ćłăăăźäșșă«èĄšç€șăăăąăŻă»ăčæš©ăćż
èŠă§ăă";
+"NSLocationAlwaysAndWhenInUseUsageDescription" = "äœçœźæ
ć ±ăć
±æăăéă«ăŻăć°ćłăèĄšç€șăăăăăźăąăŻă»ăčăElementă«ä»äžăăćż
èŠăăăăŸăă";
diff --git a/Riot/Assets/ja.lproj/Localizable.strings b/Riot/Assets/ja.lproj/Localizable.strings
index 4a63be21b9..c76236c89b 100644
--- a/Riot/Assets/ja.lproj/Localizable.strings
+++ b/Riot/Assets/ja.lproj/Localizable.strings
@@ -1,9 +1,9 @@
/* New message from a specific person, not referencing a room */
-"MSG_FROM_USER" = "%@ ăăăăăĄăă»ăŒăž";
+"MSG_FROM_USER" = "%@ăăăăĄăă»ăŒăžăé俥ăăŸăă";
/* New message from a specific person in a named room */
-"MSG_FROM_USER_IN_ROOM" = "%@ ăăă %@ ăžçșèš";
+"MSG_FROM_USER_IN_ROOM" = "%@ăăă%@ă«æçšżăăŸăă";
/* New message from a specific person, not referencing a room. Content included. */
-"MSG_FROM_USER_WITH_CONTENT" = "%@: %@";
+"MSG_FROM_USER_WITH_CONTENT" = "%@ïŒ%@";
/* New message from a specific person in a named room. Content included. */
"MSG_FROM_USER_IN_ROOM_WITH_CONTENT" = "%@ in %@: %@";
/* New action message from a specific person, not referencing a room. */
@@ -12,62 +12,62 @@
"ACTION_FROM_USER_IN_ROOM" = "%@: * %@ %@";
/* New action message from a specific person, not referencing a room. */
/* New action message from a specific person in a named room. */
-"IMAGE_FROM_USER_IN_ROOM" = "%@ ăăăćçăæçšż %@ in %@";
+"IMAGE_FROM_USER_IN_ROOM" = "%@ăăăćç%@ă%@ă«æçšżăăŸăă";
/* Multiple unread messages in a room */
-"UNREAD_IN_ROOM" = "%@ æ°ăăăĄăă»ăŒăž in %@";
+"UNREAD_IN_ROOM" = "%@件ăźæ°ăăăĄăă»ăŒăžă%@ă«ăăăŸă";
/* Multiple unread messages from a specific person, not referencing a room */
-"MSGS_FROM_USER" = "%@ æ°ăăăĄăă»ăŒăž in %@";
+"MSGS_FROM_USER" = "%@件ăźæ°ăăăĄăă»ăŒăžă%@ă«ăăăŸă";
/* Multiple unread messages from two people */
-"MSGS_FROM_TWO_USERS" = "%@ æ°ăăăĄăă»ăŒăž from %@ and %@";
+"MSGS_FROM_TWO_USERS" = "%@件ăźæ°ăăăĄăă»ăŒăžă%@ăš%@ăăć俥ăăŸăă";
/* Multiple unread messages from three people */
-"MSGS_FROM_THREE_USERS" = "%@ æ°ăăăĄăă»ăŒăž from %@, %@ and %@";
+"MSGS_FROM_THREE_USERS" = "%@件ăźæ°ăăăĄăă»ăŒăžă%@ă%@ă%@ăăć俥ăăŸăă";
/* Multiple unread messages from two plus people (ie. for 4+ people: 'others' replaces the third person) */
-"MSGS_FROM_TWO_PLUS_USERS" = "%@ æ°ăăăĄăă»ăŒăž from %@, %@ ä»";
+"MSGS_FROM_TWO_PLUS_USERS" = "%@件ăźæ°ăăăĄăă»ăŒăžă%@ă%@ăă»ăæ°äșșăăć俥ăăŸăă";
/* Multiple messages in two rooms */
-"MSGS_IN_TWO_ROOMS" = "%@ æ°ăăăĄăă»ăŒăž in %@ and %@";
+"MSGS_IN_TWO_ROOMS" = "%@件ăźæ°ăăăĄăă»ăŒăžă%@ăš%@ă«ăăăŸă";
/* Look, stuff's happened, alright? Just open the app. */
-"MSGS_IN_TWO_PLUS_ROOMS" = "%@ æ°ăăăĄăă»ăŒăž in %@, %@ ä»";
+"MSGS_IN_TWO_PLUS_ROOMS" = "%@件ăźæ°ăăăĄăă»ăŒăžă%@ă%@ăȘă©ă«ăăăŸă";
/* A user has invited you to a chat */
-"USER_INVITE_TO_CHAT" = "%@ ăăăăăȘăăćŻŸè©±ă«æćŸ
ăăŸăă";
+"USER_INVITE_TO_CHAT" = "%@ăăăăăȘăăăăŁăăă«æćŸ
ăăŸăă";
/* A user has invited you to an (unamed) group chat */
-"USER_INVITE_TO_CHAT_GROUP_CHAT" = "%@ ăăăăăȘăăă«ăŒă ăžæćŸ
ăăŸăă";
+"USER_INVITE_TO_CHAT_GROUP_CHAT" = "%@ăăăăăȘăăă°ă«ăŒăăăŁăăă«æćŸ
ăăŸăă";
/* A user has invited you to a named room */
-"USER_INVITE_TO_NAMED_ROOM" = "%@ ăăăă«ăŒă %@ ăžæćŸ
ăăŸăă";
+"USER_INVITE_TO_NAMED_ROOM" = "%@ăăăă«ăŒă %@ ă«æćŸ
ăăŸăă";
/* Incoming one-to-one voice call */
-"VOICE_CALL_FROM_USER" = "%@ ăăăăé話ç俥";
+"VOICE_CALL_FROM_USER" = "%@ăăăăé話ç俥";
/* Incoming one-to-one video call */
-"VIDEO_CALL_FROM_USER" = "%@ ăăăăæ ćă€ăé話ç俥";
+"VIDEO_CALL_FROM_USER" = "%@ăăăăăăăȘé話ăźç俥";
/* Incoming unnamed voice conference invite from a specific person */
-"VOICE_CONF_FROM_USER" = "%@ ăăăăäŒè°é話ăźç俥";
+"VOICE_CONF_FROM_USER" = "%@ăăăăă°ă«ăŒăé話ăźç俥";
/* Incoming unnamed video conference invite from a specific person */
-"VIDEO_CONF_FROM_USER" = "%@ ăăăăæ ćă€ăäŒè°é話ăźç俥";
+"VIDEO_CONF_FROM_USER" = "%@ăăăăăăăȘă°ă«ăŒăé話ăźç俥";
/* Incoming named voice conference invite from a specific person */
-"VOICE_CONF_NAMED_FROM_USER" = "äŒè°é話ăźç俥 from %@: '%@'";
+"VOICE_CONF_NAMED_FROM_USER" = "%@ăăăăă°ă«ăŒăé話ăźç俥ïŒ'%@'";
/* Incoming named video conference invite from a specific person */
-"VIDEO_CONF_NAMED_FROM_USER" = "æ ćă€ăäŒè°é話ăźç俥 from %@: '%@'";
+"VIDEO_CONF_NAMED_FROM_USER" = "%@ăăăăăăăȘă°ă«ăŒăé話ăźç俥ïŒ'%@'";
/* A single unread message in a room */
-"SINGLE_UNREAD_IN_ROOM" = "%@ă«ăĄăă»ăŒăžăćăćăăŸăă";
+"SINGLE_UNREAD_IN_ROOM" = "%@ă§ăĄăă»ăŒăžăć俥ăăŸăă";
/* A single unread message */
-"SINGLE_UNREAD" = "ăăȘăăŻăĄăă»ăŒăžăćăćăăŸăă";
+"SINGLE_UNREAD" = "ăĄăă»ăŒăžăć俥ăăŸăă";
/** Key verification **/
"KEY_VERIFICATION_REQUEST_FROM_USER" = "%@ăŻèȘ蚌ăèŠæ±ăăŠăăŸă";
/* New message indicator on a room */
-"MESSAGE_IN_X" = "%@ ć
ăźăĄăă»ăŒăž";
+"MESSAGE_IN_X" = "%@ć
ăźăĄăă»ăŒăž";
/* Sticker from a specific person, not referencing a room. */
-"STICKER_FROM_USER" = "%@ ăăăăăźăčăżăłă";
+"STICKER_FROM_USER" = "%@ăăăăčăăă«ăŒăé俥ăăŸăă";
/* Message title for a specific person in a named room */
"MSG_FROM_USER_IN_ROOM_TITLE" = "%@ïŒ%@ ăăïŒ";
/* Group call from user, CallKit caller name */
-"GROUP_CALL_FROM_USER" = "%@ (ă°ă«ăŒăé話)";
+"GROUP_CALL_FROM_USER" = "%@ïŒă°ă«ăŒăé話ïŒ";
"MESSAGE_PROTECTED" = "æ°ăăăĄăă»ăŒăž";
/* New message indicator from a DM */
-"MESSAGE_FROM_X" = "%@ ăăăźăĄăă»ăŒăž";
+"MESSAGE_FROM_X" = "%@ăăăăăźăĄăă»ăŒăž";
/** Notification messages **/
@@ -78,52 +78,55 @@
"Notification" = "éç„";
/* New message reply from a specific person in a named room. */
-"REPLY_FROM_USER_IN_ROOM_TITLE" = "%@ ăăă %@ ă§èżäżĄ";
+"REPLY_FROM_USER_IN_ROOM_TITLE" = "%@ăăă%@ă§èżäżĄăăŸăă";
/* New message reply from a specific person, not referencing a room. */
-"REPLY_FROM_USER_TITLE" = "%@ ăăăèżäżĄ";
+"REPLY_FROM_USER_TITLE" = "%@ăăăèżäżĄăăŸăă";
/** Reactions **/
/* A user has reacted to a message, including the reaction e.g. "Alice reacted đ". */
-"REACTION_FROM_USER" = "%@ ăăă %@ ăšăȘăąăŻă·ă§ăł";
+"REACTION_FROM_USER" = "%@ăăă%@ă§ăȘăąăŻă·ă§ăłăăŸăă";
/* A user has reacted to a message, but the reaction content is unknown */
-"GENERIC_REACTION_FROM_USER" = "%@ ăăăăȘăąăŻă·ă§ăł";
+"GENERIC_REACTION_FROM_USER" = "%@ăăăăȘăąăŻă·ă§ăłăé俥ăăŸăă";
/* New file message from a specific person, not referencing a room. */
-"LOCATION_FROM_USER" = "%@ ăăăäœçœźæ
ć ±ăć
±æ";
+"LOCATION_FROM_USER" = "%@ăăăäœçœźæ
ć ±ăć
±æăăŸăă";
/* New voice message from a specific person, not referencing a room. */
-"VOICE_MESSAGE_FROM_USER" = "%@ ăăăéłćŁ°ăĄăă»ăŒăžăé俥";
+"VOICE_MESSAGE_FROM_USER" = "%@ăăăéłćŁ°ăĄăă»ăŒăžăé俥ăăŸăă";
/* New video message from a specific person, not referencing a room. */
-"VIDEO_FROM_USER" = "%@ ăăăćç»ăé俥";
+"VIDEO_FROM_USER" = "%@ăăăćç»ăé俥ăăŸăă";
/** Media Messages **/
/* New image message from a specific person, not referencing a room. */
-"PICTURE_FROM_USER" = "%@ ăăăćçăé俥";
+"PICTURE_FROM_USER" = "%@ăăăćçăé俥ăăŸăă";
/* A user added a Jitsi call to a room */
-"GROUP_CALL_STARTED" = "ă°ă«ăŒăé話ăéć§ăăăŸăă";
+"GROUP_CALL_STARTED" = "ă°ă«ăŒăé話ăéć§ăăŸăă";
/* A user's membership has updated in an unknown way */
-"USER_MEMBERSHIP_UPDATED" = "%@ ăăăăăŁăŒă«ăæŽæ°ăăŸăă";
+"USER_MEMBERSHIP_UPDATED" = "%@ăăăăăăăŁăŒă«ăæŽæ°ăăŸăă";
/* A user has change their avatar */
-"USER_UPDATED_AVATAR" = "%@ ăăąăăżăŒç»ćăć€æŽăăŸăă";
+"USER_UPDATED_AVATAR" = "%@ăăăăąăăżăŒăć€æŽăăŸăă";
/* A user has change their name to a new name which we don't know */
-"GENERIC_USER_UPDATED_DISPLAYNAME" = "%@ ăććăć€æŽăăŸăă";
+"GENERIC_USER_UPDATED_DISPLAYNAME" = "%@ăăăććăć€æŽăăŸăă";
/** Membership Updates **/
/* A user has change their name to a new name */
-"USER_UPDATED_DISPLAYNAME" = "%@ ăććă %@ ă«ć€æŽăăŸăă";
+"USER_UPDATED_DISPLAYNAME" = "%@ăăăććă%@ă«ć€æŽăăŸăă";
/* New file message from a specific person, not referencing a room. */
-"FILE_FROM_USER" = "%@ ăăăĄă€ă«ăé俥ăăŸăă: %@";
+"FILE_FROM_USER" = "%@ăăăĄă€ă«ăé俥ăăŸăăïŒ%@";
/* New audio message from a specific person, not referencing a room. */
-"AUDIO_FROM_USER" = "%@ ăéłćŁ°ăăĄă€ă«ăé俥ăăŸăă: %@";
+"AUDIO_FROM_USER" = "%@ăéłćŁ°ăăĄă€ă«ăé俥ăăŸăăïŒ%@";
+
+/* New voice broadcast from a specific person, not referencing a room. */
+"VOICE_BROADCAST_FROM_USER" = "%@ăăăéłćŁ°é
俥ăéć§ăăŸăă";
diff --git a/Riot/Assets/ja.lproj/Vector.strings b/Riot/Assets/ja.lproj/Vector.strings
index 9c76e1920b..30c415fd80 100644
--- a/Riot/Assets/ja.lproj/Vector.strings
+++ b/Riot/Assets/ja.lproj/Vector.strings
@@ -8,7 +8,7 @@
"view" = "èĄšç€ș";
"next" = "æŹĄăž";
"back" = "æ»ă";
-"continue" = "ç¶ăă";
+"continue" = "ç¶èĄ";
"create" = "äœæ";
"start" = "éć§";
"leave" = "éćș";
@@ -20,27 +20,27 @@
"cancel" = "ăăŁăłă»ă«";
"save" = "äżć";
"join" = "ćć ";
-"decline" = "æă";
-"accept" = "ćè«Ÿ";
+"decline" = "æćŠ";
+"accept" = "ćæ";
"preview" = "ăăŹăă„ăŒ";
"camera" = "ă«ăĄă©";
"voice" = "éłćŁ°";
"video" = "ćç»";
-"active_call" = "é話éć§";
-"active_call_details" = "é話éć§ïŒ%@ïŒ";
+"active_call" = "ćźæœäžăźé話";
+"active_call_details" = "ćźæœäžăźé話ïŒ%@ïŒ";
"later" = "ćŸă§";
"rename" = "ććć€æŽ";
"collapse" = "æăăăă";
-"send_to" = "%@ăăăžé俥";
-"sending" = "é俥äž";
+"send_to" = "%@ăžé俥";
+"sending" = "é俥ăăŠăăŸă";
// Authentication
"auth_login" = "ăă°ă€ăł";
-"auth_register" = "ć©çšè
ç»éČ";
+"auth_register" = "ç»éČ";
"auth_submit" = "ćè«Ÿ";
-"auth_skip" = "çă";
-"auth_send_reset_email" = "ćæćăĄăŒă«é俥";
-"auth_return_to_login" = "ăă°ă€ăłç»éąăžæ»ă";
-"auth_user_id_placeholder" = "ăŠăŒă¶ăŒćăŸăăŻé»ćăĄăŒă«";
+"auth_skip" = "ăčăăă";
+"auth_send_reset_email" = "ăȘă»ăăçšăĄăŒă«ăé俥";
+"auth_return_to_login" = "ăă°ă€ăłç»éąă«æ»ă";
+"auth_user_id_placeholder" = "é»ćăĄăŒă«ăŸăăŻăŠăŒă¶ăŒć";
"auth_password_placeholder" = "ăăčăŻăŒă";
"auth_new_password_placeholder" = "æ°ăăăăčăŻăŒă";
"auth_user_name_placeholder" = "ăŠăŒă¶ăŒć";
@@ -48,15 +48,15 @@
"auth_email_placeholder" = "ăĄăŒă«ăąăăŹăč";
"auth_optional_phone_placeholder" = "é»è©±çȘć·ïŒä»»æïŒ";
"auth_phone_placeholder" = "é»è©±çȘć·";
-"auth_repeat_password_placeholder" = "ăăčăŻăŒăćçąșèȘ";
-"auth_repeat_new_password_placeholder" = "æ°ăăăăčăŻăŒăăćçąșèȘ";
+"auth_repeat_password_placeholder" = "ăăčăŻăŒăăćçąșèȘ";
+"auth_repeat_new_password_placeholder" = "Matrixăąă«ăŠăłăăźæ°ăăăăčăŻăŒăăçąșèȘ";
"auth_home_server_placeholder" = "URL (äŸ https://matrix.org)";
"auth_identity_server_placeholder" = "URL (äŸ https://vector.im)";
-"auth_invalid_login_param" = "ăŠăŒă¶ăŒćăăăčăŻăŒăăæŁăăăăăŸăă";
-"auth_invalid_user_name" = "ăŠăŒă¶ăŒćăŻćè§è±æ°ćăăăăăăă€ăăłăăąăłăăčăłăąăźăżă§èšăăŠäžăă";
-"auth_invalid_password" = "ăăčăŻăŒăăçăăăŸă(æć°6æć)";
+"auth_invalid_login_param" = "ăŠăŒă¶ăŒćăšăăčăŻăŒăăźäžæčăăăăŻäžĄæčăæŁăăăăăŸăă";
+"auth_invalid_user_name" = "ăŠăŒă¶ăŒćă«ăŻćè§è±æ°ćăăăăăăă€ăăłăăąăłăăŒăčăłăąăźăżăäœżçšăăŠăă ăă";
+"auth_invalid_password" = "ăăčăŻăŒăăçăăăŸăïŒæć°6æćïŒ";
"auth_invalid_email" = "ăĄăŒă«ăąăăŹăčăźćœąćŒăæŁăăăăăŸăă";
-"auth_invalid_phone" = "æŁăăăȘăé»è©±çȘć·ăźăăă§ă";
+"auth_invalid_phone" = "é»è©±çȘć·ăźćœąćŒăæŁăăăăăŸăă";
"auth_missing_password" = "ăăčăŻăŒăăć
„ćăăăŠăăŸăă";
"auth_add_email_message" = "é»ćăĄăŒă«ăąăăŹăčăç»éČăăăš, èȘ°ăăăăȘăăæ€çŽąăăăă, ăăčăŻăŒăçŽć€±æă«ćæćăźăĄăŒă«ăéăăăšăă§ăăŸă.";
"auth_add_phone_message" = "é»è©±çȘć·ăç»éČăăăš, èȘ°ăăăăȘăăé»è©±çȘć·ă§æ€çŽąă§ăăăăă«ăȘăăŸă.";
@@ -67,38 +67,38 @@
"auth_missing_email_or_phone" = "ăĄăŒă«ăąăăŹăčăŸăăŻé»è©±çȘć·ăć
„ćăăăŠăăŸăă";
"auth_email_in_use" = "ăăźăĄăŒă«ăąăăŹăčăŻæąă«äœżçšăăăŠăăŸă";
"auth_phone_in_use" = "ăăźé»è©±çȘć·ăŻæąă«äœżçšăăăŠăăŸă";
-"auth_untrusted_id_server" = "ăăźèȘ蚌ă”ăŒăăŒăŻäżĄçšăăăŠăăŸăă";
+"auth_untrusted_id_server" = "ăăźèȘ蚌ă”ăŒăăŒăŻäżĄé ŒăăăŠăăŸăă";
"auth_password_dont_match" = "ăăčăŻăŒăăäžèŽăăŸăă";
"auth_username_in_use" = "ăŠăŒă¶ăŒćăŻæąă«äœżçšăăăŠăăŸă";
-"auth_forgot_password" = "ăăčăŻăŒăăćżăăŸăăăïŒ";
+"auth_forgot_password" = "Matrixăźăąă«ăŠăłăăźăăčăŻăŒăăćżăăŸăăăïŒ";
"auth_email_not_found" = "é»ćăĄăŒă«ăźé俥ă«ć€±æăăŸăăïŒăĄăŒă«ăąăăŹăčăèŠă€ăăăŸăă";
-"auth_use_server_options" = "æ„ç¶ć
ă”ăŒăăŒăæćźăăïŒèżœć èšćźïŒ";
-"auth_email_validation_message" = "ç»éČăç¶èĄăăă«ăŻé»ćăĄăŒă«ăçąșèȘăăŠäžăă";
-"auth_msisdn_validation_title" = "èȘ蚌ăçąșèȘäž";
-"auth_msisdn_validation_message" = "SMSă§èȘ蚌çȘć·ăéăăŸăăă仄äžă«ăăźçȘć·ăć
„ćăăŠăă ăăă";
+"auth_use_server_options" = "æ„ç¶ć
ă”ăŒăăŒăæćźïŒé«ćșŠïŒ";
+"auth_email_validation_message" = "ç»éČăç¶èĄăăă«ăŻé»ćăĄăŒă«ăçąșèȘăăŠăă ăă";
+"auth_msisdn_validation_title" = "èȘ蚌ăźäżçäž";
+"auth_msisdn_validation_message" = "SMSă§èȘ蚌ăłăŒăăéăăŸăăă仄äžă«ăłăŒăăć
„ćăăŠăă ăăă";
"auth_msisdn_validation_error" = "é»è©±çȘć·ăèȘ蚌ă§ăăŸăăă";
"auth_recaptcha_message" = "ăăźăăŒă ă”ăŒăăŒăŻăăăȘăăăăăăă§ăŻăȘăăăšăźçąșèȘăæ±ăăŠăăŸă";
-"auth_reset_password_message" = "Matrixăźăąă«ăŠăłăăźăăčăŻăŒăăćæćăăă«ăŻăăąă«ăŠăłăă«ç»éČăăăŠăăăĄăŒă«ăąăăŹăčăć
„ćăăŠăă ăăïŒ";
+"auth_reset_password_message" = "Matrixăźăąă«ăŠăłăăźăăčăŻăŒăăćèšćźăăă«ăŻăăąă«ăŠăłăă«ç»éČăăăŠăăăĄăŒă«ăąăăŹăčăć
„ćăăŠăă ăăïŒ";
"auth_reset_password_missing_email" = "ăăȘăăźăąă«ăŠăłăă«ç»éČăăăăĄăŒă«ăąăăŹăčăźć
„ćăćż
èŠă§ăă";
"auth_reset_password_missing_password" = "æ°ăăăăčăŻăŒăăźć
„ćăćż
èŠă§ăă";
-"auth_reset_password_email_validation_message" = "%@ ăžé»ćăĄăŒă«ăé俥ăăăŸăăăăȘăłăŻăăă©ăŁăă仄äžăăŻăȘăăŻăăŠăă ăăă";
-"auth_reset_password_next_step_button" = "ăĄăŒă«ăąăăŹăčăèȘ蚌ăăŸăă";
-"auth_reset_password_error_unauthorized" = "ăĄăŒă«ăąăăŹăčăźçąșèȘă«ć€±æăăŸăăïŒé»ćăĄăŒă«ăźăȘăłăŻăăŻăȘăăŻăăăăšăçąșèȘăăŠăă ăă";
-"auth_reset_password_error_not_found" = "ăăȘăăźăĄăŒă«ăąăăŹăčăŻăæ„ç¶ć
ă”ăŒăăŒäžăźMatrix IDăšéąéŁä»ăăăăŠăăȘăăăă§ăă";
-"auth_reset_password_success_message" = "ăăȘăăźăăčăŻăŒăăŻćæćăăăŸăăă\n\năăȘăăŻć
šăŠăźă»ăă·ă§ăłăăćæăăŠăăăăăă·ă„éç„ăćăćăăăšăŻăăăŸăăăéç„ăććșŠæćčă«ăăă«ăŻăćç«Żæ«ă«ććșŠăă°ă€ăłăăŸăă";
-"auth_add_email_and_phone_warning" = "é»ćăĄăŒă«ăšé»è©±çȘć·ăźćæç»éČăŻăăŸă ă·ăčăă ăćŻŸćżă§ăăŸăăăé»è©±çȘć·ă ăăźç»éČăŻćŻèœă§ăăăææ°ăăăăăŸăăăćŸă»ă©ćäșșæ
ć ±èšćźăăăĄăŒă«ăąăăŹăčăç»éČăăŠăă ăăă";
+"auth_reset_password_email_validation_message" = "%@ ăžé»ćăĄăŒă«ăé俥ăăŸăăăé»ćăĄăŒă«ć
ăźăȘăłăŻăéăăćŸă仄äžăăŻăȘăăŻăăŠăă ăăă";
+"auth_reset_password_next_step_button" = "ăĄăŒă«ăąăăŹăčăçąșèȘăăŸăă";
+"auth_reset_password_error_unauthorized" = "ăĄăŒă«ăąăăŹăčăźèȘ蚌ă«ć€±æăăŸăăăé»ćăĄăŒă«ć
ăźăȘăłăŻăéăăăăšăçąșèȘăăŠăă ăă";
+"auth_reset_password_error_not_found" = "ăăȘăăźăĄăŒă«ăąăăŹăčăŻăăăźăăŒă ă”ăŒăăŒäžăźMatrix IDăšéąéŁä»ăăăăŠăăȘăăăă§ăă";
+"auth_reset_password_success_message" = "ăăȘăăźMatrixăźăąă«ăŠăłăăźăăčăŻăŒăăŻćæćăăăŸăăă\n\nć
šăŠăźă»ăă·ă§ăłăăăă°ăąăŠăăăăăăăăă·ă„éç„ăŻé俥ăăăŸăăăéç„ăććșŠæćčă«ăăă«ăŻăćç«Żæ«ă§ććșŠăă°ă€ăłăăŠăă ăăă";
+"auth_add_email_and_phone_warning" = "é»ćăĄăŒă«ăšé»è©±çȘć·ăźäžĄæčă«ăăç»éČăŻăăŸă ă”ăăŒăăăŠăăŸăăăé»è©±çȘć·ăźăżă§ăźç»éČăćăä»ăăŠăăŸăăăĄăŒă«ăąăăŹăčăŻăèšćźć
ăźăăăăŁăŒă«ăăćŸă»ă©èżœć ă§ăăŸăă";
// Chat creation
"room_creation_title" = "ăăŁăăăéć§";
"room_creation_account" = "ăąă«ăŠăłă";
"room_creation_appearance" = "ć€èŠł";
"room_creation_appearance_name" = "ćć";
"room_creation_appearance_picture" = "ăăŁăăç»ćïŒä»»æïŒ";
-"room_creation_privacy" = "ćäșșæ
ć ±äżè·";
+"room_creation_privacy" = "ăă©ă€ăă·ăŒ";
"room_creation_private_room" = "ăăźäŒè©±ăŻéć
Źéă§ă";
"room_creation_public_room" = "ăăźäŒè©±ăŻć
ŹéăăăŠăăŸă";
"room_creation_make_public" = "ć
Źé";
"room_creation_make_public_prompt_title" = "ăăźăăŁăăăć
ŹéăăŸăăïŒ";
-"room_creation_make_public_prompt_msg" = "ăăźăăŁăăăć
ŹéăăŠăăăăăă§ăăïŒèȘ°ă§ăăăȘăăźăĄăă»ăŒăžăèȘăă§ăăŁăăă«ćć ă§ăăŸăă";
+"room_creation_make_public_prompt_msg" = "ăăźăăŁăăăć
ŹéăăŠăăăăă§ăăïŒèȘ°ă§ăăăȘăăźăĄăă»ăŒăžăèȘăżăăăŁăăă«ćć ă§ăăŸăă";
"room_creation_keep_private" = "éć
Źéă«äżă€";
"room_creation_make_private" = "éć
Źéă«ăă";
"room_creation_wait_for_creation" = "ă«ăŒă ăŻæąă«äœæăăăŠăăŸăăăćŸ
ăĄăă ăăă";
@@ -113,53 +113,53 @@
"room_recents_invites_section" = "æćŸ
äž";
"room_recents_start_chat_with" = "ăăŁăăăéć§";
"room_recents_create_empty_room" = "ă«ăŒă ăäœæ";
-"room_recents_join_room" = "ă«ăŒă ăžćć ";
-"room_recents_join_room_title" = "ă«ăŒă ăžćć ";
+"room_recents_join_room" = "ă«ăŒă ă«ćć ";
+"room_recents_join_room_title" = "ă«ăŒă ă«ćć ";
"room_recents_join_room_prompt" = "ă«ăŒă IDăŸăăŻă«ăŒă ăźăšă€ăȘăąăčăć
„ć";
// People tab
"people_invites_section" = "æćŸ
äž";
"people_conversation_section" = "äŒè©±";
-"people_no_conversation" = "äŒè©±ăȘă";
+"people_no_conversation" = "äŒè©±ăăăăŸăă";
// Rooms tab
"room_directory_no_public_room" = "ć©çšćŻèœăȘć
Źéă«ăŒă ăŻăăăŸăă";
// Search
"search_rooms" = "ă«ăŒă ";
"search_messages" = "ăĄăă»ăŒăž";
"search_people" = "éŁç”Ąć
";
-"search_files" = "æ·»ä»ăăĄă€ă«";
+"search_files" = "ăăĄă€ă«";
"search_default_placeholder" = "æ€çŽą";
"search_people_placeholder" = "ăŠăŒă¶ăŒIDăèĄšç€șćăé»ćăĄăŒă«ă§æ€çŽą";
-"search_no_result" = "ç”æăȘă";
+"search_no_result" = "ç”æăăăăŸăă";
"search_in_progress" = "æ€çŽąăăŠăăŸăâŠ";
// Directory
"directory_cell_title" = "ă«ăŒă äžèŠ§ăèŠă";
-"directory_cell_description" = "%tuă€ăźă«ăŒă ";
+"directory_cell_description" = "%tućăźă«ăŒă ";
"directory_search_results_title" = "ă«ăŒă äžèŠ§ăźæ€çŽąç”æ";
"directory_searching_title" = "ă«ăŒă äžèŠ§ăæ€çŽąăăŠăăŸăâŠ";
"directory_search_fail" = "äžèŠ§ăććŸă§ăăŸăăă§ăă";
// Contacts
"contacts_address_book_section" = "ç«Żæ«ăźé»è©±ćžł";
-"contacts_address_book_matrix_users_toggle" = "Matrixć©çšè
ăźăż";
-"contacts_address_book_no_contact" = "ç«Żæ«ć
é»è©±ćžłă«éŁç”Ąć
ăăăăŸăă";
-"contacts_address_book_permission_required" = "ç«Żæ«ć
é»è©±ćžłăžăźăąăŻă»ăčæš©éăćż
èŠă§ă";
+"contacts_address_book_matrix_users_toggle" = "MatrixăźăŠăŒă¶ăŒăźăż";
+"contacts_address_book_no_contact" = "ç«Żæ«ăźé»è©±ćžłă«éŁç”Ąć
ăăăăŸăă";
+"contacts_address_book_permission_required" = "ç«Żæ«ăźé»è©±ćžłăžăźăąăŻă»ăčæš©éăćż
èŠă§ă";
"contacts_user_directory_section" = "ăŠăŒă¶ăŒäžèŠ§";
-"contacts_user_directory_offline_section" = "ăŠăŒă¶ăŒäžèŠ§ (ăȘăă©ă€ăł)";
+"contacts_user_directory_offline_section" = "ăŠăŒă¶ăŒäžèŠ§ïŒăȘăă©ă€ăłïŒ";
// Chat participants
"room_participants_title" = "ćć è
";
"room_participants_add_participant" = "ćć è
ăèżœć ";
"room_participants_one_participant" = "ćć è
1ć";
"room_participants_multi_participants" = "ćć è
%dć";
-"room_participants_leave_prompt_title" = "ă«ăŒă ăéćș";
-"room_participants_leave_prompt_msg" = "ă«ăŒă ăéćșăăŠăăăăă§ăăïŒ";
+"room_participants_leave_prompt_title" = "ă«ăŒă ăăéćș";
+"room_participants_leave_prompt_msg" = "ă«ăŒă ăăéćșăăŠăăăăă§ăăïŒ";
"room_participants_remove_prompt_title" = "çąșèȘ";
-"room_participants_remove_prompt_msg" = "æŹćœă«%@ăăăŁăăăăéć»ăăăŸăăïŒ";
+"room_participants_remove_prompt_msg" = "%@ăăăŁăăăăèżœæŸăăŠăăăăă§ăăïŒ";
"room_participants_remove_third_party_invite_msg" = "ă”ăŒăăăŒăăŁăźæćŸ
ăćé€ăăăăšăŻăAPIăććšăăăŸă§ă”ăăŒăăăăŠăăŸăă";
"room_participants_invite_prompt_title" = "çąșèȘ";
-"room_participants_invite_prompt_msg" = "%@ăăăŁăăă«æćŸ
ăăŠăăăăă§ăăïŒ";
-"room_participants_filter_room_members" = "ă«ăŒă ăĄăłăăŒăæ€çŽą";
+"room_participants_invite_prompt_msg" = "%@ăăăźăăŁăăă«æćŸ
ăăŠăăăăă§ăăïŒ";
+"room_participants_filter_room_members" = "ă«ăŒă ăźăĄăłăăŒăæ€çŽą";
"room_participants_invite_another_user" = "ăŠăŒă¶ăŒIDăććăé»ćăĄăŒă«ă§æ€çŽąăæćŸ
";
"room_participants_invite_malformed_id_title" = "æćŸ
ăšă©ăŒ";
-"room_participants_invite_malformed_id" = "äžæŁăȘIDă§ăăăĄăŒă«ăąăăŹăčăçšăăăă'@localpart:domain'ăźăăăȘMatrix IDăäœżçšăăŠăă ăă";
+"room_participants_invite_malformed_id" = "äžæŁăȘIDă§ăăăĄăŒă«ăąăăŹăčăçšăăăă'@localpart:domain'ăźćœąćŒăźMatrix IDăäœżçšăăŠăă ăă";
"room_participants_invited_section" = "æćŸ
äž";
"room_participants_online" = "ăȘăłă©ă€ăł";
"room_participants_offline" = "ăȘăă©ă€ăł";
@@ -167,125 +167,125 @@
"room_participants_idle" = "ăąă€ăă«";
"room_participants_now" = "çŸćš";
"room_participants_ago" = "ć";
-"room_participants_action_section_admin_tools" = "知çè
æš©éæäœ";
-"room_participants_action_section_direct_chats" = "éć
ŹéăźăăŁăă";
-"room_participants_action_section_devices" = "ă»ăă·ă§ăłäžèŠ§";
+"room_participants_action_section_admin_tools" = "知çè
ăăŒă«";
+"room_participants_action_section_direct_chats" = "ăă€ăŹăŻăăĄăă»ăŒăž";
+"room_participants_action_section_devices" = "ă»ăă·ă§ăł";
"room_participants_action_section_other" = "ăȘăă·ă§ăł";
"room_participants_action_invite" = "æćŸ
";
-"room_participants_action_leave" = "ăăźă«ăŒă ăéćș";
-"room_participants_action_remove" = "ăăźă«ăŒă ăăćé€";
+"room_participants_action_leave" = "ăăźă«ăŒă ăăéćș";
+"room_participants_action_remove" = "ăăźă«ăŒă ăăèżœæŸ";
"room_participants_action_ban" = "ăăźă«ăŒă ăăăăăăŻ";
"room_participants_action_unban" = "ăăăăŻăè§Łé€";
-"room_participants_action_ignore" = "ăăźăŠăŒă¶ăŒăźçșèšăć
šăŠéèĄšç€șă«ăă";
-"room_participants_action_unignore" = "ăăźăŠăŒă¶ăŒăźçșèšăć
šăŠèĄšç€ș";
+"room_participants_action_ignore" = "ăăźăŠăŒă¶ăŒăźăĄăă»ăŒăžăć
šăŠéèĄšç€șă«ăă";
+"room_participants_action_unignore" = "ăăźăŠăŒă¶ăŒăźăĄăă»ăŒăžăć
šăŠèĄšç€ș";
"room_participants_action_set_default_power_level" = "æš©éăäžèŹăŠăŒă¶ăŒăžć€æŽ";
"room_participants_action_set_moderator" = "æš©éăăąăăŹăŒăżăŒăžć€æŽ";
"room_participants_action_set_admin" = "æš©éă知çè
ăžć€æŽ";
"room_participants_action_start_new_chat" = "ăăŁăăăéć§";
"room_participants_action_start_voice_call" = "éłćŁ°é話ăéć§";
-"room_participants_action_start_video_call" = "æ ćä»ăéłćŁ°é話ăéć§";
+"room_participants_action_start_video_call" = "ăăăȘé話ăéć§";
"room_participants_action_mention" = "ăĄăłă·ă§ăł";
// Chat
-"room_jump_to_first_unread" = "æćăźæȘèȘäœçœźăžç§»ć";
-"room_new_message_notification" = "%d件ăźæ°ăăçșèš";
-"room_new_messages_notification" = "%d件ăźæ°ăăçșèš";
-"room_one_user_is_typing" = "%@ăăăć
„ćăăŠăăŸăâŠ";
-"room_two_users_are_typing" = "%@ăăă%@ăăăć
„ćăăŠăăŸăâŠ";
-"room_many_users_are_typing" = "%@ăăă%@ăăä»ăć
„ćăăŠăăŸăâŠ";
-"room_message_placeholder" = "èżäżĄăéăïŒæȘæć·ćïŒâŠ";
-"encrypted_room_message_placeholder" = "æć·æăé俥âŠ";
-"room_message_short_placeholder" = "ăăă«é俥æăć
„ćâŠ";
+"room_jump_to_first_unread" = "ææ°ăźæȘèȘăžç§»ć";
+"room_new_message_notification" = "%d件ăźæ°ăăăĄăă»ăŒăž";
+"room_new_messages_notification" = "%d件ăźæ°ăăăĄăă»ăŒăž";
+"room_one_user_is_typing" = "%@ăć
„ćăăŠăăŸăâŠ";
+"room_two_users_are_typing" = "%@ăš%@ăć
„ćăăŠăăŸăâŠ";
+"room_many_users_are_typing" = "%@ă%@ä»ăć
„ćăăŠăăŸăâŠ";
+"room_message_placeholder" = "ăĄăă»ăŒăžăé俥ïŒæć·ćăăăŠăăŸăăïŒâŠ";
+"encrypted_room_message_placeholder" = "æć·ćăăăăĄăă»ăŒăžăé俥âŠ";
+"room_message_short_placeholder" = "ăĄăă»ăŒăžăé俥âŠ";
"room_offline_notification" = "ă”ăŒăăŒăšăźæ„ç¶ă怱ăăăŸăăă";
"room_unsent_messages_notification" = "ăĄăă»ăŒăžăé俥ă§ăăŸăăă§ăăă";
-"room_unsent_messages_unknown_devices_notification" = "æȘç„ăźă»ăă·ă§ăłăććšăăăăă«æç« ăé俥ăăăŸăăă§ăăă";
-"room_ongoing_conference_call" = "äŒè°é話ćźæœäžă%@ăŸăăŻ%@ă§ćć ăăŠăă ăăă";
-"room_ongoing_conference_call_with_close" = "äŒè°é話ćźæœäžă%@ăŸăăŻ%@ă§ćć ăăŠăă ăăă%@ă";
+"room_unsent_messages_unknown_devices_notification" = "äžæăȘă»ăă·ă§ăłăććšăăăăăăĄăă»ăŒăžăźé俥ă«ć€±æăăŸăăă";
+"room_ongoing_conference_call" = "ă°ă«ăŒăé話ăćźæœäžă%@ăŸăăŻ%@ă§ćć ăăŠăă ăăă";
+"room_ongoing_conference_call_with_close" = "ă°ă«ăŒăé話ăćźæœäžă%@ăŸăăŻ%@ă§ćć ăăŠăă ăăă%@ă";
"room_ongoing_conference_call_close" = "éăă";
-"room_conference_call_no_power" = "ăăźă«ăŒă ă§äŒè°é話ă知çăăæš©éăćż
èŠă§ă";
+"room_conference_call_no_power" = "ăăźă«ăŒă ă§ă°ă«ăŒăé話ă知çăăăăăźæš©éăćż
èŠă§ă";
"room_prompt_resend" = "ć
šăŠćé俥";
-"room_prompt_cancel" = "ć
šăŠäžæą";
-"room_resend_unsent_messages" = "æȘé俥ăźæăćé俥";
-"room_delete_unsent_messages" = "æȘé俥ăźæăćé€";
+"room_prompt_cancel" = "ć
šăŠăăŁăłă»ă«";
+"room_resend_unsent_messages" = "æȘé俥ăźăĄăă»ăŒăžăćé俥";
+"room_delete_unsent_messages" = "æȘé俥ăźăĄăă»ăŒăžăćé€";
"room_event_action_copy" = "ăłăăŒ";
"room_event_action_quote" = "ćŒçš";
"room_event_action_redact" = "ćé€";
-"room_event_action_more" = "ăăă«";
+"room_event_action_more" = "ăăźä»";
"room_event_action_share" = "ć
±æ";
"room_event_action_permalink" = "ăĄăă»ăŒăžăžăźăȘăłăŻăăłăăŒ";
-"room_event_action_view_source" = "ăœăŒăčăèĄšç€ș";
-"room_event_action_report" = "çșèšăć ±ć";
-"room_event_action_report_prompt_reason" = "ăăźçșèšăć ±ćăăçç±";
+"room_event_action_view_source" = "ăœăŒăčăłăŒăăèĄšç€ș";
+"room_event_action_report" = "ăłăłăăłăăć ±ć";
+"room_event_action_report_prompt_reason" = "ăăźăłăłăăłăăć ±ćăăçç±";
"room_event_action_report_prompt_ignore_user" = "ăăźăŠăŒă¶ăŒăăăźć
šăŠăźçșèšăéèĄšç€șă«ăăŸăăïŒ";
"room_event_action_save" = "äżć";
"room_event_action_resend" = "ćé俥";
"room_event_action_delete" = "ćé€";
-"room_event_action_cancel_send" = "é俥äžæą";
-"room_event_action_cancel_download" = "ăăŠăłăăŒăäžæą";
-"room_event_action_view_encryption" = "æć·ă«ă€ăăŠăźæ
ć ±";
-"room_warning_about_encryption" = "ăšăłăăăŒăšăłăæć·ćăŻăăŒăżçă§ăăăäżĄé Œæ§ăäœăć ŽćăăăăŸăă\n\nçșèšăäżè·ăăăăă«ăŻăŸă 俥çšăăčăă§ăŻăăăŸăăă\n\nç«Żæ«ăćć ăăăăćăźçșèšć±„æŽăćŸ©ć·ćăăăăšăŻăŸă ă§ăăŸăăă\n\næć·ćăăăçșèšăŻăăŸă æć·ćăćźèŁ
ăăŠăăȘăăŻă©ă€ăąăłăă§ăŻèĄšç€șăăăŸăăă";
-"room_event_failed_to_send" = "é俥怱æ";
+"room_event_action_cancel_send" = "é俥ăăăŁăłă»ă«";
+"room_event_action_cancel_download" = "ăăŠăłăăŒăăăăŁăłă»ă«";
+"room_event_action_view_encryption" = "æć·ćă«ă€ăăŠăźæ
ć ±";
+"room_warning_about_encryption" = "ăšăłăăăŒăšăłăæć·ćăŻăăŒăżçăźăăăäżĄé Œæ§ăäœăć ŽćăăăăŸăă\n\năăŒăżăäżè·ăăăăă«ăŻăŸă 俥çšăăčăă§ăŻăăăŸăăă\n\nç«Żæ«ăćć ăă仄ćăźć±„æŽăćŸ©ć·ćăăăăšăŻăŸă ă§ăăŸăăă\n\næć·ćăăăăĄăă»ăŒăžăŻăæć·ćăćźèŁ
ăăŠăăȘăăŻă©ă€ăąăłăă§ăŻèĄšç€șă§ăăŸăăă";
+"room_event_failed_to_send" = "é俥ă«ć€±æăăŸăă";
// Unknown devices
-"unknown_devices_alert_title" = "ă«ăŒă ă«æȘç„ăźă»ăă·ă§ăłăććšăăŸă";
-"unknown_devices_alert" = "ăăźă«ăŒă ă«ăŻăçąșèȘăăăŠăăȘăæȘç„ăźă»ăă·ă§ăłăć«ăŸăăŠăăŸăă\năăȘăăĄăă»ăă·ă§ăłăăăŠăŒă¶ăŒæŹäșșăææăăŠăăăšăăäżèšŒăŻăăăŸăăă\nç¶ăăćă«ćă»ăă·ă§ăłăźçąșèȘăèĄăăăšăăăăăăăŸăăăçąșèȘăăăăšăȘăçșèšăćé俥ăăăăšăă§ăăŸăă";
-"unknown_devices_send_anyway" = "ăšă«ăăéă";
-"unknown_devices_call_anyway" = "ăšă«ăăé話";
-"unknown_devices_answer_anyway" = "ăšă«ăăćżç";
-"unknown_devices_verify" = "çąșèȘâŠ";
-"unknown_devices_title" = "æȘç„ăźă»ăă·ă§ăł";
+"unknown_devices_alert_title" = "ă«ăŒă ă«äžæăȘă»ăă·ă§ăłăććšăăŸă";
+"unknown_devices_alert" = "ăăźă«ăŒă ă«ăŻăæȘèȘ蚌ăźă»ăă·ă§ăłăć«ăŸăăŠăăŸăă\nă»ăă·ă§ăłăăŠăŒă¶ăŒæŹäșșăææăăŠăăăšăăäżèšŒăŻăăăŸăăă\nç¶èĄăăćă«ćă»ăă·ă§ăłăźèȘ蚌ăèĄăăăšăæšć„šăăŸăăăèȘ蚌ăăăĄăă»ăŒăžăćé俥ăăăăšăă§ăăŸăă";
+"unknown_devices_send_anyway" = "é俥";
+"unknown_devices_call_anyway" = "é話";
+"unknown_devices_answer_anyway" = "ćżç";
+"unknown_devices_verify" = "èȘ蚌âŠ";
+"unknown_devices_title" = "äžæăȘă»ăă·ă§ăł";
// Room Title
"room_title_new_room" = "æ°ăăă«ăŒă ";
"room_title_multiple_active_members" = "ć
š%@äșșäž%@äșșăćç·æ„ç¶";
"room_title_one_active_member" = "ć
š%@äșșäž%@äșșăćç·æ„ç¶";
-"room_title_invite_members" = "æćŸ
äž";
-"room_title_members" = "%@ćăźăĄăłăăŒ";
-"room_title_one_member" = "1ćăźăĄăłăăŒ";
+"room_title_invite_members" = "ăĄăłăăŒăæćŸ
";
+"room_title_members" = "%@äșșăźăĄăłăăŒ";
+"room_title_one_member" = "1äșșăźăĄăłăăŒ";
// Room Preview
-"room_preview_invitation_format" = "ăăȘăăŻ%@ăăă«ćŒă°ăăŠăăźă«ăŒă ăžćć ăăŸăă";
+"room_preview_invitation_format" = "%@ăăăȘăăăăźă«ăŒă ă«æćŸ
ăăŸăăă";
"room_preview_subtitle" = "çŸćšèĄšç€șăăŠăăăźăŻă«ăŒă ăźăăŹăă„ăŒă§ăăăĄăă»ăŒăžăźé俥ăȘă©ăŻèĄăăŸăăă";
-"room_preview_unlinked_email_warning" = "ăăźăąă«ăŠăłăă«éąéŁä»ăăăăŠăăȘă%@ćźă«æćŸ
ăé俥ăăăŸăăăć„ăźăąă«ăŠăłăă§ăă°ă€ăłăăăăăĄăŒă«ăąăăŹăčăăăźăąă«ăŠăłăă«èżœć ăăăăšăă§ăăŸăă";
-"room_preview_try_join_an_unknown_room" = "%@ ă«ćć ăăŸăăïŒ";
+"room_preview_unlinked_email_warning" = "ăăźæćŸ
ăŻăăăźăąă«ăŠăłăă«éąéŁä»ăăăăŠăăȘă%@ă«é俥ăăăŸăăăć„ăźăąă«ăŠăłăă§ăă°ă€ăłăăăăăăźăĄăŒă«ăąăăŹăčăèȘćăźăąă«ăŠăłăă«èżœć ăăŠăă ăăă";
+"room_preview_try_join_an_unknown_room" = "%@ă«ăąăŻă»ăčăăăăšăăŠăăŸăăăăźäŒè©±ă«ćć ăăŸăăïŒ";
"room_preview_try_join_an_unknown_room_default" = "ă«ăŒă ";
// Settings
"settings_title" = "èšćź";
-"account_logout_all" = "ć
šăŠăźăąă«ăŠăłăăćç·ćæ";
+"account_logout_all" = "ć
šăŠăźăąă«ăŠăłăăăă°ăąăŠă";
"settings_config_no_build_info" = "ăă«ăæ
ć ±ăăăăŸăă";
-"settings_mark_all_as_read" = "ć
šăŠăźçșèšăæąèȘă«ăă";
+"settings_mark_all_as_read" = "ć
šăŠăźăĄăă»ăŒăžăæąèȘă«ăă";
"settings_report_bug" = "ăă°ăŹăăŒă";
-"settings_config_home_server" = "æ„ç¶ć
ă”ăŒăăŒăŻ %@";
-"settings_config_identity_server" = "èȘ蚌ă”ăŒă㯠%@";
+"settings_config_home_server" = "ăăŒă ă”ăŒăăŒăŻ %@ ă§ă";
+"settings_config_identity_server" = "IDă”ăŒăăŒïŒ%@";
"settings_config_user_id" = "%@ă§ăă°ă€ăłăăŠăăŸă";
-"settings_user_settings" = "ć©çšè
èšćź";
+"settings_user_settings" = "ăŠăŒă¶ăŒèšćź";
"settings_notifications_settings" = "éç„èšćź";
"settings_calls_settings" = "é話";
"settings_user_interface" = "ç«Żæ«æäœèĄšç€ș";
-"settings_ignored_users" = "çĄèŠăăçžæ";
-"settings_contacts" = "ç«Żæ«ăźé»è©±ćžł";
-"settings_advanced" = "æĄćŒ”èšćź";
+"settings_ignored_users" = "çĄèŠăăŠăăăŠăŒă¶ăŒ";
+"settings_contacts" = "ç«Żæ«ăźéŁç”Ąć
";
+"settings_advanced" = "é«ćșŠăȘèšćź";
"settings_other" = "ăăźä»";
-"settings_labs" = "ćźéšç";
+"settings_labs" = "ă©ă";
"settings_devices" = "ă»ăă·ă§ăł";
"settings_cryptography" = "æć·ć";
"settings_sign_out" = "ă”ă€ăłăąăŠă";
-"settings_sign_out_confirmation" = "æŹćœă«ăăăăă§ăăïŒ";
-"settings_sign_out_e2e_warn" = "ăăȘăăŻăšăłăăăŒăšăłăæć·é”ă怱ăŁăŠăăŸăăŸăăăăźç«Żæ«ă§æć·ćăăăă«ăŒă ăźæăźçșèšăèȘăăăšăă§ăăȘăăȘăăŸăă";
+"settings_sign_out_confirmation" = "ăăăăă§ăăïŒ";
+"settings_sign_out_e2e_warn" = "ăšăłăăăŒăšăłăæć·é”ăæ¶ć»ăăăŸăăăăźç«Żæ«ă§ăŻăæć·ćăăăă«ăŒă ăźéć»ăźăĄăă»ăŒăžăèȘăăăšăă§ăăȘăăȘăŁăŠăăŸăăŸăă";
"settings_profile_picture" = "ăăăăŁăŒă«ç»ć";
"settings_display_name" = "èĄšç€șć";
"settings_first_name" = "ć";
"settings_surname" = "ć§";
"settings_remove_prompt_title" = "çąșèȘ";
-"settings_remove_email_prompt_msg" = "ăĄăŒă«ăąăăŹăč %@ ăæŹćœă«ćé€ăăŠăăăăă§ăăïŒ";
-"settings_remove_phone_prompt_msg" = "é»è©±çȘć· %@ ăæŹćœă«ćé€ăăŠăăăăă§ăăïŒ";
-"settings_email_address" = "é»ćăĄăŒă«";
+"settings_remove_email_prompt_msg" = "ăĄăŒă«ăąăăŹăč %@ ăćé€ăăŠăăăăă§ăăïŒ";
+"settings_remove_phone_prompt_msg" = "é»è©±çȘć· %@ ăćé€ăăŠăăăăă§ăăïŒ";
+"settings_email_address" = "ăĄăŒă«ăąăăŹăč";
"settings_email_address_placeholder" = "ăăȘăăźăĄăŒă«ăąăăŹăčăć
„ćăăŠăă ăă";
"settings_add_email_address" = "ăĄăŒă«ăąăăŹăčăèżœć ";
"settings_phone_number" = "é»è©±çȘć·";
"settings_add_phone_number" = "é»è©±çȘć·ăèżœć ";
"settings_night_mode" = "ć€éăăăăżăąăŒă";
-"settings_fail_to_update_profile" = "èȘć·±çŽčä»èšćźăźæŽæ°ă«ć€±æăăŸăă";
+"settings_fail_to_update_profile" = "ăăăăŁăŒă«ăźæŽæ°ă«ć€±æăăŸăă";
"settings_enable_push_notif" = "ăăźç«Żæ«ă§ăźéç„";
-"settings_show_decrypted_content" = "ćŸ©ć·ćăăăæç« ăèĄšç€ș";
-"settings_global_settings_info" = "ăăȘăăź%@ webăŻă©ă€ăąăłăäžă§ăć
šäœăźéç„èšćźăćŻèœă§ă";
-"settings_pin_rooms_with_missed_notif" = "éăăéç„ăăăă«ăŒă ăćșćź";
+"settings_show_decrypted_content" = "ćŸ©ć·ćăăăć
ćźčăèĄšç€ș";
+"settings_global_settings_info" = "ć
šäœăźéç„èšćźăŻ %@ webăŻă©ă€ăąăłăă§èĄăăŸă";
+"settings_pin_rooms_with_missed_notif" = "éăăéç„ăăăă«ăŒă ăăăłæąă";
"settings_ui_language" = "èšèȘ";
"settings_ui_theme" = "ć€èŠł";
"settings_ui_theme_auto" = "èȘć";
@@ -293,110 +293,110 @@
"settings_ui_theme_dark" = "ăăŒăŻ";
"settings_ui_theme_picker_title" = "ć€èŠłăéžæ";
"settings_ui_theme_picker_message" = "èČćè»ąèšćźăźç«Żæ«ă§ăŻăăèȘćăăäœżăŁăŠăă ăă";
-"settings_unignore_user" = "%@ăăăăăźăĄăă»ăŒăžăèŠăŸăăïŒ";
+"settings_unignore_user" = "%@ăăăăăźăĄăă»ăŒăžăèĄšç€șăăŸăăïŒ";
"settings_contacts_discover_matrix_users" = "é»ćăĄăŒă«ăšé»è©±çȘć·ăăŠăŒă¶ăźæ€çŽąă«äœżçš";
"settings_contacts_phonebook_country" = "é»è©±ćžłăźćœçȘć·";
"settings_labs_e2e_encryption" = "ăšăłăăăŒăšăłăæć·ć";
-"settings_labs_e2e_encryption_prompt_message" = "æć·ćăźèšćźăćźäșăăăăă«ăŻććșŠăă°ă€ăłăăŠăă ăăă";
+"settings_labs_e2e_encryption_prompt_message" = "æć·ćăźèšćźăćźäșăăă«ăŻăććșŠăă°ă€ăłăăŠăă ăăă";
"settings_labs_matrix_apps" = "MatrixăąăăȘ";
-"settings_labs_create_conference_with_jitsi" = "jitsiăźäŒè°é話ăäœæ";
+"settings_labs_create_conference_with_jitsi" = "Jitsiă§äŒè°é話ăäœæ";
"settings_version" = "ăăŒăžă§ăł %@";
-"settings_olm_version" = "OlmăăŒăžă§ăł %@";
+"settings_olm_version" = "OlmăźăăŒăžă§ăł %@";
"settings_copyright" = "èäœæš©";
"settings_term_conditions" = "ć©çšèŠçŽ";
-"settings_privacy_policy" = "ćäșșæ
ć ±äżè·æčé";
-"settings_third_party_notices" = "ć€éšă©ă€ăă©ăȘăźèŠçŽ";
+"settings_privacy_policy" = "ăă©ă€ăă·ăŒăăȘă·ăŒ";
+"settings_third_party_notices" = "ć€éšă©ă€ăă©ăȘăŒăźă©ă€ă»ăłăč";
"settings_send_crash_report" = "ćżćć©çšç¶æłăšèȘ€ćäœæ
ć ±ăé俥";
-"settings_enable_rageshake" = "ăă°ăŹăăŒăăźăăç«Żæ«ăæŻă";
-"settings_clear_cache" = "äžæäżćăæ¶ć»";
-"settings_change_password" = "ăăčăŻăŒăć€æŽ";
-"settings_old_password" = "ä»ăŸă§ăźăăčăŻăŒă";
+"settings_enable_rageshake" = "ç«Żæ«ăæŻăŁăŠäžć
·ćăć ±ć";
+"settings_clear_cache" = "ăăŁăă·ă„ăæ¶ć»";
+"settings_change_password" = "ăăčăŻăŒăăć€æŽ";
+"settings_old_password" = "仄ćăźăăčăŻăŒă";
"settings_new_password" = "æ°ăăăăčăŻăŒă";
-"settings_confirm_password" = "ăăčăŻăŒăçąșèȘ";
-"settings_fail_to_update_password" = "ăăčăŻăŒăăźæŽæ°ă«ć€±æăăŸăă";
-"settings_password_updated" = "ăăȘăăźăăčăŻăŒăăŻæŽæ°ăăăŸăă";
-"settings_crypto_device_name" = "ă»ăă·ă§ăłć: ";
-"settings_crypto_device_id" = "\nă»ăă·ă§ăłID: ";
-"settings_crypto_device_key" = "\nă»ăă·ă§ăłăăŒ:\n";
+"settings_confirm_password" = "ăăčăŻăŒăăçąșèȘ";
+"settings_fail_to_update_password" = "Matrixăźăąă«ăŠăłăăźăăčăŻăŒăăźæŽæ°ă«ć€±æăăŸăă";
+"settings_password_updated" = "Matrixăźăąă«ăŠăłăăźăăčăŻăŒăăæŽæ°ăăŸăă";
+"settings_crypto_device_name" = "ă»ăă·ă§ăłćïŒ ";
+"settings_crypto_device_id" = "\nă»ăă·ă§ăłIDïŒ ";
+"settings_crypto_device_key" = "\nă»ăă·ă§ăłăăŒïŒ\n";
"settings_crypto_export" = "é”ăăšăŻăčăăŒă";
-"settings_crypto_blacklist_unverified_devices" = "èȘ蚌ăăăă»ăă·ă§ăłăźăżă§æć·ć";
+"settings_crypto_blacklist_unverified_devices" = "èȘ蚌æžăźă»ăă·ă§ăłă«ăźăżæć·ć";
// Room Details
"room_details_title" = "ă«ăŒă ăźè©łçŽ°";
"room_details_people" = "ăĄăłăăŒ";
"room_details_files" = "ăąăăăăŒă";
"room_details_settings" = "èšćź";
-"room_details_photo" = "ă«ăŒă ăźăąă€ăłăłç»ć";
+"room_details_photo" = "ă«ăŒă ăźç»ć";
"room_details_room_name" = "ă«ăŒă ć";
"room_details_topic" = "ăăăăŻ";
"room_details_favourite_tag" = "ăæ°ă«ć
„ă";
"room_details_low_priority_tag" = "äœćȘć
ćșŠ";
-"room_details_mute_notifs" = "çșèšăăăŁăŠăéç„ăăȘă";
-"room_details_direct_chat" = "ćŻŸè©±";
+"room_details_mute_notifs" = "éç„ăăă„ăŒă";
+"room_details_direct_chat" = "ăă€ăŹăŻăăĄăă»ăŒăž";
"room_details_access_section" = "ăăźă«ăŒă ă«ăąăŻă»ăčă§ăăäșșăŻïŒ";
"room_details_access_section_invited_only" = "æćŸ
ăăăäșșăźăż";
"room_details_access_section_anyone_apart_from_guest" = "ă«ăŒă ăźăȘăłăŻăç„ăŁăŠăăäșșăȘăèȘ°ă§ăïŒăČăčăăŠăŒă¶ăŒăé€ăïŒ";
"room_details_access_section_anyone" = "ă«ăŒă ăźăȘăłăŻăç„ăŁăŠăăäșșăȘăèȘ°ă§ăïŒăČăčăăŠăŒă¶ăŒăć«ăïŒ";
"room_details_access_section_no_address_warning" = "ăăźă«ăŒă ăžăźăȘăłăŻăäœæăăă«ăŻăă«ăŒă ăźăąăăŹăčăćż
èŠă§ă";
-"room_details_access_section_directory_toggle" = "ă«ăŒă äžèŠ§ăžć
Źé";
-"room_details_history_section" = "çșèšć±„æŽăéČ芧ă§ăăäșș";
+"room_details_access_section_directory_toggle" = "ăăźă«ăŒă ăă«ăŒă äžèŠ§ă«æČèŒ";
+"room_details_history_section" = "汄æŽăéČ芧ă§ăăäșșăŻïŒ";
"room_details_history_section_anyone" = "èȘ°ă§ă";
-"room_details_history_section_members_only" = "ăĄăłăăŒăźăż (ăăźèšćźăéžæăăæçčăă)";
+"room_details_history_section_members_only" = "ăĄăłăăŒăźăżïŒăăźèšćźăéžæăăæçčăăïŒ";
"room_details_history_section_members_only_since_invited" = "ăĄăłăăŒăźăżïŒæćŸ
ăéăŁăæçčăăïŒ";
-"room_details_history_section_members_only_since_joined" = "ăĄăłăăŒăźăż (ćć ăăæçčăă)";
-"room_details_history_section_prompt_title" = "ćäșșæ
ć ±ăźèŠć";
-"room_details_history_section_prompt_msg" = "çșèšć±„æŽăèȘăăăšăă§ăăäșșăźć€æŽăŻă仄ćŸăźçșèšă«ăźăżé©çšăăăŸăăæąćăźçșèšć±„æŽăźćŻèŠæ§ăŻć€æŽăăăŸăăă";
+"room_details_history_section_members_only_since_joined" = "ăĄăłăăŒăźăżïŒćć ăăæçčăăïŒ";
+"room_details_history_section_prompt_title" = "ăă©ă€ăă·ăŒă«éąăăèŠć";
+"room_details_history_section_prompt_msg" = "汄æŽăźéČ芧暩éă«éąăăć€æŽăŻăä»ćŸăăăźă«ăŒă ă§èĄšç€șăăăăĄăă»ăŒăžă«ăźăżé©çšăăăŸăăæąćăźć±„æŽăźèŠăæčă«ăŻćœ±éżăăŸăăă";
"room_details_addresses_section" = "ăąăăŹăč";
"room_details_no_local_addresses" = "ăăźă«ăŒă ă«ăŻăăŒă«ă«ăąăăŹăčăăăăŸăă";
"room_details_new_address" = "æ°ăăăąăăŹăčăèżœć ";
"room_details_new_address_placeholder" = "æ°ăăăąăăŹăčăèżœć ïŒäŸ #foo%@ïŒ";
-"room_details_addresses_invalid_address_prompt_title" = "äžæŁăȘăšă€ăȘăąăčăźăă©ăŒăăă";
-"room_details_addresses_invalid_address_prompt_msg" = "%@ăŻăšă€ăȘăąăčăźæŁăăăă©ăŒăăăă§ăŻăăăŸăă";
+"room_details_addresses_invalid_address_prompt_title" = "ăšă€ăȘăąăčăźćœąćŒăæŁăăăăăŸăă";
+"room_details_addresses_invalid_address_prompt_msg" = "%@ăŻăšă€ăȘăąăčăźæŁăăćœąćŒă§ăŻăăăŸăă";
"room_details_addresses_disable_main_address_prompt_title" = "ăĄă€ăłăąăăŹăčăźèŠć";
-"room_details_addresses_disable_main_address_prompt_msg" = "ăĄă€ăłăąăăŹăčăèšćźăăăŠăăŸăăăăăźă«ăŒă ăźăĄă€ăłăąăăŹăčăŻçĄäœçșă«éžæăèšćźăăăŸă";
+"room_details_addresses_disable_main_address_prompt_msg" = "ăĄă€ăłăąăăŹăčăèšćźăăăŠăăŸăăăăăźă«ăŒă ăźăĄă€ăłăąăăŹăčăŻă©ăłăă ă«èšćźăăăŸă";
"room_details_banned_users_section" = "ăăăăŻăăăăŠăŒă¶ăŒ";
-"room_details_advanced_section" = "æĄćŒ”èšćź";
-"room_details_advanced_room_id" = "ă«ăŒă ăźćșæID:";
-"room_details_advanced_enable_e2e_encryption" = "æć·ćăæćčă«ăăïŒèŠć: æćčćŸă«ăăăçĄćčă«ăăăăšăŻă§ăăŸăăïŒ)";
-"room_details_advanced_e2e_encryption_enabled" = "ăăźă«ăŒă ăźçșèšăŻæć·ćăăăŠăăŸă";
-"room_details_advanced_e2e_encryption_disabled" = "ăăźă«ăŒă ăźçșèšăŻæć·ćăăăŠăăŸăăă";
-"room_details_advanced_e2e_encryption_blacklist_unverified_devices" = "èȘ蚌ăăăă»ăă·ă§ăłăźăżă§æć·ć";
+"room_details_advanced_section" = "é«ćșŠăȘèšćź";
+"room_details_advanced_room_id" = "ă«ăŒă IDïŒ";
+"room_details_advanced_enable_e2e_encryption" = "æć·ćăæćčă«ăăïŒèŠćïŒæćčă«ăăćŸă«çĄćčă«ăăăăšăŻă§ăăŸăăïŒ)";
+"room_details_advanced_e2e_encryption_enabled" = "ăăźă«ăŒă ă§ăŻæć·ćăæćčă§ă";
+"room_details_advanced_e2e_encryption_disabled" = "ăăźă«ăŒă ă§ăŻæć·ćăæćčă§ăŻăăăŸăăă";
+"room_details_advanced_e2e_encryption_blacklist_unverified_devices" = "èȘ蚌æžăźă»ăă·ă§ăłă«ăźăżæć·ć";
"room_details_fail_to_update_avatar" = "ă«ăŒă ăźăąă€ăłăłç»ćăźæŽæ°ă«ć€±æ";
"room_details_fail_to_update_room_name" = "ă«ăŒă ćăźæŽæ°ă«ć€±æ";
-"room_details_fail_to_update_topic" = "ă«ăŒă ăźèȘŹæăźæŽæ°ă«ć€±æ";
+"room_details_fail_to_update_topic" = "ăăăăŻăźæŽæ°ă«ć€±æ";
"room_details_fail_to_update_room_guest_access" = "ăČăčăă«ăăă«ăŒă ăžăźăąăŻă»ăčăźèšćźæŽæ°ă«ć€±æ";
"room_details_fail_to_update_room_join_rule" = "ćć ă«ăŒă«ăźæŽæ°ă«ć€±æ";
-"room_details_fail_to_update_room_directory_visibility" = "ă«ăŒă äžèŠ§ăźćŻèŠèšćźăźæŽæ°ă«ć€±æ";
-"room_details_fail_to_update_history_visibility" = "çșèšć±„æŽăźćŻèŠçŻćČăźèšćźæŽæ°ă«ć€±æ";
+"room_details_fail_to_update_room_directory_visibility" = "ă«ăŒă äžèŠ§ăźèŠăæčăźæŽæ°ă«ć€±æ";
+"room_details_fail_to_update_history_visibility" = "汄æŽăźèŠăæčăźèšćźæŽæ°ă«ć€±æ";
"room_details_fail_to_add_room_aliases" = "æ°ăăă«ăŒă ăąăăŹăčăźèżœć ă«ć€±æ";
"room_details_fail_to_remove_room_aliases" = "ă«ăŒă ăąăăŹăčăźćé€ă«ć€±æ";
"room_details_fail_to_update_room_canonical_alias" = "ăĄă€ăłăąăăŹăčăźæŽæ°ă«ć€±æ";
-"room_details_fail_to_update_room_direct" = "ă«ăŒă ăźćŻŸè©±ăżă°ăźć€æŽă«ć€±æ";
-"room_details_fail_to_enable_encryption" = "ă«ăŒă ăźæć·ćăźéć§ă«ć€±æ";
+"room_details_fail_to_update_room_direct" = "ăăźă«ăŒă ăźăă€ăŹăŻăăă©ă°ăźăąăăăăŒăă«ć€±æ";
+"room_details_fail_to_enable_encryption" = "ăăźă«ăŒă ăźæć·ćăźæćčćă«ć€±æ";
"room_details_save_changes_prompt" = "ć€æŽăäżćăăŸăăïŒ";
-"room_details_set_main_address" = "ăĄă€ăłăąăăŹăčăèšćź";
+"room_details_set_main_address" = "ăĄă€ăłăąăăŹăčă«èšćź";
"room_details_unset_main_address" = "ăĄă€ăłăąăăŹăčăźèšćźăè§Łé€";
-"room_details_copy_room_id" = "ă«ăŒă ćșæIDăăłăăŒ";
+"room_details_copy_room_id" = "ă«ăŒă IDăăłăăŒ";
"room_details_copy_room_address" = "ă«ăŒă ăźăąăăŹăčăăłăăŒ";
"room_details_copy_room_url" = "ă«ăŒă ăźURLăăłăăŒ";
// Read Receipts
"read_receipts_list" = "æąèȘäžèŠ§ăèŠă";
"receipt_status_read" = "æąèȘç¶æłïŒ ";
// Media picker
-"media_picker_library" = "ă©ă€ăă©ăȘ";
+"media_picker_library" = "ă©ă€ăă©ăȘăŒ";
"media_picker_select" = "éžæ";
// Directory
"directory_title" = "ă«ăŒă äžèŠ§";
-"directory_server_picker_title" = "ă«ăŒă äžèŠ§ăéžæ";
-"directory_server_all_rooms" = "%@ ă”ăŒăăŒäžăźć
šăŠăźă«ăŒă ";
+"directory_server_picker_title" = "ă«ăŒă ăăŁăŹăŻăăȘăŒăéžæ";
+"directory_server_all_rooms" = "%@ă”ăŒăăŒäžăźć
šăŠăźă«ăŒă ";
"directory_server_all_native_rooms" = "ć
šăŠăźMatrixéŁæșă«ăŒă ";
-"directory_server_type_homeserver" = "ć
Źéă«ăŒă äžèŠ§ăèĄšç€șăăăăăźæ„ç¶ă”ăŒăăŒăć
„ćăăŠăă ăă";
+"directory_server_type_homeserver" = "ć
Źéă«ăŒă ăźäžèŠ§ăèĄšç€șăăăăŒă ă”ăŒăăŒăć
„ćăăŠăă ăă";
"directory_server_placeholder" = "matrix.org";
// Events formatter
-"event_formatter_member_updates" = "%tuæš©éăć€æŽăăăŸăă";
-"event_formatter_widget_added" = "%@ăŠăŁăžă§ăăă %@ ăăă«ăăèżœć ăăăŸăă";
-"event_formatter_widget_removed" = "%@ăŠăŁăžă§ăăă %@ ăăă«ăăćé€ăăăŸăă";
-"event_formatter_jitsi_widget_added" = "éłćŁ°äŒè°ă%@ ăăă«ăăèżœć ăăăŸăă";
-"event_formatter_jitsi_widget_removed" = "éłćŁ°äŒè°ă%@ ăăă«ăăćé€ăăăŸăă";
+"event_formatter_member_updates" = "%tućăźăĄăłăăŒă·ăăăźć€æŽ";
+"event_formatter_widget_added" = "%@ăźăŠăŁăžă§ăăă%@ă«ăăèżœć ăăăŸăă";
+"event_formatter_widget_removed" = "%@ăźăŠăŁăžă§ăăă%@ă«ăăćé€ăăăŸăă";
+"event_formatter_jitsi_widget_added" = "VoIPäŒè°ă%@ă«ăăèżœć ăăăŸăă";
+"event_formatter_jitsi_widget_removed" = "VoIPäŒè°ă%@ă«ăăćé€ăăăŸăă";
// Others
"or" = "ăŸăăŻ";
"you" = "ăăȘă";
@@ -404,41 +404,41 @@
"yesterday" = "æšæ„";
"network_offline_prompt" = "ă€ăłăżăŒăăăăžăźæ„ç¶ăćăăŠăăăăă§ăă";
"public_room_section_title" = "ć
Źéă«ăŒă ïŒ%@ ă«ăŠïŒïŒ";
-"bug_report_prompt" = "ććăąăăȘăç°ćžžç”äșăăŸăăăăă°ăŹăăŒăăé俥ăăŸăăïŒ";
-"rage_shake_prompt" = "ăăȘăăŻäžæșăăăŁăŠç«Żæ«ăæșăăăŠăăăăă§ăăăă°ăŹăăŒăăăăŸăăïŒ";
+"bug_report_prompt" = "ććăąăăȘă±ăŒă·ă§ăłăăŻă©ăă·ă„ăăŸăăăăŻă©ăă·ă„ăŹăăŒăăé俥ăăŸăăïŒ";
+"rage_shake_prompt" = "ăăȘăăŻäžæșă§ç«Żæ«ăæŻăŁăŠăăăăă§ăăăă°ăŹăăŒăăć ±ćăăŸăăïŒ";
"do_not_ask_again" = "ćăłèĄšç€șăăȘă";
-"camera_access_not_granted" = "%@ăŻă«ăĄă©ăäœżçšăăæš©éăæăŁăŠăăŸăăăćäșșæ
ć ±äżè·èšćźăźć€æŽăăéĄăăăŸă";
+"camera_access_not_granted" = "%@ă«ăŻă«ăĄă©ăäœżçšăăæš©éăăăăŸăăăăă©ă€ăă·ăŒèšćźăć€æŽăăŠăă ăă";
"large_badge_value_k_format" = "%.1fK";
// room display name
"room_displayname_room_invite" = "æćŸ
";
-"room_displayname_two_members" = "%@ ăš %@";
+"room_displayname_two_members" = "%@ăš%@";
"room_displayname_no_title" = "ă ăăăăȘăéšć±";
// Call
-"call_incoming_voice_prompt" = "%@ ăăăăé話ăźç俥äž";
-"call_incoming_video_prompt" = "%@ ăăăăæ ćă€ăé話ăźç俥äž";
+"call_incoming_voice_prompt" = "%@ăăé話ăźç俥äž";
+"call_incoming_video_prompt" = "%@ăăăăăȘé話ăźç俥äž";
"call_incoming_voice" = "ç俥äžâŠ";
"call_incoming_video" = "ăăăȘé話ăźç俥äžâŠ";
"call_already_displayed" = "æąă«é話äžă§ăă";
-"call_jitsi_error" = "äŒè°é話ăžăźćć ă«ć€±æăăŸăăă";
+"call_jitsi_error" = "ă°ă«ăŒăé話ăžăźćć ă«ć€±æăăŸăăă";
// No VoIP support
-"no_voip_title" = "é話ç俥äž";
-"no_voip" = "%@ăăăăé話ăźç俥ăăăăŸăăăă%@ăŻé話ăăŸă ă”ăăŒăăăŠăăŸăăă\năăźéç„ăçĄèŠăăŠăć„ăźç«Żæ«ăăç俥ă«ćżçăăăăšăăæćŠăăăăšăă§ăăŸăă";
+"no_voip_title" = "ç俥äž";
+"no_voip" = "%@ăăăȘăăćŒăłćșăăŠăăŸăăă%@ăŻăŸă é話ăă”ăăŒăăăŠăăŸăăă\năăźéç„ăçĄèŠăăŠć„ăźç«Żæ«ăăç俥ă«ćżçăăăăšăăăŸăăŻç俥ăæćŠăăăăšăă§ăăŸăă";
// Crash report
// Crypto
"e2e_need_log_in_again" = "ććșŠăă°ă€ăłăăŠăăăźă»ăă·ă§ăłăźăšăłăăăŒăšăłăæć·é”ăçæăăć
Źéé”ăăăŒă ă”ăŒăăŒă«é俥ăăćż
èŠăăăăŸăă\năèż·æăăăăăăŸăăăăäșæżăă ăăă";
// Bug report
"bug_report_title" = "ăă°ăŹăăŒă";
-"bug_report_description" = "èȘ€ćäœăźć
ćźčăšç¶æłăźèȘŹæăăéĄăèŽăăŸăăăăȘăăŻäœăăăŸăăăïŒäœăè”·ăăăšæăăŸăăïŒćźéäœăè”·ăăŁăăźă§ăăïŒ";
-"bug_crash_report_title" = "ç°ćžžç”äșć ±ć";
-"bug_crash_report_description" = "ç°ćžžćæąăăćă«ăăȘăăăăŠăăăăšăèšăăŠăă ăă:";
-"bug_report_logs_description" = "éçșè
ăćéĄăèšșæăăăăă«ăăăźElementăźăă°ăăă°ăŹăăŒăăšäžç·ă«é俥ăăăŸăăäžèšæç« ăźăżăé俥ăăăć ŽćăŻä»„äžăźăă§ăăŻăè§Łé€ăăŠăă ăăïŒ";
+"bug_report_description" = "äžć
·ćăźć
ćźčăšç¶æłăźèȘŹæăăéĄăăăŸăăäœăăăŸăăăïŒäœăè”·ăăăčăă§ăăăïŒćźéă«è”·ăăŁăäșè±ĄăŻäœă§ăăăăïŒ";
+"bug_crash_report_title" = "ăŻă©ăă·ă„ăŹăăŒă";
+"bug_crash_report_description" = "ăŻă©ăă·ă„ăăćă«ăăȘăăăăŠăăăăšăèšăăŠăă ăăïŒ";
+"bug_report_logs_description" = "éçșè
ăćéĄăèšșæăăăăă«ăăăźElementăźăă°ăăă°ăŹăăŒăăšäžç·ă«é俥ăăăŸăăäžèšăźæç« ăźăżăé俥ăăăć ŽćăŻă仄äžăźăă§ăăŻăè§Łé€ăăŠăă ăăïŒ";
"bug_report_send_logs" = "ăă°ăé俥";
-"bug_report_send_screenshot" = "ç»éąăźăčăŻăȘăŒăłă·ă§ăăç»ćăé俥";
-"bug_report_progress_zipping" = "ăă°ăćé";
+"bug_report_send_screenshot" = "ăčăŻăȘăŒăłă·ă§ăăăźç»ćăé俥";
+"bug_report_progress_zipping" = "ăă°ăćéăăŠăăŸă";
"bug_report_progress_uploading" = "ć ±ćăé俥ăăŠăăŸă";
"bug_report_send" = "é俥";
// Widget
-"widget_no_power_to_manage" = "ăăȘăăăăźă«ăŒă ă§ăŠăŁăžă§ăăă知çăăăăăźæš©éăćż
èŠă§ă";
+"widget_no_power_to_manage" = "ăăźă«ăŒă ă§ăŠăŁăžă§ăăă知çăăăăăźæš©éăćż
èŠă§ă";
"widget_creation_failure" = "ăŠăŁăžă§ăăăźäœæă«ć€±æăăŸăă";
// Widget Integration Manager
"widget_integration_need_to_be_able_to_invite" = "ăăăèĄăă«ăŻăŠăŒă¶ăŒăæćŸ
ăăæš©éăćż
èŠă§ăă";
@@ -447,46 +447,46 @@
"widget_integration_room_not_recognised" = "ăăźă«ăŒă ă§ăŻèȘăăăăŸăăă";
"widget_integration_positive_power_level" = "æš©éăźæ°ć€ăŻæŁăźæŽæ°ă§ć
„ćăăŠăă ăăă";
"widget_integration_must_be_in_room" = "ăăȘăăŻăăźă«ăŒă ă«æć±ăăŠăăŸăăă";
-"widget_integration_no_permission_in_room" = "ăăȘăăŻăăźă«ăŒă ă§æš©éăăăăŸăăă";
-"widget_integration_missing_room_id" = "ă«ăŒă ćșæIDăźèŠæ±ă«ć€±æăăŸăăă";
-"widget_integration_missing_user_id" = "ăŠăŒă¶ăŒćșæIDăźèŠæ±ă«ć€±æăăŸăăă";
+"widget_integration_no_permission_in_room" = "ăăźă«ăŒă ă§ăăăèĄăæš©éăăăăŸăăă";
+"widget_integration_missing_room_id" = "ăȘăŻăšăčăă«room_idăăăăŸăăă";
+"widget_integration_missing_user_id" = "ăȘăŻăšăčăă«user_idăăăăŸăăă";
"widget_integration_room_not_visible" = "ă«ăŒă %@ ăŻèŠăăŸăăă";
// Share extension
"share_extension_auth_prompt" = "ăĄă€ăłăźăąăăȘă«ăă°ă€ăłăăŠăłăłăăłăăć
±æ";
-"share_extension_failed_to_encrypt" = "é俥ă«ć€±æăăŸăăăăăźă«ăŒă ăźæć·èšćźăăĄă€ăłăźç«Żæ«ă§çąșèȘăăŠäžăă";
+"share_extension_failed_to_encrypt" = "é俥ă«ć€±æăăŸăăăăăźă«ăŒă ăźæć·èšćźăăĄă€ăłăźç«Żæ«ă§çąșèȘăăŠăă ăă";
"room_details_advanced_e2e_encryption_prompt_message" = "End-to-endæć·ćăŻćźéšçăȘăăźă§ăăăäżĄé Œæ§ăäœăć ŽćăăăăŸăă\n\nçșèšăäżè·ăăăăă«ăŻăŸă ăăă俥çšăăčăă§ăŻăăăŸăăă\n\nç«Żæ«ăŻăăŸă ćć ăăćăźçșèšć±„æŽăćŸ©ć·ćăăăăšăŻă§ăăŸăăă\n\néšć±ăźæć·ćăä»ăăæćčă«ăȘăŁăăăăăçĄćčă«ăăăăšăŻă§ăăŸăăă\n\næć·ćăăăçșèšăŻăăŸă æć·ćăćźèŁ
ăăŠăăȘăăąăăȘă§ăŻèĄšç€șăăăŸăăă";
"settings_enable_callkit" = "ćŒăłćșăăźç”±ć";
-"settings_pin_rooms_with_unread" = "æȘèȘăźăăă«ăŒă ăćșćź";
+"settings_pin_rooms_with_unread" = "æȘèȘăĄăă»ăŒăžăăăă«ăŒă ăăăłæąă";
"title_groups" = "ăłăă„ăăăŁăŒ";
"room_recents_server_notice_section" = "ă·ăčăă ăąă©ăŒă";
// Groups tab
"group_invite_section" = "æćŸ
";
"group_section" = "ăłăă„ăăăŁăŒ";
-"room_message_reply_to_placeholder" = "èżäżĄăéăïŒæć·ćăăăŠăăȘăïŒâŠ";
+"room_message_reply_to_placeholder" = "èżäżĄăéăïŒæć·ćăăăŠăăŸăăïŒâŠ";
"room_do_not_have_permission_to_post" = "ăăźă«ăŒă ă«æçšżăăæš©éăăăăŸăă";
-"encrypted_room_message_reply_to_placeholder" = "æć·ćăăăèżäżĄăé俥âŠ";
+"encrypted_room_message_reply_to_placeholder" = "æć·ćăăăèżäżĄăéăâŠ";
"room_message_reply_to_short_placeholder" = "èżäżĄăéăâŠ";
-"room_event_action_view_decrypted_source" = "ćŸ©ć·ćăăăăœăŒăčăèŠă";
+"room_event_action_view_decrypted_source" = "ćŸ©ć·ćăăăăœăŒăčăłăŒăăèĄšç€ș";
"room_event_action_kick_prompt_reason" = "ăăźăŠăŒă¶ăŒăèżœæŸăăçç±";
-"room_action_send_photo_or_video" = "ćçăćç»ăéă";
-"room_action_send_sticker" = "ăčăżăłăé俥";
+"room_action_send_photo_or_video" = "ćçăŸăăŻćç»ăé俥";
+"room_action_send_sticker" = "ăčăăă«ăŒăé俥";
"room_replacement_information" = "ăăźă«ăŒă ăŻçœźăæăăăăŠăăăăąăŻăăŁăă§ăŻăăăŸăăă";
-"room_replacement_link" = "ăăĄăăăç¶ç¶äžăźäŒè©±ăçąșèȘăăă";
+"room_replacement_link" = "ăăĄăăăç¶ç¶äžăźäŒè©±ăçąșèȘă";
"room_predecessor_information" = "ăăźă«ăŒă ăŻć„ăźäŒè©±ăźç¶ăă§ăă";
-"room_predecessor_link" = "仄ćăźăĄăă»ăŒăžăèŠăă«ăŻăăăăăżăăăăŠăă ăăă";
-"room_resource_limit_exceeded_message_contact_2_link" = "ă”ăŒăăč知çè
ă«éŁç”Ą";
+"room_predecessor_link" = "仄ćăźăĄăă»ăŒăžăèĄšç€șăăă«ăŻăăăăăżăăăăŠăă ăăă";
+"room_resource_limit_exceeded_message_contact_2_link" = "ă”ăŒăăč知çè
ă«éŁç”ĄăăŠăă ăă";
"room_resource_limit_exceeded_message_contact_3" = " ăăźă”ăŒăăčăźäœżçšăç¶ç¶ăăă«ăŻă";
-"room_resource_usage_limit_reached_message_1_default" = "ăăźăăŒă ă”ăŒăăŒăŻăȘăœăŒăčć¶éăź1ă€ăè¶
ăăŠăăŸă ";
-"room_resource_usage_limit_reached_message_1_monthly_active_user" = "ăăźăăŒă ă”ăŒăăŒăŻæéăąăŻăăŁăăŠăŒă¶ăŒæ°ć¶éăè¶
ăăŠăăŸă ";
+"room_resource_usage_limit_reached_message_1_default" = "ăăźăăŒă ă”ăŒăăŒăŻăȘăœăŒăčăźäžéă«éăăŸăă ";
+"room_resource_usage_limit_reached_message_1_monthly_active_user" = "ăăźăăŒă ă”ăŒăăŒăŻæéăąăŻăăŁăăŠăŒă¶ăŒæ°ăźäžéă«éăăŸăă ";
"room_resource_usage_limit_reached_message_2" = "äžéšăźăŠăŒă¶ăŒăŻăă°ă€ăłă§ăăȘăăȘăăŸăă";
"room_resource_usage_limit_reached_message_contact_3" = " ăăźć¶éăćąăăă«ăŻă";
-"settings_deactivate_account" = "çĄćčćăăăąă«ăŠăłă";
+"settings_deactivate_account" = "ăąă«ăŠăłăăźçĄćčć";
"settings_labs_room_members_lazy_loading" = "é
滶ăăŒăă«ăŒă ăźăĄăłăăŒ";
"settings_labs_room_members_lazy_loading_error_message" = "ăăȘăăźăăŒă ă”ăŒăăŒăŻăŸă ă«ăŒă ăĄăłăăŒăźé
滶ăăŒăăă”ăăŒăăăŠăăŸăăă ćŸă§è©ŠăăŠăă ăăă";
-"settings_deactivate_my_account" = "ăąă«ăŠăłăăçĄćčă«ăăŸă";
+"settings_deactivate_my_account" = "ăąă«ăŠăłăăæ°žäč
ă«çĄćčă«ăă";
"room_details_flair_section" = "ăłăă„ăăăŁăŒăźçčèČăèĄšç€ș";
"room_details_new_flair_placeholder" = "æ°ăăăłăă„ăăăŁăŒIDăèżœć ïŒäŸ +foo%@ïŒ";
-"room_details_flair_invalid_id_prompt_title" = "çĄćčăȘćœąćŒ";
+"room_details_flair_invalid_id_prompt_title" = "äžæŁăȘćœąćŒă§ă";
"room_details_flair_invalid_id_prompt_msg" = "%@ăŻăłăă„ăăăŁăŒăźæćčăȘèć„ćă§ăŻăăăŸăă";
"room_details_fail_to_update_room_communities" = "éąéŁăăăłăă„ăăăŁăŒăźæŽæ°ă«ć€±æ";
// Group Details
@@ -495,15 +495,15 @@
"group_details_people" = "éŁç”Ąć
";
"group_details_rooms" = "ă«ăŒă ";
// Group Home
-"group_home_one_member_format" = "1ćăźăĄăłăăŒ";
-"group_home_multi_members_format" = "%tućăźăĄăłăăŒ";
-"group_home_one_room_format" = "1ă€ăźă«ăŒă ";
-"group_home_multi_rooms_format" = "%tuă€ăźă«ăŒă ";
+"group_home_one_member_format" = "1äșșăźăĄăłăăŒ";
+"group_home_multi_members_format" = "%tuäșșăźăĄăłăăŒ";
+"group_home_one_room_format" = "1ćăźă«ăŒă ";
+"group_home_multi_rooms_format" = "%tućăźă«ăŒă ";
"group_invitation_format" = "%@ăăăźăłăă„ăăăŁăŒă«ăăȘăăæćŸ
ăăŸăă";
// Group participants
"group_participants_add_participant" = "ćć è
ăèżœć ";
-"group_participants_leave_prompt_title" = "ă°ă«ăŒăăéćș";
-"group_participants_leave_prompt_msg" = "ă°ă«ăŒăăéćșăăŠăăăăă§ăăïŒ";
+"group_participants_leave_prompt_title" = "ă°ă«ăŒăăăéćș";
+"group_participants_leave_prompt_msg" = "ă°ă«ăŒăăăéćșăăŠăăăăă§ăăïŒ";
"group_participants_remove_prompt_title" = "çąșèȘ";
"group_participants_remove_prompt_msg" = "ăăźă°ă«ăŒăăă%@ăćé€ăăŠăăăăă§ăăïŒ";
"group_participants_invite_prompt_title" = "çąșèȘ";
@@ -514,36 +514,36 @@
"group_participants_invite_malformed_id" = "äžæŁăȘIDă'@localpart:domain'ăźăăăȘMatrix IDă§ăȘăăă°ăȘăăŸăă";
"group_participants_invited_section" = "æćŸ
äž";
// Group rooms
-"group_rooms_filter_rooms" = "ăłăă„ăăăŁăŒă«ăŒă ăç”ă蟌ă";
+"group_rooms_filter_rooms" = "ăłăă„ăăăŁăŒăźă«ăŒă ăç”ă蟌ă";
"event_formatter_rerequest_keys_part1_link" = "æć·é”ăćèŠæ±";
"event_formatter_rerequest_keys_part2" = " ăăȘăăźä»ăźă»ăă·ă§ăłă«ă";
"homeserver_connection_lost" = "ăăŒă ă”ăŒăăŒă«æ„ç¶ă§ăăŸăăă§ăăă";
-"widget_sticker_picker_no_stickerpacks_alert" = "çŸćšăăčăăă«ăŒăăăŻăæćčă«ăăŠăăŸăăă";
+"widget_sticker_picker_no_stickerpacks_alert" = "çŸćšăăčăăă«ăŒăăăŻăæćčă«ăȘăŁăŠăăŸăăă";
"widget_sticker_picker_no_stickerpacks_alert_add_now" = "ä»ăăèżœć ăăŸăăïŒ";
// Room key request dialog
"e2e_room_key_request_title" = "æć·é”ăźèŠæ±";
-"e2e_room_key_request_message_new_device" = "æć·é”ăèŠæ±ăăŠăăæ°ăăç«Żæ« '%@' ăèżœć ăăŸăăă";
-"e2e_room_key_request_message" = "èȘ蚌ăăăŠăăȘăç«Żæ« '%@' ăæć·é”ăèŠæ±ăăŠăăŸăă";
-"e2e_room_key_request_start_verification" = "èȘ蚌ăć§ăăŸăâŠ";
-"e2e_room_key_request_share_without_verifying" = "èȘ蚌ăăă«ć
±æ";
+"e2e_room_key_request_message_new_device" = "æć·é”ăèŠæ±ăăŠăăæ°ăăă»ăă·ă§ăł'%@'ăèżœć ăăŸăăă";
+"e2e_room_key_request_message" = "æȘèȘ蚌ăźă»ăă·ă§ăł'%@'ăæć·é”ăèŠæ±ăăŠăăŸăă";
+"e2e_room_key_request_start_verification" = "èȘ蚌ăéć§âŠ";
+"e2e_room_key_request_share_without_verifying" = "èȘ蚌ăăć
±æ";
"e2e_room_key_request_ignore_request" = "èŠæ±ăçĄèŠ";
// GDPR
-"gdpr_consent_not_given_alert_message" = "%@ăăŒă ă”ăŒăăŒăćŒăç¶ăäœżçšăăă«ăŻăć©çšèŠçŽăçąșèȘăăŠćæăăćż
èŠăăăăŸăă";
+"gdpr_consent_not_given_alert_message" = "%@ăźăăŒă ă”ăŒăăŒăćŒăç¶ăäœżçšăăă«ăŻăć©çšèŠçŽăçąșèȘăăŠćæăăćż
èŠăăăăŸăă";
"gdpr_consent_not_given_alert_review_now_action" = "çąșèȘ";
-"deactivate_account_title" = "çĄćčăȘăąă«ăŠăłă";
-"deactivate_account_informations_part1" = "ăăă«ăăăăąă«ăŠăłăăŻæ°žäč
ă«äœżçšă§ăăȘăăȘăăŸăăăă°ă€ăłăăăăšăŻă§ăăăèȘ°ăćăăŠăŒă¶ăŒIDăćç»éČăăăăšăŻă§ăăŸăăăăăă«ăăăăăȘăăźăąă«ăŠăłăăŻćć ăăŠăăć
šăŠăźă«ăŒă ăăéć»ăăăăȘăăźIDă”ăŒăăŒăăăąă«ăŠăłăăźè©łçŽ°ăćé€ăăăŸăă ";
-"deactivate_account_informations_part2_emphasize" = "ăăźćäœăŻć
ă«æ»ăăŸăăă";
-"deactivate_account_informations_part3" = "\n\năąă«ăŠăłăăźçĄćčć ";
-"deactivate_account_informations_part4_emphasize" = "ăăă©ă«ăă§ăŻăăȘăăé俥ăăăĄăă»ăŒăžăćżăăăăšăŻăăăŸăăă ";
-"deactivate_account_informations_part5" = "ăĄăă»ăŒăžăźć±„æŽăźæ¶ć»ăæăć ŽćăŻă仄äžăźăăăŻăčă«ăă§ăăŻăć
„ăăŠăă ăăă\n\nMatrixăźăĄăă»ăŒăžăźèŠăæčăŻăé»ćăĄăŒă«ăšćæ§ăźăăźă§ăăăĄăă»ăŒăžăźć±„æŽăæ¶ć»ăăăšăăăȘăăé俥ăăăĄăă»ăŒăžăŻăæ°èŠăŸăăŻæȘç»éČăźăŠăŒă¶ăŒă«ć
±æăăăăăšăŻăăăŸăăăăæąă«ăĄăă»ăŒăžăććŸăăŠăăç»éČăŠăŒă¶ăŒăŻăä»ćŸăăăźăłăăŒă«ăąăŻă»ăčă§ăăŸăă";
-"deactivate_account_forget_messages_information_part1" = "ăąă«ăŠăłăăçĄćčă«ăȘăŁăăšăă«é俥ăăć
šăŠăźăĄăă»ăŒăžăćżăăŠăă ăă (";
+"deactivate_account_title" = "ăąă«ăŠăłăăçĄćčć";
+"deactivate_account_informations_part1" = "ăăźæäœă«ăăăăăȘăăźăąă«ăŠăłăăŻæ°žäč
ă«äœżăăȘăăȘăăŸăăăă°ă€ăłăăăćăăŠăŒă¶ăŒIDăćç»éČăăăăăăăšăŻă§ăăȘăăȘăăŸăăăăȘăăźăąă«ăŠăłăăŻćć ăăŠăăć
šăŠăźă«ăŒă ăăéćșăăăăȘăăźIDă”ăŒăăŒăăăąă«ăŠăłăăźè©łçŽ°ăćé€ăăăŸăă ";
+"deactivate_account_informations_part2_emphasize" = "ăăźæäœăŻćăæ¶ăăŸăăă";
+"deactivate_account_informations_part3" = "\n\năąă«ăŠăłăăçĄćčćăăŠăă ";
+"deactivate_account_informations_part4_emphasize" = "ăăă©ă«ăă§ăŻăăȘăăé俥ăăăĄăă»ăŒăžăźć±„æŽăŻæ¶ć»ăăăŸăăă ";
+"deactivate_account_informations_part5" = "ăĄăă»ăŒăžăźć±„æŽăæ¶ć»ăăć ŽćăŻă仄äžăźăăăŻăčă«ăă§ăăŻăć
„ăăŠăă ăăă\n\nMatrixăźăĄăă»ăŒăžăźèŠăæčăŻăé»ćăĄăŒă«ăšćæ§ăźăăźă§ăăăĄăă»ăŒăžăźć±„æŽăæ¶ć»ăăăšăăăȘăăăăăŸă§é俥ăăăĄăă»ăŒăžăŻăæ°èŠăŸăăŻæȘç»éČăźăŠăŒă¶ăŒă«ć
±æăăăăăšăŻăăăŸăăăăæąă«ăĄăă»ăŒăžăććŸăăŠăăç»éČăŠăŒă¶ăŒăŻăä»ćŸăăăźăłăăŒă«ăąăŻă»ăčă§ăăŸăă";
+"deactivate_account_forget_messages_information_part1" = "ăąă«ăŠăłăăçĄćčćăăéăć
šăŠăźé俥æžăźăĄăă»ăŒăžăæ¶ć»ïŒ";
"deactivate_account_forget_messages_information_part2_emphasize" = "èŠć";
-"deactivate_account_forget_messages_information_part3" = "ïŒăăăŻć°æ„ăźăŠăŒă¶ăŒă«äŒè©±ăźäžćźć
šăȘăă„ăŒăèĄšç€șăăă)";
-"deactivate_account_validate_action" = "çĄćčăȘăąă«ăŠăłă";
-"deactivate_account_password_alert_title" = "çĄćčăȘăąă«ăŠăłă";
-"deactivate_account_password_alert_message" = "ç¶èĄăăă«ăŻăMatrix ăąă«ăŠăłăăźăăčăŻăŒăăć
„ćăăŠăă ăă";
+"deactivate_account_forget_messages_information_part3" = "ïŒä»ćŸăźăŠăŒă¶ăŒă«ăŻăäžćźć
šăȘäŒè©±ăèĄšç€șăăăŸăïŒ";
+"deactivate_account_validate_action" = "ăąă«ăŠăłăăçĄćčć";
+"deactivate_account_password_alert_title" = "ăąă«ăŠăłăăçĄćčć";
+"deactivate_account_password_alert_message" = "ç¶èĄăăă«ăŻăMatrixăźăąă«ăŠăłăăźăăčăŻăŒăăć
„ćăăŠăă ăă";
// Re-request confirmation dialog
-"rerequest_keys_alert_title" = "èŠæ±ăé俥ăăăŸăă";
+"rerequest_keys_alert_title" = "èŠæ±ăé俥ăăŸăă";
"rerequest_keys_alert_message" = "é”ăăăźă»ăă·ă§ăłă«é俥ă§ăăăăă«ăăĄăă»ăŒăžăćŸ©ć·ćă§ăăä»ăźç«Żæ«ă§%@ăè”·ćăăŠăă ăăă";
"room_event_action_ban_prompt_reason" = "ăăźăŠăŒă¶ăŒăăăăăŻăăçç±";
"room_resource_limit_exceeded_message_contact_1" = " ăéĄă ";
@@ -554,85 +554,85 @@
"close" = "éăă";
// Accessibility
"accessibility_checkbox_label" = "ăă§ăăŻăăăŻăč";
-"auth_login_single_sign_on" = "ă·ăłă°ă«ă”ă€ăłăȘăł(SSO)ă§ă”ă€ăłă€ăł";
+"auth_login_single_sign_on" = "ă”ă€ăłă€ăł";
"auth_softlogout_clear_data_sign_out" = "ă”ă€ăłăąăŠă";
-"room_message_unable_open_link_error_message" = "ăȘăłăŻăéăăăšăă§ăăŸăăă";
-"user_verification_session_details_verify_action_other_user" = "æćă§çąșèȘ";
+"room_message_unable_open_link_error_message" = "ăȘăłăŻăéăăŸăăă";
+"user_verification_session_details_verify_action_other_user" = "æćă§èȘ蚌";
"room_info_list_section_other" = "ăăźä»";
"room_info_list_several_members" = "%@äșșăźăĄăłăăŒ";
// MARK: - Room Info
-"room_info_list_one_member" = "1ćăźăĄăłăăŒ";
+"room_info_list_one_member" = "1äșșăźăĄăłăăŒ";
"create_room_placeholder_address" = "#testroom:matrix.org";
"create_room_section_header_address" = "ăąăăŹăč";
"create_room_show_in_directory" = "ă«ăŒă äžèŠ§ă«æČèŒ";
"create_room_section_footer_type" = "éć
Źéăźă«ăŒă ăŻăă«ăŒă ă«æćŸ
ăăăäșșăźăżćć ă§ăăŸăă";
-"create_room_type_public" = "ć
Źéă«ăŒă (èȘ°ă§ăćć ćŻèœ)";
-"create_room_type_private" = "éć
Źéă«ăŒă (æćŸ
è
ăźăżćć ćŻèœ)";
+"create_room_type_public" = "ć
Źéă«ăŒă ïŒèȘ°ă§ăćć ćŻèœïŒ";
+"create_room_type_private" = "éć
Źéăźă«ăŒă ïŒæćŸ
è
ăźăżćć ćŻèœïŒ";
"create_room_section_header_type" = "ăąăŻă»ăčă§ăăäșș";
"create_room_section_footer_encryption" = "æć·ćăŻăăšăăçĄćčă«ăăăăšăŻă§ăăŸăăă";
-"create_room_section_header_encryption" = "ă«ăŒă ăźæć·ć";
-"create_room_placeholder_topic" = "ăăăăŻ";
-"create_room_section_header_topic" = "ă«ăŒă ăźăăăăŻïŒä»»æïŒ";
+"create_room_section_header_encryption" = "æć·ć";
+"create_room_placeholder_topic" = "ă«ăŒă ăźăăăăŻăć
„ćăăŠăă ăă";
+"create_room_section_header_topic" = "ăăăăŻïŒä»»æïŒ";
"create_room_placeholder_name" = "ćć";
-"create_room_section_header_name" = "ă«ăŒă ć";
+"create_room_section_header_name" = "ćć";
// MARK: - Create Room
"create_room_title" = "æ°ăăă«ăŒă ";
"create_room_enable_encryption" = "æć·ćăæćčă«ăă";
"room_details_room_name_for_dm" = "ćć";
-"room_participants_security_information_room_encrypted_for_dm" = "ăăă§éć俥ăăăăĄăă»ăŒăžăŻăšăłăăăŒăšăłăæć·ćăăăŠăăŸăă\n\năĄăă»ăŒăžăŻćźć
šă«äżè·ăăăŠăăăăĄăă»ăŒăžăźăăăŻăè§Łé€ăăăăăźćșæăźé”ăŻăăăȘăăšć俥è
ă ăăæăŁăŠăăŸăă";
-"room_participants_security_information_room_not_encrypted_for_dm" = "ăăă§ăźăĄăă»ăŒăžăŻăšăłăăăŒăšăłăæć·ćăăăŠăăŸăăă";
+"room_participants_security_information_room_encrypted_for_dm" = "ăăă§ăźăĄăă»ăŒăžăŻăšăłăăăŒăšăłăă§æć·ćăăăŠăăŸăă\n\năĄăă»ăŒăžăŻćźć
šă«äżè·ăăăŠăăăăĄăă»ăŒăžăźăăăŻăè§Łé€ăăăăăźćșæăźé”ăŻăăăȘăăšć俥è
ă ăăæăŁăŠăăŸăă";
+"room_participants_security_information_room_not_encrypted_for_dm" = "ăăă§ăźăĄăă»ăŒăžăŻăšăłăăăŒăšăłăă§æć·ćăăăŠăăŸăăă";
// Mark: - Room creation introduction cell
-"room_intro_cell_add_participants_action" = "ćć è
ăèżœć ";
-"room_participants_security_information_room_encrypted" = "ăăźă«ăŒă ăźăĄăă»ăŒăžăŻăšăłăăăŒăšăłăæć·ćăăăŠăăŸăă\n\năĄăă»ăŒăžăŻćźć
šă«äżè·ăăăŠăăăăĄăă»ăŒăžăźăăăŻăè§Łé€ăăăăăźćșæăźé”ăŻăăăȘăăšć俥è
ă ăăæăŁăŠăăŸăă";
-"room_participants_security_information_room_not_encrypted" = "ăăźă«ăŒă ăźăĄăă»ăŒăžăŻăšăłăăăŒăšăłăæć·ćăăăŠăăŸăăă";
+"room_intro_cell_add_participants_action" = "éŁç”Ąć
ăèżœć ";
+"room_participants_security_information_room_encrypted" = "ăăźă«ăŒă ăźăĄăă»ăŒăžăŻăšăłăăăŒăšăłăă§æć·ćăăăŠăăŸăă\n\năĄăă»ăŒăžăŻćźć
šă«äżè·ăăăŠăăăăĄăă»ăŒăžăźăăăŻăè§Łé€ăăăăăźćșæăźé”ăŻăăăȘăăšć俥è
ă ăăæăŁăŠăăŸăă";
+"room_participants_security_information_room_not_encrypted" = "ăăźă«ăŒă ăźăĄăă»ăŒăžăŻăšăłăăăŒăšăłăă§æć·ćăăăŠăăŸăăă";
"room_intro_cell_information_dm_sentence1_part3" = "ăšăźăă€ăŹăŻăăĄăă»ăŒăžăźć§ăŸăă§ăă ";
"callbar_active_and_single_paused" = "1ă€ăźăąăŻăăŁăăȘé話ïŒ%@ïŒÂ· 1ă€ăźäžæćæąăăăé話";
// Call Bar
"callbar_only_single_active" = "ăżăăăăŠé話ïŒ%@ïŒă«æ»ă";
"settings_add_3pid_password_title_msidsn" = "é»è©±çȘć·ăèżœć ";
-"device_verification_emoji_scissors" = "ăă”ă";
-"device_verification_emoji_paperclip" = "ăăŒăăŒăŻăȘăă";
+"device_verification_emoji_scissors" = "ăŻăăż";
+"device_verification_emoji_paperclip" = "ăŻăȘăă";
"device_verification_emoji_pencil" = "éç";
"device_verification_emoji_book" = "æŹ";
"device_verification_emoji_light bulb" = "é»ç";
"device_verification_emoji_gift" = "ăźăă";
"device_verification_emoji_clock" = "æèš";
-"device_verification_emoji_hourglass" = "ăčăæèš";
-"device_verification_emoji_umbrella" = "éš";
-"device_verification_emoji_thumbs up" = "èŠȘæăç«ăŠă";
+"device_verification_emoji_hourglass" = "ç æèš";
+"device_verification_emoji_umbrella" = "ć";
+"device_verification_emoji_thumbs up" = "ăăă";
"device_verification_emoji_spanner" = "ăčăă";
"device_verification_emoji_santa" = "ă”ăłăż";
-"device_verification_emoji_glasses" = "ăĄăŹă";
-"device_verification_emoji_hat" = "ăăă";
+"device_verification_emoji_glasses" = "ăăă";
+"device_verification_emoji_hat" = "ćžœć";
"device_verification_emoji_robot" = "ăăăă";
-"device_verification_emoji_smiley" = "çŹéĄ";
+"device_verification_emoji_smiley" = "ăčăă€ă«";
"device_verification_emoji_heart" = "ăăŒă";
"device_verification_emoji_cake" = "ă±ăŒă";
"device_verification_emoji_pizza" = "ăă¶";
// Room widget permissions
"room_widget_permission_title" = "ăŠăŁăžă§ăăăèȘăżèŸŒă";
-"widget_picker_manage_integrations" = "ă€ăłăă°ăŹăŒă·ă§ăłă知çăăâŠ";
+"widget_picker_manage_integrations" = "ă€ăłăă°ăŹăŒă·ă§ăłă知çâŠ";
// Widget Picker
-"widget_picker_title" = "ă€ăłăă°ăŹăŒă·ă§ăłăăăŒăžăŁăŒ";
+"widget_picker_title" = "ă€ăłăă°ăŹăŒă·ă§ăłïŒç”±ćïŒ";
"widget_integration_manager_disabled" = "èšćźă§ă€ăłăă°ăŹăŒă·ă§ăłăăăŒăžăŁăŒăæćčă«ăăćż
èŠăăăăŸă";
-"widget_menu_remove" = "ć
šăŠćăé€ă";
+"widget_menu_remove" = "ć
šćĄăăćé€";
"widget_menu_revoke_permission" = "ăąăŻă»ăčăćăæ¶ă";
"widget_menu_open_outside" = "ăă©ăŠă¶ăŒă§éă";
-"widget_menu_refresh" = "ăȘăăŹăă·ă„";
-"widget_integrations_server_failed_to_connect" = "ă€ăłăă°ăŹăŒă·ă§ăłă”ăŒăăŒăžăźæ„ç¶ă怱æăăŸăă";
+"widget_menu_refresh" = "ćèȘăżèŸŒăż";
+"widget_integrations_server_failed_to_connect" = "ă€ăłăă°ăŹăŒă·ă§ăłă”ăŒăăŒăžăźæ„ç¶ă«ć€±æăăŸăă";
// Widget
"widget_no_integrations_server_configured" = "ă€ăłăă°ăŹăŒă·ă§ăłă”ăŒăăŒăèšćźăăăŠăăŸăă";
-"bug_report_background_mode" = "ăăăŻă°ă©ăŠăłăă§ç¶ç¶";
+"bug_report_background_mode" = "ăăăŻă°ă©ăŠăłăă§ç¶èĄ";
"e2e_key_backup_wrong_version_button_wasme" = "ăăăŻăăăă§ă";
"e2e_key_backup_wrong_version_button_settings" = "èšćź";
"e2e_key_backup_wrong_version" = "ăĄăă»ăŒăžăźé”ăźæ°ăăćźć
šăȘăăăŻăąăăăæ€ćșăăăŸăăă\n\năăăăăȘăă«ăăăăźă§ăŻăȘăć ŽćăŻăèšćźăăæ°ăăăăčăăŹăŒășăèšćźăăŠăă ăăă";
@@ -640,93 +640,93 @@
// Key backup wrong version
"e2e_key_backup_wrong_version_title" = "æ°ăăé”ăźăăăŻăąăă";
"call_no_stun_server_error_use_fallback_button" = "%@ăäœżăŁăŠăżăŠăă ăă";
-"call_actions_unhold" = "ăăçŽă";
-"call_no_stun_server_error_message_2" = "代ăăă«ă%@ăźăăăȘăăŻă”ăŒăăŒăäœżçšăăăăšăă§ăăŸăăăăăăŻäżĄé Œæ§ăäœăăăȘăăźIPăąăăŹăčăăăźă”ăŒăăŒăšć
±æăăăŠăăŸăăŸăăăăăŻăèšćźăă知çăăăăšăă§ăăŸă";
-"call_no_stun_server_error_message_1" = "é話ăçąșćźă«æ©èœăăăăăă«ăŻăăăŒă ă”ăŒăăŒ%@ăźçźĄçè
ă«TURNă”ăŒăăŒăźèšćźăäŸé ŒăăŠăă ăăă";
-"call_no_stun_server_error_title" = "ă”ăŒăăŒăźèšćźăééăŁăŠăăăăé話ă«ć€±æăăŸăă";
+"call_actions_unhold" = "ćé";
+"call_no_stun_server_error_message_2" = "ăŸă㯠%@ ăźć
Źéă”ăŒăăŒăäœżçšăăăăšăă§ăăŸăăăäżĄé Œæ§ăäœăăăŸăăăăȘăăźIPăąăăŹăčăăăźă”ăŒăăŒăšć
±æăăăŠăăŸăăŸăăăăăŻèšćźç»éąăăă知çă§ăăŸă";
+"call_no_stun_server_error_message_1" = "ćźćźăăé話ăźăăă«ăăăŒă ă”ăŒăăŒ %@ ăźçźĄçè
ă«TURNă”ăŒăăŒăźèšćźăäŸé ŒăăŠăă ăăă";
+"call_no_stun_server_error_title" = "ă”ăŒăăŒăźäžæŁăȘèšćźăźăăé話ă«ć€±æăăŸăă";
"room_does_not_exist" = "%@ăŻććšăăŸăă";
-"photo_library_access_not_granted" = "%@ăŻăă©ăă©ă€ăă©ăȘă«ăąăŻă»ăčăăæš©éăăăăŸăă";
-"camera_unavailable" = "ăäœżăăźç«Żæ«ă§ăŻă«ăĄă©ăć©çšă§ăăŸăă";
+"photo_library_access_not_granted" = "%@ă«ăŻăă©ăă©ă€ăă©ăȘăŒă«ăąăŻă»ăčăăæš©éăăăăŸăăăăă©ă€ăă·ăŒèšćźăć€æŽăăŠăă ăă";
+"camera_unavailable" = "ăăźç«Żæ«ă§ăŻă«ăĄă©ăć©çšă§ăăŸăă";
"event_formatter_widget_removed_by_you" = "ăŠăŁăžă§ăăăćé€ăăŸăăïŒ%@";
-"event_formatter_jitsi_widget_removed_by_you" = "VoIPă«ăłăăĄăŹăłăčăćé€ăăŸăă";
-"event_formatter_jitsi_widget_added_by_you" = "VoIPă«ăłăăĄăŹăłăčăèżœć ăăŸăă";
+"event_formatter_jitsi_widget_removed_by_you" = "VoIPäŒè°ăćé€ăăŸăă";
+"event_formatter_jitsi_widget_added_by_you" = "VoIPäŒè°ăèżœć ăăŸăă";
// Events formatter with you
"event_formatter_widget_added_by_you" = "ăŠăŁăžă§ăăăèżœć ăăŸăăïŒ%@";
"event_formatter_call_back" = "ăăçŽă";
"event_formatter_call_you_declined" = "é話ăæćŠăăŸăă";
"event_formatter_call_you_currently_in" = "é話äžă§ă";
-"event_formatter_call_has_ended" = "é話ăŻæćčă§ă";
+"event_formatter_call_has_ended" = "é話ăç”äșăăŸăă";
"event_formatter_call_video" = "ăăăȘé話";
"event_formatter_call_voice" = "éłćŁ°é話";
"event_formatter_message_edited_mention" = "ïŒç·šéæžïŒ";
-"image_picker_action_library" = "ă©ă€ăă©ăȘăéžă¶";
+"image_picker_action_library" = "ă©ă€ăă©ăȘăŒăăéžæ";
// Image picker
-"image_picker_action_camera" = "ćçăæźă";
+"image_picker_action_camera" = "ćçăæźćœ±";
// Media picker
-"media_picker_title" = "ăĄăăŁăąă©ă€ăă©ăȘ";
-"room_details_advanced_e2e_encryption_disabled_for_dm" = "ăăăŻæć·ćăæćčă§ăŻăăăŸăăă";
-"room_details_advanced_e2e_encryption_enabled_for_dm" = "ăăăŻæć·ćăæćčă§ă";
-"room_details_advanced_room_id_for_dm" = "ID:";
+"media_picker_title" = "ăĄăăŁăąă©ă€ăă©ăȘăŒ";
+"room_details_advanced_e2e_encryption_disabled_for_dm" = "ăăă§ăŻæć·ćăæćčă§ăŻăăăŸăăă";
+"room_details_advanced_e2e_encryption_enabled_for_dm" = "ăăă§ăŻæć·ćăæćčă§ă";
+"room_details_advanced_room_id_for_dm" = "IDïŒ";
"room_details_no_local_addresses_for_dm" = "ăăă«ăŻăăŒă«ă«ăąăăŹăčăăăăŸăă";
"room_details_access_section_directory_toggle_for_dm" = "ă«ăŒă äžèŠ§ă«æČèŒ";
"room_details_access_section_anyone_apart_from_guest_for_dm" = "ăȘăłăŻăç„ăŁăŠăăäșșăȘăèȘ°ă§ăïŒăČăčăăŠăŒă¶ăŒăé€ăïŒ";
"room_details_access_section_anyone_for_dm" = "ăȘăłăŻăç„ăŁăŠăăäșșăȘăèȘ°ă§ăïŒăČăčăăŠăŒă¶ăŒăć«ăïŒ";
"room_details_access_section_for_dm" = "ăăă«ăąăŻă»ăčă§ăăäșșăŻïŒ";
-"room_details_photo_for_dm" = "ćç";
-"room_details_integrations" = "ă€ăłăă°ăŹăŒă·ă§ăł";
+"room_details_photo_for_dm" = "ç»ć";
+"room_details_integrations" = "ă€ăłăă°ăŹăŒă·ă§ăłïŒç”±ćïŒ";
"room_details_search" = "ă«ăŒă ć
æ€çŽą";
"room_details_title_for_dm" = "è©łçŽ°";
"identity_server_settings_alert_error_invalid_identity_server" = "%@ăŻæćčăȘIDă”ăŒăăŒă§ăŻăăăŸăăă";
-"identity_server_settings_alert_error_terms_not_accepted" = "IDă”ăŒăăŒăšăăŠèšćźăăă«ăŻ%@ăźæĄä»¶ăćăć
„ăăćż
èŠăăăăŸăă";
-"identity_server_settings_alert_disconnect_still_sharing_3pid_button" = "çĄèŠăăŠćæ";
-"identity_server_settings_alert_disconnect_still_sharing_3pid" = "ăăȘăăŻăŸă IDă”ăŒăăŒ%@ă§ćäșșăăŒăżăć
±æăăŠăăŸăă\n\nćæăăćă«ăĄăŒă«ăąăăŹăčăšé»è©±çȘć·ăIDă”ăŒăăŒăăćé€ăăăăšăăć§ăăăŸăă";
+"identity_server_settings_alert_error_terms_not_accepted" = "IDă”ăŒăăŒă«èšćźăăă«ăŻă%@ăźć©çšèŠçŽăæżè«Ÿăăćż
èŠăăăăŸăă";
+"identity_server_settings_alert_disconnect_still_sharing_3pid_button" = "çĄèŠăăŠæ„ç¶è§Łé€";
+"identity_server_settings_alert_disconnect_still_sharing_3pid" = "ăăȘăăŻăŸă IDă”ăŒăăŒ %@ ă§ćäșșăăŒăżăć
±æăăŠăăŸăă\n\næ„ç¶ăè§Łé€ăăćă«ăăĄăŒă«ăąăăŹăčăšé»è©±çȘć·ăIDă”ăŒăăŒăăćé€ăăăăšăăć§ăăăŸăă";
"identity_server_settings_alert_disconnect_button" = "æ„ç¶ăè§Łé€";
-"identity_server_settings_alert_disconnect" = "IDă”ăŒăăŒ%@ăæ„ç¶è§Łé€ăăŸăăïŒ";
-"identity_server_settings_alert_disconnect_title" = "IDă”ăŒăăŒăæ„ç¶è§Łé€";
-"identity_server_settings_alert_change" = "IDă”ăŒăăŒ%1$@ăćæăă代ăăă«%2$@ă«æ„ç¶ăăŸăăïŒ";
+"identity_server_settings_alert_disconnect" = "IDă”ăŒăăŒ %@ ăăćæăăŸăăïŒ";
+"identity_server_settings_alert_disconnect_title" = "IDă”ăŒăăŒăăæ„ç¶ăè§Łé€";
+"identity_server_settings_alert_change" = "IDă”ăŒăăŒ %1$@ ăćæăă代ăăă« %2$@ ă«æ„ç¶ăăŸăăïŒ";
"identity_server_settings_alert_change_title" = "IDă”ăŒăăŒăć€æŽ";
"identity_server_settings_alert_no_terms" = "éžæăăIDă”ăŒăăŒă«ăŻć©çšèŠçŽăăăăŸăăăăăźă”ăŒăăŒăźææè
ăäżĄé Œă§ăăć Žćă«ăźăżç¶èĄăăŠăă ăăă";
"identity_server_settings_alert_no_terms_title" = "IDă”ăŒăăŒă«ăŻć©çšèŠçŽăăăăŸăă";
"identity_server_settings_disconnect" = "æ„ç¶ăè§Łé€";
-"identity_server_settings_disconnect_info" = "IDă”ăŒăăŒăšăźæ„ç¶ăè§Łé€ăăăšăä»ăźăŠăŒă¶ăŒăăçșèŠăăăȘăăȘăăăĄăŒă«ăé»è©±ă§ä»ăźăŠăŒă¶ăŒăæćŸ
ăăăăšăă§ăăăăă«ăȘăăŸăă";
+"identity_server_settings_disconnect_info" = "IDă”ăŒăăŒăšăźæ„ç¶ăè§Łé€ăăăšăä»ăźăŠăŒă¶ăŒă«ăăŁăŠèŠă€ăăăăȘăăȘăăăŸăăăĄăŒă«ăąăăŹăčăé»è©±ă§ä»ăźăŠăŒă¶ăŒăæćŸ
ăăăăšăă§ăăȘăăȘăăŸăă";
"identity_server_settings_change" = "ć€æŽ";
"identity_server_settings_add" = "èżœć ";
"identity_server_settings_place_holder" = "IDă”ăŒăăŒăć
„ć";
-"identity_server_settings_no_is_description" = "çŸćšăIDă”ăŒăăŒăäœżçšăăŠăăŸăăăăăȘăăźç„ăŁăŠăăéŁç”Ąć
ăçșèŠăăăăăăźéŁç”Ąć
ăăçșèŠăăăăăă«ăăă«ăŻă仄äžă§IDă”ăŒăăŒăèżœć ăăŠăă ăăă";
-"identity_server_settings_description" = "ăăȘăăŻ%@ăäœżăŁăŠăăăȘăăźç„ăćăăçșèŠăăăŸăćăăăăçșèŠă§ăăăăă«ăăŠăăŸăă";
+"identity_server_settings_no_is_description" = "çŸćšăIDă”ăŒăăŒăäœżçšăăŠăăŸăăăéŁç”Ąć
ăèŠă€ăăăăéŁç”Ąć
ăăèŠă€ăăŠăăăŁăăăăă«ăŻă仄äžă§IDă”ăŒăăŒăèżœć ăăŠăă ăăă";
+"identity_server_settings_description" = "çŸćš %@ ăäœżçšăăŠăèȘćăźéŁç”Ąć
ăèŠă€ăăăăéŁç”Ąć
ăăèŠă€ăăŠăăăŁăăă§ăăăăă«ăăŠăăŸăă";
"security_settings_complete_security_alert_title" = "ă»ăă„ăȘăăŁăŒăçąșèȘ";
"security_settings_crosssigning_complete_security" = "ă»ăă„ăȘăăŁăŒăçąșèȘ";
"security_settings_crosssigning_bootstrap" = "èšćź";
-"settings_devices_description" = "ă»ăă·ă§ăłăźć
ŹéćăŻăăăȘăăšăăćăăăäșșă
ă«ćŻŸăăŠèĄšç€șăăăŸă";
-"settings_key_backup_delete_confirmation_prompt_title" = "ăăăŻăąăăăźćé€";
+"settings_devices_description" = "ă»ăă·ă§ăłăźć
ŹéćăŻăăăȘăăšăăćăăăéŁç”Ąć
ă«ćŻŸăăŠèĄšç€șăăăŸă";
+"settings_key_backup_delete_confirmation_prompt_title" = "ăăăŻăąăăăćé€";
"settings_key_backup_info_valid" = "ăăźă»ăă·ă§ăłăŻé”ăăăăŻăąăăăăŠăăŸăă";
"settings_key_backup_info_algorithm" = "ăąă«ăŽăȘășă ïŒ%@";
"settings_key_backup_info_version" = "é”ăźăăăŻăąăăăźăăŒăžă§ăłïŒ%@";
"settings_key_backup_info_none" = "ăăȘăăźé”ăŻăăăźă»ăă·ă§ăłăăăăăŻăąăăăăăŠăăŸăăă";
"settings_key_backup_info_checking" = "çąșèȘăăŠăăŸăâŠ";
-"settings_add_3pid_password_message" = "ç¶èĄăăă«ăŻăMatrix ăąă«ăŠăłăăźăăčăŻăŒăăć
„ćăăŠăă ăă";
-"settings_add_3pid_invalid_password_message" = "çĄćčăȘèȘ蚌æ
ć ±";
+"settings_add_3pid_password_message" = "ç¶èĄăăă«ăŻăMatrixăźăąă«ăŠăłăăźăăčăŻăŒăăć
„ćăăŠăă ăă";
+"settings_add_3pid_invalid_password_message" = "èȘ蚌æ
ć ±ăæŁăăăăăŸăă";
"settings_add_3pid_password_title_email" = "ăĄăŒă«ăąăăŹăčăèżœć ";
-"settings_integrations_allow_description" = "ă€ăłăă°ăŹăŒă·ă§ăłăăăŒăžăŁăŒïŒ%@ïŒăäœżçšăăŠăăăăăăăȘăăžăăŠăŁăžă§ăăăăčăăă«ăŒăăăŻă知çăăŸăă\n\nèšćźăăŒăżăćăćăăăćźąæ§ă«ä»ŁăăŁăŠăŠăŁăžă§ăăăźć€æŽăă«ăŒă æćŸ
ăźé俥ăæš©éăźèšćźăèĄăăăšăă§ăăŸăă";
+"settings_integrations_allow_description" = "ă€ăłăă°ăŹăŒă·ă§ăłăăăŒăžăŁăŒ %@ ăäœżçšăăăšăăăăăăăȘăăžăăŠăŁăžă§ăăăăčăăă«ăŒăăăŻă知çă§ăăŸăă\n\nèšćźăăŒăżăć俥ăăăŠăŒă¶ăŒă«ä»ŁăăŁăŠăŠăŁăžă§ăăăźć€æŽăă«ăŒă ăžăźæćŸ
ăźé俥ăæš©éăŹăă«ăźèšćźăèĄăăăšăă§ăăŸăă";
"settings_integrations_allow_button" = "ă€ăłăă°ăŹăŒă·ă§ăłă知ç";
-"settings_calls_stun_server_fallback_button" = "ăă©ăŒă«ăăăŻăłăŒă«ăąă·ăčăă”ăŒăăŒăèš±ćŻ";
+"settings_calls_stun_server_fallback_button" = "ăă©ăŒă«ăăăŻçšăźé話ăąă·ăčăă”ăŒăăŒăèš±ćŻ";
"settings_key_backup" = "é”ăźăăăŻăąăă";
"settings_integrations" = "ă€ăłăă°ăŹăŒă·ă§ăł";
"settings_discovery_settings" = "ăăŁăčă«ăăȘăŒ";
-"room_multiple_typing_notification" = "%@ăšăăźä»ăźăŠăŒă¶ăŒăć
„ćäžă§ă";
+"room_multiple_typing_notification" = "%@ăšăăźä»ăźăĄăłăăŒ";
"external_link_confirmation_message" = "ăȘăłăŻ %@ ăŻć„ăźă”ă€ăă«ç§»ćăăŸăïŒ%@\n\nç¶èĄăăŠăăăăă§ăăïŒ";
-"room_event_action_delete_confirmation_title" = "æȘé俥ăĄăă»ăŒăžăćé€";
-"room_unsent_messages_cancel_message" = "ăăźă«ăŒă ă«ăăæȘé俥ăźăĄăă»ăŒăžăć
šăŠćé€ăăŠăăăăăă§ăăïŒ";
-"room_unsent_messages_cancel_title" = "æȘé俥ăĄăă»ăŒăžăćé€";
-"room_message_replying_to" = "%@ă«èżäżĄäž";
+"room_event_action_delete_confirmation_title" = "æȘé俥ăźăĄăă»ăŒăžăćé€";
+"room_unsent_messages_cancel_message" = "ăăźă«ăŒă ăźć
šăŠăźæȘé俥ăźăĄăă»ăŒăžăćé€ăăŠăăăăă§ăăïŒ";
+"room_unsent_messages_cancel_title" = "æȘé俥ăźăĄăă»ăŒăžăćé€";
+"room_message_replying_to" = "%@ă«èżäżĄăăŠăăŸă";
"room_message_editing" = "ç·šéäž";
"room_accessiblity_scroll_to_bottom" = "ăăĄă°ăäžăŸă§ăčăŻăăŒă«";
"room_member_power_level_short_custom" = "ă«ăčăżă ";
"room_member_power_level_short_moderator" = "ăąăăŹăŒăżăŒ";
-"room_member_power_level_custom_in" = "ă«ăčăżă (%@) in %@";
+"room_member_power_level_custom_in" = "ă«ăčăżă ïŒ%@ïŒïŒ%@";
"room_member_power_level_short_admin" = "知çè
";
"room_member_power_level_moderator_in" = "%@ăźăąăăŹăŒăżăŒ";
"room_member_power_level_admin_in" = "%@ăźçźĄçè
";
@@ -735,58 +735,58 @@
"room_participants_action_security_status_warning" = "èŠć";
"room_participants_action_security_status_complete_security" = "ă»ăă„ăȘăăŁăŒăçąșèȘ";
"room_participants_action_security_status_verify" = "èȘ蚌";
-"room_participants_action_security_status_verified" = "æ€èšŒæžăż";
+"room_participants_action_security_status_verified" = "èȘ蚌æž";
"room_participants_action_section_security" = "ă»ăă„ăȘăăŁăŒ";
-"room_participants_start_new_chat_error_using_user_email_without_identity_server" = "IDă”ăŒăăŒăèšćźăăăŠăăȘăăăăăĄăŒă«ăąăăŹăčăäœżăŁăŠéŁç”Ąć
ăšăăŁăăăéć§ăăăăšăă§ăăŸăăă";
+"room_participants_start_new_chat_error_using_user_email_without_identity_server" = "IDă”ăŒăăŒăèšćźăăăŠăăȘăăăăăĄăŒă«ăąăăŹăčăäœżçšăăŠéŁç”Ąć
ăšăăŁăăăéć§ăăăăšăŻă§ăăŸăăă";
"room_participants_filter_room_members_for_dm" = "ăĄăłăăŒăæ€çŽą";
"room_participants_remove_third_party_invite_prompt_msg" = "æćŸ
ăćăæ¶ăăŠăăăăă§ăăïŒ";
"room_participants_leave_prompt_msg_for_dm" = "éćșăăŠăăăăă§ăăïŒ";
"room_participants_leave_prompt_title_for_dm" = "éćș";
"contacts_address_book_no_identity_server" = "IDă”ăŒăăŒăèšćźăăăŠăăŸăă";
-"rooms_empty_view_information" = "ă«ăŒă ăŻéć
Źéă§ăć
Źéă§ăăăăăăă°ă«ăŒăăăŁăăă«æé©ă§ăă+ăăżăăăăăšăæąă«ăăă«ăŒă ăèŠă€ăăăăæ°ăăă«ăŒă ăäœăŁăăăăăăšăă§ăăŸăă";
+"rooms_empty_view_information" = "ă«ăŒă ăŻéć
Źéă§ăć
Źéă§ăăăăăăă°ă«ăŒăăăŁăăă«æé©ă§ăăïŒăăżăăăăăšăæąă«ăăă«ăŒă ăèŠă€ăăăăæ°ăăă«ăŒă ăäœăŁăăăăăăšăă§ăăŸăă";
"rooms_empty_view_title" = "ă«ăŒă ";
"people_empty_view_information" = "èȘ°ăšă§ăćźć
šă«ăăŁăăă§ăăŸăăïŒăăżăăăăăšéŁç”Ąć
ăèżœć ă§ăăŸăă";
"people_empty_view_title" = "éŁç”Ąć
";
-"room_creation_error_invite_user_by_email_without_identity_server" = "IDă”ăŒăăŒăèšćźăăăŠăăȘăăăăăĄăŒă«ă§ćć è
ăèżœć ăăăăšăă§ăăŸăăă";
+"room_creation_error_invite_user_by_email_without_identity_server" = "IDă”ăŒăăŒăèšćźăăăŠăăȘăăăăăĄăŒă«ă§ăŻćć è
ăèżœć ă§ăăŸăăă";
// Errors
-"error_user_already_logged_in" = "ä»ăźăăŒă ă”ăŒăăŒă«æ„ç¶ăăăăšăăŠăăăăă§ăăăă”ă€ăłăąăŠăăăŸăăïŒ";
+"error_user_already_logged_in" = "ä»ăźăăŒă ă”ăŒăăŒă«æ„ç¶ăăăăšăăŠăăăăă§ăăă”ă€ăłăąăŠăăăŸăăïŒ";
"social_login_button_title_sign_up" = "%@ă§ă”ă€ăłăąăă";
"social_login_button_title_sign_in" = "%@ă§ă”ă€ăłă€ăł";
-"social_login_button_title_continue" = "ç¶ăăŻăăĄă%@";
-"social_login_list_title_sign_up" = "ăăăăŻ";
-"social_login_list_title_sign_in" = "ăăăăŻ";
+"social_login_button_title_continue" = "%@ă§ç¶èĄ";
+"social_login_list_title_sign_up" = "ăŸăăŻ";
+"social_login_list_title_sign_in" = "ăŸăăŻ";
// Social login
-"social_login_list_title_continue" = "ç¶ăăŻăăĄă";
-"auth_softlogout_clear_data_sign_out_msg" = "ăăźç«Żæ«ă«çŸćšäżćăăăŠăăć
šăŠăźăăŒăżăæ¶ć»ăăŠăăăăă§ăăïŒćăłă”ă€ăłă€ăłăăăšăąă«ăŠăłăăăŒăżăăĄăă»ăŒăžă«ăąăŻă»ăčă§ăăŸăă";
-"auth_softlogout_clear_data_sign_out_title" = "ç¶èĄăăŠăăăăă§ăăïŒ";
-"auth_softlogout_clear_data_button" = "ć
šăŠăźăăŒăżăăŻăȘăą";
-"auth_softlogout_clear_data_message_2" = "ăăźç«Żæ«ăźäœżçšăç”äșăăć Žćăăć„ăźăąă«ăŠăłăă«ă”ă€ăłă€ăłăăăć ŽćăŻăăŻăȘăąăăŠăă ăăă";
-"auth_softlogout_clear_data_message_1" = "èŠćïŒćäșșăăŒăżïŒæć·é”ăć«ăïŒăăăźç«Żæ«ă«ăŸă äżćăăăŠăăŸăă";
-"callbar_return" = "ăăçŽă";
-"callbar_active_and_multiple_paused" = "ăąăŻăăŁăăȘé話ïŒ%@ïŒÂ· %@ăźäžæćæąăăăé話";
-"callbar_only_multiple_paused" = "äžæćæąăă%@ăźé話";
-"callbar_only_single_paused" = "é話ăźäžæćæą";
-"store_promotional_text" = "ăȘăŒăăłăăăăŻăŒăŻäžă§ăă©ă€ăă·ăŒăäżè·ăăăăŁăăăąăăȘăăăȘăèȘèș«ă§ăłăłăăăŒă«ă§ăăăăă«éäžć€źéæš©ćïŒćæŁćïŒăăăŠăăŸăăăăŒăżăă€ăăłă°ăăăăŻăăąăă”ăŒăăăŒăăŁă«ăăăąăŻă»ăčăŻăăăŸăăă";
+"social_login_list_title_continue" = "æŹĄă§ç¶èĄ";
+"auth_softlogout_clear_data_sign_out_msg" = "ăăźç«Żæ«ă«çŸćšäżćăăăŠăăć
šăŠăźăăŒăżăæ¶ć»ăăŠăăăăă§ăăïŒăąă«ăŠăłăăźăăŒăżăăĄăă»ăŒăžă«ăąăŻă»ăčăăă«ăŻăćăłă”ă€ăłă€ăłăăŠăă ăăă";
+"auth_softlogout_clear_data_sign_out_title" = "ăăăăă§ăăïŒ";
+"auth_softlogout_clear_data_button" = "ć
šăŠăźăăŒăżăæ¶ć»";
+"auth_softlogout_clear_data_message_2" = "ăăźç«Żæ«ăźäœżçšăç”äșăăăăŸăăŻć„ăźăąă«ăŠăłăă«ă”ă€ăłă€ăłăăć ŽćăŻăćäșșăăŒăżăæ¶ć»ăăŠăă ăăă";
+"auth_softlogout_clear_data_message_1" = "èŠćïŒăăȘăăźćäșșăăŒăżïŒæć·é”ăć«ăïŒăăăăźç«Żæ«ă«ăŸă äżćăăăŠăăŸăă";
+"callbar_return" = "æăèżă";
+"callbar_active_and_multiple_paused" = "1件ăźăąăŻăăŁăăȘé話ïŒ%@ïŒă»%@件ăźäžæćæąăăăé話";
+"callbar_only_multiple_paused" = "äžæćæąăă%@件ăźé話";
+"callbar_only_single_paused" = "äžæćæąăăé話";
+"store_promotional_text" = "ăȘăŒăăłăȘăăăăŻăŒăŻäžă§ăă©ă€ăă·ăŒăäżè·ăăăăŁăăă»ăłă©ăăŹăŒă·ă§ăłăąăăȘăăăȘăèȘèș«ă§ăłăłăăăŒă«ă§ăăăăă«éäžć€źéæš©ćïŒćæŁćïŒăăăŠăăŸăăăăŒăżăă€ăăłă°ăăăăŻăăąă珏äžè
ă«ăăăąăŻă»ăčăŻăăăŸăăă";
"auth_softlogout_clear_data" = "ćäșșăăŒăżăæ¶ć»";
-"auth_softlogout_recover_encryption_keys" = "æć·ćăăăăĄăă»ăŒăžăă©ăźç«Żæ«ă§ăèȘăăăăă«ăă”ă€ăłă€ăłăăŠăăźç«Żæ«ă«ăźăżäżćăăăŠăăæć·é”ăćăæ»ăăŠăă ăăă";
-"auth_softlogout_reason" = "ăăŒă ă”ăŒăăŒ(%1$@)ăźçźĄçè
ă%2$@(%3$@)ăăă”ă€ăłăąăŠăăăăŸăăă";
+"auth_softlogout_recover_encryption_keys" = "æć·é”ăŻăăźç«Żæ«ă«ăźăżäżćăăăŠăăŸăăäżè·ăăăăĄăă»ăŒăžăă©ăźç«Żæ«ă§ăèȘăă«ăŻăăăźæć·é”ăćż
èŠă«ăȘăăŸăăă”ă€ăłă€ăłăăŠæć·é”ăćŸ©ć
ăăŠăă ăăă";
+"auth_softlogout_reason" = "ăăȘăăźăăŒă ă”ăŒăăŒïŒ%1$@ïŒăźçźĄçè
ăăăăȘăăăąă«ăŠăłă %2$@ ïŒ%3$@ïŒăăă”ă€ăłăąăŠăăăăŸăăă";
"auth_softlogout_sign_in" = "ă”ă€ăłă€ăł";
"auth_softlogout_signed_out" = "ă”ă€ăłăąăŠăăăŸăă";
-"auth_autodiscover_invalid_response" = "çĄćčăȘăăŒă ă”ăŒăăŒçșèŠăŹăčăăłăč";
-"auth_accept_policies" = "ăăźăăŒă ă”ăŒăăŒăźăăȘă·ăŒăçąșèȘăăŠćæăăŠăă ăă:";
-"auth_reset_password_error_is_required" = "IDă”ăŒăăŒăèšćźăăăŠăăŸăăïŒăăčăŻăŒăăăȘă»ăăăăăăă«ă”ăŒăăŒăȘăă·ă§ăłă«èżœć ăăŠăă ăăă";
-"auth_forgot_password_error_no_configured_identity_server" = "IDă”ăŒăăŒăèšćźăăăŠăăŸăăïŒăăčăŻăŒăăăȘă»ăăăăăăă«IDă”ăŒăăŒăèżœć ăăŠăă ăăă";
-"auth_phone_is_required" = "IDă”ăŒăăŒăèšćźăăăŠăăȘăăźă§ăăăčăŻăŒăăăȘă»ăăăăăăă«é»è©±çȘć·ăèżœć ăăăăšăŻă§ăăŸăăă";
-"auth_email_is_required" = "IDă”ăŒăăŒăèšćźăăăŠăăȘăăźă§ăăăčăŻăŒăăăȘă»ăăăăăăă«ăĄăŒă«ăąăăŹăčăèżœć ăăăăšăŻă§ăăŸăăă";
+"auth_autodiscover_invalid_response" = "ăăŒă ă”ăŒăăŒăźăăŁăčă«ăăȘăŒïŒçșèŠïŒă«éąăăäžæŁăȘćżçă§ă";
+"auth_accept_policies" = "ăăźăăŒă ă”ăŒăăŒăźéć¶æčéăçąșèȘăăćæăăŠăă ăăïŒ";
+"auth_reset_password_error_is_required" = "IDă”ăŒăăŒăèšćźăăăŠăăŸăăïŒMatrixăźăąă«ăŠăłăăźăăčăŻăŒăăćèšćźăăăăă«ă”ăŒăăŒăȘăă·ă§ăłă«èżœć ăăŠăă ăăă";
+"auth_forgot_password_error_no_configured_identity_server" = "IDă”ăŒăăŒăèšćźăăăŠăăŸăăïŒăăčăŻăŒăăćèšćźăăăăă«IDă”ăŒăăŒăèżœć ăăŠăă ăăă";
+"auth_phone_is_required" = "IDă”ăŒăăŒăèšćźăăăŠăăȘăăăăMatrixăąă«ăŠăłăăźăăčăŻăŒăăźćèšćźă«äœżçšăăé»è©±çȘć·ăèżœć ăăăăšăă§ăăŸăăă";
+"auth_email_is_required" = "IDă”ăŒăăŒăèšćźăăăŠăăȘăăăăMatrixăąă«ăŠăłăăźăăčăŻăŒăăćèšćźăăéă«äœżçšăăăĄăŒă«ăąăăŹăčăèżœć ăăăăšăă§ăăŸăăă";
"auth_add_email_phone_message_2" = "ăąă«ăŠăłăćŸ©æ§çšăźăĄăŒă«ăąăăŹăčăèšćźăăŸăăćŸăăăȘăă·ă§ăłă§ăĄăŒă«ăąăăŹăčăé»è©±çȘć·ăäœżçšăăŠç„äșșă«èŠă€ăăŠăăăăăăă«ă§ăăŸăă";
"auth_add_phone_message_2" = "é»è©±çȘć·ăèšćźăăŸăăćŸăăăȘăă·ă§ăłă§ç„äșșă«èŠă€ăăŠăăăăăăă«ă§ăăŸăă";
"auth_add_email_message_2" = "ăąă«ăŠăłăćŸ©æ§çšăźăĄăŒă«ăąăăŹăčăèšćźăăŸăăćŸăăăȘăă·ă§ăłă§ç„äșșă«èŠă€ăăŠăăăăăăă«ă§ăăŸăă";
"less" = "ăăă";
"more" = "ăăŁăš";
-"switch" = "ćăæżă";
+"switch" = "ćăæżăă";
"joined" = "ćć æž";
"skip" = "ăčăăă";
@@ -795,7 +795,7 @@
// AuthenticatedSessionViewControllerFactory
"authenticated_session_flow_not_supported" = "ăăźăąăăȘăŻăăăŒă ă”ăŒăăŒăźèȘ蚌æ©æ§ăă”ăăŒăăăŠăăŸăăă";
-"manage_session_sign_out" = "ă»ăă·ă§ăłăăă”ă€ăłăąăŠă";
+"manage_session_sign_out" = "ăăźă»ăă·ă§ăłăăă”ă€ăłăąăŠă";
"manage_session_not_trusted" = "äżĄé ŒăăăŠăăŸăă";
"manage_session_trusted" = "äżĄé Œæž";
"manage_session_name" = "ă»ăă·ă§ăłć";
@@ -803,75 +803,75 @@
// Manage session
"manage_session_title" = "ă»ăă·ă§ăłă知ç";
-"security_settings_user_password_description" = "ăąă«ăŠăłăăźăăčăŻăŒăăć
„ćăăŠæŹäșșçąșèȘăèĄăŁăŠăă ăă";
+"security_settings_user_password_description" = "Matrixăźăąă«ăŠăłăăźăăčăŻăŒăăć
„ćăăŠæŹäșșçąșèȘăèĄăŁăŠăă ăă";
"security_settings_complete_security_alert_message" = "çŸćšăźă»ăă·ă§ăłăźă»ăă„ăȘăăŁăŒăćźäșăăăćż
èŠăăăăŸăă";
-"security_settings_blacklist_unverified_devices_description" = "ć
šăŠăźă»ăă·ă§ăłăèȘ蚌ăăŠăäżĄé Œă§ăăăăźăšăăŠăăŒăŻăăĄăă»ăŒăžăé俥ăăŸăă";
+"security_settings_blacklist_unverified_devices_description" = "ć
šăŠăźă»ăă·ă§ăłăèȘ蚌ăăäżĄé ŒæžăšăăŠăăŒăŻăăŠăĄăă»ăŒăžăé俥ăăŸăă";
"security_settings_blacklist_unverified_devices" = "äżĄé ŒăăŠăăȘăă»ăă·ă§ăłă«ăŻăĄăă»ăŒăžăé俥ăăȘă";
-"security_settings_advanced" = "äžçŽè
ćă";
+"security_settings_advanced" = "é«ćșŠăȘèšćź";
"security_settings_export_keys_manually" = "æćă§é”ăăšăŻăčăăŒă";
-"security_settings_cryptography" = "æć·æèĄ";
+"security_settings_cryptography" = "æć·ć";
"security_settings_crosssigning_reset" = "ăŻăăčçœČćăăȘă»ăă";
-"security_settings_crosssigning_info_ok" = "ăŻăăčçœČćăæćčă§ăă";
+"security_settings_crosssigning_info_ok" = "ăŻăăčçœČćăć©çšă§ăăŸăă";
"security_settings_crosssigning_info_trusted" = "ăŻăăčçœČćăæćčă«ăȘăŁăŠăăŸăăăŻăăčçœČćă«ćșă„ăăŠä»ăźăŠăŒă¶ăŒăèȘćăźä»ăźă»ăă·ă§ăłăäżĄé ŒăăăăšăŻă§ăăŸăăăăăźă»ăă·ă§ăłă«ăŻăŻăăčçœČćçšăźç§ćŻé”ăăȘăăăăăăźă»ăă·ă§ăłăăăŻăăčçœČćăèĄăăăšăŻă§ăăŸăăăăăźă»ăă·ă§ăłăźă»ăă„ăȘăăŁăŒăćźäșăăŠăă ăăă";
"security_settings_crosssigning_info_exists" = "ăąă«ăŠăłăă«ăŻăŻăăčçœČćIDăăăăŸăăăăăźă»ăă·ă§ăłăŻăŸă äżĄé ŒăăăŠăăŸăăăăăźă»ăă·ă§ăłăźă»ăă„ăȘăăŁăŒăćźäșăăŠăă ăăă";
-"security_settings_crosssigning_info_not_bootstrapped" = "ăŻăăčçœČćăăŸă èĄăăăŠăăŸăăă";
+"security_settings_crosssigning_info_not_bootstrapped" = "ăŻăăčçœČćăăŸă èšćźăăăŠăăŸăăă";
"security_settings_crosssigning" = "ăŻăăčçœČć";
"security_settings_backup" = "ăĄăă»ăŒăžăźăăăŻăąăă";
"security_settings_secure_backup_delete" = "ăăăŻăąăăăźćé€";
"security_settings_secure_backup_synchronise" = "ćæ";
"security_settings_secure_backup_setup" = "èšćź";
-"security_settings_secure_backup_description" = "ă»ăă·ă§ăłă«ăąăŻă»ăčă§ăăȘăăȘăć Žćă«ćăăŠăăąă«ăŠăłăăăŒăżăšæć·é”ăăăăŻăąăăăăŸăăé”ăŻäžæăźă»ăă„ăȘăăŁăŒăăŒă§äżè·ăăăŸăă";
+"security_settings_secure_backup_description" = "ă»ăă·ă§ăłă«ăąăŻă»ăčă§ăăȘăăȘăć Žćă«ćăăŠăăąă«ăŠăłăăăŒăżăšæć·é”ăăăăŻăąăăăăŸăăăăé”ăŻäžæăźă»ăă„ăȘăăŁăŒăăŒă§äżè·ăăăŸăă";
"security_settings_secure_backup" = "ćźć
šăȘăăăŻăąăă";
-"security_settings_crypto_sessions_description_2" = "èŠèŠăăźăȘăăă°ă€ăłăăăć ŽćăŻăMatrixăąă«ăŠăłăăźăăčăŻăŒăăć€æŽăăăăăŻăąăăăăȘă»ăăăăŠăă ăăă";
+"security_settings_crypto_sessions_description_2" = "èŠèŠăăźăȘăăă°ă€ăłăăăć ŽćăŻăMatrixăźăąă«ăŠăłăăźăăčăŻăŒăăć€æŽăăăăăŻăąăăăăȘă»ăăăăŠăă ăăă";
"security_settings_crypto_sessions_loading" = "ă»ăă·ă§ăłăèȘăżèŸŒăă§ăăŸăâŠ";
"security_settings_crypto_sessions" = "ă»ăă·ă§ăł";
// Security settings
"security_settings_title" = "ă»ăă„ăȘăăŁăŒ";
"settings_show_NSFW_public_rooms" = "NSFWăăăȘăăŻă«ăŒă ăèĄšç€ș";
-"settings_identity_server_no_is_description" = "çŸćšăIDă”ăŒăăŒăäœżçšăăŠăăŸăăăăăȘăăźç„ăŁăŠăăéŁç”Ąć
ăçșèŠăăăăăăźéŁç”Ąć
ăăçșèŠăăăăăă«ăăă«ăŻă仄äžă§IDă”ăŒăăŒăèżœć ăăŠăă ăăă";
+"settings_identity_server_no_is_description" = "çŸćšăIDă”ăŒăăŒăäœżçšăăŠăăŸăăăéŁç”Ąć
ăèŠă€ăăăăéŁç”Ąć
ăăèŠă€ăăŠăăăŁăăăăă«ăŻă仄äžă§IDă”ăŒăăŒăèżœć ăăŠăă ăăă";
"settings_identity_server_no_is" = "IDă”ăŒăăŒăèšćźăăăŠăăŸăă";
-"settings_identity_server_description" = "äžèšă§èšćźăăIDă”ăŒăăŒăäœżăŁăŠăèȘćăźç„ăćăăçșèŠăăăăçșèŠăăăăăăăăšăă§ăăŸăă";
+"settings_identity_server_description" = "äžèšă§èšćźăăIDă”ăŒăăŒăäœżăăšăèȘćăźéŁç”Ąć
ăèŠă€ăăăăéŁç”Ąć
ăăèŠă€ăăŠăăăŁăăăăăăšăă§ăăŸăă";
"settings_discovery_three_pid_details_enter_sms_code_action" = "SMSăąăŻăăŁăăŒă·ă§ăłăłăŒăăć
„ć";
"settings_discovery_three_pid_details_cancel_email_validation_action" = "ăĄăŒă«ăźèȘ蚌ăăăŁăłă»ă«";
-"settings_discovery_three_pid_details_revoke_action" = "ćăæ¶ă";
+"settings_discovery_three_pid_details_revoke_action" = "ćăæ¶ă";
"settings_discovery_three_pid_details_share_action" = "ć
±æ";
"settings_discovery_three_pid_details_title_email" = "ăĄăŒă«ăąăăŹăčă知ç";
"settings_discovery_three_pid_details_title_phone_number" = "é»è©±çȘć·ă知ç";
-"settings_discovery_three_pid_details_information_phone_number" = "ä»ăźăŠăŒă¶ăŒăăăȘăăçșèŠăăăăă«ăŒă ă«æćŸ
ăăéă«äœżçšă§ăăé»è©±çȘć·ăźèšćźă知çăăŸăăăąă«ăŠăłăăžé»è©±çȘć·ăźèżœć ăćé€ăă§ăăŸăă";
-"settings_discovery_three_pid_details_information_email" = "ä»ăźăŠăŒă¶ăŒăăăȘăăçșèŠăăăăă«ăŒă ă«æćŸ
ăăéă«äœżçšă§ăăăĄăŒă«ăąăăŹăčăźèšćźă知çăăŸăăăąă«ăŠăłăăžăĄăŒă«ăąăăŹăčăźèżœć ăćé€ăă§ăăŸăă";
+"settings_discovery_three_pid_details_information_phone_number" = "ä»ăźăŠăŒă¶ăŒăăăȘăăçșèŠăăăăă«ăŒă ă«æćŸ
ăăăăăéă«äœżçšă§ăăé»è©±çȘć·ăźèšćźă知çăăŸăăăąă«ăŠăłăç»éąă§é»è©±çȘć·ăèżœć ăćé€ă§ăăŸăă";
+"settings_discovery_three_pid_details_information_email" = "ä»ăźăŠăŒă¶ăŒăăăȘăăçșèŠăăăăă«ăŒă ă«æćŸ
ăăăăăéă«äœżçšă§ăăăĄăŒă«ăąăăŹăčăźèšćźă知çăăŸăăăąă«ăŠăłăç»éąă§ăĄăŒă«ăąăăŹăčăèżœć ăćé€ă§ăăŸăă";
"settings_discovery_error_message" = "ăšă©ăŒăçșçăăŸăăăćè©ŠèĄăăŠăă ăăă";
"settings_discovery_three_pids_management_information_part3" = "ă";
"settings_discovery_three_pids_management_information_part2" = "ăŠăŒă¶ăŒèšćź";
-"settings_discovery_three_pids_management_information_part1" = "ä»ăźăŠăŒă¶ăŒăăăȘăăçșèŠăăăăă«ăŒă ă«æćŸ
ăăéă«äœżçšăăăĄăŒă«ăąăăŹăčăé»è©±çȘć·ă知çă§ăăŸăăăăźăȘăčăă«ăĄăŒă«ăąăăŹăčăé»è©±çȘć·ăèżœć ăăăăćé€ăăăăăăăšăă§ăăŸăă ";
-"settings_discovery_terms_not_signed" = "ăĄăŒă«ăąăăŹăčăé»è©±çȘć·ă§ăąă«ăŠăłăăèŠă€ăăŠăăăăăăă«ăăă«ăŻăIDă”ăŒăăŒïŒ%@ïŒăźć©çšèŠçŽăžăźćæăćż
èŠă§ăă";
-"settings_discovery_no_identity_server" = "çŸćšăIDă”ăŒăăŒăäœżçšăăŠăăŸăăăăăȘăăźç„ăŁăŠăăéŁç”Ąć
ăăçșèŠăăăăăă«ăăă«ăŻăIDă”ăŒăăŒăèżœć ăăŠăă ăăă";
-"settings_key_backup_delete_confirmation_prompt_msg" = "ăăăăă§ăăïŒé”ăé©ćă«ăăăŻăąăăăăăŠăăȘăăšăæć·ćăăăăĄăă»ăŒăžă怱ăăăšăăăăŸăă";
+"settings_discovery_three_pids_management_information_part1" = "ä»ăźăŠăŒă¶ăŒăăăȘăăçșèŠăăăăă«ăŒă ă«æćŸ
ăăéă«äœżçšăăăĄăŒă«ăąăăŹăčăé»è©±çȘć·ă知çă§ăăŸăăăăźăȘăčăă«ăăĄăŒă«ăąăăŹăčăé»è©±çȘć·ăèżœć ăăăăćé€ăăăăăăăšăă§ăăŸăă ";
+"settings_discovery_terms_not_signed" = "ăĄăŒă«ăąăăŹăčăé»è©±çȘć·ă§ăąă«ăŠăłăăèŠă€ăăŠăăăăăăă«ăăă«ăŻăIDă”ăŒăăŒ %@ ăźć©çšèŠçŽăžăźćæăćż
èŠă§ăă";
+"settings_discovery_no_identity_server" = "çŸćšăIDă”ăŒăăŒăäœżçšăăŠăăŸăăăéŁç”Ąć
ăăèŠă€ăăŠăăăăăă«ăăă«ăŻăIDă”ăŒăăŒăèżœć ăăŠăă ăăă";
+"settings_key_backup_delete_confirmation_prompt_msg" = "ăăăăă§ăăïŒé”ăé©ćă«ăăăŻăąăăăăăŠăăȘăăšăæć·ćăăăăĄăă»ăŒăžăèȘăżćăăȘăăȘăŁăŠăăŸăăŸăă";
"settings_key_backup_button_connect" = "ăăźă»ăă·ă§ăłăé”ăźăăăŻăąăăă«æ„ç¶";
-"settings_key_backup_button_delete" = "ăăăŻăąăăăźćé€";
+"settings_key_backup_button_delete" = "ăăăŻăąăăăćé€";
"settings_key_backup_button_restore" = "ăăăŻăąăăăăćŸ©ć
";
"settings_key_backup_button_create" = "é”ăźăăăŻăąăăăäœżçšéć§";
"settings_key_backup_info_trust_signature_invalid_device_unverified" = "ăăăŻăąăăă«ăŻ%@ă«ăăçĄćčăȘçœČćăăăăŸă";
"settings_key_backup_info_trust_signature_invalid_device_verified" = "ăăăŻăąăăă«ăŻ%@ă«ăăçĄćčăȘçœČćăăăăŸă";
"settings_key_backup_info_trust_signature_valid_device_unverified" = "ăăăŻăąăăă«ăŻ%@ă«ăăçœČćăăăăŸă";
"settings_key_backup_info_trust_signature_valid_device_verified" = "ăăăŻăąăăă«ăŻ%@ă«ăăæćčăȘçœČćăăăăŸă";
-"settings_key_backup_info_trust_signature_valid" = "ăăăŻăąăăă«ăŻăăźă»ăă·ă§ăłăźæćčăȘçœČćăăăăŸă";
-"settings_key_backup_info_trust_signature_unknown" = "ăăăŻăąăăă«ăŻIDïŒ%@ă«ăăă»ăă·ă§ăłăźçœČćăăăăŸă";
-"settings_key_backup_info_progress_done" = "ć
šăŠăźé”ăăăăŻăąăăăăăŠăăŸă";
+"settings_key_backup_info_trust_signature_valid" = "ăăăŻăąăăă«ăŻăăźă»ăă·ă§ăłă«ăăæćčăȘçœČćăăăăŸă";
+"settings_key_backup_info_trust_signature_unknown" = "ăăăŻăąăăă«ăŻăIDïŒ%@ă«ăăă»ăă·ă§ăłăźçœČćăăăăŸă";
+"settings_key_backup_info_progress_done" = "ć
šăŠăźé”ăăăăŻăąăăăăŸăă";
"settings_key_backup_info_progress" = "%@ăźé”ăăăăŻăąăăăăŠăăŸăâŠ";
-"settings_key_backup_info_not_valid" = "ăăźă»ăă·ă§ăłă§ăŻé”ăăăăŻăąăăăăŠăăŸăăăăćŸ©ć
ă«äœżçšăăăăä»ćŸé”ăèżœć ăăăă§ăăăăăŻăąăăăæăŁăŠăăŸăă";
+"settings_key_backup_info_not_valid" = "ăăźă»ăă·ă§ăłă§ăŻé”ăăăăŻăąăăăăŠăăŸăăăăćŸ©ć
ă«äœżçšăăăăé”ăä»ćŸèżœć ăăăă§ăăăăăŻăąăăăæăŁăŠăăŸăă";
"settings_key_backup_info_signout_warning" = "é”ă怱ăăăȘăăăăă”ă€ăłăąăŠăăăćă«ăăăŻăąăăăăŠăă ăăă";
"settings_key_backup_info" = "æć·ćăăăăĄăă»ăŒăžăŻăăšăłăăăŒăšăłăăźæć·ćă«ăăŁăŠäżè·ăăăŠăăŸăăăăăăźæć·ćăăăăĄăă»ăŒăžăèȘăăăăźé”ăæăŁăŠăăăźăŻăăăȘăăšć俥è
ă ăă§ăă";
"settings_labs_message_reaction" = "ç””æćă§ăĄăă»ăŒăžă«ććż";
"settings_security" = "ă»ăă„ăȘăăŁăŒ";
-"settings_three_pids_management_information_part3" = "";
-"settings_three_pids_management_information_part2" = "ăăŁăčă«ăăȘăŒ";
-"store_full_description" = "ElementăŻăŸăŁăăæ°ăăăĄăă»ăłăžăŁăŒăąăăȘă§ăă\n\n1. ăăȘăèȘèș«ăăă©ă€ăă·ăŒăăłăłăăăŒă«ăăăăšăćŻèœă«ăăŸăă\n2. MatrixăăăăŻăŒăŻă«ăăèȘ°ăšă§ăăłăă„ăă±ăŒă·ă§ăłă§ăăă ăă§ăȘăăSlackăȘă©ăźăąăăȘăšéŁæșăăă°ăä»ăźăăăăŻăŒăŻăšăăłăă„ăă±ăŒă·ă§ăłăèĄăăăšăă§ăăŸăă\n3. ćșćăăăŒăżăă€ăăłă°ăăăăŻăăąăăŠăŒă¶ăŒăźćČă蟌ăżăăăăăȘăăćźăăŸăă\n4. ăšăłăăăŒăšăłăæć·ćăšăŻăăčçœČćă«ăăŁăŠăăȘăăäżè·ăăŸăă\n\nElementăŻćæŁćïŒéäžć€źéæš©ćïŒă§ăȘăŒăăłăœăŒăčă§ăăăăăä»ăźăĄăă»ăłăžăŁăŒăąăăȘăšćźć
šă«ç°ăȘăŁăŠăăŸăă\n\nElementă§ăŻăăăȘăèȘèș«ăă”ăŒăăŒăéć¶ăăăăšăăă”ăŒăăŒăéžă¶ăăšăă§ăăŸăăăăȘăăźăăŒăżăšäŒè©±ă«éąăăăă©ă€ăă·ăŒăæææš©ăŻăăăȘăèȘèș«ă§çźĄçă§ăăŸăăăăă«ăElementăŻéăăăăăăăŻăŒăŻă«ăąăŻă»ăčăăăźă§ăElementăźăŠăŒă¶ăŒä»„ć€ăšă話ăăăšăă§ăăŸăăăăăăăăăŠćźć
šă§ăă\n\nElementăŻMatrixăŒăŒăȘăŒăăłăȘćæŁćé俥ăźæšæșèŠæ ŒăŒăŒă§ćäœăăăăăăăăć
šăŠăćźçŸăăăăšăă§ăăŠăăŸăă\n\nElementă§ăŻăă©ăźă”ăŒăăŒăäœżçšăăăăăăèȘèș«ă§ElementăźăąăăȘăăæ±șăăăăšăă§ăăŸăă\n\n1. éçșè
ăăăčăăă matrix.org ăźăăăȘăăŻă”ăŒăăŒă§çĄæăąă«ăŠăłăăććŸăăă\n2. ăăȘăèȘèș«ăă”ăŒăăŒăéć¶ăăăąă«ăŠăłăă知çăăă\n3. Element Matrix ServicesăźăăčăăŁăłă°ăă©ăăăă©ăŒă ă«ć ć
„ăăă«ăčăżă ă”ăŒăăŒäžă§ăąă«ăŠăłăăäœăă\n\năȘăElementăéžă¶ăčăăȘăźăïŒ\n\nèȘćăźăăŒăżăăèȘćă§ææ: ăăŒăżăăĄăă»ăŒăžăäżçźĄăăć ŽæăèȘćă§æ±șăăăăšăă§ăăŸăăăăŒăżăææăăłăłăăăŒă«ăăăźăŻăăăȘăèȘèș«ă§ăăăăŒăżăè§Łæăăă珏äžè
ă«ăăŒăżăæžĄăăăăă淚性ITäŒæ„ă§ăŻăăăŸăăă\n\năȘăŒăăłăȘăĄăă»ăŒăžăłă°ăšăłă©ăăŹăŒă·ă§ăł: MatrixăăăăŻăŒăŻäžăźèȘ°ăšă§ăăçžæăElementăä»ăźMatrixăąăăȘăäœżăŁăŠăăăăăăă«ăŻSlackăIRCăXMPPăźăăăȘä»ăźăĄăă»ăŒăžăłă°ă·ăčăă ăäœżăŁăŠăăăă«éąăăăăăăŁăăăăăăăšăă§ăăŸăă\n\néćžžă«ćźć
š: æŹç©ăźăšăłăă»ăăŒă»ăšăłăăźæć·ćïŒäŒè©±ă«ćć ăăŠăăäșșă ăăăĄăă»ăŒăžăćŸ©ć·ćă§ăăŸăïŒăšăäŒè©±ćć è
ăźçæŁæ§ăçąșèȘăăăăăźăŻăăčçœČćăèĄăăŸăă\n\nć
æŹçăȘăłăă„ăă±ăŒă·ă§ăł: ăĄăă»ăŒăžăłă°ăéłćŁ°ăăăłăăăȘé話ăăăĄă€ă«ć
±æăç»éąć
±æăăăźä»ć€ăăźæ©èœç”±ćăăăăăăŠăŁăžă§ăăăæäŸăăŸăăă«ăŒă ăăłăă„ăăăŁăŒăç«ăĄäžăăŠéŁç”Ąăćăćăăç©äșăăčă ăŒășă«æăéăăŸăăăă\n\năă€ă§ăăă©ăă«ăăŠă: ć
šăŠăźç«Żæ«ăšăŠă§ăïŒhttps://app.element.ioïŒă§ăĄăă»ăŒăžăźć±„æŽăćæăăăăăăă©ăă«ăăŠăéŁç”Ąăćăăăšăă§ăăŸăă";
+"settings_three_pids_management_information_part3" = "ă§èšćźăăŸăăăă";
+"settings_three_pids_management_information_part2" = "ăăŁăčă«ăăȘăŒïŒçșèŠïŒ";
+"store_full_description" = "ElementăŻăŸăŁăăæ°ăăăĄăă»ăłăžăŁăŒăąăăȘă§ăă\n\n1. ăăȘăèȘèș«ăăă©ă€ăă·ăŒăăłăłăăăŒă«ă§ăăŸăă\n2. MatrixăăăăŻăŒăŻă«ăăèȘ°ăšă§ăăłăă„ăă±ăŒă·ă§ăłă§ăăă ăă§ăȘăăSlackăȘă©ăźăąăăȘăšéŁæșăăă°ăä»ăźăăăăŻăŒăŻăšăăłăă„ăă±ăŒă·ă§ăłăèĄăăăšăă§ăăŸăă\n3. ćșćăăăŒăżăă€ăăłă°ăăăăŻăăąăăŠăŒă¶ăŒăźćČă蟌ăżăăăăăȘăăćźăăŸăă\n4. ăšăłăăăŒăšăłăæć·ćăšăăŻăăčçœČćă«ăăèȘ蚌ă§ăăăȘăăäżè·ăăŸăă\n\nElementăŻćæŁćïŒéäžć€źéæš©ćïŒă§ăȘăŒăăłăœăŒăčă§ăăăăăä»ăźăĄăă»ăłăžăŁăŒăąăăȘăšćźć
šă«ç°ăȘăŁăŠăăŸăă\n\nElementă§ăŻăăăȘăèȘèș«ăă”ăŒăăŒăéć¶ăăăăšăăă”ăŒăăŒăéžă¶ăăšăă§ăăŸăăăăȘăăźăăŒăżăšäŒè©±ă«éąăăăă©ă€ăă·ăŒăæææš©ăŻăăăȘăèȘèș«ă§çźĄçă§ăăŸăăăăă«ăElementăŻéăăăăăăăŻăŒăŻă«ăąăŻă»ăčăăăźă§ăElementăźăŠăŒă¶ăŒä»„ć€ăšă話ăăăšăă§ăăŸăăăăăăăăăŠćźć
šă§ăă\n\nElementăŻMatrixââăȘăŒăăłăȘćæŁćé俥ăźæšæșèŠæ Œââă§ćäœăăăăăăăăć
šăŠăćźçŸăăăăšăă§ăăŠăăŸăă\n\nElementă§ăŻăă©ăźă”ăŒăăŒăäœżçšăăăăăăèȘèș«ă§ElementăźăąăăȘăăæ±șăăăăšăă§ăăŸăă\n\n1. éçșè
ăăăčăăă matrix.org ăźăăăȘăăŻă”ăŒăăŒă§çĄæăąă«ăŠăłăăććŸăăă\n2. ăăȘăèȘèș«ăă”ăŒăăŒăéć¶ăăăąă«ăŠăłăă知çăăă\n3. Element Matrix ServicesăźăăčăăŁăłă°ăă©ăăăă©ăŒă ă«ć ć
„ăăă«ăčăżă ă”ăŒăăŒäžă§ăąă«ăŠăłăăäœăă\n\năȘăElementăéžă¶ăčăăȘăźăïŒ\n\nèȘćăźăăŒăżăăèȘćă§ææïŒăăŒăżăăĄăă»ăŒăžăäżçźĄăăć ŽæăèȘćă§æ±șăăăăšăă§ăăŸăăăăŒăżăææăăłăłăăăŒă«ăăăźăŻăăăȘăèȘèș«ă§ăăăăŒăżăè§Łæăăă珏äžè
ă«ăăŒăżăæžĄăăăăă淚性ITäŒæ„ă§ăŻăăăŸăăă\n\năȘăŒăăłăȘăĄăă»ăŒăžăłă°ăšăłă©ăăŹăŒă·ă§ăłïŒMatrixăăăăŻăŒăŻäžăźèȘ°ăšă§ăăçžæăElementăä»ăźMatrixăąăăȘăäœżăŁăŠăăăăăăă«ăŻSlackăIRCăXMPPăźăăăȘä»ăźăĄăă»ăŒăžăłă°ă·ăčăă ăäœżăŁăŠăăăă«éąăăăăăăŁăăăăăăăšăă§ăăŸăă\n\néćžžă«ćźć
šïŒæŹç©ăźăšăłăă»ăăŒă»ăšăłăăźæć·ćïŒäŒè©±ă«ćć ăăŠăăäșșă ăăăĄăă»ăŒăžăćŸ©ć·ćă§ăăŸăïŒăšăäŒè©±ćć è
ăźç«Żæ«ăèȘ蚌ăăăăăźăŻăăčçœČćăèĄăăŸăă\n\nć
æŹçăȘăłăă„ăă±ăŒă·ă§ăłïŒăĄăă»ăŒăžăłă°ăéłćŁ°ăăăłăăăȘé話ăăăĄă€ă«ć
±æăç»éąć
±æăăăźä»ć€ăăźæ©èœç”±ćăăăăăăŠăŁăžă§ăăăæäŸăăŸăăă«ăŒă ăăłăă„ăăăŁăŒăç«ăĄäžăăŠéŁç”Ąăćăćăăç©äșăăčă ăŒășă«æăéăăŸăăăă\n\năă€ă§ăăă©ăă«ăăŠăïŒć
šăŠăźç«Żæ«ăšăŠă§ă https://app.element.io ă§ăĄăă»ăŒăžăźć±„æŽăćæăăăăăăă©ăă«ăăŠăéŁç”Ąăćăăăšăă§ăăŸăă";
"user_verification_session_details_additional_information_untrusted_other_user" = "ăŠăŒă¶ăŒăăăźă»ăă·ă§ăłăäżĄé ŒăăăŸă§ăŻăă»ăă·ă§ăłăšăźéă§éć俥ăăăăĄăă»ăŒăžă«ăŻèŠćăèĄšç€șăăăŸăăăŸăăæćă§èȘ蚌ăăăăšăă§ăăŸăă";
-"user_verification_session_details_information_untrusted_other_user" = " æ°ăăă»ăă·ă§ăłăäœżăŁăŠă”ă€ăłă€ăłăăŸăă:";
-"user_verification_session_details_information_untrusted_current_user" = "ăăźă»ăă·ă§ăłăèȘ蚌ăăăăšă§ăäżĄé Œă§ăăăăźăšăăŠăăŒăŻăăæć·ćăăăăĄăă»ăŒăžăžăźăąăŻă»ăčăèš±ćŻăăŸăă";
-"user_verification_session_details_information_trusted_other_user_part2" = " æ€èšŒæžăż:";
-"user_verification_session_details_information_trusted_other_user_part1" = "ăăźă»ăă·ă§ăłăŻćźć
šăȘăăźăšăăŠäżĄé ŒăăăŠăăŸăăăȘăăȘă ";
+"user_verification_session_details_information_untrusted_other_user" = " ăæ°ăăă»ăă·ă§ăłăäœżăŁăŠă”ă€ăłă€ăłăăŸăăïŒ";
+"user_verification_session_details_information_untrusted_current_user" = "ăăźă»ăă·ă§ăłăèȘ蚌ăăŠäżĄé ŒæžăšăăŠăăŒăŻăăæć·ćăăăăĄăă»ăŒăžăžăźăąăŻă»ăčăèš±ćŻă";
+"user_verification_session_details_information_trusted_other_user_part2" = " ăæ€èšŒăăŸăăïŒ";
+"user_verification_session_details_information_trusted_other_user_part1" = "ăăźă»ăă·ă§ăłăŻćźć
šăȘăăźăšăăŠäżĄé ŒăăăŠăăŸăă ";
"user_verification_session_details_information_trusted_current_user" = "ăăźă»ăă·ă§ăłăŻăèȘ蚌ăăăăăćźć
šăȘăăźăšăăŠäżĄé ŒăăăŠăăŸăă";
"user_verification_session_details_untrusted_title" = "äżĄé ŒăăăŠăăŸăă";
@@ -880,17 +880,17 @@
"user_verification_session_details_trusted_title" = "äżĄé Œæž";
"user_verification_sessions_list_session_untrusted" = "äżĄé ŒăăăŠăăŸăă";
"user_verification_sessions_list_session_trusted" = "äżĄé Œæž";
-"user_verification_sessions_list_table_title" = "ă»ăă·ă§ăłäžèŠ§";
-"user_verification_sessions_list_information" = "ăăźă«ăŒă ă«ăăăăźăŠăŒă¶ăŒăšăźăĄăă»ăŒăžăŻăšăłăăăŒăšăłăă§æć·ćăăăŠăă珏äžè
ăèȘăżćăăăšăŻă§ăăŸăăă";
-"user_verification_sessions_list_user_trust_level_unknown_title" = "æȘç„";
+"user_verification_sessions_list_table_title" = "ă»ăă·ă§ăł";
+"user_verification_sessions_list_information" = "ăăźă«ăŒă ă«ăăăăźăŠăŒă¶ăŒăšăźăĄăă»ăŒăžăŻăšăłăăăŒăšăłăă§æć·ćăăăŠăăă珏äžè
ăè§ŁèȘăăăăšăŻă§ăăŸăăă";
+"user_verification_sessions_list_user_trust_level_unknown_title" = "äžæ";
"user_verification_sessions_list_user_trust_level_warning_title" = "èŠć";
// Sessions list
"user_verification_sessions_list_user_trust_level_trusted_title" = "äżĄé Œæž";
-"user_verification_start_additional_information" = "ćźćżăăŠăć©çšăăă ăăăă«ăçŽæ„ăäŒăăăăăć„ăźæčæłă§ăéŁç”Ąăă ăăă";
-"user_verification_start_waiting_partner" = "%@ăćŸ
ăŁăŠăăŸăâŠ";
-"user_verification_start_information_part2" = " 䞥æčăźç«Żæ«ă§ăŻăłăżă€ă ăłăŒăăçąșèȘăăŸăă";
+"user_verification_start_additional_information" = "ă»ăă„ăȘăăŁăŒăé«ăăăăă«ăćŻŸéąă§èĄăăăä»ăźé俥ææź”ăć©çšăăŸăăăă";
+"user_verification_start_waiting_partner" = "%@ăćŸ
æ©ăăŠăăŸăâŠ";
+"user_verification_start_information_part2" = " 䞥æčăźç«Żæ«ă§ăŻăłăżă€ă ăłăŒăăçąșèȘăăèȘ蚌ăăŠăă ăăă";
"user_verification_start_information_part1" = "ă»ăă„ăȘăăŁăŒăé«ăăăăă« ";
// MARK: - User verification
@@ -902,23 +902,23 @@
"key_verification_scan_confirmation_scanned_user_information" = "%@ăŻćăă·ăŒă«ăăèĄšç€șăăŠăăŸăăïŒ";
// Scanned
-"key_verification_scan_confirmation_scanned_title" = "ăŸăăȘăă§ăïŒ";
-"key_verification_scan_confirmation_scanning_device_waiting_other" = "ä»ăźç«Żæ«ăćŸ
ăŁăŠăăŸăâŠ";
+"key_verification_scan_confirmation_scanned_title" = "ăăć°ăă§ăïŒ";
+"key_verification_scan_confirmation_scanning_device_waiting_other" = "ä»ăźç«Żæ«ăćŸ
æ©ăăŠăăŸăâŠ";
// MARK: Scan confirmation
// Scanning
-"key_verification_scan_confirmation_scanning_title" = "ăăć°ăă§ăăçąșèȘăćŸ
ăŁăŠăăŸăâŠ";
-"key_verification_scan_confirmation_scanning_user_waiting_other" = "%@ăćŸ
ăŁăŠăăŸăâŠ";
-"key_verification_verify_qr_code_scan_other_code_success_message" = "QRăłăŒăăźèȘ蚌ă«æćăăŸăăă";
-"key_verification_verify_qr_code_scan_other_code_success_title" = "ăłăŒăăæćčă«ăȘăăŸăăïŒ";
-"key_verification_verify_qr_code_other_scan_my_code_title" = "çžæăQRăłăŒăăèȘăżćăŁăŠăăăŸăăăïŒ";
-"key_verification_verify_qr_code_start_emoji_action" = "ç””æćă«ăăèȘ蚌";
+"key_verification_scan_confirmation_scanning_title" = "ăăć°ăă§ăïŒçąșèȘăćŸ
æ©ăăŠăăŸăâŠ";
+"key_verification_scan_confirmation_scanning_user_waiting_other" = "%@ăćŸ
æ©ăăŠăăŸăâŠ";
+"key_verification_verify_qr_code_scan_other_code_success_message" = "QRăłăŒăăæŁćžžă«æ€èšŒăăŸăăă";
+"key_verification_verify_qr_code_scan_other_code_success_title" = "ăłăŒăăæ€èšŒăăŸăăïŒ";
+"key_verification_verify_qr_code_other_scan_my_code_title" = "çžæăQRăłăŒăăæŁćžžă«èȘăżćăăŸăăăïŒ";
+"key_verification_verify_qr_code_start_emoji_action" = "ç””æćă§èȘ蚌";
"key_verification_verify_qr_code_cannot_scan_action" = "ăčăăŁăłă§ăăŸăăăïŒ";
-"key_verification_verify_qr_code_scan_code_action" = "ăłăŒăăăčăăŁăł";
+"key_verification_verify_qr_code_scan_code_action" = "ăłăŒăăăčăăŁăłăăŠăă ăă";
"key_verification_verify_qr_code_emoji_information" = "ç””æćăźäžŠăłăæŻèŒăăŠèȘ蚌ă";
-"key_verification_verify_qr_code_information_other_device" = "仄äžăźăłăŒăăăčăăŁăłăăŠçąșèȘăăŠăă ăă:";
-"key_verification_verify_qr_code_information" = "ăłăŒăăăčăăŁăłăăŠăăäșăăăăŁăăăšçąșèȘăăŸăă";
+"key_verification_verify_qr_code_information_other_device" = "仄äžăźăłăŒăăăčăăŁăłăăŠèȘ蚌ăăŠăă ăăïŒ";
+"key_verification_verify_qr_code_information" = "ăłăŒăăăčăăŁăłăăŠăăäșăăćźć
šă«èȘ蚌ăăŸăăăă";
// MARK: QR code
@@ -928,16 +928,16 @@
"key_verification_incoming_request_incoming_alert_message" = "%@ăŻèȘ蚌ăèŠæ±ăăŠăăŸă";
"key_verification_tile_conclusion_warning_title" = "äżĄé ŒăăăŠăăȘăă”ă€ăłă€ăł";
-"key_verification_tile_conclusion_done_title" = "æ€èšŒæžăż";
-"key_verification_tile_request_incoming_approval_decline" = "ćŽäž";
-"key_verification_tile_request_incoming_approval_accept" = "æżèȘ";
-"key_verification_tile_request_status_accepted" = "ăăȘăăŻæżèȘăăŸăă";
+"key_verification_tile_conclusion_done_title" = "èȘ蚌æž";
+"key_verification_tile_request_incoming_approval_decline" = "æćŠ";
+"key_verification_tile_request_incoming_approval_accept" = "ćæ";
+"key_verification_tile_request_status_accepted" = "æżèȘăăŸăă";
"key_verification_tile_request_status_cancelled" = "%@ăŻăăŁăłă»ă«ăăŸăă";
-"key_verification_tile_request_status_cancelled_by_me" = "ăăȘăăŻăăŁăłă»ă«ăăŸăă";
+"key_verification_tile_request_status_cancelled_by_me" = "ăăŁăłă»ă«ăăŸăă";
"key_verification_tile_request_status_expired" = "æéćă";
-"key_verification_tile_request_status_waiting" = "ăćŸ
ăĄăă ăăâŠ";
-"key_verification_tile_request_status_data_loading" = "æ„æăèȘăżèŸŒăżâŠ";
-"key_verification_tile_request_outgoing_title" = "èȘ蚌ăé俥æž";
+"key_verification_tile_request_status_waiting" = "ćŸ
æ©ăăŠăăŸăâŠ";
+"key_verification_tile_request_status_data_loading" = "æ„æăèȘăżèŸŒăă§ăăŸăâŠ";
+"key_verification_tile_request_outgoing_title" = "èȘ蚌ăé俥ăăŸăă";
// Tiles
@@ -951,28 +951,28 @@
// Generic errors
-"error_invite_3pid_with_no_identity_server" = "ăĄăŒă«ă§æćŸ
ăăăăă«èšćźăăIDă”ăŒăăŒăèżœć ăăŸăă";
+"error_invite_3pid_with_no_identity_server" = "ăĄăŒă«ă§æćŸ
ăăă«ăŻăèšćźă§IDă”ăŒăăŒăèżœć ăăŠăă ăăă";
// MARK: Reaction history
"reaction_history_title" = "ăȘăąăŻă·ă§ăłăźć±„æŽ";
-"emoji_picker_places_category" = "æ
ăšć Žæ";
-"emoji_picker_flags_category" = "ćœæ";
+"emoji_picker_places_category" = "æ
èĄăšć Žæ";
+"emoji_picker_flags_category" = "æ";
"emoji_picker_symbols_category" = "ă·ăłăă«";
-"emoji_picker_objects_category" = "ăȘăăžă§ăŻă";
+"emoji_picker_objects_category" = "ç©äœ";
"emoji_picker_foods_category" = "éŁăčç©ăšéŁČăżç©";
"emoji_picker_nature_category" = "ćç©ăšèȘç¶";
-"emoji_picker_people_category" = "çŹéĄăšăżăăȘ";
+"emoji_picker_people_category" = "èĄšæ
ăšäșșă
";
// MARK: Emoji picker
-"emoji_picker_title" = "ăăă«ăŒ";
+"emoji_picker_title" = "ăȘăąăŻă·ă§ăł";
// MARK: File upload
"file_upload_error_title" = "ăăĄă€ă«ăźăąăăăăŒăăšă©ăŒ";
-"file_upload_error_unsupported_file_type_message" = "ăăĄă€ă«ăźăżă€ăăă”ăăŒăăăăŠăăŸăăă";
+"file_upload_error_unsupported_file_type_message" = "ăăĄă€ă«ăźçšźéĄăă”ăăŒăăăăŠăăŸăăă";
"device_verification_emoji_pin" = "ăăł";
"device_verification_emoji_folder" = "ăă©ă«ăăŒ";
-"device_verification_emoji_headphones" = "ăăăăă©ăł";
-"device_verification_emoji_anchor" = "ăąăłă«ăŒ";
+"device_verification_emoji_headphones" = "ăăăăăł";
+"device_verification_emoji_anchor" = "ăăă";
"device_verification_emoji_bell" = "ăă«";
"device_verification_emoji_trumpet" = "ăă©ăłăăă";
"device_verification_emoji_guitar" = "ăźăżăŒ";
@@ -982,55 +982,55 @@
"device_verification_emoji_aeroplane" = "éŁèĄæ©";
"device_verification_emoji_bicycle" = "èȘè»ąè»";
"device_verification_emoji_train" = "é»è»";
-"device_verification_emoji_flag" = "ăă©ă°";
-"device_verification_emoji_telephone" = "ăăŹăă©ăł";
-"device_verification_emoji_hammer" = "ăăłăăŒ";
+"device_verification_emoji_flag" = "æ";
+"device_verification_emoji_telephone" = "é»è©±æ©";
+"device_verification_emoji_hammer" = "éæ§";
"device_verification_emoji_key" = "é”";
-"device_verification_emoji_lock" = "é ";
-"settings_three_pids_management_information_part1" = "ăă°ă€ăłăăąă«ăŠăłăăźććŸ©ă«äœżçšă§ăăăĄăŒă«ăąăăŹăčăé»è©±çȘć·ăăăă§çźĄçăăŸăăèȘ°ăăăȘăăźăăšăçșèŠă§ăăăă知çăă ";
+"device_verification_emoji_lock" = "é ć";
+"settings_three_pids_management_information_part1" = "ăă°ă€ăłăăąă«ăŠăłăăźććŸ©ă«äœżçšă§ăăăĄăŒă«ăąăăŹăčăé»è©±çȘć·ăăăă§çźĄçăăăȘăăèŠă€ăăăăäșșă ";
"settings_identity_server_settings" = "IDă”ăŒăăŒ";
"external_link_confirmation_title" = "ăăźăȘăłăŻăćçąșèȘăăŠăă ăă";
-"media_type_accessibility_sticker" = "ăčăăŁăă«ăŒ";
+"media_type_accessibility_sticker" = "ăčăăă«ăŒ";
"media_type_accessibility_file" = "ăăĄă€ă«";
"media_type_accessibility_location" = "äœçœźæ
ć ±";
"media_type_accessibility_video" = "ćç»";
"media_type_accessibility_audio" = "éłćŁ°";
"media_type_accessibility_image" = "ç»ć";
"room_open_dialpad" = "ăă€ă€ă«ăăă";
-"room_place_voice_call" = "ăăăȘé話";
-"room_accessibility_hangup" = "é話ăćă";
-"room_event_action_delete_confirmation_message" = "ăăźæȘé俥ăĄăă»ăŒăžăćé€ăăŠăăăăăă§ăăïŒ";
+"room_place_voice_call" = "éłćŁ°é話";
+"room_accessibility_hangup" = "é»è©±ăćă";
+"room_event_action_delete_confirmation_message" = "ăăźæȘé俥ăźăĄăă»ăŒăžăćé€ăăŠăăăăă§ăăïŒ";
"room_accessibility_video_call" = "ăăăȘé話";
"room_accessibility_call" = "é話";
-"room_accessibility_integrations" = "ç”±ć";
+"room_accessibility_integrations" = "ă€ăłăă°ăŹăŒă·ă§ăłïŒç”±ćïŒ";
"room_accessibility_search" = "æ€çŽą";
"room_accessibility_upload" = "ăąăăăăŒă";
-"room_message_edits_history_title" = "ăĄăă»ăŒăžăç·šé";
+"room_message_edits_history_title" = "ăĄăă»ăŒăžăźç·šé汄æŽ";
"room_action_reply" = "èżäżĄ";
-"room_action_send_file" = "ăăĄă€ă«ăéă";
-"room_action_camera" = "ćçăăăăȘăźæźćœ±";
-"room_event_action_reaction_history" = "ććżăźć±„æŽ";
+"room_action_send_file" = "ăăĄă€ă«ăé俥";
+"room_action_camera" = "ćçăŸăăŻćç»ăæźćœ±";
+"room_event_action_reaction_history" = "ăȘăąăŻă·ă§ăłăźć±„æŽ";
"room_event_action_reaction_show_less" = "èĄšç€șăăȘă";
"room_event_action_reaction_show_all" = "ć
šăŠăèŠă";
"room_event_action_edit" = "ç·šé";
"room_event_action_reply" = "èżäżĄ";
-"device_verification_security_advice_emoji" = "ç””æćăźé çȘăŻăăäžæčăźăă°ă€ăłăšäžèŽăăŸăăïŒ";
+"device_verification_security_advice_emoji" = "ç””æćăæŻèŒăăŠăćăé çȘă§çŸăăŠăăăăšăçąșèȘăăŠăă ăăă";
"key_verification_verify_sas_validate_action" = "äžèŽăăŠăăŸă";
-"key_verification_verify_sas_cancel_action" = "äžèŽăăŸăă";
+"key_verification_verify_sas_cancel_action" = "äžèŽăăŠăăŸăă";
// MARK: Verify
-"key_verification_verify_sas_title_emoji" = "ç””æćăźæŻèŒ";
+"key_verification_verify_sas_title_emoji" = "ç””æćăæŻèŒ";
"device_verification_self_verify_alert_validate_action" = "èȘ蚌";
-"device_verification_self_verify_alert_message" = "ăă°ă€ăłăèȘ蚌ăăŠăă ăăïŒ%@";
+"device_verification_self_verify_alert_message" = "æ°ăăăă°ă€ăłăăăȘăăźăąă«ăŠăłăă«ăąăŻă»ăčăăŠăăŸăăăă°ă€ăłăèȘ蚌ăăŠăă ăăïŒ%@";
// MARK: Self verification start
// New login
-"device_verification_self_verify_alert_title" = "ăă°ă€ăłăăŸăăăïŒ";
+"device_verification_self_verify_alert_title" = "æ°ăăăă°ă€ăłă§ăăăă°ă€ăłăăŸăăăïŒ";
"room_recents_suggested_rooms_section" = "ăăăăăźă«ăŒă ";
"settings_show_url_previews_description" = "ăăŹăă„ăŒăŻæć·ćăăăŠăăȘăă«ăŒă ă§ăźăżèĄšç€șăăăŸăă";
-"settings_show_url_previews" = "ăŠă§ăă”ă€ăăăŹăă„ăŒăèĄšç€ș";
+"settings_show_url_previews" = "ăŠă§ăă”ă€ăăźăăŹăă„ăŒăèĄšç€ș";
"biometrics_setup_enable_button_title_x" = "%@ăæćčă«ăă";
"biometrics_setup_title_x" = "%@ăæćčă«ăă";
"biometrics_settings_enable_x" = "%@ăæćčă«ăă";
@@ -1039,12 +1039,12 @@
// MARK: - Biometrics Protection
"biometrics_mode_touch_id" = "Touch ID";
-"pin_protection_settings_enable_pin" = "PINăæćčă«ăă";
-"pin_protection_settings_section_header_with_biometrics" = "PINăš%@";
-"pin_protection_settings_section_header" = "PIN";
+"pin_protection_settings_enable_pin" = "PINăłăŒăăæćčă«ăă";
+"pin_protection_settings_section_header_with_biometrics" = "PINăłăŒăăš%@";
+"pin_protection_settings_section_header" = "PINăłăŒă";
"settings_mentions_and_keywords_encryption_notice" = "æș枯端æ«ă§ăŻăæć·ćăăăă«ăŒă ă§ăźăĄăłă·ă§ăłăšăăŒăŻăŒăăźéç„ăŻć俥ă§ăăŸăăă";
"settings_new_keyword" = "ăăŒăŻăŒăăèżœć ";
-"settings_your_keywords" = "仄äžă§ăăŒăŻăŒăăæćźă§ăăŸă";
+"settings_your_keywords" = "ăăŒăŻăŒă";
"settings_mentions_and_keywords" = "ăĄăłă·ă§ăłăšăăŒăŻăŒă";
"settings_messages_containing_keywords" = "ăăŒăŻăŒă";
"settings_messages_containing_at_room" = "@room";
@@ -1054,7 +1054,7 @@
"settings_group_messages" = "ă°ă«ăŒăăĄăă»ăŒăž";
"settings_encrypted_direct_messages" = "æć·ćăăăăă€ăŹăŻăăĄăă»ăŒăž";
"settings_direct_messages" = "ăă€ăŹăŻăăĄăă»ăŒăž";
-"settings_notify_me_for" = "仄äžăăĄăă»ăŒăžă«ć«ăŸăăć Žćă«éç„";
+"settings_notify_me_for" = "仄äžăźć Žćă«éç„";
"settings_phone_contacts" = "ç«Żæ«ăźéŁç”Ąć
";
"settings_notifications" = "éç„";
"settings_links" = "ăȘăłăŻ";
@@ -1105,13 +1105,13 @@
"secrets_setup_recovery_passphrase_validate_action" = "ćźäș";
"sign_out_non_existing_key_backup_sign_out_confirmation_alert_backup_action" = "ăăăŻăąăă";
"room_event_action_forward" = "è»ąé";
-"room_event_action_view_in_room" = "ă«ăŒă ă«èĄšç€ș";
+"room_event_action_view_in_room" = "ă«ăŒă ć
ă§èĄšç€ș";
"room_notifs_settings_encrypted_room_notice" = "æć·ćăăăă«ăŒă ă§ăźăĄăłă·ă§ăłăšăăŒăŻăŒăă«ăăéç„ăŻăæș枯端æ«ă§ăŻć©çšă§ăăŸăăă";
"room_notifs_settings_mentions_and_keywords" = "ăĄăłă·ă§ăłăšăăŒăŻăŒăăźăż";
"security_settings_secure_backup_info_valid" = "ăăźă»ăă·ă§ăłăŻé”ăăăăŻăąăăăăŠăăŸăă";
"key_backup_setup_intro_setup_action_without_existing_backup" = "é”ăźăăăŻăąăăăäœżçšéć§";
"space_participants_action_ban" = "ăăźăčăăŒăčăăăăăăŻ";
-"space_participants_action_remove" = "ăăźăčăăŒăčăăćé€";
+"space_participants_action_remove" = "ăăźăčăăŒăčăăèżœæŸ";
"accessibility_button_label" = "ăăżăł";
"ok" = "OK";
"spaces_empty_space_detail" = "éć
Źéă§æćŸ
ăćż
èŠăȘă«ăŒă ăŻèĄšç€șăăăŠăăŸăăă";
@@ -1126,8 +1126,8 @@
"home_empty_view_title" = "%@ăžăăăăă\n%@";
"threads_empty_tip" = "ăăłăïŒăĄăă»ăŒăžăăżăăăăŠăăčăŹăăăăéžæăăéć§ă";
-"threads_empty_info_all" = "ăčăŹăăăçšăăăšăäŒè©±ăźăăŒăăäżăŁăăăäŒè©±ăèżœè·Ąăăăăăăźăćźčæă«ăȘăăŸăă";
-"threads_empty_title" = "ăčăŹăăă§ăăŁăčă«ăă·ă§ăłăæŽçăăŠçźĄç";
+"threads_empty_info_all" = "ăčăŹăăæ©èœăäœżăăšăäŒè©±ăźăăŒăăç¶æăăăăäŒè©±ăç°Ąćă«èżœè·Ąăăăăăăăšăă§ăăŸăă";
+"threads_empty_title" = "ăčăŹăăæ©èœăäœżăŁăŠăäŒè©±ăăŸăšăăŸăăă";
"secure_key_backup_setup_intro_use_security_key_title" = "ă»ăă„ăȘăăŁăŒăăŒăäœżçš";
// MARK: Secure backup setup
@@ -1135,7 +1135,7 @@
// Intro
"secure_key_backup_setup_intro_title" = "ă»ăă„ăąăăăŻăąăă";
-"spaces_explore_rooms" = "ă«ăŒă ăæąçŽą";
+"spaces_explore_rooms" = "ă«ăŒă ăæąă";
"secure_key_backup_setup_intro_use_security_key_info" = "ă»ăă„ăȘăăŁăŒăăŒăçæăăŸăăăăčăŻăŒăăăăŒăžăŁăŒăăăăŻéćș«ăźăăăȘćźć
šăȘć Žæă§äżçźĄăăŠăă ăăă";
"secure_key_backup_setup_intro_info" = "ă”ăŒăăŒäžăźæć·é”ăăăăŻăąăăăăŠăæć·ćăăăăĄăă»ăŒăžăšăăŒăżăžăźăąăŻă»ăčă怱ăăăăźăéČăăŸăăăă";
"secure_backup_setup_banner_subtitle" = "æć·ćăăăăĄăă»ăŒăžăšăăŒăżăžăźăąăŻă»ăčă怱ăăăăźăéČăăŸăăă";
@@ -1146,11 +1146,11 @@
"matrix" = "Matrix";
// Login Screen
-"login_create_account" = "ăąă«ăŠăłăäœæ:";
+"login_create_account" = "ăąă«ăŠăłăăäœæïŒ";
"login_server_url_placeholder" = "URL (äŸ https://matrix.org)";
-"login_home_server_title" = "æ„ç¶ć
ă”ăŒăăŒURL:";
-"login_home_server_info" = "ăăȘăăźæ„ç¶ć
ă”ăŒăăŒăŻăăăȘăăźć
šăŠăźäŒè©±ăšăąă«ăŠăłăæ
ć ±ăäżćăăŸă";
-"login_identity_server_title" = "èȘ蚌ă”ăŒăăŒURL:";
+"login_home_server_title" = "ăăŒă ă”ăŒăăŒăźURLïŒ";
+"login_home_server_info" = "ăăȘăăźăăŒă ă”ăŒăăŒăŻăăăȘăăźć
šăŠăźäŒè©±ăšăąă«ăŠăłăæ
ć ±ăäżćăăŸă";
+"login_identity_server_title" = "IDă”ăŒăăŒăźURLïŒ";
"login_password_placeholder" = "ăăčăŻăŒă";
"login_email_placeholder" = "ăĄăŒă«ăąăăŹăč";
// Action
@@ -1160,40 +1160,40 @@
"resend_message" = "ăĄăă»ăŒăžăćé俥";
"select_all" = "ć
šăŠéžæ";
"show_details" = "è©łçŽ°ăèĄšç€ș";
-"login_identity_server_info" = "MatrixăŻăă©ăźé»ćăĄăŒă«ăȘă©ăă©ăźMatrix IDă«ć±ăăŠăăăăèżœè·Ąăăăąă€ăăłăăŁăăŁă”ăŒăăŒăæäŸăăŸăă çŸćš https://matrix.org ăźăżăććšăăŸăă";
+"login_identity_server_info" = "MatrixăŻăé»ćăĄăŒă«ăȘă©ăăMatrix IDăæ€çŽąăăIDă”ăŒăăŒăæäŸăăŸăăçŸćšăŻ https://matrix.org ăźăżăććšăăŸăă";
"login_user_id_placeholder" = "Matrix IDïŒäŸ @bob:matrix.org ăŸă㯠bobïŒ";
-"login_optional_field" = "ăȘăă·ă§ăł";
-"login_display_name_placeholder" = "èĄšç€șć (äŸ Bob Obson)";
-"login_email_info" = "ăĄăŒă«ăąăăŹăčăæćźăăăšăä»ăźăŠăŒă¶ăŒăăăȘăăMatrixă§ç°Ąćă«èŠă€ăăăăšăă§ăăä»ćŸăăčăŻăŒăăăȘă»ăăăăăăšăă§ăăŸăă";
-"login_prompt_email_token" = "ăĄăŒă«ăźèȘ蚌ăăŒăŻăłăć
„ćăăŠăă ăă:";
+"login_optional_field" = "ä»»æ";
+"login_display_name_placeholder" = "èĄšç€șćïŒäŸ Bob ObsonïŒ";
+"login_email_info" = "ăĄăŒă«ăąăăŹăčăæćźăăăšăä»ăźăŠăŒă¶ăŒăăăȘăăMatrixă§ăăç°Ąćă«èŠă€ăăăăŸăăăŸăăé»ćăĄăŒă«ă§ăăčăŻăŒăăăȘă»ăăăăăăšăćŻèœăšăȘăăŸăă";
+"login_prompt_email_token" = "é»ćăĄăŒă«ăźèȘ蚌ăăŒăŻăłăć
„ćăăŠăă ăăïŒ";
"login_error_title" = "ăă°ă€ăłă«ć€±æăăŸăă";
"login_error_no_login_flow" = "ăăźăăŒă ă”ăŒăăŒăăèȘ蚌æ
ć ±ăććŸă§ăăŸăăă§ăă";
"login_error_do_not_support_login_flows" = "çŸćšăăăźăăŒă ă”ăŒăăŒă«ăăŁăŠćźçŸ©ăăăăă°ă€ăłăăăŒăźäžéšăŸăăŻć
šăŠăă”ăăŒăăăŠăăŸăă";
"login_error_registration_is_not_supported" = "ç»éČăŻçŸćšă”ăăŒăăăăŠăăŸăă";
-"login_error_forbidden" = "çĄćčăȘăŠăŒă¶ăŒć/ăăčăŻăŒă";
+"login_error_forbidden" = "ăŠăŒă¶ăŒćăăăčăŻăŒăăæŁăăăăăŸăă";
"login_error_unknown_token" = "æćźăăăăąăŻă»ăčăăŒăŻăłăèȘèăăăŸăăă§ăă";
"login_error_bad_json" = "äžæŁăȘćœąćŒăźJSON";
"login_error_not_json" = "æćčăȘJSONăć«ăă§ăăŸăăă§ăă";
-"login_error_limit_exceeded" = "ăăŸăă«ăć€ăăźăȘăŻăšăčăăéăăăŸăă";
+"login_error_limit_exceeded" = "ăă°ă€ăłèŠæ±ăć€ăăăŸă";
"login_error_user_in_use" = "ăăźăŠăŒă¶ăŒćăŻæąă«äœżçšăăăŠăăŸă";
-"login_error_login_email_not_yet" = "ăŸă ăŻăȘăăŻăăăŠăăȘăăĄăŒă«ăȘăłăŻ";
-"login_use_fallback" = "ăă©ăŒă«ăăăŻăăŒăžăäœżçš";
+"login_error_login_email_not_yet" = "ăŸă ăŻăȘăăŻăăăŠăăȘăé»ćăĄăŒă«ăźăȘăłăŻ";
+"login_use_fallback" = "ăă©ăŒă«ăăăŻçšăźăăŒăžăäœżçš";
"login_leave_fallback" = "ăăŁăłă»ă«";
"login_invalid_param" = "çĄćčăȘăă©ăĄăŒăżăŒ";
"register_error_title" = "ç»éČă«ć€±æăăŸăă";
-"login_error_forgot_password_is_not_supported" = "Forgot passwordăŻçŸćšă”ăăŒăăăăŠăăŸăă";
-"login_mobile_device" = "æș枯";
+"login_error_forgot_password_is_not_supported" = "ăăăčăŻăŒăăćżăăć ŽćăăŻçŸćšă”ăăŒăăăăŠăăŸăă";
+"login_mobile_device" = "æș枯端æ«";
"login_tablet_device" = "ăżăăŹăă";
"login_desktop_device" = "ăăčăŻăăă";
"login_error_resource_limit_exceeded_title" = "ăȘăœăŒăčć¶éăè¶
ăăŸăă";
-"login_error_resource_limit_exceeded_message_default" = "ăăźăăŒă ă”ăŒăăŒăŻăăȘăœăŒăčć¶éăź1ă€ăè¶
ăăŠăăŸăă";
-"login_error_resource_limit_exceeded_message_monthly_active_user" = "ăăźăăŒă ă”ăŒăăŒăŻăæéăąăŻăăŁăăŠăŒă¶ăŒć¶éăè¶
ăăŠăăŸăă";
+"login_error_resource_limit_exceeded_message_default" = "ăăźăăŒă ă”ăŒăăŒăŻăȘăœăŒăčăźäžéă«éăăŸăăă";
+"login_error_resource_limit_exceeded_message_monthly_active_user" = "ăăźăăŒă ă”ăŒăăŒăŻæéăąăŻăăŁăăŠăŒă¶ăŒæ°ăźäžéă«éăăŸăă ă";
"login_error_resource_limit_exceeded_message_contact" = "\n\năăźă”ăŒăăčăç¶èĄăăă«ăŻăă”ăŒăăč知çè
ă«éŁç”ĄăăŠăă ăăă";
"login_error_resource_limit_exceeded_contact_button" = "知çè
ă«éŁç”Ą";
"abort" = "äžæ";
"discard" = "ç ŽæŁ";
"dismiss" = "ćŽäž";
-"submit" = "æćș";
+"submit" = "é俥";
"submit_code" = "ăłăŒăăé俥";
"set_default_power_level" = "æš©éăŹăă«ăăȘă»ăă";
"set_moderator" = "ăąăăŹăŒăżăŒăèšćź";
@@ -1203,31 +1203,31 @@
"start_video_call" = "ăăăȘé話ăéć§";
"mention" = "ăĄăłă·ă§ăł";
"select_account" = "ăąă«ăŠăłăăéžæ";
-"attach_media" = "ă©ă€ăă©ăȘăăăĄăăŁăąăæ·»ä»";
-"capture_media" = "ćç/ăăăȘăæźă";
+"attach_media" = "ă©ă€ăă©ăȘăŒăăăĄăăŁăąăæ·»ä»";
+"capture_media" = "ćç/ćç»ăæźă";
"invite_user" = "MatrixăŠăŒă¶ăŒăæćŸ
";
-"reset_to_default" = "ăăă©ă«ăă«ăȘă»ăă";
+"reset_to_default" = "æąćźă«ăȘă»ăă";
"cancel_upload" = "ăąăăăăŒăăăăŁăłă»ă«";
"cancel_download" = "ăăŠăłăăŒăăăăŁăłă»ă«";
"answer_call" = "é話ă«ćżç";
"reject_call" = "é話ăæćŠ";
-"end_call" = "é話ç”äș";
+"end_call" = "é話ăç”äș";
"ignore" = "çĄèŠ";
// Events formatter
"notice_avatar_changed_too" = "ïŒăąăăżăŒăć€æŽăăăŸăăïŒ";
"notice_room_name_removed" = "%@ăă«ăŒă ćăćé€ăăŸăă";
"notice_room_topic_removed" = "%@ăăăăăŻăćé€ăăŸăă";
-"notice_event_redacted" = "<ç·šéăăă%@>";
+"notice_event_redacted" = "<%@ăç·šéăăăŸăă>";
"notice_event_redacted_by" = " %@ă«ăă";
"notice_event_redacted_reason" = " [çç±: %@]";
-"notice_profile_change_redacted" = "%@ăćœŒăăźăăăăŁăŒă« %@ăæŽæ°ăăŸăă";
-"notice_room_created" = "%@ăă«ăŒă ăäœæăăŸăă";
-"notice_room_join_rule" = "ç”ćă«ăŒă«ăŻæŹĄăźăšăă: %@";
-"notice_room_power_level_intro" = "ă«ăŒă ăĄăłăăŒăźæš©éăŹăă«:";
-"notice_room_power_level_acting_requirement" = "ăąăŻă·ă§ăłćă«ăŠăŒă¶ăŒăźćż
èŠăȘæć°æš©éăŹăă«:";
-"notice_room_power_level_event_requirement" = "ă€ăăłăă«éąéŁăăæć°æš©éăŹăă«:";
-"notice_room_aliases" = "ă«ăŒă ăšă€ăȘăąăč: %@";
-"notice_room_related_groups" = "ăăźă«ăŒă ă«éąéŁä»ăăăăă°ă«ăŒă: %@";
+"notice_profile_change_redacted" = "%@ăăăăăŁăŒă«%@ăæŽæ°ăăŸăă";
+"notice_room_created" = "%@ăă«ăŒă ăäœæăèšćźăăŸăăă";
+"notice_room_join_rule" = "ćć ă«ăŒă«ïŒ%@";
+"notice_room_power_level_intro" = "ă«ăŒă ăĄăłăăŒăźæš©éăŹăă«ïŒ";
+"notice_room_power_level_acting_requirement" = "ăąăŻă·ă§ăłă«ćż
èŠăȘăŠăŒă¶ăŒăźæć°æš©éăŹăă«ïŒ";
+"notice_room_power_level_event_requirement" = "ă€ăăłăă«éąéŁăăæć°æš©éăŹăă«ïŒ";
+"notice_room_aliases" = "ă«ăŒă ăźăšă€ăȘăąăčïŒ%@";
+"notice_room_related_groups" = "ăăźă«ăŒă ă«éąéŁä»ăăăăă°ă«ăŒăïŒ%@";
"notice_encrypted_message" = "æć·ćăăăăĄăă»ăŒăž";
"notice_image_attachment" = "ç»ćæ·»ä»";
"notice_audio_attachment" = "éłćŁ°æ·»ä»";
@@ -1235,17 +1235,17 @@
"notice_location_attachment" = "äœçœźæ
ć ±æ·»ä»";
"notice_file_attachment" = "ăăĄă€ă«æ·»ä»";
"notice_invalid_attachment" = "çĄćčăȘæ·»ä»";
-"notice_unsupported_attachment" = "ă”ăăŒăăăăŠăăȘăæ·»ä»: %@";
-"notice_feedback" = "ăăŁăŒăăăăŻă€ăăłă (id: %@): %@";
-"notice_redaction" = "%@ăŻă€ăăłăăç·šéăăŸăă (id: %@)";
+"notice_unsupported_attachment" = "ă”ăăŒăăăăŠăăȘăæ·»ä»ăăĄă€ă«ïŒ%@";
+"notice_feedback" = "ăăŁăŒăăăăŻă€ăăłăïŒidïŒ%@ïŒïŒ%@";
+"notice_redaction" = "%@ăŻă€ăăłăăç·šéăăŸăăïŒidïŒ%@ïŒ";
"notice_error_unsupported_event" = "ă”ăăŒăăăăŠăăȘăă€ăăłă";
"notice_error_unexpected_event" = "äșæăăȘăă€ăăłă";
-"notice_error_unknown_event_type" = "äžæăȘă€ăăłăăżă€ă";
-"notice_room_history_visible_to_anyone" = "%@ăä»ćŸăźă«ăŒă 汄æŽăăèȘ°ă§ăăéČ芧ćŻèœă«èšćźăăŸăăă";
-"notice_room_history_visible_to_members" = "%@ăä»ćŸăźă«ăŒă 汄æŽăăăĄăłăăŒăźăżăéČ芧ćŻèœă«èšćźăăŸăăă";
-"notice_room_history_visible_to_members_from_invited_point" = "%@ăä»ćŸăźă«ăŒă 汄æŽăăăĄăłăăŒăźăż ïŒæćŸ
ăăăæçč仄éïŒăéČ芧ćŻèœă«èšćźăăŸăăă";
-"notice_room_history_visible_to_members_from_joined_point" = "%@ăä»ćŸăźă«ăŒă 汄æŽăăăĄăłăăŒăźăż ïŒćć ăăæçč仄éïŒăéČ芧ćŻèœă«èšćźăăŸăăă";
-"notice_crypto_unable_to_decrypt" = "** ćŸ©ć·ćă§ăăŸăă: %@ **";
+"notice_error_unknown_event_type" = "ă€ăăłăăźçšźéĄăäžæă§ă";
+"notice_room_history_visible_to_anyone" = "%@ăä»ćŸăźă«ăŒă ăźć±„æŽăăèȘ°ă§ăăéČ芧ćŻèœă«èšćźăăŸăăă";
+"notice_room_history_visible_to_members" = "%@ăä»ćŸăźă«ăŒă ăźć±„æŽăăăĄăłăăŒăźăżăéČ芧ćŻèœă«èšćźăăŸăăă";
+"notice_room_history_visible_to_members_from_invited_point" = "%@ăä»ćŸăźă«ăŒă ăźć±„æŽăăăĄăłăăŒăźăż ïŒæćŸ
ăăăæçč仄éïŒăéČ芧ćŻèœă«èšćźăăŸăăă";
+"notice_room_history_visible_to_members_from_joined_point" = "%@ăä»ćŸăźă«ăŒă ăźć±„æŽăăăĄăłăăŒăźăż ïŒćć ăăæçč仄éïŒăéČ芧ćŻèœă«èšćźăăŸăăă";
+"notice_crypto_unable_to_decrypt" = "** ćŸ©ć·ćă§ăăŸăăïŒ%@ **";
"notice_crypto_error_unknown_inbound_session_id" = "é俥è
ăźă»ăă·ă§ăłăăăăźăĄăă»ăŒăžçšăźé”ăé俥ăăăŠăăŸăăă";
"notice_sticker" = "ăčăăă«ăŒ";
"notice_in_reply_to" = "èżäżĄć
";
@@ -1255,15 +1255,15 @@
"settings" = "èšćź";
"settings_enable_inapp_notifications" = "ăąăăȘć
éç„ăæćčă«ăă";
"settings_enable_push_notifications" = "ăăă·ă„éç„ăæćčă«ăă";
-"settings_enter_validation_token_for" = "%@ăźèȘ蚌ăăŒăŻăłăć
„ć:";
-"notification_settings_room_rule_title" = "ă«ăŒă : '%@'";
+"settings_enter_validation_token_for" = "%@ăźèȘ蚌ăăŒăŻăłăć
„ćïŒ";
+"notification_settings_room_rule_title" = "ă«ăŒă ïŒ'%@'";
// Devices
-"device_details_title" = "ă»ăă·ă§ăłæ
ć ±\n";
-"device_details_name" = "ćć\n";
+"device_details_title" = "ă»ăă·ă§ăłăźæ
ć ±\n";
+"device_details_name" = "ć
Źéç«Żæ«ć\n";
"device_details_identifier" = "ID\n";
-"device_details_last_seen" = "æç”æ„ç¶æ„\n";
+"device_details_last_seen" = "çŽèżăźăȘăłă©ă€ăłæ„æ\n";
"device_details_last_seen_format" = "%@ @ %@\n";
-"device_details_rename_prompt_message" = "ă»ăă·ă§ăłăźć
ŹéćăŻăăăȘăăšăăćăăăäșșă
ă«ćŻŸăăŠèĄšç€șăăăŸă";
+"device_details_rename_prompt_message" = "ă»ăă·ă§ăłăźć
ŹéćăŻăăăȘăăšăăćăăăéŁç”Ąć
ă«ćŻŸăăŠèĄšç€șăăăŸă";
"device_details_delete_prompt_title" = "èȘ蚌";
"device_details_delete_prompt_message" = "ăăźæäœă«ăŻăèżœć ăźèȘ蚌ăćż
èŠă§ăă\nç¶èĄăăă«ăŻăăăčăŻăŒăăć
„ćăăŠăă ăăă";
// Encryption information
@@ -1277,47 +1277,47 @@
"room_event_encryption_info_event_decryption_error" = "ćŸ©ć·ćăšă©ăŒ\n";
"room_event_encryption_info_event_unencrypted" = "æć·ćăăăŠăăŸăă";
"room_event_encryption_info_event_none" = "ăȘă";
-"room_event_encryption_info_device" = "\né俥è
ă»ăă·ă§ăłæ
ć ±\n";
-"room_event_encryption_info_device_unknown" = "æȘç„ăźă»ăă·ă§ăł\n";
-"room_event_encryption_info_device_name" = "ćć\n";
+"room_event_encryption_info_device" = "\né俥è
ăźă»ăă·ă§ăłăźæ
ć ±\n";
+"room_event_encryption_info_device_unknown" = "äžæăȘă»ăă·ă§ăł\n";
+"room_event_encryption_info_device_name" = "ć
Źéç«Żæ«ć\n";
"room_event_encryption_info_device_id" = "ID\n";
"room_event_encryption_info_device_verification" = "èȘ蚌\n";
-"room_event_encryption_info_device_fingerprint" = "Ed25519 fingerprint\n";
-"room_event_encryption_info_device_verified" = "æ€èšŒæžăż";
-"room_event_encryption_info_device_not_verified" = "èȘ蚌ăăăŠăăȘă";
-"room_event_encryption_info_device_blocked" = "ăă©ăăŻăȘăčăă«èŒăă";
-"room_event_encryption_info_verify" = "èȘ蚌ăăŠăăŸăâŠ";
-"room_event_encryption_info_unverify" = "æȘèȘ蚌";
-"room_event_encryption_info_block" = "ăă©ăăŻăȘăčă";
-"room_event_encryption_info_unblock" = "ăă©ăăŻă§ăȘăăȘăčă";
-"room_event_encryption_verify_title" = "ă»ăă·ă§ăłèȘ蚌\n\n";
-"room_event_encryption_verify_message" = "ăăźă»ăă·ă§ăłăäżĄé Œă§ăăăăšăçąșèȘăăă«ăŻăä»ăźæčæłïŒćŻŸéąăé»è©±ăȘă©ïŒă§ææè
ă«éŁç”Ąăăă»ăă·ă§ăłăźăŠăŒă¶ăŒèšćźă§èĄšç€șăăăé”ă仄äžăźé”ăšäžèŽăăăă©ăăăèšȘăăŠăă ăăă\n\nă»ăă·ă§ăłć: %@\nă»ăă·ă§ăłID: %@\nă»ăă·ă§ăłăăŒ: %@\n\näžèŽăăć ŽćăŻăäžăźçąșèȘăăżăłăæŒăăŸăă ăă仄ć€ăźäșșăăăźă»ăă·ă§ăłăććăăŠăăć ŽćăŻă代ăăă«ăă©ăăŻăȘăčăăăżăłăæŒăăŠăă ăăă\n\nć°æ„ăăźèȘ蚌ăăă»ăčăŻăăæŽç·Žăăăăăźă«ăȘăăŸăă";
+"room_event_encryption_info_device_fingerprint" = "Ed25519 ăăŁăłăŹăŒăăȘăłă\n";
+"room_event_encryption_info_device_verified" = "èȘ蚌æž";
+"room_event_encryption_info_device_not_verified" = "èȘ蚌ăăăŠăăŸăă";
+"room_event_encryption_info_device_blocked" = "ăă©ăăŻăȘăčăă«èżœć æž";
+"room_event_encryption_info_verify" = "èȘ蚌âŠ";
+"room_event_encryption_info_unverify" = "èȘ蚌ăćăæ¶ă";
+"room_event_encryption_info_block" = "ăă©ăăŻăȘăčăă«èżœć ";
+"room_event_encryption_info_unblock" = "ăă©ăăŻăȘăčăăăé€ć€";
+"room_event_encryption_verify_title" = "ă»ăă·ă§ăłăèȘ蚌\n\n";
+"room_event_encryption_verify_message" = "ăăźă»ăă·ă§ăłăäżĄé Œă§ăăăăšăçąșèȘăăă«ăŻăä»ăźæčæłïŒćŻŸéąăé»è©±ăȘă©ïŒă§ææè
ă«éŁç”Ąăăă»ăă·ă§ăłăźăŠăŒă¶ăŒèšćźă§èĄšç€șăăăé”ă仄äžăźé”ăšäžèŽăăăă©ăăăèšȘăăŠăă ăăă\n\nă»ăă·ă§ăłćïŒ%@\nă»ăă·ă§ăłIDïŒ%@\nă»ăă·ă§ăłăăŒïŒ%@\n\näžèŽăăć ŽćăŻăäžăźçąșèȘăăżăłăæŒăăŸăă ăă仄ć€ăźäșșăăăźă»ăă·ă§ăłăććăăŠăăć ŽćăŻă代ăăă«ăă©ăăŻăȘăčăăăżăłăæŒăăŠăă ăăă\n\nć°æ„ăăźèȘ蚌ăăă»ăčăŻăăæŽç·Žăăăăăźă«ăȘăăŸăă";
"room_event_encryption_verify_ok" = "èȘ蚌";
// Account
"account_save_changes" = "ć€æŽăäżć";
-"account_link_email" = "ăȘăłăŻăĄăŒă«";
-"account_linked_emails" = "ăȘăłăŻăăăăĄăŒă«";
+"account_link_email" = "é»ćăĄăŒă«ăăȘăłăŻ";
+"account_linked_emails" = "ăȘăłăŻăăé»ćăĄăŒă«";
"account_email_validation_title" = "èȘ蚌ăźäżçäž";
-"account_email_validation_message" = "é»ćăĄăŒă«ăçąșèȘăăŠăæŹæäžăźURLăăŻăȘăăŻăăŠăă ăăăćźäșăăăăç¶èĄăăăăăŻăȘăăŻăăŠăă ăăă";
-"account_email_validation_error" = "ăĄăŒă«ăąăăŹăčăèȘ蚌ă§ăăŸăăăăĄăŒă«ăçąșèȘăăŠăèšèŒăăăŠăăăȘăłăŻăăŻăȘăăŻăăŠăă ăăăăăźćŸăăç¶èĄăăăăăŻăȘăăŻăăŠăă ăă";
+"account_email_validation_message" = "é»ćăĄăŒă«ăçąșèȘăăŠăæŹæäžăźURLăăŻăȘăăŻăăŠăă ăăăćźäșăăăăç¶èĄăăăŻăȘăăŻăăŠăă ăăă";
+"account_email_validation_error" = "ăĄăŒă«ăąăăŹăčăèȘ蚌ă§ăăŸăăăăĄăŒă«ăçąșèȘăăŠăèšèŒăăăŠăăăȘăłăŻăăŻăȘăăŻăăŠăă ăăăćźäșăăăăç¶èĄăăăăăŻăȘăăŻăăŠăă ăă";
"account_msisdn_validation_title" = "èȘ蚌ăźäżçäž";
"account_msisdn_validation_message" = "SMSă§èȘ蚌çȘć·ăéăăŸăăă仄äžă«ăăźçȘć·ăć
„ćăăŠăă ăăă";
-"account_msisdn_validation_error" = "é»è©±çȘć·ăçąșèȘă§ăăŸăăă";
+"account_msisdn_validation_error" = "é»è©±çȘć·ăèȘ蚌ă§ăăŸăăă";
"account_error_display_name_change_failed" = "èĄšç€șćăźć€æŽă«ć€±æăăŸăă";
"account_error_picture_change_failed" = "ç»ćăźć€æŽă«ć€±æăăŸăă";
"account_error_matrix_session_is_not_opened" = "Matrixă»ăă·ă§ăłăéăăăŠăăŸăă";
-"account_error_email_wrong_title" = "çĄćčăȘé»ćăĄăŒă«ăąăăŹăč";
+"account_error_email_wrong_title" = "çĄćčăȘăĄăŒă«ăąăăŹăč";
"account_error_email_wrong_description" = "ăĄăŒă«ăąăăŹăčăźćœąćŒăæŁăăăăăŸăă";
"account_error_msisdn_wrong_title" = "çĄćčăȘé»è©±çȘć·";
"account_error_msisdn_wrong_description" = "é»è©±çȘć·ăźćœąćŒăæŁăăăăăŸăă";
// Room creation
-"room_creation_name_title" = "ă«ăŒă ć:";
-"room_creation_name_placeholder" = "(äŸ ă©ăłăă°ă«ăŒă)";
-"room_creation_alias_title" = "ă«ăŒă ăźć„ć:";
-"room_creation_alias_placeholder" = "(äŸ #foo:example.org)";
-"room_creation_alias_placeholder_with_homeserver" = "(äŸ #foo%@)";
-"room_creation_participants_title" = "ćć è
:";
-"room_creation_participants_placeholder" = "(äŸ @bob:homeserver1; @john:homeserver2âŠ)";
+"room_creation_name_title" = "ă«ăŒă ćïŒ";
+"room_creation_name_placeholder" = "ïŒäŸ ă©ăłăă°ă«ăŒăïŒ";
+"room_creation_alias_title" = "ă«ăŒă ăźć„ćïŒ";
+"room_creation_alias_placeholder" = "ïŒäŸ #foo:example.orgïŒ";
+"room_creation_alias_placeholder_with_homeserver" = "ïŒäŸ #foo%@ïŒ";
+"room_creation_participants_title" = "ćć è
ïŒ";
+"room_creation_participants_placeholder" = "ïŒäŸ @bob:homeserver1; @john:homeserver2âŠïŒ";
// Room
"room_please_select" = "ă«ăŒă ăéžæăăŠăă ăă";
"room_error_join_failed_title" = "ă«ăŒă ă«ćć ă§ăăŸăăă§ăă";
@@ -1326,34 +1326,34 @@
"room_error_topic_edition_not_authorized" = "ăăźă«ăŒă ăźăăăăŻăç·šéăăæš©éăăăăŸăă";
"room_error_cannot_load_timeline" = "ăżă€ă ă©ă€ăłăźèȘăżèŸŒăżă«ć€±æăăŸăă";
"room_error_timeline_event_not_found_title" = "ăżă€ă ă©ă€ăłăźäœçœźăèȘăżèŸŒăăŸăăă§ăă";
-"room_error_timeline_event_not_found" = "ăąăăȘă±ăŒă·ă§ăłăăăźă«ăŒă ăźăżă€ă ă©ă€ăłă«çčćźăźăă€ăłăăăăŒăăăăăšăăŸăăăăăăăèŠă€ăăăăšăă§ăăŸăăă§ăă";
-"room_left" = "ăăȘăăŻă«ăŒă ăćșăŸăă";
-"room_no_power_to_create_conference_call" = "ăăźă«ăŒă ă§äŒè°ăéć§ăăăăă«æćŸ
ăăæš©éăćż
èŠă§ă";
-"room_no_conference_call_in_encrypted_rooms" = "æć·ćăăăäŒè°ćź€ă§ăŻäŒè°é話ăŻă”ăăŒăăăăŸăă";
+"room_error_timeline_event_not_found" = "ăăźă«ăŒă ăźăżă€ă ă©ă€ăłă«çčćźăźăă€ăłăăèȘăżèŸŒăăăšăăŸăăăăèŠă€ăăăăŸăăă§ăă";
+"room_left" = "ă«ăŒă ăăéćșăăŸăă";
+"room_no_power_to_create_conference_call" = "ăăźă«ăŒă ă§äŒè°ăéć§ăăă«ăŻăæćŸ
ăăăăăźæš©éăćż
èŠă§ă";
+"room_no_conference_call_in_encrypted_rooms" = "æć·ćăăăă«ăŒă ă§ăŻăă°ă«ăŒăé話ăŻă”ăăŒăăăăŸăă";
// Reply to message
"message_reply_to_sender_sent_an_image" = "ç»ćăé俥ăăŸăăă";
-"message_reply_to_sender_sent_a_video" = "ćç»ăéăăŸăăă";
-"message_reply_to_sender_sent_an_audio_file" = "ăȘăŒăăŁăȘăăĄă€ă«ăé俥ăăŸăăă";
+"message_reply_to_sender_sent_a_video" = "ćç»ăé俥ăăŸăăă";
+"message_reply_to_sender_sent_an_audio_file" = "éłćŁ°ăăĄă€ă«ăé俥ăăŸăăă";
"message_reply_to_sender_sent_a_file" = "ăăĄă€ă«ăé俥ăăŸăăă";
-"message_reply_to_message_to_reply_to_prefix" = "ă«èżäżĄ";
+"message_reply_to_message_to_reply_to_prefix" = "èżäżĄć
";
// Room members
"room_member_ignore_prompt" = "ăăźăŠăŒă¶ăŒăăăźć
šăŠăźăĄăă»ăŒăžăéèĄšç€șă«ăăŸăăïŒ";
-"room_member_power_level_prompt" = "ăăźć€æŽăć
ă«æ»ăăăšăŻă§ăăŸăăăăŠăŒă¶ăŒăèȘćăšćăăŹăă«ăźæš©éăæă€ăăă«äżăăŸăăăăăăăă§ăă?";
+"room_member_power_level_prompt" = "ăăźăŠăŒă¶ăŒă«ăăȘăăšćăæš©éăŹăă«ăäžăăăăšăăŠăăŸăăăăźć€æŽăŻćăæ¶ăăŸăăă\năăăăă§ăăïŒ";
// Attachment
-"attachment_size_prompt" = "æŹĄăźăăă«é俥ăăŸăă:";
-"attachment_original" = "ćźéăźă”ă€ăș: %@";
-"attachment_small" = "ć°: %@";
-"attachment_medium" = "äž: %@";
-"attachment_large" = "性: %@";
-"attachment_cancel_download" = "ăăŠăłăăŒăăăăŁăłă»ă«ăăŸăă?";
-"attachment_cancel_upload" = "ăąăăăăŒăăăăŁăłă»ă«ăăŸăă?";
-"attachment_multiselection_size_prompt" = "ç»ćăæŹĄăźăăă«é俥ăăŸăă:";
+"attachment_size_prompt" = "æŹĄăźăăă«é俥ăăŸăăïŒ";
+"attachment_original" = "ćźéăźă”ă€ășïŒ%@";
+"attachment_small" = "ć°ïŒ%@";
+"attachment_medium" = "äžïŒ%@";
+"attachment_large" = "性ïŒ%@";
+"attachment_cancel_download" = "ăăŠăłăăŒăăăăŁăłă»ă«ăăŸăăïŒ";
+"attachment_cancel_upload" = "ăąăăăăŒăăăăŁăłă»ă«ăăŸăăïŒ";
+"attachment_multiselection_size_prompt" = "ç»ćăæŹĄăźăăă«é俥ăăŸăăïŒ";
"attachment_multiselection_original" = "ćźéăźă”ă€ăș";
-"attachment_e2e_keys_file_prompt" = "ăăźăăĄă€ă«ă«ăŻăMatrixăŻă©ă€ăąăłăăăăšăŻăčăăŒăăăăæć·é”ăć«ăŸăăŠăăŸăă\năăĄă€ă«ăźć
ćźčăèĄšç€șăăăăăăĄă€ă«ć
ăźé”ăă€ăłăăŒăăăŸăăïŒ";
+"attachment_e2e_keys_file_prompt" = "ăăźăăĄă€ă«ă«ăŻăMatrixăźăŻă©ă€ăąăłăăăăšăŻăčăăŒăăăăæć·é”ăć«ăŸăăŠăăŸăă\năăĄă€ă«ăźć
ćźčăèĄšç€șăăăăăăĄă€ă«ć
ăźé”ăă€ăłăăŒăăăŸăăïŒ";
"attachment_e2e_keys_import" = "ă€ăłăăŒăâŠ";
// Contacts
"contact_mx_users" = "MatrixăŠăŒă¶ăŒ";
-"contact_local_contacts" = "ăăŒă«ă«ăźéŁç”Ąć
";
+"contact_local_contacts" = "ç«Żæ«ăźéŁç”Ąć
";
// Groups
// Search
"search_no_results" = "ç”æăăăăŸăă";
@@ -1365,19 +1365,19 @@
"format_time_d" = "æ„";
// E2E import
"e2e_import_room_keys" = "ă«ăŒă ăźæć·é”ăă€ăłăăŒă";
-"e2e_import_prompt" = "ăăźăăă»ăčă§ăŻă仄ćă«ć„ăźMatrixăŻă©ă€ăąăłăăăăšăŻăčăăŒăăăæć·é”ăă€ăłăăŒăă§ăăŸăă ăăă«ăăăä»ăźăŻă©ă€ăąăłăăè§ŁèȘă§ăăć
šăŠăźăĄăă»ăŒăžăè§ŁèȘăăăăšăă§ăăŸăă\năšăŻăčăăŒăăăæć·é”ăźăăĄă€ă«ăŻăăăčăăŹăŒășă§äżè·ăăăŠăăŸăă ăăĄă€ă«ăćŸ©ć·ćăăă«ăŻăăăčăăŹăŒășăăăă«ć
„ćăăćż
èŠăăăăŸăă";
+"e2e_import_prompt" = "ăăźăăă»ăčă§ăŻă仄ćă«ć„ăźMatrixăźăŻă©ă€ăąăłăăăăšăŻăčăăŒăăăæć·é”ăă€ăłăăŒăă§ăăŸăă ăăă«ăăăä»ăźăŻă©ă€ăąăłăăè§ŁèȘă§ăăć
šăŠăźăĄăă»ăŒăžăè§ŁèȘăăăăšăă§ăăŸăă\năšăŻăčăăŒăăăæć·é”ăźăăĄă€ă«ăŻăăăčăăŹăŒășă§äżè·ăăăŠăăŸăă ăăĄă€ă«ăćŸ©ć·ćăăă«ăŻăăăčăăŹăŒășăăăă«ć
„ćăăćż
èŠăăăăŸăă";
"e2e_import" = "ă€ăłăăŒă";
"e2e_passphrase_enter" = "ăăčăăŹăŒășăć
„ć";
// E2E export
"e2e_export_room_keys" = "ă«ăŒă ăźæć·é”ăăšăŻăčăăŒă";
-"e2e_export_prompt" = "ăăźăăă»ăčă§ăŻăæć·ćăăăă«ăŒă ă§ć俥ăăăĄăă»ăŒăžăźé”ăăăŒă«ă«ăăĄă€ă«ă«ăšăŻăčăăŒăă§ăăŸăă ăăźăăĄă€ă«ăć„ăźMatrixăŻă©ă€ăąăłăă«ă€ăłăăŒăăăăšăăŻă©ă€ăąăłăăŻăăăăźăĄăă»ăŒăžăćŸ©ć·ćăăăăšăă§ăăŸăă\năšăŻăčăăŒăăăăăĄă€ă«ăäœżăă°ăèȘ°ă§ăæć·ćăăăăĄăă»ăŒăžăćŸ©ć·ćă§ăăăźă§ăăăĄă€ă«ăćźć
šă«äżă€ăăă«æłšæăăćż
èŠăăăăŸăă";
+"e2e_export_prompt" = "ăăźăăă»ăčă§ăŻăæć·ćăăăă«ăŒă ă§ć俥ăăăĄăă»ăŒăžăźé”ăăăŒă«ă«ăăĄă€ă«ă«ăšăŻăčăăŒăă§ăăŸăă ăăźăăĄă€ă«ăć„ăźMatrixăźăŻă©ă€ăąăłăă«ă€ăłăăŒăăăăšăăŻă©ă€ăąăłăăŻăăăăźăĄăă»ăŒăžăćŸ©ć·ćăăăăšăă§ăăŸăă\năšăŻăčăăŒăăăăăĄă€ă«ăäœżăăšăèȘ°ă§ăæć·ćăăăăĄăă»ăŒăžăćŸ©ć·ćă§ăăăăăăăĄă€ă«ăćźć
šă«äżă€ăăă«æłšæăăćż
èŠăăăăŸăă";
"e2e_export" = "ăšăŻăčăăŒă";
"e2e_passphrase_confirm" = "ăăčăăŹăŒășăçąșèȘ";
"e2e_passphrase_empty" = "ăăčăăŹăŒășăŻç©șă§ăăŁăŠăŻăăăŸăă";
-"e2e_passphrase_not_match" = "ăăčăăŹăŒășăŻäžèŽăăćż
èŠăăăăŸă";
+"e2e_passphrase_not_match" = "ăăčăăŹăŒășăäžèŽăăŠăăŸăă";
"e2e_passphrase_create" = "ăăčăăŹăŒășăźäœæ";
// Others
-"user_id_title" = "ăŠăŒă¶ăŒID:";
+"user_id_title" = "ăŠăŒă¶ăŒIDïŒ";
"offline" = "ăȘăă©ă€ăł";
"unsent" = "æȘé俥";
"error" = "ăšă©ăŒ";
@@ -1388,38 +1388,38 @@
"public" = "ć
Źé";
"power_level" = "æš©éăŹăă«";
"network_error_not_reachable" = "ăăăăŻăŒăŻæ„ç¶ăçąșèȘăăŠăă ăă";
-"user_id_placeholder" = "äŸ: @bob:homeserver";
-"ssl_homeserver_url" = "ăăŒă ă”ăŒăăŒăźURL: %@";
+"user_id_placeholder" = "äŸïŒ@bob:homeserver";
+"ssl_homeserver_url" = "ăăŒă ă”ăŒăăŒăźURLïŒ%@";
// Permissions
-"camera_access_not_granted_for_call" = "ăăăȘé話ăŻă«ăĄă©ă«ăąăŻă»ăčăăćż
èŠăăăăŸăăă%@ă«ăŻăăźă«ăĄă©ăäœżçšăăæš©éăăăăŸăă";
-"microphone_access_not_granted_for_call" = "é話ă«ăŻăă€ăŻăžăźăąăŻă»ăčăćż
èŠă§ăăă%@ă«ăŻäœżçšèš±ćŻăăăăŸăă";
-"local_contacts_access_not_granted" = "ăăŒă«ă«ăźéŁç”Ąć
ăăăŠăŒă¶ăŒăæąăă«ăŻéŁç”Ąć
ă«ăąăŻă»ăčăăćż
èŠăăăăŸăăă%@ă«ăŻăăźăąăŻă»ăčæš©éăăăăŸăă";
-"local_contacts_access_discovery_warning_title" = "ăŠăŒă¶ăŒăźæąçŽą";
-"local_contacts_access_discovery_warning" = "%@ăŻăăŠăŒă¶ăŒăæ€çŽąăăăăă«ăăȘăăźéŁç”Ąć
ăăé»ćăĄăŒă«ăšé»è©±çȘć·ăăąăăăăŒăăăă";
+"camera_access_not_granted_for_call" = "ăăăȘé話ă«ăŻă«ăĄă©ăžăźăąăŻă»ăčăćż
èŠă§ăăă%@ă«ăŻă«ăĄă©ăäœżçšăăæš©éăăăăŸăă";
+"microphone_access_not_granted_for_call" = "é話ă«ăŻăă€ăŻăžăźăąăŻă»ăčăćż
èŠă§ăăă%@ă«ăŻăă€ăŻăäœżçšăăæš©éăăăăŸăă";
+"local_contacts_access_not_granted" = "ăăŒă«ă«ăźéŁç”Ąć
ăăăŠăŒă¶ăŒăæąăă«ăŻéŁç”Ąć
ă«ăąăŻă»ăčăăćż
èŠăăăăŸăăă%@ă«ăŻăąăŻă»ăčæš©éăăăăŸăă";
+"local_contacts_access_discovery_warning_title" = "ăŠăŒă¶ăŒăæąă";
+"local_contacts_access_discovery_warning" = "Matrixăæąă«äœżçšăăŠăăéŁç”Ąć
ăèŠă€ăăăăă%@ăŻé»è©±ćžłă«ăăăĄăŒă«ăąăăŹăčăšé»è©±çȘć·ăăăăȘăăéžæăăMatrixăźIDă”ăŒăăŒă«é俥ăăăăšăă§ăăŸăăă”ăăŒăăăŠăăć ŽćăćäșșăăŒăżăŻé俥ćă«ăăă·ă„ćăăăŸăăè©łçŽ°ăŻIDă”ăŒăăŒăźăă©ă€ăă·ăŒăăȘă·ăŒăçąșèȘăăŠăă ăăă";
// Country picker
"country_picker_title" = "ćœăéžæ";
// Language picker
"language_picker_title" = "èšèȘăéžæ";
-"language_picker_default_language" = "æąćźć€ (%@)";
+"language_picker_default_language" = "æąćźć€ïŒ%@ïŒ";
"notice_room_invite" = "%@ă%@ăæćŸ
ăăŸăă";
-"notice_room_third_party_invite" = "%@ă%@ă«ă«ăŒă ăžăźæćŸ
ç¶ăéăăŸăă";
+"notice_room_third_party_invite" = "%@ă%@ă«ă«ăŒă ăžăźæćŸ
ăéăăŸăă";
"notice_room_third_party_registered_invite" = "%@ă%@ăźæćŸ
ăćăć
„ăăŸăă";
"notice_room_join" = "%@ăćć ăăŸăă";
"notice_room_leave" = "%@ăéćșăăŸăă";
"notice_room_reject" = "%@ăæćŸ
ăæćŠăăŸăă";
-"notice_room_kick" = "%@ă%@ăèżœăćșăăŸăă";
-"notice_room_unban" = "%@ă%@ăèżœæŸè§Łé€ăăŸăă";
-"notice_room_ban" = "%@ă%@ăèżœæŸăăŸăă";
-"notice_room_withdraw" = "%@ă%@ăźæćŸ
ăèŸéăăŸăă";
-"notice_room_reason" = ". çç±: %@";
+"notice_room_kick" = "%@ă%@ăèżœæŸăăŸăă";
+"notice_room_unban" = "%@ă%@ăźăăăăŻăè§Łé€ăăŸăă";
+"notice_room_ban" = "%@ă%@ăăăăăŻăăŸăă";
+"notice_room_withdraw" = "%@ă%@ăźæćŸ
ăćăäžăăŸăă";
+"notice_room_reason" = "ăçç±ïŒ%@";
"notice_avatar_url_changed" = "%@ăăąăăżăŒăć€æŽăăŸăă";
"notice_display_name_set" = "%@ăèĄšç€șćă%@ă«èšćźăăŸăă";
"notice_display_name_changed_from" = "%@ăèĄšç€șćă%@ăă%@ă«ć€æŽăăŸăă";
"notice_display_name_removed" = "%@ăèĄšç€șćăćé€ăăŸăă";
-"notice_topic_changed" = "%@ăăăăăŻăæŹĄăźăăă«ć€æŽăăŸăăïŒ%@";
-"notice_room_name_changed" = "%@ăă«ăŒă ćăæŹĄăźăăă«ć€æŽăăŸăăïŒ%@";
-"notice_placed_voice_call" = "%@ăé»è©±ăăăăŸăă";
-"notice_placed_video_call" = "%@ăăăăȘé»è©±ăăăăŸăă";
+"notice_topic_changed" = "%@ăăăăăŻăă%@ăă«ć€æŽăăŸăăă";
+"notice_room_name_changed" = "%@ăă«ăŒă ćă%@ă«ć€æŽăăŸăăă";
+"notice_placed_voice_call" = "%@ăéłćŁ°é話ăçș俥ăăŸăă";
+"notice_placed_video_call" = "%@ăăăăȘé話ăçș俥ăăŸăă";
"notice_answered_video_call" = "%@ăé»è©±ă«ćșăŸăă";
"notice_ended_video_call" = "%@ăé話ăç”äșăăŸăă";
"notice_conference_call_request" = "%@ăVoIPäŒè°ăăȘăŻăšăčăăăŸăă";
@@ -1429,21 +1429,21 @@
"send" = "é俥";
"copy_button_name" = "ăłăăŒ";
"resend" = "ćé俥";
-"redact" = "ç·šé";
+"redact" = "ćé€";
"share" = "ć
±æ";
-"set_power_level" = "æš©éăŹăă«";
+"set_power_level" = "æš©éăŹăă«ăèšćź";
"delete" = "ćé€";
// actions
"action_logout" = "ăă°ăąăŠă";
-"create_room" = "ă«ăŒă ăäœă";
+"create_room" = "ă«ăŒă ăäœæ";
"login" = "ăă°ă€ăł";
"create_account" = "ăąă«ăŠăłăăäœæ";
-"membership_invite" = "æćŸ
ăăŸăă";
-"membership_leave" = "éćșăăŸăă";
-"membership_ban" = "ăăăăŻăăŸăă";
-"num_members_one" = "%@ ăŠăŒă¶ăŒ";
-"num_members_other" = "%@ ăŠăŒă¶ăŒ";
-"kick" = "ăăăŻ";
+"membership_invite" = "æćŸ
æž";
+"membership_leave" = "éćșæž";
+"membership_ban" = "ăăăăŻæž";
+"num_members_one" = "%@äșșăźăŠăŒă¶ăŒ";
+"num_members_other" = "%@äșșăźăŠăŒă¶ăŒ";
+"kick" = "äŒè©±ăăèżœæŸ";
"ban" = "ăăăăŻ";
"unban" = "ăăăăŻè§Łé€";
"message_unsaved_changes" = "äżćăăăŠăăȘăć€æŽăăăăŸăă éćșăăăšć€æŽăŻćăæ¶ăăăŸăă";
@@ -1452,59 +1452,59 @@
"login_error_must_start_http" = "URL㯠http[s]:// ă§ć§ăŸăćż
èŠăăăăŸă";
// room details dialog screen
// contacts list screen
-"invitation_message" = "ç§ăŻmatrixă§ăăȘăăšăăŁăăăăăă è©łçŽ°ăŻăŠă§ăă”ă€ăhttp://matrix.orgăăć°ăăă ăăă";
+"invitation_message" = "matrixă§ăăŁăăăăŸăăăă è©łçŽ°ăŻăŠă§ăă”ă€ă http://matrix.org ă§çąșèȘăăŠăă ăăă";
// Settings screen
-"settings_title_config" = "æ§æ";
+"settings_title_config" = "èšćź";
"settings_title_notifications" = "éç„";
// Notification settings screen
"notification_settings_disable_all" = "ć
šăŠăźéç„ăçĄćčă«ăă";
"notification_settings_enable_notifications" = "éç„ăæćčă«ăă";
"notification_settings_enable_notifications_warning" = "çŸćšăć
šăŠăźç«Żæ«ă§ć
šăŠăźéç„ăçĄćčă«ăȘăŁăŠăăŸăă";
-"notification_settings_global_info" = "éç„èšćźăŻăŠăŒă¶ăŒăąă«ăŠăłăă«äżćăăăăăčăŻăăăéç„ăć«ăć
šăŠăźăŻă©ă€ăąăłăéă§ć
±æăăăŸăă\n\nă«ăŒă«ăŻé çȘă«é©çšăăăŸăă äžèŽăăæćăźă«ăŒă«ăŻăăĄăă»ăŒăžăźç”æăćźçŸ©ăăŸăă\nă ăăïŒćèȘăăšăźéç„ăŻăé俥è
ăăšăźéç„ăăăéèŠăȘă«ăŒă ăăšăźéç„ăăăéèŠă§ăă\nćăçšźéĄăźè€æ°ăźă«ăŒă«ăźć ŽćăäžèŽăăăȘăčăăźæćăźă«ăŒă«ăćȘć
ăăăŸăă";
+"notification_settings_global_info" = "éç„èšćźăŻăŠăŒă¶ăŒăąă«ăŠăłăă«äżćăăăăăčăŻăăăéç„ăć«ăć
šăŠăźăŻă©ă€ăąăłăéă§ć
±æăăăŸăă\n\nă«ăŒă«ăŻé çȘă«é©çšăăăŸăă äžèŽăăæćăźă«ăŒă«ăŻăăĄăă»ăŒăžăźç”æăćźçŸ©ăăŸăă\năăăăŁăŠăćèȘćäœăźéç„ăŻă«ăŒă ćäœăźéç„ăăăćȘć
ăăăă«ăŒă ćäœăźéç„ăŻăé俥è
ćäœăźéç„ăăăćȘć
ăăăŸăă\nćăçšźéĄăźè€æ°ăźă«ăŒă«ă«éąăăŠăŻăäžèŽăăăȘăčăăźæćăźă«ăŒă«ăćȘć
ăăăŸăă";
"notification_settings_per_word_notifications" = "ćèȘćäœăźéç„";
-"notification_settings_per_word_info" = "ćèȘăŻć€§æćăšć°æćăćșć„ăăă«äžèŽăăă*ăŻă€ă«ăă«ăŒăăć«ăăăăšăă§ăăŸăă ćŸăŁăŠ:\nfooăŻăćșćăæćă§ćČăŸăăæććfooïŒäŸ ć„èȘçčăç©șçœăèĄăźéć§/ç”äșïŒăšäžèŽăăŸăă\nfoo*ăŻăfooă§ć§ăŸăćèȘă«äžèŽăăŸăă\n*foo*ăŻă3æćăźfooăć«ăćèȘă«äžèŽăăŸăă";
+"notification_settings_per_word_info" = "ćèȘăŻć€§æćăšć°æćăćșć„ăăă«äžèŽăăă*ăŻă€ă«ăă«ăŒăăć«ăăăăšăă§ăăŸăă ăăŁăŠă\nfooăŻăćșćăæćă§ćČăŸăăæććfooïŒäŸ ć„èȘçčăç©șçœăèĄăźéć§/ç”äșïŒăšäžèŽăăŸăă\nfoo*ăŻăfooă§ć§ăŸăćèȘă«äžèŽăăŸăă\n*foo*ăŻă3æćăźfooăć«ăćèȘă«äžèŽăăŸăă";
"notification_settings_always_notify" = "ćžžă«éç„";
-"notification_settings_never_notify" = "æ±șăăŠéç„ăăȘă";
+"notification_settings_never_notify" = "éç„ăăȘă";
"notification_settings_word_to_match" = "äžèŽăăćèȘ";
"notification_settings_highlight" = "ăă€ă©ă€ă";
"notification_settings_custom_sound" = "ă«ăčăżă ă”ăŠăłă";
-"notification_settings_per_room_notifications" = "1ă«ăŒă ăăăăźéç„";
-"notification_settings_per_sender_notifications" = "é俥è
ăăšăźéç„";
+"notification_settings_per_room_notifications" = "ă«ăŒă ćäœăźéç„";
+"notification_settings_per_sender_notifications" = "é俥è
ćäœăźéç„";
"notification_settings_sender_hint" = "@user:domain.com";
"notification_settings_select_room" = "ă«ăŒă ăéžæ";
"notification_settings_other_alerts" = "ăăźä»ăźăąă©ăŒă";
-"notification_settings_contain_my_user_name" = "ç§ăźăŠăŒă¶ăŒćăć«ăăĄăă»ăŒăžă«ă€ăăŠéłă§ç§ă«éç„ăăŠăă ăă";
-"notification_settings_contain_my_display_name" = "ç§ăźèĄšç€șćăć«ăŸăăŠăăăĄăă»ăŒăžăć±ăăéă«éłă§éç„";
-"notification_settings_just_sent_to_me" = "ç§ă«éăăăăĄăă»ăŒăžă«ă€ăăŠăźéłă§ç§ă«ç„ăăă";
-"notification_settings_invite_to_a_new_room" = "ç§ăæ°ăăă«ăŒă ă«æćŸ
ăăăăšăă«ç„ăăă";
+"notification_settings_contain_my_user_name" = "ç§ăźăŠăŒă¶ăŒćăć«ăăĄăă»ăŒăžă«ă€ăăŠéłă§éç„";
+"notification_settings_contain_my_display_name" = "ç§ăźèĄšç€șćăć«ăăĄăă»ăŒăžă«ă€ăăŠéłă§éç„";
+"notification_settings_just_sent_to_me" = "ç§ă«ăźăżé俥ăăăăĄăă»ăŒăžă«ă€ăăŠéłă§éç„";
+"notification_settings_invite_to_a_new_room" = "æ°ăăă«ăŒă ă«æćŸ
ăăăăšăă«éç„";
"notification_settings_people_join_leave_rooms" = "èȘ°ăăă«ăŒă ă«ćć ăăăăŻéćșăăăšăă«éç„";
"notification_settings_receive_a_call" = "é話ăć俥ăăăšăă«éç„";
"notification_settings_suppress_from_bots" = "ăăăăăăźéç„ăæć¶";
"notification_settings_by_default" = "æąćźć€ă§ăŻâŠ";
-"notification_settings_notify_all_other" = "ä»ăźć
šăŠăźăĄăă»ăŒăž/ă«ăŒă ă«ă€ăăŠéç„";
+"notification_settings_notify_all_other" = "ä»ăźć
šăŠăźăĄăă»ăŒăžăŸăăŻă«ăŒă ă«ă€ăăŠéç„";
// gcm section
// call string
"call_waiting" = "ćŸ
æ©äž...";
-"call_connecting" = "é話æ„ç¶äžâŠ";
-"call_ended" = "é話ç”äș";
+"call_connecting" = "æ„ç¶ăăŠăăŸăâŠ";
+"call_ended" = "é話ăç”äșăăŸăă";
"call_ring" = "ćŒăłćșăäž...";
-"incoming_video_call" = "ç俥ăăăȘé話";
-"incoming_voice_call" = "ç俥éłćŁ°é話";
-"call_invite_expired" = "æéćăăźæćŸ
ăłăŒă«";
+"incoming_video_call" = "ăăăȘé話ăźç俥äž";
+"incoming_voice_call" = "éłćŁ°é話ăźç俥äž";
+"call_invite_expired" = "é話ăźæćŸ
ăźæéăćăăŸăă";
// unrecognized SSL certificate
"ssl_trust" = "äżĄé Œ";
"ssl_logout_account" = "ăă°ăąăŠă";
"ssl_remain_offline" = "çĄèŠ";
-"ssl_fingerprint_hash" = "æçŽ (%@):";
-"ssl_could_not_verify" = "ăȘăąăŒăă”ăŒăăŒăźIDăçąșèȘă§ăăŸăăă§ăăă";
-"ssl_cert_not_trust" = "ăăăŻăèȘ°ăăăăȘăăźăă©ăăŁăăŻăæȘæăæăŁăŠććăăŠăăăăăăȘăăźé»è©±æ©ăăȘăąăŒăă”ăŒăăŒăăæäŸăăă蚌ææžăäżĄé ŒăăŠăăȘăăăšăæćłăăŸăă";
-"ssl_cert_new_account_expl" = "ă”ăŒăăŒçźĄçè
ăăăăäșæăăăăšèż°ăčăć ŽćăŻă仄äžăźæçŽăæäŸăăăæçŽăšäžèŽăăăăšăçąșèȘăăŠăă ăăă";
-"ssl_unexpected_existing_expl" = "蚌ææžăŻăăäœżăăźæș枯é»è©±ă«ăŠäżĄé Œăăăăăźăăć€æŽăăăŸăăă ăăăŻéćžžă«çăăăăšă§ăă ăăźæ°ăă蚌ææžă«ćæăăȘăăăšăăć§ăăăŸăă";
-"ssl_expected_existing_expl" = "蚌ææžă仄ćă«äżĄé ŒăăăăăźăăäżĄé ŒăăăŠăăȘăăăźă«ć€æŽăăăŸăăă ă”ăŒăăŒă蚌ææžăæŽæ°ăăćŻèœæ§ăăăăŸăă äșæłăăăæçŽă«ă€ăăŠăŻăă”ăŒăăŒçźĄçè
ă«ăćăćăăăă ăăă";
-"ssl_only_accept" = "ă”ăŒăăŒçźĄçè
ăäžèšăźăăźăšäžèŽăăæçŽăçșèĄăăć Žćă«ăźăżă蚌ææžăćăć
„ăăŠăă ăăă";
-"unignore" = "çĄèŠăăȘă";
-"notice_encryption_enabled_ok" = "%@ăăšăłăăăŒăšăłăæć·ćăăȘăłă«ăăŸăăă";
-"notice_encryption_enabled_unknown_algorithm" = "%1$@ăăšăłăăăŒăšăłăæć·ćăăȘăłă«ăăŸăăïŒäžæăȘăąă«ăŽăȘășă %2$@ïŒă";
+"ssl_fingerprint_hash" = "ăăŁăłăŹăŒăăȘăłăïŒ%@ïŒïŒ";
+"ssl_could_not_verify" = "ăȘăąăŒăă”ăŒăăŒăźIDăèȘ蚌ă§ăăŸăăă§ăăă";
+"ssl_cert_not_trust" = "ăăăŻăèȘ°ăăăăȘăăźăă©ăăŁăăŻăććăăŠăăăăăăȘăăźé»è©±æ©ăăȘăąăŒăă”ăŒăăŒăăæäŸăăă蚌ææžăäżĄé ŒăăŠăăȘăăăšăæćłăăŠăăćŻèœæ§ăăăăŸăă";
+"ssl_cert_new_account_expl" = "ă”ăŒăăŒăźçźĄçè
ăăăăăŻæłćźăăăŠăăăăšă§ăăăšèż°ăčăć ŽćăŻă仄äžăźăăŁăłăŹăŒăăȘăłăăă知çè
ă«ăăăăŁăłăŹăŒăăȘăłăăšäžèŽăăăăšăçąșèȘăăŠăă ăăă";
+"ssl_unexpected_existing_expl" = "蚌ææžăŻăăȘăăźé»è©±ă«ăăäżĄé ŒăăăŠăăăăźăăć€æŽăăăŠăăŸăăăăăŻăăăăŠç°ćžžăȘäșæ
ă§ăăăăźæ°ăă蚌ææžăæżèȘăăȘăăăšăćŒ·ăæšć„šăăŸăă";
+"ssl_expected_existing_expl" = "蚌ææžă仄ćă«äżĄé ŒăăăăăźăăäżĄé ŒăăăŠăăȘăăăźă«ć€æŽăăăŸăăăă”ăŒăăŒă蚌ææžăæŽæ°ăăćŻèœæ§ăăăăŸăăă”ăŒăăŒăźçźĄçè
ă«éŁç”ĄăăŠăé©ćăȘăăŁăłăŹăŒăăȘăłăăçąșèȘăăŠăă ăăă";
+"ssl_only_accept" = "ă”ăŒăăŒăźçźĄçè
ăäžèšăźăăźăšäžèŽăăăăŁăłăŹăŒăăȘăłăăçșèĄăăć Žćă«ăźăżă蚌ææžăæżèȘăăŠăă ăăă";
+"unignore" = "çĄèŠăè§Łé€";
+"notice_encryption_enabled_ok" = "%@ăăšăłăăăŒăšăłăæć·ćăæćčă«ăăŸăăă";
+"notice_encryption_enabled_unknown_algorithm" = "%1$@ăăšăłăăăŒăšăłăæć·ćïŒèȘèăăăŠăăȘăăąă«ăŽăȘășă %2$@ïŒăæćčă«ăăŸăăă";
"device_details_rename_prompt_title" = "ă»ăă·ă§ăłć";
"account_error_push_not_allowed" = "éç„ăŻèš±ćŻăăăŠăăŸăă";
"notice_room_third_party_revoked_invite" = "%@ă%@ăźă«ăŒă ăžăźæćŸ
ăćăæ¶ăăŸăă";
@@ -1512,27 +1512,27 @@
"notice_room_invite_by_you" = "%@ăæćŸ
ăăŸăă";
"notice_room_invite_you" = "%@ăăăȘăăæćŸ
ăăŸăă";
"notice_room_join_by_you" = "ćć ăăŸăă";
-"notice_room_leave_by_you" = "ăăȘăăéćșăăŸăă";
-"notice_room_kick_by_you" = "%@ăăăăŻăăŸăă";
+"notice_room_leave_by_you" = "éćșăăŸăă";
+"notice_room_kick_by_you" = "%@ăèżœæŸăăŸăă";
"notice_room_unban_by_you" = "%@ăźăăăăŻăè§Łé€ăăŸăă";
"notice_room_ban_by_you" = "%@ăăăăăŻăăŸăă";
"notice_avatar_url_changed_by_you" = "ăąăăżăŒăć€æŽăăŸăă";
"notice_display_name_set_by_you" = "èĄšç€șćă%@ă«ć€æŽăăŸăă";
"notice_display_name_changed_from_by_you" = "èĄšç€șćă%@ăă%@ă«ć€æŽăăŸăă";
"notice_display_name_removed_by_you" = "èĄšç€șćăćé€ăăŸăă";
-"notice_topic_changed_by_you" = "ăăăăŻăć€æŽăăŸăă: %@";
-"notice_room_name_changed_by_you" = "ă«ăŒă ăźććăć€æŽăăŸăă: %@";
-"notice_placed_voice_call_by_you" = "éłćŁ°é話ăéć§ăăŸăă";
-"notice_placed_video_call_by_you" = "ăăăȘé話ăéć§ăăŸăă";
+"notice_topic_changed_by_you" = "ăăăăŻăă%@ăă«ć€æŽăăŸăăă";
+"notice_room_name_changed_by_you" = "ă«ăŒă ćă%@ă«ć€æŽăăŸăăă";
+"notice_placed_voice_call_by_you" = "éłćŁ°é話ăçș俥ăăŸăă";
+"notice_placed_video_call_by_you" = "ăăăȘé話ăçș俥ăăŸăă";
"notice_answered_video_call_by_you" = "é»è©±ă«ćșăŸăă";
"notice_ended_video_call_by_you" = "é話ăç”äșăăŸăă";
"notice_conference_call_request_by_you" = "VoIPäŒè°ăăȘăŻăšăčăăăŸăă";
"notice_room_name_removed_by_you" = "ă«ăŒă ćăćé€ăăŸăă";
"notice_room_topic_removed_by_you" = "ăăăăŻăćé€ăăŸăă";
"notice_profile_change_redacted_by_you" = "ăăăăŁăŒă« %@ăæŽæ°ăăŸăă";
-"notice_room_created_by_you" = "ă«ăŒă ăäœæăăŸăă";
-"notice_encryption_enabled_ok_by_you" = "ăăȘăăŻăšăłăăăŒăšăłăæć·ćăăȘăłă«ăăŸăăă";
-"notice_redaction_by_you" = "ă€ăăłăăç·šéăăŸăă (id: %@)";
+"notice_room_created_by_you" = "ă«ăŒă ăäœæăèšćźăăŸăăă";
+"notice_encryption_enabled_ok_by_you" = "ăšăłăăăŒăšăłăæć·ćăæćčă«ăăŸăăă";
+"notice_redaction_by_you" = "ă€ăăłăăç·šéăăŸăăïŒidïŒ%@ïŒ";
"resume_call" = "ćé";
"notice_room_history_visible_to_members_from_joined_point_for_dm" = "%@ăä»ćŸăźăĄăă»ăŒăžăăć
šćĄ ïŒćć ăăæçč仄éïŒăéČ芧ćŻèœă«èšćźăăŸăăă";
"notice_room_history_visible_to_members_from_invited_point_for_dm" = "%@ăä»ćŸăźăĄăă»ăŒăžăăăĄăłăăŒăźăż ïŒæćŸ
ăăăæçč仄éïŒăéČ芧ćŻèœă«èšćźăăŸăăă";
@@ -1575,39 +1575,39 @@
// Mark: - Polls
"poll_edit_form_create_poll" = "ăąăłă±ăŒăăäœæ";
-"poll_timeline_vote_not_registered_subtitle" = "çłăèšłăăăŸăăăæç„šăç»éČăăăŠăăŸăăăććșŠăè©Šăăă ăă";
-"poll_timeline_vote_not_registered_title" = "æç„šăç»éČăăăŠăăŸăă";
+"poll_timeline_vote_not_registered_subtitle" = "æç„šă§ăăŸăăă§ăăăăăäžćșŠăăçŽăăŠăă ăă";
+"poll_timeline_vote_not_registered_title" = "æç„šă§ăăŸăăă§ăă";
"poll_timeline_total_final_results" = "ćèš%luç„šăźæç„šă«ćșă„ăæç”ç”æ";
"poll_timeline_total_final_results_one_vote" = "ćèš1ç„šăźæç„šă«ćșă„ăæç”ç”æ";
-"poll_timeline_total_votes_not_voted" = "ćèš%luç„šăæç„šăăăšç”æăçąșèȘă§ăăŸă";
-"poll_timeline_total_one_vote_not_voted" = "ćèš1ç„šăæç„šăăăšç”æăçąșèȘă§ăăŸă";
+"poll_timeline_total_votes_not_voted" = "ćèš%luç„šăæç„šăăăšç”æăçąșèȘă§ăăŸă";
+"poll_timeline_total_one_vote_not_voted" = "ćèš1ç„šăæç„šăăăšç”æăçąșèȘă§ăăŸă";
"poll_timeline_total_votes" = "ćèš%luç„š";
"poll_timeline_total_one_vote" = "ćèš1ç„š";
"biometrics_cant_unlocked_alert_message_retry" = "ćè©ŠèĄ";
"biometrics_usage_reason" = "ăąăăȘăéăă«ăŻèȘ蚌ăćż
èŠă§ă";
"settings_sending_media" = "ç»ćăšćç»ăźé俥";
-"invite_friends_share_text" = "%@ ă§ăźéŁç”Ąć
: %@";
+"invite_friends_share_text" = "%@ă§ă話ăăăŸăăăïŒ%@";
"side_menu_action_invite_friends" = "ćă ăĄăæćŸ
";
"call_more_actions_change_audio_device" = "ăȘăŒăăŁăȘăăă€ăčăć€æŽ";
"call_more_actions_dialpad" = "ăă€ă€ă«ăăă";
-"onboarding_splash_login_button_title" = "æąă«ăąă«ăŠăłăăæăŁăŠăăŸă";
+"onboarding_splash_login_button_title" = "æąă«ăąă«ăŠăłăăăăăŸă";
// Onboarding
"onboarding_splash_register_button_title" = "ăąă«ăŠăłăăäœæ";
-"notice_room_created_by_you_for_dm" = "ćć ăăŸăă";
-"notice_room_created_for_dm" = "%@ăćć ăăŸăă";
+"notice_room_created_by_you_for_dm" = "ćć ăăŸăăă";
+"notice_room_created_for_dm" = "%@ăćć ăăŸăăă";
"onboarding_use_case_existing_server_button" = "ă”ăŒăăŒă«æ„ç¶";
"callbar_only_single_active_group" = "ăżăăăăŠă°ă«ăŒăé話ă«ćć (%@)";
-"settings_confirm_media_size" = "é俥æăźă”ă€ășçąșèȘ";
-"settings_confirm_media_size_description" = "ăăźæ©èœăăȘăłă«ăăăšăç»ćăćç»ăă©ăźă”ă€ășă§é俥ăăăçąșèȘăăç»éąăèĄšç€șăăăŸăă";
-"settings_contacts_enable_sync_description" = "IDă”ăŒăăŒăäœżçšăăŠéŁç”Ąć
ăæąăăšćæă«ăéŁç”Ąć
ăăăȘăăæąăăăăă«ăăŸăă";
-"home_syncing" = "ćæäž";
+"settings_confirm_media_size" = "é俥æă«ă”ă€ășăçąșèȘ";
+"settings_confirm_media_size_description" = "ăăźæ©èœăăȘăłă«ăăăšăç»ćăćç»ăă©ăźă”ă€ășă§é俥ăăăçąșèȘăăç»éąăèĄšç€șăăŸăă";
+"settings_contacts_enable_sync_description" = "IDă”ăŒăăŒăäœżçšăăăšăéŁç”Ąć
ăæąăăăăçžæăăăȘăăæąăăăă§ăăăăă«ăȘăăŸăă";
+"home_syncing" = "ćæăăŠăăŸă";
"search_filter_placeholder" = "ç”ă蟌ă";
// MARK: - Share invite link
"share_invite_link_action" = "æćŸ
ăȘăłăŻăć
±æ";
-"room_intro_cell_information_room_with_topic_sentence2" = "ăăăăŻ: %@";
+"room_intro_cell_information_room_with_topic_sentence2" = "ăăăăŻïŒ%@";
"room_intro_cell_information_room_sentence1_part3" = "ăźć§ăŸăă§ăă ";
"room_intro_cell_information_room_sentence1_part1" = "ăăă ";
"room_intro_cell_information_dm_sentence1_part1" = "ăăă ";
@@ -1616,23 +1616,23 @@
"spaces_add_space_title" = "ăčăăŒăčăäœæ";
"spaces_creation_address" = "ăąăăŹăč";
"spaces_creation_visibility_message" = "æąćăźăčăăŒăčă«ćć ăăă«ăŻăæćŸ
ăćż
èŠă§ăă";
-"spaces_creation_footer" = "ăăźèšćźăŻćŸăăć€æŽă§ăăŸă";
-"onboarding_display_name_hint" = "ăăźèšćźăŻćŸăăć€æŽă§ăăŸă";
+"spaces_creation_footer" = "ăăăŻćŸăăć€æŽă§ăăŸă";
+"onboarding_display_name_hint" = "ăăăŻćŸăăć€æŽă§ăăŸă";
"spaces_creation_visibility_title" = "äœæăăăčăăŒăčăźçšźéĄăéžæăăŠăă ăă";
-"space_public_join_rule_detail" = "èȘ°ă§ăćć ćŻèœăăłăă„ăăăŁăŒćă";
-"space_private_join_rule_detail" = "æćŸ
è
ăźăżćć ćŻèœăćäșșăăăŒă ćă";
-"onboarding_use_case_title" = "èȘ°ăšè©±ăăăšăäžçȘć€ăă§ăăïŒ";
+"space_public_join_rule_detail" = "èȘ°ă§ăćć ćŻèœăăłăă„ăăăŁăŒćă";
+"space_private_join_rule_detail" = "æćŸ
è
ăźăżćć ćŻèœăćäșșăăăŒă ćă";
+"onboarding_use_case_title" = "èȘ°ăšæăăăäŒè©±ăăŸăăïŒ";
"onboarding_splash_page_4_message" = "ElementăŻè·ć Žć©çšă«ăæé©ă§ăăäžçă§æăćźć
šăȘç”çčă«ăăŁăŠäżĄé ŒăăăŠăăŸăă";
-"onboarding_splash_page_4_title_no_pun" = "ăăŒă ăźăăăźăĄăă»ăŒăžăłă°ă";
-"onboarding_splash_page_3_message" = "E2Eă§æć·ćăăăŠăăăç»éČă«é»è©±çȘć·ăŻäžèŠă§ăăćșćăăăŒăżćéăăăăŸăăă";
-"onboarding_splash_page_3_title" = "ćźć
šăȘăĄăă»ăŒăžă";
-"onboarding_splash_page_2_message" = "ăăŒăżăă©ăă«äżćăăăăăèȘćă§éžăłăäž»ć°æš©ăšçŹç«ăæă«ć
„ăăăăMatrixă§æ„ç¶ă";
-"onboarding_splash_page_2_title" = "äž»ć°æš©ăŻăăȘăă«ăăă";
+"onboarding_splash_page_4_title_no_pun" = "ăăȘăăźăăŒă ăźăĄăă»ăŒăžăłă°ă«ă";
+"onboarding_splash_page_3_message" = "ăšăłăăăŒăšăłăă§æć·ćăăăŠăăăç»éČă«é»è©±çȘć·ăŻäžèŠă§ăăćșćăăăŒăżćéăăăăŸăăă";
+"onboarding_splash_page_3_title" = "ćźć
šăȘăĄăă»ăŒăžăźăăăšăă";
+"onboarding_splash_page_2_message" = "äŒè©±ăźäżćć
ăèȘćă§æ±șăăăăèȘćă§çźĄçă§ăăçŹç«ăăăłăă„ăă±ăŒă·ă§ăłăMatrixăăăšă«ă";
+"onboarding_splash_page_2_title" = "äž»ć°æš©ăæĄăăźăŻăăăȘăă§ăă";
"onboarding_splash_page_1_message" = "ăȘăłă©ă€ăłäžă§ăćŻŸéąăźäŒè©±ăšćăăŹăă«ă§ăă©ă€ăă·ăŒăćźăăćźć
šă§çŹç«ăăăłăă„ăă±ăŒă·ă§ăłă";
-"saving" = "äżćäž";
+"saving" = "äżćăăŠăăŸă";
// Activities
-"loading" = "ăăŒăäž";
+"loading" = "èȘăżèŸŒăă§ăăŸă";
"confirm" = "çąșèȘ";
"edit" = "ç·šé";
"suggest" = "ă”ăžă§ăčă";
@@ -1640,22 +1640,22 @@
"existing" = "æąć";
"new_word" = "æ°èŠ";
"stop" = "ćæą";
-"spaces_creation_post_process_creating_space_task" = "%@ăäœæäž";
+"spaces_creation_post_process_creating_space_task" = "%@ăäœæăăŠăăŸă";
"side_menu_coach_message" = "ćłă«ăčăŻă€ăăŸăăŻăżăăă§ć
šăŠăźă«ăŒă ăèĄšç€șăăăŸă";
-"spaces_creation_post_process_creating_space" = "ăčăăŒăčăäœæäž";
-"spaces_creation_add_rooms_message" = "ăăźăčăăŒăčăŻăăȘăć°çšăźăăăä»ăźäșșă«éç„ăăăăăšăŻăăăŸăăăăăźèšćźăŻćŸăăć€æŽă§ăăŸăă";
-"spaces_creation_add_rooms_title" = "ă©ăăèżœć ăăŸăăïŒ";
-"spaces_creation_sharing_type_me_and_teammates_detail" = "ăăȘăăšăăŒă ăĄă€ăăźéć
ŹéăźăčăăŒăč";
+"spaces_creation_post_process_creating_space" = "ăčăăŒăčăäœæăăŠăăŸă";
+"spaces_creation_add_rooms_message" = "ăăăŻăăȘăć°çšăźăčăăŒăčă§ăä»ăźäșșăăăŻèŠăăŸăăăćŸăăă«ăŒă ăäŒè©±ăèżœć ăăăăšăă§ăăŸăă";
+"spaces_creation_add_rooms_title" = "äœăèżœć ăăŸăăïŒ";
+"spaces_creation_sharing_type_me_and_teammates_detail" = "èȘćăšăăŒă ăĄă€ăăźéć
ŹéăźăčăăŒăč";
"spaces_creation_sharing_type_me_and_teammates_title" = "èȘćăšăăŒă ăĄă€ă";
"spaces_creation_sharing_type_just_me_detail" = "ă«ăŒă ăæŽçăăăăăźéć
ŹéăźăčăăŒăč";
"spaces_creation_sharing_type_just_me_title" = "èȘćć°çš";
-"spaces_creation_sharing_type_message" = "ćć è
ăéžæăăŠăă ăă%@ăăăźèšćźăŻćŸăăć€æŽă§ăăŸăă";
-"spaces_creation_settings_message" = "è©łçŽ°ăć
„ćăăŠăă ăăăăăźèšćźăŻćŸăăć€æŽă§ăăŸăă";
-"spaces_creation_address_default_message" = "ăčăăŒăčăŻä»„äžăźăăă«èĄšèšăăăŸă\n%@";
-"space_settings_current_address_message" = "ăčăăŒăčăŻä»„äžăźăăă«èĄšèšăăăŸă\n%@";
-"space_topic" = "èȘŹææ";
-"spaces_creation_cancel_message" = "éČæç¶æłăŻć€±ăăăŸăă";
-"spaces_creation_cancel_title" = "ăčăăŒăčăźäœæăćæąăăŸăăïŒ";
+"spaces_creation_sharing_type_message" = "é©ćăȘäșșă %@ ăąăŻă»ăčă§ăăăăšăçąșèȘăăŠăă ăăăăăźèšćźăŻćŸăăć€æŽă§ăăŸăă";
+"spaces_creation_settings_message" = "è©łçŽ°ăć
„ćăăŠăă ăăăăăăŻăă€ă§ăć€æŽă§ăăŸăă";
+"spaces_creation_address_default_message" = "ăčăăŒăčăŻä»„äžă§éČ芧ćŻèœă«ăȘăăŸă\n%@";
+"space_settings_current_address_message" = "ăčăăŒăčăŻä»„äžă§éČ芧ă§ăăŸă\n%@";
+"space_topic" = "è©łçŽ°";
+"spaces_creation_cancel_message" = "ăăăŸă§ăźèšćźăŻć€±ăăăŸăă";
+"spaces_creation_cancel_title" = "ăčăăŒăčăźäœæăäžæąăăŸăăïŒ";
"create_room_section_footer_type_private" = "æćŸ
ăăäșșăźăżăæ€çŽąă»ćć ă§ăăŸăă";
// MARK: - Searchable Directory View Controller
@@ -1668,8 +1668,8 @@
// MARK: Sign out warning
"sign_out_existing_key_backup_alert_title" = "ă”ă€ăłăąăŠăăăŠăăăăă§ăăïŒ";
-"find_your_contacts_message" = "%@ ă§ăăȘăăźéŁç”Ąć
ăèĄšç€șăăç„äșșăšăźăăŁăăăçŽ æ©ăć§ăăŸăă";
-"find_your_contacts_footer" = "ăăźèšćźăŻăă€ă§ăçĄćčă«ă§ăăŸă";
+"find_your_contacts_message" = "%@ă§ăăȘăăźéŁç”Ąć
ăèĄšç€șăăç„äșșăšăźäŒè©±ăăăć§ăăăăăăă«ăăŸăăăă";
+"find_your_contacts_footer" = "ăăźèšćźăŻăă€ă§ăçĄćčă«ă§ăăŸăă";
"find_your_contacts_button_title" = "éŁç”Ąć
ăæ€çŽą";
"find_your_contacts_title" = "éŁç”Ąć
ăăȘăčăăąăă";
@@ -1679,7 +1679,7 @@
// MARK: - Invite friends
-"invite_friends_action" = "ćă ăĄă %@ ă«æćŸ
";
+"invite_friends_action" = "ćéă%@ă«æćŸ
";
"call_transfer_error_title" = "ăšă©ăŒ";
"home_context_menu_mark_as_read" = "æąèȘă«ăă";
"home_context_menu_normal_priority" = "éćžžćȘć
ćșŠ";
@@ -1689,34 +1689,34 @@
// MARK: - Call Transfer
"call_transfer_title" = "è»ąé";
-"room_info_back_button_title" = "ă«ăŒă æ
ć ±";
+"room_info_back_button_title" = "ă«ăŒă ăźæ
ć ±";
"create_room_processing" = "ă«ăŒă ăäœæăăŠăăŸă";
"call_transfer_users" = "ăŠăŒă¶ăŒ";
"home_context_menu_notifications" = "éç„";
"home_context_menu_make_dm" = "éŁç”Ąć
ă«ç§»ć";
"home_context_menu_make_room" = "ă«ăŒă ă«ç§»ć";
-"leave_space_title" = "%@ ăéćș";
-"room_participants_leave_success" = "ă«ăŒă ăéćșăăŸăă";
+"leave_space_title" = "%@ăăéćș";
+"room_participants_leave_success" = "ă«ăŒă ăăéćșăăŸăă";
"room_participants_leave_processing" = "éćșăăŠăăŸă";
"event_formatter_group_call_leave" = "éćș";
"home_context_menu_leave" = "éćș";
// Mark: Leave space
-"leave_space_action" = "ăčăăŒăčăéćș";
+"leave_space_action" = "ăčăăŒăčăăéćș";
"leave_space_selection_title" = "ă«ăŒă ăéžæ";
"create_room_section_footer_type_restricted" = "èȘ°ă§ăăčăăŒăčćă§æ€çŽąă»ćć ă§ăăŸăă";
-"create_room_suggest_room" = "ăčăăŒăčăĄăłăăŒă«ăăăă";
+"create_room_suggest_room" = "ăčăăŒăčăźăĄăłăăŒăžăźăăăă";
"create_room_show_in_directory_footer" = "ä»ăźäșșăæ€çŽąă»ćć ă§ăăăăă«ăȘăăŸăă";
-"create_room_promotion_header" = "PR";
+"create_room_promotion_header" = "ăăăąăŒă";
"searchable_directory_search_placeholder" = "ććăŸă㯠ID";
"room_suggestion_settings_screen_title" = "ăčăăŒăčă«ăăăăăźă«ăŒă ăäœæ";
-"room_suggestion_settings_screen_message" = "ăăăăăźă«ăŒă ăŻăăčăăŒăčăĄăłăăŒă«ćć ăæšć„šăăăăźăšă㊠PR ăăăŸăă";
+"room_suggestion_settings_screen_message" = "ăăăăăźă«ăŒă ăŻăăčăăŒăčăźăĄăłăăŒă«ćŻŸăăŠćć ćèŁăšăăŠèĄšç€șăăăŸăă";
// Room suggestion Settings
"room_suggestion_settings_screen_nav_title" = "ăăăăăźă«ăŒă ";
-"room_details_promote_room_suggest_title" = "ăčăăŒăčăĄăłăăŒăžăźăăăă";
-"settings_default" = "ăăă©ă«ăăźéç„";
+"room_details_promote_room_suggest_title" = "ăčăăŒăčăźăĄăłăăŒăžăźăăăă";
+"settings_default" = "éç„ăźăăă©ă«ă";
"pin_protection_reset_alert_action_reset" = "ăȘă»ăă";
"authentication_recaptcha_title" = "ăăȘăăŻäșșéă§ăăïŒ";
"authentication_verify_msisdn_waiting_button" = "ăłăŒăăćé俥";
@@ -1730,24 +1730,24 @@
"password_validation_error_contain_uppercase_letter" = "性æćăć«ăă";
"password_validation_error_contain_lowercase_letter" = "ć°æćăć«ăă";
/* The placeholder will show a number */
-"password_validation_error_max_length" = "%d æć仄äž";
+"password_validation_error_max_length" = "%dæć仄äž";
/* The placeholder will show a number */
-"password_validation_error_min_length" = "%d æć仄äž";
+"password_validation_error_min_length" = "%dæć仄äž";
// MARK: Password Validation
-"password_validation_info_header" = "仄äžăźæĄä»¶ăæșăăăăčăŻăŒăăèšćźăăŠăă ăă:";
+"password_validation_info_header" = "仄äžăźæĄä»¶ăæșăăăăčăŻăŒăăèšćźăăŠăă ăăïŒ";
"space_selector_empty_view_title" = "ăŸă ăčăăŒăčăăăăŸăă";
-"all_chats_empty_list_placeholder_title" = "æȘèȘăŻăăăŸăă";
+"all_chats_empty_list_placeholder_title" = "æȘèȘăŻăăăŸăăă";
"all_chats_empty_unreads_placeholder_message" = "æȘèȘăźăĄăă»ăŒăžăăăć ŽćăŻăăăă«èĄšç€șăăăŸăă";
-"room_notifs_settings_account_settings" = "ăąă«ăŠăłăèšćź";
+"room_notifs_settings_account_settings" = "ăąă«ăŠăłăăźèšćź";
"room_access_settings_screen_upgrade_alert_upgrading" = "ă«ăŒă ăăąăăă°ăŹăŒăăăŠăăŸă";
"room_access_settings_screen_upgrade_alert_upgrade_button" = "ăąăăă°ăŹăŒă";
"room_access_settings_screen_edit_spaces" = "ăčăăŒăčăç·šé";
"room_access_settings_screen_upgrade_required" = "ăąăăă°ăŹăŒăăćż
èŠ";
"room_access_settings_screen_upgrade_alert_title" = "ă«ăŒă ăăąăăă°ăŹăŒă";
"room_access_settings_screen_public_message" = "èȘ°ă§ăæ€çŽąă»ćć ă§ăăŸăă";
-"room_access_settings_screen_private_message" = "æćŸ
ăăăäșșă ăăæ€çŽąă»ćć ă§ăăŸăă";
-"room_access_settings_screen_message" = "èȘ°ă %@ ăæ€çŽąă»ćć ă§ăăăéžæăăŠăă ăăă";
+"room_access_settings_screen_private_message" = "æćŸ
ăăăäșșăźăżæ€çŽąă»ćć ă§ăăŸăă";
+"room_access_settings_screen_message" = "èȘ°ă%@ăæ€çŽąă»ćć ă§ăăăéžæăăŠăă ăăă";
"space_settings_access_section" = "ăăźăčăăŒăčă«ăąăŻă»ăčă§ăăäșșăŻïŒ";
"room_access_settings_screen_title" = "ăăźă«ăŒă ă«ăąăŻă»ăčă§ăăäșșăŻïŒ";
"room_notifs_settings_none" = "ăȘă";
@@ -1770,12 +1770,12 @@
"space_selector_empty_view_information" = "ăčăăŒăčăŻăă«ăŒă ăšéŁç”Ąć
ăăŸăšăăæčæłă§ăăăŻăăă«ăăčăăŒăčăäœæăăŸăăăă";
"all_chats_all_filter" = "ć
šăŠ";
"all_chats_edit_layout_recents" = "汄æŽ";
-"all_chats_edit_layout_unreads" = "æȘèȘ";
-"all_chats_section_title" = "ăăŁăă";
+"all_chats_edit_layout_unreads" = "æȘèȘăă";
+"all_chats_section_title" = "äŒè©±";
// Mark: - All Chats
-"all_chats_title" = "ć
šăŠăźăăŁăă";
+"all_chats_title" = "ć
šăŠăźäŒè©±";
"location_sharing_live_loading" = "äœçœźæ
ć ±ïŒă©ă€ăïŒăèȘăżèŸŒăă§ăăŸăâŠ";
"location_sharing_live_list_item_stop_sharing_action" = "ćæą";
"location_sharing_live_list_item_current_user_display_name" = "ăăȘă";
@@ -1789,7 +1789,7 @@
"location_sharing_live_share_title" = "äœçœźæ
ć ±ïŒă©ă€ăïŒăć
±æ";
"service_terms_modal_decline_button" = "æćŠ";
"service_terms_modal_accept_button" = "ćæ";
-"service_terms_modal_description_identity_server" = "ăăźæäœă«ăăăç«Żæ«ăźéŁç”Ąć
ă«ăăȘăăźé»è©±çȘć·ăé»ćăĄăŒă«ăäżćăăŠăăäșșăăăȘăăæ€çŽąă§ăăăăă«ăȘăăŸăă";
+"service_terms_modal_description_identity_server" = "ăăă«ăăăç«Żæ«ăźéŁç”Ąć
ă«ăăȘăăźé»è©±çȘć·ăé»ćăĄăŒă«ăäżćăăŠăăäșșăăăăȘăăæ€çŽąă§ăăăăă«ăȘăăŸăă";
// Service terms
"service_terms_modal_title_message" = "ç¶èĄăăă«ăŻă仄äžăźć©çšèŠçŽă«ćæăăŠăă ăă";
@@ -1797,7 +1797,1030 @@
// Alert explaining what an identity server / integration manager is.
"service_terms_modal_information_title_identity_server" = "IDă”ăŒăăŒ";
-"location_sharing_invalid_power_level_message" = "äœçœźæ
ć ±ïŒă©ă€ăïŒăźć
±æă«ăŻé©ćăȘæš©éăćż
èŠă§ăă";
+"location_sharing_invalid_power_level_message" = "ăăźă«ăŒă ă§ăźäœçœźæ
ć ±ïŒă©ă€ăïŒăźć
±æă«ăŻé©ćăȘæš©éăćż
èŠă§ăă";
"location_sharing_live_error" = "äœçœźæ
ć ±ïŒă©ă€ăïŒăźăšă©ăŒ";
-"all_chats_onboarding_page_title3" = "ăăŁăŒăăăăŻăé俥";
"all_chats_edit_layout" = "ăŹă€ăąăŠăăźèšćź";
+
+// Crypto
+"e2e_enabling_on_app_update" = "%@ăŻăšăłăăăŒăšăłăăźæć·ćă«ćŻŸćżăăŸăăăăæćčă«ăăă«ăŻććșŠăă°ă€ăłăăćż
èŠăăăăŸăă\n\năąăăȘă±ăŒă·ă§ăłăźèšćźăăä»ăăăăăăăŻćŸă§èĄăăăšăă§ăăŸăă";
+"analytics_prompt_stop" = "ć
±æăćæą";
+"analytics_prompt_not_now" = "ćŸă§";
+"analytics_prompt_point_3" = "ăăăŻăă€ă§ăèšćźăăçĄćčă«ă§ăăŸă";
+/* Note: The word "don't" is formatted in bold */
+"analytics_prompt_point_2" = "ç§ăăĄăŻăæ
ć ±ă珏äžè
ăšć
±æăăăăšăŻăăăŸăă";
+/* Note: The word "don't" is formatted in bold */
+"analytics_prompt_point_1" = "ç§ăăĄăŻăăąă«ăŠăłăăźăăăȘăăăŒăżăèšéČăăăćæăăăăăăăšăŻăăăŸăă";
+"analytics_prompt_terms_link_upgrade" = "ăă";
+"call_jitsi_unable_to_start" = "ă°ă«ăŒăé話ăéć§ă§ăăŸăă";
+"network_offline_message" = "ăȘăă©ă€ăłă§ăăæ„ç¶ăçąșèȘăăŠăă ăăă";
+"network_offline_title" = "ăȘăă©ă€ăłă§ă";
+"event_formatter_group_call_join" = "ćć ";
+"event_formatter_group_call" = "ă°ă«ăŒăé話";
+"event_formatter_call_end_call" = "é話ăç”äș";
+"event_formatter_call_retry" = "ćè©ŠèĄ";
+"event_formatter_call_decline" = "æćŠ";
+"event_formatter_call_connection_failed" = "æ„ç¶ă«ć€±æăăŸăă";
+"event_formatter_call_ringing" = "ćŒăłćșăăŠăăŸăâŠ";
+"event_formatter_call_connecting" = "æ„ç¶ăăŠăăŸăâŠ";
+"call_ringing" = "ćŒăłćșăăŠăăŸăâŠ";
+"room_notifs_settings_manage_notifications" = "éç„ăŻ%@ă§çźĄçă§ăăŸă";
+"room_access_settings_screen_upgrade_alert_auto_invite_switch" = "ăĄăłăăŒăæ°ăăă«ăŒă ă«èȘćçă«æćŸ
";
+"room_access_settings_screen_upgrade_alert_note" = "ăąăăă°ăŹăŒăăăăšăăăźă«ăŒă ăźæ°ăăăăŒăžă§ăłăäœæăăăŸăăä»ăăć
šăŠăźăĄăă»ăŒăžăŻăăąăŒă«ă€ăăăă«ăŒă ă«æźăăŸăă";
+"room_access_settings_screen_upgrade_alert_message_no_param" = "äžäœăźăčăăŒăčă«ć±ăăäșșăŻăèȘ°ă§ăăăźă«ăŒă ăæ€çŽąăăćć ăăăăšăă§ăăŸăăæćă§ć
šćĄăæćŸ
ăăćż
èŠăŻăăăŸăăăăăăŻă«ăŒă ăźèšćźăăăă€ă§ăć€æŽă§ăăŸăă";
+"room_access_settings_screen_upgrade_alert_message" = "%@ă«ć±ăăäșșăŻăèȘ°ă§ăăăźă«ăŒă ăæ€çŽąăăćć ăăăăšăă§ăăŸăăæćă§ć
šćĄăæćŸ
ăăćż
èŠăŻăăăŸăăăăăăŻă«ăŒă ăźèšćźăăăă€ă§ăć€æŽă§ăăŸăă";
+
+// Room Access Settings
+"room_access_settings_screen_nav_title" = "ă«ăŒă ăžăźăąăŻă»ăč";
+"room_details_polls" = "ăąăłă±ăŒăăźć±„æŽ";
+// User sessions management
+"user_sessions_settings" = "ă»ăă·ă§ăłă知ç";
+"manage_session_sign_out_other_sessions" = "ä»ăźć
šăŠăźă»ăă·ă§ăłăăă”ă€ăłăąăŠă";
+"manage_session_rename" = "ă»ăă·ă§ăłćăć€æŽ";
+"manage_session_name_info_link" = "è©łçŽ°ăèĄšç€ș";
+/* The placeholder will be replaces with manage_session_name_info_link */
+"manage_session_name_info" = "ă»ăă·ă§ăłćăŻéŁç”Ąć
ă«ăèĄšç€șăăăŸăă%@";
+"manage_session_name_hint" = "ă»ăă·ă§ăłćăèšćźăăăšăç«Żæ«ăăăç°Ąćă«èȘèă§ăăăăă«ăȘăăŸăă";
+"security_settings_coming_soon" = "çłăèšłăăăŸăăăăăźăąăŻă·ă§ăłăŻ%@ iOSă§ăŻăŸă ć©çšă§ăăŸăăăä»ăźMatrixăźăŻă©ă€ăąăłăăäœżăŁăŠèšćźăăŠăă ăăăć°æ„çă«ăŻ%@ iOSă§ăćźèŁ
ăăăäșćźă§ăă";
+"security_settings_secure_backup_reset" = "ćèšćź";
+"security_settings_secure_backup_info_checking" = "çąșèȘăăŠăăŸăâŠ";
+"settings_presence_offline_mode_description" = "æćčă«ăăăšăăăźăąăăȘă±ăŒă·ă§ăłăäœżçšăăŠăăéă«ăăä»ăźăŠăŒă¶ăŒă«ăȘăă©ă€ăłăšăăŠèĄšç€șăăăŸăă";
+"settings_presence_offline_mode" = "ăȘăă©ă€ăłăąăŒă";
+"settings_enable_room_message_bubbles" = "ćčăćșăă§ăĄăă»ăŒăžăèĄšç€ș";
+"settings_discovery_accept_terms" = "IDă”ăŒăăŒăźć©çšèŠçŽăæżè«Ÿ";
+"settings_labs_confirm_crypto_sdk" = "ăăźæ©èœăŻćźéšæź”éăźăăăäșæăăăšăăă«æ©èœăăăæćłăăȘăç”æăćŒăè”·ăăćŻèœæ§ăăăăŸăăăăźæ©èœăçĄćčă«ăăă«ăŻăăă°ăąăŠăăăŠććșŠăă°ă€ăłăăŠăă ăăăèȘćèȘèș«ăźć€æă§æ
éă«äœżăŁăŠăă ăăă";
+"settings_labs_enable_voice_broadcast" = "éłćŁ°é
俥";
+"settings_labs_enable_new_app_layout" = "ăąăăȘă±ăŒă·ă§ăłăźæ°ăăăŹă€ăąăŠă";
+"settings_labs_enable_new_client_info_feature" = "ăŻă©ă€ăąăłăăźć称ăăăŒăžă§ăłăURLăèšéČăăă»ăă·ă§ăłăăăŒăžăŁăŒă§ăăćźčæă«ă»ăă·ă§ăłăèȘèă§ăăăăèšćź";
+"settings_labs_enable_new_session_manager" = "æ°ăăă»ăă·ă§ăłăăăŒăžăŁăŒ";
+"settings_labs_use_only_latest_user_avatar_and_name" = "ăŠăŒă¶ăŒăźăąăăżăŒăšććăăĄăă»ăŒăžăźć±„æŽă«èĄšç€ș";
+"settings_labs_enable_threads" = "ăĄăă»ăŒăžăźăčăŹăăæ©èœ";
+"settings_labs_enabled_polls" = "ăąăłă±ăŒă";
+"settings_ui_show_redactions_in_room_history" = "ćé€ăăăăĄăă»ăŒăžă«éąăăéç„ăèĄšç€ș";
+"settings_calls_stun_server_fallback_description" = "ăăŒă ă”ăŒăăŒăăă©ăŒă«ăăăŻçšăźé話ăąă·ăčăă”ăŒăăŒăæäŸăăŠăăȘăć Žć㯠%@ ăèš±ćŻïŒIPăąăăŹăčăé話äžă«ć
±æăăăŸăïŒă";
+"settings_callkit_info" = "ăăăŻç»éąă«ç俥ăèĄšç€șă%@ăźç俥ăŻă·ăčăă ăźéè©±ć±„æŽă§çąșèȘă§ăăŸăăiCloudăæćčă«ăȘăŁăŠăăć Žćăăăźéè©±ć±„æŽăŻAppleăšć
±æăăăŸăă";
+"settings_notifications_disabled_alert_title" = "éç„ăçĄćčă§ă";
+"threads_discourage_information_1" = "ăăŒă ă”ăŒăăŒăă”ăăŒăăăŠăăȘăăăăăčăŹăăæ©èœăŻäžćźćźăăăăăŸăăăăčăŹăăăźăĄăă»ăŒăžăćźćźăăŠèĄšç€șăăăȘăăăăăăăăŸăă ";
+"threads_beta_cancel" = "ćŸă§";
+"threads_beta_enable" = "è©ŠăăŠăżă";
+"threads_beta_information_link" = "è©łçŽ°ăèĄšç€ș";
+"threads_beta_title" = "ăčăŹăă";
+"threads_notice_done" = "äșè§Ł";
+"threads_notice_title" = "ăčăŹăăæ©èœăŻæŁćŒçă«ăȘăăŸăăđ";
+"message_from_a_thread" = "ăčăŹăăăă";
+"room_accessibility_record_voice_message" = "éłćŁ°ăĄăă»ăŒăžăéČéł";
+"room_event_copy_link_info" = "ăȘăłăŻăăŻăȘăăăăŒăă«ăłăăŒăăŸăăă";
+"room_event_action_end_poll" = "ăąăłă±ăŒăăç”äș";
+"room_event_action_remove_poll" = "ăąăłă±ăŒăăćé€";
+"room_participants_invite_prompt_to_msg" = "%@ă%@ă«æćŸ
ăăŠăăăăă§ăăïŒ";
+"find_your_contacts_identity_service_error" = "IDă”ăŒăăŒă«æ„ç¶ă§ăăŸăăă";
+"contacts_address_book_permission_denied" = "ç«Żæ«ăźé»è©±ćžłă%@ăèȘăżćăăăšăŻèš±ćŻăăăŠăăŸăă";
+/* The placeholder %1$tu will be replaced with a number and %2$@ with the user's search terms. Note the > at the start indicates "more than 20 results". */
+"directory_search_results_more_than" = ">%2$@ăźæ€çŽąç”æ%1$tu件";
+/* The placeholder %1$tu will be replaced with a number and %2$@ with the user's search terms. */
+"directory_search_results" = "%2$@ăźæ€çŽąç”æ%1$tu件";
+"room_recents_unknown_room_error_message" = "ăăźă«ăŒă ăçșèŠă§ăăŸăăăććšăăăăšăçąșèȘăăŠăă ăă";
+"room_creation_dm_error" = "ăă€ăŹăŻăăĄăă»ăŒăžăäœæă§ăăŸăăă§ăăăæćŸ
ăăăăŠăŒă¶ăŒăçąșèȘăăăăäžćșŠăăçŽăăŠăă ăăă";
+"password_policy_pwd_in_dict_error" = "ăăčăŻăŒăăèŸæžă§èŠă€ăăăŸăăăèš±ćŻă§ăăŸăăă";
+
+// MARK: Password policy errors
+"password_policy_too_short_pwd_error" = "ăăčăŻăŒăăçăăăŸă";
+"password_validation_error_header" = "æćźăăăăčăŻăŒăăŻä»„äžăźèŠä»¶ăæșăăăŠăăŸăăïŒ";
+"authentication_qr_login_failure_retry" = "ăăäžćșŠè©Šă";
+"authentication_qr_login_failure_request_denied" = "ăȘăŻăšăčăăŻăăäžæčăźç«Żæ«ă§æćŠăăăŸăăă";
+"authentication_qr_login_failure_invalid_qr" = "QRăłăŒăăäžæŁă§ăă";
+"authentication_qr_login_loading_waiting_signin" = "ç«Żæ«ăźă”ă€ăłă€ăłăćŸ
æ©ăăŠăăŸăă";
+"authentication_qr_login_loading_connecting_device" = "ç«Żæ«ă«æ„ç¶ăăŠăăŸă";
+"authentication_qr_login_confirm_subtitle" = "仄äžăźăłăŒăăä»ăźç«Żæ«ăšäžèŽăăŠăăăăšăçąșèȘăăŠăă ăăïŒ";
+"authentication_qr_login_confirm_title" = "ćźć
šăȘæ„ç¶ăçąșç«ăăŸăă";
+"authentication_qr_login_scan_title" = "QRăłăŒăăăčăăŁăł";
+"authentication_qr_login_display_subtitle" = "ă”ă€ăłăąăŠăăăç«Żæ«ă§ä»„äžăźQRăłăŒăăăčăăŁăłăăŠăă ăăă";
+"authentication_qr_login_start_title" = "QRăłăŒăăăčăăŁăł";
+"authentication_terms_policy_url_error" = "éžæăăéć¶æčéăèŠă€ăăăŸăăă§ăăăćŸă§ăăäžćșŠăăçŽăăŠăă ăăă";
+/* The placeholder will show the homeserver's domain */
+"authentication_terms_message" = "%@ăźć©çšèŠçŽăšéć¶æčéăçąșèȘăăŠăă ăă";
+"authentication_verify_msisdn_invalid_phone_number" = "é»è©±çȘć·ăäžæŁă§ă";
+/* The placeholder will show the phone number that was entered. */
+"authentication_verify_msisdn_waiting_message" = "ăłăŒăă%@ă«é俥ăăăŸăă";
+"authentication_verify_msisdn_waiting_title" = "é»è©±çȘć·ăèȘ蚌ăăŠăă ăă";
+"authentication_verify_msisdn_otp_text_field_placeholder" = "çąșèȘăłăŒă";
+/* The placeholder will show the homeserver's domain */
+"authentication_verify_msisdn_input_message" = "%@ăŻăąă«ăŠăłăăźèȘ蚌ăćż
èŠă§ă";
+"authentication_verify_msisdn_input_title" = "é»è©±çȘć·ăć
„ćăăŠăă ăă";
+"authentication_choose_password_not_verified_message" = "ăĄăŒă«ăăăŻăčăçąșèȘăăŠăă ăă";
+"authentication_choose_password_input_message" = "ăăčăŻăŒăăŻ8æć仄äžă«èšćźăăŠăă ăă";
+"authentication_choose_password_input_title" = "ăăčăŻăŒăăéžæ";
+"authentication_forgot_password_waiting_button" = "é»ćăĄăŒă«ăćé俥";
+/* The placeholder will show the email address that was entered. */
+"authentication_forgot_password_waiting_message" = "%@ă«é俥ăăăæé ă«ćŸăŁăŠăă ăăă";
+"authentication_forgot_password_waiting_title" = "é»ćăĄăŒă«ăçąșèȘăăŠăă ăăă";
+"authentication_forgot_password_text_field_placeholder" = "ăĄăŒă«ăąăăŹăč";
+/* The placeholder will show the homeserver's domain */
+"authentication_forgot_password_input_message" = "%@ăŻèȘ蚌ăȘăłăŻăé俥ăăŸă";
+"authentication_forgot_password_input_title" = "é»ćăĄăŒă«ăć
„ćăăŠăă ăă";
+"authentication_verify_email_waiting_button" = "é»ćăĄăŒă«ăćé俥";
+"authentication_verify_email_waiting_hint" = "é»ćăĄăŒă«ăć±ăăŠăăŸăăăïŒ";
+/* The placeholder will show the email address that was entered. */
+"authentication_verify_email_waiting_message" = "%@ă«é俥ăăăæé ă«ćŸăŁăŠăă ăăă";
+"authentication_verify_email_waiting_title" = "ăĄăŒă«ăąăăŹăčăèȘ蚌ăăŠăă ăăă";
+"authentication_verify_email_text_field_placeholder" = "ăĄăŒă«ăąăăŹăč";
+/* The placeholder will show the homeserver's domain */
+"authentication_verify_email_input_message" = "%@ăŻăąă«ăŠăłăăźèȘ蚌ăćż
èŠă§ă";
+"authentication_verify_email_input_title" = "é»ćăĄăŒă«ăć
„ćăăŠăă ăă";
+"authentication_cancel_flow_confirmation_message" = "ăąă«ăŠăłăăăŸă äœæăăăŠăăŸăăăç»éČăäžæąăăŸăăïŒ";
+"authentication_server_selection_server_url" = "ăăŒă ă”ăŒăăŒăźURL";
+"authentication_login_with_qr" = "QRăłăŒăă§ă”ă€ăłă€ăł";
+"authentication_login_username" = "ăŠăŒă¶ăŒć / ăĄăŒă«ăąăăŹăč / é»è©±çȘć·";
+"authentication_login_title" = "ăăăăăȘăăïŒ";
+"authentication_registration_password_footer" = "8æć仄äžă«ăăŠăă ăă";
+"authentication_registration_username_footer" = "ăăăŻćŸăăć€æŽă§ăăŸăă";
+"authentication_registration_username" = "ăŠăŒă¶ăŒć";
+
+// MARK: Authentication
+"authentication_registration_title" = "ăąă«ăŠăłăăäœæ";
+"onboarding_celebration_button" = "éČăżăŸăăă";
+"onboarding_celebration_message" = "ăăăăŁăŒă«ăŻèšćźç»éąăăăă€ă§ăæŽæ°ă§ăăŸă";
+"onboarding_celebration_title" = "ćéĄăăăŸăăïŒ";
+"onboarding_avatar_accessibility_label" = "ăăăăŁăŒă«ç»ć";
+"onboarding_avatar_title" = "ăăăăŁăŒă«ç»ćăèżœć ";
+"onboarding_display_name_max_length" = "èĄšç€șćăŻ256ć仄äžă«ăăŠăă ăă";
+"onboarding_display_name_placeholder" = "èĄšç€șć";
+"onboarding_display_name_message" = "ăĄăă»ăŒăžăé俥ăăéă«èĄšç€șăăăŸăă";
+"onboarding_display_name_title" = "èĄšç€șćăéžæ";
+"onboarding_personalization_skip" = "ăăźăčăăăăăčăăă";
+"onboarding_personalization_save" = "äżćăăŠç¶èĄ";
+"onboarding_congratulations_home_button" = "ăăŒă ă«ç§»ć";
+"onboarding_congratulations_personalize_button" = "ăăăăŁăŒă«ăèšćź";
+/* The placeholder string contains the user's matrix ID */
+"onboarding_congratulations_message" = "ăăȘăăźăąă«ăŠăłă %@ ăäœæăăăŸăă";
+"onboarding_congratulations_title" = "ăăă§ăšăăăăăŸăïŒ";
+"onboarding_use_case_existing_server_message" = "æąćăźă”ăŒăăŒă«ćć ăăŸăăïŒ";
+"onboarding_use_case_skip_button" = "ăăźèłȘćăăčăăă";
+/* The placeholder string contains onboarding_use_case_skip_button as a tappable action */
+"onboarding_use_case_not_sure_yet" = "èż·ăŁăŠăăŸăăïŒ%@";
+"onboarding_use_case_community_messaging" = "ăłăă„ăăăŁăŒ";
+"onboarding_use_case_work_messaging" = "ăăŒă ";
+"onboarding_use_case_personal_messaging" = "ćéăšćź¶æ";
+"onboarding_use_case_message" = "ăżăăȘăšçčăăæć©ăăăăăăŸă";
+"onboarding_splash_page_1_title" = "èȘćăźäŒè©±ăŻăèȘćăźăăźă";
+"accessibility_selected" = "éžææž";
+"invite_to" = "%@ă«æćŸ
";
+"joining" = "ćć ăăŠăăŸă";
+"key_backup_setup_passphrase_passphrase_placeholder" = "ăăčăăŹăŒășăć
„ć";
+"key_backup_setup_passphrase_passphrase_title" = "ć
„ć";
+"key_backup_setup_passphrase_info" = "é”ăźăłăăŒăæć·ćăăŠă”ăŒăăŒă«äżćăăŸăăăăăŻăąăăăäżè·ăăăăă«ăăčăăŹăŒășăèšćźăăŠăă ăăă\n\næ性éăźă»ăă„ăȘăăŁăŒăçąșäżăăăăă«ăMatrixăźăąă«ăŠăłăăźăăčăŻăŒăăšç°ăȘăăăźă«èšćźăăăăšă性ćă§ăă";
+
+// Passphrase
+
+"key_backup_setup_passphrase_title" = "ăăăŻăąăăăă»ăă„ăȘăăŁăŒăăŹăŒășă§äżè·";
+"key_backup_setup_intro_manual_export_action" = "æćă§é”ăăšăŻăčăăŒă";
+"key_backup_setup_intro_manual_export_info" = "ïŒé«ćșŠïŒ";
+"key_backup_setup_intro_setup_connect_action_with_existing_backup" = "ăăźç«Żæ«ăé”ăźăăăŻăąăăă«æ„ç¶";
+"key_backup_setup_intro_info" = "æć·ćăăăăĄăă»ăŒăžăŻăăšăłăăăŒăšăłăăźæć·ćă«ăăŁăŠäżè·ăăăŠăăŸăăăăăăźæć·ćăăăăĄăă»ăŒăžăèȘăăăăźé”ăæăŁăŠăăăźăŻăăăȘăăšć俥è
ă ăă§ăă\n\né”ă怱ăăăȘăăăăé”ăćźć
šă«ăăăŻăąăăăăŠăă ăăă";
+
+// Intro
+
+"key_backup_setup_intro_title" = "æć·ćăăăăĄăă»ăŒăžăæ±șăăŠć€±ăăȘăăăă«";
+"key_backup_setup_skip_alert_skip_action" = "ăčăăă";
+"key_backup_setup_skip_alert_message" = "ăă°ăąăŠăăăăăăźç«Żæ«ă怱ăăăăăăăšăăĄăă»ăŒăžă«ăąăŻă»ăčă§ăăȘăăȘăćŻèœæ§ăăăăŸăă";
+"key_backup_setup_skip_alert_title" = "ăăăăă§ăăïŒ";
+
+
+// MARK: Key backup setup
+
+"key_backup_setup_title" = "é”ăźăăăŻăąăă";
+
+// Banner
+
+"secure_backup_setup_banner_title" = "ă»ăă„ăąăăăŻăąăă";
+"secure_key_backup_setup_cancel_alert_message" = "ăăŸăăŁăłă»ă«ăăăšăăă°ă€ăłă§ăăȘăăȘăŁăéă«ăæć·ćăăăăĄăă»ăŒăžăšăăŒăżă怱ăŁăŠăăŸăćŻèœæ§ăăăăŸăă\n\nèšćźăăăă»ăă„ăąăăăŻăąăăăźèšćźăé”ăźçźĄçăèĄăăăšăă§ăăŸăă";
+
+
+// Cancel
+
+"secure_key_backup_setup_cancel_alert_title" = "ăăăăă§ăăïŒ";
+"secure_key_backup_setup_existing_backup_error_delete_it" = "ćé€";
+"secure_key_backup_setup_existing_backup_error_unlock_it" = "ăăăŻăè§Łé€";
+"secure_key_backup_setup_intro_use_security_passphrase_info" = "ăăȘăă ăăç„ăŁăŠăăç§ćŻăźăăčăŻăŒăăć
„ćăăŠăă ăăăăăăŻăąăăçšă«ă»ăă„ăȘăăŁăŒăăŒăçæăăŸăă";
+"secure_key_backup_setup_intro_use_security_passphrase_title" = "ă»ăă„ăȘăăŁăŒăăŹăŒășăäœżçš";
+"service_terms_modal_table_header_integration_manager" = "ă€ăłăă°ăŹăŒă·ă§ăłăăăŒăžăŁăŒăźć©çšèŠçŽ";
+"service_terms_modal_table_header_identity_server" = "IDă”ăŒăăŒăźć©çšèŠçŽ";
+"service_terms_modal_footer" = "ăăźèšćźăŻăă€ă§ăçĄćčă«ă§ăăŸăă";
+"share_extension_send_now" = "é俥";
+"room_widget_permission_room_id_permission" = "ă«ăŒă ID";
+"room_widget_permission_widget_id_permission" = "ăŠăŁăžă§ăăID";
+"room_widget_permission_theme_permission" = "ăăȘăăźăăŒă";
+"room_widget_permission_user_id_permission" = "ăăȘăăźăŠăŒă¶ăŒID";
+"room_widget_permission_avatar_url_permission" = "ăăȘăăźăąăăżăŒăźURL";
+"room_widget_permission_display_name_permission" = "ăăȘăăźèĄšç€șć";
+"room_widget_permission_information_title" = "ăăăäœżçšăăăšăăŒăżă%@ăšć
±æăăăćŻèœæ§ăăăăŸăïŒ\n";
+"room_widget_permission_webview_information_title" = "ăăăäœżçšăăăšăăŻăăăŒăèšćźăăăăăŒăżă%@ăšć
±æăăăćŻèœæ§ăăăăŸăïŒ\n";
+"room_widget_permission_creator_info_title" = "ăŠăŁăžă§ăăăèżœć ăăäșșïŒ";
+"key_backup_setup_passphrase_confirm_passphrase_placeholder" = "ăăčăăŹăŒășăçąșèȘ";
+"key_backup_setup_passphrase_confirm_passphrase_title" = "çąșèȘ";
+"key_backup_setup_passphrase_set_passphrase_action" = "ăăčăăŹăŒășăèšćź";
+"key_backup_setup_passphrase_confirm_passphrase_invalid" = "ăăčăăŹăŒășăäžèŽăăŸăă";
+"key_backup_setup_passphrase_setup_recovery_key_info" = "ăŸăăŻăăȘă«ăăȘăŒăăŒă§ăăăŻăąăăăçąșäżăăćźć
šăȘć Žæă«äżćăăŠăă ăăă";
+"key_backup_setup_passphrase_setup_recovery_key_action" = "ïŒé«ćșŠïŒă»ăă„ăȘăăŁăŒăăŒă§èšćź";
+
+// Success
+
+"key_backup_setup_success_title" = "æćăăŸăăïŒ";
+"key_backup_recover_invalid_passphrase_title" = "ă»ăă„ăȘăăŁăŒăăŹăŒășăæŁăăăăăŸăă";
+
+// Success from secure backup
+"key_backup_setup_success_from_secure_backup_info" = "é”ăăăăŻăąăăăăŠăăŸăă";
+"key_backup_setup_success_from_passphrase_save_recovery_key_action" = "ă»ăă„ăȘăăŁăŒăăŒăäżć";
+
+// Success from passphrase
+"key_backup_setup_success_from_passphrase_info" = "ăăȘăăźé”ăŻăăăŻăąăăăăăŠăăŸăă\n\nă»ăă„ăȘăăŁăŒăăŒăŻă»ăŒăăăŁăŒăăăăšăȘăăŸăăăăčăăŹăŒășăćżăăć Žćă§ăăă»ăă„ăȘăăŁăŒăăŒăäœżăă°ăæć·ćăăăăĄăă»ăŒăžă«ăąăŻă»ăčăăăăšăă§ăăŸăă\n\nă»ăă„ăȘăăŁăŒăăŒăŻăăăčăŻăŒăăăăŒăžăŁăŒïŒăăăăŻéćș«ïŒăźăăăȘăéćžžă«ćźć
šăȘć Žæă§äżçźĄăăŠăă ăăă";
+"key_backup_recover_invalid_passphrase" = "ăăźăăčăăŹăŒășă§ăŻăăăŻăąăăăćŸ©ć·ćă§ăăŸăăă§ăăăæŁăăă»ăă„ăȘăăŁăŒăăŹăŒășăć
„ćăăăăšăçąșèȘăăŠăă ăăă";
+"key_backup_recover_invalid_recovery_key_title" = "ă»ăă„ăȘăăŁăŒăăŒăäžèŽăăŸăă";
+
+// Recover from private key
+"key_backup_recover_from_private_key_info" = "ăăăŻăąăăăćŸ©ć
ăăŠăăŸăâŠ";
+"key_backup_recover_invalid_recovery_key" = "ăăźé”ă§ăŻăăăŻăąăăăćŸ©ć·ćă§ăăŸăăă§ăăăæŁăăă»ăă„ăȘăăŁăŒăăŒăć
„ćăăăăšăçąșèȘăăŠăă ăăă";
+
+// Recover from passphrase
+
+"key_backup_recover_from_passphrase_info" = "ă»ăă„ăȘăăŁăŒăăŹăŒășăäœżăăšăæć·ćăăăăĄăă»ăŒăžăźć±„æŽăźăăăŻăè§Łé€ă§ăăŸă";
+"key_backup_recover_from_passphrase_lost_passphrase_action_part1" = "ă»ăă„ăȘăăŁăŒăăŹăŒășăćăăăŸăăăïŒăăăȘăšă㯠";
+"key_backup_recover_from_passphrase_lost_passphrase_action_part3" = "ă";
+"key_backup_recover_from_passphrase_lost_passphrase_action_part2" = "ă»ăă„ăȘăăŁăŒăăŒăäœżăăŸăăă";
+"key_backup_recover_from_passphrase_recover_action" = "汄æŽăźăăăŻăè§Łé€";
+"location_sharing_live_timer_selector_title" = "äœçœźæ
ć ±ăć
±æăăæéăéžæăăŠăă ăăă";
+"location_sharing_live_timer_selector_short" = "15ć";
+"location_sharing_live_timer_selector_medium" = "1æé";
+"location_sharing_live_timer_selector_long" = "8æé";
+"location_sharing_live_no_user_locations_error_title" = "ăŠăŒă¶ăŒăźäœçœźæ
ć ±ăŻăăăŸăă";
+"location_sharing_live_stop_sharing_error" = "äœçœźæ
ć ±ăźć
±æăźćæąă«ć€±æăăŸăă";
+"location_sharing_live_stop_sharing_progress" = "äœçœźæ
ć ±ăźć
±æăćæą";
+"location_sharing_live_lab_promotion_text" = "æłšæïŒăăăŻäžæçăȘćźèŁ
ă«ăăè©Šéšæ©èœă§ăăăăȘăăźäœçœźæ
ć ±ăźć±„æŽăŻă«ăŒă ăźăĄăłăăŒă«ćŻŸăăŠæ°žç¶çă«éČ芧ćŻèœăšăȘăăŸăă";
+"location_sharing_live_lab_promotion_title" = "äœçœźæ
ć ±ïŒă©ă€ăïŒăźć
±æ";
+"location_sharing_live_lab_promotion_activation" = "äœçœźæ
ć ±ïŒă©ă€ăïŒăźć
±æăæćčă«ăă";
+
+// MARK: User sessions management
+
+// Parameter is the application display name (e.g. "Element")
+"user_sessions_default_session_display_name" = "%@ iOS";
+"user_sessions_overview_title" = "ă»ăă·ă§ăł";
+"user_sessions_overview_security_recommendations_section_title" = "ă»ăă„ăȘăăŁăŒă«éąăăć§ć";
+"user_sessions_overview_security_recommendations_section_info" = "仄äžăźć§ćă«ćŸăăăąă«ăŠăłăăźă»ăă„ăȘăăŁăŒăæčćăăŸăăăă";
+"user_sessions_overview_security_recommendations_unverified_title" = "æȘèȘ蚌ăźă»ăă·ă§ăł";
+"user_sessions_overview_security_recommendations_inactive_title" = "éăąăŻăăŁăăȘă»ăă·ă§ăł";
+"user_sessions_overview_security_recommendations_inactive_info" = "äœżçšăăŠăăȘăć€ăă»ăă·ă§ăłïŒ90æ„仄äžäœżçšăăăŠăăŸăăïŒăăă”ă€ăłăąăŠăăăăăšăæ€èšăăŠăă ăăă";
+"user_sessions_overview_other_sessions_section_title" = "ăăźä»ăźă»ăă·ă§ăł";
+"user_sessions_overview_other_sessions_section_info" = "ă»ăă„ăȘăăŁăŒăæ性éă«é«ăăă«ăŻăă»ăă·ă§ăłăèȘ蚌ăăäžæăȘă»ăă·ă§ăłăć©çšăăŠăăȘăă»ăă·ă§ăłăăă”ă€ăłăąăŠăăăŠăă ăăă";
+"user_sessions_show_location_info" = "IPăąăăŹăčăèĄšç€ș";
+"user_sessions_hide_location_info" = "IPăąăăŹăčăèĄšç€șăăȘă";
+"user_sessions_overview_current_session_section_title" = "çŸćšăźă»ăă·ă§ăł";
+"user_sessions_view_all_action" = "ć
šăŠèĄšç€șïŒ%dïŒ";
+"user_session_verified" = "èȘ蚌æžăźă»ăă·ă§ăł";
+"user_session_unverified" = "æȘèȘ蚌ăźă»ăă·ă§ăł";
+"user_session_verification_unknown" = "èȘ蚌ăźç¶æ
ăäžæă§ă";
+"user_session_verified_short" = "èȘ蚌æž";
+"user_session_unverified_short" = "æȘèȘ蚌";
+"user_session_verification_unknown_short" = "äžæ";
+"user_session_verify_action" = "ă»ăă·ă§ăłăèȘ蚌";
+"user_session_view_details" = "è©łçŽ°ăèĄšç€ș";
+"major_update_learn_more_action" = "è©łçŽ°ăèĄšç€ș";
+"user_session_learn_more" = "è©łçŽ°ăèĄšç€ș";
+"user_session_verified_additional_info" = "çŸćšăźă»ăă·ă§ăłăŻćźć
šăȘăĄăă»ăŒăžăźăăăšăă«ćŻŸćżăăŠăăŸăă";
+"user_session_unverified_additional_info" = "ăăćźć
šăȘăĄăă»ăŒăžăźăăăšăăźăăă«ăçŸćšăźă»ăă·ă§ăłăèȘ蚌ăăŸăăăă";
+"user_other_session_unverified_additional_info" = "ă»ăă„ăȘăăŁăŒăšćźćźæ§ăźèŠłçčăăăăăźă»ăă·ă§ăłăèȘ蚌ăăăă”ă€ăłăąăŠăăăŠăă ăăă";
+"user_other_session_permanently_unverified_additional_info" = "ăăźă»ăă·ă§ăłăŻæć·ćăă”ăăŒăăăŠăăȘăăăăèȘ蚌ă§ăăŸăăă";
+"user_other_session_verified_additional_info" = "ăăźă»ăă·ă§ăłăŻćźć
šăȘăĄăă»ăŒăžăźăăăšăăźæșćăă§ăăŠăăŸăă";
+"user_session_push_notifications" = "ăăă·ă„éç„";
+"user_session_got_it" = "äșè§Ł";
+"user_session_verified_session_title" = "èȘ蚌æžăźă»ăă·ă§ăł";
+"user_session_unverified_session_title" = "æȘèȘ蚌ăźă»ăă·ă§ăł";
+"user_session_inactive_session_title" = "éăąăŻăăŁăăȘă»ăă·ă§ăł";
+"user_session_rename_session_title" = "ă»ăă·ă§ăłćăć€æŽ";
+"user_other_session_security_recommendation_title" = "ăăźä»ăźă»ăă·ă§ăł";
+"user_other_session_unverified_sessions_header_subtitle" = "ă»ăă·ă§ăłăèȘ蚌ăăăšăăăćźć
šăȘăĄăă»ăŒăžăźăăăšăăćŻèœă«ăȘăăŸăăèŠèŠăăźăȘăăăŸăăŻäœżçšăăŠăăȘăă»ăă·ă§ăłăăăă°ăă”ă€ăłăąăŠăăăŸăăăă";
+"user_other_session_current_session_details" = "çŸćšăźă»ăă·ă§ăł";
+"user_other_session_verified_sessions_header_subtitle" = "ă»ăă„ăȘăăŁăŒăæ性éă«é«ăăă«ăŻăäžæăȘă»ăă·ă§ăłăć©çšăăŠăăȘăă»ăă·ă§ăłăăă”ă€ăłăąăŠăăăŠăă ăăă";
+"user_other_session_filter" = "ç”ă蟌ă";
+"user_other_session_filter_menu_all" = "ć
šăŠăźă»ăă·ă§ăł";
+"user_other_session_filter_menu_verified" = "èȘ蚌æž";
+"user_other_session_filter_menu_unverified" = "æȘèȘ蚌";
+"user_other_session_filter_menu_inactive" = "éăąăŻăăŁă";
+"user_other_session_no_inactive_sessions" = "äœżçšăăŠăăȘăă»ăă·ă§ăłăŻăăăŸăăă";
+"user_other_session_no_verified_sessions" = "èȘ蚌æžăźă»ăă·ă§ăłăŻăăăŸăăă";
+"user_other_session_no_unverified_sessions" = "æȘèȘ蚌ăźă»ăă·ă§ăłăŻăăăŸăăă";
+"user_other_session_clear_filter" = "ç”ă蟌ăżăè§Łé€";
+"user_other_session_menu_select_sessions" = "ă»ăă·ă§ăłăéžæ";
+"user_other_session_menu_sign_out_sessions" = "%@件ăźă»ăă·ă§ăłăăă”ă€ăłăąăŠă";
+"device_name_desktop" = "%@ăăčăŻăăă";
+"device_name_unknown" = "äžæăȘăŻă©ă€ăąăłă";
+"device_type_name_desktop" = "ăăčăŻăăă";
+"device_type_name_web" = "ăŠă§ă";
+"device_type_name_mobile" = "æș枯端æ«";
+"device_type_name_unknown" = "äžæ";
+"user_session_details_title" = "ă»ăă·ă§ăłăźè©łçŽ°";
+"user_session_details_session_section_header" = "ă»ăă·ă§ăł";
+"user_session_details_application_section_header" = "ăąăăȘă±ăŒă·ă§ăł";
+"user_session_details_device_section_header" = "ç«Żæ«";
+"user_session_details_session_name" = "ă»ăă·ă§ăłć";
+"user_session_details_session_id" = "ă»ăă·ă§ăłID";
+"user_session_details_last_activity" = "çŽèżăźăąăŻăăŁăăăŁăŒ";
+"user_session_details_device_ip_address" = "IPăąăăŹăč";
+"user_session_details_device_browser" = "ăă©ăŠă¶ăŒ";
+"user_session_details_device_os" = "ăȘăăŹăŒăăŁăłă°ă·ăčăă ";
+"user_session_details_application_name" = "ćć";
+"user_session_details_application_version" = "ăăŒăžă§ăł";
+"user_session_details_application_url" = "URL";
+"user_session_overview_current_session_title" = "çŸćšăźă»ăă·ă§ăł";
+"user_session_overview_session_title" = "ă»ăă·ă§ăł";
+"user_session_overview_session_details_button_title" = "ă»ăă·ă§ăłăźè©łçŽ°";
+"wysiwyg_composer_start_action_stickers" = "ăčăăă«ăŒ";
+"wysiwyg_composer_start_action_attachments" = "æ·»ä»ăăĄă€ă«";
+"wysiwyg_composer_start_action_polls" = "ăąăłă±ăŒă";
+"wysiwyg_composer_start_action_location" = "äœçœźæ
ć ±";
+"wysiwyg_composer_start_action_camera" = "ă«ăĄă©";
+"wysiwyg_composer_start_action_voice_broadcast" = "éłćŁ°é
俥";
+
+// Formatting Actions
+"wysiwyg_composer_format_action_bold" = "ć€Șćă«ăă";
+"wysiwyg_composer_format_action_italic" = "æćäœă«ăă";
+
+
+
+// Links
+"wysiwyg_composer_link_action_text" = "ăăăčă";
+"wysiwyg_composer_link_action_link" = "ăȘăłăŻ";
+"wysiwyg_composer_link_action_create_title" = "ăȘăłăŻăäœæ";
+"wysiwyg_composer_link_action_edit_title" = "ăȘăłăŻăç·šé";
+"deselect_all" = "ć
šăŠăźéžæăè§Łé€";
+"ignore_user" = "ăŠăŒă¶ăŒăçĄèŠ";
+"notice_room_name_removed_for_dm" = "%@ăă«ăŒă ćăćé€ăăŸăă";
+// New
+"notice_room_join_rule_invite" = "%@ăăăźă«ăŒă ăăæćŸ
è
ăźăżćć ćŻèœăă«èšćźăăŸăăă";
+"notice_room_join_rule_invite_for_dm" = "%@ăăăăăæćŸ
è
ăźăżćć ćŻèœăă«èšćźăăŸăăă";
+"notice_room_join_rule_invite_by_you" = "ăăźă«ăŒă ăăæćŸ
è
ăźăżćć ćŻèœăă«èšćźăăŸăăă";
+"notice_room_join_rule_invite_by_you_for_dm" = "ăăăăæćŸ
è
ăźăżćć ćŻèœăă«èšćźăăŸăăă";
+"notice_room_join_rule_public" = "%@ăă«ăŒă ăć
ŹéăăŸăăă";
+"notice_room_join_rule_public_for_dm" = "%@ăć
ŹéăăŸăăă";
+"notice_room_join_rule_public_by_you" = "ă«ăŒă ăć
ŹéăăŸăăă";
+"notice_room_join_rule_public_by_you_for_dm" = "ć
ŹéăăŸăăă";
+"notice_room_power_level_intro_for_dm" = "ăĄăłăăŒăźæš©éăŹăă«ïŒ";
+"notice_room_aliases_for_dm" = "ăšă€ăȘăąăčïŒ%@";
+"notice_voice_broadcast_live" = "ă©ă€ăé
俥";
+"notice_voice_broadcast_ended" = "%@ăéłćŁ°é
俥ăç”äșăăŸăăă";
+"notice_voice_broadcast_ended_by_you" = "éłćŁ°é
俥ăç”äșăăŸăăă";
+"room_event_encryption_info_key_authenticity_not_guaranteed" = "ăăźæć·ćăăăăĄăă»ăŒăžăźçæŁæ§ăŻăăźç«Żæ«ă§ăŻäżèšŒă§ăăŸăăă";
+"room_left_for_dm" = "éćșăăŸăă";
+"message_reply_to_sender_sent_their_live_location" = "äœçœźæ
ć ±ïŒă©ă€ăïŒă";
+"attachment_unsupported_preview_title" = "ăăŹăă„ăŒă§ăăŸăă";
+"attachment_unsupported_preview_message" = "ăăźăăĄă€ă«ăźçšźéĄăŻă”ăăŒăăăŠăăŸăăă";
+"microphone_access_not_granted_for_voice_message" = "éłćŁ°ăĄăă»ăŒăžă«ăŻăă€ăŻăžăźăąăŻă»ăčăćż
èŠă§ăăă%@ă«ăŻăă€ăŻăäœżçšăăæš©éăăăăŸăă";
+"notice_room_third_party_invite_for_dm" = "%@ă%@ăæćŸ
ăăŸăă";
+"notice_room_name_changed_for_dm" = "%@ăććă%@ă«ć€æŽăăŸăăă";
+"notice_room_third_party_invite_by_you" = "%@ă«ă«ăŒă ăžăźæćŸ
ăéăăŸăă";
+"notice_room_third_party_invite_by_you_for_dm" = "%@ăæćŸ
ăăŸăă";
+"notice_room_third_party_registered_invite_by_you" = "%@ăźæćŸ
ăćăć
„ăăŸăă";
+"notice_room_reject_by_you" = "æćŸ
ăæćŠăăŸăă";
+"notice_room_withdraw_by_you" = "%@ăźæćŸ
ăćăäžăăŸăă";
+"notice_declined_video_call_by_you" = "é話ăæćŠăăŸăă";
+"notice_room_history_visible_to_anyone_by_you" = "ä»ćŸăźă«ăŒă ăźć±„æŽăăèȘ°ă§ăăéČ芧ćŻèœă«èšćźăăŸăăă";
+"notice_room_history_visible_to_members_by_you" = "ä»ćŸăźă«ăŒă ăźć±„æŽăăăĄăłăăŒăźăżăéČ芧ćŻèœă«èšćźăăŸăăă";
+"notice_room_history_visible_to_members_by_you_for_dm" = "ä»ćŸăźăĄăă»ăŒăžăăăĄăłăăŒăźăżăéČ芧ćŻèœă«èšćźăăŸăăă";
+"notice_room_history_visible_to_members_from_invited_point_by_you" = "ä»ćŸăźăĄăă»ăŒăžăăăĄăłăăŒăźăż ïŒæćŸ
ăăăæçč仄éïŒăéČ芧ćŻèœă«èšćźăăŸăăă";
+"notice_room_history_visible_to_members_from_invited_point_by_you_for_dm" = "ä»ćŸăźăĄăă»ăŒăžăăć
šćĄ ïŒæćŸ
ăăăæçč仄éïŒăéČ芧ćŻèœă«èšćźăăŸăăă";
+"notice_room_history_visible_to_members_from_joined_point_by_you" = "ä»ćŸăźă«ăŒă ăźć±„æŽăăăĄăłăăŒăźăż ïŒćć ăăæçč仄éïŒăéČ芧ćŻèœă«èšćźăăŸăăă";
+"notice_room_history_visible_to_members_from_joined_point_by_you_for_dm" = "ä»ćŸăźăĄăă»ăŒăžăăć
šćĄ ïŒćć ăăæçč仄éïŒăéČ芧ćŻèœă«èšćźăăŸăăă";
+"call_more_actions_audio_use_device" = "ç«Żæ«ăźăčăăŒă«ăŒ";
+"call_more_actions_transfer" = "è»ąé";
+"call_voice_with_user" = "%@ăšăźéłćŁ°é話";
+"call_transfer_to_user" = "%@ă«è»ąé";
+"pin_protection_confirm_pin" = "PINăłăŒăăçąșèȘăăŠăă ăă";
+"pin_protection_choose_pin" = "PINăłăŒăăèšćźăăŠăă ăă";
+"pin_protection_choose_pin_welcome_after_register" = "ăăăăă";
+
+// MARK: - PIN Protection
+
+"pin_protection_choose_pin_welcome_after_login" = "ăăăăăȘăăă";
+"major_update_done_action" = "äșè§Ł";
+"cross_signing_setup_banner_subtitle" = "ä»ăźç«Żæ«ăăăç°Ąćă«èȘ蚌";
+
+// MARK: - Cross-signing
+
+// Banner
+
+"cross_signing_setup_banner_title" = "æć·ćăźèšćź";
+"secrets_reset_reset_action" = "ăȘă»ăă";
+"secrets_reset_warning_message" = "汄æŽăšăĄăă»ăŒăžăæ¶ć»ăăăäżĄé Œæžăźç«Żæ«ăäżĄé ŒæžăźăŠăŒă¶ăŒăćăæ¶ăăăŸăă";
+"secrets_reset_warning_title" = "ć
šăŠăăȘă»ăăăăăš";
+"secrets_reset_information" = "ăăźç«Żæ«ăèȘ蚌ă§ăăä»ăźç«Żæ«ăć
šăăȘăć Žćă«ăźăżăç¶èĄăăŠăă ăăă";
+
+// MARK: - Secrets reset
+
+"secrets_reset_title" = "ć
šăŠăȘă»ăă";
+
+
+"secrets_setup_recovery_passphrase_summary_title" = "ă»ăă„ăȘăăŁăŒăăŹăŒășăäżć";
+"secrets_setup_recovery_passphrase_confirm_passphrase_placeholder" = "ăăčăăŹăŒășăçąșèȘ";
+"secrets_setup_recovery_passphrase_confirm_passphrase_title" = "çąșèȘ";
+"secrets_setup_recovery_passphrase_confirm_information" = "çąșèȘăźăăăă»ăă„ăȘăăŁăŒăăŹăŒășăćć
„ćăăŠăă ăăă";
+"secrets_setup_recovery_passphrase_additional_information" = "Matrixăźăąă«ăŠăłăăăčăŻăŒăăšéăăăźă«ăăŠăă ăăă";
+"secrets_setup_recovery_passphrase_information" = "ăăȘăăăç„ăăȘăă»ăă„ăȘăăŁăŒăăŹăŒășăć
„ćăăŠăă ăăăă”ăŒăăŒă§æ©ćŻæ
ć ±ăäżè·ăăăăă«äœżçšăăŸăă";
+
+// Recovery passphrase
+
+"secrets_setup_recovery_passphrase_title" = "ă»ăă„ăȘăăŁăŒăăŹăŒășăèšćź";
+"secrets_setup_recovery_key_storage_alert_title" = "性ćă«äżè·ăăŸăăă";
+"secrets_setup_recovery_key_export_action" = "äżć";
+"secrets_setup_recovery_key_loading" = "èȘăżèŸŒăă§ăăŸăâŠ";
+
+// MARK: - Secrets set up
+
+// Recovery Key
+
+"secrets_setup_recovery_key_title" = "ă»ăă„ăȘăăŁăŒăăŒăäżć";
+"secrets_recovery_with_key_invalid_recovery_key_title" = "æ©ćŻăčăăŹăŒăžă«ăąăŻă»ăčă§ăăŸăă";
+"secrets_recovery_with_key_recover_action" = "é”ăäœżçš";
+"secrets_recovery_with_key_recovery_key_placeholder" = "ă»ăă„ăȘăăŁăŒăăŒăć
„ć";
+"secrets_recovery_with_key_recovery_key_title" = "ć
„ć";
+"secrets_recovery_with_key_information_unlock_secure_backup_with_key" = "ç¶èĄăăă«ăŻă»ăă„ăȘăăŁăŒăăŒăć
„ćăăŠăă ăăă";
+
+// Recover with key
+
+"secrets_recovery_with_key_title" = "ă»ăă„ăȘăăŁăŒăăŒ";
+"secrets_recovery_with_passphrase_invalid_passphrase_title" = "æ©ćŻăčăăŹăŒăžă«ăąăŻă»ăčă§ăăŸăă";
+"secrets_recovery_with_passphrase_lost_passphrase_action_part3" = "ă";
+"secrets_recovery_with_passphrase_lost_passphrase_action_part2" = "ă»ăă„ăȘăăŁăŒăăŒăäœżăăŸăăă";
+"secrets_recovery_with_passphrase_lost_passphrase_action_part1" = "ă»ăă„ăȘăăŁăŒăăŹăŒășăćăăăŸăăăïŒăăăȘăšă㯠";
+"secrets_recovery_with_passphrase_passphrase_placeholder" = "ă»ăă„ăȘăăŁăŒăăŹăŒășăć
„ć";
+"secrets_recovery_with_passphrase_passphrase_title" = "ć
„ć";
+
+// Recover with passphrase
+
+"secrets_recovery_with_passphrase_title" = "ă»ăă„ăȘăăŁăŒăăŹăŒăș";
+"secrets_recovery_reset_action_part_2" = "ć
šăŠăȘă»ăă";
+"user_verification_session_details_verify_action_current_user_manually" = "ăăăčăăäœżăŁăŠæćă§èȘ蚌";
+"key_verification_verify_qr_code_scan_code_other_device_action" = "ăăźç«Żæ«ă§ăčăăŁăł";
+"emoji_picker_activity_category" = "ăąăŻăăŁăăăŁăŒ";
+"device_verification_emoji_corn" = "ăšăăăăă";
+"device_verification_emoji_strawberry" = "ăăĄă";
+"device_verification_emoji_apple" = "ăȘăłăŽ";
+"device_verification_emoji_banana" = "ăăă";
+"device_verification_emoji_fire" = "ç";
+"device_verification_emoji_cloud" = "éČ";
+"device_verification_emoji_moon" = "æ";
+"device_verification_emoji_globe" = "ć°ç";
+"device_verification_emoji_mushroom" = "ăăźă";
+"device_verification_emoji_cactus" = "ă”ăăăł";
+"device_verification_emoji_tree" = "æš";
+"device_verification_emoji_flower" = "è±";
+"device_verification_emoji_butterfly" = "ăĄăăăĄă";
+"device_verification_emoji_octopus" = "ăă";
+"device_verification_emoji_fish" = "é";
+"device_verification_emoji_turtle" = "äș";
+"device_verification_emoji_penguin" = "ăăłăźăł";
+"device_verification_emoji_rooster" = "ăăŻăăȘ";
+"device_verification_emoji_panda" = "ăăłă";
+"device_verification_emoji_rabbit" = "ăăă";
+"device_verification_emoji_elephant" = "ăŸăŠ";
+"device_verification_emoji_pig" = "ăăż";
+"device_verification_emoji_unicorn" = "ăŠăăłăŒăł";
+"device_verification_emoji_horse" = "銏";
+"device_verification_emoji_lion" = "ă©ă€ăȘăł";
+"device_verification_emoji_cat" = "ç«";
+
+// MARK: Emoji
+"device_verification_emoji_dog" = "çŹ";
+
+// User
+
+"key_verification_verified_user_information" = "ăăźăŠăŒă¶ăŒăšăźăĄăă»ăŒăžăŻăšăłăăăŒăšăłăă§æć·ćăăăŠăăă珏äžè
ăè§ŁèȘăăăăšăŻă§ăăŸăăă";
+"key_verification_verified_new_session_title" = "æ°ăăă»ăă·ă§ăłăèȘ蚌ăăŸăăïŒ";
+"device_verification_verified_got_it_button" = "äșè§Ł";
+
+// MARK: Verified
+
+// Device
+
+"device_verification_verified_title" = "èȘ蚌ăăŸăăïŒ";
+
+// Device
+
+"device_verification_verify_wait_partner" = "çžæăźæżèȘăćŸ
æ©ăăŠăăŸăâŠ";
+"key_verification_manually_verify_device_validate_action" = "èȘ蚌";
+"key_verification_manually_verify_device_additional_information" = "äžèŽăăŠăăȘăć ŽćăŻăăłăă„ăă±ăŒă·ă§ăłăźă»ăă„ăȘăăŁăŒăæăȘăăăŠăăćŻèœæ§ăăăăŸăă";
+"key_verification_manually_verify_device_key_title" = "ă»ăă·ă§ăłăăŒ";
+"key_verification_manually_verify_device_id_title" = "ă»ăă·ă§ăłID";
+"key_verification_manually_verify_device_name_title" = "ă»ăă·ă§ăłć";
+"key_verification_manually_verify_device_instruction" = "ä»ăźă»ăă·ă§ăłăźăŠăŒă¶ăŒèšćźă§ă仄äžăæŻèŒăăŠæżèȘăăŠăă ăăïŒ";
+
+// MARK: Manually Verify Device
+
+"key_verification_manually_verify_device_title" = "ăăăčăăäœżăŁăŠæćă§èȘ蚌";
+"key_verification_verify_sas_additional_information" = "ă»ăă„ăȘăăŁăŒăæ性éă«é«ăăă«ăŻăćŻŸéąă§èĄăăăä»ăźäżĄé Œă§ăăé俥ææź”ăäœżçšăăŠăă ăăă";
+"key_verification_verify_sas_title_number" = "çȘć·ăæŻèŒ";
+"device_verification_self_verify_wait_recover_secrets_additional_information" = "æąćăźă»ăă·ă§ăłă«ăąăŻă»ăčă§ăăȘăć Žć";
+"device_verification_self_verify_wait_recover_secrets_with_passphrase" = "ă»ăă„ăȘăăŁăŒăăŹăŒășăŸăăŻă»ăă„ăȘăăŁăŒăăŒăäœżçš";
+"device_verification_self_verify_wait_recover_secrets_without_passphrase" = "ă»ăă„ăȘăăŁăŒăăŒăäœżçš";
+"device_verification_self_verify_wait_new_sign_in_title" = "ăăźăă°ă€ăłăèȘ蚌";
+"key_verification_self_verify_unverified_sessions_alert_validate_action" = "çąșèȘ";
+"key_verification_alert_body" = "ăąă«ăŠăłăăćźć
šăă©ăăçąșèȘăăŠăă ăăă";
+
+// Unverified sessions
+"key_verification_alert_title" = "æȘèȘ蚌ăźă»ăă·ă§ăłăăăăŸă";
+"key_verification_self_verify_current_session_alert_validate_action" = "èȘ蚌";
+
+// Current session
+
+"key_verification_self_verify_current_session_alert_title" = "ăăźă»ăă·ă§ăłăèȘ蚌";
+"device_verification_self_verify_start_waiting" = "ćŸ
æ©ăăŠăăŸăâŠ";
+"device_verification_self_verify_start_information" = "æ°ăăă»ăă·ă§ăłăèȘ蚌ăăŠăæć·ćăăăăĄăă»ăŒăžă«ăąăŻă»ăčă§ăăăăă«ăăŸăăăă";
+"device_verification_self_verify_start_verify_action" = "èȘ蚌ăéć§";
+"device_verification_start_use_legacy_action" = "ăŹăŹă·ăŒèȘ蚌ăäœżçš";
+"device_verification_start_verify_button" = "èȘ蚌ăéć§";
+
+// MARK: Start
+"device_verification_start_title" = "çăæććăæŻèŒăăŠèȘ蚌";
+"device_verification_incoming_description_2" = "ăăźă»ăă·ă§ăłăèȘ蚌ăăăšăäżĄé ŒæžăšăăŠăăŒăŻăăăăăȘăăźă»ăă·ă§ăłăçžæă«äżĄé ŒæžăšăăŠăăŒăŻăăăŸăă";
+"device_verification_incoming_description_1" = "ăăźă»ăă·ă§ăłăèȘ蚌ăăăšăäżĄé ŒæžăšăăŠăăŒăŻăăăŸăăçžæăźă»ăă·ă§ăłăäżĄé Œăăăšăăăäžć±€ćźćżăăŠăšăłăăăŒăšăłăæć·ćăäœżçšăăăăšăă§ăăŸăă";
+
+// MARK: Incoming
+"device_verification_incoming_title" = "èȘ蚌ăźăȘăŻăšăčăăć±ăăŠăăŸă";
+"device_verification_error_cannot_load_device" = "ă»ăă·ă§ăłăźæ
ć ±ăèȘăżèŸŒăăŸăăă";
+"device_verification_cancelled_by_me" = "èȘ蚌ăăăŁăłă»ă«ăăăŸăăăçç±ïŒ%@";
+"device_verification_cancelled" = "çžæăèȘ蚌ăăăŁăłă»ă«ăăŸăăă";
+"device_verification_security_advice_number" = "æ°ćăæŻèŒăăŠăćăé çȘă§çŸăăŠăăăăšăçąșèȘăăŠăă ăăă";
+"key_verification_this_session_title" = "ăăźă»ăă·ă§ăłăèȘ蚌";
+
+// MARK: - Device Verification
+"key_verification_other_session_title" = "ă»ăă·ă§ăłăèȘ蚌";
+"sign_out_key_backup_in_progress_alert_discard_key_backup_action" = "æć·ćăăăăĄăă»ăŒăžăŻäžèŠă§ă";
+"sign_out_key_backup_in_progress_alert_title" = "é”ăăăăŻăąăăăăŠăăŸăăćŠçäžă«ă”ă€ăłăąăŠăăăăšăæć·ćăăăăĄăă»ăŒăžă«ăąăŻă»ăčă§ăăȘăăȘăăŸăă";
+"sign_out_non_existing_key_backup_sign_out_confirmation_alert_message" = "ă”ă€ăłăąăŠăăăćă«é”ăăăăŻăąăăăăȘăăšăæć·ćăăăăĄăă»ăŒăžă«ăąăŻă»ăčă§ăăȘăăȘăăŸăă";
+"sign_out_non_existing_key_backup_alert_discard_key_backup_action" = "æć·ćăăăăĄăă»ăŒăžăŻäžèŠă§ă";
+"sign_out_non_existing_key_backup_alert_setup_secure_backup_action" = "ă»ăă„ăąăăăŻăąăăăäœżçšéć§";
+"sign_out_non_existing_key_backup_alert_title" = "ä»ă”ă€ăłăąăŠăăăăšăăăȘăăźæć·ćăăăăĄăă»ăŒăžă«ăąăŻă»ăčă§ăăȘăăȘăăŸă";
+"sign_out_confirmation_message" = "ă”ă€ăłăąăŠăăăŠăăăăă§ăăïŒ";
+
+// MARK: Sign out warning
+
+"sign_out" = "ă”ă€ăłăąăŠă";
+
+// Success
+
+"key_backup_recover_success_info" = "ăăăŻăąăăăćŸ©ć
ăăŸăăïŒ";
+"key_backup_recover_from_recovery_key_lost_recovery_key_action" = "ă»ăă„ăȘăăŁăŒăăŒăçĄăăăŸăăăïŒăèšćźă§æ°ăăă»ăă„ăȘăăŁăŒăăŒăèšćźă§ăăŸăă";
+"key_backup_recover_from_recovery_key_recover_action" = "汄æŽăźăăăŻăè§Łé€";
+"key_backup_recover_from_recovery_key_recovery_key_placeholder" = "ă»ăă„ăȘăăŁăŒăăŒăć
„ć";
+"key_backup_recover_from_recovery_key_recovery_key_title" = "ć
„ć";
+
+// Recover from recovery key
+
+"key_backup_recover_from_recovery_key_info" = "ă»ăă„ăȘăăŁăŒăăŒăäœżăăšăæć·ćăăăăĄăă»ăŒăžăźć±„æŽăźăăăŻăè§Łé€ă§ăăŸă";
+"call_video_with_user" = "%@ăšăźăăăȘé話";
+"call_more_actions_hold" = "äżç";
+"notice_encryption_enabled_unknown_algorithm_by_you" = "ăšăłăăăŒăšăłăæć·ćïŒèȘèăăăŠăăȘăăąă«ăŽăȘășă %@ïŒăæćčă«ăăŸăăă";
+"notice_room_name_removed_by_you_for_dm" = "ă«ăŒă ćăćé€ăăŸăă";
+"notice_room_third_party_revoked_invite_by_you" = "%@ăźă«ăŒă ăžăźæćŸ
ăćăæ¶ăăŸăă";
+"notice_declined_video_call" = "%@ăé話ăæćŠăăŸăă";
+"attachment_size_prompt_message" = "ăăăŻèšćźăăçĄćčă«ă§ăăŸăă";
+"message_reply_to_sender_sent_their_location" = "äœçœźæ
ć ±ăć
±æăăŸăăă";
+"message_reply_to_sender_sent_a_voice_message" = "éłćŁ°ăĄăă»ăŒăžăé俥ăăŸăăă";
+"wysiwyg_composer_start_action_text_formatting" = "ăăăčăăźèŁ
éŁŸ";
+"user_session_details_device_model" = "ćœąćŒ";
+"user_inactive_session_item_with_date" = "90æ„仄äžäœżçšăăăŠăăŸăăïŒ%@ïŒ";
+"user_inactive_session_item" = "90æ„仄äžäœżçšăăăŠăăŸăă";
+
+/* %1$@ will be the verification state and %2$@ will be user_session_item_details_verification_unknown or user_other_session_current_session_details */
+"user_session_item_details" = "%1$@ · %2$@";
+"user_other_session_selected_count" = "%@件éžææž";
+"user_session_inactive_session_description" = "éăąăŻăăŁăăȘă»ăă·ă§ăłăŻăăă°ăăäœżçšăăăŠăăŸăăăăæć·é”ăć俥ăăŠăăă»ăă·ă§ăłă§ăă\n\näœżçšăăŠăăȘăă»ăă·ă§ăłăćé€ăăăšăă»ăă„ăȘăăŁăŒăšăăă©ăŒăăłăčăæčćăăăŸăăăŸăăæ°ăăă»ăă·ă§ăłăçăăăć Žćă«ăăăćźčæă«çčćźă§ăăăăă«ăȘăăŸăă";
+"user_session_permanently_unverified_session_description" = "ăăźă»ăă·ă§ăłăŻæć·ćăă”ăăŒăăăŠăăȘăăăăèȘ蚌ă§ăăŸăăă\n\năăźă»ăă·ă§ăłă§ăŻăæć·ćăæćčă«ăȘăŁăŠăăă«ăŒă ă«ćć ăăăăšăă§ăăŸăăă\n\nă»ăă„ăȘăăŁăŒăšăă©ă€ăă·ăŒäżè·ăźèŠłçčăăăæć·ćăă”ăăŒăăăŠăăMatrixăźăŻă©ă€ăąăłăăźäœżçšăæšć„šăăŸăă";
+"user_sessions_overview_security_recommendations_unverified_info" = "æȘèȘ蚌ăźă»ăă·ă§ăłăèȘ蚌ăăăăă”ă€ăłăąăŠăăăŠăă ăăă";
+"location_sharing_live_list_item_time_left" = "æźă%@";
+"location_sharing_live_viewer_title" = "äœçœźæ
ć ±";
+"location_sharing_live_map_callout_title" = "äœçœźæ
ć ±ăć
±æ";
+"location_sharing_pin_drop_share_title" = "ăăźäœçœźæ
ć ±ăé俥";
+"location_sharing_static_share_title" = "çŸćšăźäœçœźæ
ć ±ăé俥";
+"location_sharing_map_loading_error" = "ć°ćłăèȘăżèŸŒăăŸăă\năăźăăŒă ă”ăŒăăŒăŻć°ćłăèȘăżèŸŒăăăèšćźăăăŠăăŸăă";
+"location_sharing_allow_background_location_cancel_action" = "ćŸă§";
+"location_sharing_allow_background_location_validate_action" = "èšćź";
+"location_sharing_allow_background_location_title" = "ăąăŻă»ăčăèš±ćŻ";
+"location_sharing_settings_header" = "äœçœźæ
ć ±ăźć
±æ";
+"location_sharing_open_open_street_maps" = "OpenStreetMapă§éă";
+"location_sharing_open_apple_maps" = "Appleăăăă§éă";
+"location_sharing_invalid_authorization_not_now" = "ćŸă§";
+"location_sharing_locating_user_error_title" = "%@ăŻäœçœźæ
ć ±ă«ăąăŻă»ăčă§ăăŸăăă§ăăăćŸă§ăăäžćșŠăăçŽăăŠăă ăăă";
+"location_sharing_post_failure_subtitle" = "%@ăŻäœçœźæ
ć ±ăé俥ă§ăăŸăăă§ăăăćŸă§ăăäžćșŠăăçŽăăŠăă ăăă";
+"location_sharing_post_failure_title" = "äœçœźæ
ć ±ăé俥ă§ăăŸăăă§ăă";
+"location_sharing_close_action" = "éăă";
+"poll_timeline_ended_text" = "ăąăłă±ăŒăăç”äșăăŸăă";
+"poll_timeline_decryption_error" = "ćŸ©ć·ăšă©ăŒă«ăăăăăă€ăăźæç„šăŻă«ăŠăłăă§ăăŸăă";
+"poll_history_fetching_error" = "ăąăłă±ăŒăăźććŸäžă«ăšă©ăŒăçșçăăŸăăă";
+"poll_history_no_past_poll_text" = "ăăźă«ăŒă ă«éć»ăźăąăłă±ăŒăăŻăăăŸăă";
+"poll_history_no_active_poll_text" = "ăăźă«ăŒă ă«ćźæœäžăźăąăłă±ăŒăăŻăăăŸăă";
+"poll_history_past_segment_title" = "éć»ăźăąăłă±ăŒă";
+"poll_history_active_segment_title" = "ćźæœäžăźăąăłă±ăŒă";
+"poll_history_loading_text" = "ăąăłă±ăŒăăèĄšç€șăăŠăăŸă";
+
+// MARK: - Polls history
+
+"poll_history_title" = "ăąăłă±ăŒăăźć±„æŽ";
+"space_detail_nav_title" = "ăčăăŒăčăźè©łçŽ°";
+
+// MARK: - Room invites
+
+"room_invites_empty_view_title" = "æ°çăŻăăăŸăăă";
+"all_chats_edit_menu_space_settings" = "ăčăăŒăčăźèšćź";
+"all_chats_edit_menu_leave_space" = "%@ăăéćș";
+"all_chats_user_menu_accessibility_label" = "ăŠăŒă¶ăŒăĄăă„ăŒ";
+"room_recents_recently_viewed_section" = "æèżèĄšç€șăăă«ăŒă ";
+"all_chats_empty_space_information" = "ăčăăŒăčăŻăă«ăŒă ăéŁç”Ąć
ăăŸăšăăæ°ăăæčæłă§ăăćłäžăźăăżăłăäœżăăšăæąćăźă«ăŒă ăèżœć ăăăæ°ăă«äœæăăăă§ăăŸăă";
+"all_chats_edit_layout_sorting_options_title" = "ăĄăă»ăŒăžă䞊ăłæżăă";
+"all_chats_edit_layout_add_filters_title" = "ăĄăă»ăŒăžăç”ă蟌ă";
+"version_check_modal_action_title_supported" = "äșè§Ł";
+"voice_broadcast_recorder_connection_error" = "æ„ç¶ăšă©ăŒ - éČéłăćæąăăŸăă";
+"voice_broadcast_connection_error_message" = "éČéłăéć§ă§ăăŸăăăćŸă§ăăäžćșŠăăçŽăăŠăă ăăă";
+"voice_broadcast_connection_error_title" = "æ„ç¶ăšă©ăŒ";
+"voice_broadcast_voip_cannot_start_description" = "ă©ă€ăé
俥ăéČéłăăŠăăăăăé話ăéć§ă§ăăŸăăăé話ăéć§ăăă«ăŻăă©ă€ăé
俥ăç”äșăăŠăă ăăă";
+"voice_broadcast_voip_cannot_start_title" = "é話ăéć§ă§ăăŸăă";
+"voice_broadcast_stop_alert_agree_button" = "ăŻăăćæą";
+"voice_broadcast_stop_alert_description" = "ă©ă€ăé
俥ăç”äșăăŠăăăăă§ăăïŒé
俥ăç”äșăăéČéłăăăźă«ăŒă ă§ć©çšă§ăăăăèšćźăăŸăă";
+"voice_broadcast_stop_alert_title" = "ă©ă€ăé
俥ăćæąăăŸăăïŒ";
+"voice_broadcast_buffering" = "ăăăăĄăȘăłă°ăăŠăăŸăâŠ";
+"voice_broadcast_time_left" = "æźă%@";
+"voice_broadcast_tile" = "éłćŁ°é
俥";
+"voice_broadcast_live" = "ă©ă€ă";
+"voice_broadcast_playback_lock_screen_placeholder" = "éłćŁ°é
俥";
+"voice_broadcast_playback_loading_error" = "ăăźéłćŁ°é
俥ăćçă§ăăŸăăă";
+"voice_broadcast_already_in_progress_message" = "æąă«éłćŁ°é
俥ăéČéłăăŠăăŸăăæ°ăăć§ăăă«ăŻä»ăźéłćŁ°é
俥ăç”äșăăŠăă ăăă";
+"voice_broadcast_blocked_by_someone_else_message" = "ä»ăźäșșăæąă«éłćŁ°é
俥ăéČéłăăŠăăŸăăæ°ăăć§ăăă«ăŻéłćŁ°é
俥ăç”ăăăŸă§ćŸ
æ©ăăŠăă ăăă";
+"voice_broadcast_permission_denied_message" = "ăăźă«ăŒă ă§éłćŁ°é
俥ăéć§ăăæš©éăăăăŸăăăă«ăŒă ăźçźĄçè
ă«éŁç”ĄăăŠæš©éăźä»äžăäŸé ŒăăŠăă ăăă";
+
+// MARK: - Voice Broadcast
+"voice_broadcast_unauthorized_title" = "æ°ăăéłćŁ°é
俥ăéć§ă§ăăŸăă";
+"voice_message_broadcast_in_progress_message" = "ă©ă€ăé
俥ăéČéłăăŠăăăăăéłćŁ°ăĄăă»ăŒăžăéć§ă§ăăŸăăăéłćŁ°ăĄăă»ăŒăžăźéČéłăéć§ăăă«ăŻăă©ă€ăé
俥ăç”äșăăŠăă ăă";
+"voice_message_broadcast_in_progress_title" = "éłćŁ°ăĄăă»ăŒăžăéć§ă§ăăŸăă";
+"voice_message_lock_screen_placeholder" = "éłćŁ°ăĄăă»ăŒăž";
+"voice_message_remaining_recording_time" = "æźă%@";
+
+// MARK: - Voice Messages
+
+"voice_message_release_to_send" = "æŒăç¶ăăŠéČéłăăéąăăšé俥";
+"side_menu_app_version" = "ăăŒăžă§ăł %@";
+"user_avatar_view_accessibility_hint" = "ăŠăŒă¶ăŒăźăąăăżăŒăć€æŽ";
+
+// MARK: - User avatar view
+
+"user_avatar_view_accessibility_label" = "ăąăăżăŒ";
+"space_avatar_view_accessibility_hint" = "ăčăăŒăčăźăąăăżăŒăć€æŽ";
+
+// MARK: Avatar
+
+"space_avatar_view_accessibility_label" = "ăąăăżăŒ";
+"leave_space_selection_no_rooms" = "ă«ăŒă ăéžæăăȘă";
+"spaces_creation_post_process_creating_room" = "%@ăäœæăăŠăăŸă";
+"spaces_creation_post_process_uploading_avatar" = "ăąăăżăŒăăąăăăăŒăăăŠăăŸă";
+"spaces_creation_invite_by_username_title" = "ăăŒă ăæćŸ
";
+"spaces_creation_invite_by_username" = "ăŠăŒă¶ăŒćă§æćŸ
";
+"spaces_creation_sharing_type_title" = "èȘ°ăšäœżăăŸăăïŒ";
+"spaces_creation_email_invites_email_title" = "é»ćăĄăŒă«";
+"spaces_creation_email_invites_title" = "ăăŒă ăæćŸ
";
+"spaces_creation_new_rooms_support" = "ă”ăăŒă";
+"spaces_creation_new_rooms_random" = "ă©ăłăă ";
+"spaces_creation_new_rooms_general" = "äžèŹ";
+"spaces_creation_new_rooms_room_name_title" = "ă«ăŒă ć";
+"spaces_creation_private_space_title" = "ăăȘăăźéć
ŹéăźăčăăŒăč";
+"spaces_creation_public_space_title" = "ăăȘăăźć
ŹéăčăăŒăč";
+"spaces_subspace_creation_visibility_title" = "äœæăăă”ăăčăăŒăčăźçšźéĄăéžæăăŠăă ăă";
+
+// MARK: - Space Creation
+
+"spaces_creation_hint" = "ăčăăŒăčăŻăă«ăŒă ăéŁç”Ąć
ăăŸăšăăæ°ăăæčæłă§ăă";
+"spaces_add_space" = "ăčăăŒăčăèżœć ";
+"spaces_add_room" = "ă«ăŒă ăèżœć ";
+"spaces_invite_people" = "éŁç”Ąć
ăæćŸ
";
+"space_public_join_rule" = "ć
ŹéăčăăŒăč";
+"space_private_join_rule" = "éć
ŹéăźăčăăŒăč";
+"spaces_no_result_found_title" = "æ€çŽąç”æăăăăŸăă";
+"space_tag" = "ăčăăŒăč";
+"spaces_explore_rooms_one_room" = "1ćăźă«ăŒă ";
+"spaces_explore_rooms_room_number" = "%@ćăźă«ăŒă ";
+"leave_space_and_all_rooms_action" = "ć
šăŠăźă«ăŒă ăšăčăăŒăčăăéćș";
+"leave_space_only_action" = "ă©ăźă«ăŒă ăăăéćșăăȘă";
+"threads_discourage_information_2" = "\n\năčăŹăăæ©èœăæćčă«ăăŠăăăăă§ăăïŒ";
+"room_no_privileges_to_create_group_call" = "é話ăéć§ăăă«ăŻçźĄçè
ăăăăŻăąăăŹăŒăżăŒă§ăăćż
èŠăăăăŸăă";
+"contacts_address_book_permission_denied_alert_message" = "éŁç”Ąć
ăæćčă«ăăă«ăŻăç«Żæ«ăźèšćźç»éąăéăăŠăă ăăă";
+"contacts_address_book_permission_denied_alert_title" = "éŁç”Ąć
ăçĄćčă§ă";
+"password_policy_weak_pwd_error" = "ăăčăŻăŒăăćŒ±ăăăŸăă8æć仄äžă§ă性æćăć°æćăæ°ćăçčæźæćăăăăă1ă€ăă€ć«ăăŠăă ăăă";
+"authentication_qr_login_loading_signed_in" = "ä»ăźç«Żæ«ă§ă”ă€ăłă€ăłăăŸăăă";
+"authentication_qr_login_display_step1" = "ä»ăźç«Żæ«ă§ElementăéăăŠăă ăă";
+"authentication_qr_login_start_display_qr" = "ăăźç«Żæ«ă§QRăłăŒăăèĄšç€ș";
+"authentication_qr_login_start_need_alternative" = "ć„ăźæčæłăćż
èŠă§ăăïŒ";
+"authentication_qr_login_start_step1" = "ä»ăźç«Żæ«ă§ElementăéăăŠăă ăă";
+"authentication_qr_login_start_subtitle" = "ăăźç«Żæ«ăźă«ăĄă©ăäœżçšăăŠăä»ăźç«Żæ«ă«èĄšç€șăăăŠăăQRăłăŒăăăčăăŁăłăăŠăă ăăïŒ";
+"authentication_choose_password_not_verified_title" = "é»ćăĄăŒă«ăŻèȘ蚌ăăăŠăăŸăă";
+"authentication_server_selection_generic_error" = "ăăźURLă§ă”ăŒăăŒăçșèŠă§ăăŸăăăURLăçąșèȘăăŠăă ăăă";
+"authentication_server_selection_register_title" = "ăăȘăăźăăŒă ă”ăŒăăŒăéžæăăŠăă ăă";
+"authentication_server_selection_login_message" = "ăăŒă ă”ăŒăăŒăźăąăăŹăčăć
„ćăăŠăă ăă";
+"authentication_server_selection_login_title" = "ăăŒă ă”ăŒăăŒă«æ„ç¶";
+"authentication_login_forgot_password" = "ăăčăŻăŒăăćżăăć Žć";
+"event_formatter_call_answer" = "ćșă";
+"event_formatter_call_incoming_video" = "ç俥äžăźăăăȘé話";
+"event_formatter_call_incoming_voice" = "ç俥äžăźéłćŁ°é話";
+"event_formatter_call_has_ended_with_time" = "é話ăç”äșăăŸăăă»%@";
+"room_access_space_chooser_other_spaces_section" = "ăăźä»ăźăčăăŒăčăŸăăŻă«ăŒă ";
+"room_access_settings_screen_setting_room_access" = "ă«ăŒă ăźăąăŻă»ăčăźèšćź";
+"settings_labs_enable_wysiwyg_composer" = "ăȘăăăăăčăăšăăŁăżăŒăè©ŠăăŠăżă";
+"settings_labs_enable_ringing_for_group_calls" = "ă°ă«ăŒăé話ă§ćŒăłćșă";
+"settings_notifications_disabled_alert_message" = "éç„ăæćčă«ăăă«ăŻăç«Żæ«ăźèšćźç»éąăéăăŠăă ăăă";
+"room_accessibility_record_voice_message_hint" = "2ćç¶ăăŠăżăăăé·æŒăăăăšéČéłă";
+"room_preview_decline_invitation_options" = "æćŸ
ăæćŠăăăăăăźăŠăŒă¶ăŒăçĄèŠăăŸăăïŒ";
+"threads_beta_information" = "ăčăŹăăæ©èœăäœżăŁăŠăäŒè©±ăăŸăšăăŸăăăă\n\năčăŹăăæ©èœăäœżăăšăäŒè©±ăźăăŒăăç¶æăăăăäŒè©±ăç°Ąćă«èżœè·Ąăăăăăăăšăă§ăăŸăă ";
+"threads_notice_information" = "ćźéšæéäžă«äœæăăăăčăŹăăăŻéćžžăźèżäżĄăšăăŠèĄšç€șăăăŸăă
ăčăŹăăæ©èœăŻMatrixăźä»æ§ăźäžéšă«ăȘăŁăăăăăăăŻäžćșŠéăăźć€æŽă§ăă";
+"threads_empty_info_my" = "æąćăźăčăŹăăă«èżäżĄăăăăăĄăă»ăŒăžăăżăăăăăčăŹăăăăăæ°ăăăčăŹăăăéć§ă";
+"room_accessibility_thread_more" = "ăăźä»";
+"room_first_message_placeholder" = "æćăźăĄăă»ăŒăžăé俥âŠ";
+
+// MARK: - Chat
+
+"room_slide_to_end_group_call" = "ăčă©ă€ăăăăšć
šćĄăźé話ăç”äș";
+"authentication_qr_login_failure_request_timed_out" = "æéć
ă«ăȘăłăŻăćźäșăăŸăăă§ăăă";
+"authentication_qr_login_failure_title" = "ăȘăłăŻă«ć€±æăăŸăă";
+"authentication_qr_login_start_step2" = "èšćźăăăă»ăă„ăȘăăŁăŒăšăă©ă€ăă·ăŒăăéăăŠăă ăă";
+"authentication_qr_login_confirm_alert" = "ăăźăłăŒăăźćșæăç„ăŁăŠăăăăšăçąșèȘăăŠăă ăăăç«Żæ«ăăȘăłăŻăăăšăăăȘăăźăąă«ăŠăłăă«çĄć¶éă«ăąăŻă»ăčă§ăăăăă«ăȘăăŸăă";
+"authentication_qr_login_scan_subtitle" = "QRăłăŒăă仄äžăźćè§ćœąă«ćăăăŠăă ăă";
+"authentication_qr_login_display_step2" = "ăQRăłăŒăă§ă”ă€ăłă€ăłăăéžæăăŠăă ăă";
+"authentication_qr_login_start_step4" = "ăăăźç«Żæ«ă§QRăłăŒăăèĄšç€șăăéžæăăŠăă ăă";
+"authentication_qr_login_start_step3" = "ăç«Żæ«ăăȘăłăŻăăéžæăăŠăă ăă";
+"authentication_qr_login_display_title" = "ç«Żæ«ăăȘăłăŻ";
+/* The placeholder will show the full Matrix ID that has been entered. */
+"authentication_registration_username_footer_available" = "ä»ăźäșș㯠%@ ă§ăăȘăăèŠă€ăăăăšăă§ăăŸă";
+"authentication_server_selection_register_message" = "ăăȘăăźăăŒă ă”ăŒăăŒăźăąăăŹăčăć
„ćăăŠăă ăăăăăă«ăăȘăăźć
šăŠăźăăŒăżăăăčăăăăŸă";
+"authentication_server_info_title_login" = "ăąă«ăŠăłăă«ă”ă€ăłă€ăłăăă”ăŒăăŒ";
+"authentication_server_info_title" = "ăąă«ăŠăłăăäœæăăă”ăŒăăŒ";
+"onboarding_avatar_message" = "èĄšç€șćă«ăăăăŁăŒă«ç»ćăèżœć ăăŸăăă";
+"all_chats_edit_layout_add_filters_message" = "ăăȘăăéžæăăă«ăăŽăȘăŒă«ăĄăă»ăŒăžăèȘćçă«ăăŁă«ăżăȘăłă°";
+"all_chats_empty_view_information" = "ăăŒă ăćéăç”çčćăăźăȘăŒă«ă€ăłăŻăłăźćźć
šăȘăăŁăăăąăăȘă§ăăăŻăăă«ăăăŁăăăäœæăăăæąćăźă«ăŒă ă«ćć ăăŸăăăă";
+"home_empty_view_information" = "ăăŒă ăćéăç”çčćăăźăȘăŒă«ă€ăłăŻăłăźćźć
šăȘăăŁăăăąăăȘă§ăă仄äžăźïŒăăżăłăæŒăăšăéŁç”Ąć
ăšă«ăŒă ăèżœć ă§ăăŸăă";
+"all_chats_empty_view_title" = "%@\năŻç©șă§ăă";
+"all_chats_nothing_found_placeholder_message" = "æ€çŽąăèȘżæŽăăŠăżăŠăă ăăă";
+"all_chats_nothing_found_placeholder_title" = "äœăèŠă€ăăăŸăăă§ăăă";
+"all_chats_edit_layout_pin_spaces_title" = "ăčăăŒăčăăăłæąă";
+"all_chats_edit_layout_add_section_message" = "ă»ăŻă·ă§ăłăăăŒă ă«ăăłæąăăăăšç°Ąćă«ăąăŻă»ăčă§ăăŸă";
+"all_chats_edit_layout_add_section_title" = "ă»ăŻă·ă§ăłăăăŒă ă«èżœć ";
+"version_check_banner_subtitle_deprecated" = "%@ăźă”ăăŒăăŻiOS %@ă§ç”äșăăŸăăă%@ăźäœżçšăç¶ç¶ăăć ŽćăŻăiOSăźăăŒăžă§ăłăăąăăă°ăŹăŒăăăŠăă ăăă";
+"version_check_banner_subtitle_supported" = "%@ăźă”ăăŒăăŻiOS %@ă§èżæ„äžă«ç”äșăăŸăă%@ăźäœżçšăç¶ç¶ăăć ŽćăŻăiOSăźăăŒăžă§ăłăăąăăă°ăŹăŒăăăŠăă ăăă";
+"version_check_modal_action_title_deprecated" = "æčæłăçąșèȘ";
+"version_check_modal_title_supported" = "iOS %@ăźă”ăăŒăăŻèżæ„äžă«ç”äșăăŸă";
+
+// MARK: - Version check
+
+"version_check_banner_title_supported" = "iOS %@ăźă”ăăŒăăŻèżæ„äžă«ç”äșăăŸă";
+"version_check_banner_title_deprecated" = "iOS %@ăźă”ăăŒăăŻç”äșăăŸăă";
+"version_check_modal_title_deprecated" = "iOS %@ăźă”ăăŒăăŻç”äșăăŸăă";
+"attachment_size_prompt_title" = "é俥ăăă”ă€ășăçąșèȘ";
+"attachment_small_with_resolution" = "ć°ïŒ%@ïŒ~%@ïŒ";
+"attachment_medium_with_resolution" = "äžïŒ%@ïŒ~%@ïŒ";
+"attachment_large_with_resolution" = "性ïŒ%@ïŒ~%@ïŒ";
+"e2e_passphrase_too_short" = "ăăčăăŹăŒășăçăăăŸăïŒ%dæć仄äžă«ăăŠăă ăăïŒ";
+"notice_room_third_party_revoked_invite_for_dm" = "%@ă%@ăźæćŸ
ăćăæ¶ăăŸăă";
+"notice_room_third_party_revoked_invite_by_you_for_dm" = "%@ăźæćŸ
ăćăæ¶ăăŸăă";
+"notice_room_name_changed_by_you_for_dm" = "ććă%@ă«ć€æŽăăŸăăă";
+"call_remote_holded" = "%@ăé話ăäżçăăŸăă";
+"call_holded" = "é話ăäżçăăŸăă";
+"call_more_actions_unhold" = "ćé";
+"user_session_rename_session_description" = "ăăȘăăćć ăăăă€ăŹăŻăăĄăă»ăŒăžăšă«ăŒă ăźä»ăźăŠăŒă¶ăŒăŻăăăȘăăźă»ăă·ă§ăłăźäžèŠ§ăéČ芧ă§ăăŸăă\n\nă»ăă·ă§ăłăźäžèŠ§ăăăçžæăŻăăȘăăšăăćăăăŠăăăăšăçąșăăăăăšăă§ăăŸăăăȘăăăăȘăăăăă«ć
„ćăăă»ăă·ă§ăłćăŻçžæă«ćŻŸăăŠèĄšç€șăăăŸăă";
+"user_session_unverified_session_description" = "æȘèȘ蚌ăźă»ăă·ă§ăłăŻăèȘ蚌æ
ć ±ă§ăă°ă€ăłăăăŠăăŸăăăăŻăăčèȘ蚌ăŻèĄăăăŠăăȘăă»ăă·ă§ăłă§ăă\n\năăăăźă»ăă·ă§ăłăŻăăąă«ăŠăłăăźäžæŁäœżçšăç€șăăŠăăćŻèœæ§ăăăăăăæłšæăăŠçąșèȘăăŠăă ăăă";
+"user_session_verified_session_description" = "èȘ蚌æžăźă»ăă·ă§ăłăŻăăăčăăŹăŒășăźć
„ćăăŸăăŻä»ăźèȘ蚌æžăźă»ăă·ă§ăłă§æŹäșșçąșèȘăèĄăŁăă»ăă·ă§ăłă§ăă\n\nèȘ蚌æžăźă»ăă·ă§ăłă«ăŻăæć·ćăăăăĄăă»ăŒăžăćŸ©ć·ćăăéă«äœżçšăăć
šăŠăźé”ăćăăŁăŠăăŸăăăŸăăä»ăźăŠăŒă¶ăŒă«ćŻŸăăŠăŻăăăȘăăăăźă»ăă·ă§ăłăäżĄé ŒăăŠăăăăšăèĄšç€șăăăŸăă";
+"user_session_push_notifications_message" = "æćčă«ăăăšăăăźă»ăă·ă§ăłăŻăăă·ă„éç„ăć俥ăăŸăă";
+"launch_loading_server_syncing" = "ă”ăŒăăŒăšćæăăŠăăŸă";
+"launch_loading_processing_response" = "ăăŒăżăćŠçăăŠăăŸă\n%@ %%";
+"wysiwyg_composer_format_action_link" = "ăȘăłăŻăźèŁ
éŁŸăé©çš";
+"wysiwyg_composer_format_action_inline_code" = "ă€ăłă©ă€ăłăłăŒăăźèŁ
éŁŸăé©çš";
+"wysiwyg_composer_format_action_unordered_list" = "çźæĄæžăăȘăčăăźèĄšç€șăćăæżăă";
+"wysiwyg_composer_format_action_ordered_list" = "çȘć·ä»ăăȘăčăăźèĄšç€șăćăæżăă";
+"wysiwyg_composer_format_action_code_block" = "ăłăŒăăăăăŻăźèĄšç€șăćăæżăă";
+"wysiwyg_composer_format_action_quote" = "ćŒçšăźèĄšç€șăćăæżăă";
+"poll_timeline_reply_ended_poll" = "ç”äșăăăąăłă±ăŒă";
+"settings_labs_enable_crypto_sdk" = "Rust ăšăłăăăŒăšăłăæć·ć";
+"settings_labs_disable_crypto_sdk" = "Rust ăšăłăăăŒăšăłăæć·ćïŒçĄćčă«ăăă«ăŻăă°ăąăŠăăăŠăă ăăïŒ";
+
+// MARK: - Launch loading
+
+"launch_loading_migrating_data" = "ăăŒăżă移èĄăăŠăăŸă\n%@ %%";
+"poll_history_load_more" = "ä»ăźăąăłă±ăŒăăèȘăżèŸŒă";
+"key_backup_recover_from_private_key_progress" = "%@%%ćźäș";
+"voice_broadcast_playback_unable_to_decrypt" = "ăăźéłćŁ°é
俥ăćŸ©ć·ćă§ăăŸăăă";
+"home_context_menu_mark_as_unread" = "æȘèȘă«ăă";
+"key_backup_setup_passphrase_passphrase_valid" = "ăăă§ăăïŒ";
+"key_backup_setup_passphrase_passphrase_invalid" = "èȘăèżœć ăăŠăżă";
+"biometrics_cant_unlocked_alert_title" = "ăąăăȘăźăăăŻăè§Łé€ă§ăăŸăă";
+"key_backup_setup_passphrase_confirm_passphrase_valid" = "ăăă§ăăïŒ";
+"room_avatar_view_accessibility_hint" = "ă«ăŒă ăźăąăăżăŒăć€æŽ";
+"room_intro_cell_information_dm_sentence2" = "ăăźäŒè©±ăŻăäșäșșă ăă§ăä»ăźäșșăŻćć ă§ăăŸăăă";
+"favourites_empty_view_information" = "ăæ°ă«ć
„ăç»éČă«ăŻăăă€ăăźæčæłăăăăŸăăăäžçȘæăŁćăæ©ăăźăŻăé·æŒăăăăăšă§ăăæăăŒăŻăăżăăăăăšăèȘćçă«ăăă«èĄšç€șăăăäżçźĄăăăŸăă";
+"room_intro_cell_information_multiple_dm_sentence2" = "èȘ°ăăæćŸ
ăăȘăéăăăăźäŒè©±ă«ćć ăăŠăăăźăŻăăȘăă ăă§ăă";
+"analytics_prompt_message_new_user" = "%@ăźæčćăšèȘČéĄæœćșăźăăă«ăćżćăźäœżçšç¶æłăăŒăżăźé俥ăăéĄăăăŸăăè€æ°ăźç«Żæ«ă§ăźäœżçšăćæăăăăă«ăăăȘăăźć
šç«Żæ«ć
±éăźă©ăłăă ăȘèć„ćăçæăăŸăă";
+
+// Analytics
+"analytics_prompt_title" = "%@ăźæčćăæäŒă";
+"event_formatter_call_active_video" = "ćźæœäžăźăăăȘé話";
+"event_formatter_call_active_voice" = "ćźæœäžăźéłćŁ°é話";
+"launch_loading_server_syncing_nth_attempt" = "ă”ăŒăăŒăšćæăăŠăăŸă\nïŒ%@ćè©ŠèĄïŒ";
+"create_room_suggest_room_footer" = "ăăăăăźă«ăŒă ăŻăăčăăŒăčăźăĄăłăăŒă«ćŻŸăăŠćć ćèŁăšăăŠèĄšç€șăăăŸăă";
+"create_room_section_footer_type_public" = "ăčăăŒăčăźććă ăă§ăȘăăæćŸ
ăăăäșșă ăăæ€çŽąă»ćć ă§ăăŸăă";
+"searchable_directory_x_network" = "%@ăăăăŻăŒăŻ";
+"pin_protection_explanatory" = "PINăłăŒăăèšćźăăăšăăĄăă»ăŒăžăéŁç”Ąć
ăȘă©ăźăăŒăżăäżè·ă§ăăŸăăăąăăȘăźéć§æă«PINăłăŒăăć
„ćăăăăèŠæ±ăăŸăă";
+"secrets_recovery_with_key_information_default" = "ă»ăă„ăȘăăŁăŒăăŒăć
„ćăăăšăäżè·ăăăăĄăă»ăŒăžăźć±„æŽăšăä»ăźă»ăă·ă§ăłăźèȘ蚌çšăźăŻăăčçœČćIDă«ăąăŻă»ăčă§ăăŸăă";
+"secrets_recovery_with_passphrase_information_default" = "ă»ăă„ăȘăăŁăŒăăŹăŒășăć
„ćăăăšăäżè·ăăăăĄăă»ăŒăžăźć±„æŽăšăä»ăźă»ăă·ă§ăłăźèȘ蚌çšăźăŻăăčçœČćIDă«ăąăŻă»ăčă§ăăŸăă";
+"user_verification_session_details_verify_action_current_user" = "ă€ăłăżă©ăŻăăŁăèȘ蚌";
+"share_extension_low_quality_video_message" = "%@ăăăé«ăćèłȘă§é俥ăăăăăŻăăăäœăćèłȘă§é俥ă";
+"room_access_space_chooser_other_spaces_section_info" = "ăăăăŻă%@ăźä»ăźçźĄçè
ăăăăčăăŒăčăŸăăŻă«ăŒă ă§ăă";
+"room_access_space_chooser_known_spaces_section" = "%@ăć«ăăăăȘăăç„ăŁăŠăăăčăăŒăč";
+
+// MARK: - Side menu
+
+"side_menu_reveal_action_accessibility_label" = "ć·Šăźăăă«";
+"leave_space_selection_all_rooms" = "ć
šăŠăźă«ăŒă ăéžæ";
+"spaces_add_room_missing_permission_message" = "ăăźăčăăŒăčă«ă«ăŒă ăèżœć ăăæš©éăăăăŸăăă";
+"spaces_creation_invite_by_username_message" = "ćŸăăæćŸ
ăăăăšăă§ăăŸăă";
+"spaces_creation_email_invites_message" = "ćŸăăæćŸ
ăăăăšăă§ăăŸăă";
+"spaces_creation_address_invalid_characters" = "%@\nă«ăŻäžæŁăȘæćăăăăŸă";
+"spaces_creation_address_already_exists" = "%@\năŻæąă«ććšăăŸă";
+"spaces_creation_empty_room_name_error" = "ć称ăćż
èŠă§ă";
+"space_settings_update_failed_message" = "ăčăăŒăčăźèšćźăźæŽæ°ă«ć€±æăăŸăăăćè©ŠèĄăăŸăăïŒ";
+"spaces_coming_soon_title" = "èżæ„ć
Źé";
+"spaces_explore_rooms_format" = "%@ăæąă";
+"spaces_create_subspace_title" = "ă”ăăčăăŒăčăäœæ";
+"space_beta_announce_title" = "ăčăăŒăčăŻèżæ„ć
Źé";
+"space_beta_announce_badge" = "ăăŒăżç";
+
+// MARK: - Spaces
+
+"space_feature_unavailable_title" = "ăčăăŒăčăŻăŸă ăăăŸăă";
+"room_invite_to_room_option_title" = "ăăźă«ăŒă ăźăż";
+"share_invite_link_room_text" = "ăăă«ăĄăŻă%@ ăăăăźă«ăŒă ă«ćć ăăŠăă ăăă";
+"share_invite_link_space_text" = "ăăă«ăĄăŻă%@ ăăăăźăčăăŒăčă«ćć ăăŠăă ăăă";
+
+// MARK: Key backup recover
+
+"key_backup_recover_title" = "ăĄăă»ăŒăžăäżè·";
+"secure_key_backup_setup_existing_backup_error_info" = "ăăăŻăè§Łé€ăăŠă»ăă„ăąăăăŻăąăăă§ćć©çšăăăăćé€ăăŠă»ăă„ăąăăăŻăąăăă§ăĄăă»ăŒăžăźæ°ăăăăăŻăąăăăäœæă";
+"room_access_settings_screen_restricted_message" = "ăčăăŒăčăèȘ°ă§ăæ€çŽąăăćć ă§ăăăăă«ăăă\nćŻŸè±ĄăźăčăăŒăčăçąșèȘăăŠăă ăăă";
+"room_details_promote_room_title" = "ă«ăŒă ăăăăąăŒă";
+"settings_about" = "æŠèŠ";
+"call_transfer_error_message" = "é話ăźè»ąéă«ć€±æăăŸăă";
+"call_transfer_contacts_all" = "ć
šăŠ";
+"call_transfer_contacts_recent" = "汄æŽ";
+
+// MARK: - Dial Pad
+"dialpad_title" = "ăă€ă€ă«ăăă";
+"create_room_type_restricted" = "ăčăăŒăčăźăĄăłăăŒ";
+"biometrics_cant_unlocked_alert_message_login" = "ćăă°ă€ăł";
+"biometrics_cant_unlocked_alert_message_x" = "ăăăŻăè§Łé€ăăă«ăŻă%@ăäœżçšăăăăćăă°ă€ăłăăŠ%@ăæćčă«ăăŠăă ăă";
+"biometrics_setup_subtitle" = "æéăçŻçŽ";
+"biometrics_desetup_disable_button_title_x" = "%@ăçĄćčă«ăă";
+"biometrics_desetup_title_x" = "%@ăçĄćčă«ăă";
+"pin_protection_kick_user_alert_message" = "ć€æ°ăźăšă©ăŒăçșçăăăăăăă°ăąăŠăăăŸăă";
+"pin_protection_not_allowed_pin" = "ă»ăă„ăȘăăŁăŒäžăźçç±ă§ăăăźPINăłăŒăăŻć©çšă§ăăŸăăăä»ăźPINăłăŒăăè©ŠăăŠăă ăă";
+"pin_protection_settings_change_pin" = "PINăłăŒăăć€æŽ";
+"pin_protection_settings_enabled_forced" = "PINăłăŒăăæćčă§ă";
+"pin_protection_settings_section_footer" = "PINăłăŒăăćèšćźăăă«ăŻăćăă°ă€ăłăăŠæ°ăăăłăŒăăäœæăăŠăă ăăă";
+"pin_protection_mismatch_too_many_times_error_message" = "PINăłăŒăăèŠăăŠăăȘăć ŽćăŻăPINăłăŒăăćżăăŸăăăăźăăżăłăăżăăăăŠăă ăăă";
+"pin_protection_mismatch_error_message" = "ăăäžćșŠăăçŽăăŠăă ăă";
+"pin_protection_mismatch_error_title" = "PINăłăŒăăäžèŽăăŸăă";
+"pin_protection_reset_alert_message" = "PINăłăŒăăćèšćźăăă«ăŻăćăă°ă€ăłăăŠæ°ăăăłăŒăăäœæăăŠăă ăă";
+"pin_protection_reset_alert_title" = "PINăłăŒăăćèšćź";
+"pin_protection_forgot_pin" = "PINăłăŒăăćżăăŸăă";
+"pin_protection_enter_pin" = "PINăłăŒăăć
„ćăăŠăă ăă";
+"pin_protection_confirm_pin_to_change" = "PINăłăŒăăć€æŽăăă«ăŻăPINăłăŒăăçąșèȘăăŠăă ăă";
+"pin_protection_confirm_pin_to_disable" = "PINăłăŒăăçĄćčă«ăăă«ăŻăPINăłăŒăăçąșèȘăăŠăă ăă";
+"major_update_information" = "ăąăăȘăźććăć€æŽăăŸăăïŒăąăăȘăŻææ°çă§ăăąă«ăŠăłăă«ăŻăă°ă€ăłæžă§ăă";
+
+// MARK: - Major update
+
+"major_update_title" = "RiotăŻ%@ă«ăȘăăŸăă";
+"secrets_reset_authentication_message" = "æżèȘăăă«ăŻMatrixăźăąă«ăŠăłăăźăăčăŻăŒăăć
„ćăăŠăă ăă";
+"secrets_setup_recovery_passphrase_summary_information" = "ă»ăă„ăȘăăŁăŒăăŹăŒășăèšéČăăŠăă ăăăă»ăă„ăȘăăŁăŒăăŹăŒășăäœżăăšăæć·ćăăăĄăă»ăŒăžăăăŒăżăźăăăŻăè§Łé€ăăăăšăă§ăăŸăă";
+"secrets_setup_recovery_key_storage_alert_message" = "â ć°ć·ăăŠćźć
šăȘć Žæă§äżçźĄ\nâ USBăăŒăăăăŻăąăăçšăă©ă€ăă«äżć\nâ ćäșșçšăźăŻă©ăŠăăčăăŹăŒăžă«ăłăăŒ";
+"secrets_setup_recovery_key_information" = "ă»ăă„ăȘăăŁăŒăăŒăŻćźć
šăȘć Žæă§äżçźĄăăŠăă ăăăă»ăă„ăȘăăŁăŒăăŒăäœżăăšăæć·ćăăăĄăă»ăŒăžăăăŒăżăźăăăŻăè§Łé€ăăăăšăă§ăăŸăă";
+"secrets_recovery_with_key_invalid_recovery_key_message" = "æŁăăă»ăă„ăȘăăŁăŒăăŒăć
„ćăăăăšăçąșèȘăăŠăă ăăă";
+"secrets_recovery_with_key_information_unlock_secure_backup_with_phrase" = "ç¶èĄăăă«ăŻă»ăă„ăȘăăŁăŒăăŹăŒășăć
„ćăăŠăă ăăă";
+"secrets_recovery_with_key_information_verify_device" = "ă»ăă„ăȘăăŁăŒăăŒăäœżçšăăŠăăăźç«Żæ«ăèȘ蚌ăăŠăă ăăă";
+"secrets_recovery_with_passphrase_invalid_passphrase_message" = "æŁăăă»ăă„ăȘăăŁăŒăăŹăŒășăć
„ćăăăăšăçąșèȘăăŠăă ăăă";
+"secrets_recovery_with_passphrase_recover_action" = "ă»ăă„ăȘăăŁăŒăăŹăŒășăäœżçš";
+"secrets_recovery_with_passphrase_information_verify_device" = "ă»ăă„ăȘăăŁăŒăăŹăŒășăäœżçšăăŠăăăźç«Żæ«ăèȘ蚌ăăŠăă ăăă";
+
+// MARK: - Secrets recovery
+
+"secrets_recovery_reset_action_part_1" = "ć
šăŠăźćŸ©æ§çšăźææź”ăćżăăăăçĄăăăŸăăăïŒ ";
+"user_verification_session_details_additional_information_untrusted_current_user" = "ăăźă»ăă·ă§ăłă«ă”ă€ăłă€ăłăăȘăăŁăć ŽćăăăȘăăźăąă«ăŠăłăăźćźć
šæ§ăæăȘăăăŠăăćŻèœæ§ăăăăŸăă";
+"device_verification_self_verify_wait_recover_secrets_checking_availability" = "ä»ăźèȘ蚌æčæłăçąșèȘăăŠăăŸăâŠ";
+"device_verification_self_verify_wait_additional_information" = "ăăăŻ%@ăšăăŻăăčçœČćă«ćŻŸćżăăä»ăźMatrixăźăŻă©ă€ăąăłăă§æ©èœăăŸăă";
+"device_verification_self_verify_wait_information" = "æć·ćăăăăĄăă»ăŒăžă«ăąăŻă»ăčăăă«ăŻăăăȘăăźä»ăźă»ăă·ă§ăłăăăăźă»ăă·ă§ăłăèȘ蚌ăăćż
èŠăăăăŸăă\n\nä»ăźç«Żæ«ă§ææ°ăź%@ăäœżçšăăŠăă ăăïŒ";
+"key_verification_self_verify_current_session_alert_message" = "ä»ăźăŠăŒă¶ăŒăŻäżĄé ŒăăȘăăăăăăŸăăă";
+"device_verification_start_use_legacy" = "äœăèĄšç€șăăăŸăăăïŒăŸă ć
šăŠăźăŻă©ă€ăąăłăăŻă€ăłăżă©ăŻăăŁăăȘèȘ蚌ăă”ăăŒăăăŠăăŸăăăăŹăŹă·ăŒèȘ蚌ăäœżçšăăŠăă ăăă";
+"device_verification_start_wait_partner" = "çžæăźæżè«ŸăćŸ
æ©ăăŠăăŸăâŠ";
+"key_verification_user_title" = "èȘ蚌";
+"key_verification_new_session_title" = "æ°ăăă»ăă·ă§ăłăèȘ蚌";
+"sign_out_key_backup_in_progress_alert_cancel_action" = "ćŸ
æ©ăăŸă";
+"sign_out_non_existing_key_backup_sign_out_confirmation_alert_title" = "æć·ćăăăăĄăă»ăŒăžă怱ăăŸă";
+"secure_key_backup_setup_existing_backup_error_title" = "ăĄăă»ăŒăžăźăăăŻăąăăăŻæąă«ććšăăŸă";
+"service_terms_modal_policy_checkbox_accessibility_hint" = "ăă§ăăŻăăŠ%@ăæżè«ŸăăŠăă ăă";
+"service_terms_modal_information_description_integration_manager" = "ă€ăłăă°ăŹăŒă·ă§ăłăăăŒăžăŁăŒăäœżăăšă珏äžè
ă«ăăæ©èœăèżœć ăăăăšăă§ăăŸăă";
+"service_terms_modal_information_description_identity_server" = "IDă”ăŒăăŒăäœżăăšăé»è©±çȘć·ăăĄăŒă«ăąăăŹăčăæ€çŽąăăŠăéŁç”Ąć
ăæąă«ăąă«ăŠăłăăăăŁăŠăăăă©ăăçąșèȘăăăăšăă§ăăŸăă";
+"service_terms_modal_description_integration_manager" = "ăăăăăăȘăăžăăŠăŁăžă§ăăăăčăăă«ăŒăăăŻăźäœżçšăèš±ćŻăăŸăă";
+"share_extension_low_quality_video_title" = "ćç»ăäœćèłȘă§é俥";
+"analytics_prompt_yes" = "ăŻăă性äžć€«ă§ă";
+/* Note: The placeholder is for the contents of analytics_prompt_terms_link_upgrade */
+"analytics_prompt_terms_upgrade" = "èŠçŽă%@ă§çąșèȘăăŠăă ăăăăăăăă§ăăïŒ";
+/* Note: The placeholder is for the contents of analytics_prompt_terms_link_new_user */
+"analytics_prompt_terms_new_user" = "èŠçŽăŻ%@ă§çąșèȘă§ăăŸăă";
+"analytics_prompt_message_upgrade" = "ăăȘăăŻä»„ćăć©çšç¶æłă«éąăăćżćăăŒăżăźć
±æă«ćæăăŸăăăè€æ°ăźç«Żæ«ă§ăźäœżçšăćæăăăăă«ăăăȘăăźć
šç«Żæ«ć
±éăźă©ăłăă ăȘèć„ćăçæăăŸăă";
+"spaces_creation_in_one_space" = "1ćăźăčăăŒăčă«";
+"spaces_creation_in_many_spaces" = "%@ćăźăčăăŒăčă«";
+"spaces_creation_in_spacename_plus_many" = "%@ăš%@ćăźăčăăŒăčă«";
+"spaces_creation_in_spacename_plus_one" = "%@ăš1ćăźăčăăŒăčă«";
+"spaces_creation_in_spacename" = "%@ă«";
+"event_formatter_group_call_incoming" = "%@ïŒ%@ă«ăŠïŒ";
+
+// MARK: Reactions
+
+"room_event_action_reaction_more" = "ä»%@件";
+"notice_event_redacted_by_you" = " ăăȘăă«ăă";
+"room_displayname_all_other_members_left" = "%@ïŒéćșæžïŒ";
+"user_session_item_details_last_activity" = "çŽèżăźăȘăłă©ă€ăłæ„æ %@";
+"version_check_modal_subtitle_deprecated" = "ç§ăăĄăŻ%@ăźé«éćăšæčćă«ćăç”ăă§ăăŸăăăæźćż”ăȘăăçŸćšăźiOSăźăăŒăžă§ăłăŻăăăăźäżźæŁă«ćŻŸćżăăŠăăȘăăăăă”ăăŒăăç”äșăăŸăăă\năȘăăŹăŒăăŁăłă°ă·ăčăă ăăąăăăăŒăăăŠă%@ăæ性éă«æŽ»çšăăŸăăăă";
+"version_check_modal_subtitle_supported" = "ç§ăăĄăŻ%@ăźé«éćăšæčćă«ćăç”ăă§ăăŸăăăæźćż”ăȘăăçŸćšăźiOSăźăăŒăžă§ăłăŻăăăăźäżźæŁă«ćŻŸćżăăŠăăȘăăăăèżæ„äžă«ă”ăăŒăć€ăšăȘăăŸăă\năȘăăŹăŒăăŁăłă°ă·ăčăă ăăąăăăăŒăăăŠă%@ăæ性éă«æŽ»çšăăŸăăăă";
+"key_verification_verified_this_session_information" = "äżè·ăăăăĄăă»ăŒăžăăăźç«Żæ«ă§èȘăăăšăă§ăăŸăăăŸăăä»ăźăŠăŒă¶ăŒăăăźç«Żæ«ăäżĄé Œăăăăšăă§ăăŸăă";
+"key_verification_verified_new_session_information" = "äżè·ăăăăĄăă»ăŒăžăæ°ăăç«Żæ«ă§èȘăăăšăă§ăăŸăăăŸăăä»ăźăŠăŒă¶ăŒăăăźç«Żæ«ăäżĄé Œăăăăšăă§ăăŸăă";
+"key_verification_verified_other_session_information" = "äżè·ăăăăĄăă»ăŒăžăä»ăźă»ăă·ă§ăłă§èȘăăăšăă§ăăŸăăăŸăăä»ăźăŠăŒă¶ăŒăăăźă»ăă·ă§ăłăäżĄé Œăăăăšăă§ăăŸăă";
+"call_consulting_with_user" = "%@ăšçžè«ăăŠăăŸă";
+"room_displayname_more_than_two_members" = "%@ăšăăźä»%@äșș";
+"notice_error_unformattable_event" = "** ăĄăă»ăŒăžăæç»ă§ăăŸăăăäžć
·ćăć ±ćăăŠăă ăă";
+"wysiwyg_composer_format_action_un_indent" = "ă€ăłăăłăăæžăă";
+"wysiwyg_composer_format_action_indent" = "ă€ăłăăłăăćąăă";
+"wysiwyg_composer_format_action_strikethrough" = "äžç·ă§èŁ
éŁŸ";
+"wysiwyg_composer_format_action_underline" = "æăĄæ¶ăç·ă§èŁ
éŁŸ";
+
+
+// MARK: - WYSIWYG Composer
+
+// Send Media Actions
+"wysiwyg_composer_start_action_media_picker" = "ăă©ăă©ă€ăă©ăȘăŒ";
+"user_session_details_device_ip_location" = "IPäœçœźæ
ć ±";
+"user_session_details_session_section_footer" = "ăżăăăăŠæŒăç¶ăăăšăăŒăżăăłăăŒăăŸăă";
+"device_name_mobile" = "%@ăąăă€ă«";
+"device_name_web" = "%@ăŠă§ă";
+// First item is client name and second item is session display name
+"user_session_name" = "%@ïŒ%@";
+"user_session_verification_unknown_additional_info" = "çŸćšăźă»ăă·ă§ăłăèȘ蚌ăăăšăăăźă»ăă·ă§ăłăźèȘ蚌ăźç¶æ
ăçąșèȘă§ăăŸăă";
+"user_sessions_overview_link_device" = "ç«Żæ«ăăȘăłăŻ";
+"location_sharing_live_timer_incoming" = "%@ăŸă§ć
±æïŒă©ă€ăïŒ";
+"location_sharing_live_list_item_last_update_invalid" = "æćŸăźæŽæ°ăŻäžæă§ă";
+"location_sharing_live_list_item_last_update" = "%@ćă«æŽæ°æž";
+"location_sharing_live_list_item_sharing_expired" = "ć
±æăźæéăćăăŸăă";
+"location_sharing_map_credits_title" = "© Copyright";
+"location_sharing_allow_background_location_message" = "äœçœźæ
ć ±ïŒă©ă€ăïŒăć
±æăăăć ŽćăElementăŻăăăŻă°ă©ăŠăłăă§äœçœźæ
ć ±ă«ăąăŻă»ăčă§ăăćż
èŠăăăăŸăăăąăŻă»ăčăèš±ćŻăăă«ăŻăăèšćźăăźăäœçœźæ
ć ±ăă«ăăăćžžă«ăăăżăăăăŠăă ăăă";
+"location_sharing_invalid_authorization_error_title" = "%@ă«ăŻäœçœźæ
ć ±ă«ăąăŻă»ăčăăæš©éăăăăŸăăăăèšćźăăźăäœçœźæ
ć ±ăăăăąăŻă»ăčăæćčă«ă§ăăŸăă";
+"location_sharing_loading_map_error_title" = "%@ăŻć°ćłăèȘăżèŸŒăăŸăăă§ăăăćŸă§ăăäžćșŠăăçŽăăŠăă ăăă";
+"poll_history_no_past_poll_period_text" = "éć»%@æ„ă«ćźæœăăăăąăłă±ăŒăăŻăăăŸăăăăăă«ăąăłă±ăŒăăèȘăżèŸŒăżăćăźæăźăąăłă±ăŒăăèĄšç€ș";
+"poll_history_no_active_poll_period_text" = "éć»%@æ„ă«ćźæœäžăźăąăłă±ăŒăăŻăăăŸăăăăăă«ăąăłă±ăŒăăèȘăżèŸŒăżăćăźæăźăąăłă±ăŒăăèĄšç€ș";
+"poll_history_detail_view_in_timeline" = "ăąăłă±ăŒăăăżă€ă ă©ă€ăłă«èĄšç€ș";
+"space_invite_nav_title" = "ăčăăŒăčă«æćŸ
";
+
+// MARK: - Space Selector
+
+"space_selector_title" = "ăčăăŒăč";
+"room_invites_empty_view_information" = "ăăă«æćŸ
ăèĄšç€șăăăŸăă";
+"voice_message_stop_locked_mode_recording" = "éČéłăăżăăăăŠćæąăŸăăŻćç";
+"leave_space_and_more_rooms" = "ăčăăŒăčăš%@ćăźă«ăŒă ăăéćș";
+"leave_space_and_one_room" = "ăčăăŒăčăš1ćăźă«ăŒă ăăéćș";
+"spaces_creation_post_process_inviting_users" = "%@äșșăźăŠăŒă¶ăŒăæćŸ
ăăŠăăŸă";
+"spaces_creation_post_process_adding_rooms" = "%@ćăźă«ăŒă ăèżœć ăăŠăăŸă";
+"spaces_creation_new_rooms_message" = "ăăăăă«ă«ăŒă ăäœăăŸăă";
+"spaces_creation_new_rooms_title" = "ă©ăźăăăȘè°è«ăèĄăăŸăăïŒ";
+"spaces_subspace_creation_visibility_message" = "äœæăăăčăăŒăčăŻ%@ă«èżœć ăăăŸăă";
+"spaces_feature_not_available" = "ăăźæ©èœăŻăŸă ć©çšă§ăăŸăăăćœéąăŻăăłăłăă„ăŒăżăŒă§%@ă«ăăăăăèĄăăăšăă§ăăŸăă";
+"spaces_no_member_found_detail" = "%@ăźăĄăłăăŒä»„ć€ăźäșșăæąăăŠăăŸăăïŒćœéąăŻăăŠă§ăçăŸăăŻăăčăŻăăăçă§æćŸ
ă§ăăŸăă";
+"spaces_coming_soon_detail" = "ăăźæ©èœăŻăŸă ćźèŁ
ăăăŠăăŸăăăćœéąăŻăăłăłăă„ăŒăżăŒă§%@ă«ăăăăăèĄăăăšăă§ăăŸăă";
+"spaces_invites_coming_soon_title" = "æćŸ
ăŻèżæ„ć
Źé";
+"spaces_add_rooms_coming_soon_title" = "ă«ăŒă ăźèżœć ăŻèżæ„ć
Źé";
+"spaces_no_room_found_detail" = "éć
Źéă§æćŸ
ăćż
èŠăȘăăźăŻèĄšç€șăăăŠăăŸăăă";
+"leave_space_message_admin_warning" = "ăăȘăăŻăăźăčăăŒăčăźçźĄçè
ă§ăăéćșăăćă«ă知çè
ăźæš©éăć„ăźăĄăłăăŒă«ç§»èČăăŠăă ăăă";
+"leave_space_message" = "%@ăăéćșăăŠăăăăă§ăăïŒăăźăčăăŒăčăźć
šăŠăźă«ăŒă ăšăčăăŒăčăăăéćșăăŸăăïŒ";
+"spaces_add_subspace_title" = "%@ć
ă«ăčăăŒăčăäœæ";
+"space_feature_unavailable_information" = "ăčăăŒăčăŻăă«ăŒă ăéŁç”Ąć
ăăŸăšăăæ°ăăæčæłă§ăă\n\nèżæ„ć
Źéäșćźă§ăăć„ăźăă©ăăăă©ăŒă ă§ăčăăŒăčă«ćć ăăăšăăăă§ćć ăăă©ăźă«ăŒă ă«ăăąăŻă»ăčăăăăšăă§ăăŸăă";
+"space_beta_announce_information" = "ăčăăŒăčăŻăă«ăŒă ăéŁç”Ąć
ăăŸăšăăæ°ăăæčæłă§ăăiOSçă§ăŻăŸă äœżçšă§ăăŸăăăăăŠă§ăçăšăăčăŻăăăçă§ăŻäœżçšă§ăăŸăă";
+"space_feature_unavailable_subtitle" = "ăčăăŒăčăŻiOSçă§ăŻăŸă äœżçšă§ăăŸăăăăăŠă§ăçăšăăčăŻăăăçă§ăŻäœżçšă§ăăŸă";
+"space_beta_announce_subtitle" = "ăłăă„ăăăŁăŒæ©èœăźæ°ăăăăŒăžă§ăł";
+"space_invite_not_enough_permission" = "ăăźăčăăŒăčă«ăŠăŒă¶ăŒăæćŸ
ăăæš©éăăăăŸăă";
+"room_invite_not_enough_permission" = "ăăźă«ăŒă ă«ăŠăŒă¶ăŒăæćŸ
ăăæš©éăăăăŸăă";
+"room_invite_to_room_option_detail" = "%@ăźăĄăłăăŒă«ăŻăȘăăŸăăă";
+"room_invite_to_space_option_detail" = "%@ăæąăăăšăŻă§ăăŸăăă%@ăźăĄăłăăŒă«ăŻăȘăăŸăăă";
+
+// MARK: - Room invite
+
+"room_invite_to_space_option_title" = "%@ă«";
+"event_formatter_call_missed_video" = "äžćšç俥ïŒăăăȘïŒ";
+"event_formatter_call_missed_voice" = "äžćšç俥ïŒéłćŁ°ïŒ";
+"settings_push_rules_error" = "éç„ăźèšćźăăąăăăăŒăăăéă«ăšă©ăŒăçșçăăŸăăăăăäžćșŠăȘăă·ă§ăłăćăæżăăŠăżăŠăă ăăă";
+"settings_presence" = "ăăŹăŒăłăčïŒăčăăŒăżăčèĄšç€șïŒ";
diff --git a/Riot/Assets/nl.lproj/Vector.strings b/Riot/Assets/nl.lproj/Vector.strings
index ab294231c8..a814c281b5 100644
--- a/Riot/Assets/nl.lproj/Vector.strings
+++ b/Riot/Assets/nl.lproj/Vector.strings
@@ -2605,14 +2605,6 @@
// Mark: - Room invites
"room_invites_empty_view_title" = "Niets nieuws.";
-"all_chats_onboarding_try_it" = "Probeer het uit";
-"all_chats_onboarding_title" = "Wat is nieuw";
-"all_chats_onboarding_page_message3" = "Tik op je profiel om ons te laten weten wat je ervan vindt.";
-"all_chats_onboarding_page_title3" = "Geef feedback";
-"all_chats_onboarding_page_message2" = "Krijg sneller en gemakkelijker toegang tot je Spaces (linksonder) dan ooit tevoren.";
-"all_chats_onboarding_page_title2" = "Toegang tot spaces";
-"all_chats_onboarding_page_message1" = "Om je Element te vereenvoudigen, zijn tabbladen nu optioneel. Beheer ze met behulp van het menu rechtsboven.";
-"all_chats_onboarding_page_title1" = "Welkom bij de nieuwe weergave!";
"all_chats_edit_menu_space_settings" = "Space instellingen";
"all_chats_edit_menu_leave_space" = "Verlaat %@";
"all_chats_user_menu_settings" = "Gebruikersinstellingen";
diff --git a/Riot/Assets/pl.lproj/Vector.strings b/Riot/Assets/pl.lproj/Vector.strings
index 8532c4b4de..9106d3eea1 100644
--- a/Riot/Assets/pl.lproj/Vector.strings
+++ b/Riot/Assets/pl.lproj/Vector.strings
@@ -2533,13 +2533,6 @@
// Mark: - Room invites
"room_invites_empty_view_title" = "Nic nowego.";
-"all_chats_onboarding_try_it" = "WyprĂłbuj";
-"all_chats_onboarding_title" = "Co nowego";
-"all_chats_onboarding_page_message3" = "Dotknij swojego profilu by poinformowaÄ nas, co o tym sÄ
dzisz.";
-"all_chats_onboarding_page_title3" = "PrzeĆlij opiniÄ";
-"all_chats_onboarding_page_message2" = "Uzyskaj dostÄp do twoich przestrzeni (lewy dolny rĂłg) szybciej i proĆciej niĆŒÂ kiedykolwiek.";
-"all_chats_onboarding_page_message1" = "Aby uproĆciÄ korzystanie z Element, karty sÄ
 teraz opcjonalne. MoĆŒesz nimi zarzÄ
dzaÄÂ w menu w prawym gĂłrnym rogu.";
-"all_chats_onboarding_page_title1" = "Witaj w nowym widoku!";
"all_chats_edit_menu_space_settings" = "Ustawienia przestrzeni";
"all_chats_edit_menu_leave_space" = "OpuĆÄ %@";
"all_chats_user_menu_settings" = "Ustawienia uĆŒytkownika";
diff --git a/Riot/Assets/pt_BR.lproj/Vector.strings b/Riot/Assets/pt_BR.lproj/Vector.strings
index 582951c39b..0d9dbe5d9a 100644
--- a/Riot/Assets/pt_BR.lproj/Vector.strings
+++ b/Riot/Assets/pt_BR.lproj/Vector.strings
@@ -2446,14 +2446,6 @@
// Mark: - Room invites
"room_invites_empty_view_title" = "Nada novo.";
-"all_chats_onboarding_try_it" = "Experimentar";
-"all_chats_onboarding_title" = "O que tem de novo";
-"all_chats_onboarding_page_message3" = "Toque em seu perfil para nos deixar sabendo do que vocĂȘ acha.";
-"all_chats_onboarding_page_title3" = "DĂȘ Feedback";
-"all_chats_onboarding_page_message2" = "Acesse seus Espaços (esquerda fundo) mais råpido e fåcil que jamais antes.";
-"all_chats_onboarding_page_title2" = "Acesse Espaços";
-"all_chats_onboarding_page_message1" = "Para simplificar seu Element, abas sĂŁo agora opcionais. Gerencie-as usando o menu direito topo.";
-"all_chats_onboarding_page_title1" = "Boas vindas a uma nova visĂŁo!";
"all_chats_nothing_found_placeholder_message" = "Tente ajustar sua pesquisa.";
"all_chats_nothing_found_placeholder_title" = "Nada encontrado.";
"all_chats_empty_unreads_placeholder_message" = "Isto Ă© onde suas mensagens nĂŁo-lidas vĂŁo aparecer, quando vocĂȘ tiver algumas.";
diff --git a/Riot/Assets/sk.lproj/Vector.strings b/Riot/Assets/sk.lproj/Vector.strings
index 83b316cf8d..0aace81cce 100644
--- a/Riot/Assets/sk.lproj/Vector.strings
+++ b/Riot/Assets/sk.lproj/Vector.strings
@@ -2668,14 +2668,6 @@
// Mark: - Room invites
"room_invites_empty_view_title" = "NiÄ novĂ©.";
-"all_chats_onboarding_try_it" = "VyskĂșĆĄajte si to";
-"all_chats_onboarding_title" = "Äo je novĂ©";
-"all_chats_onboarding_page_message3" = "Ć€uknite na svoj profil a dajte nĂĄm vedieĆ„, Äo si myslĂte.";
-"all_chats_onboarding_page_title3" = "Poskytnite spĂ€tnĂș vĂ€zbu";
-"all_chats_onboarding_page_title2" = "PrĂstup k priestorom";
-"all_chats_onboarding_page_message2" = "ZĂskajte prĂstup k svojim priestorom (vÄŸavo dole) rĂœchlejĆĄie a jednoduchĆĄie ako kedykoÄŸvek predtĂœm.";
-"all_chats_onboarding_page_message1" = "Pre zjednoduĆĄenie vaĆĄej aplikĂĄcie Element, sĂș teraz karty voliteÄŸnĂ©. Spravujte ich pomocou ponuky vpravo hore.";
-"all_chats_onboarding_page_title1" = "Vitajte v novom zobrazenĂ!";
"all_chats_nothing_found_placeholder_message" = "SkĂșste upraviĆ„ svoje hÄŸadanie.";
"all_chats_nothing_found_placeholder_title" = "NiÄ sa nenaĆĄlo.";
"all_chats_empty_unreads_placeholder_message" = "Tu sa zobrazia nepreÄĂtanĂ© sprĂĄvy, ak nejakĂ© mĂĄte.";
@@ -2917,6 +2909,18 @@
// MARK: - Launch loading
"launch_loading_migrating_data" = "MigrĂĄcia Ășdajov\n%@ %%";
-"settings_labs_disable_crypto_sdk" = "Crypto SDK je povolenĂ©. Ak to chcete vypnĂșĆ„, preinĆĄtalujte prosĂm aplikĂĄciu";
-"settings_labs_confirm_crypto_sdk" = "TĂșto akciu nemoĆŸno vrĂĄtiĆ„ spÀƄ";
-"settings_labs_enable_crypto_sdk" = "ZapnĂșĆ„ novĂ© Crypto SDK vyuĆŸĂvajĂșce Rust";
+"settings_labs_disable_crypto_sdk" = "Rust end-to-end ĆĄifrovanie (odhlĂĄste sa, aby ste ho vypli)";
+"settings_labs_confirm_crypto_sdk" = "UpozorĆujeme, ĆŸe tĂĄto funkcia je stĂĄle v experimentĂĄlnej fĂĄze, preto nemusĂ fungovaĆ„ podÄŸa oÄakĂĄvanĂ a mĂŽĆŸe maĆ„ potenciĂĄlne nezamĂœĆĄÄŸanĂ© dĂŽsledky. Ak chcete funkciu vrĂĄtiĆ„ spÀƄ, jednoducho sa odhlĂĄste a znova prihlĂĄste. PouĆŸĂvajte ju podÄŸa vlastnĂ©ho uvĂĄĆŸenia a s opatrnosĆ„ou.";
+"settings_labs_enable_crypto_sdk" = "Rust end-to-end ĆĄifrovanie";
+"poll_history_load_more" = "NaÄĂtaĆ„ ÄalĆĄie ankety";
+"poll_history_no_past_poll_period_text" = "Za poslednĂœch %@ dnĂ nie sĂș aktĂvne ĆŸiadne ankety. NaÄĂtanĂm ÄalĆĄĂch ankiet zobrazĂte ankety za predchĂĄdzajĂșce mesiace";
+"poll_history_no_active_poll_period_text" = "Za poslednĂœch %@ dnĂ nie sĂș aktĂvne ĆŸiadne ankety. NaÄĂtanĂm ÄalĆĄĂch ankiet zobrazĂte ankety za predchĂĄdzajĂșce mesiace";
+"poll_history_loading_text" = "Zobrazenie ankiet";
+"poll_history_fetching_error" = "Chyba pri naÄĂtavanĂ ankiet.";
+"voice_broadcast_playback_unable_to_decrypt" = "Toto hlasové vysielanie sa nedå deƥifrovaƄ.";
+"home_context_menu_mark_as_unread" = "OznaÄiĆ„ ako nepreÄĂtanĂ©";
+"key_backup_recover_from_private_key_progress" = "%@%% DokonÄenĂ©";
+"wysiwyg_composer_format_action_indent" = "ZvĂ€ÄĆĄenie odsadenia";
+"wysiwyg_composer_format_action_un_indent" = "ZmenĆĄenie odsadenia";
+"poll_history_detail_view_in_timeline" = "ZobraziĆ„ anketu na Äasovej osi";
+"settings_push_rules_error" = "Pri aktualizĂĄcii vaĆĄich predvolieb oznĂĄmenĂ doĆĄlo k chybe. SkĂșste prosĂm prepnĂșĆ„ moĆŸnosĆ„ znova.";
diff --git a/Riot/Assets/sq.lproj/Localizable.strings b/Riot/Assets/sq.lproj/Localizable.strings
index a49dd96602..8036083e0c 100644
--- a/Riot/Assets/sq.lproj/Localizable.strings
+++ b/Riot/Assets/sq.lproj/Localizable.strings
@@ -118,3 +118,6 @@
/* New file message from a specific person, not referencing a room. */
"LOCATION_FROM_USER" = "%@ tregoi vendndodhjen e vet";
+
+/* New voice broadcast from a specific person, not referencing a room. */
+"VOICE_BROADCAST_FROM_USER" = "%@ nisi një transmetim zanor";
diff --git a/Riot/Assets/sq.lproj/Vector.strings b/Riot/Assets/sq.lproj/Vector.strings
index b2a297d078..4e6a4269eb 100644
--- a/Riot/Assets/sq.lproj/Vector.strings
+++ b/Riot/Assets/sq.lproj/Vector.strings
@@ -2417,7 +2417,6 @@
// MARK: Authentication
"authentication_registration_title" = "Krijoni llogarinë tuaj";
-"all_chats_onboarding_page_message3" = "Prekni profilin tuaj qĂ« tĂ« na bĂ«ni tĂ« ditur se çâmendoni.";
"all_chats_edit_layout_add_section_message" = "Fiksoni ndarje te kreu, për hyrje të lehtë në ta";
"room_event_encryption_info_key_authenticity_not_guaranteed" = "Sâmund tĂ« garantohet mirĂ«filltĂ«sia e kĂ«tij mesazhi tĂ« fshehtĂ«zuar nĂ« kĂ«tĂ« pajisje.";
"deselect_all" = "Shpërzgjidhi Krejt";
@@ -2534,13 +2533,6 @@
// Mark: - Room invites
"room_invites_empty_view_title" = "Sâka gjĂ« tĂ« re.";
-"all_chats_onboarding_try_it" = "Provojeni";
-"all_chats_onboarding_title" = "Ăâka tĂ« re";
-"all_chats_onboarding_page_title3" = "Jepni PĂ«rshtypje";
-"all_chats_onboarding_page_message2" = "Hyni në Hapësirat tuaja (poshtë djathtas) më shpejt dhe më kollaj se kurrë më parë.";
-"all_chats_onboarding_page_title2" = "Hyni Në Hapësira";
-"all_chats_onboarding_page_message1" = "Që të thjeshtohet Element-i juaj, skedat tanimë janë opsionale. Administrojini duke përdorur menunë djathtas në krye.";
-"all_chats_onboarding_page_title1" = "Mirë se vini te një pamje e re!";
"all_chats_edit_menu_space_settings" = "Rregullime hapësire";
"all_chats_edit_menu_leave_space" = "Braktise %@";
"all_chats_user_menu_settings" = "Rregullime përdoruesi";
@@ -2687,3 +2679,35 @@
"voice_broadcast_voip_cannot_start_title" = "Sâniset dot njĂ« thirrje";
"voice_message_broadcast_in_progress_message" = "Sâmund tĂ« niset mesazh zanor, ngaqĂ« aktualisht po regjistroni njĂ« transmetim tĂ« drejtpĂ«rdrejtĂ«. Ju lutemi, pĂ«rfundoni transmetimin e drejtpĂ«rdrejtĂ«, qĂ« tĂ« mund tĂ« nisni regjistrimin e njĂ« mesazhi zanor";
"voice_message_broadcast_in_progress_title" = "Sâniset dot mesazh zanor";
+"wysiwyg_composer_format_action_quote" = "Shfaq/fshih citim";
+"wysiwyg_composer_format_action_code_block" = "Shfaq/fshih bllok kodi";
+"wysiwyg_composer_format_action_ordered_list" = "Shfaq/fshih listë të numërtuar";
+"wysiwyg_composer_format_action_unordered_list" = "Shfaq/fshih listë me toptha";
+"poll_timeline_reply_ended_poll" = "Pyetësor i përfunduar";
+"poll_history_fetching_error" = "Gabim në sjelle pyetësorë.";
+"poll_history_load_more" = "Ngarko më tepër pyetësorë";
+"poll_history_no_past_poll_period_text" = "Sâka pyetĂ«sorĂ« tĂ« kaluar pĂ«r %@ ditĂ«t e shkuara. QĂ« tĂ« shihni pyetĂ«sorĂ« nga muajt e kaluar, ngarkoni mĂ« tepĂ«r pyetĂ«sorĂ«";
+"poll_history_no_active_poll_period_text" = "Sâka pyetĂ«sorĂ« aktivĂ« pĂ«r %@ ditĂ«t e shkuara. QĂ« tĂ« shihni pyetĂ«sorĂ« nga muajt e kaluar, ngarkoni mĂ« tepĂ«r pyetĂ«sorĂ«";
+"poll_history_loading_text" = "Shfaqje pyetësorësh";
+
+// MARK: - Polls history
+
+"poll_history_title" = "Historik pyetësorësh";
+"voice_broadcast_playback_unable_to_decrypt" = "Sâarrihet tĂ« shfshehtĂ«zohet ky transmetim zanor.";
+"voice_broadcast_recorder_connection_error" = "Gabim lidhjeje - Incizimi u ndal";
+"voice_broadcast_connection_error_message" = "Mjerisht, sâjemi nĂ« gjendje tĂ« nisim njĂ« incizim mu tani. Ju lutemi, riprovoni mĂ« vonĂ«.";
+"voice_broadcast_connection_error_title" = "Gabim lidhjeje";
+"home_context_menu_mark_as_unread" = "Vëri shenjë si i palexuar";
+
+// MARK: - Launch loading
+
+"launch_loading_migrating_data" = "Po migrohen të dhëna\n%@ %%";
+"key_backup_recover_from_private_key_progress" = "Plotësuar %@%%";
+"room_details_polls" = "Historik pyetësorësh";
+"settings_labs_disable_crypto_sdk" = "Fshehtëzim skaj-më-skaj bazuar në Rust (që ta çaktivizoni, dilni)";
+"settings_labs_confirm_crypto_sdk" = "Ju lutemi, kini parasysh se kjo veçori është ende në fazë eksperimentale, mund të mos funksionojë siç pritet dhe mundet, në potencial, të ketë pasojë të paparashikuara. Që ta prapaktheni këtë veçori, thjesht dilni nga llogaria dhe rihyni. Përdoreni me përgjegjësinë tuaj dhe me kujdes.";
+"settings_labs_enable_crypto_sdk" = "Fshehtëzim skaj-më-skaj bazuar në Rust";
+"settings_push_rules_error" = "Ndodhi një gabim, kur përditësoheshin parapëlqimet tuaja për njoftime. JU lutemi, provoni të aktivizoni mundësi tuaj sërish.";
+"wysiwyg_composer_format_action_un_indent" = "Zvogëlo shmangie kryeradhë";
+"wysiwyg_composer_format_action_indent" = "Rrit shmangie kryeradhe";
+"poll_history_detail_view_in_timeline" = "Shiheni pyetësorin në rrjedhë kohore";
diff --git a/Riot/Assets/sv.lproj/Vector.strings b/Riot/Assets/sv.lproj/Vector.strings
index 872645f667..a8fa6cf8b1 100644
--- a/Riot/Assets/sv.lproj/Vector.strings
+++ b/Riot/Assets/sv.lproj/Vector.strings
@@ -2472,3 +2472,199 @@
"authentication_choose_password_not_verified_title" = "E-post inte verifierad";
"authentication_login_with_qr" = "Logga in med QR-kod";
"invite_to" = "Bjud in till %@";
+"room_event_encryption_info_key_authenticity_not_guaranteed" = "Ăktheten för det hĂ€r krypterade meddelandet kan inte garanteras pĂ„ den hĂ€r enheten.";
+"notice_voice_broadcast_ended_by_you" = "Du avslutade en röstsÀndning.";
+"notice_voice_broadcast_ended" = "%@ avslutade en röstsÀndning.";
+"notice_voice_broadcast_live" = "DirektsÀndning";
+"deselect_all" = "VĂ€lj bort alla";
+"wysiwyg_composer_link_action_edit_title" = "Redigera lÀnk";
+"wysiwyg_composer_link_action_create_title" = "Skapa en lÀnk";
+"wysiwyg_composer_link_action_link" = "LĂ€nk";
+
+
+
+// Links
+"wysiwyg_composer_link_action_text" = "Text";
+"wysiwyg_composer_format_action_quote" = "VĂ€xla citat";
+"wysiwyg_composer_format_action_code_block" = "VĂ€xla kodblock";
+"wysiwyg_composer_format_action_ordered_list" = "VĂ€xla numrerad lista";
+"wysiwyg_composer_format_action_unordered_list" = "VĂ€xla punktlista";
+"wysiwyg_composer_format_action_inline_code" = "TillÀmpa inline-kodstil";
+"wysiwyg_composer_format_action_link" = "TillÀmpa lÀnkformat";
+"wysiwyg_composer_format_action_strikethrough" = "TillÀmpa understruken stil";
+"wysiwyg_composer_format_action_underline" = "TillÀmpa genomstruken stil";
+"wysiwyg_composer_format_action_italic" = "TillÀmpa kursiv stil";
+
+// Formatting Actions
+"wysiwyg_composer_format_action_bold" = "TillÀmpa fetstil";
+"wysiwyg_composer_start_action_voice_broadcast" = "RöstsÀndning";
+"wysiwyg_composer_start_action_text_formatting" = "Textformatering";
+"wysiwyg_composer_start_action_camera" = "Kamera";
+"wysiwyg_composer_start_action_location" = "Plats";
+"wysiwyg_composer_start_action_polls" = "Omröstningar";
+"wysiwyg_composer_start_action_attachments" = "Bilagor";
+"wysiwyg_composer_start_action_stickers" = "Dekaler";
+
+
+// MARK: - WYSIWYG Composer
+
+// Send Media Actions
+"wysiwyg_composer_start_action_media_picker" = "Fotobibliotek";
+"user_session_overview_session_details_button_title" = "Sessionsdetaljer";
+"user_session_overview_session_title" = "Session";
+"user_session_overview_current_session_title" = "Nuvarande session";
+"user_session_details_application_url" = "URL";
+"user_session_details_application_version" = "Version";
+"user_session_details_application_name" = "Namn";
+"user_session_details_device_os" = "Operativsystem";
+"user_session_details_device_browser" = "WebblÀsare";
+"user_session_details_device_model" = "Modell";
+"user_session_details_device_ip_location" = "IP-plats";
+"user_session_details_device_ip_address" = "IP-adress";
+"user_session_details_last_activity" = "Senaste aktivitet";
+"user_session_details_session_section_footer" = "Kopiera data genom att trycka pÄ den och hÄlla nere.";
+"user_session_details_session_id" = "Sessions-ID";
+"user_session_details_session_name" = "Sessionsnamn";
+"user_session_details_device_section_header" = "Enhet";
+"user_session_details_application_section_header" = "Applikation";
+"user_session_details_session_section_header" = "Session";
+"user_session_details_title" = "Sessionsdetaljer";
+"device_type_name_unknown" = "OkÀnd";
+"device_type_name_mobile" = "Mobil";
+"device_type_name_web" = "Webb";
+"device_type_name_desktop" = "Skrivbord";
+"device_name_unknown" = "OkÀnd klient";
+"device_name_mobile" = "%@ Mobil";
+"device_name_web" = "%@ Webb";
+"device_name_desktop" = "%@ Skrivbord";
+"user_inactive_session_item_with_date" = "Inaktiv i 90+ dagar (%@)";
+"user_inactive_session_item" = "Inaktiv i 90+ dagar";
+"user_session_item_details_last_activity" = "Senast aktiv %@";
+
+/* %1$@ will be the verification state and %2$@ will be user_session_item_details_verification_unknown or user_other_session_current_session_details */
+"user_session_item_details" = "%1$@ · %2$@";
+// First item is client name and second item is session display name
+"user_session_name" = "%@: %@";
+"user_other_session_menu_sign_out_sessions" = "Logga ut ur %@ sessioner";
+"user_other_session_menu_select_sessions" = "VĂ€lj sessioner";
+"user_other_session_selected_count" = "%@ valda";
+"user_other_session_clear_filter" = "Rensa filter";
+"user_other_session_no_unverified_sessions" = "Inga overifierade sessioner hittade.";
+"user_other_session_no_verified_sessions" = "Inga verifierade sessioner hittade.";
+"user_other_session_no_inactive_sessions" = "Inga inaktiva sessioner hittade.";
+"user_other_session_filter_menu_inactive" = "Inaktiva";
+"user_other_session_filter_menu_unverified" = "Overifierade";
+"user_other_session_filter_menu_verified" = "Verifierade";
+"user_other_session_filter_menu_all" = "Alla sessioner";
+"user_other_session_filter" = "Filtrera";
+"user_other_session_verified_sessions_header_subtitle" = "För bÀst sÀkerhet, logga ut ur alla sessioner du inte kÀnner igen eller anvÀnder lÀngre.";
+"user_other_session_current_session_details" = "Din nuvarande session";
+"user_other_session_unverified_sessions_header_subtitle" = "Verifiera dina sessioner för förbÀttrade sÀkra meddelanden eller logga ut ur de du inte kÀnner igen eller anvÀnder lÀngre.";
+"user_other_session_security_recommendation_title" = "Andra sessioner";
+"user_session_rename_session_description" = "Andra anvÀndare i direktmeddelanden och rum du gÄr med i kan se den fulla listan över dina sessioner.\n\nDetta gör att de kan lita pÄ att de verkligen pratar med dig, men det betyder ocksÄ att de kan se sessionsnamnet du anger hÀr.";
+"user_session_rename_session_title" = "Döper om sessioner";
+"user_session_inactive_session_description" = "Inaktiva sessioner Àr sessioner du inte har anvÀnt pÄ ett tag, men de fortsÀtter att ta emot krypteringsnycklar.\n\nBorttagning av inaktiva sessioner förbÀttrar sÀkerhet och prestanda, och gör det enklare för dig att identifiera om en ny session ser misstÀnkt ut.";
+"user_session_inactive_session_title" = "Inaktiva sessioner";
+"user_session_permanently_unverified_session_description" = "Sessionen stöder inte kryptering, sÄ den kan inte verifieras.\n\nDu kommer inte kunna delta i rum dÀr kryptering Àr aktiverat nÀr du anvÀnder den hÀr sessionen.\n\nFör bÀst sÀkerhet sÄ rekommenderas det att anvÀnda Matrixklienter som stöder kryptering.";
+"user_session_unverified_session_description" = "Overifierade sessioner Àr sessioner som har loggat in med dina uppgifter men som inte har korsverifierats.\n\nDu bör speciellt försÀkra att du kÀnner igen dessa sessioner eftersom de kan representera obehörig anvÀndning av ditt konto.";
+"user_session_unverified_session_title" = "Overifierad session";
+"user_session_verified_session_description" = "Verifierade sessioner Àr alla stÀllen dÀr du anvÀnder Element efter att ha angett din lösenfras eller bekrÀftat din identitet med en annan verifierad session.\n\nDet betyder att du har alla nycklar som krÀvs för att lÄsa upp krypterade meddelanden och bekrÀfta för andra anvÀndare att du litar pÄ den hÀr sessionen.";
+"user_session_verified_session_title" = "Verifierade sessioner";
+"user_session_got_it" = "FörstÄtt";
+"user_session_push_notifications_message" = "NÀr aktiverad sÄ tar den hÀr sessionen emot pushnotiser.";
+"user_session_push_notifications" = "Pushnotiser";
+"user_other_session_verified_additional_info" = "Den hÀr sessioner Àr redo för sÀkra meddelanden.";
+"user_other_session_permanently_unverified_additional_info" = "Den hÀr sessionen stöder inte kryptering och kan dÀrför inte verifieras.";
+"user_other_session_unverified_additional_info" = "Verifiera eller logga ut ur den hÀr sessionen för bÀst sÀkerhet och pÄlitlighet.";
+"user_session_verification_unknown_additional_info" = "Verifiera din nuvarande session för att avslöja den hÀr sessionens verifieringsstatus.";
+"user_session_unverified_additional_info" = "Verifiera din nuvarande session för förbÀttrade sÀkra meddelanden.";
+"user_session_verified_additional_info" = "Din nuvarande session Àr redo för sÀkra meddelanden.";
+"user_session_learn_more" = "LĂ€s mer";
+"user_session_view_details" = "Visa detaljer";
+"user_session_verify_action" = "Verifiera session";
+"user_session_verification_unknown_short" = "OkÀnd";
+"user_session_unverified_short" = "Overifierad";
+"user_session_verified_short" = "Verifierad";
+"user_session_verification_unknown" = "OkÀnd verifieringsstatus";
+"user_session_unverified" = "Overifierad session";
+"user_session_verified" = "Verifierad session";
+"user_sessions_view_all_action" = "Visa alla (%d)";
+"user_sessions_overview_link_device" = "LĂ€nka en enhet";
+"user_sessions_overview_current_session_section_title" = "Nuvarande session";
+"user_sessions_hide_location_info" = "Dölj IP-adress";
+"user_sessions_show_location_info" = "Visa IP-adress";
+"user_sessions_overview_other_sessions_section_info" = "För bÀst sÀkerhet, verifiera dina sessioner och logga ut ur alla sessioner du inte kÀnner igen eller anvÀnder lÀngre.";
+"user_sessions_overview_other_sessions_section_title" = "Andra sessioner";
+"user_sessions_overview_security_recommendations_inactive_info" = "ĂvervĂ€g att logga ut ur gamla sessioner (90 dagar eller Ă€ldre) du inte anvĂ€nder lĂ€ngre.";
+"user_sessions_overview_security_recommendations_inactive_title" = "Inaktiva sessioner";
+"user_sessions_overview_security_recommendations_unverified_info" = "Verifiera eller logga ut frÄn overifierade sessioner.";
+"user_sessions_overview_security_recommendations_unverified_title" = "Overifierade sessioner";
+"user_sessions_overview_security_recommendations_section_info" = "FörbÀttra din kontosÀkerhet genom att följa dessa rekommendationer.";
+"user_sessions_overview_security_recommendations_section_title" = "SĂ€kerhetsrekommendationer";
+"user_sessions_overview_title" = "Sessioner";
+
+// MARK: User sessions management
+
+// Parameter is the application display name (e.g. "Element")
+"user_sessions_default_session_display_name" = "%@ iOS";
+"location_sharing_map_loading_error" = "Kan inte ladda karta.\nDen hÀr hemservern Àr inte konfigurerad för att visa kartor";
+"location_sharing_invalid_power_level_message" = "Du har inte de behörigheter som krÀvs för att dela realtidsplats i det hÀr rummet.";
+"location_sharing_invalid_power_level_title" = "Du Àr inte behörig att dela realtidsplats";
+"poll_timeline_reply_ended_poll" = "Avslutade omröstning";
+"poll_timeline_ended_text" = "Avslutade omröstningen";
+"poll_timeline_decryption_error" = "PÄ grund av avkrypteringsfel sÄ kanske inte vissa röster rÀknas";
+"poll_history_fetching_error" = "Fel vid hÀmtning av omröstningar.";
+"poll_history_load_more" = "Ladda fler omröstningar";
+"poll_history_no_past_poll_period_text" = "Det finns inga tidigare omröstningar frÄn det senaste %@ dagarna. Ladda fler omröstningar för att se omröstningar frÄn tidigare mÄnader";
+"poll_history_no_active_poll_period_text" = "Det finns inga aktiva omröstningar under de senaste %@ dagarna. Ladda fler omröstningar för att visa omröstningar för tidigare mÄnader";
+"poll_history_no_past_poll_text" = "Det finns inga tidigare omröstningar i det hÀr rummet";
+"poll_history_no_active_poll_text" = "Det finns inga aktiva omröstningar i det hÀr rummet";
+"poll_history_past_segment_title" = "Tidigare omröstningar";
+"poll_history_active_segment_title" = "Aktiva omröstningar";
+"poll_history_loading_text" = "Visar omröstningar";
+
+// MARK: - Polls history
+
+"poll_history_title" = "Omröstningshistorik";
+"space_invite_nav_title" = "Utrymmesinbjudan";
+"space_detail_nav_title" = "Utrymmesdetalj";
+"space_selector_create_space" = "Skapa utrymme";
+"space_selector_empty_view_information" = "Utrymmen Àr ett sÀtt att gruppera rum och personer. Skapa et utrymme för att komma igÄng.";
+"space_selector_empty_view_title" = "Inga utrymmen Àn.";
+
+// MARK: - Space Selector
+
+"space_selector_title" = "Mina utrymmen";
+"room_invites_empty_view_information" = "Det hÀr Àr vart dina inbjudningar hamnar.";
+
+// MARK: - Room invites
+
+"room_invites_empty_view_title" = "Inget nytt.";
+"all_chats_edit_menu_space_settings" = "UtrymmesinstÀllningar";
+"all_chats_edit_menu_leave_space" = "LĂ€mna %@";
+"all_chats_user_menu_settings" = "AnvÀndarinstÀllningar";
+"all_chats_user_menu_accessibility_label" = "AnvÀndarmeny";
+"room_recents_recently_viewed_section" = "Nyligen sedda";
+"all_chats_nothing_found_placeholder_message" = "Pröva att justera din sökning.";
+"all_chats_nothing_found_placeholder_title" = "Inget hittat.";
+"all_chats_empty_unreads_placeholder_message" = "Det hÀr Àr vart dina olÀsta meddelanden kommer att hamna, nÀr du har nÄgra.";
+"voice_broadcast_recorder_connection_error" = "Anslutningsfel - Inspelning pausad";
+"voice_broadcast_connection_error_message" = "TyvÀrr kan vi inte starta en röstsÀndning för tillfÀllet. VÀnligen pröva igen senare.";
+"voice_broadcast_connection_error_title" = "Anslutningsfel";
+"voice_broadcast_playback_lock_screen_placeholder" = "RöstsÀndning";
+
+// MARK: - Launch loading
+
+"launch_loading_migrating_data" = "Migrerar data\n%@ %%";
+"room_details_polls" = "Omröstningshistorik";
+"settings_labs_disable_crypto_sdk" = "TotalstrÀckskryptering i Rust (logga ut för att stÀnga av)";
+"settings_labs_confirm_crypto_sdk" = "VÀnligen observera att den hÀr funktionen fortfarande ska anses vara experimentell, den kanske inte fungerar som förvÀntat eller kan leda till okÀnda konsekvenser. För att ÄtergÄ, logga ut och logga sedan in igen. AnvÀnd pÄ egen risk.";
+"settings_labs_enable_crypto_sdk" = "TotalstrÀckskryptering i Rust";
+"accessibility_selected" = "vald";
+"settings_push_rules_error" = "Ett fel uppstod vid uppdatering av dina aviseringsinstÀllningar. VÀnligen försök att vÀxla dina alternativ igen.";
+"wysiwyg_composer_format_action_un_indent" = "Minska indrag";
+"wysiwyg_composer_format_action_indent" = "Ăka indrag";
+"poll_history_detail_view_in_timeline" = "Visa omröstning i tidslinje";
+"voice_broadcast_playback_unable_to_decrypt" = "Kunde inte avkryptera denna röstsÀndning.";
+"home_context_menu_mark_as_unread" = "Markera som olÀst";
+"key_backup_recover_from_private_key_progress" = "%@%% FĂ€rdig";
diff --git a/Riot/Assets/uk.lproj/Vector.strings b/Riot/Assets/uk.lproj/Vector.strings
index 95c51d890c..cc3bd8b93e 100644
--- a/Riot/Assets/uk.lproj/Vector.strings
+++ b/Riot/Assets/uk.lproj/Vector.strings
@@ -2670,14 +2670,6 @@
// Mark: - Room invites
"room_invites_empty_view_title" = "ĐŃŃĐŸĐłĐŸ ĐœĐŸĐČĐŸĐłĐŸ.";
-"all_chats_onboarding_try_it" = "ĐĄĐżŃĐŸĐ±ŃĐČĐ°ŃĐž";
-"all_chats_onboarding_title" = "Đ©ĐŸ ĐœĐŸĐČĐŸĐłĐŸ";
-"all_chats_onboarding_page_message3" = "ĐąĐŸŃĐșĐœŃŃŃŃŃ ŃĐČĐŸĐłĐŸ ĐżŃĐŸŃŃĐ»Ń, ŃĐŸĐ± ŃĐŸĐ·ĐżĐŸĐČŃŃŃĐž ĐœĐ°ĐŒ ŃĐČĐŸŃ ĐŽŃĐŒĐșŃ.";
-"all_chats_onboarding_page_title3" = "ĐапОŃŃŃŃ ĐČŃĐŽĐłŃĐș";
-"all_chats_onboarding_page_message2" = "ĐŃŃĐžĐŒŃĐčŃĐ” ĐŽĐŸŃŃŃĐż ĐŽĐŸ ŃĐČĐŸŃŃ
ĐżŃĐŸŃŃĐŸŃŃĐČ (ŃĐœĐžĐ·Ń Đ»ŃĐČĐŸŃŃŃ) ŃĐČОЎŃĐ” ŃĐ° лДгŃĐ”, ĐœŃж ŃĐ°ĐœŃŃĐ”.";
-"all_chats_onboarding_page_title2" = "ĐĐŸŃŃŃĐż ĐŽĐŸ ĐżŃĐŸŃŃĐŸŃŃĐČ";
-"all_chats_onboarding_page_message1" = "Đ©ĐŸĐ± ŃĐżŃĐŸŃŃĐžŃĐž ĐČĐ°Ń Element, ĐČĐșлаЎĐșĐž ŃĐ”ĐżĐ”Ń ĐœĐ”ĐŸĐ±ĐŸĐČâŃĐ·ĐșĐŸĐČŃ. ĐĐ”ŃŃĐčŃĐ” ĐœĐžĐŒĐž Ń ĐČĐ”ŃŃ
ĐœŃĐŸĐŒŃ ĐżŃĐ°ĐČĐŸĐŒŃ ĐŒĐ”ĐœŃ.";
-"all_chats_onboarding_page_title1" = "ĐŃŃĐ°ŃĐŒĐŸ ĐČ ĐœĐŸĐČĐŸĐŒŃ ĐČОглŃĐŽŃ!";
"all_chats_nothing_found_placeholder_message" = "ĐĄĐżŃĐŸĐ±ŃĐčŃĐ” ĐœĐ°Đ»Đ°ŃŃŃĐČĐ°ŃĐž ĐżĐŸŃŃĐș.";
"all_chats_nothing_found_placeholder_title" = "ĐŃŃĐŸĐłĐŸ ĐœĐ” Đ·ĐœĐ°ĐčĐŽĐ”ĐœĐŸ.";
"all_chats_empty_unreads_placeholder_message" = "ĐąŃŃ Đ·'ŃĐČĐ»ŃŃĐžĐŒŃŃŃŃŃ ĐČĐ°ŃŃ ĐœĐ”ĐżŃĐŸŃĐžŃĐ°ĐœŃ ĐżĐŸĐČŃĐŽĐŸĐŒĐ»Đ”ĐœĐœŃ, ŃĐșŃĐŸ ĐČĐŸĐœĐž Ń.";
@@ -2919,6 +2911,18 @@
// MARK: - Launch loading
"launch_loading_migrating_data" = "ĐĐ”ŃĐ”ĐœĐ”ŃĐ”ĐœĐœŃ ĐŽĐ°ĐœĐžŃ
\n%@ %%";
-"settings_labs_disable_crypto_sdk" = "Crypto SDK ŃĐČŃĐŒĐșĐœĐ”ĐœĐŸ. Đ©ĐŸĐ± ĐČĐžĐŒĐșĐœŃŃĐž, пДŃĐ”ĐČŃŃĐ°ĐœĐŸĐČŃŃŃ Đ·Đ°ŃŃĐŸŃŃĐœĐŸĐș";
-"settings_labs_confirm_crypto_sdk" = "ĐŃŃ ĐœĐ” ĐŒĐŸĐ¶ĐœĐ° ŃĐșĐ°ŃŃĐČĐ°ŃĐž";
-"settings_labs_enable_crypto_sdk" = "ĐŁĐČŃĐŒĐșĐœŃŃĐž ĐœĐŸĐČĐžĐč Đ·Đ°ŃĐœĐŸĐČĐ°ĐœĐžĐč ĐœĐ° rust Crypto SDK";
+"settings_labs_disable_crypto_sdk" = "ĐĐ°ŃĐșŃŃĐ·ĐœĐ” ŃĐžŃŃŃĐČĐ°ĐœĐœŃ Rust (ĐČĐžĐčĐŽŃŃŃ, ŃĐŸĐ± ĐČĐžĐŒĐșĐœŃŃĐž)";
+"settings_labs_confirm_crypto_sdk" = "ĐĐ°ŃĐČажŃĐ”, ŃĐŸ ĐŸŃĐșŃĐ»ŃĐșĐž ŃŃ ŃŃĐœĐșŃŃŃ ĐŽĐŸŃŃ ĐżĐ”ŃДбŃĐČĐ°Ń ĐœĐ° ŃŃĐ°ĐŽŃŃ Đ”ĐșŃпДŃĐžĐŒĐ”ĐœŃŃ, ĐČĐŸĐœĐ° ĐŒĐŸĐ¶Đ” ĐżŃĐ°ŃŃĐČĐ°ŃĐž ĐœĐ” ŃĐ°Đș, ŃĐș ĐŸŃŃĐșŃŃŃŃŃŃ, Ń ĐŒĐŸĐ¶Đ” ĐŒĐ°ŃĐž ĐœĐ”ĐżĐ”ŃДЎбаŃŃĐČĐ°ĐœŃ ĐœĐ°ŃĐ»ŃĐŽĐșĐž. Đ©ĐŸĐ± ĐČĐžĐŒĐșĐœŃŃĐž ŃŃ ŃŃĐœĐșŃŃŃ, ĐżŃĐŸŃŃĐŸ ĐČĐžĐčĐŽŃŃŃ Đ· ŃĐžŃŃĐ”ĐŒĐž ŃĐ° ŃĐČŃĐčĐŽŃŃŃ Đ·ĐœĐŸĐČŃ. ĐĐžĐșĐŸŃĐžŃŃĐŸĐČŃĐčŃĐ” ĐœĐ° ĐČлаŃĐœĐžĐč ŃĐŸĐ·ŃŃĐŽ Ń Đ· ĐŸĐ±Đ”ŃĐ”Đ¶ĐœŃŃŃŃ.";
+"settings_labs_enable_crypto_sdk" = "ĐĐ°ŃĐșŃŃĐ·ĐœĐ” ŃĐžŃŃŃĐČĐ°ĐœĐœŃ Rust";
+"poll_history_load_more" = "ĐĐ°ĐČĐ°ĐœŃажОŃĐž бŃĐ»ŃŃĐ” ĐŸĐżĐžŃŃĐČĐ°ĐœŃ";
+"poll_history_no_past_poll_period_text" = "ĐĐ° ĐŸŃŃĐ°ĐœĐœŃ %@ ĐŽĐœŃĐČ ĐœĐ”ĐŒĐ°Ń Đ°ĐșŃĐžĐČĐœĐžŃ
ĐŸĐżĐžŃŃĐČĐ°ĐœŃ. ĐĐ°ĐČĐ°ĐœŃажŃĐ” бŃĐ»ŃŃĐ” ĐŸĐżĐžŃŃĐČĐ°ĐœŃ, ŃĐŸĐ± пДŃДглŃĐœŃŃĐž ĐŸĐżĐžŃŃĐČĐ°ĐœĐœŃ Đ·Đ° ĐżĐŸĐżĐ”ŃĐ”ĐŽĐœŃ ĐŒŃŃŃŃŃ";
+"poll_history_no_active_poll_period_text" = "ĐĐ° ĐŸŃŃĐ°ĐœĐœŃ %@ ĐŽĐœŃĐČ ĐœĐ”ĐŒĐ°Ń Đ°ĐșŃĐžĐČĐœĐžŃ
ĐŸĐżĐžŃŃĐČĐ°ĐœŃ. ĐĐ°ĐČĐ°ĐœŃажŃĐ” бŃĐ»ŃŃĐ” ĐŸĐżĐžŃŃĐČĐ°ĐœŃ, ŃĐŸĐ± пДŃДглŃĐœŃŃĐž ĐŸĐżĐžŃŃĐČĐ°ĐœĐœŃ Đ·Đ° ĐżĐŸĐżĐ”ŃĐ”ĐŽĐœŃ ĐŒŃŃŃŃŃ";
+"poll_history_loading_text" = "ĐĐŸĐșĐ°Đ· ĐŸĐżĐžŃŃĐČĐ°ĐœŃ";
+"poll_history_fetching_error" = "ĐĐŸĐŒĐžĐ»ĐșĐ° ĐŸŃŃĐžĐŒĐ°ĐœĐœŃ ĐŸĐżĐžŃŃĐČĐ°ĐœŃ.";
+"key_backup_recover_from_private_key_progress" = "%@%% ĐČĐžĐșĐŸĐœĐ°ĐœĐŸ";
+"voice_broadcast_playback_unable_to_decrypt" = "ĐĐ”ĐŒĐŸĐ¶Đ»ĐžĐČĐŸ ŃĐŸĐ·ŃĐžŃŃŃĐČĐ°ŃĐž ŃŃ ĐłĐŸĐ»ĐŸŃĐŸĐČŃ ŃŃĐ°ĐœŃĐ»ŃŃŃŃ.";
+"home_context_menu_mark_as_unread" = "ĐĐŸĐ·ĐœĐ°ŃĐžŃĐž ĐœĐ”ĐżŃĐŸŃĐžŃĐ°ĐœĐžĐŒ";
+"wysiwyg_composer_format_action_un_indent" = "ĐĐŒĐ”ĐœŃĐžŃĐž ĐČŃĐŽŃŃŃĐż";
+"wysiwyg_composer_format_action_indent" = "ĐбŃĐ»ŃŃĐžŃĐž ĐČŃĐŽŃŃŃĐż";
+"settings_push_rules_error" = "ĐĄŃалаŃŃ ĐżĐŸĐŒĐžĐ»ĐșĐ° ĐżŃĐŽ ŃĐ°Ń ĐŸĐœĐŸĐČĐ»Đ”ĐœĐœŃ ĐœĐ°Đ»Đ°ŃŃŃĐČĐ°ĐœŃ ŃĐżĐŸĐČŃŃĐ”ĐœŃ. ĐĄĐżŃĐŸĐ±ŃĐčŃĐ” Đ·ĐŒŃĐœĐžŃĐž ĐœĐ°Đ»Đ°ŃŃŃĐČĐ°ĐœĐœŃ ŃĐ” ŃĐ°Đ·.";
+"poll_history_detail_view_in_timeline" = "ĐĐ”ŃДглŃĐœŃŃĐž ĐŸĐżĐžŃŃĐČĐ°ĐœĐœŃ Ń ŃŃŃŃŃŃŃ";
diff --git a/Riot/Assets/zh_Hans.lproj/Vector.strings b/Riot/Assets/zh_Hans.lproj/Vector.strings
index f7fd8166c9..69d2d7cb93 100644
--- a/Riot/Assets/zh_Hans.lproj/Vector.strings
+++ b/Riot/Assets/zh_Hans.lproj/Vector.strings
@@ -287,8 +287,8 @@
"settings_old_password" = "æ§ćŻç ";
"settings_new_password" = "æ°ćŻç ";
"settings_confirm_password" = "çĄźèź€ćŻç ";
-"settings_fail_to_update_password" = "æŽæ°ćŻç ć€±èŽ„";
-"settings_password_updated" = "æšçćŻç ć·Čç»æŽæ°";
+"settings_fail_to_update_password" = "æŽæ°Matrix莊æ·ćŻç ć€±èŽ„";
+"settings_password_updated" = "æšçMatrix莊æ·ćŻç ć·Čç»æŽæ°";
"settings_crypto_device_name" = "äŒèŻćç§°ïŒ ";
"settings_crypto_device_id" = "\näŒèŻIDïŒ ";
"settings_crypto_device_key" = "\näŒèŻćŻé„:\n";
@@ -582,7 +582,7 @@
"deactivate_account_informations_part5" = "ćŠææšćžææ仏ćżèź°æšçæ¶æŻïŒèŻ·ćŸéäžéąçæĄ\n\nMatrixäžçæ¶æŻćŻè§æ§äžç”ćéźä»¶ç±»äŒŒă æ仏ćżèź°æšçæ¶æŻæćłçæšć·Čćéçæ¶æŻć°äžäŒćäžä»»äœæ°çšæ·ææȘæłšćçšæ·ć
±äș«ïŒäœć·Čææèźżéźèżäșæ¶æŻçæłšćçšæ·ä»ćŻèźżéźć
¶ćŻæŹă";
"deactivate_account_forget_messages_information_part1" = "ćœæç莊æ·èą«ćçšæ¶ïŒèŻ·ćżèź°æćéçæææ¶æŻïŒ";
"deactivate_account_forget_messages_information_part3" = ": èżäŒćŻŒèŽć°æ„ć ć
„ççšæ·çć°çæŻäžæź”äžćźæŽçćŻčèŻïŒ";
-"deactivate_account_password_alert_message" = "èŠç»§ç»ïŒèŻ·èŸć
„æšçćŻç ";
+"deactivate_account_password_alert_message" = "èŠç»§ç»ïŒèŻ·èŸć
„äœ çMatrix莊æ·ćŻç ";
"rerequest_keys_alert_message" = "èŻ·ćšćŠäžć°ćŻä»„è§ŁćŻæ¶æŻçèźŸć€äžćŻćš%@ïŒèżæ ·ćźć°±ćŻä»„ć°ćŻé„ćéć°æ€äŒèŻă";
"key_backup_setup_title" = "ćŻé„ć€ä»œ";
"key_backup_setup_skip_alert_title" = "æšçĄźćźćïŒ";
@@ -725,7 +725,7 @@
"settings_labs_enable_cross_signing" = "ćŒćŻäș€ćçŸćæçšæ·éȘèŻèäžæŻæèźŸć€éȘèŻïŒćŒćäžïŒ";
"settings_add_3pid_password_title_email" = "æ·»ć éźçź±ć°ć";
"settings_add_3pid_password_title_msidsn" = "æ·»ć ç”èŻć·ç ";
-"settings_add_3pid_password_message" = "èŻ·ćĄ«ćäœ çćŻç 仄继ç»";
+"settings_add_3pid_password_message" = "èŻ·ćĄ«ćäœ çMatrix莊æ·çćŻç 仄继ç»";
"settings_add_3pid_invalid_password_message" = "éȘèŻäżĄæŻæ æ";
"settings_key_backup_button_connect" = "ć
łèæ€äŒèŻć°ćŻé„ć€ä»œ";
"settings_devices_description" = "äŒèŻçć
ŹćŒććäŒćŻčäœ èç»çäșșćŻè§";
@@ -1044,15 +1044,15 @@
"key_verification_bootstrap_not_setup_title" = "éèŻŻ";
"key_verification_bootstrap_not_setup_message" = "æšéèŠć
ćŻćšäș€ćçŸćă";
"key_verification_verify_qr_code_title" = "éèżæ«æèżèĄéȘèŻ";
-"key_verification_verify_qr_code_information" = "æ«æ代ç 仄ćźć
šć°çžäșéȘèŻă";
-"key_verification_verify_qr_code_information_other_device" = "æ«æ仄äžä»Łç 仄éȘèŻïŒ";
+"key_verification_verify_qr_code_information" = "æ«ææĄç 仄ćźć
šć°çžäșéȘèŻă";
+"key_verification_verify_qr_code_information_other_device" = "æ«æ仄äžæĄç 仄éȘèŻïŒ";
"key_verification_verify_qr_code_emoji_information" = "éèżæŻèŸćŻäžçèĄšæ
珊ć·èżèĄéȘèŻă";
-"key_verification_verify_qr_code_scan_code_action" = "æ«æä»ä»Źç代ç ";
+"key_verification_verify_qr_code_scan_code_action" = "æ«æä»ä»ŹçæĄç ";
"key_verification_verify_qr_code_cannot_scan_action" = "äžèœæ«æćïŒ";
"key_verification_verify_qr_code_start_emoji_action" = "éèżèĄšæ
珊ć·éȘèŻ";
-"key_verification_verify_qr_code_other_scan_my_code_title" = "ć
¶ä»çšæ·æŻćŠæćæ«æäșäș绎ç ïŒ";
+"key_verification_verify_qr_code_other_scan_my_code_title" = "ć
¶ä»çšæ·æŻćŠæćæ«æäșQRç ïŒ";
"key_verification_verify_qr_code_scan_other_code_success_title" = "代ç ć·ČéȘèŻïŒ";
-"key_verification_verify_qr_code_scan_other_code_success_message" = "äș绎ç ć·ČæćéȘèŻă";
+"key_verification_verify_qr_code_scan_other_code_success_message" = "QRç ć·ČæćéȘèŻă";
// Scanning
"key_verification_scan_confirmation_scanning_title" = "ćż«ć„œäșïŒæŁćšçćŸ
çĄźèź€âŠ";
"key_verification_scan_confirmation_scanning_user_waiting_other" = "çćŸ
äž%@âŠ";
@@ -1082,7 +1082,7 @@
"secrets_recovery_with_key_invalid_recovery_key_title" = "æ æłèźżéźæșćŻććš";
"secrets_recovery_with_key_invalid_recovery_key_message" = "èŻ·éȘèŻæšèŸć
„çćźć
šćŻé„æŻćŠæŁçĄźă";
"rooms_empty_view_information" = "æżéŽéćžžéćä»»äœçŸ€èïŒæ èźșæŻç§äșșçèżæŻć
Źć
±çăçčć»+仄æ„æŸç°ææżéŽïŒææ°ć»șæżéŽă";
-"security_settings_user_password_description" = "éèżèŸć
„æšç莊æ·ćŻç çĄźèź€æšçèș«ä»œ";
+"security_settings_user_password_description" = "éèżèŸć
„æšçMatrix莊æ·ćŻç çĄźèź€æšçèș«ä»œ";
"rooms_empty_view_title" = "æżéŽ";
"people_empty_view_information" = "äžä»»äœäșșćźć
šè怩ăçčć»+ćŒć§æ·»ć äșșćă";
"people_empty_view_title" = "çšæ·";
@@ -1104,7 +1104,7 @@
"security_settings_secure_backup_synchronise" = "ćæ„";
"security_settings_secure_backup_setup" = "èźŸçœź";
"security_settings_secure_backup_description" = "ć€ä»œäœ ç莊æ·æ°æźć€ä»œćć ćŻćŻé„ïŒä»„éČäœ æ æłèźżéźäŒèŻă äœ çćŻé„ć°ćć°ćŻäžçćźć
šćŻé„äżæ€ă";
-"security_settings_crypto_sessions_description_2" = "ćŠææšæȘæŸćè”·ç»ćœïŒèŻ·æŽæčćŻç ćč¶éçœźćźć
šć€ä»œă";
+"security_settings_crypto_sessions_description_2" = "ćŠææšæȘæŸćè”·ç»ćœïŒèŻ·æŽæčMatrix莊æ·çćŻç ćč¶éçœźćźć
šć€ä»œă";
"settings_show_NSFW_public_rooms" = "æŸç€ș NSFW ć
Źć
±æżéŽ";
"external_link_confirmation_message" = "æ€éŸæ„ %@ äŒć°æšćžŠèłćŠäžäžȘçœç«ïŒ%@\n\næŻćŠććŸïŒ";
"external_link_confirmation_title" = "ćć»æ€éŸæ„";
@@ -1167,14 +1167,14 @@
"room_info_list_section_other" = "ć
¶ä»";
"create_room_section_footer_encryption" = "ć ćŻäžç»ćŻçšïŒäŸżæ æłçŠçšă";
"create_room_placeholder_address" = "#testroom:matrix.org";
-"create_room_section_header_address" = "æżéŽć°ć";
-"create_room_section_header_type" = "æżéŽç±»ć";
+"create_room_section_header_address" = "ć°ć";
+"create_room_section_header_type" = "è°ćŻä»„ć ć
„";
"create_room_enable_encryption" = "ćŻçšć ćŻ";
-"create_room_section_header_encryption" = "æżéŽć ćŻ";
+"create_room_section_header_encryption" = "ć ćŻ";
"create_room_placeholder_topic" = "èżäžȘæżéŽæŻć
łäșä»äčçïŒ";
-"create_room_section_header_topic" = "æżéŽèŻéąïŒćŻéïŒ";
+"create_room_section_header_topic" = "èŻéąïŒćŻéïŒ";
"create_room_placeholder_name" = "ć称";
-"create_room_section_header_name" = "æżéŽć称";
+"create_room_section_header_name" = "ć称";
// MARK: - Create Room
@@ -1251,10 +1251,10 @@
"invite_friends_share_text" = "ćšïŒćš %@ è·æèŻŽïŒ%@";
"favourites_empty_view_information" = "äœ ćŻä»„éæ©ć ç§æčæł - æćż«ćȘéæäœăçčć»ææïŒćźä»ŹäŒèȘćšćșç°ćšèżéïŒä»„祟äżćźć
šă";
"home_empty_view_information" = "ćąéăæććç»ç»çäžäœććźć
šè怩ćșçšçšćșă çčć»äžéąçă+ăæéźæ·»ć äșșććæżéŽă";
-"create_room_show_in_directory" = "ćšçźćœäžæŸç€șæżéŽ";
+"create_room_show_in_directory" = "ćšæżéŽçźćœäžæŸç€ș";
"create_room_section_footer_type" = "äșș仏ćȘæćšæ¶ć°è怩柀éèŻ·ćæćŻä»„èżć
„ç§ææżéŽă";
-"create_room_type_public" = "ć
ŹćŒæżéŽ";
-"create_room_type_private" = "ç§ææżéŽ";
+"create_room_type_public" = "ć
ŹćŒæżéŽïŒä»»äœäșșïŒ";
+"create_room_type_private" = "ç§ææżéŽïŒä»
éèŻ·ïŒ";
"biometrics_cant_unlocked_alert_message_login" = "éæ°ç»ćœ";
"biometrics_cant_unlocked_alert_message_x" = "è„èŠè§ŁéïŒèŻ·äœżçš %@ æéæ°ç»ćœćč¶ćŻçš %@";
"biometrics_cant_unlocked_alert_title" = "æ æłè§Łéćșçšçšćș";
@@ -1288,7 +1288,7 @@
// Banner
"cross_signing_setup_banner_title" = "èźŸçœźć ćŻ";
-"secrets_reset_authentication_message" = "èŻ·èŸć
„äœ ç莊æ·ćŻç èżèĄçĄźèź€";
+"secrets_reset_authentication_message" = "èŻ·èŸć
„äœ çMatrix莊æ·ćŻç èżèĄçĄźèź€";
"secrets_reset_warning_message" = "æšć°éæ°ćŻćšïŒæČĄæććČèź°ćœïŒæ¶æŻïŒć俥任çèźŸć€æć俥任ççšæ·ă";
"secrets_reset_warning_title" = "ćŠæäœ éæ©ć
šéšéçœź";
"secrets_reset_information" = "ä»
ćœæČĄæć
¶ä»èźŸć€ćŻçšæ„éȘèŻæ€èźŸć€æ¶ïŒææ§èĄæ€æäœă";
@@ -2259,19 +2259,29 @@
"authentication_qr_login_failure_retry" = "ćèŻäžæŹĄ";
"authentication_qr_login_failure_request_timed_out" = "èżæ„æČĄæćšè§ćźçæ¶éŽć
ćźæă";
"authentication_qr_login_failure_request_denied" = "èŻ·æ±ćšćŠäžäžȘèźŸć€äžèą«æç»ă";
-"authentication_qr_login_failure_invalid_qr" = "äș绎ç æ æă";
+"authentication_qr_login_failure_invalid_qr" = "QRç æ æă";
"authentication_qr_login_failure_title" = "èżæ„ć€±èŽ„";
"authentication_qr_login_loading_signed_in" = "æšç°ćšć·Čç»ç»ćœć°ćŠäžäžȘèźŸć€äžă";
-"authentication_qr_login_loading_waiting_signin" = "çćŸ
èźŸć€ç»ćœă";
-"authentication_qr_login_loading_connecting_device" = "èżæ„ć°èźŸć€";
-"authentication_qr_login_confirm_alert" = "èŻ·çĄźäżæšç„éæ€ä»Łç çæ„æșăéèżèżæ„èźŸć€ïŒæšć°äžșæäșșæäŸćŻčæšćžæ·çćźć
šèźżéźæéă";
-"authentication_qr_login_confirm_subtitle" = "çĄźèź€äžéąç代ç äžæšçć
¶ä»èźŸć€ćčé
:";
-"authentication_qr_login_confirm_title" = "ć»șç«ćźć
šèżæ„";
-"authentication_qr_login_scan_subtitle" = "ć°äș绎ç æŸçœźćšäžéąçæčæĄäž";
-"authentication_qr_login_scan_title" = "æ«æäș绎ç ";
-"authentication_qr_login_display_step2" = "éæ©â仄äș绎ç ç»ć
„â";
+"authentication_qr_login_loading_waiting_signin" = "æŁćšçćŸ
èźŸć€ä»„ç»ćœă";
+"authentication_qr_login_loading_connecting_device" = "æŁćšèżæ„ć°èźŸć€";
+"authentication_qr_login_confirm_alert" = "èŻ·çĄźäżæšç„éæ€ä»Łç çæ„æșăéèżèżæ„èźŸć€ïŒæšć°äžșæäșșæäŸćŻčæšèŽŠæ·çćźć
šèźżéźæéă";
+"authentication_qr_login_confirm_subtitle" = "çĄźèź€äžéąç代ç äžæšçć
¶ä»èźŸć€ćčé
ïŒ";
+"authentication_qr_login_confirm_title" = "ćźć
šèżæ„ć·Čć»șç«";
+"authentication_qr_login_scan_subtitle" = "ć°QRç æŸçœźćšäžéąçæčæĄäž";
+"authentication_qr_login_scan_title" = "æ«æQRç ";
+"authentication_qr_login_display_step2" = "éæ©â仄QRç ç»ć
„â";
"authentication_qr_login_display_step1" = "ćšæšçć
¶ćźèźŸć€äžæćŒElement";
"onboarding_splash_page_4_title_no_pun" = "äžșæšçćąéćéæ¶æŻă";
"user_session_learn_more" = "äșè§ŁæŽć€";
"manage_session_name_info_link" = "äșè§ŁæŽć€";
"threads_beta_information_link" = "äșè§ŁæŽć€";
+"authentication_qr_login_display_subtitle" = "çšäœ ç»ćșçèźŸć€æ«æäžéąçQRç ă";
+"room_invite_to_space_option_detail" = "ä»ä»ŹćŻä»„æąçŽą %@ïŒäœäžäŒæäžș %@ çæćă";
+"analytics_prompt_message_new_user" = "éèżćäș«ćżćçäœżçšæ°æźïŒćžźć©æ仏èŻć«éźéąćč¶æčèż %@ ăäžșäșäșè§Łäșș仏ćŠäœäœżçšć€äžȘèźŸć€ïŒæ仏ć°çæäžäžȘéæșçæ èŻçŹŠïŒç±äœ çèźŸć€ć
±äș«ă";
+"threads_notice_done" = "ç„éäș";
+"message_from_a_thread" = "æ„èȘæ¶æŻć";
+"threads_empty_info_all" = "æ¶æŻććžźć©äœ çćŻčèŻäžçŠ»éąäžæäșè·èžȘă";
+"accessibility_selected" = "ć·Čéäž";
+"deselect_all" = "ćæ¶ć
šé";
+"notice_voice_broadcast_ended" = "%@ç»æäșäžäžȘèŻéłćčżæă";
+"notice_voice_broadcast_ended_by_you" = "äœ ç»æäșäžäžȘèŻéłćčżæă";
diff --git a/Riot/Categories/MXBugReportRestClient+Riot.swift b/Riot/Categories/MXBugReportRestClient+Riot.swift
index 93eff76aaa..2c46498699 100644
--- a/Riot/Categories/MXBugReportRestClient+Riot.swift
+++ b/Riot/Categories/MXBugReportRestClient+Riot.swift
@@ -46,10 +46,10 @@ extension MXBugReportRestClient {
// User info (TODO: handle multi-account and find a way to expose them in rageshake API)
var userInfo = [String: String]()
let mainAccount = MXKAccountManager.shared().accounts.first
- if let userId = mainAccount?.mxSession.myUser.userId {
+ if let userId = mainAccount?.mxSession?.myUser?.userId {
userInfo["user_id"] = userId
}
- if let deviceId = mainAccount?.mxSession.matrixRestClient.credentials.deviceId {
+ if let deviceId = mainAccount?.mxSession?.myDeviceId {
userInfo["device_id"] = deviceId
}
diff --git a/Riot/Categories/MXRoom+Riot.m b/Riot/Categories/MXRoom+Riot.m
index df47c16740..04538ba804 100644
--- a/Riot/Categories/MXRoom+Riot.m
+++ b/Riot/Categories/MXRoom+Riot.m
@@ -637,7 +637,7 @@ - (void)enablePushRule:(MXPushRule *)rule completion:(void (^)(void))completion
}];
}
- [notificationCenter enableRule:rule isEnabled:YES];
+ [notificationCenter enableRule:rule isEnabled:YES completion:nil];
}
- (void)setNotificationCenterDidFailObserver:(id)anObserver
diff --git a/Riot/Categories/MatrixSDKCrypto+LocalizedError.swift b/Riot/Categories/MatrixSDKCrypto+LocalizedError.swift
new file mode 100644
index 0000000000..4b314a0c18
--- /dev/null
+++ b/Riot/Categories/MatrixSDKCrypto+LocalizedError.swift
@@ -0,0 +1,26 @@
+//
+// Copyright 2023 New Vector Ltd
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+import Foundation
+import MatrixSDKCrypto
+
+extension CryptoStoreError: LocalizedError {
+ public var errorDescription: String? {
+ // We dont really care about the type of error here when showing to the user.
+ // Details about the error are tracked independently
+ return VectorL10n.e2eNeedLogInAgain
+ }
+}
diff --git a/Riot/Categories/Publisher+Riot.swift b/Riot/Categories/Publisher+Riot.swift
index 98bb522b37..7c70404c6e 100644
--- a/Riot/Categories/Publisher+Riot.swift
+++ b/Riot/Categories/Publisher+Riot.swift
@@ -33,4 +33,10 @@ extension Publisher {
Just($0).delay(for: .seconds(spacingDelay), scheduler: scheduler)
}
}
+
+ func eraseOutput() -> AnyPublisher {
+ self
+ .map { _ in () }
+ .eraseToAnyPublisher()
+ }
}
diff --git a/Riot/Generated/Vector_Strings.swift b/Riot/Generated/Vector_Strings.swift
index dfc25344aa..32a0e5b087 100644
--- a/Riot/Generated/Vector_Strings.swift
+++ b/Riot/Generated/Vector_Strings.swift
@@ -211,38 +211,6 @@ public class VectorL10n: NSObject {
public static var allChatsNothingFoundPlaceholderTitle: String {
return VectorL10n.tr("Vector", "all_chats_nothing_found_placeholder_title")
}
- /// To simplify your Element, tabs are now optional. Manage them using the top-right menu.
- public static var allChatsOnboardingPageMessage1: String {
- return VectorL10n.tr("Vector", "all_chats_onboarding_page_message1")
- }
- /// Access your Spaces (bottom-left) faster and easier than ever before.
- public static var allChatsOnboardingPageMessage2: String {
- return VectorL10n.tr("Vector", "all_chats_onboarding_page_message2")
- }
- /// Tap your profile to let us know what you think.
- public static var allChatsOnboardingPageMessage3: String {
- return VectorL10n.tr("Vector", "all_chats_onboarding_page_message3")
- }
- /// Welcome to a new view!
- public static var allChatsOnboardingPageTitle1: String {
- return VectorL10n.tr("Vector", "all_chats_onboarding_page_title1")
- }
- /// Access Spaces
- public static var allChatsOnboardingPageTitle2: String {
- return VectorL10n.tr("Vector", "all_chats_onboarding_page_title2")
- }
- /// Give Feedback
- public static var allChatsOnboardingPageTitle3: String {
- return VectorL10n.tr("Vector", "all_chats_onboarding_page_title3")
- }
- /// What's new
- public static var allChatsOnboardingTitle: String {
- return VectorL10n.tr("Vector", "all_chats_onboarding_title")
- }
- /// Try it out
- public static var allChatsOnboardingTryIt: String {
- return VectorL10n.tr("Vector", "all_chats_onboarding_try_it")
- }
/// Chats
public static var allChatsSectionTitle: String {
return VectorL10n.tr("Vector", "all_chats_section_title")
@@ -2547,6 +2515,10 @@ public class VectorL10n: NSObject {
public static var homeContextMenuMarkAsRead: String {
return VectorL10n.tr("Vector", "home_context_menu_mark_as_read")
}
+ /// Mark as unread
+ public static var homeContextMenuMarkAsUnread: String {
+ return VectorL10n.tr("Vector", "home_context_menu_mark_as_unread")
+ }
/// Mute
public static var homeContextMenuMute: String {
return VectorL10n.tr("Vector", "home_context_menu_mute")
@@ -2755,6 +2727,10 @@ public class VectorL10n: NSObject {
public static var keyBackupRecoverFromPrivateKeyInfo: String {
return VectorL10n.tr("Vector", "key_backup_recover_from_private_key_info")
}
+ /// %@%% Complete
+ public static func keyBackupRecoverFromPrivateKeyProgress(_ p1: String) -> String {
+ return VectorL10n.tr("Vector", "key_backup_recover_from_private_key_progress", p1)
+ }
/// Use your Security Key to unlock your secure message history
public static var keyBackupRecoverFromRecoveryKeyInfo: String {
return VectorL10n.tr("Vector", "key_backup_recover_from_recovery_key_info")
@@ -4851,10 +4827,34 @@ public class VectorL10n: NSObject {
public static var pollHistoryActiveSegmentTitle: String {
return VectorL10n.tr("Vector", "poll_history_active_segment_title")
}
+ /// View poll in timeline
+ public static var pollHistoryDetailViewInTimeline: String {
+ return VectorL10n.tr("Vector", "poll_history_detail_view_in_timeline")
+ }
+ /// Error fetching polls.
+ public static var pollHistoryFetchingError: String {
+ return VectorL10n.tr("Vector", "poll_history_fetching_error")
+ }
+ /// Load more polls
+ public static var pollHistoryLoadMore: String {
+ return VectorL10n.tr("Vector", "poll_history_load_more")
+ }
+ /// Displaying polls
+ public static var pollHistoryLoadingText: String {
+ return VectorL10n.tr("Vector", "poll_history_loading_text")
+ }
+ /// There are no active polls for the past %@ days. Load more polls to view polls for previous months
+ public static func pollHistoryNoActivePollPeriodText(_ p1: String) -> String {
+ return VectorL10n.tr("Vector", "poll_history_no_active_poll_period_text", p1)
+ }
/// There are no active polls in this room
public static var pollHistoryNoActivePollText: String {
return VectorL10n.tr("Vector", "poll_history_no_active_poll_text")
}
+ /// There are no past polls for the past %@ days. Load more polls to view polls for previous months
+ public static func pollHistoryNoPastPollPeriodText(_ p1: String) -> String {
+ return VectorL10n.tr("Vector", "poll_history_no_past_poll_period_text", p1)
+ }
/// There are no past polls in this room
public static var pollHistoryNoPastPollText: String {
return VectorL10n.tr("Vector", "poll_history_no_past_poll_text")
@@ -7591,7 +7591,7 @@ public class VectorL10n: NSObject {
public static var settingsLabs: String {
return VectorL10n.tr("Vector", "settings_labs")
}
- /// This action cannot be undone
+ /// Please be advised that as this feature is still in its experimental stage, it may not function as expected and could potentially have unintended consequences. To revert the feature, simply log out and log back in. Use at your own discretion and with caution.
public static var settingsLabsConfirmCryptoSdk: String {
return VectorL10n.tr("Vector", "settings_labs_confirm_crypto_sdk")
}
@@ -7599,7 +7599,7 @@ public class VectorL10n: NSObject {
public static var settingsLabsCreateConferenceWithJitsi: String {
return VectorL10n.tr("Vector", "settings_labs_create_conference_with_jitsi")
}
- /// Crypto SDK is enabled. To disable please reinstall the app
+ /// Rust end-to-end encryption (log out to disable)
public static var settingsLabsDisableCryptoSdk: String {
return VectorL10n.tr("Vector", "settings_labs_disable_crypto_sdk")
}
@@ -7615,7 +7615,7 @@ public class VectorL10n: NSObject {
public static var settingsLabsEnableAutoReportDecryptionErrors: String {
return VectorL10n.tr("Vector", "settings_labs_enable_auto_report_decryption_errors")
}
- /// Enable new rust-based Crypto SDK
+ /// Rust end-to-end encryption
public static var settingsLabsEnableCryptoSdk: String {
return VectorL10n.tr("Vector", "settings_labs_enable_crypto_sdk")
}
@@ -7779,6 +7779,10 @@ public class VectorL10n: NSObject {
public static var settingsProfilePicture: String {
return VectorL10n.tr("Vector", "settings_profile_picture")
}
+ /// An error occurred when updating your notification preferences. Please try to toggle your option again.
+ public static var settingsPushRulesError: String {
+ return VectorL10n.tr("Vector", "settings_push_rules_error")
+ }
/// Are you sure you want to remove the email address %@?
public static func settingsRemoveEmailPromptMsg(_ p1: String) -> String {
return VectorL10n.tr("Vector", "settings_remove_email_prompt_msg", p1)
@@ -9259,6 +9263,10 @@ public class VectorL10n: NSObject {
public static var voiceBroadcastPlaybackLockScreenPlaceholder: String {
return VectorL10n.tr("Vector", "voice_broadcast_playback_lock_screen_placeholder")
}
+ /// Unable to decrypt this voice broadcast.
+ public static var voiceBroadcastPlaybackUnableToDecrypt: String {
+ return VectorL10n.tr("Vector", "voice_broadcast_playback_unable_to_decrypt")
+ }
/// Connection error - Recording paused
public static var voiceBroadcastRecorderConnectionError: String {
return VectorL10n.tr("Vector", "voice_broadcast_recorder_connection_error")
@@ -9423,6 +9431,10 @@ public class VectorL10n: NSObject {
public static var wysiwygComposerFormatActionCodeBlock: String {
return VectorL10n.tr("Vector", "wysiwyg_composer_format_action_code_block")
}
+ /// Increase indentation
+ public static var wysiwygComposerFormatActionIndent: String {
+ return VectorL10n.tr("Vector", "wysiwyg_composer_format_action_indent")
+ }
/// Apply inline code format
public static var wysiwygComposerFormatActionInlineCode: String {
return VectorL10n.tr("Vector", "wysiwyg_composer_format_action_inline_code")
@@ -9447,6 +9459,10 @@ public class VectorL10n: NSObject {
public static var wysiwygComposerFormatActionStrikethrough: String {
return VectorL10n.tr("Vector", "wysiwyg_composer_format_action_strikethrough")
}
+ /// Decrease indentation
+ public static var wysiwygComposerFormatActionUnIndent: String {
+ return VectorL10n.tr("Vector", "wysiwyg_composer_format_action_un_indent")
+ }
/// Apply strikethrough format
public static var wysiwygComposerFormatActionUnderline: String {
return VectorL10n.tr("Vector", "wysiwyg_composer_format_action_underline")
diff --git a/Riot/Managers/EncryptionKeyManager/EncryptionKeyManager.swift b/Riot/Managers/EncryptionKeyManager/EncryptionKeyManager.swift
index 5085e9efb1..484a638321 100644
--- a/Riot/Managers/EncryptionKeyManager/EncryptionKeyManager.swift
+++ b/Riot/Managers/EncryptionKeyManager/EncryptionKeyManager.swift
@@ -31,6 +31,7 @@ class EncryptionKeyManager: NSObject, MXKeyProviderDelegate {
private static let cryptoOlmPickleKey: KeyValueStoreKey = "cryptoOlmPickleKey"
private static let roomLastMessageIv: KeyValueStoreKey = "roomLastMessageIv"
private static let roomLastMessageAesKey: KeyValueStoreKey = "roomLastMessageAesKey"
+ private static let cryptoSDKStoreKey: KeyValueStoreKey = "cryptoSDKStoreKey"
private let keychainStore: KeyValueStore = KeychainStore(withKeychain: Keychain(service: keychainService, accessGroup: BuildSettings.keychainAccessGroup))
@@ -47,6 +48,7 @@ class EncryptionKeyManager: NSObject, MXKeyProviderDelegate {
generateKeyIfNotExists(forKey: EncryptionKeyManager.cryptoOlmPickleKey, size: 32)
generateIvIfNotExists(forKey: EncryptionKeyManager.roomLastMessageIv)
generateAesKeyIfNotExists(forKey: EncryptionKeyManager.roomLastMessageAesKey)
+ generateKeyIfNotExists(forKey: EncryptionKeyManager.cryptoSDKStoreKey, size: 32)
assert(keychainStore.containsObject(forKey: EncryptionKeyManager.contactsIv), "[EncryptionKeyManager] initKeys: Failed to generate IV for acount")
assert(keychainStore.containsObject(forKey: EncryptionKeyManager.contactsAesKey), "[EncryptionKeyManager] initKeys: Failed to generate AES Key for acount")
@@ -55,6 +57,7 @@ class EncryptionKeyManager: NSObject, MXKeyProviderDelegate {
assert(keychainStore.containsObject(forKey: EncryptionKeyManager.cryptoOlmPickleKey), "[EncryptionKeyManager] initKeys: Failed to generate Key for olm pickle key")
assert(keychainStore.containsObject(forKey: EncryptionKeyManager.roomLastMessageIv), "[EncryptionKeyManager] initKeys: Failed to generate IV for room last message")
assert(keychainStore.containsObject(forKey: EncryptionKeyManager.roomLastMessageAesKey), "[EncryptionKeyManager] initKeys: Failed to generate AES Key for room last message encryption")
+ assert(keychainStore.containsObject(forKey: EncryptionKeyManager.cryptoSDKStoreKey), "[EncryptionKeyManager] initKeys: Failed to generate Key for crypto sdk store")
}
// MARK: - MXKeyProviderDelegate
@@ -64,6 +67,7 @@ class EncryptionKeyManager: NSObject, MXKeyProviderDelegate {
|| dataType == MXKAccountManagerDataType
|| dataType == MXCryptoOlmPickleKeyDataType
|| dataType == MXRoomLastMessageDataType
+ || dataType == MXCryptoSDKStoreKeyDataType
}
func hasKeyForData(ofType dataType: String) -> Bool {
@@ -77,7 +81,10 @@ class EncryptionKeyManager: NSObject, MXKeyProviderDelegate {
case MXRoomLastMessageDataType:
return keychainStore.containsObject(forKey: EncryptionKeyManager.roomLastMessageIv) &&
keychainStore.containsObject(forKey: EncryptionKeyManager.roomLastMessageAesKey)
+ case MXCryptoSDKStoreKeyDataType:
+ return keychainStore.containsObject(forKey: EncryptionKeyManager.cryptoSDKStoreKey)
default:
+ MXLog.warning("[EncryptionKeyManager] hasKeyForData: No key for \(dataType)")
return false
}
}
@@ -103,7 +110,12 @@ class EncryptionKeyManager: NSObject, MXKeyProviderDelegate {
let aesKey = try? keychainStore.data(forKey: EncryptionKeyManager.roomLastMessageAesKey) {
return MXAesKeyData(iv: ivKey, key: aesKey)
}
+ case MXCryptoSDKStoreKeyDataType:
+ if let key = try? keychainStore.data(forKey: EncryptionKeyManager.cryptoSDKStoreKey) {
+ return MXRawDataKey(key: key)
+ }
default:
+ MXLog.failure("[EncryptionKeyManager] keyDataForData: Attempting to get data for unknown type", dataType)
return nil
}
return nil
diff --git a/Riot/Managers/PushRulesUpdater/PushRulesUpdater.swift b/Riot/Managers/PushRulesUpdater/PushRulesUpdater.swift
new file mode 100644
index 0000000000..a0ffea92f0
--- /dev/null
+++ b/Riot/Managers/PushRulesUpdater/PushRulesUpdater.swift
@@ -0,0 +1,62 @@
+//
+// Copyright 2023 New Vector Ltd
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+import Combine
+
+final class PushRulesUpdater {
+ private var cancellables: Set = .init()
+ private var rules: [NotificationPushRuleType] = []
+ private let notificationSettingsService: NotificationSettingsServiceType
+
+ init(notificationSettingsService: NotificationSettingsServiceType) {
+ self.notificationSettingsService = notificationSettingsService
+
+ notificationSettingsService
+ .rulesPublisher
+ .weakAssign(to: \.rules, on: self)
+ .store(in: &cancellables)
+ }
+
+ func syncRulesIfNeeded() async {
+ await withTaskGroup(of: Void.self) { [rules, notificationSettingsService] group in
+ for rule in rules {
+ guard let ruleId = rule.pushRuleId else {
+ continue
+ }
+
+ let relatedRules = ruleId.syncedRules(in: rules)
+
+ for relatedRule in relatedRules {
+ guard rule.hasSameContentOf(relatedRule) == false else {
+ continue
+ }
+
+ group.addTask {
+ try? await notificationSettingsService.updatePushRuleActions(for: relatedRule.ruleId,
+ enabled: rule.enabled,
+ actions: rule.ruleActions)
+ }
+ }
+ }
+ }
+ }
+}
+
+private extension NotificationPushRuleType {
+ func hasSameContentOf(_ otherRule: NotificationPushRuleType) -> Bool? {
+ enabled == otherRule.enabled && ruleActions == otherRule.ruleActions
+ }
+}
diff --git a/Riot/Managers/Settings/RiotSettings.swift b/Riot/Managers/Settings/RiotSettings.swift
index 5669235cc5..ee178bd686 100644
--- a/Riot/Managers/Settings/RiotSettings.swift
+++ b/Riot/Managers/Settings/RiotSettings.swift
@@ -209,11 +209,9 @@ final class RiotSettings: NSObject {
@UserDefault(key: "enableVoiceBroadcast", defaultValue: false, storage: defaults)
var enableVoiceBroadcast
- #if DEBUG
/// Flag indicating if we are using rust-based `MatrixCryptoSDK` instead of `MatrixSDK`'s internal crypto module
@UserDefault(key: "enableCryptoSDK", defaultValue: false, storage: defaults)
var enableCryptoSDK
- #endif
// MARK: Calls
diff --git a/Riot/Modules/Analytics/Analytics.swift b/Riot/Modules/Analytics/Analytics.swift
index b608c862e1..60e1560b9b 100644
--- a/Riot/Modules/Analytics/Analytics.swift
+++ b/Riot/Modules/Analytics/Analytics.swift
@@ -324,6 +324,11 @@ extension Analytics {
viewRoomTrigger = .unknown
capture(event: event)
}
+
+ func trackCryptoSDKEnabled() {
+ let event = AnalyticsEvent.CryptoSDKEnabled()
+ capture(event: event)
+ }
}
// MARK: - MXAnalyticsDelegate
@@ -393,3 +398,14 @@ extension Analytics: MXAnalyticsDelegate {
monitoringClient.trackNonFatalIssue(issue, details: details)
}
}
+
+/// iOS-specific analytics event triggered when users select the Crypto SDK labs option
+///
+/// Due to this event being iOS only, and temporary during gradual rollout of Crypto SDK,
+/// this event is not added into the shared analytics schema
+extension AnalyticsEvent {
+ struct CryptoSDKEnabled: AnalyticsEventProtocol {
+ let eventName = "CryptoSDKEnabled"
+ let properties: [String: Any] = [:]
+ }
+}
diff --git a/Riot/Modules/Application/AppCoordinator.swift b/Riot/Modules/Application/AppCoordinator.swift
index 19da06b648..faf6867384 100755
--- a/Riot/Modules/Application/AppCoordinator.swift
+++ b/Riot/Modules/Application/AppCoordinator.swift
@@ -14,6 +14,7 @@
limitations under the License.
*/
+import Combine
import Foundation
import Intents
import MatrixSDK
@@ -73,6 +74,8 @@ final class AppCoordinator: NSObject, AppCoordinatorType {
}
private var currentSpaceId: String?
+ private var cancellables: Set = .init()
+ private var pushRulesUpdater: PushRulesUpdater?
// MARK: Public
@@ -99,9 +102,10 @@ final class AppCoordinator: NSObject, AppCoordinatorType {
// MARK: - Public methods
func start() {
- self.setupLogger()
- self.setupTheme()
- self.excludeAllItemsFromBackup()
+ setupLogger()
+ setupTheme()
+ excludeAllItemsFromBackup()
+ setupPushRulesSessionEvents()
// Setup navigation router store
_ = NavigationRouterStore.shared
@@ -305,6 +309,47 @@ final class AppCoordinator: NSObject, AppCoordinatorType {
self.splitViewCoordinator?.start(with: spaceId)
}
+ private func setupPushRulesSessionEvents() {
+ let sessionReady = NotificationCenter.default.publisher(for: .mxSessionStateDidChange)
+ .compactMap { $0.object as? MXSession }
+ .filter { $0.state == .running }
+ .removeDuplicates { session1, session2 in
+ session1 == session2
+ }
+
+ sessionReady
+ .sink { [weak self] session in
+ self?.setupPushRulesUpdater(session: session)
+ }
+ .store(in: &cancellables)
+
+
+ let sessionClosed = NotificationCenter.default.publisher(for: .mxSessionStateDidChange)
+ .compactMap { $0.object as? MXSession }
+ .filter { $0.state == .closed }
+
+ sessionClosed
+ .sink { [weak self] _ in
+ self?.pushRulesUpdater = nil
+ }
+ .store(in: &cancellables)
+ }
+
+ private func setupPushRulesUpdater(session: MXSession) {
+ pushRulesUpdater = .init(notificationSettingsService: MXNotificationSettingsService(session: session))
+
+ let applicationDidBecomeActive = NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification).eraseOutput()
+ let needsCheckPublisher = applicationDidBecomeActive.merge(with: Just(())).eraseToAnyPublisher()
+
+ needsCheckPublisher
+ .sink { _ in
+ Task { @MainActor [weak self] in
+ await self?.pushRulesUpdater?.syncRulesIfNeeded()
+ }
+ }
+ .store(in: &cancellables)
+ }
+
private func presentApplicationUpdate(with versionInfo: ClientVersionInfo) {
guard self.appVersionUpdateCoordinator == nil else {
MXLog.debug("[AppCoordinor] AppVersionUpdateCoordinator already presented")
diff --git a/Riot/Modules/Application/LegacyAppDelegate.m b/Riot/Modules/Application/LegacyAppDelegate.m
index 4dd739982a..9e39bfe566 100644
--- a/Riot/Modules/Application/LegacyAppDelegate.m
+++ b/Riot/Modules/Application/LegacyAppDelegate.m
@@ -2366,6 +2366,9 @@ - (void)logoutSendingRequestServer:(BOOL)sendLogoutServerRequest
// Clear cache
[self clearCache];
+ // Reset Crypto SDK configuration (labs flag for which crypto module to use)
+ [CryptoSDKConfiguration.shared disable];
+
// Reset key backup banner preferences
[SecureBackupBannerPreferences.shared reset];
@@ -2399,9 +2402,6 @@ - (void)logoutSendingRequestServer:(BOOL)sendLogoutServerRequest
// Logout all matrix account
[[MXKAccountManager sharedManager] logoutWithCompletion:^{
- // We reset allChatsOnboardingHasBeenDisplayed flag on logout
- RiotSettings.shared.allChatsOnboardingHasBeenDisplayed = NO;
-
if (completion)
{
completion (YES);
diff --git a/Riot/Modules/Common/Recents/RecentsViewController.m b/Riot/Modules/Common/Recents/RecentsViewController.m
index 191918af0c..8078e48fcc 100644
--- a/Riot/Modules/Common/Recents/RecentsViewController.m
+++ b/Riot/Modules/Common/Recents/RecentsViewController.m
@@ -2784,6 +2784,11 @@ - (UITargetedPreview *)tableView:(UITableView *)tableView previewForDismissingCo
// editedRoomId = nil;
//}
+-(void)roomContextActionServiceDidMarkRoom:(id)service
+{
+ [self refreshRecentsTable];
+}
+
#pragma mark - RecentCellContextMenuProviderDelegate
- (void)recentCellContextMenuProviderDidStartShowingPreview:(RecentCellContextMenuProvider *)menuProvider
diff --git a/Riot/Modules/Common/Recents/Views/RecentTableViewCell.m b/Riot/Modules/Common/Recents/Views/RecentTableViewCell.m
index a2614b3f3f..1662b23a7e 100644
--- a/Riot/Modules/Common/Recents/Views/RecentTableViewCell.m
+++ b/Riot/Modules/Common/Recents/Views/RecentTableViewCell.m
@@ -69,6 +69,7 @@ - (void)render:(MXKCellData *)cellData
self.missedNotifAndUnreadIndicator.hidden = YES;
self.missedNotifAndUnreadBadgeBgView.hidden = YES;
self.missedNotifAndUnreadBadgeBgViewWidthConstraint.constant = 0;
+ self.missedNotifAndUnreadBadgeLabel.text = @"";
roomCellData = (id)cellData;
if (roomCellData)
@@ -91,10 +92,15 @@ - (void)render:(MXKCellData *)cellData
self.lastEventDecriptionLabelTrailingConstraint.constant = self.unsentImageView.hidden ? 10 : 30;
// Notify unreads and bing
- if (roomCellData.hasUnread)
+ if (roomCellData.isRoomMarkedAsUnread)
+ {
+ self.missedNotifAndUnreadBadgeBgView.hidden = NO;
+ self.missedNotifAndUnreadBadgeBgView.backgroundColor = ThemeService.shared.theme.tintColor;
+ self.missedNotifAndUnreadBadgeBgViewWidthConstraint.constant = 20;
+ }
+ else if (roomCellData.hasUnread)
{
self.missedNotifAndUnreadIndicator.hidden = NO;
-
if (0 < roomCellData.notificationCount)
{
self.missedNotifAndUnreadIndicator.backgroundColor = roomCellData.highlightCount ? ThemeService.shared.theme.noticeColor : ThemeService.shared.theme.noticeSecondaryColor;
diff --git a/Riot/Modules/ContextMenu/ActionProviders/RoomActionProvider.swift b/Riot/Modules/ContextMenu/ActionProviders/RoomActionProvider.swift
index 7d12f88780..c019aae9c0 100644
--- a/Riot/Modules/ContextMenu/ActionProviders/RoomActionProvider.swift
+++ b/Riot/Modules/ContextMenu/ActionProviders/RoomActionProvider.swift
@@ -34,7 +34,7 @@ class RoomActionProvider: RoomActionProviderProtocol {
var menu: UIMenu {
if service.isRoomJoined {
- var children = service.hasUnread ? [self.markAsReadAction] : []
+ var children = service.hasUnread ? [self.markAsReadAction] : [self.markAsUnreadAction]
children.append(contentsOf: [
self.directChatAction,
self.notificationsAction,
@@ -113,6 +113,14 @@ class RoomActionProvider: RoomActionProviderProtocol {
self.service.markAsRead()
}
}
+ private var markAsUnreadAction: UIAction {
+ return UIAction(
+ title: VectorL10n.homeContextMenuMarkAsUnread,
+ image: UIImage(systemName: "envelope.badge")) { [weak self] action in
+ guard let self = self else { return }
+ self.service.markAsUnread()
+ }
+ }
private var leaveAction: UIAction {
let image = UIImage(systemName: "rectangle.righthalf.inset.fill.arrow.right")
diff --git a/Riot/Modules/ContextMenu/Services/RoomContextActionService.swift b/Riot/Modules/ContextMenu/Services/RoomContextActionService.swift
index c3abab55b8..12c02c9381 100644
--- a/Riot/Modules/ContextMenu/Services/RoomContextActionService.swift
+++ b/Riot/Modules/ContextMenu/Services/RoomContextActionService.swift
@@ -38,7 +38,7 @@ class RoomContextActionService: NSObject, RoomContextActionServiceProtocol {
self.room = room
self.delegate = delegate
self.isRoomJoined = room.summary?.isJoined ?? false
- self.hasUnread = room.summary?.hasAnyUnread ?? false
+ self.hasUnread = (room.summary?.hasAnyUnread ?? false) || room.isMarkedAsUnread
self.roomMembership = room.summary?.membership ?? .unknown
self.session = room.mxSession
self.unownedRoomService = UnownedRoomContextActionService(roomId: room.roomId, canonicalAlias: room.summary?.aliases?.first, session: self.session, delegate: delegate)
@@ -108,6 +108,11 @@ class RoomContextActionService: NSObject, RoomContextActionServiceProtocol {
func markAsRead() {
room.markAllAsRead()
+ self.delegate?.roomContextActionServiceDidMarkRoom(self)
+ }
+ func markAsUnread() {
+ room.setUnread()
+ self.delegate?.roomContextActionServiceDidMarkRoom(self)
}
// MARK: - Private
diff --git a/Riot/Modules/ContextMenu/Services/RoomContextActionServiceProtocol.swift b/Riot/Modules/ContextMenu/Services/RoomContextActionServiceProtocol.swift
index d44213bd4e..25c66773f0 100644
--- a/Riot/Modules/ContextMenu/Services/RoomContextActionServiceProtocol.swift
+++ b/Riot/Modules/ContextMenu/Services/RoomContextActionServiceProtocol.swift
@@ -22,6 +22,7 @@ import Foundation
func roomContextActionService(_ service: RoomContextActionServiceProtocol, showRoomNotificationSettingsForRoomWithId roomId: String)
func roomContextActionServiceDidJoinRoom(_ service: RoomContextActionServiceProtocol)
func roomContextActionServiceDidLeaveRoom(_ service: RoomContextActionServiceProtocol)
+ func roomContextActionServiceDidMarkRoom(_ service: RoomContextActionServiceProtocol)
}
/// `RoomContextActionServiceProtocol` classes are meant to be called by a `RoomActionProviderProtocol` instance so it provides the implementation of the menu actions.
diff --git a/Riot/Modules/Home/AllChats/AllChatsViewController.swift b/Riot/Modules/Home/AllChats/AllChatsViewController.swift
index ede8da3b05..7cf0ddfc29 100644
--- a/Riot/Modules/Home/AllChats/AllChatsViewController.swift
+++ b/Riot/Modules/Home/AllChats/AllChatsViewController.swift
@@ -73,8 +73,6 @@ class AllChatsViewController: HomeViewController {
private var isOnboardingCoordinatorPreparing: Bool = false
- private var allChatsOnboardingCoordinatorBridgePresenter: AllChatsOnboardingCoordinatorBridgePresenter?
-
private var theme: Theme {
ThemeService.shared().theme
}
@@ -208,7 +206,7 @@ class AllChatsViewController: HomeViewController {
searchController.isActive = false
guard let spaceId = spaceId else {
- self.dataSource?.currentSpace = nil
+ dataSource?.currentSpace = nil
updateUI()
return
@@ -219,7 +217,7 @@ class AllChatsViewController: HomeViewController {
return
}
- self.dataSource.currentSpace = space
+ dataSource?.currentSpace = space
updateUI()
self.recentsTableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
@@ -303,7 +301,7 @@ class AllChatsViewController: HomeViewController {
@objc private func showSpaceSelectorAction(sender: AnyObject) {
Analytics.shared.viewRoomTrigger = .roomList
- let currentSpaceId = self.dataSource.currentSpace?.spaceId ?? SpaceSelectorConstants.homeSpaceId
+ let currentSpaceId = dataSource?.currentSpace?.spaceId ?? SpaceSelectorConstants.homeSpaceId
let spaceSelectorBridgePresenter = SpaceSelectorBottomSheetCoordinatorBridgePresenter(session: self.mainSession, selectedSpaceId: currentSpaceId, showHomeSpace: true)
spaceSelectorBridgePresenter.present(from: self, animated: true)
spaceSelectorBridgePresenter.delegate = self
@@ -325,7 +323,7 @@ class AllChatsViewController: HomeViewController {
return super.tableView(tableView, numberOfRowsInSection: section)
}
- return dataSource.tableView(tableView, numberOfRowsInSection: section)
+ return dataSource?.tableView(tableView, numberOfRowsInSection: section) ?? 0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
@@ -333,6 +331,10 @@ class AllChatsViewController: HomeViewController {
return super.tableView(tableView, cellForRowAt: indexPath)
}
+ guard let dataSource = dataSource else {
+ MXLog.failure("Missing data source")
+ return UITableViewCell()
+ }
return dataSource.tableView(tableView, cellForRowAt: indexPath)
}
@@ -343,7 +345,7 @@ class AllChatsViewController: HomeViewController {
return super.tableView(tableView, heightForRowAt: indexPath)
}
- return dataSource.cellHeight(at: indexPath)
+ return dataSource?.cellHeight(at: indexPath) ?? 0
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
@@ -607,7 +609,7 @@ class AllChatsViewController: HomeViewController {
}
private func showSpaceInvite() {
- guard let session = mainSession, let spaceRoom = dataSource.currentSpace?.room else {
+ guard let session = mainSession, let spaceRoom = dataSource?.currentSpace?.room else {
return
}
@@ -619,7 +621,7 @@ class AllChatsViewController: HomeViewController {
}
private func showSpaceMembers() {
- guard let session = mainSession, let spaceId = dataSource.currentSpace?.spaceId else {
+ guard let session = mainSession, let spaceId = dataSource?.currentSpace?.spaceId else {
return
}
@@ -633,7 +635,7 @@ class AllChatsViewController: HomeViewController {
}
private func showSpaceSettings() {
- guard let session = mainSession, let spaceId = dataSource.currentSpace?.spaceId else {
+ guard let session = mainSession, let spaceId = dataSource?.currentSpace?.spaceId else {
return
}
@@ -654,7 +656,7 @@ class AllChatsViewController: HomeViewController {
}
private func showLeaveSpace() {
- guard let session = mainSession, let spaceSummary = dataSource.currentSpace?.summary else {
+ guard let session = mainSession, let spaceSummary = dataSource?.currentSpace?.summary else {
return
}
@@ -692,20 +694,6 @@ class AllChatsViewController: HomeViewController {
self.navigationController?.pushViewController(invitesViewController, animated: true)
}
- private func showAllChatsOnboardingScreen() {
- let allChatsOnboardingCoordinatorBridgePresenter = AllChatsOnboardingCoordinatorBridgePresenter()
- allChatsOnboardingCoordinatorBridgePresenter.completion = { [weak self] in
- RiotSettings.shared.allChatsOnboardingHasBeenDisplayed = true
-
- guard let self = self else { return }
- self.allChatsOnboardingCoordinatorBridgePresenter?.dismiss(animated: true, completion: {
- self.allChatsOnboardingCoordinatorBridgePresenter = nil
- })
- }
-
- allChatsOnboardingCoordinatorBridgePresenter.present(from: self, animated: true)
- self.allChatsOnboardingCoordinatorBridgePresenter = allChatsOnboardingCoordinatorBridgePresenter
- }
}
private extension AllChatsViewController {
@@ -752,11 +740,11 @@ extension AllChatsViewController: SpaceSelectorBottomSheetCoordinatorBridgePrese
extension AllChatsViewController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
guard let searchText = searchController.searchBar.text, !searchText.isEmpty else {
- self.dataSource.search(withPatterns: nil)
+ self.dataSource?.search(withPatterns: nil)
return
}
- self.dataSource.search(withPatterns: [searchText])
+ self.dataSource?.search(withPatterns: [searchText])
}
}
@@ -792,7 +780,7 @@ extension AllChatsViewController: AllChatsEditActionProviderDelegate {
case .startChat:
startChat()
case .createSpace:
- showCreateSpace(parentSpaceId: dataSource.currentSpace?.spaceId)
+ showCreateSpace(parentSpaceId: dataSource?.currentSpace?.spaceId)
}
}
@@ -911,10 +899,12 @@ extension AllChatsViewController: SplitViewMasterViewControllerProtocol {
return
}
- let devices = mainSession.crypto.devices(forUser: mainSession.myUserId).values
- let userHasOneUnverifiedDevice = devices.contains(where: {!$0.trustLevel.isCrossSigningVerified})
- if userHasOneUnverifiedDevice {
- presentReviewUnverifiedSessionsAlert(with: session)
+ if let userId = mainSession.myUserId, let crypto = mainSession.crypto {
+ let devices = crypto.devices(forUser: userId).values
+ let userHasOneUnverifiedDevice = devices.contains(where: {!$0.trustLevel.isCrossSigningVerified})
+ if userHasOneUnverifiedDevice {
+ presentReviewUnverifiedSessionsAlert(with: session)
+ }
}
}
diff --git a/Riot/Modules/KeyBackup/Recover/PrivateKey/KeyBackupRecoverFromPrivateKeyViewController.storyboard b/Riot/Modules/KeyBackup/Recover/PrivateKey/KeyBackupRecoverFromPrivateKeyViewController.storyboard
index 1c8ba341c8..42e99205e5 100644
--- a/Riot/Modules/KeyBackup/Recover/PrivateKey/KeyBackupRecoverFromPrivateKeyViewController.storyboard
+++ b/Riot/Modules/KeyBackup/Recover/PrivateKey/KeyBackupRecoverFromPrivateKeyViewController.storyboard
@@ -1,25 +1,23 @@
-
-
-
-
+
+
-
+
-
+
-
+
-
+
@@ -40,15 +38,24 @@
+
+
+
+
@@ -72,6 +79,7 @@
+
@@ -79,10 +87,10 @@
-
+
diff --git a/Riot/Modules/KeyBackup/Recover/PrivateKey/KeyBackupRecoverFromPrivateKeyViewController.swift b/Riot/Modules/KeyBackup/Recover/PrivateKey/KeyBackupRecoverFromPrivateKeyViewController.swift
index bdd616d12a..cc44e01e4b 100644
--- a/Riot/Modules/KeyBackup/Recover/PrivateKey/KeyBackupRecoverFromPrivateKeyViewController.swift
+++ b/Riot/Modules/KeyBackup/Recover/PrivateKey/KeyBackupRecoverFromPrivateKeyViewController.swift
@@ -29,6 +29,7 @@ final class KeyBackupRecoverFromPrivateKeyViewController: UIViewController {
@IBOutlet private weak var shieldImageView: UIImageView!
@IBOutlet private weak var informationLabel: UILabel!
+ @IBOutlet private weak var progressLabel: UILabel!
// MARK: Private
@@ -118,8 +119,8 @@ final class KeyBackupRecoverFromPrivateKeyViewController: UIViewController {
private func render(viewState: KeyBackupRecoverFromPrivateKeyViewState) {
switch viewState {
- case .loading:
- self.renderLoading()
+ case .loading(let progress):
+ self.renderLoading(progress: progress)
case .loaded:
self.renderLoaded()
case .error(let error):
@@ -127,8 +128,11 @@ final class KeyBackupRecoverFromPrivateKeyViewController: UIViewController {
}
}
- private func renderLoading() {
+ private func renderLoading(progress: Double) {
self.activityPresenter.presentActivityIndicator(on: self.view, animated: true)
+
+ let percent = Int(round(progress * 100))
+ self.progressLabel.text = VectorL10n.keyBackupRecoverFromPrivateKeyProgress("\(percent)")
}
private func renderLoaded() {
diff --git a/Riot/Modules/KeyBackup/Recover/PrivateKey/KeyBackupRecoverFromPrivateKeyViewModel.swift b/Riot/Modules/KeyBackup/Recover/PrivateKey/KeyBackupRecoverFromPrivateKeyViewModel.swift
index cef1d7c0cc..04fb48850f 100644
--- a/Riot/Modules/KeyBackup/Recover/PrivateKey/KeyBackupRecoverFromPrivateKeyViewModel.swift
+++ b/Riot/Modules/KeyBackup/Recover/PrivateKey/KeyBackupRecoverFromPrivateKeyViewModel.swift
@@ -27,6 +27,7 @@ final class KeyBackupRecoverFromPrivateKeyViewModel: KeyBackupRecoverFromPrivate
private let keyBackup: MXKeyBackup
private var currentHTTPOperation: MXHTTPOperation?
private let keyBackupVersion: MXKeyBackupVersion
+ private var progressUpdateTimer: Timer?
// MARK: Public
@@ -56,7 +57,14 @@ final class KeyBackupRecoverFromPrivateKeyViewModel: KeyBackupRecoverFromPrivate
private func recoverWithPrivateKey() {
- self.update(viewState: .loading)
+ self.update(viewState: .loading(0))
+
+ // Update loading progress every second until no longer loading
+ progressUpdateTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] _ in
+ if let progress = self?.keyBackup.importProgress {
+ self?.update(viewState: .loading(progress.fractionCompleted))
+ }
+ }
self.currentHTTPOperation = keyBackup.restore(usingPrivateKeyKeyBackup: keyBackupVersion, room: nil, session: nil, success: { [weak self] (_, _) in
guard let self = self else {
@@ -91,6 +99,11 @@ final class KeyBackupRecoverFromPrivateKeyViewModel: KeyBackupRecoverFromPrivate
}
private func update(viewState: KeyBackupRecoverFromPrivateKeyViewState) {
+ if case .loading = viewState {} else {
+ progressUpdateTimer?.invalidate()
+ progressUpdateTimer = nil
+ }
+
self.viewDelegate?.keyBackupRecoverFromPrivateKeyViewModel(self, didUpdateViewState: viewState)
}
}
diff --git a/Riot/Modules/KeyBackup/Recover/PrivateKey/KeyBackupRecoverFromPrivateKeyViewState.swift b/Riot/Modules/KeyBackup/Recover/PrivateKey/KeyBackupRecoverFromPrivateKeyViewState.swift
index bdd4178534..b4ef05fb94 100644
--- a/Riot/Modules/KeyBackup/Recover/PrivateKey/KeyBackupRecoverFromPrivateKeyViewState.swift
+++ b/Riot/Modules/KeyBackup/Recover/PrivateKey/KeyBackupRecoverFromPrivateKeyViewState.swift
@@ -20,7 +20,7 @@ import Foundation
/// KeyBackupRecoverFromPrivateKeyViewController view state
enum KeyBackupRecoverFromPrivateKeyViewState {
- case loading
+ case loading(Double)
case loaded
case error(Error)
}
diff --git a/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitCoordinator.swift b/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitCoordinator.swift
index 88c2537db9..68dcab40e7 100644
--- a/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitCoordinator.swift
+++ b/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitCoordinator.swift
@@ -25,7 +25,6 @@ final class KeyVerificationSelfVerifyWaitCoordinator: KeyVerificationSelfVerifyW
// MARK: Private
- private let session: MXSession
private var keyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWaitViewModelType
private let keyVerificationSelfVerifyWaitViewController: KeyVerificationSelfVerifyWaitViewController
private let cancellable: Bool
@@ -40,9 +39,7 @@ final class KeyVerificationSelfVerifyWaitCoordinator: KeyVerificationSelfVerifyW
// MARK: - Setup
init(session: MXSession, isNewSignIn: Bool, cancellable: Bool) {
- self.session = session
-
- let keyVerificationSelfVerifyWaitViewModel = KeyVerificationSelfVerifyWaitViewModel(session: self.session, isNewSignIn: isNewSignIn)
+ let keyVerificationSelfVerifyWaitViewModel = KeyVerificationSelfVerifyWaitViewModel(session: session, isNewSignIn: isNewSignIn)
let keyVerificationSelfVerifyWaitViewController = KeyVerificationSelfVerifyWaitViewController.instantiate(with: keyVerificationSelfVerifyWaitViewModel, cancellable: cancellable)
self.keyVerificationSelfVerifyWaitViewModel = keyVerificationSelfVerifyWaitViewModel
self.keyVerificationSelfVerifyWaitViewController = keyVerificationSelfVerifyWaitViewController
diff --git a/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewModel.swift b/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewModel.swift
index b064d4f84b..5d4830bede 100644
--- a/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewModel.swift
+++ b/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewModel.swift
@@ -26,11 +26,19 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
private let session: MXSession
private let keyVerificationService: KeyVerificationService
- private let verificationManager: MXKeyVerificationManager
+ private let verificationManager: MXKeyVerificationManager?
private let isNewSignIn: Bool
- private var secretsRecoveryAvailability: SecretsRecoveryAvailability
+ private var secretsRecoveryAvailability: SecretsRecoveryAvailability?
private var keyVerificationRequest: MXKeyVerificationRequest?
+ private var myUserId: String {
+ guard let userId = session.myUserId else {
+ MXLog.error("[KeyVerificationSelfVerifyWaitViewModel] userId is missing")
+ return ""
+ }
+ return userId
+ }
+
// MARK: Public
weak var viewDelegate: KeyVerificationSelfVerifyWaitViewModelViewDelegate?
@@ -40,10 +48,10 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
init(session: MXSession, isNewSignIn: Bool) {
self.session = session
- self.verificationManager = session.crypto.keyVerificationManager
+ self.verificationManager = session.crypto?.keyVerificationManager
self.keyVerificationService = KeyVerificationService()
self.isNewSignIn = isNewSignIn
- self.secretsRecoveryAvailability = session.crypto.recoveryService.vc_availability
+ self.secretsRecoveryAvailability = session.crypto?.recoveryService.vc_availability
}
deinit {
@@ -59,9 +67,16 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
case .cancel:
self.cancel()
case .recoverSecrets:
- switch self.secretsRecoveryAvailability {
+ guard let availability = secretsRecoveryAvailability else {
+ MXLog.error("[KeyVerificationSelfVerifyWaitViewModel] process: secretsRecoveryAvailability not set")
+ self.cancel()
+ return
+ }
+
+ switch availability {
case .notAvailable:
- fatalError("Should not happen: When recovery is not available button is hidden")
+ MXLog.error("Should not happen: When recovery is not available button is hidden")
+ self.cancel()
case .available(let secretsRecoveryMode):
self.coordinatorDelegate?.keyVerificationSelfVerifyWaitViewModel(self, wantsToRecoverSecretsWith: secretsRecoveryMode)
}
@@ -71,12 +86,16 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
// MARK: - Private
private func loadData() {
+ guard let verificationManager = verificationManager else {
+ MXLog.failure("Verification manager is not set")
+ return
+ }
if !self.isNewSignIn {
MXLog.debug("[KeyVerificationSelfVerifyWaitViewModel] loadData: Send a verification request to all devices")
let keyVerificationService = KeyVerificationService()
- self.verificationManager.requestVerificationByToDevice(withUserId: self.session.myUserId, deviceIds: nil, methods: keyVerificationService.supportedKeyVerificationMethods(), success: { [weak self] (keyVerificationRequest) in
+ verificationManager.requestVerificationByToDevice(withUserId: self.myUserId, deviceIds: nil, methods: keyVerificationService.supportedKeyVerificationMethods(), success: { [weak self] (keyVerificationRequest) in
guard let self = self else {
return
}
@@ -103,7 +122,7 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
MXLog.debug("[KeyVerificationSelfVerifyWaitViewModel] loadData: Send a verification request to all devices instead of waiting")
let keyVerificationService = KeyVerificationService()
- self.verificationManager.requestVerificationByToDevice(withUserId: self.session.myUserId, deviceIds: nil, methods: keyVerificationService.supportedKeyVerificationMethods(), success: { [weak self] (keyVerificationRequest) in
+ verificationManager.requestVerificationByToDevice(withUserId: self.myUserId, deviceIds: nil, methods: keyVerificationService.supportedKeyVerificationMethods(), success: { [weak self] (keyVerificationRequest) in
guard let self = self else {
return
}
@@ -132,12 +151,18 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
}
private func continueLoadData() {
+ guard let verificationManager = verificationManager, let recoveryService = session.crypto?.recoveryService else {
+ MXLog.error("[KeyVerificationSelfVerifyWaitViewModel] continueLoadData: Missing dependencies")
+ return
+ }
+
// update availability again
- self.secretsRecoveryAvailability = session.crypto.recoveryService.vc_availability
+ let availability = recoveryService.vc_availability
+ self.secretsRecoveryAvailability = availability
- let viewData = KeyVerificationSelfVerifyWaitViewData(isNewSignIn: self.isNewSignIn, secretsRecoveryAvailability: self.secretsRecoveryAvailability)
+ let viewData = KeyVerificationSelfVerifyWaitViewData(isNewSignIn: self.isNewSignIn, secretsRecoveryAvailability: availability)
- self.registerKeyVerificationManagerNewRequestNotification(for: self.verificationManager)
+ self.registerKeyVerificationManagerNewRequestNotification(for: verificationManager)
self.update(viewState: .loaded(viewData))
self.registerTransactionDidStateChangeNotification()
self.registerKeyVerificationRequestChangeNotification()
@@ -251,7 +276,7 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
@objc private func transactionDidStateChange(notification: Notification) {
guard let sasTransaction = notification.object as? MXSASTransaction,
- sasTransaction.isIncoming, sasTransaction.otherUserId == self.session.myUserId else {
+ sasTransaction.isIncoming, sasTransaction.otherUserId == self.myUserId else {
return
}
self.sasTransactionDidStateChange(sasTransaction)
diff --git a/Riot/Modules/MatrixKit/Controllers/MXKNotificationSettingsViewController.m b/Riot/Modules/MatrixKit/Controllers/MXKNotificationSettingsViewController.m
index 1524eb2d75..7007c12bfa 100644
--- a/Riot/Modules/MatrixKit/Controllers/MXKNotificationSettingsViewController.m
+++ b/Riot/Modules/MatrixKit/Controllers/MXKNotificationSettingsViewController.m
@@ -193,7 +193,7 @@ - (IBAction)onButtonPressed:(id)sender
MXPushRule *pushRule = [_mxAccount.mxSession.notificationCenter ruleById:kMXNotificationCenterDisableAllNotificationsRuleID];
if (pushRule)
{
- [_mxAccount.mxSession.notificationCenter enableRule:pushRule isEnabled:!areAllDisabled];
+ [_mxAccount.mxSession.notificationCenter enableRule:pushRule isEnabled:!areAllDisabled completion:nil];
}
}
}
diff --git a/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSource.m b/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSource.m
index 5f33af838e..0998122aef 100644
--- a/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSource.m
+++ b/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSource.m
@@ -2150,7 +2150,10 @@ - (void)resendEventWithEventId:(NSString *)eventId success:(void (^)(NSString *)
}
else
{
- failure([NSError errorWithDomain:MXKRoomDataSourceErrorDomain code:MXKRoomDataSourceErrorResendGeneric userInfo:nil]);
+ if (failure)
+ {
+ failure([NSError errorWithDomain:MXKRoomDataSourceErrorDomain code:MXKRoomDataSourceErrorResendGeneric userInfo:nil]);
+ }
MXLogWarning(@"[MXKRoomDataSource][%p] resendEventWithEventId: Warning - Unable to resend room message of type: %@", self, msgType);
}
}
@@ -2177,7 +2180,10 @@ - (void)resendEventWithEventId:(NSString *)eventId success:(void (^)(NSString *)
NSURL *localFileURL = [NSURL URLWithString:localFilePath];
if (![NSFileManager.defaultManager fileExistsAtPath:localFilePath]) {
- failure([NSError errorWithDomain:MXKRoomDataSourceErrorDomain code:MXKRoomDataSourceErrorResendInvalidLocalFilePath userInfo:nil]);
+ if (failure)
+ {
+ failure([NSError errorWithDomain:MXKRoomDataSourceErrorDomain code:MXKRoomDataSourceErrorResendInvalidLocalFilePath userInfo:nil]);
+ }
MXLogWarning(@"[MXKRoomDataSource][%p] resendEventWithEventId: Warning - Unable to resend voice message, invalid file path.", self);
return;
}
@@ -2247,7 +2253,10 @@ - (void)resendEventWithEventId:(NSString *)eventId success:(void (^)(NSString *)
}
else
{
- failure([NSError errorWithDomain:MXKRoomDataSourceErrorDomain code:MXKRoomDataSourceErrorResendGeneric userInfo:nil]);
+ if (failure)
+ {
+ failure([NSError errorWithDomain:MXKRoomDataSourceErrorDomain code:MXKRoomDataSourceErrorResendGeneric userInfo:nil]);
+ }
MXLogWarning(@"[MXKRoomDataSource][%p] resendEventWithEventId: Warning - Unable to resend room message of type: %@", self, msgType);
}
}
@@ -2259,13 +2268,19 @@ - (void)resendEventWithEventId:(NSString *)eventId success:(void (^)(NSString *)
}
else
{
- failure([NSError errorWithDomain:MXKRoomDataSourceErrorDomain code:MXKRoomDataSourceErrorResendInvalidMessageType userInfo:nil]);
+ if (failure)
+ {
+ failure([NSError errorWithDomain:MXKRoomDataSourceErrorDomain code:MXKRoomDataSourceErrorResendInvalidMessageType userInfo:nil]);
+ }
MXLogWarning(@"[MXKRoomDataSource][%p] resendEventWithEventId: Warning - Unable to resend room message of type: %@", self, msgType);
}
}
else
{
- failure([NSError errorWithDomain:MXKRoomDataSourceErrorDomain code:MXKRoomDataSourceErrorResendInvalidMessageType userInfo:nil]);
+ if (failure)
+ {
+ failure([NSError errorWithDomain:MXKRoomDataSourceErrorDomain code:MXKRoomDataSourceErrorResendInvalidMessageType userInfo:nil]);
+ }
MXLogWarning(@"[MXKRoomDataSource][%p] MXKRoomDataSource: Warning - Only resend of MXEventTypeRoomMessage is allowed. Event.type: %@", self, event.type);
}
}
diff --git a/Riot/Modules/MatrixKit/Models/RoomList/MXKRecentCellData.m b/Riot/Modules/MatrixKit/Models/RoomList/MXKRecentCellData.m
index 958e316fa0..474494d59c 100644
--- a/Riot/Modules/MatrixKit/Models/RoomList/MXKRecentCellData.m
+++ b/Riot/Modules/MatrixKit/Models/RoomList/MXKRecentCellData.m
@@ -66,6 +66,11 @@ - (BOOL)hasUnread
return (roomSummary.localUnreadEventCount != 0);
}
+- (BOOL)isRoomMarkedAsUnread
+{
+ return [[self mxSession] isRoomMarkedAsUnread:roomSummary.roomId];;
+}
+
- (NSString *)roomIdentifier
{
if (self.isSuggestedRoom)
diff --git a/Riot/Modules/MatrixKit/Models/RoomList/MXKRecentCellDataStoring.h b/Riot/Modules/MatrixKit/Models/RoomList/MXKRecentCellDataStoring.h
index 7185ae4eb5..3c417c1faa 100644
--- a/Riot/Modules/MatrixKit/Models/RoomList/MXKRecentCellDataStoring.h
+++ b/Riot/Modules/MatrixKit/Models/RoomList/MXKRecentCellDataStoring.h
@@ -50,6 +50,7 @@
@property (nonatomic, readonly) NSString *lastEventDate;
@property (nonatomic, readonly) BOOL hasUnread;
+@property (nonatomic, readonly) BOOL isRoomMarkedAsUnread;
@property (nonatomic, readonly) NSUInteger notificationCount;
@property (nonatomic, readonly) NSUInteger highlightCount;
@property (nonatomic, readonly) NSString *notificationCountStringValue;
diff --git a/Riot/Modules/MatrixKit/Utils/EventFormatter/HTMLFormatter.swift b/Riot/Modules/MatrixKit/Utils/EventFormatter/HTMLFormatter.swift
index 6c7e43a90a..819eb632fd 100644
--- a/Riot/Modules/MatrixKit/Utils/EventFormatter/HTMLFormatter.swift
+++ b/Riot/Modules/MatrixKit/Utils/EventFormatter/HTMLFormatter.swift
@@ -47,9 +47,7 @@ class HTMLFormatter: NSObject {
var options: [AnyHashable: Any] = [
DTUseiOS6Attributes: true,
- DTDefaultFontFamily: font.familyName,
- DTDefaultFontName: font.fontName,
- DTDefaultFontSize: font.pointSize,
+ DTDefaultFontDescriptor: font.fontDescriptor,
DTDefaultLinkDecoration: false,
DTDefaultLinkColor: ThemeService.shared().theme.colors.links,
DTWillFlushBlockCallBack: sanitizeCallback
diff --git a/Riot/Modules/MatrixKit/Utils/EventFormatter/MXKEventFormatter.m b/Riot/Modules/MatrixKit/Utils/EventFormatter/MXKEventFormatter.m
index 422e089902..da231c119b 100644
--- a/Riot/Modules/MatrixKit/Utils/EventFormatter/MXKEventFormatter.m
+++ b/Riot/Modules/MatrixKit/Utils/EventFormatter/MXKEventFormatter.m
@@ -1053,8 +1053,22 @@ - (NSAttributedString *)attributedStringFromEvent:(MXEvent*)event
else if ([event.decryptionError.domain isEqualToString:MXDecryptingErrorDomain]
&& event.decryptionError.code == MXDecryptingErrorUnknownInboundSessionIdCode)
{
- // Make the unknown inbound session id error description more user friendly
- errorDescription = [VectorL10n noticeCryptoErrorUnknownInboundSessionId];
+ // Hide the decryption error for VoiceBroadcast chunks
+ BOOL isVoiceBroadcastChunk = NO;
+ if ([event.relatesTo.relationType isEqualToString:MXEventRelationTypeReference]) {
+ MXEvent *startEvent = [mxSession.store eventWithEventId:event.relatesTo.eventId
+ inRoom:event.roomId];
+
+ if (startEvent) {
+ isVoiceBroadcastChunk = (startEvent.eventType == MXEventTypeCustom && [startEvent.type isEqualToString:VoiceBroadcastSettings.voiceBroadcastInfoContentKeyType]);
+ }
+ }
+ if (isVoiceBroadcastChunk) {
+ displayText = nil;
+ } else {
+ // Make the unknown inbound session id error description more user friendly
+ errorDescription = [VectorL10n noticeCryptoErrorUnknownInboundSessionId];
+ }
}
else if ([event.decryptionError.domain isEqualToString:MXDecryptingErrorDomain]
&& event.decryptionError.code == MXDecryptingErrorDuplicateMessageIndexCode)
diff --git a/Riot/Modules/MatrixKit/Views/PushRule/MXKPushRuleTableViewCell.m b/Riot/Modules/MatrixKit/Views/PushRule/MXKPushRuleTableViewCell.m
index a65174564e..79632d87ce 100644
--- a/Riot/Modules/MatrixKit/Views/PushRule/MXKPushRuleTableViewCell.m
+++ b/Riot/Modules/MatrixKit/Views/PushRule/MXKPushRuleTableViewCell.m
@@ -163,7 +163,7 @@ - (IBAction)onButtonPressed:(id)sender
if (sender == _controlButton)
{
// Swap enable state
- [_mxSession.notificationCenter enableRule:_mxPushRule isEnabled:!_mxPushRule.enabled];
+ [_mxSession.notificationCenter enableRule:_mxPushRule isEnabled:!_mxPushRule.enabled completion:nil];
}
else if (sender == _deleteButton)
{
diff --git a/Riot/Modules/Room/MXKRoomViewController.m b/Riot/Modules/Room/MXKRoomViewController.m
index 9d8755a2ba..752dc71c85 100644
--- a/Riot/Modules/Room/MXKRoomViewController.m
+++ b/Riot/Modules/Room/MXKRoomViewController.m
@@ -370,6 +370,11 @@ - (void)viewDidAppear:(BOOL)animated
[self.roomDataSource.room.summary markAllAsReadLocally];
[self updateCurrentEventIdAtTableBottom:YES];
+
+ if (!self.isContextPreview)
+ {
+ [self.roomDataSource.room resetUnread];
+ }
}
- (void)viewWillDisappear:(BOOL)animated
diff --git a/Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift b/Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift
index 04972e6ae1..ac694dc49f 100644
--- a/Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift
+++ b/Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift
@@ -176,8 +176,12 @@ final class RoomInfoCoordinator: NSObject, RoomInfoCoordinatorType {
coordinator.start()
push(coordinator: coordinator)
case .pollHistory:
- let coordinator: PollHistoryCoordinator = .init(parameters: .init(mode: .active))
+ let coordinator: PollHistoryCoordinator = .init(parameters: .init(mode: .active, room: room, navigationRouter: navigationRouter))
coordinator.start()
+ coordinator.completion = { [weak self] event in
+ guard let self else { return }
+ self.delegate?.roomInfoCoordinator(self, viewEventInTimeline: event)
+ }
push(coordinator: coordinator)
default:
guard let tabIndex = target.tabIndex else {
diff --git a/Riot/Modules/Room/RoomInfo/RoomInfoCoordinatorBridgePresenter.swift b/Riot/Modules/Room/RoomInfo/RoomInfoCoordinatorBridgePresenter.swift
index b8db2a66a8..39e740bfcc 100644
--- a/Riot/Modules/Room/RoomInfo/RoomInfoCoordinatorBridgePresenter.swift
+++ b/Riot/Modules/Room/RoomInfo/RoomInfoCoordinatorBridgePresenter.swift
@@ -17,12 +17,14 @@
*/
import Foundation
+import MatrixSDK
@objc protocol RoomInfoCoordinatorBridgePresenterDelegate {
func roomInfoCoordinatorBridgePresenterDelegateDidComplete(_ coordinatorBridgePresenter: RoomInfoCoordinatorBridgePresenter)
func roomInfoCoordinatorBridgePresenter(_ coordinatorBridgePresenter: RoomInfoCoordinatorBridgePresenter, didRequestMentionForMember member: MXRoomMember)
func roomInfoCoordinatorBridgePresenterDelegateDidLeaveRoom(_ coordinatorBridgePresenter: RoomInfoCoordinatorBridgePresenter)
func roomInfoCoordinatorBridgePresenter(_ coordinatorBridgePresenter: RoomInfoCoordinatorBridgePresenter, didReplaceRoomWithReplacementId roomId: String)
+ func roomInfoCoordinatorBridgePresenter(_ coordinator: RoomInfoCoordinatorBridgePresenter, viewEventInTimeline event: MXEvent)
}
/// RoomInfoCoordinatorBridgePresenter enables to start RoomInfoCoordinator from a view controller.
@@ -129,6 +131,9 @@ extension RoomInfoCoordinatorBridgePresenter: RoomInfoCoordinatorDelegate {
func roomInfoCoordinator(_ coordinator: RoomInfoCoordinatorType, didReplaceRoomWithReplacementId roomId: String) {
self.delegate?.roomInfoCoordinatorBridgePresenter(self, didReplaceRoomWithReplacementId: roomId)
}
+ func roomInfoCoordinator(_ coordinator: RoomInfoCoordinatorType, viewEventInTimeline event: MXEvent) {
+ self.delegate?.roomInfoCoordinatorBridgePresenter(self, viewEventInTimeline: event)
+ }
}
// MARK: - UIAdaptivePresentationControllerDelegate
diff --git a/Riot/Modules/Room/RoomInfo/RoomInfoCoordinatorType.swift b/Riot/Modules/Room/RoomInfo/RoomInfoCoordinatorType.swift
index 80f696b0bf..2122ddf1df 100644
--- a/Riot/Modules/Room/RoomInfo/RoomInfoCoordinatorType.swift
+++ b/Riot/Modules/Room/RoomInfo/RoomInfoCoordinatorType.swift
@@ -17,12 +17,14 @@
*/
import Foundation
+import MatrixSDK
protocol RoomInfoCoordinatorDelegate: AnyObject {
func roomInfoCoordinatorDidComplete(_ coordinator: RoomInfoCoordinatorType)
func roomInfoCoordinator(_ coordinator: RoomInfoCoordinatorType, didRequestMentionForMember member: MXRoomMember)
func roomInfoCoordinatorDidLeaveRoom(_ coordinator: RoomInfoCoordinatorType)
func roomInfoCoordinator(_ coordinator: RoomInfoCoordinatorType, didReplaceRoomWithReplacementId roomId: String)
+ func roomInfoCoordinator(_ coordinator: RoomInfoCoordinatorType, viewEventInTimeline event: MXEvent)
}
/// `RoomInfoCoordinatorType` is a protocol describing a Coordinator that handle keybackup setup navigation flow.
diff --git a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewController.swift b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewController.swift
index d2646ed3d3..93df4d701d 100644
--- a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewController.swift
+++ b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewController.swift
@@ -205,7 +205,7 @@ final class RoomInfoListViewController: UIViewController {
rows.append(rowMembers)
}
- if BuildSettings.pollsHistoryEnabled {
+ if BuildSettings.pollsEnabled {
rows.append(rowPollHistory)
}
diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m
index e8b5e61550..f391bc8636 100644
--- a/Riot/Modules/Room/RoomViewController.m
+++ b/Riot/Modules/Room/RoomViewController.m
@@ -5286,25 +5286,9 @@ - (IBAction)onButtonPressed:(id)sender
{
// Dismiss potential keyboard.
[self dismissKeyboard];
-
- // Jump to the last unread event by using a temporary room data source initialized with the last unread event id.
- MXWeakify(self);
- [RoomDataSource loadRoomDataSourceWithRoomId:self.roomDataSource.roomId
- initialEventId:self.roomDataSource.room.accountData.readMarkerEventId
- threadId:self.roomDataSource.threadId
- andMatrixSession:self.mainSession
- onComplete:^(id roomDataSource) {
- MXStrongifyAndReturnIfNil(self);
-
- [roomDataSource finalizeInitialization];
-
- // Center the bubbles table content on the bottom of the read marker event in order to display correctly the read marker view.
- self.centerBubblesTableViewContentOnTheInitialEventBottom = YES;
- [self displayRoom:roomDataSource];
-
- // Give the data source ownership to the room view controller.
- self.hasRoomDataSourceOwnership = YES;
- }];
+ NSString *eventId = self.roomDataSource.room.accountData.readMarkerEventId;
+ NSString *threadId = self.roomDataSource.threadId;
+ [self reloadRoomWihtEventId:eventId threadId:threadId];
}
else if (sender == self.resetReadMarkerButton)
{
@@ -7910,6 +7894,35 @@ - (void)roomInfoCoordinatorBridgePresenter:(RoomInfoCoordinatorBridgePresenter *
// [[AppDelegate theDelegate] showRoomWithParameters:parameters];
}
}
+- (void)roomInfoCoordinatorBridgePresenter:(RoomInfoCoordinatorBridgePresenter *)coordinator
+ viewEventInTimeline:(MXEvent *)event
+{
+ [self.navigationController popToViewController:self animated:true];
+ [self reloadRoomWihtEventId:event.eventId threadId:event.threadId];
+}
+
+-(void)reloadRoomWihtEventId:(NSString *)eventId
+ threadId:(NSString *)threadId
+{
+ // Jump to the last unread event by using a temporary room data source initialized with the last unread event id.
+ MXWeakify(self);
+ [RoomDataSource loadRoomDataSourceWithRoomId:self.roomDataSource.roomId
+ initialEventId:eventId
+ threadId:threadId
+ andMatrixSession:self.mainSession
+ onComplete:^(id roomDataSource) {
+ MXStrongifyAndReturnIfNil(self);
+
+ [roomDataSource finalizeInitialization];
+
+ // Center the bubbles table content on the bottom of the read marker event in order to display correctly the read marker view.
+ self.centerBubblesTableViewContentOnTheInitialEventBottom = YES;
+ [self displayRoom:roomDataSource];
+
+ // Give the data source ownership to the room view controller.
+ self.hasRoomDataSourceOwnership = YES;
+ }];
+}
#pragma mark - RemoveJitsiWidgetViewDelegate
diff --git a/Riot/Modules/Room/Views/WYSIWYGInputToolbar/WysiwygInputToolbarView.swift b/Riot/Modules/Room/Views/WYSIWYGInputToolbar/WysiwygInputToolbarView.swift
index 013602843c..d611fb06ad 100644
--- a/Riot/Modules/Room/Views/WYSIWYGInputToolbar/WysiwygInputToolbarView.swift
+++ b/Riot/Modules/Room/Views/WYSIWYGInputToolbar/WysiwygInputToolbarView.swift
@@ -17,6 +17,7 @@
import Foundation
import Reusable
import WysiwygComposer
+import HTMLParser
import SwiftUI
import Combine
import UIKit
@@ -43,9 +44,14 @@ class WysiwygInputToolbarView: MXKRoomInputToolbarView, NibLoadable, HtmlRoomInp
private var voiceMessageBottomConstraint: NSLayoutConstraint?
private var hostingViewController: VectorHostingController!
private var wysiwygViewModel = WysiwygComposerViewModel(
- textColor: ThemeService.shared().theme.colors.primaryContent,
- linkColor: ThemeService.shared().theme.colors.links,
- codeBackgroundColor: ThemeService.shared().theme.selectedBackgroundColor
+ parserStyle: HTMLParserStyle(textColor: ThemeService.shared().theme.colors.primaryContent,
+ linkColor: ThemeService.shared().theme.colors.links,
+ codeBackgroundColor: ThemeService.shared().theme.selectedBackgroundColor,
+ codeBorderColor: ThemeService.shared().theme.textQuinaryColor,
+ quoteBackgroundColor: ThemeService.shared().theme.selectedBackgroundColor,
+ quoteBorderColor: ThemeService.shared().theme.textQuinaryColor,
+ borderWidth: 1.0,
+ cornerRadius: 4.0)
)
private var viewModel: ComposerViewModelProtocol!
@@ -298,9 +304,14 @@ class WysiwygInputToolbarView: MXKRoomInputToolbarView, NibLoadable, HtmlRoomInp
private func update(theme: Theme) {
hostingViewController.view.backgroundColor = theme.colors.background
- wysiwygViewModel.textColor = theme.colors.primaryContent
- wysiwygViewModel.linkColor = theme.colors.links
- wysiwygViewModel.codeBackgroundColor = theme.selectedBackgroundColor
+ wysiwygViewModel.parserStyle = HTMLParserStyle(textColor: ThemeService.shared().theme.colors.primaryContent,
+ linkColor: ThemeService.shared().theme.colors.links,
+ codeBackgroundColor: ThemeService.shared().theme.selectedBackgroundColor,
+ codeBorderColor: ThemeService.shared().theme.textQuinaryColor,
+ quoteBackgroundColor: ThemeService.shared().theme.selectedBackgroundColor,
+ quoteBorderColor: ThemeService.shared().theme.textQuinaryColor,
+ borderWidth: 1.0,
+ cornerRadius: 4.0)
}
private func updateTextViewHeight() {
diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m
index 6cff6af96c..8dc76f357a 100644
--- a/Riot/Modules/Settings/SettingsViewController.m
+++ b/Riot/Modules/Settings/SettingsViewController.m
@@ -639,12 +639,10 @@ - (void)updateSections
if (BuildSettings.settingsScreenShowLabSettings)
{
Section *sectionLabs = [Section sectionWithTag:SECTION_TAG_LABS];
- #if DEBUG
if (MXSDKOptions.sharedInstance.isCryptoSDKAvailable)
{
[sectionLabs addRowWithTag:LABS_ENABLE_CRYPTO_SDK];
}
- #endif
[sectionLabs addRowWithTag:LABS_ENABLE_RINGING_FOR_GROUP_CALLS_INDEX];
[sectionLabs addRowWithTag:LABS_ENABLE_THREADS_INDEX];
@@ -2677,7 +2675,6 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
}
else
{
- #if DEBUG
if (row == LABS_ENABLE_CRYPTO_SDK)
{
MXKTableViewCellWithLabelAndSwitch *labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath];
@@ -2686,11 +2683,10 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
labelAndSwitchCell.mxkSwitch.on = isEnabled;
[labelAndSwitchCell.mxkSwitch setEnabled:!isEnabled];
labelAndSwitchCell.mxkSwitch.onTintColor = ThemeService.shared.theme.tintColor;
- [labelAndSwitchCell.mxkSwitch addTarget:self action:@selector(toggleEnableCryptoSDKFeature:) forControlEvents:UIControlEventTouchUpInside];
+ [labelAndSwitchCell.mxkSwitch addTarget:self action:@selector(enableCryptoSDKFeature:) forControlEvents:UIControlEventTouchUpInside];
cell = labelAndSwitchCell;
}
- #endif
}
}
else if (section == SECTION_TAG_SECURITY)
@@ -3510,17 +3506,14 @@ - (void)toggleEnableVoiceBroadcastFeature:(UISwitch *)sender
RiotSettings.shared.enableVoiceBroadcast = sender.isOn;
}
-#if DEBUG
-- (void)toggleEnableCryptoSDKFeature:(UISwitch *)sender
+- (void)enableCryptoSDKFeature:(UISwitch *)sender
{
- BOOL isEnabled = sender.isOn;
- MXWeakify(self);
-
[currentAlert dismissViewControllerAnimated:NO completion:nil];
- UIAlertController *confirmationAlert = [UIAlertController alertControllerWithTitle:nil
+ UIAlertController *confirmationAlert = [UIAlertController alertControllerWithTitle:VectorL10n.settingsLabsEnableCryptoSdk
message:VectorL10n.settingsLabsConfirmCryptoSdk
preferredStyle:UIAlertControllerStyleAlert];
+ MXWeakify(self);
[confirmationAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n cancel] style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) {
MXStrongifyAndReturnIfNil(self);
self->currentAlert = nil;
@@ -3529,17 +3522,16 @@ - (void)toggleEnableCryptoSDKFeature:(UISwitch *)sender
}]];
[confirmationAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n continue] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
- MXStrongifyAndReturnIfNil(self);
- RiotSettings.shared.enableCryptoSDK = isEnabled;
- MXSDKOptions.sharedInstance.enableCryptoSDK = isEnabled;
+ [CryptoSDKConfiguration.shared enable];
+ [Analytics.shared trackCryptoSDKEnabled];
+
[[AppDelegate theDelegate] reloadMatrixSessions:YES];
}]];
[self presentViewController:confirmationAlert animated:YES completion:nil];
currentAlert = confirmationAlert;
}
-#endif
- (void)togglePinRoomsWithMissedNotif:(UISwitch *)sender
{
diff --git a/Riot/Modules/Spaces/SpaceRoomList/ExploreRoomCoordinator.swift b/Riot/Modules/Spaces/SpaceRoomList/ExploreRoomCoordinator.swift
index 41ba90c2c3..278eaaf2e5 100644
--- a/Riot/Modules/Spaces/SpaceRoomList/ExploreRoomCoordinator.swift
+++ b/Riot/Modules/Spaces/SpaceRoomList/ExploreRoomCoordinator.swift
@@ -17,6 +17,7 @@
*/
import UIKit
+import MatrixSDK
@objcMembers
final class ExploreRoomCoordinator: NSObject, ExploreRoomCoordinatorType {
@@ -519,5 +520,8 @@ extension ExploreRoomCoordinator: RoomInfoCoordinatorDelegate {
self.remove(childCoordinator: coordinator)
}
}
+ func roomInfoCoordinator(_ coordinator: RoomInfoCoordinatorType, viewEventInTimeline event: MXEvent) {
+
+ }
}
diff --git a/Riot/Modules/VoiceBroadcast/VoiceBroadcastSDK/VoiceBroadcastAggregator.swift b/Riot/Modules/VoiceBroadcast/VoiceBroadcastSDK/VoiceBroadcastAggregator.swift
index 39264b42c9..4522df16c3 100644
--- a/Riot/Modules/VoiceBroadcast/VoiceBroadcastSDK/VoiceBroadcastAggregator.swift
+++ b/Riot/Modules/VoiceBroadcast/VoiceBroadcastSDK/VoiceBroadcastAggregator.swift
@@ -35,6 +35,7 @@ public protocol VoiceBroadcastAggregatorDelegate: AnyObject {
func voiceBroadcastAggregator(_ aggregator: VoiceBroadcastAggregator, didReceiveChunk: VoiceBroadcastChunk)
func voiceBroadcastAggregator(_ aggregator: VoiceBroadcastAggregator, didReceiveState: VoiceBroadcastInfoState)
func voiceBroadcastAggregatorDidUpdateData(_ aggregator: VoiceBroadcastAggregator)
+ func voiceBroadcastAggregator(_ aggregator: VoiceBroadcastAggregator, didUpdateUndecryptableEventList events: Set)
}
/**
@@ -58,6 +59,7 @@ public class VoiceBroadcastAggregator {
private var referenceEventsListener: Any?
private var events: [MXEvent] = []
+ private var undecryptableEvents: Set = []
public private(set) var voiceBroadcast: VoiceBroadcast! {
didSet {
@@ -84,7 +86,7 @@ public class VoiceBroadcastAggregator {
try buildVoiceBroadcastStartContent()
}
-
+
private func buildVoiceBroadcastStartContent() throws {
guard let event = session.store.event(withEventId: voiceBroadcastStartEventId, inRoom: room.roomId),
let eventContent = VoiceBroadcastInfo(fromJSON: event.content),
@@ -118,7 +120,11 @@ public class VoiceBroadcastAggregator {
@objc private func eventDidDecrypt(sender: Notification) {
guard let event = sender.object as? MXEvent else { return }
-
+
+ if undecryptableEvents.remove(event) != nil {
+ delegate?.voiceBroadcastAggregator(self, didUpdateUndecryptableEventList: undecryptableEvents)
+ }
+
self.handleEvent(event: event)
}
@@ -138,8 +144,19 @@ public class VoiceBroadcastAggregator {
private func updateVoiceBroadcast(event: MXEvent) {
guard event.sender == self.voiceBroadcastSenderId,
let relatedEventId = event.relatesTo?.eventId,
- relatedEventId == self.voiceBroadcastStartEventId,
- event.content[VoiceBroadcastSettings.voiceBroadcastContentKeyChunkType] != nil else {
+ relatedEventId == self.voiceBroadcastStartEventId else {
+ return
+ }
+
+ // Handle decryption errors
+ if event.decryptionError != nil {
+ self.undecryptableEvents.insert(event)
+ self.delegate?.voiceBroadcastAggregator(self, didUpdateUndecryptableEventList: self.undecryptableEvents)
+
+ return
+ }
+
+ guard event.content[VoiceBroadcastSettings.voiceBroadcastContentKeyChunkType] != nil else {
return
}
@@ -192,15 +209,22 @@ public class VoiceBroadcastAggregator {
}
self.events.removeAll()
+ self.undecryptableEvents.removeAll()
self.voiceBroadcastLastChunkSequence = 0
let filteredChunk = response.chunk.filter { event in
event.sender == self.voiceBroadcastSenderId &&
event.content[VoiceBroadcastSettings.voiceBroadcastContentKeyChunkType] != nil
}
-
self.events.append(contentsOf: filteredChunk)
-
+
+ let decryptionFailure = response.chunk.filter { event in
+ event.sender == self.voiceBroadcastSenderId &&
+ event.decryptionError != nil
+ }
+ self.undecryptableEvents.formUnion(decryptionFailure)
+ self.delegate?.voiceBroadcastAggregator(self, didUpdateUndecryptableEventList: self.undecryptableEvents)
+
let eventTypes = [VoiceBroadcastSettings.voiceBroadcastInfoContentKeyType, kMXEventTypeStringRoomMessage]
self.referenceEventsListener = self.room.listen(toEventsOfTypes: eventTypes, onEvent: { [weak self] event, direction, roomState in
self?.handleEvent(event: event, direction: direction, roomState: roomState)
diff --git a/Riot/Utils/EventFormatter+DTCoreTextFix.h b/Riot/Utils/EventFormatter+DTCoreTextFix.h
deleted file mode 100644
index 90be432c46..0000000000
--- a/Riot/Utils/EventFormatter+DTCoreTextFix.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-Copyright 2020 New Vector Ltd
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-@import Foundation;
-
-#import "EventFormatter.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface EventFormatter(DTCoreTextFix)
-
-// Fix DTCoreText iOS 13 issue (https://github.com/Cocoanetics/DTCoreText/issues/1168)
-+ (void)fixDTCoreTextFont;
-
-@end
-
-NS_ASSUME_NONNULL_END
diff --git a/Riot/Utils/EventFormatter+DTCoreTextFix.m b/Riot/Utils/EventFormatter+DTCoreTextFix.m
deleted file mode 100644
index 110d036fcc..0000000000
--- a/Riot/Utils/EventFormatter+DTCoreTextFix.m
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
-Copyright 2020 New Vector Ltd
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-#import "EventFormatter+DTCoreTextFix.h"
-
-@import UIKit;
-@import CoreText;
-@import ObjectiveC;
-
-#pragma mark - UIFont DTCoreText fix
-
-@interface UIFont (vc_DTCoreTextFix)
-
-+ (UIFont *)vc_fixedFontWithCTFont:(CTFontRef)ctFont;
-
-@end
-
-@implementation UIFont (vc_DTCoreTextFix)
-
-+ (UIFont *)vc_fixedFontWithCTFont:(CTFontRef)ctFont {
- NSString *fontName = (__bridge_transfer NSString *)CTFontCopyName(ctFont, kCTFontPostScriptNameKey);
-
- CGFloat fontSize = CTFontGetSize(ctFont);
- UIFont *font = [UIFont fontWithName:fontName size:fontSize];
-
- // On iOS 13+ "TimesNewRomanPSMT" will be used instead of "SFUI"
- // In case of "Times New Roman" fallback, use system font and reuse UIFontDescriptorSymbolicTraits.
- if ([font.familyName.lowercaseString containsString:@"times"])
- {
- UIFontDescriptorSymbolicTraits symbolicTraits = (UIFontDescriptorSymbolicTraits)CTFontGetSymbolicTraits(ctFont);
-
- UIFontDescriptor *systemFontDescriptor = [UIFont systemFontOfSize:fontSize].fontDescriptor;
-
- UIFontDescriptor *finalFontDescriptor = [systemFontDescriptor fontDescriptorWithSymbolicTraits:symbolicTraits];
- font = [UIFont fontWithDescriptor:finalFontDescriptor size:fontSize];
- }
-
- return font;
-}
-
-@end
-
-#pragma mark - Implementation
-
-@implementation EventFormatter(DTCoreTextFix)
-
-// DTCoreText iOS 13 fix. See issue and comment here: https://github.com/Cocoanetics/DTCoreText/issues/1168#issuecomment-583541514
-+ (void)fixDTCoreTextFont
-{
- static dispatch_once_t onceToken;
-
- dispatch_once(&onceToken, ^{
- Class originalClass = object_getClass([UIFont class]);
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wundeclared-selector"
- SEL originalSelector = @selector(fontWithCTFont:); // DTCoreText method we're overriding
- SEL ourSelector = @selector(vc_fixedFontWithCTFont:); // Use custom implementation
-#pragma clang diagnostic pop
-
- Method originalMethod = class_getClassMethod(originalClass, originalSelector);
- Method swizzledMethod = class_getClassMethod(originalClass, ourSelector);
-
- method_exchangeImplementations(originalMethod, swizzledMethod);
- });
-}
-
-@end
diff --git a/Riot/Utils/EventFormatter.m b/Riot/Utils/EventFormatter.m
index 8b2c44ddbf..209aad7106 100644
--- a/Riot/Utils/EventFormatter.m
+++ b/Riot/Utils/EventFormatter.m
@@ -25,7 +25,6 @@
#import "MXDecryptionResult.h"
#import "DecryptionFailureTracker.h"
-#import "EventFormatter+DTCoreTextFix.h"
#import
#pragma mark - Constants definitions
@@ -50,11 +49,6 @@ @interface EventFormatter ()
@implementation EventFormatter
-+ (void)load
-{
- [self fixDTCoreTextFont];
-}
-
- (void)initDateTimeFormatters
{
[super initDateTimeFormatters];
diff --git a/Riot/target.yml b/Riot/target.yml
index 5933bbe650..8468e277b5 100644
--- a/Riot/target.yml
+++ b/Riot/target.yml
@@ -44,6 +44,7 @@ targets:
- package: SwiftOGG
- package: WysiwygComposer
- package: DeviceKit
+ - package: DTCoreText
configFiles:
Debug: Debug.xcconfig
diff --git a/RiotNSE/NotificationService.swift b/RiotNSE/NotificationService.swift
index 0fd204f21c..a25c40f41b 100644
--- a/RiotNSE/NotificationService.swift
+++ b/RiotNSE/NotificationService.swift
@@ -41,6 +41,7 @@ class NotificationService: UNNotificationServiceExtension {
private var ongoingVoIPPushRequests: [String: Bool] = [:]
private var userAccount: MXKAccount?
+ private var isCryptoSDKEnabled = false
/// Best attempt contents. Will be updated incrementally, if something fails during the process, this best attempt content will be showed as notification. Keys are eventId's
private var bestAttemptContents: [String: UNMutableNotificationContent] = [:]
@@ -195,9 +196,10 @@ class NotificationService: UNNotificationServiceExtension {
self.userAccount = MXKAccountManager.shared()?.activeAccounts.first
if let userAccount = userAccount {
Self.backgroundServiceInitQueue.sync {
- if NotificationService.backgroundSyncService?.credentials != userAccount.mxCredentials {
+ if hasChangedCryptoSDK() || NotificationService.backgroundSyncService?.credentials != userAccount.mxCredentials {
MXLog.debug("[NotificationService] setup: MXBackgroundSyncService init: BEFORE")
self.logMemory()
+
NotificationService.backgroundSyncService = MXBackgroundSyncService(withCredentials: userAccount.mxCredentials, persistTokenDataHandler: { persistTokenDataHandler in
MXKAccountManager.shared().readAndWriteCredentials(persistTokenDataHandler)
}, unauthenticatedHandler: { error, softLogout, refreshTokenAuth, completion in
@@ -214,6 +216,16 @@ class NotificationService: UNNotificationServiceExtension {
}
}
+ /// Determine whether we have switched from using crypto v1 to v2 or vice versa which will require
+ /// rebuilding `MXBackgroundSyncService`
+ private func hasChangedCryptoSDK() -> Bool {
+ guard isCryptoSDKEnabled != RiotSettings.shared.enableCryptoSDK else {
+ return false
+ }
+ isCryptoSDKEnabled = RiotSettings.shared.enableCryptoSDK
+ return true
+ }
+
/// Attempts to preprocess payload and attach room display name to the best attempt content
/// - Parameters:
/// - eventId: Event identifier to mutate best attempt content
diff --git a/RiotNSE/target.yml b/RiotNSE/target.yml
index 36e5a145e8..049acbfd49 100644
--- a/RiotNSE/target.yml
+++ b/RiotNSE/target.yml
@@ -33,6 +33,7 @@ targets:
dependencies:
- package: DeviceKit
+ - package: DTCoreText
configFiles:
Debug: Debug.xcconfig
diff --git a/RiotShareExtension/target.yml b/RiotShareExtension/target.yml
index 322d314acd..0b309c9224 100644
--- a/RiotShareExtension/target.yml
+++ b/RiotShareExtension/target.yml
@@ -33,6 +33,7 @@ targets:
dependencies:
- package: DeviceKit
+ - package: DTCoreText
configFiles:
Debug: Debug.xcconfig
diff --git a/RiotSwiftUI/Modules/Common/Mock/MockAppScreens.swift b/RiotSwiftUI/Modules/Common/Mock/MockAppScreens.swift
index 43db68f107..2ad8451b17 100644
--- a/RiotSwiftUI/Modules/Common/Mock/MockAppScreens.swift
+++ b/RiotSwiftUI/Modules/Common/Mock/MockAppScreens.swift
@@ -73,6 +73,7 @@ enum MockAppScreens {
MockComposerCreateActionListScreenState.self,
MockComposerLinkActionScreenState.self,
MockVoiceBroadcastPlaybackScreenState.self,
- MockPollHistoryScreenState.self
+ MockPollHistoryScreenState.self,
+ MockPollHistoryDetailScreenState.self
]
}
diff --git a/RiotSwiftUI/Modules/Room/AllChatsOnboarding/AllChatsOnboardingViewModel.swift b/RiotSwiftUI/Modules/Room/AllChatsOnboarding/AllChatsOnboardingViewModel.swift
deleted file mode 100644
index 0ba19872a6..0000000000
--- a/RiotSwiftUI/Modules/Room/AllChatsOnboarding/AllChatsOnboardingViewModel.swift
+++ /dev/null
@@ -1,63 +0,0 @@
-//
-// Copyright 2021 New Vector Ltd
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-import Combine
-import SwiftUI
-
-typealias AllChatsOnboardingViewModelType = StateStoreViewModel
-
-class AllChatsOnboardingViewModel: AllChatsOnboardingViewModelType, AllChatsOnboardingViewModelProtocol {
- // MARK: - Properties
-
- // MARK: Private
-
- // MARK: Public
-
- var completion: ((AllChatsOnboardingViewModelResult) -> Void)?
-
- // MARK: - Setup
-
- static func makeAllChatsOnboardingViewModel() -> AllChatsOnboardingViewModelProtocol {
- AllChatsOnboardingViewModel()
- }
-
- private init() {
- super.init(initialViewState: Self.defaultState())
- }
-
- private static func defaultState() -> AllChatsOnboardingViewState {
- AllChatsOnboardingViewState(pages: [
- AllChatsOnboardingPageData(image: Asset.Images.allChatsOnboarding1.image,
- title: VectorL10n.allChatsOnboardingPageTitle1,
- message: VectorL10n.allChatsOnboardingPageMessage1),
- AllChatsOnboardingPageData(image: Asset.Images.allChatsOnboarding2.image,
- title: VectorL10n.allChatsOnboardingPageTitle2,
- message: VectorL10n.allChatsOnboardingPageMessage2),
- AllChatsOnboardingPageData(image: Asset.Images.allChatsOnboarding3.image,
- title: VectorL10n.allChatsOnboardingPageTitle3,
- message: VectorL10n.allChatsOnboardingPageMessage3)
- ])
- }
-
- // MARK: - Public
-
- override func process(viewAction: AllChatsOnboardingViewAction) {
- switch viewAction {
- case .cancel:
- completion?(.cancel)
- }
- }
-}
diff --git a/RiotSwiftUI/Modules/Room/AllChatsOnboarding/Coordinator/AllChatsOnboardingCoordinator.swift b/RiotSwiftUI/Modules/Room/AllChatsOnboarding/Coordinator/AllChatsOnboardingCoordinator.swift
deleted file mode 100644
index df189c1447..0000000000
--- a/RiotSwiftUI/Modules/Room/AllChatsOnboarding/Coordinator/AllChatsOnboardingCoordinator.swift
+++ /dev/null
@@ -1,92 +0,0 @@
-//
-// Copyright 2021 New Vector Ltd
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-import CommonKit
-import SwiftUI
-
-/// All Chats onboarding screen
-final class AllChatsOnboardingCoordinator: NSObject, Coordinator, Presentable {
- // MARK: - Properties
-
- // MARK: Private
-
- private let hostingController: UIViewController
- private var viewModel: AllChatsOnboardingViewModelProtocol
-
- private var indicatorPresenter: UserIndicatorTypePresenterProtocol
- private var loadingIndicator: UserIndicator?
-
- // MARK: Public
-
- // Must be used only internally
- var childCoordinators: [Coordinator] = []
- var completion: (() -> Void)?
-
- // MARK: - Setup
-
- override init() {
- let viewModel = AllChatsOnboardingViewModel.makeAllChatsOnboardingViewModel()
- let view = AllChatsOnboarding(viewModel: viewModel.context)
- self.viewModel = viewModel
- hostingController = VectorHostingController(rootView: view)
- indicatorPresenter = UserIndicatorTypePresenter(presentingViewController: hostingController)
-
- super.init()
-
- hostingController.presentationController?.delegate = self
- }
-
- // MARK: - Public
-
- func start() {
- MXLog.debug("[AllChatsOnboardingCoordinator] did start.")
- viewModel.completion = { [weak self] result in
- guard let self = self else { return }
- MXLog.debug("[AllChatsOnboardingCoordinator] AllChatsOnboardingViewModel did complete with result: \(result).")
- switch result {
- case .cancel:
- self.completion?()
- }
- }
- }
-
- func toPresentable() -> UIViewController {
- hostingController
- }
-
- // MARK: - Private
-
- /// Show an activity indicator whilst loading.
- /// - Parameters:
- /// - label: The label to show on the indicator.
- /// - isInteractionBlocking: Whether the indicator should block any user interaction.
- private func startLoading(label: String = VectorL10n.loading, isInteractionBlocking: Bool = true) {
- loadingIndicator = indicatorPresenter.present(.loading(label: label, isInteractionBlocking: isInteractionBlocking))
- }
-
- /// Hide the currently displayed activity indicator.
- private func stopLoading() {
- loadingIndicator = nil
- }
-}
-
-// MARK: - UIAdaptivePresentationControllerDelegate
-
-extension AllChatsOnboardingCoordinator: UIAdaptivePresentationControllerDelegate {
- func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
- completion?()
- }
-}
diff --git a/RiotSwiftUI/Modules/Room/AllChatsOnboarding/Coordinator/AllChatsOnboardingCoordinatorBridgePresenter.swift b/RiotSwiftUI/Modules/Room/AllChatsOnboarding/Coordinator/AllChatsOnboardingCoordinatorBridgePresenter.swift
deleted file mode 100644
index 75977054d9..0000000000
--- a/RiotSwiftUI/Modules/Room/AllChatsOnboarding/Coordinator/AllChatsOnboardingCoordinatorBridgePresenter.swift
+++ /dev/null
@@ -1,63 +0,0 @@
-//
-// Copyright 2022 New Vector Ltd
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-import Foundation
-
-@objc protocol AllChatsOnboardingCoordinatorBridgePresenterDelegate {
- func allChatsOnboardingCoordinatorBridgePresenterDidCancel(_ coordinatorBridgePresenter: AllChatsOnboardingCoordinatorBridgePresenter)
-}
-
-/// `AllChatsOnboardingCoordinatorBridgePresenter` enables to start `AllChatsOnboardingCoordinator` from a view controller.
-/// This bridge is used while waiting for global usage of coordinator pattern.
-/// It breaks the Coordinator abstraction and it has been introduced for Objective-C compatibility (mainly for integration in legacy view controllers).
-/// Each bridge should be removed once the underlying Coordinator has been integrated by another Coordinator.
-@objcMembers
-final class AllChatsOnboardingCoordinatorBridgePresenter: NSObject {
- // MARK: - Properties
-
- // MARK: Private
-
- private var coordinator: AllChatsOnboardingCoordinator?
-
- // MARK: Public
-
- var completion: (() -> Void)?
-
- // MARK: - Public
-
- func present(from viewController: UIViewController, animated: Bool) {
- let coordinator = AllChatsOnboardingCoordinator()
- coordinator.completion = { [weak self] in
- guard let self = self else { return }
- self.completion?()
- }
- let presentable = coordinator.toPresentable()
- viewController.present(presentable, animated: animated, completion: nil)
- coordinator.start()
-
- self.coordinator = coordinator
- }
-
- func dismiss(animated: Bool, completion: (() -> Void)?) {
- guard let coordinator = coordinator else {
- return
- }
- coordinator.toPresentable().dismiss(animated: animated) {
- self.coordinator = nil
- completion?()
- }
- }
-}
diff --git a/RiotSwiftUI/Modules/Room/AllChatsOnboarding/View/AllChatsOnboarding.swift b/RiotSwiftUI/Modules/Room/AllChatsOnboarding/View/AllChatsOnboarding.swift
deleted file mode 100644
index 513cc55a34..0000000000
--- a/RiotSwiftUI/Modules/Room/AllChatsOnboarding/View/AllChatsOnboarding.swift
+++ /dev/null
@@ -1,80 +0,0 @@
-//
-// Copyright 2021 New Vector Ltd
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-import SwiftUI
-
-struct AllChatsOnboarding: View {
- // MARK: - Properties
-
- // MARK: Private
-
- @Environment(\.theme) private var theme: ThemeSwiftUI
- @State private var selectedTab = 0
-
- // MARK: Public
-
- @ObservedObject var viewModel: AllChatsOnboardingViewModel.Context
-
- var body: some View {
- VStack {
- Text(VectorL10n.allChatsOnboardingTitle)
- .font(theme.fonts.title3SB)
- .foregroundColor(theme.colors.primaryContent)
- .padding()
- TabView(selection: $selectedTab) {
- ForEach(viewModel.viewState.pages.indices, id: \.self) { index in
- let page = viewModel.viewState.pages[index]
- AllChatsOnboardingPage(image: page.image,
- title: page.title,
- message: page.message)
- .tag(index)
- }
- }
- .tabViewStyle(PageTabViewStyle(indexDisplayMode: .automatic))
- .indexViewStyle(.page(backgroundDisplayMode: .always))
-
- Button { onCallToAction() } label: {
- Text(selectedTab == viewModel.viewState.pages.count - 1 ? VectorL10n.allChatsOnboardingTryIt : VectorL10n.next)
- .animation(nil)
- }
- .buttonStyle(PrimaryActionButtonStyle())
- .padding()
- }
- .background(theme.colors.background.ignoresSafeArea())
- .frame(maxHeight: .infinity)
- }
-
- // MARK: - Private
-
- private func onCallToAction() {
- if selectedTab == viewModel.viewState.pages.count - 1 {
- viewModel.send(viewAction: .cancel)
- } else {
- withAnimation {
- selectedTab += 1
- }
- }
- }
-}
-
-// MARK: - Previews
-
-struct AllChatsOnboarding_Previews: PreviewProvider {
- static var previews: some View {
- AllChatsOnboarding(viewModel: AllChatsOnboardingViewModel.makeAllChatsOnboardingViewModel().context).theme(.light).preferredColorScheme(.light)
- AllChatsOnboarding(viewModel: AllChatsOnboardingViewModel.makeAllChatsOnboardingViewModel().context).theme(.dark).preferredColorScheme(.dark)
- }
-}
diff --git a/RiotSwiftUI/Modules/Room/AllChatsOnboarding/View/AllChatsOnboardingPage.swift b/RiotSwiftUI/Modules/Room/AllChatsOnboarding/View/AllChatsOnboardingPage.swift
deleted file mode 100644
index c6a5f06fa6..0000000000
--- a/RiotSwiftUI/Modules/Room/AllChatsOnboarding/View/AllChatsOnboardingPage.swift
+++ /dev/null
@@ -1,62 +0,0 @@
-//
-// Copyright 2022 New Vector Ltd
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-import SwiftUI
-
-struct AllChatsOnboardingPage: View {
- // MARK: - Properties
-
- let image: UIImage
- let title: String
- let message: String
-
- // MARK: Private
-
- @Environment(\.theme) private var theme: ThemeSwiftUI
-
- var body: some View {
- VStack {
- Spacer()
- Image(uiImage: image)
- Spacer()
- Text(title)
- .font(theme.fonts.title2B)
- .foregroundColor(theme.colors.primaryContent)
- .padding(.bottom, 16)
- Text(message)
- .multilineTextAlignment(.center)
- .font(theme.fonts.callout)
- .foregroundColor(theme.colors.primaryContent)
- Spacer()
- }
- .padding(.horizontal)
- }
-}
-
-// MARK: - Previews
-
-struct AllChatsOnboardingPage_Previews: PreviewProvider {
- static var previews: some View {
- preview.theme(.light).preferredColorScheme(.light)
- preview.theme(.dark).preferredColorScheme(.dark)
- }
-
- private static var preview: some View {
- AllChatsOnboardingPage(image: Asset.Images.allChatsOnboarding1.image,
- title: VectorL10n.allChatsOnboardingPageTitle1,
- message: VectorL10n.allChatsOnboardingPageMessage1)
- }
-}
diff --git a/RiotSwiftUI/Modules/Room/Composer/Model/ComposerModels.swift b/RiotSwiftUI/Modules/Room/Composer/Model/ComposerModels.swift
index 5525e99403..800494c5db 100644
--- a/RiotSwiftUI/Modules/Room/Composer/Model/ComposerModels.swift
+++ b/RiotSwiftUI/Modules/Room/Composer/Model/ComposerModels.swift
@@ -36,6 +36,8 @@ enum FormatType {
case strikethrough
case unorderedList
case orderedList
+ case indent
+ case unIndent
case inlineCode
case codeBlock
case quote
@@ -66,6 +68,10 @@ extension FormatItem {
return Asset.Images.bulletList.name
case .orderedList:
return Asset.Images.numberedList.name
+ case .indent:
+ return Asset.Images.indentIncrease.name
+ case .unIndent:
+ return Asset.Images.indentDecrease.name
case .inlineCode:
return Asset.Images.code.name
case .codeBlock:
@@ -91,6 +97,10 @@ extension FormatItem {
return "unorderedListButton"
case .orderedList:
return "orderedListButton"
+ case .indent:
+ return "indentListButton"
+ case .unIndent:
+ return "unIndentButton"
case .inlineCode:
return "inlineCodeButton"
case .codeBlock:
@@ -116,6 +126,10 @@ extension FormatItem {
return VectorL10n.wysiwygComposerFormatActionUnorderedList
case .orderedList:
return VectorL10n.wysiwygComposerFormatActionOrderedList
+ case .indent:
+ return VectorL10n.wysiwygComposerFormatActionIndent
+ case .unIndent:
+ return VectorL10n.wysiwygComposerFormatActionUnIndent
case .inlineCode:
return VectorL10n.wysiwygComposerFormatActionInlineCode
case .codeBlock:
@@ -144,6 +158,10 @@ extension FormatType {
return .unorderedList
case .orderedList:
return .orderedList
+ case .indent:
+ return .indent
+ case .unIndent:
+ return .unIndent
case .inlineCode:
return .inlineCode
case .codeBlock:
@@ -171,6 +189,10 @@ extension FormatType {
return .unorderedList
case .orderedList:
return .orderedList
+ case .indent:
+ return .indent
+ case .unIndent:
+ return .unIndent
case .inlineCode:
return .inlineCode
case .codeBlock:
diff --git a/RiotSwiftUI/Modules/Room/NotificationSettings/Service/MatrixSDK/MXRoomNotificationSettingsService.swift b/RiotSwiftUI/Modules/Room/NotificationSettings/Service/MatrixSDK/MXRoomNotificationSettingsService.swift
index e9d192b490..caaa45a530 100644
--- a/RiotSwiftUI/Modules/Room/NotificationSettings/Service/MatrixSDK/MXRoomNotificationSettingsService.swift
+++ b/RiotSwiftUI/Modules/Room/NotificationSettings/Service/MatrixSDK/MXRoomNotificationSettingsService.swift
@@ -30,6 +30,10 @@ final class MXRoomNotificationSettingsService: RoomNotificationSettingsServiceTy
private var observers: [ObjectIdentifier] = []
+ private var notificationCenter: MXNotificationCenter? {
+ room.mxSession?.notificationCenter
+ }
+
// MARK: Public
var notificationState: RoomNotificationState {
@@ -166,7 +170,7 @@ final class MXRoomNotificationSettingsService: RoomNotificationSettingsServiceTy
}
handleFailureCallback(completion)
- room.mxSession.notificationCenter.addRoomRule(
+ notificationCenter?.addRoomRule(
room.roomId,
notify: false,
sound: false,
@@ -184,7 +188,7 @@ final class MXRoomNotificationSettingsService: RoomNotificationSettingsServiceTy
}
handleFailureCallback(completion)
- room.mxSession.notificationCenter.addOverrideRule(
+ notificationCenter?.addOverrideRule(
withId: roomId,
conditions: [["kind": "event_match", "key": "room_id", "pattern": roomId]],
notify: false,
@@ -196,11 +200,11 @@ final class MXRoomNotificationSettingsService: RoomNotificationSettingsServiceTy
private func removePushRule(rule: MXPushRule, completion: @escaping Completion) {
handleUpdateCallback(completion) { [weak self] in
guard let self = self else { return true }
- return self.room.mxSession.notificationCenter.rule(byId: rule.ruleId) == nil
+ return self.notificationCenter?.rule(byId: rule.ruleId) == nil
}
handleFailureCallback(completion)
- room.mxSession.notificationCenter.removeRule(rule)
+ notificationCenter?.removeRule(rule)
}
private func enablePushRule(rule: MXPushRule, completion: @escaping Completion) {
@@ -210,7 +214,7 @@ final class MXRoomNotificationSettingsService: RoomNotificationSettingsServiceTy
}
handleFailureCallback(completion)
- room.mxSession.notificationCenter.enableRule(rule, isEnabled: true)
+ notificationCenter?.enableRule(rule, isEnabled: true)
}
private func handleUpdateCallback(_ completion: @escaping Completion, releaseCheck: @escaping () -> Bool) {
@@ -283,14 +287,14 @@ private extension MXRoom {
}
var overridePushRule: MXPushRule? {
- guard let overrideRules = mxSession.notificationCenter.rules.global.override else {
+ guard let overrideRules = mxSession?.notificationCenter?.rules?.global?.override else {
return nil
}
return getRoomRule(from: overrideRules)
}
var roomPushRule: MXPushRule? {
- guard let roomRules = mxSession.notificationCenter.rules.global.room else {
+ guard let roomRules = mxSession?.notificationCenter?.rules?.global?.room else {
return nil
}
return getRoomRule(from: roomRules)
diff --git a/RiotSwiftUI/Modules/Room/PollHistory/Coordinator/PollHistoryCoordinator.swift b/RiotSwiftUI/Modules/Room/PollHistory/Coordinator/PollHistoryCoordinator.swift
index b9129a6e93..faa293abf4 100644
--- a/RiotSwiftUI/Modules/Room/PollHistory/Coordinator/PollHistoryCoordinator.swift
+++ b/RiotSwiftUI/Modules/Room/PollHistory/Coordinator/PollHistoryCoordinator.swift
@@ -15,29 +15,32 @@
//
import CommonKit
+import MatrixSDK
import SwiftUI
struct PollHistoryCoordinatorParameters {
let mode: PollHistoryMode
+ let room: MXRoom
+ let navigationRouter: NavigationRouterType
}
-final class PollHistoryCoordinator: Coordinator, Presentable {
+final class PollHistoryCoordinator: NSObject, Coordinator, Presentable {
private let parameters: PollHistoryCoordinatorParameters
private let pollHistoryHostingController: UIViewController
private var pollHistoryViewModel: PollHistoryViewModelProtocol
+ private let navigationRouter: NavigationRouterType
// Must be used only internally
var childCoordinators: [Coordinator] = []
- var completion: (() -> Void)?
+ var completion: ((MXEvent) -> Void)?
init(parameters: PollHistoryCoordinatorParameters) {
self.parameters = parameters
-
- #warning("replace with the real service after that it's done")
- let viewModel = PollHistoryViewModel(mode: parameters.mode, pollService: MockPollHistoryService())
+ let viewModel = PollHistoryViewModel(mode: parameters.mode, pollService: PollHistoryService(room: parameters.room, chunkSizeInDays: PollHistoryConstants.chunkSizeInDays))
let view = PollHistory(viewModel: viewModel.context)
pollHistoryViewModel = viewModel
pollHistoryHostingController = VectorHostingController(rootView: view)
+ navigationRouter = parameters.navigationRouter
}
// MARK: - Public
@@ -45,11 +48,61 @@ final class PollHistoryCoordinator: Coordinator, Presentable {
func start() {
MXLog.debug("[PollHistoryCoordinator] did start.")
pollHistoryViewModel.completion = { [weak self] result in
- self?.completion?()
+ switch result {
+ case .showPollDetail(let poll):
+ self?.showPollDetail(poll)
+ }
}
}
+ func showPollDetail(_ poll: TimelinePollDetails) {
+ guard let event = parameters.room.mxSession.store.event(withEventId: poll.id, inRoom: parameters.room.roomId),
+ let detailCoordinator: PollHistoryDetailCoordinator = try? .init(parameters: .init(event: event, poll: poll, room: parameters.room)) else {
+ pollHistoryViewModel.context.alertInfo = .init(id: true, title: VectorL10n.settingsDiscoveryErrorMessage)
+ return
+ }
+ detailCoordinator.toPresentable().presentationController?.delegate = self
+ detailCoordinator.completion = { [weak self, weak detailCoordinator, weak event] result in
+ guard let self, let coordinator = detailCoordinator, let event = event else { return }
+ self.handlePollDetailResult(result, coordinator: coordinator, event: event, poll: poll)
+ }
+
+ add(childCoordinator: detailCoordinator)
+ detailCoordinator.start()
+ toPresentable().present(detailCoordinator.toPresentable(), animated: true)
+ }
+
func toPresentable() -> UIViewController {
pollHistoryHostingController
}
+
+ private func handlePollDetailResult(_ result: PollHistoryDetailViewModelResult, coordinator: Coordinator, event: MXEvent, poll: TimelinePollDetails) {
+ switch result {
+ case .dismiss:
+ toPresentable().dismiss(animated: true)
+ remove(childCoordinator: coordinator)
+ case .viewInTimeline:
+ toPresentable().dismiss(animated: false)
+ remove(childCoordinator: coordinator)
+ var event = event
+ if poll.closed {
+ let room = parameters.room
+ let relatedEvents = room.mxSession.store.relations(forEvent: event.eventId, inRoom: room.roomId, relationType: MXEventRelationTypeReference)
+ let pollEndedEvent = relatedEvents.first(where: { $0.eventType == .pollEnd })
+ event = pollEndedEvent ?? event
+ }
+ completion?(event)
+ }
+ }
+}
+
+// MARK: UIAdaptivePresentationControllerDelegate
+
+extension PollHistoryCoordinator: UIAdaptivePresentationControllerDelegate {
+ func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
+ guard let coordinator = childCoordinators.last else {
+ return
+ }
+ remove(childCoordinator: coordinator)
+ }
}
diff --git a/RiotSwiftUI/Modules/Room/PollHistory/MockPollHistoryScreenState.swift b/RiotSwiftUI/Modules/Room/PollHistory/MockPollHistoryScreenState.swift
index 65d393957b..a1c12e5f33 100644
--- a/RiotSwiftUI/Modules/Room/PollHistory/MockPollHistoryScreenState.swift
+++ b/RiotSwiftUI/Modules/Room/PollHistory/MockPollHistoryScreenState.swift
@@ -14,6 +14,7 @@
// limitations under the License.
//
+import Combine
import Foundation
import SwiftUI
@@ -25,8 +26,12 @@ enum MockPollHistoryScreenState: MockScreenState, CaseIterable {
// mock that screen.
case active
case past
- case activeEmpty
- case pastEmpty
+ case activeNoMoreContent
+ case contentLoading
+ case empty
+ case emptyLoading
+ case emptyNoMoreContent
+ case loading
/// The associated screen
var screenType: Any.Type {
@@ -35,25 +40,40 @@ enum MockPollHistoryScreenState: MockScreenState, CaseIterable {
/// Generate the view struct for the screen state.
var screenView: ([Any], AnyView) {
- let pollHistoryMode: PollHistoryMode
+ var pollHistoryMode: PollHistoryMode = .active
let pollService = MockPollHistoryService()
switch self {
case .active:
pollHistoryMode = .active
+ case .activeNoMoreContent:
+ pollHistoryMode = .active
+ pollService.hasNextBatch = false
case .past:
pollHistoryMode = .past
- case .activeEmpty:
+ case .contentLoading:
+ pollService.nextBatchPublishers.append(MockPollPublisher.loadingPolls)
+ case .empty:
pollHistoryMode = .active
- pollService.activePollsData = []
- case .pastEmpty:
- pollHistoryMode = .past
- pollService.pastPollsData = []
+ pollService.nextBatchPublishers = [MockPollPublisher.emptyPolls]
+ case .emptyLoading:
+ pollService.nextBatchPublishers = [MockPollPublisher.emptyPolls, MockPollPublisher.loadingPolls]
+ case .emptyNoMoreContent:
+ pollService.hasNextBatch = false
+ pollService.nextBatchPublishers = [MockPollPublisher.emptyPolls]
+ case .loading:
+ pollService.nextBatchPublishers = [MockPollPublisher.loadingPolls]
}
let viewModel = PollHistoryViewModel(mode: pollHistoryMode, pollService: pollService)
// can simulate service and viewModel actions here if needs be.
+ switch self {
+ case .contentLoading, .emptyLoading:
+ viewModel.process(viewAction: .loadMoreContent)
+ default:
+ break
+ }
return (
[pollHistoryMode, viewModel],
@@ -62,3 +82,17 @@ enum MockPollHistoryScreenState: MockScreenState, CaseIterable {
)
}
}
+
+enum MockPollPublisher {
+ static var emptyPolls: AnyPublisher {
+ Empty(completeImmediately: true).eraseToAnyPublisher()
+ }
+
+ static var loadingPolls: AnyPublisher {
+ Empty(completeImmediately: false).eraseToAnyPublisher()
+ }
+
+ static var failure: AnyPublisher {
+ Fail(error: NSError(domain: "fake", code: 1)).eraseToAnyPublisher()
+ }
+}
diff --git a/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryDetail/Coordinator/PollHistoryDetailCoordinator.swift b/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryDetail/Coordinator/PollHistoryDetailCoordinator.swift
new file mode 100644
index 0000000000..4b166b3aa0
--- /dev/null
+++ b/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryDetail/Coordinator/PollHistoryDetailCoordinator.swift
@@ -0,0 +1,66 @@
+//
+// Copyright 2021 New Vector Ltd
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+import Combine
+import CommonKit
+import MatrixSDK
+import SwiftUI
+
+struct PollHistoryDetailCoordinatorParameters {
+ let event: MXEvent
+ let poll: TimelinePollDetails
+ let room: MXRoom
+}
+
+final class PollHistoryDetailCoordinator: Coordinator, Presentable {
+ private let parameters: PollHistoryDetailCoordinatorParameters
+ private let pollHistoryDetailHostingController: UIViewController
+ private var pollHistoryDetailViewModel: PollHistoryDetailViewModelProtocol
+
+ // Must be used only internally
+ var childCoordinators: [Coordinator] = []
+ var completion: ((PollHistoryDetailViewModelResult) -> Void)?
+
+ init(parameters: PollHistoryDetailCoordinatorParameters) throws {
+ self.parameters = parameters
+ let timelinePollCoordinator = try TimelinePollCoordinator(parameters: .init(session: parameters.room.mxSession, room: parameters.room, pollEvent: parameters.event))
+
+ let viewModel = PollHistoryDetailViewModel(poll: parameters.poll)
+ let view = PollHistoryDetail(viewModel: viewModel.context, contentPoll: timelinePollCoordinator.toView())
+ pollHistoryDetailViewModel = viewModel
+ pollHistoryDetailHostingController = VectorHostingController(rootView: view)
+ add(childCoordinator: timelinePollCoordinator)
+ }
+
+ // MARK: - Public
+
+ func start() {
+ MXLog.debug("[PollHistoryDetailCoordinator] did start.")
+ pollHistoryDetailViewModel.completion = { [weak self] result in
+ guard let self = self else { return }
+ switch result {
+ case .dismiss:
+ self.completion?(.dismiss)
+ case .viewInTimeline:
+ self.completion?(.viewInTimeline)
+ }
+ }
+ }
+
+ func toPresentable() -> UIViewController {
+ pollHistoryDetailHostingController
+ }
+}
diff --git a/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryDetail/MockPollHistoryDetailScreenState.swift b/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryDetail/MockPollHistoryDetailScreenState.swift
new file mode 100644
index 0000000000..09a8fb3c7d
--- /dev/null
+++ b/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryDetail/MockPollHistoryDetailScreenState.swift
@@ -0,0 +1,56 @@
+//
+// Copyright 2021 New Vector Ltd
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+import Foundation
+import SwiftUI
+
+enum MockPollHistoryDetailScreenState: MockScreenState, CaseIterable {
+ case openDisclosed
+ case closedDisclosed
+ case openUndisclosed
+ case closedUndisclosed
+ case closedPollEnded
+
+ var screenType: Any.Type {
+ PollHistoryDetail.self
+ }
+
+ var poll: TimelinePollDetails {
+ let answerOptions = [TimelinePollAnswerOption(id: "1", text: "First", count: 10, winner: false, selected: false),
+ TimelinePollAnswerOption(id: "2", text: "Second", count: 5, winner: false, selected: true),
+ TimelinePollAnswerOption(id: "3", text: "Third", count: 15, winner: true, selected: false)]
+
+ let poll = TimelinePollDetails(id: "id",
+ question: "Question",
+ answerOptions: answerOptions,
+ closed: self == .closedDisclosed || self == .closedUndisclosed ? true : false,
+ startDate: .init(timeIntervalSinceReferenceDate: 0),
+ totalAnswerCount: 20,
+ type: self == .closedDisclosed || self == .openDisclosed ? .disclosed : .undisclosed,
+ eventType: self == .closedPollEnded ? .ended : .started,
+ maxAllowedSelections: 1,
+ hasBeenEdited: false,
+ hasDecryptionError: false)
+ return poll
+ }
+
+ var screenView: ([Any], AnyView) {
+ let timelineViewModel = TimelinePollViewModel(timelinePollDetails: poll)
+ let viewModel = PollHistoryDetailViewModel(poll: poll)
+
+ return ([viewModel], AnyView(PollHistoryDetail(viewModel: viewModel.context, contentPoll: TimelinePollView(viewModel: timelineViewModel.context))))
+ }
+}
diff --git a/RiotSwiftUI/Modules/Room/AllChatsOnboarding/AllChatsOnboardingModels.swift b/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryDetail/PollHistoryDetailModels.swift
similarity index 58%
rename from RiotSwiftUI/Modules/Room/AllChatsOnboarding/AllChatsOnboardingModels.swift
rename to RiotSwiftUI/Modules/Room/PollHistory/PollHistoryDetail/PollHistoryDetailModels.swift
index 76beb12055..7d4fd63656 100644
--- a/RiotSwiftUI/Modules/Room/AllChatsOnboarding/AllChatsOnboardingModels.swift
+++ b/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryDetail/PollHistoryDetailModels.swift
@@ -15,29 +15,31 @@
//
import Foundation
-import UIKit
+import SwiftUI
// MARK: - Coordinator
-// MARK: View model
+typealias PollHistoryDetailViewModelCallback = (PollHistoryDetailViewModelResult) -> Void
-enum AllChatsOnboardingViewModelResult {
- case cancel
+enum PollHistoryDetailViewModelResult {
+ case dismiss
+ case viewInTimeline
}
// MARK: View
-struct AllChatsOnboardingPageData: Identifiable {
- let id = UUID().uuidString
- let image: UIImage
- let title: String
- let message: String
-}
+struct PollHistoryDetailViewState: BindableState {
+ var poll: TimelinePollDetails
+ var pollStartDate: Date {
+ poll.startDate
+ }
-struct AllChatsOnboardingViewState: BindableState {
- let pages: [AllChatsOnboardingPageData]
+ var isPollClosed: Bool {
+ poll.closed
+ }
}
-enum AllChatsOnboardingViewAction {
- case cancel
+enum PollHistoryDetailViewAction {
+ case dismiss
+ case viewInTimeline
}
diff --git a/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryDetail/PollHistoryDetailViewModel.swift b/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryDetail/PollHistoryDetailViewModel.swift
new file mode 100644
index 0000000000..58a18441a6
--- /dev/null
+++ b/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryDetail/PollHistoryDetailViewModel.swift
@@ -0,0 +1,43 @@
+//
+// Copyright 2021 New Vector Ltd
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+import Combine
+import SwiftUI
+
+typealias PollHistoryDetailViewModelType = StateStoreViewModel
+
+class PollHistoryDetailViewModel: PollHistoryDetailViewModelType, PollHistoryDetailViewModelProtocol {
+ // MARK: Public
+
+ var completion: PollHistoryDetailViewModelCallback?
+
+ // MARK: - Setup
+
+ init(poll: TimelinePollDetails) {
+ super.init(initialViewState: PollHistoryDetailViewState(poll: poll))
+ }
+
+ // MARK: - Public
+
+ override func process(viewAction: PollHistoryDetailViewAction) {
+ switch viewAction {
+ case .dismiss:
+ completion?(.dismiss)
+ case .viewInTimeline:
+ completion?(.viewInTimeline)
+ }
+ }
+}
diff --git a/RiotSwiftUI/Modules/Room/AllChatsOnboarding/AllChatsOnboardingViewModelProtocol.swift b/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryDetail/PollHistoryDetailViewModelProtocol.swift
similarity index 68%
rename from RiotSwiftUI/Modules/Room/AllChatsOnboarding/AllChatsOnboardingViewModelProtocol.swift
rename to RiotSwiftUI/Modules/Room/PollHistory/PollHistoryDetail/PollHistoryDetailViewModelProtocol.swift
index dd963c4075..0e4abb98a0 100644
--- a/RiotSwiftUI/Modules/Room/AllChatsOnboarding/AllChatsOnboardingViewModelProtocol.swift
+++ b/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryDetail/PollHistoryDetailViewModelProtocol.swift
@@ -16,8 +16,7 @@
import Foundation
-protocol AllChatsOnboardingViewModelProtocol {
- var completion: ((AllChatsOnboardingViewModelResult) -> Void)? { get set }
- static func makeAllChatsOnboardingViewModel() -> AllChatsOnboardingViewModelProtocol
- var context: AllChatsOnboardingViewModelType.Context { get }
+protocol PollHistoryDetailViewModelProtocol {
+ var completion: PollHistoryDetailViewModelCallback? { get set }
+ var context: PollHistoryDetailViewModelType.Context { get }
}
diff --git a/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryDetail/Test/UI/PollHistoryDetailUITests.swift b/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryDetail/Test/UI/PollHistoryDetailUITests.swift
new file mode 100644
index 0000000000..952a271fbe
--- /dev/null
+++ b/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryDetail/Test/UI/PollHistoryDetailUITests.swift
@@ -0,0 +1,36 @@
+//
+// Copyright 2021 New Vector Ltd
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+import RiotSwiftUI
+import XCTest
+
+class PollHistoryDetailUITests: MockScreenTestCase {
+ func testPollHistoryDetailOpenPoll() {
+ app.goToScreenWithIdentifier(MockPollHistoryDetailScreenState.openDisclosed.title)
+ let title = app.navigationBars.staticTexts.firstMatch.label
+ XCTAssertEqual(title, VectorL10n.pollHistoryActiveSegmentTitle)
+ XCTAssertEqual(app.staticTexts["PollHistoryDetail.date"].label, "1/1/01")
+ XCTAssertEqual(app.buttons["PollHistoryDetail.viewInTimeLineButton"].label, VectorL10n.pollHistoryDetailViewInTimeline)
+ }
+
+ func testPollHistoryDetailClosedPoll() {
+ app.goToScreenWithIdentifier(MockPollHistoryDetailScreenState.closedDisclosed.title)
+ let title = app.navigationBars.staticTexts.firstMatch.label
+ XCTAssertEqual(title, VectorL10n.pollHistoryPastSegmentTitle)
+ XCTAssertEqual(app.staticTexts["PollHistoryDetail.date"].label, "1/1/01")
+ XCTAssertEqual(app.buttons["PollHistoryDetail.viewInTimeLineButton"].label, VectorL10n.pollHistoryDetailViewInTimeline)
+ }
+}
diff --git a/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryDetail/Test/Unit/PollHistoryDetailViewModelTests.swift b/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryDetail/Test/Unit/PollHistoryDetailViewModelTests.swift
new file mode 100644
index 0000000000..a501cbeb0b
--- /dev/null
+++ b/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryDetail/Test/Unit/PollHistoryDetailViewModelTests.swift
@@ -0,0 +1,67 @@
+//
+// Copyright 2021 New Vector Ltd
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+import XCTest
+
+@testable import RiotSwiftUI
+
+class PollHistoryDetailViewModelTests: XCTestCase {
+ private enum Constants {
+ static let counterInitialValue = 0
+ }
+
+ var viewModel: PollHistoryDetailViewModel!
+ var context: PollHistoryDetailViewModelType.Context!
+
+ override func setUpWithError() throws {
+ let answerOptions = [TimelinePollAnswerOption(id: "1", text: "1", count: 1, winner: false, selected: false),
+ TimelinePollAnswerOption(id: "2", text: "2", count: 1, winner: false, selected: false),
+ TimelinePollAnswerOption(id: "3", text: "3", count: 1, winner: false, selected: false)]
+
+ let timelinePoll = TimelinePollDetails(id: "poll-id",
+ question: "Question",
+ answerOptions: answerOptions,
+ closed: false,
+ startDate: .init(),
+ totalAnswerCount: 3,
+ type: .disclosed,
+ eventType: .started,
+ maxAllowedSelections: 1,
+ hasBeenEdited: false,
+ hasDecryptionError: false)
+
+ viewModel = PollHistoryDetailViewModel(poll: timelinePoll)
+ context = viewModel.context
+ }
+
+ func testInitialState() {
+ XCTAssertFalse(context.viewState.isPollClosed)
+ }
+
+ func testProcessAction() {
+ viewModel.completion = { result in
+ XCTAssertEqual(result, .viewInTimeline)
+ }
+ viewModel.process(viewAction: .viewInTimeline)
+ }
+
+ func testProcessDismiss() {
+ viewModel.completion = { result in
+ XCTAssertEqual(result, .dismiss)
+ }
+ viewModel.process(viewAction: .dismiss)
+ }
+}
diff --git a/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryDetail/View/PollHistoryDetail.swift b/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryDetail/View/PollHistoryDetail.swift
new file mode 100644
index 0000000000..54b3279363
--- /dev/null
+++ b/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryDetail/View/PollHistoryDetail.swift
@@ -0,0 +1,111 @@
+//
+// Copyright 2021 New Vector Ltd
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+import SwiftUI
+
+struct PollHistoryDetail: View {
+ // MARK: Private
+
+ @Environment(\.theme) private var theme: ThemeSwiftUI
+
+ // MARK: Public
+
+ @ObservedObject var viewModel: PollHistoryDetailViewModel.Context
+ var contentPoll: any View
+
+ var body: some View {
+ navigation
+ }
+
+ private var navigation: some View {
+ if #available(iOS 16.0, *) {
+ return NavigationStack {
+ content
+ }
+ } else {
+ return NavigationView {
+ content
+ }
+ }
+ }
+
+ private var content: some View {
+ ScrollView {
+ VStack(alignment: .leading) {
+ Text(DateFormatter.pollShortDateFormatter.string(from: viewModel.viewState.pollStartDate))
+ .foregroundColor(theme.colors.tertiaryContent)
+ .font(theme.fonts.caption1)
+ .padding([.top])
+ .accessibilityIdentifier("PollHistoryDetail.date")
+ AnyView(contentPoll)
+ .navigationTitle(navigationTitle)
+ .navigationBarTitleDisplayMode(.inline)
+ .navigationBarBackButtonHidden(true)
+ .navigationBarItems(leading: backButton, trailing: doneButton)
+ viewInTimeline
+ }
+ }
+ .padding([.horizontal], 16)
+ .padding([.top, .bottom])
+ .background(theme.colors.background.ignoresSafeArea())
+ }
+
+ private var backButton: some View {
+ Button(action: {
+ viewModel.send(viewAction: .dismiss)
+ }) {
+ Image(systemName: "chevron.left")
+ .aspectRatio(contentMode: .fit)
+ .foregroundColor(theme.colors.accent)
+ }
+ }
+
+ private var doneButton: some View {
+ Button {
+ viewModel.send(viewAction: .dismiss)
+ } label: {
+ Text(VectorL10n.done)
+ }
+ .accentColor(theme.colors.accent)
+ }
+
+ private var viewInTimeline: some View {
+ Button {
+ viewModel.send(viewAction: .viewInTimeline)
+ } label: {
+ Text(VectorL10n.pollHistoryDetailViewInTimeline)
+ }
+ .accentColor(theme.colors.accent)
+ .accessibilityIdentifier("PollHistoryDetail.viewInTimeLineButton")
+ }
+
+ private var navigationTitle: String {
+ if viewModel.viewState.isPollClosed {
+ return VectorL10n.pollHistoryPastSegmentTitle
+ } else {
+ return VectorL10n.pollHistoryActiveSegmentTitle
+ }
+ }
+}
+
+// MARK: - Previews
+
+struct PollHistoryDetail_Previews: PreviewProvider {
+ static let stateRenderer = MockPollHistoryDetailScreenState.stateRenderer
+ static var previews: some View {
+ stateRenderer.screenGroup()
+ }
+}
diff --git a/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryModels.swift b/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryModels.swift
index 93ef308193..4f4f2a6060 100644
--- a/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryModels.swift
+++ b/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryModels.swift
@@ -16,8 +16,12 @@
// MARK: View model
-enum PollHistoryViewModelResult: Equatable {
- #warning("e.g. show poll detail")
+enum PollHistoryConstants {
+ static let chunkSizeInDays: UInt = 30
+}
+
+enum PollHistoryViewModelResult {
+ case showPollDetail(poll: TimelinePollDetails)
}
// MARK: View
@@ -29,6 +33,7 @@ enum PollHistoryMode: CaseIterable {
struct PollHistoryViewBindings {
var mode: PollHistoryMode
+ var alertInfo: AlertInfo?
}
struct PollHistoryViewState: BindableState {
@@ -37,10 +42,16 @@ struct PollHistoryViewState: BindableState {
}
var bindings: PollHistoryViewBindings
- var polls: [PollListData] = []
+ var isLoading = false
+ var canLoadMoreContent = true
+ var polls: [TimelinePollDetails]?
+ var syncStartDate: Date = .init()
+ var syncedUpTo: Date = .distantFuture
}
enum PollHistoryViewAction {
case viewAppeared
case segmentDidChange
+ case showPollDetail(poll: TimelinePollDetails)
+ case loadMoreContent
}
diff --git a/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryViewModel.swift b/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryViewModel.swift
index 4199251da3..fa02f1a4f4 100644
--- a/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryViewModel.swift
+++ b/RiotSwiftUI/Modules/Room/PollHistory/PollHistoryViewModel.swift
@@ -14,24 +14,22 @@
// limitations under the License.
//
+import Combine
import SwiftUI
typealias PollHistoryViewModelType = StateStoreViewModel
final class PollHistoryViewModel: PollHistoryViewModelType, PollHistoryViewModelProtocol {
private let pollService: PollHistoryServiceProtocol
- private var polls: [PollListData] = []
- private var fetchingTask: Task? {
- didSet {
- oldValue?.cancel()
- }
- }
+ private var polls: [TimelinePollDetails]?
+ private var subcriptions: Set = .init()
var completion: ((PollHistoryViewModelResult) -> Void)?
init(mode: PollHistoryMode, pollService: PollHistoryServiceProtocol) {
self.pollService = pollService
super.init(initialViewState: PollHistoryViewState(mode: mode))
+ state.canLoadMoreContent = pollService.hasNextBatch
}
// MARK: - Public
@@ -39,39 +37,117 @@ final class PollHistoryViewModel: PollHistoryViewModelType, PollHistoryViewModel
override func process(viewAction: PollHistoryViewAction) {
switch viewAction {
case .viewAppeared:
- fetchingTask = fetchPolls()
+ setupUpdateSubscriptions()
+ fetchContent()
case .segmentDidChange:
- updatePolls()
+ updateViewState()
+ case .showPollDetail(let poll):
+ completion?(.showPollDetail(poll: poll))
+ case .loadMoreContent:
+ fetchContent()
}
}
}
private extension PollHistoryViewModel {
- func fetchPolls() -> Task {
- Task {
- let polls = try await pollService.fetchHistory()
-
- guard Task.isCancelled == false else {
- return
+ func fetchContent() {
+ state.isLoading = true
+
+ pollService
+ .nextBatch()
+ .collect()
+ .sink { [weak self] completion in
+ self?.handleBatchEnded(completion: completion)
+ } receiveValue: { [weak self] polls in
+ self?.add(polls: polls)
}
-
- await MainActor.run {
- self.polls = polls
- updatePolls()
+ .store(in: &subcriptions)
+ }
+
+ func handleBatchEnded(completion: Subscribers.Completion) {
+ state.isLoading = false
+ state.canLoadMoreContent = pollService.hasNextBatch
+
+ switch completion {
+ case .finished:
+ break
+ case .failure:
+ polls = polls ?? []
+ state.bindings.alertInfo = .init(id: true, title: VectorL10n.pollHistoryFetchingError)
+ }
+
+ updateViewState()
+ }
+
+ func setupUpdateSubscriptions() {
+ subcriptions.removeAll()
+
+ pollService
+ .updates
+ .sink { [weak self] detail in
+ self?.update(poll: detail)
+ self?.updateViewState()
+ }
+ .store(in: &subcriptions)
+
+ pollService
+ .fetchedUpTo
+ .weakAssign(to: \.state.syncedUpTo, on: self)
+ .store(in: &subcriptions)
+
+ pollService
+ .livePolls
+ .sink { [weak self] livePoll in
+ self?.add(polls: [livePoll])
+ self?.updateViewState()
}
+ .store(in: &subcriptions)
+ }
+
+ func update(poll: TimelinePollDetails) {
+ guard let pollIndex = polls?.firstIndex(where: { $0.id == poll.id }) else {
+ return
}
+
+ polls?[pollIndex] = poll
+ }
+
+ func add(polls: [TimelinePollDetails]) {
+ self.polls = (self.polls ?? []) + polls
}
- func updatePolls() {
- let renderedPolls: [PollListData]
+ func updateViewState() {
+ let renderedPolls: [TimelinePollDetails]?
switch context.mode {
case .active:
- renderedPolls = polls.filter { $0.winningOption == nil }
+ renderedPolls = polls?.filter { $0.closed == false }
case .past:
- renderedPolls = polls.filter { $0.winningOption != nil }
+ renderedPolls = polls?.filter { $0.closed == true }
}
- state.polls = renderedPolls
+ state.polls = renderedPolls?.sorted(by: { $0.startDate > $1.startDate })
+ }
+}
+
+extension PollHistoryViewModel.Context {
+ var emptyPollsText: String {
+ switch (viewState.bindings.mode, viewState.canLoadMoreContent) {
+ case (.active, true):
+ return VectorL10n.pollHistoryNoActivePollPeriodText("\(syncedPastDays)")
+ case (.active, false):
+ return VectorL10n.pollHistoryNoActivePollText
+ case (.past, true):
+ return VectorL10n.pollHistoryNoPastPollPeriodText("\(syncedPastDays)")
+ case (.past, false):
+ return VectorL10n.pollHistoryNoPastPollText
+ }
+ }
+
+ var syncedPastDays: Int {
+ guard let days = Calendar.current.dateComponents([.day], from: viewState.syncedUpTo, to: viewState.syncStartDate).day else {
+ return 0
+ }
+ return max(0, days)
}
}
diff --git a/RiotSwiftUI/Modules/Room/PollHistory/Service/MatrixSDK/PollHistoryService.swift b/RiotSwiftUI/Modules/Room/PollHistory/Service/MatrixSDK/PollHistoryService.swift
index a2dcf256ae..7f6d8c5f6c 100644
--- a/RiotSwiftUI/Modules/Room/PollHistory/Service/MatrixSDK/PollHistoryService.swift
+++ b/RiotSwiftUI/Modules/Room/PollHistory/Service/MatrixSDK/PollHistoryService.swift
@@ -14,11 +14,220 @@
// limitations under the License.
//
-import MatrixSDK
+import Combine
import Foundation
+import MatrixSDK
final class PollHistoryService: PollHistoryServiceProtocol {
- func fetchHistory() async throws -> [PollListData] {
- []
+ private let room: MXRoom
+ private let timeline: MXEventTimeline
+ private let chunkSizeInDays: UInt
+
+ private var timelineListener: Any?
+ private var roomListener: Any?
+
+ // polls aggregation
+ private var pollAggregationContexts: [String: PollAggregationContext] = [:]
+
+ // polls
+ private var currentBatchSubject: PassthroughSubject?
+ private var livePollsSubject: PassthroughSubject = .init()
+
+ // polls updates
+ private let updatesSubject: PassthroughSubject = .init()
+
+ // timestamps
+ private var targetTimestamp: Date = .init()
+ private var oldestEventDateSubject: CurrentValueSubject = .init(.init())
+
+ var updates: AnyPublisher {
+ updatesSubject.eraseToAnyPublisher()
+ }
+
+ init(room: MXRoom, chunkSizeInDays: UInt) {
+ self.room = room
+ self.chunkSizeInDays = chunkSizeInDays
+ timeline = MXRoomEventTimeline(room: room, andInitialEventId: nil)
+ setupTimeline()
+ setupLiveUpdates()
+ }
+
+ func nextBatch() -> AnyPublisher {
+ currentBatchSubject?.eraseToAnyPublisher() ?? startPagination()
+ }
+
+ var hasNextBatch: Bool {
+ timeline.canPaginate(.backwards)
+ }
+
+ var fetchedUpTo: AnyPublisher {
+ oldestEventDateSubject.eraseToAnyPublisher()
+ }
+
+ var livePolls: AnyPublisher {
+ livePollsSubject.eraseToAnyPublisher()
+ }
+
+ deinit {
+ guard let roomListener = roomListener else {
+ return
+ }
+ room.removeListener(roomListener)
+ }
+
+ class PollAggregationContext {
+ var pollAggregator: PollAggregator?
+ let isLivePoll: Bool
+ var published: Bool
+
+ init(pollAggregator: PollAggregator? = nil, isLivePoll: Bool, published: Bool = false) {
+ self.pollAggregator = pollAggregator
+ self.isLivePoll = isLivePoll
+ self.published = published
+ }
+ }
+}
+
+private extension PollHistoryService {
+ enum Constants {
+ static let pageSize: UInt = 250
+ }
+
+ func setupTimeline() {
+ timeline.resetPagination()
+
+ timelineListener = timeline.listenToEvents { [weak self] event, _, _ in
+ if event.eventType == .pollStart {
+ self?.aggregatePoll(pollStartEvent: event, isLivePoll: false)
+ }
+
+ self?.updateTimestamp(event: event)
+ }
+ }
+
+ func setupLiveUpdates() {
+ roomListener = room.listen(toEventsOfTypes: [kMXEventTypeStringPollStart, kMXEventTypeStringPollStartMSC3381]) { [weak self] event, _, _ in
+ if event.eventType == .pollStart {
+ self?.aggregatePoll(pollStartEvent: event, isLivePoll: true)
+ }
+ }
+ }
+
+ func updateTimestamp(event: MXEvent) {
+ oldestEventDate = min(event.originServerDate, oldestEventDate)
+ }
+
+ func startPagination() -> AnyPublisher {
+ let startingTimestamp = oldestEventDate
+ targetTimestamp = startingTimestamp.subtractingDays(chunkSizeInDays) ?? startingTimestamp
+
+ let batchSubject = PassthroughSubject()
+ currentBatchSubject = batchSubject
+
+ DispatchQueue.main.async { [weak self] in
+ guard let self = self else {
+ return
+ }
+ self.paginate()
+ }
+
+ return batchSubject.eraseToAnyPublisher()
+ }
+
+ func paginate() {
+ timeline.paginate(Constants.pageSize, direction: .backwards, onlyFromStore: false) { [weak self] response in
+ guard let self = self else {
+ return
+ }
+
+ switch response {
+ case .success:
+ if self.timeline.canPaginate(.backwards), self.timestampTargetReached == false {
+ self.paginate()
+ } else {
+ self.completeBatch(completion: .finished)
+ }
+ case .failure(let error):
+ self.completeBatch(completion: .failure(error))
+ }
+ }
+ }
+
+ func completeBatch(completion: Subscribers.Completion) {
+ currentBatchSubject?.send(completion: completion)
+ currentBatchSubject = nil
+ }
+
+ func aggregatePoll(pollStartEvent: MXEvent, isLivePoll: Bool) {
+ let eventId: String = pollStartEvent.eventId
+
+ guard pollAggregationContexts[eventId] == nil else {
+ return
+ }
+
+ let newContext: PollAggregationContext = .init(isLivePoll: isLivePoll)
+ pollAggregationContexts[eventId] = newContext
+
+ do {
+ newContext.pollAggregator = try PollAggregator(session: room.mxSession, room: room, pollEvent: pollStartEvent, delegate: self)
+ } catch {
+ pollAggregationContexts.removeValue(forKey: eventId)
+ }
+ }
+
+ var timestampTargetReached: Bool {
+ oldestEventDate <= targetTimestamp
+ }
+
+ var oldestEventDate: Date {
+ get {
+ oldestEventDateSubject.value
+ }
+ set {
+ oldestEventDateSubject.send(newValue)
+ }
+ }
+}
+
+private extension Date {
+ func subtractingDays(_ days: UInt) -> Date? {
+ Calendar.current.date(byAdding: DateComponents(day: -Int(days)), to: self)
+ }
+}
+
+private extension MXEvent {
+ var originServerDate: Date {
+ .init(timeIntervalSince1970: Double(originServerTs) / 1000)
+ }
+}
+
+// MARK: - PollAggregatorDelegate
+
+extension PollHistoryService: PollAggregatorDelegate {
+ func pollAggregatorDidStartLoading(_ aggregator: PollAggregator) { }
+
+ func pollAggregator(_ aggregator: PollAggregator, didFailWithError: Error) { }
+
+ func pollAggregatorDidEndLoading(_ aggregator: PollAggregator) {
+ guard let context = pollAggregationContexts[aggregator.poll.id], context.published == false else {
+ return
+ }
+
+ context.published = true
+
+ let newPoll: TimelinePollDetails = .init(poll: aggregator.poll, represent: .started)
+
+ if context.isLivePoll {
+ livePollsSubject.send(newPoll)
+ } else {
+ currentBatchSubject?.send(newPoll)
+ }
+ }
+
+ func pollAggregatorDidUpdateData(_ aggregator: PollAggregator) {
+ guard let context = pollAggregationContexts[aggregator.poll.id], context.published else {
+ return
+ }
+ updatesSubject.send(.init(poll: aggregator.poll, represent: .started))
}
}
diff --git a/RiotSwiftUI/Modules/Room/PollHistory/Service/Mock/MockPollHistoryService.swift b/RiotSwiftUI/Modules/Room/PollHistory/Service/Mock/MockPollHistoryService.swift
index 62796963de..c98f4e136d 100644
--- a/RiotSwiftUI/Modules/Room/PollHistory/Service/Mock/MockPollHistoryService.swift
+++ b/RiotSwiftUI/Modules/Room/PollHistory/Service/Mock/MockPollHistoryService.swift
@@ -1,4 +1,4 @@
-//
+//
// Copyright 2023 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,31 +14,70 @@
// limitations under the License.
//
+import Combine
+
final class MockPollHistoryService: PollHistoryServiceProtocol {
- var activePollsData: [PollListData] = (1..<10)
- .map { index in
- PollListData(
- startDate: .init().addingTimeInterval(-CGFloat(index) * 3600),
- question: "Do you like the active poll number \(index)?",
- numberOfVotes: 30,
- winningOption: nil
- )
- }
+ lazy var nextBatchPublishers: [AnyPublisher] = [
+ (activePollsData + pastPollsData)
+ .publisher
+ .setFailureType(to: Error.self)
+ .eraseToAnyPublisher()
+ ]
+
+ func nextBatch() -> AnyPublisher {
+ nextBatchPublishers.isEmpty ? Empty().eraseToAnyPublisher() : nextBatchPublishers.removeFirst()
+ }
+
+ var updatesPublisher: AnyPublisher = Empty().eraseToAnyPublisher()
+ var updates: AnyPublisher {
+ updatesPublisher
+ }
+
+ var hasNextBatch = true
- var pastPollsData: [PollListData] = (1..<10)
- .map { index in
- PollListData(
- startDate: .init().addingTimeInterval(-CGFloat(index) * 3600),
- question: "Do you like the past poll number \(index)?",
- numberOfVotes: 30,
- winningOption: .init(id: "id", text: "Yes, of course!", count: 20, winner: true, selected: true)
- )
- }
+ var fetchedUpToPublisher: AnyPublisher = Just(.init()).eraseToAnyPublisher()
+ var fetchedUpTo: AnyPublisher {
+ fetchedUpToPublisher
+ }
+
+ var livePollsPublisher: AnyPublisher = Empty().eraseToAnyPublisher()
+ var livePolls: AnyPublisher {
+ livePollsPublisher
+ }
+}
- func fetchHistory() async throws -> [PollListData] {
- (activePollsData + pastPollsData)
- .sorted { poll1, poll2 in
- poll1.startDate > poll2.startDate
+private extension MockPollHistoryService {
+ var activePollsData: [TimelinePollDetails] {
+ (1...3)
+ .map { index in
+ TimelinePollDetails(id: "a\(index)",
+ question: "Do you like the active poll number \(index)?",
+ answerOptions: [],
+ closed: false,
+ startDate: .init().addingTimeInterval(TimeInterval(-index) * 3600 * 24),
+ totalAnswerCount: 30,
+ type: .disclosed,
+ eventType: .started,
+ maxAllowedSelections: 1,
+ hasBeenEdited: false,
+ hasDecryptionError: false)
+ }
+ }
+
+ var pastPollsData: [TimelinePollDetails] {
+ (1...3)
+ .map { index in
+ TimelinePollDetails(id: "p\(index)",
+ question: "Do you like the active poll number \(index)?",
+ answerOptions: [.init(id: "id", text: "Yes, of course!", count: 20, winner: true, selected: true)],
+ closed: true,
+ startDate: .init().addingTimeInterval(TimeInterval(-index) * 3600 * 24),
+ totalAnswerCount: 30,
+ type: .disclosed,
+ eventType: .started,
+ maxAllowedSelections: 1,
+ hasBeenEdited: false,
+ hasDecryptionError: false)
}
}
}
diff --git a/RiotSwiftUI/Modules/Room/PollHistory/Service/PollHistoryServiceProtocol.swift b/RiotSwiftUI/Modules/Room/PollHistory/Service/PollHistoryServiceProtocol.swift
index 4bb9b43b53..5132478cc8 100644
--- a/RiotSwiftUI/Modules/Room/PollHistory/Service/PollHistoryServiceProtocol.swift
+++ b/RiotSwiftUI/Modules/Room/PollHistory/Service/PollHistoryServiceProtocol.swift
@@ -1,4 +1,4 @@
-//
+//
// Copyright 2023 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,6 +14,24 @@
// limitations under the License.
//
+import Combine
+
protocol PollHistoryServiceProtocol {
- func fetchHistory() async throws -> [PollListData]
+ /// Returns a Publisher publishing the polls in the next batch.
+ /// Implementations should return the same publisher if `nextBatch()` is called again before the previous publisher completes.
+ func nextBatch() -> AnyPublisher
+
+ /// Publishes updates for the polls previously pusblished by the `nextBatch()` or `livePolls` publishers.
+ var updates: AnyPublisher { get }
+
+ /// Publishes live polls not related with the current batch.
+ var livePolls: AnyPublisher { get }
+
+ /// Returns true every time the service can fetch another batch.
+ /// There is no guarantee the `nextBatch()` returned publisher will publish something anyway.
+ var hasNextBatch: Bool { get }
+
+ /// Publishes the date up to the service is synced (in the past).
+ /// This date doesn't need to be related with any poll event.
+ var fetchedUpTo: AnyPublisher { get }
}
diff --git a/RiotSwiftUI/Modules/Room/PollHistory/Test/UI/PollHistoryUITests.swift b/RiotSwiftUI/Modules/Room/PollHistory/Test/UI/PollHistoryUITests.swift
index 5867b88e8f..ddce4978ca 100644
--- a/RiotSwiftUI/Modules/Room/PollHistory/Test/UI/PollHistoryUITests.swift
+++ b/RiotSwiftUI/Modules/Room/PollHistory/Test/UI/PollHistoryUITests.swift
@@ -17,13 +17,14 @@
import RiotSwiftUI
import XCTest
-class PollHistoryUITests: MockScreenTestCase {
+final class PollHistoryUITests: MockScreenTestCase {
func testActivePollHistoryHasContent() {
app.goToScreenWithIdentifier(MockPollHistoryScreenState.active.title)
let title = app.navigationBars.firstMatch.identifier
let emptyText = app.staticTexts["PollHistory.emptyText"]
let items = app.staticTexts["PollListItem.title"]
let selectedSegment = app.buttons[VectorL10n.pollHistoryActiveSegmentTitle]
+ let loadMoreButton = app.buttons["PollHistory.loadMore"]
let winningOption = app.staticTexts["PollListData.winningOption"]
XCTAssertEqual(title, VectorL10n.pollHistoryTitle)
@@ -31,6 +32,7 @@ class PollHistoryUITests: MockScreenTestCase {
XCTAssertFalse(emptyText.exists)
XCTAssertTrue(selectedSegment.exists)
XCTAssertEqual(selectedSegment.value as? String, VectorL10n.accessibilitySelected)
+ XCTAssertTrue(loadMoreButton.exists)
XCTAssertFalse(winningOption.exists)
}
@@ -40,29 +42,74 @@ class PollHistoryUITests: MockScreenTestCase {
let emptyText = app.staticTexts["PollHistory.emptyText"]
let items = app.staticTexts["PollListItem.title"]
let selectedSegment = app.buttons[VectorL10n.pollHistoryPastSegmentTitle]
- let winningOption = app.staticTexts["PollListData.winningOption"]
+ let loadMoreButton = app.buttons["PollHistory.loadMore"]
+ let winningOption = app.buttons["PollAnswerOption0"]
XCTAssertEqual(title, VectorL10n.pollHistoryTitle)
XCTAssertTrue(items.exists)
XCTAssertFalse(emptyText.exists)
XCTAssertTrue(selectedSegment.exists)
XCTAssertEqual(selectedSegment.value as? String, VectorL10n.accessibilitySelected)
+ XCTAssertTrue(loadMoreButton.exists)
XCTAssertTrue(winningOption.exists)
}
- func testPastPollHistoryIsEmpty() {
- app.goToScreenWithIdentifier(MockPollHistoryScreenState.pastEmpty.title)
+ func testActivePollHistoryHasContentAndCantLoadMore() {
+ app.goToScreenWithIdentifier(MockPollHistoryScreenState.activeNoMoreContent.title)
+ let emptyText = app.staticTexts["PollHistory.emptyText"]
+ let items = app.staticTexts["PollListItem.title"]
+ let loadMoreButton = app.buttons["PollHistory.loadMore"]
+
+ XCTAssertTrue(items.exists)
+ XCTAssertFalse(emptyText.exists)
+ XCTAssertFalse(loadMoreButton.exists)
+ }
+
+ func testActivePollHistoryHasContentAndCanLoadMore() {
+ app.goToScreenWithIdentifier(MockPollHistoryScreenState.contentLoading.title)
let title = app.navigationBars.firstMatch.identifier
let emptyText = app.staticTexts["PollHistory.emptyText"]
let items = app.staticTexts["PollListItem.title"]
- let selectedSegment = app.buttons[VectorL10n.pollHistoryPastSegmentTitle]
- let winningOption = app.staticTexts["PollListData.winningOption"]
+ let loadMoreButton = app.buttons["PollHistory.loadMore"]
+
+ XCTAssertTrue(items.exists)
+ XCTAssertFalse(emptyText.exists)
+ XCTAssertTrue(loadMoreButton.exists)
+ XCTAssertFalse(loadMoreButton.isEnabled)
+ }
+
+ func testActivePollHistoryEmptyAndCanLoadMore() {
+ app.goToScreenWithIdentifier(MockPollHistoryScreenState.empty.title)
+ let emptyText = app.staticTexts["PollHistory.emptyText"]
+ let items = app.staticTexts["PollListItem.title"]
+ let loadMoreButton = app.buttons["PollHistory.loadMore"]
- XCTAssertEqual(title, VectorL10n.pollHistoryTitle)
XCTAssertFalse(items.exists)
XCTAssertTrue(emptyText.exists)
- XCTAssertTrue(selectedSegment.exists)
- XCTAssertEqual(selectedSegment.value as? String, VectorL10n.accessibilitySelected)
- XCTAssertFalse(winningOption.exists)
+ XCTAssertTrue(loadMoreButton.exists)
+ XCTAssertTrue(loadMoreButton.isEnabled)
+ }
+
+ func testActivePollHistoryEmptyAndLoading() {
+ app.goToScreenWithIdentifier(MockPollHistoryScreenState.emptyLoading.title)
+ let emptyText = app.staticTexts["PollHistory.emptyText"]
+ let items = app.staticTexts["PollListItem.title"]
+ let loadMoreButton = app.buttons["PollHistory.loadMore"]
+
+ XCTAssertFalse(items.exists)
+ XCTAssertTrue(emptyText.exists)
+ XCTAssertTrue(loadMoreButton.exists)
+ XCTAssertFalse(loadMoreButton.isEnabled)
+ }
+
+ func testActivePollHistoryEmptyAndCantLoadMore() {
+ app.goToScreenWithIdentifier(MockPollHistoryScreenState.emptyNoMoreContent.title)
+ let emptyText = app.staticTexts["PollHistory.emptyText"]
+ let items = app.staticTexts["PollListItem.title"]
+ let loadMoreButton = app.buttons["PollHistory.loadMore"]
+
+ XCTAssertFalse(items.exists)
+ XCTAssertTrue(emptyText.exists)
+ XCTAssertFalse(loadMoreButton.exists)
}
}
diff --git a/RiotSwiftUI/Modules/Room/PollHistory/Test/Unit/PollHistoryViewModelTests.swift b/RiotSwiftUI/Modules/Room/PollHistory/Test/Unit/PollHistoryViewModelTests.swift
new file mode 100644
index 0000000000..efce641d4e
--- /dev/null
+++ b/RiotSwiftUI/Modules/Room/PollHistory/Test/Unit/PollHistoryViewModelTests.swift
@@ -0,0 +1,135 @@
+//
+// Copyright 2023 New Vector Ltd
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+import Combine
+@testable import RiotSwiftUI
+import XCTest
+
+final class PollHistoryViewModelTests: XCTestCase {
+ private var viewModel: PollHistoryViewModel!
+ private var pollHistoryService: MockPollHistoryService = .init()
+
+ override func setUpWithError() throws {
+ pollHistoryService = .init()
+ viewModel = .init(mode: .active, pollService: pollHistoryService)
+ }
+
+ func testEmitsContentOnLanding() throws {
+ XCTAssert(viewModel.state.polls == nil)
+ viewModel.process(viewAction: .viewAppeared)
+ XCTAssertFalse(try polls.isEmpty)
+ }
+
+ func testLoadingState() throws {
+ XCTAssertFalse(viewModel.state.isLoading)
+ viewModel.process(viewAction: .viewAppeared)
+ XCTAssertFalse(viewModel.state.isLoading)
+ XCTAssertFalse(try polls.isEmpty)
+ }
+
+ func testLoadingStateIsTrueWhileLoading() {
+ XCTAssertFalse(viewModel.state.isLoading)
+ pollHistoryService.nextBatchPublishers = [MockPollPublisher.loadingPolls, MockPollPublisher.emptyPolls]
+ viewModel.process(viewAction: .viewAppeared)
+ XCTAssertTrue(viewModel.state.isLoading)
+ viewModel.process(viewAction: .viewAppeared)
+ XCTAssertFalse(viewModel.state.isLoading)
+ }
+
+ func testUpdatesAreHandled() throws {
+ let mockUpdates: PassthroughSubject = .init()
+ pollHistoryService.updatesPublisher = mockUpdates.eraseToAnyPublisher()
+ viewModel.process(viewAction: .viewAppeared)
+
+ var firstPoll = try XCTUnwrap(try polls.first)
+ XCTAssertEqual(firstPoll.question, "Do you like the active poll number 1?")
+ firstPoll.question = "foo"
+
+ mockUpdates.send(firstPoll)
+
+ let updatedPoll = try XCTUnwrap(viewModel.state.polls?.first)
+ XCTAssertEqual(updatedPoll.question, "foo")
+ }
+
+ func testSegmentsAreUpdated() throws {
+ viewModel.process(viewAction: .viewAppeared)
+ XCTAssertFalse(try polls.isEmpty)
+ XCTAssertTrue(try polls.allSatisfy { !$0.closed })
+
+ viewModel.state.bindings.mode = .past
+ viewModel.process(viewAction: .segmentDidChange)
+
+ XCTAssertTrue(try polls.allSatisfy(\.closed))
+ }
+
+ func testPollsAreReverseOrdered() throws {
+ viewModel.process(viewAction: .viewAppeared)
+
+ let pollDates = try polls.map(\.startDate)
+ XCTAssertEqual(pollDates, pollDates.sorted(by: { $0 > $1 }))
+ }
+
+ func testLivePollsAreHandled() throws {
+ pollHistoryService.nextBatchPublishers = [MockPollPublisher.emptyPolls]
+ pollHistoryService.livePollsPublisher = Just(mockPoll).eraseToAnyPublisher()
+ viewModel.process(viewAction: .viewAppeared)
+ XCTAssertEqual(viewModel.state.polls?.count, 1)
+ XCTAssertEqual(viewModel.state.polls?.first?.id, "id")
+ }
+
+ func testLivePollsDontChangeLoadingState() throws {
+ let livePolls = PassthroughSubject()
+ pollHistoryService.nextBatchPublishers = [MockPollPublisher.loadingPolls]
+ pollHistoryService.livePollsPublisher = livePolls.eraseToAnyPublisher()
+ viewModel.process(viewAction: .viewAppeared)
+ XCTAssertTrue(viewModel.state.isLoading)
+ XCTAssertNil(viewModel.state.polls)
+ livePolls.send(mockPoll)
+ XCTAssertTrue(viewModel.state.isLoading)
+ XCTAssertNotNil(viewModel.state.polls)
+ XCTAssertEqual(viewModel.state.polls?.count, 1)
+ }
+
+ func testAfterFailureCompletionIsCalled() throws {
+ pollHistoryService.nextBatchPublishers = [MockPollPublisher.failure]
+ viewModel.process(viewAction: .viewAppeared)
+ XCTAssertFalse(viewModel.state.isLoading)
+ XCTAssertNotNil(viewModel.state.polls)
+ XCTAssertNotNil(viewModel.state.bindings.alertInfo)
+ }
+}
+
+private extension PollHistoryViewModelTests {
+ var polls: [TimelinePollDetails] {
+ get throws {
+ try XCTUnwrap(viewModel.state.polls)
+ }
+ }
+
+ var mockPoll: TimelinePollDetails {
+ .init(id: "id",
+ question: "Do you like polls?",
+ answerOptions: [],
+ closed: false,
+ startDate: .init(),
+ totalAnswerCount: 3,
+ type: .undisclosed,
+ eventType: .started,
+ maxAllowedSelections: 1,
+ hasBeenEdited: false,
+ hasDecryptionError: false)
+ }
+}
diff --git a/RiotSwiftUI/Modules/Room/PollHistory/View/PollHistory.swift b/RiotSwiftUI/Modules/Room/PollHistory/View/PollHistory.swift
index 7cf9bb45aa..612f85089f 100644
--- a/RiotSwiftUI/Modules/Room/PollHistory/View/PollHistory.swift
+++ b/RiotSwiftUI/Modules/Room/PollHistory/View/PollHistory.swift
@@ -31,11 +31,7 @@ struct PollHistory: View {
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal, 16)
- if viewModel.viewState.polls.isEmpty {
- noPollsView
- } else {
- pollListView
- }
+ content
}
.padding(.top, 32)
.frame(maxWidth: .infinity, maxHeight: .infinity)
@@ -48,37 +44,94 @@ struct PollHistory: View {
.onChange(of: viewModel.mode) { _ in
viewModel.send(viewAction: .segmentDidChange)
}
+ .alert(item: $viewModel.alertInfo) {
+ $0.alert
+ }
+ }
+
+ @ViewBuilder
+ private var content: some View {
+ if viewModel.viewState.polls == nil {
+ loadingView
+ } else if viewModel.viewState.polls?.isEmpty == true {
+ noPollsView
+ } else {
+ pollListView
+ }
}
private var pollListView: some View {
ScrollView {
LazyVStack(spacing: 32) {
- let enumeratedPolls = Array(viewModel.viewState.polls.enumerated())
-
- ForEach(enumeratedPolls, id: \.offset) { _, pollData in
- PollListItem(pollData: pollData)
+ ForEach(viewModel.viewState.polls ?? []) { pollData in
+ Button(action: {
+ viewModel.send(viewAction: .showPollDetail(poll: pollData))
+ }) {
+ PollListItem(pollData: pollData)
+ }
}
.frame(maxWidth: .infinity, alignment: .leading)
+
+ loadMoreButton
+ .frame(maxWidth: .infinity, alignment: .leading)
+ }
+ .padding(.top, 32)
+ .padding(.horizontal, 16)
+ }
+ }
+
+ @ViewBuilder
+ private var loadMoreButton: some View {
+ if viewModel.viewState.canLoadMoreContent {
+ HStack(spacing: 8) {
+ if viewModel.viewState.isLoading {
+ spinner
+ }
Button {
- #warning("handle action")
+ viewModel.send(viewAction: .loadMoreContent)
} label: {
- Text("Load more polls")
+ Text(VectorL10n.pollHistoryLoadMore)
+ .font(theme.fonts.body)
}
- .frame(maxWidth: .infinity, alignment: .leading)
+ .accessibilityIdentifier("PollHistory.loadMore")
+ .disabled(viewModel.viewState.isLoading)
}
- .padding(.top, 32)
- .padding(.horizontal, 16)
}
}
+ private var spinner: some View {
+ ProgressView()
+ .progressViewStyle(CircularProgressViewStyle())
+ }
+
private var noPollsView: some View {
- Text(viewModel.mode == .active ? VectorL10n.pollHistoryNoActivePollText : VectorL10n.pollHistoryNoPastPollText)
- .font(theme.fonts.body)
- .foregroundColor(theme.colors.secondaryContent)
- .frame(maxHeight: .infinity)
- .padding(.horizontal, 16)
- .accessibilityLabel("PollHistory.emptyText")
+ VStack(spacing: 32) {
+ Text(viewModel.emptyPollsText)
+ .font(theme.fonts.body)
+ .multilineTextAlignment(.center)
+ .foregroundColor(theme.colors.secondaryContent)
+ .padding(.horizontal, 16)
+ .accessibilityIdentifier("PollHistory.emptyText")
+
+ if viewModel.viewState.canLoadMoreContent {
+ loadMoreButton
+ }
+ }
+ .frame(maxHeight: .infinity)
+ }
+
+ private var loadingView: some View {
+ HStack(spacing: 8) {
+ spinner
+
+ Text(VectorL10n.pollHistoryLoadingText)
+ .font(theme.fonts.body)
+ .foregroundColor(theme.colors.secondaryContent)
+ .frame(maxHeight: .infinity)
+ .accessibilityIdentifier("PollHistory.loadingText")
+ }
+ .padding(.horizontal, 16)
}
}
diff --git a/RiotSwiftUI/Modules/Room/PollHistory/View/PollListItem.swift b/RiotSwiftUI/Modules/Room/PollHistory/View/PollListItem.swift
index 335d62c397..6ee1b0ddfb 100644
--- a/RiotSwiftUI/Modules/Room/PollHistory/View/PollListItem.swift
+++ b/RiotSwiftUI/Modules/Room/PollHistory/View/PollListItem.swift
@@ -16,26 +16,19 @@
import SwiftUI
-struct PollListData {
- let startDate: Date
- let question: String
- let numberOfVotes: UInt
- let winningOption: TimelinePollAnswerOption?
-}
-
struct PollListItem: View {
@Environment(\.theme) private var theme
- private let pollData: PollListData
+ private let pollData: TimelinePollDetails
@ScaledMetric private var imageSize = 16
- init(pollData: PollListData) {
+ init(pollData: TimelinePollDetails) {
self.pollData = pollData
}
var body: some View {
VStack(alignment: .leading, spacing: 12) {
- Text(pollData.formattedDate)
+ Text(DateFormatter.pollShortDateFormatter.string(from: pollData.startDate))
.foregroundColor(theme.colors.tertiaryContent)
.font(theme.fonts.caption1)
@@ -50,59 +43,24 @@ struct PollListItem: View {
.lineLimit(2)
.accessibilityLabel("PollListItem.title")
}
+ .frame(maxWidth: .infinity, alignment: .leading)
- if pollData.winningOption != nil {
+ if pollData.closed {
VStack(alignment: .leading, spacing: 12) {
- optionView(winningOption: pollData.winningOption!)
+ let winningOptions = pollData.answerOptions.filter(\.winner)
+
+ ForEach(winningOptions) {
+ TimelinePollAnswerOptionButton(poll: pollData, answerOption: $0, action: nil)
+ }
+
resultView
}
}
}
}
- private var clipShape: some Shape {
- RoundedRectangle(cornerRadius: 4.0)
- }
-
- private func optionView(winningOption: TimelinePollAnswerOption) -> some View {
- VStack(alignment: .leading, spacing: 12.0) {
- HStack(alignment: .top, spacing: 8.0) {
- Text(pollData.winningOption!.text)
- .font(theme.fonts.body)
- .foregroundColor(theme.colors.primaryContent)
- .accessibilityIdentifier("PollListData.winningOption")
-
- Spacer()
-
- votesText(winningOption: winningOption)
- }
-
- ProgressView(value: Double(winningOption.count),
- total: Double(pollData.numberOfVotes))
- .progressViewStyle(LinearProgressViewStyle())
- .scaleEffect(x: 1.0, y: 1.2, anchor: .center)
- }
- .frame(maxWidth: .infinity, alignment: .leading)
- .padding(.horizontal, 8.0)
- .padding(.top, 12.0)
- .padding(.bottom, 12.0)
- .clipShape(clipShape)
- .overlay(clipShape.stroke(theme.colors.accent, lineWidth: 1.0))
- .accentColor(theme.colors.accent)
- }
-
- private func votesText(winningOption: TimelinePollAnswerOption) -> some View {
- Label {
- Text(winningOption.count == 1 ? VectorL10n.pollTimelineOneVote : VectorL10n.pollTimelineVotesCount(Int(winningOption.count)))
- .font(theme.fonts.footnote)
- .foregroundColor(theme.colors.accent)
- } icon: {
- Image(uiImage: Asset.Images.pollWinnerIcon.image)
- }
- }
-
private var resultView: some View {
- let text = pollData.numberOfVotes == 1 ? VectorL10n.pollTimelineTotalFinalResultsOneVote : VectorL10n.pollTimelineTotalFinalResults(Int(pollData.numberOfVotes))
+ let text = pollData.totalAnswerCount == 1 ? VectorL10n.pollTimelineTotalFinalResultsOneVote : VectorL10n.pollTimelineTotalFinalResults(Int(pollData.totalAnswerCount))
return Text(text)
.font(theme.fonts.footnote)
@@ -110,14 +68,8 @@ struct PollListItem: View {
}
}
-private extension PollListData {
- var formattedDate: String {
- DateFormatter.shortDateFormatter.string(from: startDate)
- }
-}
-
-private extension DateFormatter {
- static let shortDateFormatter: DateFormatter = {
+extension DateFormatter {
+ static let pollShortDateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.timeStyle = .none
formatter.dateStyle = .short
@@ -131,22 +83,48 @@ private extension DateFormatter {
struct PollListItem_Previews: PreviewProvider {
static var previews: some View {
Group {
- let pollData1 = PollListData(
- startDate: .init(),
- question: "Do you like polls?",
- numberOfVotes: 30,
- winningOption: .init(id: "id", text: "Yes, of course!", count: 18, winner: true, selected: true)
- )
-
- PollListItem(pollData: pollData1)
-
- let pollData2 = PollListData(
- startDate: .init(),
- question: "Do you like polls?",
- numberOfVotes: 30,
- winningOption: nil)
+ let pollData1 = TimelinePollDetails(id: UUID().uuidString,
+ question: "Do you like polls?",
+ answerOptions: [.init(id: "id", text: "Yes, of course!", count: 18, winner: true, selected: true)],
+ closed: true,
+ startDate: .init(),
+ totalAnswerCount: 30,
+ type: .disclosed,
+ eventType: .started,
+ maxAllowedSelections: 1,
+ hasBeenEdited: false,
+ hasDecryptionError: false)
+
+ let pollData2 = TimelinePollDetails(id: UUID().uuidString,
+ question: "Do you like polls?",
+ answerOptions: [.init(id: "id", text: "Yes, of course!", count: 18, winner: true, selected: true)],
+ closed: false,
+ startDate: .init(),
+ totalAnswerCount: 30,
+ type: .disclosed,
+ eventType: .started,
+ maxAllowedSelections: 1,
+ hasBeenEdited: false,
+ hasDecryptionError: false)
- PollListItem(pollData: pollData2)
+ let pollData3 = TimelinePollDetails(id: UUID().uuidString,
+ question: "Do you like polls?",
+ answerOptions: [
+ .init(id: "id1", text: "Yes, of course!", count: 15, winner: true, selected: true),
+ .init(id: "id2", text: "No, I don't :-(", count: 15, winner: true, selected: true)
+ ],
+ closed: true,
+ startDate: .init(),
+ totalAnswerCount: 30,
+ type: .disclosed,
+ eventType: .started,
+ maxAllowedSelections: 1,
+ hasBeenEdited: false,
+ hasDecryptionError: false)
+
+ ForEach([pollData1, pollData2, pollData3]) { poll in
+ PollListItem(pollData: poll)
+ }
}
.padding()
}
diff --git a/RiotSwiftUI/Modules/Room/PollHistory/View/SegmentedPicker.swift b/RiotSwiftUI/Modules/Room/PollHistory/View/SegmentedPicker.swift
index 520a649c7a..14b53d6446 100644
--- a/RiotSwiftUI/Modules/Room/PollHistory/View/SegmentedPicker.swift
+++ b/RiotSwiftUI/Modules/Room/PollHistory/View/SegmentedPicker.swift
@@ -39,7 +39,7 @@ struct SegmentedPicker: View {
} label: {
Text(segment.description)
.font(isSelectedSegment ? theme.fonts.headline : theme.fonts.body)
- .underline(isSelectedSegment)
+ .underlineBar(isSelectedSegment)
}
.accentColor(isSelectedSegment ? theme.colors.accent : theme.colors.primaryContent)
.accessibilityLabel(segment.description)
@@ -49,6 +49,23 @@ struct SegmentedPicker: View {
}
}
+private extension Text {
+ @ViewBuilder
+ func underlineBar(_ isActive: Bool) -> some View {
+ if #available(iOS 15.0, *) {
+ overlay(alignment: .bottom) {
+ if isActive {
+ Rectangle()
+ .frame(height: 1)
+ .offset(y: 2)
+ }
+ }
+ } else {
+ underline(isActive)
+ }
+ }
+}
+
struct SegmentedPicker_Previews: PreviewProvider {
static var previews: some View {
SegmentedPicker(
diff --git a/RiotSwiftUI/Modules/Room/TimelinePoll/Coordinator/TimelinePollCoordinator.swift b/RiotSwiftUI/Modules/Room/TimelinePoll/Coordinator/TimelinePollCoordinator.swift
index c3c1cf3270..3214fae658 100644
--- a/RiotSwiftUI/Modules/Room/TimelinePoll/Coordinator/TimelinePollCoordinator.swift
+++ b/RiotSwiftUI/Modules/Room/TimelinePoll/Coordinator/TimelinePollCoordinator.swift
@@ -33,7 +33,7 @@ final class TimelinePollCoordinator: Coordinator, Presentable, PollAggregatorDel
private let selectedAnswerIdentifiersSubject = PassthroughSubject<[String], Never>()
private var pollAggregator: PollAggregator
- private var viewModel: TimelinePollViewModelProtocol!
+ private(set) var viewModel: TimelinePollViewModelProtocol!
private var cancellables = Set()
// MARK: Public
@@ -86,6 +86,10 @@ final class TimelinePollCoordinator: Coordinator, Presentable, PollAggregatorDel
func toPresentable() -> UIViewController {
VectorHostingController(rootView: TimelinePollView(viewModel: viewModel.context))
}
+
+ func toView() -> any View {
+ TimelinePollView(viewModel: viewModel.context)
+ }
func canEndPoll() -> Bool {
pollAggregator.poll.isClosed == false
@@ -114,10 +118,17 @@ final class TimelinePollCoordinator: Coordinator, Presentable, PollAggregatorDel
func pollAggregator(_ aggregator: PollAggregator, didFailWithError: Error) { }
// MARK: - Private
-
- // PollProtocol is intentionally not available in the SwiftUI target as we don't want
- // to add the SDK as a dependency to it. We need to translate from one to the other on this level.
+
func buildTimelinePollFrom(_ poll: PollProtocol) -> TimelinePollDetails {
+ let representedType: TimelinePollEventType = parameters.pollEvent.eventType == .pollStart ? .started : .ended
+ return .init(poll: poll, represent: representedType)
+ }
+}
+
+// PollProtocol is intentionally not available in the SwiftUI target as we don't want
+// to add the SDK as a dependency to it. We need to translate from one to the other on this level.
+extension TimelinePollDetails {
+ init(poll: PollProtocol, represent eventType: TimelinePollEventType) {
let answerOptions = poll.answerOptions.map { pollAnswerOption in
TimelinePollAnswerOption(id: pollAnswerOption.id,
text: pollAnswerOption.text,
@@ -126,21 +137,27 @@ final class TimelinePollCoordinator: Coordinator, Presentable, PollAggregatorDel
selected: pollAnswerOption.isCurrentUserSelection)
}
- return TimelinePollDetails(question: poll.text,
- answerOptions: answerOptions,
- closed: poll.isClosed,
- totalAnswerCount: poll.totalAnswerCount,
- type: pollKindToTimelinePollType(poll.kind),
- eventType: parameters.pollEvent.eventType == .pollStart ? .started : .ended,
- maxAllowedSelections: poll.maxAllowedSelections,
- hasBeenEdited: poll.hasBeenEdited,
- hasDecryptionError: poll.hasDecryptionError)
+ self.init(id: poll.id,
+ question: poll.text,
+ answerOptions: answerOptions,
+ closed: poll.isClosed,
+ startDate: poll.startDate,
+ totalAnswerCount: poll.totalAnswerCount,
+ type: poll.kind.timelinePollType,
+ eventType: eventType,
+ maxAllowedSelections: poll.maxAllowedSelections,
+ hasBeenEdited: poll.hasBeenEdited,
+ hasDecryptionError: poll.hasDecryptionError)
}
-
- private func pollKindToTimelinePollType(_ kind: PollKind) -> TimelinePollType {
- let mapping = [PollKind.disclosed: TimelinePollType.disclosed,
- PollKind.undisclosed: TimelinePollType.undisclosed]
-
- return mapping[kind] ?? .disclosed
+}
+
+private extension PollKind {
+ var timelinePollType: TimelinePollType {
+ switch self {
+ case .disclosed:
+ return .disclosed
+ case .undisclosed:
+ return .undisclosed
+ }
}
}
diff --git a/RiotSwiftUI/Modules/Room/TimelinePoll/Test/Unit/TimelinePollViewModelTests.swift b/RiotSwiftUI/Modules/Room/TimelinePoll/Test/Unit/TimelinePollViewModelTests.swift
index cd806da546..a36a7d0925 100644
--- a/RiotSwiftUI/Modules/Room/TimelinePoll/Test/Unit/TimelinePollViewModelTests.swift
+++ b/RiotSwiftUI/Modules/Room/TimelinePoll/Test/Unit/TimelinePollViewModelTests.swift
@@ -29,9 +29,11 @@ class TimelinePollViewModelTests: XCTestCase {
TimelinePollAnswerOption(id: "2", text: "2", count: 1, winner: false, selected: false),
TimelinePollAnswerOption(id: "3", text: "3", count: 1, winner: false, selected: false)]
- let timelinePoll = TimelinePollDetails(question: "Question",
+ let timelinePoll = TimelinePollDetails(id: "poll-id",
+ question: "Question",
answerOptions: answerOptions,
closed: false,
+ startDate: .init(),
totalAnswerCount: 3,
type: .disclosed,
eventType: .started,
diff --git a/RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollModels.swift b/RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollModels.swift
index 3629aae3ed..0ee87c55f9 100644
--- a/RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollModels.swift
+++ b/RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollModels.swift
@@ -62,37 +62,20 @@ extension MutableCollection where Element == TimelinePollAnswerOption {
}
struct TimelinePollDetails {
+ var id: String
var question: String
var answerOptions: [TimelinePollAnswerOption]
var closed: Bool
+ var startDate: Date
var totalAnswerCount: UInt
var type: TimelinePollType
var eventType: TimelinePollEventType
var maxAllowedSelections: UInt
- var hasBeenEdited = true
+ var hasBeenEdited: Bool
var hasDecryptionError: Bool
- init(question: String, answerOptions: [TimelinePollAnswerOption],
- closed: Bool,
- totalAnswerCount: UInt,
- type: TimelinePollType,
- eventType: TimelinePollEventType,
- maxAllowedSelections: UInt,
- hasBeenEdited: Bool,
- hasDecryptionError: Bool) {
- self.question = question
- self.answerOptions = answerOptions
- self.closed = closed
- self.totalAnswerCount = totalAnswerCount
- self.type = type
- self.eventType = eventType
- self.maxAllowedSelections = maxAllowedSelections
- self.hasBeenEdited = hasBeenEdited
- self.hasDecryptionError = hasDecryptionError
- }
-
var hasCurrentUserVoted: Bool {
- answerOptions.filter { $0.selected == true }.count > 0
+ answerOptions.contains(where: \.selected)
}
var shouldDiscloseResults: Bool {
@@ -108,6 +91,8 @@ struct TimelinePollDetails {
}
}
+extension TimelinePollDetails: Identifiable { }
+
struct TimelinePollViewState: BindableState {
var poll: TimelinePollDetails
var bindings: TimelinePollViewStateBindings
diff --git a/RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollScreenState.swift b/RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollScreenState.swift
index a53a745b80..8c70b21e3e 100644
--- a/RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollScreenState.swift
+++ b/RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollScreenState.swift
@@ -33,9 +33,11 @@ enum MockTimelinePollScreenState: MockScreenState, CaseIterable {
TimelinePollAnswerOption(id: "2", text: "Second", count: 5, winner: false, selected: true),
TimelinePollAnswerOption(id: "3", text: "Third", count: 15, winner: true, selected: false)]
- let poll = TimelinePollDetails(question: "Question",
+ let poll = TimelinePollDetails(id: "id",
+ question: "Question",
answerOptions: answerOptions,
closed: self == .closedDisclosed || self == .closedUndisclosed ? true : false,
+ startDate: .init(),
totalAnswerCount: 20,
type: self == .closedDisclosed || self == .openDisclosed ? .disclosed : .undisclosed,
eventType: self == .closedPollEnded ? .ended : .started,
diff --git a/RiotSwiftUI/Modules/Room/TimelinePoll/View/TimelinePollAnswerOptionButton.swift b/RiotSwiftUI/Modules/Room/TimelinePoll/View/TimelinePollAnswerOptionButton.swift
index 85309c31c9..1488911bd6 100644
--- a/RiotSwiftUI/Modules/Room/TimelinePoll/View/TimelinePollAnswerOptionButton.swift
+++ b/RiotSwiftUI/Modules/Room/TimelinePoll/View/TimelinePollAnswerOptionButton.swift
@@ -25,23 +25,26 @@ struct TimelinePollAnswerOptionButton: View {
let poll: TimelinePollDetails
let answerOption: TimelinePollAnswerOption
- let action: () -> Void
+ let action: (() -> Void)?
// MARK: Public
var body: some View {
- Button(action: action) {
+ Button {
+ action?()
+ } label: {
let rect = RoundedRectangle(cornerRadius: 4.0)
answerOptionLabel
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal, 8.0)
.padding(.top, 12.0)
- .padding(.bottom, 12.0)
+ .padding(.bottom, 8.0)
.clipShape(rect)
.overlay(rect.stroke(borderAccentColor, lineWidth: 1.0))
.accentColor(progressViewAccentColor)
}
.accessibilityIdentifier("PollAnswerOption\(optionIndex)")
+ .disabled(action == nil)
}
var answerOptionLabel: some View {
@@ -55,20 +58,12 @@ struct TimelinePollAnswerOptionButton: View {
.font(theme.fonts.body)
.foregroundColor(theme.colors.primaryContent)
.accessibilityIdentifier("PollAnswerOption\(optionIndex)Label")
+ .frame(maxWidth: .infinity, alignment: .leading)
- if poll.closed, answerOption.winner {
- Spacer()
- Image(uiImage: Asset.Images.pollWinnerIcon.image)
- }
- }
-
- if poll.type == .disclosed || poll.closed {
- HStack {
- ProgressView(value: Double(poll.shouldDiscloseResults ? answerOption.count : 0),
- total: Double(poll.totalAnswerCount))
- .progressViewStyle(LinearProgressViewStyle())
- .scaleEffect(x: 1.0, y: 1.2, anchor: .center)
- .accessibilityIdentifier("PollAnswerOption\(optionIndex)Progress")
+ HStack(spacing: 6) {
+ if poll.closed, answerOption.winner {
+ Image(uiImage: Asset.Images.pollWinnerIcon.image)
+ }
if poll.shouldDiscloseResults {
Text(answerOption.count == 1 ? VectorL10n.pollTimelineOneVote : VectorL10n.pollTimelineVotesCount(Int(answerOption.count)))
@@ -78,6 +73,13 @@ struct TimelinePollAnswerOptionButton: View {
}
}
}
+
+ if poll.type == .disclosed || poll.closed {
+ ProgressView(value: Double(poll.shouldDiscloseResults ? answerOption.count : 0), total: Double(poll.totalAnswerCount))
+ .progressViewStyle(LinearProgressViewStyle.linear)
+ .scaleEffect(x: 1.0, y: 1.2, anchor: .center)
+ .accessibilityIdentifier("PollAnswerOption\(optionIndex)Progress")
+ }
}
}
@@ -143,12 +145,15 @@ struct TimelinePollAnswerOptionButton_Previews: PreviewProvider {
}
}
}
+ .padding()
}
static func buildPoll(closed: Bool, type: TimelinePollType) -> TimelinePollDetails {
- TimelinePollDetails(question: "",
+ TimelinePollDetails(id: UUID().uuidString,
+ question: "",
answerOptions: [],
closed: closed,
+ startDate: .init(),
totalAnswerCount: 100,
type: type,
eventType: .started,
diff --git a/RiotSwiftUI/Modules/Room/VoiceBroadcastPlayback/MatrixSDK/VoiceBroadcastPlaybackViewModel.swift b/RiotSwiftUI/Modules/Room/VoiceBroadcastPlayback/MatrixSDK/VoiceBroadcastPlaybackViewModel.swift
index ffe713e735..35933ffced 100644
--- a/RiotSwiftUI/Modules/Room/VoiceBroadcastPlayback/MatrixSDK/VoiceBroadcastPlaybackViewModel.swift
+++ b/RiotSwiftUI/Modules/Room/VoiceBroadcastPlayback/MatrixSDK/VoiceBroadcastPlaybackViewModel.swift
@@ -44,8 +44,17 @@ class VoiceBroadcastPlaybackViewModel: VoiceBroadcastPlaybackViewModelType, Voic
private var reloadVoiceBroadcastChunkQueue: Bool = false
private var seekToChunkTime: TimeInterval?
+ /// The last chunk we tried to load
+ private var lastChunkProcessed: UInt = 0
+ /// The last chunk correctly loaded and added to the player's queue
private var lastChunkAddedToPlayer: UInt = 0
+ private var hasAttachmentErrors: Bool = false {
+ didSet {
+ updateErrorState()
+ }
+ }
+
private var isPlayingLastChunk: Bool {
// We can't play the last chunk if the brodcast is not stopped
guard state.broadcastState == .stopped else {
@@ -60,18 +69,19 @@ class VoiceBroadcastPlaybackViewModel: VoiceBroadcastPlaybackViewModelType, Voic
return state.bindings.progress + 1000 >= state.playingState.duration - Float(chunkDuration)
}
- private var playingChunk: VoiceBroadcastChunk? {
+ /// Current chunk loaded in the audio player
+ private var currentChunk: VoiceBroadcastChunk? {
guard let currentAudioPlayerUrl = audioPlayer?.currentUrl,
- let playingEventId = voiceBroadcastAttachmentCacheManagerLoadResults.first(where: { result in
+ let currentEventId = voiceBroadcastAttachmentCacheManagerLoadResults.first(where: { result in
result.url == currentAudioPlayerUrl
})?.eventIdentifier else {
return nil
}
- let playingChunk = voiceBroadcastAggregator.voiceBroadcast.chunks.first(where: { chunk in
- chunk.attachment.eventId == playingEventId
+ let currentChunk = voiceBroadcastAggregator.voiceBroadcast.chunks.first(where: { chunk in
+ chunk.attachment.eventId == currentEventId
})
- return playingChunk
+ return currentChunk
}
private var isLivePlayback: Bool {
@@ -111,7 +121,9 @@ class VoiceBroadcastPlaybackViewModel: VoiceBroadcastPlaybackViewModelType, Voic
broadcastState: voiceBroadcastAggregator.voiceBroadcastState,
playbackState: .stopped,
playingState: VoiceBroadcastPlayingState(duration: Float(voiceBroadcastAggregator.voiceBroadcast.duration), isLive: false, canMoveForward: false, canMoveBackward: false),
- bindings: VoiceBroadcastPlaybackViewStateBindings(progress: 0))
+ bindings: VoiceBroadcastPlaybackViewStateBindings(progress: 0),
+ decryptionState: VoiceBroadcastPlaybackDecryptionState(errorCount: 0),
+ showPlaybackError: false)
super.init(initialViewState: viewState)
displayLink = CADisplayLink(target: WeakTarget(self, selector: #selector(handleDisplayLinkTick)), selector: WeakTarget.triggerSelector)
@@ -197,8 +209,8 @@ class VoiceBroadcastPlaybackViewModel: VoiceBroadcastPlaybackViewModelType, Voic
// If we known the last chunk sequence, use it to check if we need to stop
// Note: it's possible to be in .stopped state and to still have a last chunk sequence at 0 (old versions or a crash during recording). In this case, we use isPlayingLastChunk as a fallback solution
if voiceBroadcastAggregator.voiceBroadcastLastChunkSequence > 0 {
- // we should stop only if we have already added the last chunk to the player
- shouldStop = (lastChunkAddedToPlayer == voiceBroadcastAggregator.voiceBroadcastLastChunkSequence)
+ // we should stop only if we have already processed the last chunk
+ shouldStop = (lastChunkProcessed == voiceBroadcastAggregator.voiceBroadcastLastChunkSequence)
} else {
shouldStop = isPlayingLastChunk
}
@@ -235,10 +247,12 @@ class VoiceBroadcastPlaybackViewModel: VoiceBroadcastPlaybackViewModelType, Voic
private func seek(to seekTime: Float) {
// Flush the chunks queue and the current audio player playlist
+ lastChunkProcessed = 0
lastChunkAddedToPlayer = 0
voiceBroadcastChunkQueue = []
reloadVoiceBroadcastChunkQueue = isProcessingVoiceBroadcastChunk
audioPlayer?.removeAllPlayerItems()
+ hasAttachmentErrors = false
let chunks = reorderVoiceBroadcastChunks(chunks: Array(voiceBroadcastAggregator.voiceBroadcast.chunks))
@@ -325,6 +339,8 @@ class VoiceBroadcastPlaybackViewModel: VoiceBroadcastPlaybackViewModelType, Voic
return
}
+ self.lastChunkProcessed = chunk.sequence
+
switch result {
case .success(let result):
guard result.eventIdentifier == chunk.attachment.eventId else {
@@ -368,19 +384,46 @@ class VoiceBroadcastPlaybackViewModel: VoiceBroadcastPlaybackViewModelType, Voic
audioPlayer.seekToTime(time)
self.seekToChunkTime = nil
}
-
+
+ self.hasAttachmentErrors = false
+ self.processNextVoiceBroadcastChunk()
+
case .failure (let error):
- MXLog.error("[VoiceBroadcastPlaybackViewModel] processVoiceBroadcastChunkQueue: loadAttachment error", context: error)
- if self.voiceBroadcastChunkQueue.count == 0 {
- // No more chunk to try. Go to error
- self.state.playbackState = .error
+ MXLog.error("[VoiceBroadcastPlaybackViewModel] processVoiceBroadcastChunkQueue: loadAttachment error", context: ["error": error, "chunk": chunk.sequence])
+ self.hasAttachmentErrors = true
+ // If nothing has been added to the player's queue, exit the buffer state
+ if self.lastChunkAddedToPlayer == 0 {
+ self.pause()
}
}
-
- self.processNextVoiceBroadcastChunk()
}
}
+ private func resetErrorState() {
+ state.showPlaybackError = false
+ }
+
+ private func updateErrorState() {
+ // Show an error if the playback state is .error
+ var showPlaybackError = state.playbackState == .error
+
+ // Or if there is an attachment error
+ if hasAttachmentErrors {
+ // only if the audio player is not playing and has nothing left to play
+ let audioPlayerIsPlaying = audioPlayer?.isPlaying ?? false
+ let currentPlayerTime = audioPlayer?.currentTime ?? 0
+ let currentPlayerDuration = audioPlayer?.duration ?? 0
+ let currentChunkSequence = currentChunk?.sequence ?? 0
+ let hasNoMoreChunkToPlay = (currentChunk == nil && lastChunkAddedToPlayer == 0) || (currentChunkSequence == lastChunkAddedToPlayer)
+ if !audioPlayerIsPlaying && hasNoMoreChunkToPlay && (currentPlayerDuration - currentPlayerTime < 0.2) {
+ showPlaybackError = true
+ }
+ }
+
+ state.showPlaybackError = showPlaybackError
+
+ }
+
private func updateDuration() {
let duration = voiceBroadcastAggregator.voiceBroadcast.duration
state.playingState.duration = Float(duration)
@@ -403,10 +446,11 @@ class VoiceBroadcastPlaybackViewModel: VoiceBroadcastPlaybackViewModelType, Voic
} else {
seek(to: state.bindings.progress)
}
+ resetErrorState()
}
@objc private func handleDisplayLinkTick() {
- guard let playingSequence = self.playingChunk?.sequence else {
+ guard let playingSequence = self.currentChunk?.sequence else {
return
}
@@ -437,7 +481,7 @@ class VoiceBroadcastPlaybackViewModel: VoiceBroadcastPlaybackViewModelType, Voic
state.playingState.remainingTimeLabel = label
state.playingState.canMoveBackward = state.bindings.progress > 0
- state.playingState.canMoveForward = state.bindings.progress < state.playingState.duration
+ state.playingState.canMoveForward = (state.playingState.duration - state.bindings.progress) > 500
}
private func handleVoiceBroadcastChunksProcessing() {
@@ -486,12 +530,24 @@ extension VoiceBroadcastPlaybackViewModel: VoiceBroadcastAggregatorDelegate {
handleVoiceBroadcastChunksProcessing()
}
}
+
+ func voiceBroadcastAggregator(_ aggregator: VoiceBroadcastAggregator, didUpdateUndecryptableEventList events: Set) {
+ state.decryptionState.errorCount = events.count
+ if events.count > 0 {
+ MXLog.debug("[VoiceBroadcastPlaybackViewModel] voice broadcast decryption error count: \(events.count)/\(aggregator.voiceBroadcast.chunks.count)")
+
+ if [.playing, .buffering].contains(state.playbackState) {
+ pause()
+ }
+ }
+ }
}
// MARK: - VoiceMessageAudioPlayerDelegate
extension VoiceBroadcastPlaybackViewModel: VoiceMessageAudioPlayerDelegate {
func audioPlayerDidFinishLoading(_ audioPlayer: VoiceMessageAudioPlayer) {
+ updateErrorState()
}
func audioPlayerDidStartPlaying(_ audioPlayer: VoiceMessageAudioPlayer) {
@@ -499,6 +555,7 @@ extension VoiceBroadcastPlaybackViewModel: VoiceMessageAudioPlayerDelegate {
state.playingState.isLive = isLivePlayback
isPlaybackInitialized = true
displayLink.isPaused = false
+ resetErrorState()
}
func audioPlayerDidPausePlaying(_ audioPlayer: VoiceMessageAudioPlayer) {
@@ -510,6 +567,9 @@ extension VoiceBroadcastPlaybackViewModel: VoiceMessageAudioPlayerDelegate {
func audioPlayerDidStopPlaying(_ audioPlayer: VoiceMessageAudioPlayer) {
MXLog.debug("[VoiceBroadcastPlaybackViewModel] audioPlayerDidStopPlaying")
state.playbackState = .stopped
+
+ updateErrorState()
+
state.playingState.isLive = false
audioPlayer.deregisterDelegate(self)
self.mediaServiceProvider.deregisterNowPlayingInfoDelegate(forPlayer: audioPlayer)
@@ -519,11 +579,16 @@ extension VoiceBroadcastPlaybackViewModel: VoiceMessageAudioPlayerDelegate {
func audioPlayer(_ audioPlayer: VoiceMessageAudioPlayer, didFailWithError error: Error) {
state.playbackState = .error
+ updateErrorState()
}
func audioPlayerDidFinishPlaying(_ audioPlayer: VoiceMessageAudioPlayer) {
MXLog.debug("[VoiceBroadcastPlaybackViewModel] audioPlayerDidFinishPlaying: \(audioPlayer.playerItems.count)")
- stopIfVoiceBroadcastOver()
+ if hasAttachmentErrors {
+ stop()
+ } else {
+ stopIfVoiceBroadcastOver()
+ }
}
}
diff --git a/RiotSwiftUI/Modules/Room/VoiceBroadcastPlayback/View/VoiceBroadcastPlaybackDecryptionErrorView.swift b/RiotSwiftUI/Modules/Room/VoiceBroadcastPlayback/View/VoiceBroadcastPlaybackDecryptionErrorView.swift
new file mode 100644
index 0000000000..598bde5c3f
--- /dev/null
+++ b/RiotSwiftUI/Modules/Room/VoiceBroadcastPlayback/View/VoiceBroadcastPlaybackDecryptionErrorView.swift
@@ -0,0 +1,47 @@
+//
+// Copyright 2023 New Vector Ltd
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+import SwiftUI
+
+struct VoiceBroadcastPlaybackDecryptionErrorView: View {
+ // MARK: - Properties
+
+ // MARK: Private
+
+ @Environment(\.theme) private var theme: ThemeSwiftUI
+
+ // MARK: Public
+
+ var body: some View {
+ ZStack {
+ HStack(spacing: 0) {
+ Image(uiImage: Asset.Images.errorIcon.image)
+ .frame(width: 40, height: 40)
+ Text(VectorL10n.voiceBroadcastPlaybackUnableToDecrypt)
+ .multilineTextAlignment(.center)
+ .font(theme.fonts.caption1)
+ .foregroundColor(theme.colors.alert)
+ }
+ }
+ .frame(maxWidth: .infinity, maxHeight: .infinity)
+ }
+}
+
+struct VoiceBroadcastPlaybackDecryptionErrorView_Previews: PreviewProvider {
+ static var previews: some View {
+ VoiceBroadcastPlaybackDecryptionErrorView()
+ }
+}
diff --git a/RiotSwiftUI/Modules/Room/VoiceBroadcastPlayback/View/VoiceBroadcastPlaybackView.swift b/RiotSwiftUI/Modules/Room/VoiceBroadcastPlayback/View/VoiceBroadcastPlaybackView.swift
index 09ed1ff443..b4bcaa7aa6 100644
--- a/RiotSwiftUI/Modules/Room/VoiceBroadcastPlayback/View/VoiceBroadcastPlaybackView.swift
+++ b/RiotSwiftUI/Modules/Room/VoiceBroadcastPlayback/View/VoiceBroadcastPlaybackView.swift
@@ -91,7 +91,7 @@ struct VoiceBroadcastPlaybackView: View {
}
}
}.frame(maxWidth: .infinity, alignment: .leading)
-
+
if viewModel.viewState.broadcastState != .stopped {
Label {
Text(VectorL10n.voiceBroadcastLive)
@@ -109,7 +109,12 @@ struct VoiceBroadcastPlaybackView: View {
.frame(maxWidth: .infinity, alignment: .leading)
.padding(EdgeInsets(top: 0.0, leading: 0.0, bottom: 4.0, trailing: 0.0))
- if viewModel.viewState.playbackState == .error {
+ if viewModel.viewState.decryptionState.errorCount > 0 {
+ VoiceBroadcastPlaybackDecryptionErrorView()
+ .fixedSize(horizontal: false, vertical: true)
+ .accessibilityIdentifier("decryptionErrorView")
+ }
+ else if viewModel.viewState.showPlaybackError {
VoiceBroadcastPlaybackErrorView()
} else {
HStack (spacing: 34.0) {
@@ -156,8 +161,8 @@ struct VoiceBroadcastPlaybackView: View {
}
VoiceBroadcastSlider(value: $viewModel.progress,
- minValue: 0.0,
- maxValue: viewModel.viewState.playingState.duration) { didChange in
+ minValue: 0.0,
+ maxValue: viewModel.viewState.playingState.duration) { didChange in
viewModel.send(viewAction: .sliderChange(didChange: didChange))
}
diff --git a/RiotSwiftUI/Modules/Room/VoiceBroadcastPlayback/VoiceBroadcastPlaybackModels.swift b/RiotSwiftUI/Modules/Room/VoiceBroadcastPlayback/VoiceBroadcastPlaybackModels.swift
index 488b65c1d6..7a810a1673 100644
--- a/RiotSwiftUI/Modules/Room/VoiceBroadcastPlayback/VoiceBroadcastPlaybackModels.swift
+++ b/RiotSwiftUI/Modules/Room/VoiceBroadcastPlayback/VoiceBroadcastPlaybackModels.swift
@@ -48,12 +48,18 @@ struct VoiceBroadcastPlayingState {
var canMoveBackward: Bool
}
+struct VoiceBroadcastPlaybackDecryptionState {
+ var errorCount: Int
+}
+
struct VoiceBroadcastPlaybackViewState: BindableState {
var details: VoiceBroadcastPlaybackDetails
var broadcastState: VoiceBroadcastInfoState
var playbackState: VoiceBroadcastPlaybackState
var playingState: VoiceBroadcastPlayingState
var bindings: VoiceBroadcastPlaybackViewStateBindings
+ var decryptionState: VoiceBroadcastPlaybackDecryptionState
+ var showPlaybackError: Bool
}
struct VoiceBroadcastPlaybackViewStateBindings {
diff --git a/RiotSwiftUI/Modules/Room/VoiceBroadcastPlayback/VoiceBroadcastPlaybackScreenState.swift b/RiotSwiftUI/Modules/Room/VoiceBroadcastPlayback/VoiceBroadcastPlaybackScreenState.swift
index 306a5be8c4..59b434ca96 100644
--- a/RiotSwiftUI/Modules/Room/VoiceBroadcastPlayback/VoiceBroadcastPlaybackScreenState.swift
+++ b/RiotSwiftUI/Modules/Room/VoiceBroadcastPlayback/VoiceBroadcastPlaybackScreenState.swift
@@ -43,11 +43,12 @@ enum MockVoiceBroadcastPlaybackScreenState: MockScreenState, CaseIterable {
var screenView: ([Any], AnyView) {
let details = VoiceBroadcastPlaybackDetails(senderDisplayName: "Alice", avatarData: AvatarInput(mxContentUri: "", matrixItemId: "!fakeroomid:matrix.org", displayName: "The name of the room"))
- let viewModel = MockVoiceBroadcastPlaybackViewModel(initialViewState: VoiceBroadcastPlaybackViewState(details: details, broadcastState: .started, playbackState: .stopped, playingState: VoiceBroadcastPlayingState(duration: 10.0, isLive: true, canMoveForward: false, canMoveBackward: false), bindings: VoiceBroadcastPlaybackViewStateBindings(progress: 0)))
+ let viewModel = MockVoiceBroadcastPlaybackViewModel(initialViewState: VoiceBroadcastPlaybackViewState(details: details, broadcastState: .started, playbackState: .stopped, playingState: VoiceBroadcastPlayingState(duration: 10.0, isLive: true, canMoveForward: false, canMoveBackward: false), bindings: VoiceBroadcastPlaybackViewStateBindings(progress: 0), decryptionState: VoiceBroadcastPlaybackDecryptionState(errorCount: 0), showPlaybackError: false))
return (
[false, viewModel],
- AnyView(VoiceBroadcastPlaybackView(viewModel: viewModel.context))
+ AnyView(VoiceBroadcastPlaybackView(viewModel: viewModel.context)
+ .environmentObject(AvatarViewModel.withMockedServices()))
)
}
}
diff --git a/RiotSwiftUI/Modules/Settings/Notifications/Model/MatrixSDK/MXNotificationPushRule.swift b/RiotSwiftUI/Modules/Settings/Notifications/Model/MatrixSDK/MXNotificationPushRule.swift
index 2c4d16d8b4..337ed45168 100644
--- a/RiotSwiftUI/Modules/Settings/Notifications/Model/MatrixSDK/MXNotificationPushRule.swift
+++ b/RiotSwiftUI/Modules/Settings/Notifications/Model/MatrixSDK/MXNotificationPushRule.swift
@@ -41,6 +41,10 @@ extension MXPushRule: NotificationPushRuleType {
return false
}
+ var ruleActions: NotificationActions? {
+ .init(notify: notify, highlight: highlight, sound: sound)
+ }
+
private func getAction(actionType: MXPushRuleActionType, tweakType: String? = nil) -> MXPushRuleAction? {
guard let actions = actions as? [MXPushRuleAction] else {
return nil
diff --git a/RiotSwiftUI/Modules/Settings/Notifications/Model/Mock/MockNotificationPushRule.swift b/RiotSwiftUI/Modules/Settings/Notifications/Model/Mock/MockNotificationPushRule.swift
index 49166c99e7..64aff03887 100644
--- a/RiotSwiftUI/Modules/Settings/Notifications/Model/Mock/MockNotificationPushRule.swift
+++ b/RiotSwiftUI/Modules/Settings/Notifications/Model/Mock/MockNotificationPushRule.swift
@@ -16,10 +16,12 @@
import Foundation
-struct MockNotificationPushRule: NotificationPushRuleType {
+struct MockNotificationPushRule: NotificationPushRuleType, Equatable {
var ruleId: String!
var enabled: Bool
+ var ruleActions: NotificationActions? = NotificationStandardActions.notifyDefaultSound.actions
+
func matches(standardActions: NotificationStandardActions?) -> Bool {
- false
+ standardActions?.actions == ruleActions
}
}
diff --git a/RiotSwiftUI/Modules/Settings/Notifications/Model/NotificationActions.swift b/RiotSwiftUI/Modules/Settings/Notifications/Model/NotificationActions.swift
index 88b11b3bec..98fa347645 100644
--- a/RiotSwiftUI/Modules/Settings/Notifications/Model/NotificationActions.swift
+++ b/RiotSwiftUI/Modules/Settings/Notifications/Model/NotificationActions.swift
@@ -17,7 +17,7 @@
import Foundation
/// The actions defined on a push rule, used in the static push rule definitions.
-struct NotificationActions {
+struct NotificationActions: Equatable {
let notify: Bool
let highlight: Bool
let sound: String?
diff --git a/RiotSwiftUI/Modules/Settings/Notifications/Model/NotificationPushRuleDefinitions.swift b/RiotSwiftUI/Modules/Settings/Notifications/Model/NotificationPushRuleDefinitions.swift
index 77c6e1ef2b..c30b81fecf 100644
--- a/RiotSwiftUI/Modules/Settings/Notifications/Model/NotificationPushRuleDefinitions.swift
+++ b/RiotSwiftUI/Modules/Settings/Notifications/Model/NotificationPushRuleDefinitions.swift
@@ -22,7 +22,7 @@ extension NotificationPushRuleId {
/// It is defined similarly across Web and Android.
/// - Parameter index: The notification index for which to get the actions for.
/// - Returns: The associated `NotificationStandardActions`.
- func standardActions(for index: NotificationIndex) -> NotificationStandardActions? {
+ func standardActions(for index: NotificationIndex) -> NotificationStandardActions {
switch self {
case .containDisplayName:
switch index {
@@ -42,7 +42,7 @@ extension NotificationPushRuleId {
case .silent: return .notify
case .noisy: return .highlight
}
- case .oneToOneRoom:
+ case .oneToOneRoom, .oneToOnePollStart, .msc3930oneToOnePollStart, .oneToOnePollEnd, .msc3930oneToOnePollEnd:
switch index {
case .off: return .dontNotify
case .silent: return .notify
@@ -54,7 +54,7 @@ extension NotificationPushRuleId {
case .silent: return .notify
case .noisy: return .notifyDefaultSound
}
- case .allOtherMessages:
+ case .allOtherMessages, .pollStart, .msc3930pollStart, .pollEnd, .msc3930pollEnd:
switch index {
case .off: return .dontNotify
case .silent: return .notify
diff --git a/RiotSwiftUI/Modules/Settings/Notifications/Model/NotificationPushRuleIds.swift b/RiotSwiftUI/Modules/Settings/Notifications/Model/NotificationPushRuleIds.swift
index d74968c8bb..46cca080e7 100644
--- a/RiotSwiftUI/Modules/Settings/Notifications/Model/NotificationPushRuleIds.swift
+++ b/RiotSwiftUI/Modules/Settings/Notifications/Model/NotificationPushRuleIds.swift
@@ -30,6 +30,18 @@ enum NotificationPushRuleId: String {
case allOtherMessages = ".m.rule.message"
case encrypted = ".m.rule.encrypted"
case keywords = "_keywords"
+ // poll started event
+ case pollStart = ".m.rule.poll_start"
+ case msc3930pollStart = ".org.matrix.msc3930.rule.poll_start"
+ // poll started event (one to one)
+ case oneToOnePollStart = ".m.rule.poll_start_one_to_one"
+ case msc3930oneToOnePollStart = ".org.matrix.msc3930.rule.poll_start_one_to_one"
+ // poll ended event
+ case pollEnd = ".m.rule.poll_end"
+ case msc3930pollEnd = ".org.matrix.msc3930.rule.poll_end"
+ // poll ended event (one to one)
+ case oneToOnePollEnd = ".m.rule.poll_end_one_to_one"
+ case msc3930oneToOnePollEnd = ".org.matrix.msc3930.rule.poll_end_one_to_one"
}
extension NotificationPushRuleId: Identifiable {
@@ -65,6 +77,20 @@ extension NotificationPushRuleId {
return VectorL10n.settingsEncryptedGroupMessages
case .keywords:
return VectorL10n.settingsMessagesContainingKeywords
+ case .pollStart, .msc3930pollStart, .oneToOnePollStart, .msc3930oneToOnePollStart, .pollEnd, .msc3930pollEnd, .oneToOnePollEnd, .msc3930oneToOnePollEnd:
+ // They don't need to be rendered on the UI
+ return ""
+ }
+ }
+
+ var syncedRules: [NotificationPushRuleId] {
+ switch self {
+ case .oneToOneRoom:
+ return [.oneToOnePollStart, .msc3930oneToOnePollStart, .oneToOnePollEnd, .msc3930oneToOnePollEnd]
+ case .allOtherMessages:
+ return [.pollStart, .msc3930pollStart, .pollEnd, .msc3930pollEnd]
+ default:
+ return []
}
}
}
diff --git a/RiotSwiftUI/Modules/Settings/Notifications/Model/NotificationPushRuleType.swift b/RiotSwiftUI/Modules/Settings/Notifications/Model/NotificationPushRuleType.swift
index 1f98242c70..14ed88e69a 100644
--- a/RiotSwiftUI/Modules/Settings/Notifications/Model/NotificationPushRuleType.swift
+++ b/RiotSwiftUI/Modules/Settings/Notifications/Model/NotificationPushRuleType.swift
@@ -19,5 +19,13 @@ import Foundation
protocol NotificationPushRuleType {
var ruleId: String! { get }
var enabled: Bool { get }
+ var ruleActions: NotificationActions? { get }
+
func matches(standardActions: NotificationStandardActions?) -> Bool
}
+
+extension NotificationPushRuleType {
+ var pushRuleId: NotificationPushRuleId? {
+ ruleId.flatMap(NotificationPushRuleId.init(rawValue:))
+ }
+}
diff --git a/RiotSwiftUI/Modules/Settings/Notifications/Service/MatrixSDK/MXNotificationSettingsService.swift b/RiotSwiftUI/Modules/Settings/Notifications/Service/MatrixSDK/MXNotificationSettingsService.swift
index 375b50ab94..9bf01ef4c0 100644
--- a/RiotSwiftUI/Modules/Settings/Notifications/Service/MatrixSDK/MXNotificationSettingsService.swift
+++ b/RiotSwiftUI/Modules/Settings/Notifications/Service/MatrixSDK/MXNotificationSettingsService.swift
@@ -44,7 +44,9 @@ class MXNotificationSettingsService: NotificationSettingsServiceType {
// Observe future updates to content rules
rulesUpdated
- .compactMap { _ in self.session.notificationCenter.rules.global.content as? [MXPushRule] }
+ .compactMap { [weak self] _ in
+ self?.session.notificationCenter.rules.global.content as? [MXPushRule]
+ }
.assign(to: &$contentRules)
// Set initial value of rules
@@ -53,14 +55,15 @@ class MXNotificationSettingsService: NotificationSettingsServiceType {
}
// Observe future updates to rules
rulesUpdated
- .compactMap { _ in self.session.notificationCenter.flatRules as? [MXPushRule] }
+ .compactMap { [weak self] _ in
+ self?.session.notificationCenter.flatRules as? [MXPushRule]
+ }
.assign(to: &$rules)
}
func add(keyword: String, enabled: Bool) {
let index = NotificationIndex.index(when: enabled)
- guard let actions = NotificationPushRuleId.keywords.standardActions(for: index)?.actions
- else {
+ guard let actions = NotificationPushRuleId.keywords.standardActions(for: index).actions else {
return
}
session.notificationCenter.addContentRuleWithRuleId(matchingPattern: keyword, notify: actions.notify, sound: actions.sound, highlight: actions.highlight)
@@ -71,16 +74,52 @@ class MXNotificationSettingsService: NotificationSettingsServiceType {
session.notificationCenter.removeRule(rule)
}
- func updatePushRuleActions(for ruleId: String, enabled: Bool, actions: NotificationActions?) {
- guard let rule = session.notificationCenter.rule(byId: ruleId) else { return }
- session.notificationCenter.enableRule(rule, isEnabled: enabled)
+ func updatePushRuleActions(for ruleId: String,
+ enabled: Bool,
+ actions: NotificationActions?) async throws {
- if let actions = actions {
- session.notificationCenter.updatePushRuleActions(ruleId,
- kind: rule.kind,
- notify: actions.notify,
- soundName: actions.sound,
- highlight: actions.highlight)
+ guard let rule = session.notificationCenter.rule(byId: ruleId) else {
+ return
+ }
+
+ guard let actions = actions else {
+ try await session.notificationCenter.enableRule(pushRule: rule, isEnabled: enabled)
+ return
+ }
+
+ // Updating the actions before enabling the rule allows the homeserver to triggers just one sync update
+ try await session.notificationCenter.updatePushRuleActions(ruleId,
+ kind: rule.kind,
+ notify: actions.notify,
+ soundName: actions.sound,
+ highlight: actions.highlight)
+
+ try await session.notificationCenter.enableRule(pushRule: rule, isEnabled: enabled)
+ }
+}
+
+private extension MXNotificationCenter {
+ func enableRule(pushRule: MXPushRule, isEnabled: Bool) async throws {
+ try await withCheckedThrowingContinuation { (continuation: CheckedContinuation) in
+ enableRule(pushRule, isEnabled: isEnabled) { error in
+ if let error = error {
+ continuation.resume(with: .failure(error))
+ } else {
+ continuation.resume()
+ }
+ }
+ }
+ }
+
+ func updatePushRuleActions(ruleId: String, kind: __MXPushRuleKind, notify: Bool, soundName: String, highlight: Bool) async throws {
+ try await withCheckedThrowingContinuation { (continuation: CheckedContinuation) in
+ updatePushRuleActions(ruleId, kind: kind, notify: notify, soundName: soundName, highlight: highlight) { error in
+ if let error = error {
+ continuation.resume(with: .failure(error))
+ } else {
+ continuation.resume()
+ }
+ }
}
}
}
diff --git a/RiotSwiftUI/Modules/Settings/Notifications/Service/Mock/MockNotificationSettingsService.swift b/RiotSwiftUI/Modules/Settings/Notifications/Service/Mock/MockNotificationSettingsService.swift
index 44a553f6cb..0bff31370c 100644
--- a/RiotSwiftUI/Modules/Settings/Notifications/Service/Mock/MockNotificationSettingsService.swift
+++ b/RiotSwiftUI/Modules/Settings/Notifications/Service/Mock/MockNotificationSettingsService.swift
@@ -44,5 +44,11 @@ class MockNotificationSettingsService: NotificationSettingsServiceType, Observab
keywords.remove(keyword)
}
- func updatePushRuleActions(for ruleId: String, enabled: Bool, actions: NotificationActions?) { }
+ func updatePushRuleActions(for ruleId: String, enabled: Bool, actions: NotificationActions?) async throws {
+ guard let ruleIndex = rules.firstIndex(where: { $0.ruleId == ruleId }) else {
+ return
+ }
+
+ rules[ruleIndex] = MockNotificationPushRule(ruleId: ruleId, enabled: enabled, ruleActions: actions)
+ }
}
diff --git a/RiotSwiftUI/Modules/Settings/Notifications/Service/NotificationSettingsServiceType.swift b/RiotSwiftUI/Modules/Settings/Notifications/Service/NotificationSettingsServiceType.swift
index a5a1671e33..5b06dfb6de 100644
--- a/RiotSwiftUI/Modules/Settings/Notifications/Service/NotificationSettingsServiceType.swift
+++ b/RiotSwiftUI/Modules/Settings/Notifications/Service/NotificationSettingsServiceType.swift
@@ -40,5 +40,5 @@ protocol NotificationSettingsServiceType {
/// - ruleId: The id of the rule.
/// - enabled: Whether the rule should be enabled or disabled.
/// - actions: The actions to update with.
- func updatePushRuleActions(for ruleId: String, enabled: Bool, actions: NotificationActions?)
+ func updatePushRuleActions(for ruleId: String, enabled: Bool, actions: NotificationActions?) async throws
}
diff --git a/RiotSwiftUI/Modules/Settings/Notifications/Test/Unit/NotificationSettingsViewModelTests.swift b/RiotSwiftUI/Modules/Settings/Notifications/Test/Unit/NotificationSettingsViewModelTests.swift
new file mode 100644
index 0000000000..95b5e08fad
--- /dev/null
+++ b/RiotSwiftUI/Modules/Settings/Notifications/Test/Unit/NotificationSettingsViewModelTests.swift
@@ -0,0 +1,140 @@
+//
+// Copyright 2023 New Vector Ltd
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+@testable import RiotSwiftUI
+import XCTest
+
+final class NotificationSettingsViewModelTests: XCTestCase {
+ private var viewModel: NotificationSettingsViewModel!
+ private var notificationService: MockNotificationSettingsService!
+
+ override func setUpWithError() throws {
+ notificationService = .init()
+ }
+
+ func testAllTheRulesAreChecked() throws {
+ viewModel = .init(notificationSettingsService: notificationService, ruleIds: .default)
+
+ XCTAssertEqual(viewModel.viewState.selectionState.count, 4)
+ XCTAssertTrue(viewModel.viewState.selectionState.values.allSatisfy { $0 })
+ }
+
+ func testUpdateRule() async {
+ viewModel = .init(notificationSettingsService: notificationService, ruleIds: .default)
+ notificationService.rules = [MockNotificationPushRule].default
+
+ await viewModel.update(ruleID: .encrypted, isChecked: false)
+ XCTAssertEqual(viewModel.viewState.selectionState.count, 4)
+ XCTAssertEqual(viewModel.viewState.selectionState[.encrypted], false)
+ }
+
+ func testUpdateOneToOneRuleAlsoUpdatesPollRules() async {
+ setupWithPollRules()
+
+ await viewModel.update(ruleID: .oneToOneRoom, isChecked: false)
+
+ XCTAssertEqual(viewModel.viewState.selectionState.count, 8)
+ XCTAssertEqual(viewModel.viewState.selectionState[.oneToOneRoom], false)
+ XCTAssertEqual(viewModel.viewState.selectionState[.oneToOnePollStart], false)
+ XCTAssertEqual(viewModel.viewState.selectionState[.oneToOnePollEnd], false)
+
+ // unrelated poll rules stay the same
+ XCTAssertEqual(viewModel.viewState.selectionState[.allOtherMessages], true)
+ XCTAssertEqual(viewModel.viewState.selectionState[.pollStart], true)
+ XCTAssertEqual(viewModel.viewState.selectionState[.pollEnd], true)
+ }
+
+ func testUpdateMessageRuleAlsoUpdatesPollRules() async {
+ setupWithPollRules()
+
+ await viewModel.update(ruleID: .allOtherMessages, isChecked: false)
+ XCTAssertEqual(viewModel.viewState.selectionState.count, 8)
+ XCTAssertEqual(viewModel.viewState.selectionState[.allOtherMessages], false)
+ XCTAssertEqual(viewModel.viewState.selectionState[.pollStart], false)
+ XCTAssertEqual(viewModel.viewState.selectionState[.pollEnd], false)
+
+ // unrelated poll rules stay the same
+ XCTAssertEqual(viewModel.viewState.selectionState[.oneToOneRoom], true)
+ XCTAssertEqual(viewModel.viewState.selectionState[.oneToOnePollStart], true)
+ XCTAssertEqual(viewModel.viewState.selectionState[.oneToOnePollEnd], true)
+ }
+
+ func testMismatchingRulesAreHandled() async {
+ setupWithPollRules()
+
+ await viewModel.update(ruleID: .allOtherMessages, isChecked: false)
+
+ // simulating a "mismatch" on the poll started rule
+ await viewModel.update(ruleID: .pollStart, isChecked: true)
+
+ XCTAssertEqual(viewModel.viewState.selectionState.count, 8)
+
+ // The other messages rule ui flag should match the loudest related poll rule
+ XCTAssertEqual(viewModel.viewState.selectionState[.allOtherMessages], true)
+ }
+
+ func testMismatchingOneToOneRulesAreHandled() async {
+ setupWithPollRules()
+
+ await viewModel.update(ruleID: .oneToOneRoom, isChecked: false)
+ // simulating a "mismatch" on the one to one poll started rule
+ await viewModel.update(ruleID: .oneToOnePollStart, isChecked: true)
+
+ XCTAssertEqual(viewModel.viewState.selectionState.count, 8)
+
+ // The one to one room rule ui flag should match the loudest related poll rule
+ XCTAssertEqual(viewModel.viewState.selectionState[.oneToOneRoom], true)
+
+ // the oneToOneRoom rule should be flagged as "out of sync"
+ XCTAssertTrue(viewModel.isRuleOutOfSync(.oneToOneRoom))
+ XCTAssertFalse(viewModel.isRuleOutOfSync(.allOtherMessages))
+ }
+}
+
+private extension NotificationSettingsViewModelTests {
+ func setupWithPollRules() {
+ viewModel = .init(notificationSettingsService: notificationService, ruleIds: .default + .polls)
+ notificationService.rules = [MockNotificationPushRule].default + [MockNotificationPushRule].polls
+ }
+}
+
+private extension Array where Element == NotificationPushRuleId {
+ static var `default`: [NotificationPushRuleId] {
+ [.oneToOneRoom, .allOtherMessages, .oneToOneEncryptedRoom, .encrypted]
+ }
+
+ static var polls: [NotificationPushRuleId] {
+ [.pollStart, .pollEnd, .oneToOnePollStart, .oneToOnePollEnd]
+ }
+}
+
+private extension Array where Element == MockNotificationPushRule {
+ static var `default`: [MockNotificationPushRule] {
+ [NotificationPushRuleId]
+ .default
+ .map { ruleId in
+ MockNotificationPushRule(ruleId: ruleId.rawValue, enabled: true)
+ }
+ }
+
+ static var polls: [MockNotificationPushRule] {
+ [NotificationPushRuleId]
+ .polls
+ .map { ruleId in
+ MockNotificationPushRule(ruleId: ruleId.rawValue, enabled: true)
+ }
+ }
+}
diff --git a/RiotSwiftUI/Modules/Settings/Notifications/View/NotificationSettings.swift b/RiotSwiftUI/Modules/Settings/Notifications/View/NotificationSettings.swift
index 18be2680d2..62cdf247a4 100644
--- a/RiotSwiftUI/Modules/Settings/Notifications/View/NotificationSettings.swift
+++ b/RiotSwiftUI/Modules/Settings/Notifications/View/NotificationSettings.swift
@@ -21,6 +21,7 @@ import SwiftUI
/// Also renders an optional bottom section.
/// Used in the case of keywords, for the keyword chips and input.
struct NotificationSettings: View {
+ @Environment(\.theme) var theme: ThemeSwiftUI
@ObservedObject var viewModel: NotificationSettingsViewModel
var bottomSection: BottomSection?
@@ -31,15 +32,28 @@ struct NotificationSettings: View {
header: FormSectionHeader(text: VectorL10n.settingsNotifyMeFor)
) {
ForEach(viewModel.viewState.ruleIds) { ruleId in
- let checked = viewModel.viewState.selectionState[ruleId] ?? false
- FormPickerItem(title: ruleId.title, selected: checked) {
- viewModel.update(ruleID: ruleId, isChecked: !checked)
+ VStack(alignment: .leading, spacing: 4) {
+ let checked = viewModel.viewState.selectionState[ruleId] ?? false
+ FormPickerItem(title: ruleId.title, selected: checked) {
+ Task {
+ await viewModel.update(ruleID: ruleId, isChecked: !checked)
+ }
+ }
+
+ if viewModel.isRuleOutOfSync(ruleId) {
+ Text(VectorL10n.settingsPushRulesError)
+ .font(theme.fonts.caption1)
+ .foregroundColor(theme.colors.alert)
+ .padding(.horizontal)
+ .padding(.bottom, 16)
+ }
}
}
}
bottomSection
}
.activityIndicator(show: viewModel.viewState.saving)
+ .disabled(viewModel.viewState.saving)
}
}
diff --git a/RiotSwiftUI/Modules/Settings/Notifications/ViewModel/NotificationSettingsViewModel.swift b/RiotSwiftUI/Modules/Settings/Notifications/ViewModel/NotificationSettingsViewModel.swift
index 5885975723..154f926cee 100644
--- a/RiotSwiftUI/Modules/Settings/Notifications/ViewModel/NotificationSettingsViewModel.swift
+++ b/RiotSwiftUI/Modules/Settings/Notifications/ViewModel/NotificationSettingsViewModel.swift
@@ -49,7 +49,9 @@ final class NotificationSettingsViewModel: NotificationSettingsViewModelType, Ob
// Observe when the rules are updated, to subsequently update the state of the settings.
notificationSettingsService.rulesPublisher
- .sink(receiveValue: rulesUpdated(newRules:))
+ .sink { [weak self] newRules in
+ self?.rulesUpdated(newRules: newRules)
+ }
.store(in: &cancellables)
// Only observe keywords if the current settings view displays it.
@@ -88,7 +90,9 @@ final class NotificationSettingsViewModel: NotificationSettingsViewModelType, Ob
// Keyword rules were updates, check if we need to update the setting.
keywordsRules
.map { $0.contains { $0.enabled } }
- .sink(receiveValue: keywordRuleUpdated(anyEnabled:))
+ .sink { [weak self] in
+ self?.keywordRuleUpdated(anyEnabled: $0)
+ }
.store(in: &cancellables)
// Update the viewState with the final keywords to be displayed.
@@ -105,35 +109,27 @@ final class NotificationSettingsViewModel: NotificationSettingsViewModelType, Ob
// MARK: - Public
- func update(ruleID: NotificationPushRuleId, isChecked: Bool) {
+ @MainActor
+ func update(ruleID: NotificationPushRuleId, isChecked: Bool) async {
let index = NotificationIndex.index(when: isChecked)
- if ruleID == .keywords {
- // Keywords is handled differently to other settings
- updateKeywords(isChecked: isChecked)
- return
- }
- // Get the static definition and update the actions and enabled state.
- guard let standardActions = ruleID.standardActions(for: index) else { return }
+ let standardActions = ruleID.standardActions(for: index)
let enabled = standardActions != .disabled
- notificationSettingsService.updatePushRuleActions(
- for: ruleID.rawValue,
- enabled: enabled,
- actions: standardActions.actions
- )
- }
-
- private func updateKeywords(isChecked: Bool) {
- guard !keywordsOrdered.isEmpty else {
- viewState.selectionState[.keywords]?.toggle()
- return
- }
- // Get the static definition and update the actions and enabled state for every keyword.
- let index = NotificationIndex.index(when: isChecked)
- guard let standardActions = NotificationPushRuleId.keywords.standardActions(for: index) else { return }
- let enabled = standardActions != .disabled
- keywordsOrdered.forEach { keyword in
- notificationSettingsService.updatePushRuleActions(
- for: keyword,
+
+ switch ruleID {
+ case .keywords: // Keywords is handled differently to other settings
+ await updateKeywords(isChecked: isChecked)
+
+ case .oneToOneRoom, .allOtherMessages:
+ await updatePushAction(
+ id: ruleID,
+ enabled: enabled,
+ standardActions: standardActions,
+ then: ruleID.syncedRules
+ )
+
+ default:
+ try? await notificationSettingsService.updatePushRuleActions(
+ for: ruleID.rawValue,
enabled: enabled,
actions: standardActions.actions
)
@@ -152,17 +148,94 @@ final class NotificationSettingsViewModel: NotificationSettingsViewModelType, Ob
notificationSettingsService.remove(keyword: keyword)
}
- // MARK: - Private
+ func isRuleOutOfSync(_ ruleId: NotificationPushRuleId) -> Bool {
+ viewState.outOfSyncRules.contains(ruleId) && viewState.saving == false
+ }
+}
+
+// MARK: - Private
+
+private extension NotificationSettingsViewModel {
+ @MainActor
+ func updateKeywords(isChecked: Bool) async {
+ guard !keywordsOrdered.isEmpty else {
+ viewState.selectionState[.keywords]?.toggle()
+ return
+ }
+
+ // Get the static definition and update the actions and enabled state for every keyword.
+ let index = NotificationIndex.index(when: isChecked)
+ let standardActions = NotificationPushRuleId.keywords.standardActions(for: index)
+ let enabled = standardActions != .disabled
+ let keywordsToUpdate = keywordsOrdered
+
+ await withThrowingTaskGroup(of: Void.self) { group in
+ for keyword in keywordsToUpdate {
+ group.addTask {
+ try await self.notificationSettingsService.updatePushRuleActions(
+ for: keyword,
+ enabled: enabled,
+ actions: standardActions.actions
+ )
+ }
+ }
+ }
+ }
- private func rulesUpdated(newRules: [NotificationPushRuleType]) {
+ func updatePushAction(id: NotificationPushRuleId,
+ enabled: Bool,
+ standardActions: NotificationStandardActions,
+ then rules: [NotificationPushRuleId]) async {
+ await MainActor.run {
+ viewState.saving = true
+ }
+
+ do {
+ // update the 'parent rule' first
+ try await notificationSettingsService.updatePushRuleActions(for: id.rawValue, enabled: enabled, actions: standardActions.actions)
+
+ // synchronize all the 'children rules' with the parent rule
+ await withThrowingTaskGroup(of: Void.self) { group in
+ for ruleId in rules {
+ group.addTask {
+ try await self.notificationSettingsService.updatePushRuleActions(for: ruleId.rawValue, enabled: enabled, actions: standardActions.actions)
+ }
+ }
+ }
+ await completeUpdate()
+ } catch {
+ await completeUpdate()
+ }
+ }
+
+ @MainActor
+ func completeUpdate() {
+ viewState.saving = false
+ }
+
+ func rulesUpdated(newRules: [NotificationPushRuleType]) {
+ var outOfSyncRules: Set = .init()
+
for rule in newRules {
- guard let ruleId = NotificationPushRuleId(rawValue: rule.ruleId),
- ruleIds.contains(ruleId) else { continue }
- viewState.selectionState[ruleId] = isChecked(rule: rule)
+ guard
+ let ruleId = rule.pushRuleId,
+ ruleIds.contains(ruleId)
+ else {
+ continue
+ }
+
+ let relatedSyncedRules = ruleId.syncedRules(in: newRules)
+ viewState.selectionState[ruleId] = isChecked(rule: rule, syncedRules: relatedSyncedRules)
+
+ if isOutOfSync(rule: rule, syncedRules: relatedSyncedRules) {
+ outOfSyncRules.insert(ruleId)
+ }
}
+
+ viewState.outOfSyncRules = outOfSyncRules
}
- private func keywordRuleUpdated(anyEnabled: Bool) {
+ func keywordRuleUpdated(anyEnabled: Bool) {
if !keywordsOrdered.isEmpty {
viewState.selectionState[.keywords] = anyEnabled
}
@@ -174,8 +247,10 @@ final class NotificationSettingsViewModel: NotificationSettingsViewModelType, Ob
/// The same logic is used on android.
/// - Parameter rule: The push rule type to check.
/// - Returns: Wether it should be displayed as checked or not checked.
- private func isChecked(rule: NotificationPushRuleType) -> Bool {
- guard let ruleId = NotificationPushRuleId(rawValue: rule.ruleId) else { return false }
+ func defaultIsChecked(rule: NotificationPushRuleType) -> Bool {
+ guard let ruleId = rule.pushRuleId else {
+ return false
+ }
let firstIndex = NotificationIndex.allCases.first { nextIndex in
rule.matches(standardActions: ruleId.standardActions(for: nextIndex))
@@ -187,4 +262,45 @@ final class NotificationSettingsViewModel: NotificationSettingsViewModelType, Ob
return index.enabled
}
+
+ func isChecked(rule: NotificationPushRuleType, syncedRules: [NotificationPushRuleType]) -> Bool {
+ guard let ruleId = rule.pushRuleId else {
+ return false
+ }
+
+ switch ruleId {
+ case .oneToOneRoom, .allOtherMessages:
+ let ruleIsChecked = defaultIsChecked(rule: rule)
+ let someSyncedRuleIsChecked = syncedRules.contains(where: { defaultIsChecked(rule: $0) })
+ // The "loudest" rule will be applied when there is a clash between a rule and its dependent rules.
+ return ruleIsChecked || someSyncedRuleIsChecked
+ default:
+ return defaultIsChecked(rule: rule)
+ }
+ }
+
+ func isOutOfSync(rule: NotificationPushRuleType, syncedRules: [NotificationPushRuleType]) -> Bool {
+ guard let ruleId = rule.pushRuleId else {
+ return false
+ }
+
+ switch ruleId {
+ case .oneToOneRoom, .allOtherMessages:
+ let ruleIsChecked = defaultIsChecked(rule: rule)
+ return syncedRules.contains(where: { defaultIsChecked(rule: $0) != ruleIsChecked })
+ default:
+ return false
+ }
+ }
+}
+
+extension NotificationPushRuleId {
+ func syncedRules(in rules: [NotificationPushRuleType]) -> [NotificationPushRuleType] {
+ rules.filter {
+ guard let ruleId = $0.pushRuleId else {
+ return false
+ }
+ return syncedRules.contains(ruleId)
+ }
+ }
}
diff --git a/RiotSwiftUI/Modules/Settings/Notifications/ViewModel/NotificationSettingsViewState.swift b/RiotSwiftUI/Modules/Settings/Notifications/ViewModel/NotificationSettingsViewState.swift
index 22bb4fed83..a732f56b1b 100644
--- a/RiotSwiftUI/Modules/Settings/Notifications/ViewModel/NotificationSettingsViewState.swift
+++ b/RiotSwiftUI/Modules/Settings/Notifications/ViewModel/NotificationSettingsViewState.swift
@@ -22,5 +22,6 @@ struct NotificationSettingsViewState {
var saving: Bool
var ruleIds: [NotificationPushRuleId]
var selectionState: [NotificationPushRuleId: Bool]
+ var outOfSyncRules: Set = .init()
var keywords = [String]()
}
diff --git a/RiotTests/PushRulesUpdaterTests.swift b/RiotTests/PushRulesUpdaterTests.swift
new file mode 100644
index 0000000000..1eec9dda58
--- /dev/null
+++ b/RiotTests/PushRulesUpdaterTests.swift
@@ -0,0 +1,106 @@
+//
+// Copyright 2023 New Vector Ltd
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+import Combine
+import XCTest
+@testable import Element
+
+final class PushRulesUpdaterTests: XCTestCase {
+ private var notificationService: MockNotificationSettingsService!
+ private var pushRulesUpdater: PushRulesUpdater!
+
+ override func setUpWithError() throws {
+ notificationService = .init()
+ notificationService.rules = [MockNotificationPushRule].default
+ pushRulesUpdater = .init(notificationSettingsService: notificationService)
+ }
+
+ func testNoRuleIsUpdated() async throws {
+ await pushRulesUpdater.syncRulesIfNeeded()
+ XCTAssertEqual(notificationService.rules as? [MockNotificationPushRule], [MockNotificationPushRule].default)
+ }
+
+ func testSingleRuleAffected() async throws {
+ let targetActions: NotificationActions = .init(notify: true, sound: "default")
+ let targetRuleIndex = try mockRule(ruleId: .pollStart, enabled: false, actions: targetActions)
+
+ await pushRulesUpdater.syncRulesIfNeeded()
+
+ XCTAssertEqual(self.notificationService.rules[targetRuleIndex].ruleActions, NotificationStandardActions.notifyDefaultSound.actions)
+ XCTAssertTrue(self.notificationService.rules[targetRuleIndex].enabled)
+ }
+
+ func testAffectedRulesAreUpdated() async throws {
+ let targetActions: NotificationActions = .init(notify: true, sound: "abc")
+ try mockRule(ruleId: .allOtherMessages, enabled: true, actions: targetActions)
+ let affectedRules: [NotificationPushRuleId] = [.allOtherMessages, .pollStart, .msc3930pollStart, .pollEnd, .msc3930pollEnd]
+
+ await pushRulesUpdater.syncRulesIfNeeded()
+
+ for rule in self.notificationService.rules {
+ guard let id = rule.pushRuleId else {
+ continue
+ }
+
+ if affectedRules.contains(id) {
+ XCTAssertEqual(rule.ruleActions, targetActions)
+ } else {
+ XCTAssertEqual(rule.ruleActions, NotificationStandardActions.notifyDefaultSound.actions)
+ }
+ }
+ }
+
+ func testAffectedOneToOneRulesAreUpdated() async throws {
+ let targetActions: NotificationActions = .init(notify: true, sound: "abc")
+ try mockRule(ruleId: .oneToOneRoom, enabled: true, actions: targetActions)
+ let affectedRules: [NotificationPushRuleId] = [.oneToOneRoom, .oneToOnePollStart, .msc3930oneToOnePollStart, .oneToOnePollEnd, .msc3930oneToOnePollEnd]
+
+ await pushRulesUpdater.syncRulesIfNeeded()
+
+ for rule in self.notificationService.rules {
+ guard let id = rule.pushRuleId else {
+ continue
+ }
+
+ if affectedRules.contains(id) {
+ XCTAssertEqual(rule.ruleActions, targetActions)
+ } else {
+ XCTAssertEqual(rule.ruleActions, NotificationStandardActions.notifyDefaultSound.actions)
+ }
+ }
+ }
+}
+
+private extension PushRulesUpdaterTests {
+ @discardableResult
+ func mockRule(ruleId: NotificationPushRuleId, enabled: Bool, actions: NotificationActions) throws -> Int {
+ guard let ruleIndex = notificationService.rules.firstIndex(where: { $0.pushRuleId == ruleId }) else {
+ throw NSError(domain: "no ruleIndex found", code: 0)
+ }
+ notificationService.rules[ruleIndex] = MockNotificationPushRule(ruleId: ruleId.rawValue, enabled: enabled, ruleActions: actions)
+ return ruleIndex
+ }
+}
+
+private extension Array where Element == MockNotificationPushRule {
+ static var `default`: [MockNotificationPushRule] {
+ let ids: [NotificationPushRuleId] = [.oneToOneRoom, .allOtherMessages, .pollStart, .msc3930pollStart, .pollEnd, .msc3930pollEnd, .oneToOnePollStart, .msc3930oneToOnePollStart, .oneToOnePollEnd, .msc3930oneToOnePollEnd]
+
+ return ids.map {
+ MockNotificationPushRule(ruleId: $0.rawValue, enabled: true)
+ }
+ }
+}
diff --git a/SiriIntents/target.yml b/SiriIntents/target.yml
index 324497cf3c..82f7a89da9 100644
--- a/SiriIntents/target.yml
+++ b/SiriIntents/target.yml
@@ -34,6 +34,7 @@ targets:
dependencies:
- sdk: Intents.framework
- package: DeviceKit
+ - package: DTCoreText
configFiles:
Debug: Debug.xcconfig
diff --git a/Tchap/Generated/Images_Riot.swift b/Tchap/Generated/Images_Riot.swift
index cdc2c5c49f..aa59c8834a 100644
--- a/Tchap/Generated/Images_Riot.swift
+++ b/Tchap/Generated/Images_Riot.swift
@@ -22,9 +22,6 @@ internal typealias AssetImageTypeAlias = ImageAsset.Image
internal class Asset: NSObject {
@objcMembers
@objc(AssetImages) internal class Images: NSObject {
- internal static let allChatsOnboarding1 = ImageAsset(name: "all_chats_onboarding1")
- internal static let allChatsOnboarding2 = ImageAsset(name: "all_chats_onboarding2")
- internal static let allChatsOnboarding3 = ImageAsset(name: "all_chats_onboarding3")
internal static let analyticsCheckmark = ImageAsset(name: "AnalyticsCheckmark")
internal static let analyticsLogo = ImageAsset(name: "AnalyticsLogo")
internal static let socialLoginButtonApple = ImageAsset(name: "social_login_button_apple")
diff --git a/Tchap/Utils/Tools.m b/Tchap/Utils/Tools.m
index 0a850e0178..1f4e3930b8 100644
--- a/Tchap/Utils/Tools.m
+++ b/Tchap/Utils/Tools.m
@@ -37,7 +37,11 @@ + (NSString *)presenceText:(MXUser *)user
presenceText = [VectorL10n roomParticipantsIdle];
break;
- case MXPresenceUnknown: // Do like matrix-js-sdk
+ case MXPresenceUnknown:
+ // Fix https://github.com/vector-im/element-ios/issues/6597
+ // Return nil because we don't want to display anything if the status is unknown
+ return nil;
+
case MXPresenceOffline:
presenceText = [VectorL10n roomParticipantsOffline];
break;
diff --git a/Tchap/target.yml b/Tchap/target.yml
index 0389e05569..b38fbf7d97 100644
--- a/Tchap/target.yml
+++ b/Tchap/target.yml
@@ -75,6 +75,7 @@ targetTemplates:
- path: ../Config/Project-Warnings.xcconfig
- path: ../Config/AppIdentifiers.xcconfig
- path: ../Config/CommonConfiguration.swift
+ - path: ../Config/CryptoSDKConfiguration.swift
- path: ../Config/Configurable.swift
- path: ../Tchap
excludes:
@@ -143,6 +144,7 @@ targetTemplates:
- path: ../Riot/Managers/RoomMessageLinkParser/RoomMessageURLParser.swift
- path: ../Riot/Managers/PasswordStrength
- path: ../Riot/Managers/PushNotification
+ - path: ../Riot/Managers/PushRulesUpdater
- path: ../Riot/Managers/Serialization
- path: ../Riot/Managers/Settings/RiotSettings.swift
- path: ../Riot/Managers/Settings/Shared
diff --git a/changelog.d/761.change b/changelog.d/761.change
new file mode 100644
index 0000000000..36682d1cdf
--- /dev/null
+++ b/changelog.d/761.change
@@ -0,0 +1,2 @@
+Rebase/element ios 1.10.2
+
diff --git a/fastlane/Fastfile b/fastlane/Fastfile
index 62a0dbb959..9a3f33a2e4 100644
--- a/fastlane/Fastfile
+++ b/fastlane/Fastfile
@@ -205,6 +205,8 @@ platform :ios do
# Generate xcodebuild additional arguments
xcargs_hash = {
"GCC_PREPROCESSOR_DEFINITIONS" => "$(GCC_PREPROCESSOR_DEFINITIONS) #{additional_preprocessor_definitions}",
+ # Fix XCode 14 code signing issues for Swift packages containing resources bundles.
+ "CODE_SIGN_STYLE" => "Manual",
}
xcargs = xcargs_hash.map { |k, v| "#{k}=#{v.shellescape}" }.join(" ")
diff --git a/project.yml b/project.yml
index 4d14d4020d..f08d4619d7 100644
--- a/project.yml
+++ b/project.yml
@@ -59,7 +59,10 @@ packages:
branch: main
WysiwygComposer:
url: https://github.com/matrix-org/matrix-wysiwyg-composer-swift
- version: 0.19.0
+ version: 0.22.0
DeviceKit:
url: https://github.com/devicekit/DeviceKit
majorVersion: 4.7.0
+ DTCoreText:
+ url: https://github.com/Cocoanetics/DTCoreText
+ version: 1.6.27
\ No newline at end of file