Merge branch 'release/1.8.0/master'
14
.github/workflows/release-alpha.yml
vendored
|
@ -13,7 +13,21 @@ env:
|
|||
MX_GIT_BRANCH: ${{ github.event.pull_request.head.ref }}
|
||||
|
||||
jobs:
|
||||
check-secret:
|
||||
runs-on: macos-11
|
||||
outputs:
|
||||
out-key: ${{ steps.out-key.outputs.defined }}
|
||||
steps:
|
||||
- id: out-key
|
||||
env:
|
||||
P12_KEY: ${{ secrets.ALPHA_CERTIFICATES_P12 }}
|
||||
P12_PASSWORD_KEY: ${{ secrets.ALPHA_CERTIFICATES_P12 }}
|
||||
if: "${{ env.P12_KEY != '' || env.P12_PASSWORD_KEY != '' }}"
|
||||
run: echo "::set-output name=defined::true"
|
||||
build:
|
||||
# Run job if secrets are avilable (not avaiable for forks).
|
||||
needs: [check-secret]
|
||||
if: needs.check-secret.outputs.out-key == 'true'
|
||||
name: Release
|
||||
runs-on: macos-11
|
||||
|
||||
|
|
46
.github/workflows/triage-move-labelled.yml
vendored
|
@ -190,3 +190,49 @@ jobs:
|
|||
env:
|
||||
PROJECT_ID: "PN_kwDOAM0swc3m-g"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
move_FTUE_issues:
|
||||
name: Z-FTUE to FTUE board
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'Z-FTUE')
|
||||
steps:
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
mutation add_to_project($projectid:ID!,$contentid:ID!) {
|
||||
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
|
||||
projectNextItem {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectid: ${{ env.PROJECT_ID }}
|
||||
contentid: ${{ github.event.issue.node_id }}
|
||||
env:
|
||||
PROJECT_ID: "PN_kwDOAM0swc4AAqVx"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
move_WTF_issues:
|
||||
name: Z-WTF to WTF board
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'Z-WTF')
|
||||
steps:
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
mutation add_to_project($projectid:ID!,$contentid:ID!) {
|
||||
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
|
||||
projectNextItem {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectid: ${{ env.PROJECT_ID }}
|
||||
contentid: ${{ github.event.issue.node_id }}
|
||||
env:
|
||||
PROJECT_ID: "PN_kwDOAM0swc4AArk0"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
|
49
CHANGES.md
|
@ -1,3 +1,52 @@
|
|||
## Changes in 1.8.0 (2022-02-09)
|
||||
|
||||
✨ Features
|
||||
|
||||
- Threads: Add `View in room` action to the thread root event. ([#5117](https://github.com/vector-im/element-ios/issues/5117))
|
||||
- Add a splash screen before authentication is shown. ([#5159](https://github.com/vector-im/element-ios/issues/5159))
|
||||
- Remove location sharing settings entry and enable it by default. Add .well-known configuration support for tile server and map styles. ([#5298](https://github.com/vector-im/element-ios/issues/5298))
|
||||
|
||||
🙌 Improvements
|
||||
|
||||
- Show target user avatars for collapsed membership changes ([#4148](https://github.com/vector-im/element-ios/pull/4148))
|
||||
- Updated available emojis with data from https://github.com/missive/emoji-mart/blob/master/data/apple.json ([#5517](https://github.com/vector-im/element-ios/pull/5517))
|
||||
- Upgrade MatrixSDK version ([v0.22.0](https://github.com/matrix-org/matrix-ios-sdk/releases/tag/v0.22.0)).
|
||||
- Permalinks: Create for thread events & handle navigations. ([#5094](https://github.com/vector-im/element-ios/issues/5094))
|
||||
- Search: Navigate to thread view for search results in threads. ([#5095](https://github.com/vector-im/element-ios/issues/5095))
|
||||
- Search: display matching pattern with a highlight color ([#5252](https://github.com/vector-im/element-ios/issues/5252))
|
||||
|
||||
🐛 Bugfixes
|
||||
|
||||
- Share: Handle jpeg and png UTType properly ([#3636](https://github.com/vector-im/element-ios/issues/3636))
|
||||
- Timeline: automatically scroll timeline to the bottom when opening a room or rotating device. ([#4524](https://github.com/vector-im/element-ios/issues/4524))
|
||||
- Fix bugs when building with Xcode 13: bar appearance / header padding / space avatar content size. Additionally, use UIKit context menus on the home screen. ([#4883](https://github.com/vector-im/element-ios/issues/4883))
|
||||
- joining a space seemed to noop ([#5171](https://github.com/vector-im/element-ios/issues/5171))
|
||||
- Accepting a Space Invite has shouty button labels ([#5175](https://github.com/vector-im/element-ios/issues/5175))
|
||||
- RoomDataSource: Avoid reloading of data source on thread screen itself. ([#5263](https://github.com/vector-im/element-ios/issues/5263))
|
||||
- MXKAccount: Gracefully pause the session. ([#5426](https://github.com/vector-im/element-ios/issues/5426))
|
||||
- HomeViewController: Reload section if total number of rooms changed. ([#5448](https://github.com/vector-im/element-ios/issues/5448))
|
||||
- Selecting Transfer in a call should immediately put the the other person on hold until the call connects or the Transfer is cancelled. ([#5451](https://github.com/vector-im/element-ios/issues/5451))
|
||||
- Avatar view prevents to select space in space list ([#5454](https://github.com/vector-im/element-ios/issues/5454))
|
||||
- Fixes media library freezing under iOS 15.2. ([#5465](https://github.com/vector-im/element-ios/issues/5465))
|
||||
- Room Settings: Fix incorrect header title. ([#5525](https://github.com/vector-im/element-ios/issues/5525))
|
||||
|
||||
🗣 Translations
|
||||
|
||||
- Localisation: Add Indonesian and Slovak languages. ([#5048](https://github.com/vector-im/element-ios/issues/5048))
|
||||
|
||||
🧱 Build
|
||||
|
||||
- Fix CI builds for external contributors using forked repos. ([#5496](https://github.com/vector-im/element-ios/pull/5496), [#5491](https://github.com/vector-im/element-ios/issues/5491))
|
||||
- Use Xcode 13.2 to build the project. ([#4883](https://github.com/vector-im/element-ios/issues/4883))
|
||||
|
||||
Others
|
||||
|
||||
- Add WIP to towncrier. ([#5446](https://github.com/vector-im/element-ios/pull/5446))
|
||||
- Add a simple screen SwiftUI template. ([#5349](https://github.com/vector-im/element-ios/issues/5349))
|
||||
- Added a new automation for FTUE and WTF Project boards ([#5493](https://github.com/vector-im/element-ios/issues/5493))
|
||||
- Fix the indentation in the project board automation file on FTU and WTF labels ([#5504](https://github.com/vector-im/element-ios/issues/5504))
|
||||
|
||||
|
||||
## Changes in 1.7.0 (2022-01-25)
|
||||
|
||||
✨ Features
|
||||
|
|
|
@ -15,5 +15,5 @@
|
|||
//
|
||||
|
||||
// Version
|
||||
MARKETING_VERSION = 1.7.0
|
||||
CURRENT_PROJECT_VERSION = 1.7.0
|
||||
MARKETING_VERSION = 1.8.0
|
||||
CURRENT_PROJECT_VERSION = 1.8.0
|
||||
|
|
|
@ -293,9 +293,9 @@ final class BuildSettings: NSObject {
|
|||
static let roomScreenAllowFilesAction: Bool = true
|
||||
|
||||
// Timeline style
|
||||
static let roomScreenAllowTimelineStyleConfiguration: Bool = false
|
||||
static let roomScreenAllowTimelineStyleConfiguration: Bool = true
|
||||
static let roomScreenTimelineDefaultStyleIdentifier: RoomTimelineStyleIdentifier = .plain
|
||||
static var roomScreenEnableMessageBubblesByDefault: Bool {
|
||||
static var isRoomScreenEnableMessageBubblesByDefault: Bool {
|
||||
return self.roomScreenTimelineDefaultStyleIdentifier == .bubble
|
||||
}
|
||||
|
||||
|
@ -351,6 +351,9 @@ final class BuildSettings: NSObject {
|
|||
static let authScreenShowCustomServerOptions = true
|
||||
static let authScreenShowSocialLoginSection = true
|
||||
|
||||
// MARK: - Authentication Options
|
||||
static let authEnableRefreshTokens = false
|
||||
|
||||
// MARK: - Unified Search
|
||||
static let unifiedSearchScreenShowPublicDirectory = true
|
||||
|
||||
|
@ -369,7 +372,7 @@ final class BuildSettings: NSObject {
|
|||
|
||||
// MARK: - Location Sharing
|
||||
|
||||
static let tileServerMapURL = URL(string: "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx")!
|
||||
static let tileServerMapStyleURL = URL(string: "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx")!
|
||||
|
||||
static var locationSharingEnabled: Bool {
|
||||
guard #available(iOS 14, *) else {
|
||||
|
|
|
@ -74,8 +74,13 @@ class CommonConfiguration: NSObject, Configurable {
|
|||
|
||||
// Disable key backup on common
|
||||
sdkOptions.enableKeyBackupWhenStartingMXCrypto = false
|
||||
|
||||
// Pass threading option to the SDK
|
||||
sdkOptions.enableThreads = RiotSettings.shared.enableThreads
|
||||
|
||||
sdkOptions.clientPermalinkBaseUrl = BuildSettings.clientPermalinkBaseUrl
|
||||
|
||||
sdkOptions.authEnableRefreshTokens = BuildSettings.authEnableRefreshTokens
|
||||
// Configure key provider delegate
|
||||
MXKeyProvider.sharedInstance().delegate = EncryptionKeyManager.shared
|
||||
}
|
||||
|
|
5
Podfile
|
@ -13,7 +13,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.21.0'
|
||||
$matrixSDKVersion = '= 0.22.0'
|
||||
# $matrixSDKVersion = :local
|
||||
# $matrixSDKVersion = { :branch => 'develop'}
|
||||
# $matrixSDKVersion = { :specHash => { git: 'https://git.io/fork123', branch: 'fix' } }
|
||||
|
@ -87,6 +87,7 @@ abstract_target 'RiotPods' do
|
|||
import_SwiftUI_pods
|
||||
|
||||
pod 'DGCollectionViewLeftAlignFlowLayout', '~> 1.0.4'
|
||||
pod 'UICollectionViewRightAlignedLayout', '~> 0.0.3'
|
||||
pod 'KTCenterFlowLayout', '~> 1.3.1'
|
||||
pod 'ZXingObjC', '~> 3.6.5'
|
||||
pod 'FlowCommoniOS', '~> 1.12.0'
|
||||
|
@ -150,4 +151,4 @@ post_install do |installer|
|
|||
config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
20
Podfile.lock
|
@ -57,16 +57,16 @@ PODS:
|
|||
- LoggerAPI (1.9.200):
|
||||
- Logging (~> 1.1)
|
||||
- Logging (1.4.0)
|
||||
- MatrixSDK (0.21.0):
|
||||
- MatrixSDK/Core (= 0.21.0)
|
||||
- MatrixSDK/Core (0.21.0):
|
||||
- MatrixSDK (0.22.0):
|
||||
- MatrixSDK/Core (= 0.22.0)
|
||||
- MatrixSDK/Core (0.22.0):
|
||||
- AFNetworking (~> 4.0.0)
|
||||
- GZIP (~> 1.3.0)
|
||||
- libbase58 (~> 0.1.4)
|
||||
- OLMKit (~> 3.2.5)
|
||||
- Realm (= 10.16.0)
|
||||
- SwiftyBeaver (= 1.9.5)
|
||||
- MatrixSDK/JingleCallStack (0.21.0):
|
||||
- MatrixSDK/JingleCallStack (0.22.0):
|
||||
- JitsiMeetSDK (= 3.10.2)
|
||||
- MatrixSDK/Core
|
||||
- OLMKit (3.2.5):
|
||||
|
@ -95,6 +95,7 @@ PODS:
|
|||
- LoggerAPI (~> 1.7)
|
||||
- SwiftLint (0.44.0)
|
||||
- SwiftyBeaver (1.9.5)
|
||||
- UICollectionViewRightAlignedLayout (0.0.3)
|
||||
- WeakDictionary (2.0.2)
|
||||
- zxcvbn-ios (1.0.4)
|
||||
- ZXingObjC (3.6.5):
|
||||
|
@ -116,8 +117,8 @@ DEPENDENCIES:
|
|||
- KeychainAccess (~> 4.2.2)
|
||||
- KTCenterFlowLayout (~> 1.3.1)
|
||||
- libPhoneNumber-iOS (~> 0.9.13)
|
||||
- MatrixSDK (= 0.21.0)
|
||||
- MatrixSDK/JingleCallStack (= 0.21.0)
|
||||
- MatrixSDK (= 0.22.0)
|
||||
- MatrixSDK/JingleCallStack (= 0.22.0)
|
||||
- OLMKit
|
||||
- PostHog (~> 1.4.4)
|
||||
- ReadMoreTextView (~> 3.0.1)
|
||||
|
@ -127,6 +128,7 @@ DEPENDENCIES:
|
|||
- SwiftGen (~> 6.3)
|
||||
- SwiftJWT (~> 3.6.200)
|
||||
- SwiftLint (~> 0.44.0)
|
||||
- UICollectionViewRightAlignedLayout (~> 0.0.3)
|
||||
- WeakDictionary (~> 2.0)
|
||||
- zxcvbn-ios
|
||||
- ZXingObjC (~> 3.6.5)
|
||||
|
@ -169,6 +171,7 @@ SPEC REPOS:
|
|||
- SwiftJWT
|
||||
- SwiftLint
|
||||
- SwiftyBeaver
|
||||
- UICollectionViewRightAlignedLayout
|
||||
- WeakDictionary
|
||||
- zxcvbn-ios
|
||||
- ZXingObjC
|
||||
|
@ -209,7 +212,7 @@ SPEC CHECKSUMS:
|
|||
libPhoneNumber-iOS: 0a32a9525cf8744fe02c5206eb30d571e38f7d75
|
||||
LoggerAPI: ad9c4a6f1e32f518fdb43a1347ac14d765ab5e3d
|
||||
Logging: beeb016c9c80cf77042d62e83495816847ef108b
|
||||
MatrixSDK: cd98e3e4287b8a4f3a5bb47642beae80e8f62534
|
||||
MatrixSDK: 21201cd007145d96beff24cc7f9727ced497c3fd
|
||||
OLMKit: 9fb4799c4a044dd2c06bda31ec31a12191ad30b5
|
||||
PostHog: 4b6321b521569092d4ef3a02238d9435dbaeb99f
|
||||
ReadMoreTextView: 19147adf93abce6d7271e14031a00303fe28720d
|
||||
|
@ -221,10 +224,11 @@ SPEC CHECKSUMS:
|
|||
SwiftJWT: 88c412708f58c169d431d344c87bc79a87c830ae
|
||||
SwiftLint: e96c0a8c770c7ebbc4d36c55baf9096bb65c4584
|
||||
SwiftyBeaver: 84069991dd5dca07d7069100985badaca7f0ce82
|
||||
UICollectionViewRightAlignedLayout: 823eef8c567eba4a44c21bc2ffcb0d0d5f361e2d
|
||||
WeakDictionary: 8cd038acd77e5d54ca4ebaec3d20853d732b45e0
|
||||
zxcvbn-ios: fef98b7c80f1512ff0eec47ac1fa399fc00f7e3c
|
||||
ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb
|
||||
|
||||
PODFILE CHECKSUM: 39329dd448eb0ad10c396f84f854a18962ab1fc4
|
||||
PODFILE CHECKSUM: 2a13c9d4f4894152af066c746582fde2e731cbff
|
||||
|
||||
COCOAPODS: 1.11.2
|
||||
|
|
|
@ -64,27 +64,6 @@
|
|||
</objects>
|
||||
<point key="canvasLocation" x="5047" y="-1437"/>
|
||||
</scene>
|
||||
<!--Room Context Timeline-->
|
||||
<scene sceneID="Htr-h8-baq">
|
||||
<objects>
|
||||
<viewController title="Room Context Timeline" hidesBottomBarWhenPushed="YES" id="Too-LV-OLW" customClass="RoomViewController" sceneMemberID="viewController">
|
||||
<navigationItem key="navigationItem" id="yLe-Hk-Sol">
|
||||
<nil key="title"/>
|
||||
<view key="titleView" contentMode="scaleToFill" id="djN-zB-Vni" userLabel="Room title view container">
|
||||
<rect key="frame" x="8" y="2" width="312" height="40"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
</navigationItem>
|
||||
<connections>
|
||||
<outlet property="roomTitleViewContainer" destination="djN-zB-Vni" id="VQG-Mp-hSa"/>
|
||||
<segue destination="gkO-rP-nGK" kind="show" identifier="showContactDetails" id="ziz-Xl-QVg"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Yjg-uP-Hcy" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="3326" y="-1299"/>
|
||||
</scene>
|
||||
<!--Room Search View Controller-->
|
||||
<scene sceneID="rUg-1s-vHX">
|
||||
<objects>
|
||||
|
@ -98,9 +77,6 @@
|
|||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
<connections>
|
||||
<segue destination="Too-LV-OLW" kind="show" identifier="showTimeline" id="P1V-0d-mYL"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="bK5-DX-KSF" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
|
@ -543,10 +519,29 @@
|
|||
</objects>
|
||||
<point key="canvasLocation" x="374" y="449"/>
|
||||
</scene>
|
||||
<!--Thread-->
|
||||
<scene sceneID="Opl-gU-pwm">
|
||||
<objects>
|
||||
<viewController storyboardIdentifier="ThreadViewControllerStoryboardId" title="Room" hidesBottomBarWhenPushed="YES" id="R2h-H9-hdJ" userLabel="Thread" customClass="ThreadViewController" customModule="Riot" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<navigationItem key="navigationItem" id="TFF-nx-BSb">
|
||||
<nil key="title"/>
|
||||
<view key="titleView" contentMode="scaleToFill" id="e4J-vI-jzo" userLabel="Room title view container">
|
||||
<rect key="frame" x="8" y="2" width="312" height="40"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
</navigationItem>
|
||||
<connections>
|
||||
<outlet property="roomTitleViewContainer" destination="e4J-vI-jzo" id="b1C-TY-2R6"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="kHX-sJ-uYE" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="-153" y="-419"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<inferredMetricsTieBreakers>
|
||||
<segue reference="Tfl-tq-LQp"/>
|
||||
<segue reference="f5u-Y1-7nt"/>
|
||||
</inferredMetricsTieBreakers>
|
||||
<resources>
|
||||
<image name="launch_screen_logo" width="240" height="240"/>
|
||||
|
|
6
Riot/Assets/Images.xcassets/Onboarding/Contents.json
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
15
Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage1.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "OnboardingSplashScreenPage1.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"preserves-vector-representation" : true
|
||||
}
|
||||
}
|
15
Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage1Dark.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "OnboardingSplashScreenPage1-Dark.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"preserves-vector-representation" : true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,872 @@
|
|||
%PDF-1.7
|
||||
|
||||
1 0 obj
|
||||
<< /Type /XObject
|
||||
/Length 2 0 R
|
||||
/Group << /Type /Group
|
||||
/S /Transparency
|
||||
>>
|
||||
/Subtype /Form
|
||||
/Resources << >>
|
||||
/BBox [ 0.000000 0.000000 300.000000 300.000000 ]
|
||||
>>
|
||||
stream
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 116.000000 142.000000 cm
|
||||
0.083333 0.083333 0.083333 scn
|
||||
0.000000 6.500000 m
|
||||
0.000000 10.089850 2.910149 13.000000 6.500000 13.000000 c
|
||||
87.500000 13.000000 l
|
||||
91.089851 13.000000 94.000000 10.089850 94.000000 6.500000 c
|
||||
94.000000 6.500000 l
|
||||
94.000000 2.910150 91.089851 0.000000 87.500000 0.000000 c
|
||||
6.500002 0.000000 l
|
||||
2.910151 0.000000 0.000000 2.910150 0.000000 6.500000 c
|
||||
0.000000 6.500000 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 116.000000 142.000000 cm
|
||||
1.000000 0.505882 0.176471 scn
|
||||
0.000000 6.500000 m
|
||||
0.000000 10.089850 2.910149 13.000000 6.500000 13.000000 c
|
||||
87.500000 13.000000 l
|
||||
91.089851 13.000000 94.000000 10.089850 94.000000 6.500000 c
|
||||
94.000000 6.500000 l
|
||||
94.000000 2.910150 91.089851 0.000000 87.500000 0.000000 c
|
||||
6.500002 0.000000 l
|
||||
2.910151 0.000000 0.000000 2.910150 0.000000 6.500000 c
|
||||
0.000000 6.500000 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
882
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
<< /Type /XObject
|
||||
/Length 4 0 R
|
||||
/Group << /Type /Group
|
||||
/S /Transparency
|
||||
>>
|
||||
/Subtype /Form
|
||||
/Resources << >>
|
||||
/BBox [ 0.000000 0.000000 300.000000 300.000000 ]
|
||||
>>
|
||||
stream
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 127.119080 85.000000 cm
|
||||
0.083333 0.083333 0.083333 scn
|
||||
0.000000 6.500000 m
|
||||
0.000000 10.089850 2.910149 13.000000 6.500000 13.000000 c
|
||||
119.500000 13.000000 l
|
||||
123.089851 13.000000 126.000000 10.089850 126.000000 6.500000 c
|
||||
126.000000 6.500000 l
|
||||
126.000000 2.910150 123.089851 0.000000 119.500000 0.000000 c
|
||||
6.499998 0.000000 l
|
||||
2.910147 0.000000 0.000000 2.910150 0.000000 6.500000 c
|
||||
0.000000 6.500000 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 127.119080 85.000000 cm
|
||||
0.454902 0.819608 0.172549 scn
|
||||
0.000000 6.500000 m
|
||||
0.000000 10.089850 2.910149 13.000000 6.500000 13.000000 c
|
||||
119.500000 13.000000 l
|
||||
123.089851 13.000000 126.000000 10.089850 126.000000 6.500000 c
|
||||
126.000000 6.500000 l
|
||||
126.000000 2.910150 123.089851 0.000000 119.500000 0.000000 c
|
||||
6.499998 0.000000 l
|
||||
2.910147 0.000000 0.000000 2.910150 0.000000 6.500000 c
|
||||
0.000000 6.500000 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
896
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<< /Type /XObject
|
||||
/Length 6 0 R
|
||||
/Group << /Type /Group
|
||||
/S /Transparency
|
||||
>>
|
||||
/Subtype /Form
|
||||
/Resources << >>
|
||||
/BBox [ 0.000000 0.000000 300.000000 300.000000 ]
|
||||
>>
|
||||
stream
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 102.000000 207.000000 cm
|
||||
0.083333 0.083333 0.083333 scn
|
||||
0.000000 6.500000 m
|
||||
0.000000 10.089850 2.910149 13.000000 6.500000 13.000000 c
|
||||
119.500000 13.000000 l
|
||||
123.089851 13.000000 126.000000 10.089850 126.000000 6.500000 c
|
||||
126.000000 6.500000 l
|
||||
126.000000 2.910150 123.089851 0.000000 119.500000 0.000000 c
|
||||
6.499998 0.000000 l
|
||||
2.910147 0.000000 0.000000 2.910150 0.000000 6.500000 c
|
||||
0.000000 6.500000 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 102.000000 207.000000 cm
|
||||
0.360784 0.337255 0.960784 scn
|
||||
0.000000 6.500000 m
|
||||
0.000000 10.089850 2.910149 13.000000 6.500000 13.000000 c
|
||||
119.500000 13.000000 l
|
||||
123.089851 13.000000 126.000000 10.089850 126.000000 6.500000 c
|
||||
126.000000 6.500000 l
|
||||
126.000000 2.910150 123.089851 0.000000 119.500000 0.000000 c
|
||||
6.499998 0.000000 l
|
||||
2.910147 0.000000 0.000000 2.910150 0.000000 6.500000 c
|
||||
0.000000 6.500000 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
898
|
||||
endobj
|
||||
|
||||
7 0 obj
|
||||
<< /Type /XObject
|
||||
/Length 8 0 R
|
||||
/Group << /Type /Group
|
||||
/S /Transparency
|
||||
>>
|
||||
/Subtype /Form
|
||||
/Resources << /XObject << /X2 1 0 R
|
||||
/X3 3 0 R
|
||||
/X1 5 0 R
|
||||
>>
|
||||
/ExtGState << /E6 << /ca 0.400000 >>
|
||||
/E4 << /ca 0.500000 >>
|
||||
/E2 << /ca 0.500000 >>
|
||||
/E5 << /ca 0.700000 >>
|
||||
/E3 << /ca 0.700000 >>
|
||||
/E1 << /ca 0.700000 >>
|
||||
>>
|
||||
>>
|
||||
/BBox [ 0.000000 0.000000 300.000000 300.000000 ]
|
||||
>>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 51.000000 183.000000 cm
|
||||
0.054167 0.054167 0.054167 scn
|
||||
38.000000 19.000000 m
|
||||
38.000000 8.506590 29.493410 0.000000 19.000000 0.000000 c
|
||||
8.506590 0.000000 0.000000 8.506590 0.000000 19.000000 c
|
||||
0.000000 29.493410 8.506590 38.000000 19.000000 38.000000 c
|
||||
29.493410 38.000000 38.000000 29.493410 38.000000 19.000000 c
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
/E1 gs
|
||||
1.000000 0.000000 -0.000000 1.000000 51.000000 183.000000 cm
|
||||
0.835294 0.847059 0.968627 scn
|
||||
38.000000 19.000000 m
|
||||
38.000000 8.506590 29.493410 0.000000 19.000000 0.000000 c
|
||||
8.506590 0.000000 0.000000 8.506590 0.000000 19.000000 c
|
||||
0.000000 29.493410 8.506590 38.000000 19.000000 38.000000 c
|
||||
29.493410 38.000000 38.000000 29.493410 38.000000 19.000000 c
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
/E2 gs
|
||||
/X1 Do
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 102.000000 184.000000 cm
|
||||
0.054167 0.054167 0.054167 scn
|
||||
0.000000 6.500000 m
|
||||
0.000000 10.089850 2.910149 13.000000 6.500000 13.000000 c
|
||||
141.500000 13.000000 l
|
||||
145.089859 13.000000 148.000000 10.089850 148.000000 6.500000 c
|
||||
148.000000 6.500000 l
|
||||
148.000000 2.910150 145.089844 0.000000 141.500000 0.000000 c
|
||||
6.499999 0.000000 l
|
||||
2.910148 0.000000 0.000000 2.910150 0.000000 6.500000 c
|
||||
0.000000 6.500000 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 102.000000 184.000000 cm
|
||||
0.556863 0.600000 0.643137 scn
|
||||
0.000000 6.500000 m
|
||||
0.000000 10.089850 2.910149 13.000000 6.500000 13.000000 c
|
||||
141.500000 13.000000 l
|
||||
145.089859 13.000000 148.000000 10.089850 148.000000 6.500000 c
|
||||
148.000000 6.500000 l
|
||||
148.000000 2.910150 145.089844 0.000000 141.500000 0.000000 c
|
||||
6.499999 0.000000 l
|
||||
2.910148 0.000000 0.000000 2.910150 0.000000 6.500000 c
|
||||
0.000000 6.500000 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 60.000000 119.000000 cm
|
||||
0.054167 0.054167 0.054167 scn
|
||||
38.000000 19.000000 m
|
||||
38.000000 8.506590 29.493410 0.000000 19.000000 0.000000 c
|
||||
8.506590 0.000000 0.000000 8.506590 0.000000 19.000000 c
|
||||
0.000000 29.493410 8.506590 38.000000 19.000000 38.000000 c
|
||||
29.493410 38.000000 38.000000 29.493410 38.000000 19.000000 c
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
/E3 gs
|
||||
1.000000 0.000000 -0.000000 1.000000 60.000000 119.000000 cm
|
||||
0.964706 0.878431 0.811765 scn
|
||||
38.000000 19.000000 m
|
||||
38.000000 8.506590 29.493410 0.000000 19.000000 0.000000 c
|
||||
8.506590 0.000000 0.000000 8.506590 0.000000 19.000000 c
|
||||
0.000000 29.493410 8.506590 38.000000 19.000000 38.000000 c
|
||||
29.493410 38.000000 38.000000 29.493410 38.000000 19.000000 c
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
/E4 gs
|
||||
/X2 Do
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 116.000000 121.000000 cm
|
||||
0.054167 0.054167 0.054167 scn
|
||||
0.000000 6.500000 m
|
||||
0.000000 10.089850 2.910149 13.000000 6.500000 13.000000 c
|
||||
56.500000 13.000000 l
|
||||
60.089848 13.000000 63.000000 10.089850 63.000000 6.500000 c
|
||||
63.000000 6.500000 l
|
||||
63.000000 2.910150 60.089851 0.000000 56.500000 0.000000 c
|
||||
6.500001 0.000000 l
|
||||
2.910151 0.000000 0.000000 2.910150 0.000000 6.500000 c
|
||||
0.000000 6.500000 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 116.000000 121.000000 cm
|
||||
0.556863 0.600000 0.643137 scn
|
||||
0.000000 6.500000 m
|
||||
0.000000 10.089850 2.910149 13.000000 6.500000 13.000000 c
|
||||
56.500000 13.000000 l
|
||||
60.089848 13.000000 63.000000 10.089850 63.000000 6.500000 c
|
||||
63.000000 6.500000 l
|
||||
63.000000 2.910150 60.089851 0.000000 56.500000 0.000000 c
|
||||
6.500001 0.000000 l
|
||||
2.910151 0.000000 0.000000 2.910150 0.000000 6.500000 c
|
||||
0.000000 6.500000 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 189.000000 121.000000 cm
|
||||
0.054167 0.054167 0.054167 scn
|
||||
0.000000 6.500000 m
|
||||
0.000000 10.089850 2.910149 13.000000 6.500000 13.000000 c
|
||||
57.500000 13.000000 l
|
||||
61.089851 13.000000 64.000000 10.089850 64.000000 6.500000 c
|
||||
64.000000 6.500000 l
|
||||
64.000000 2.910150 61.089851 0.000000 57.500000 0.000000 c
|
||||
6.500000 0.000000 l
|
||||
2.910149 0.000000 0.000000 2.910150 0.000000 6.500000 c
|
||||
0.000000 6.500000 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 189.000000 121.000000 cm
|
||||
0.556863 0.600000 0.643137 scn
|
||||
0.000000 6.500000 m
|
||||
0.000000 10.089850 2.910149 13.000000 6.500000 13.000000 c
|
||||
57.500000 13.000000 l
|
||||
61.089851 13.000000 64.000000 10.089850 64.000000 6.500000 c
|
||||
64.000000 6.500000 l
|
||||
64.000000 2.910150 61.089851 0.000000 57.500000 0.000000 c
|
||||
6.500000 0.000000 l
|
||||
2.910149 0.000000 0.000000 2.910150 0.000000 6.500000 c
|
||||
0.000000 6.500000 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 69.999939 60.000000 cm
|
||||
1.000000 1.000000 1.000000 scn
|
||||
38.000000 19.000000 m
|
||||
38.000000 8.506590 29.493410 0.000000 19.000000 0.000000 c
|
||||
8.506590 0.000000 0.000000 8.506590 0.000000 19.000000 c
|
||||
0.000000 29.493410 8.506590 38.000000 19.000000 38.000000 c
|
||||
29.493410 38.000000 38.000000 29.493410 38.000000 19.000000 c
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 69.999939 60.000000 cm
|
||||
0.054167 0.054167 0.054167 scn
|
||||
38.000000 19.000000 m
|
||||
38.000000 8.506590 29.493410 0.000000 19.000000 0.000000 c
|
||||
8.506590 0.000000 0.000000 8.506590 0.000000 19.000000 c
|
||||
0.000000 29.493410 8.506590 38.000000 19.000000 38.000000 c
|
||||
29.493410 38.000000 38.000000 29.493410 38.000000 19.000000 c
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
/E5 gs
|
||||
1.000000 0.000000 -0.000000 1.000000 69.999939 60.000000 cm
|
||||
0.894118 0.964706 0.894118 scn
|
||||
38.000000 19.000000 m
|
||||
38.000000 8.506590 29.493410 0.000000 19.000000 0.000000 c
|
||||
8.506590 0.000000 0.000000 8.506590 0.000000 19.000000 c
|
||||
0.000000 29.493410 8.506590 38.000000 19.000000 38.000000 c
|
||||
29.493410 38.000000 38.000000 29.493410 38.000000 19.000000 c
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
/E6 gs
|
||||
/X3 Do
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 115.999939 72.000000 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
0.000000 9.000000 m
|
||||
0.000000 13.970562 4.029438 18.000000 9.000000 18.000000 c
|
||||
23.000000 18.000000 l
|
||||
27.970562 18.000000 32.000000 13.970562 32.000000 9.000000 c
|
||||
32.000000 9.000000 l
|
||||
32.000000 4.029437 27.970562 0.000000 23.000000 0.000000 c
|
||||
9.000000 0.000000 l
|
||||
4.029438 0.000000 0.000000 4.029437 0.000000 9.000000 c
|
||||
0.000000 9.000000 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 123.366089 77.722778 cm
|
||||
0.557143 0.600000 0.642857 scn
|
||||
4.910892 3.273924 m
|
||||
4.910892 1.917818 3.811552 0.818478 2.455446 0.818478 c
|
||||
1.099341 0.818478 0.000000 1.917818 0.000000 3.273924 c
|
||||
0.000000 4.630030 1.099341 5.729370 2.455446 5.729370 c
|
||||
3.811552 5.729370 4.910892 4.630030 4.910892 3.273924 c
|
||||
h
|
||||
11.458750 2.455442 m
|
||||
11.458750 1.099336 10.359408 -0.000004 9.003304 -0.000004 c
|
||||
7.647198 -0.000004 6.547857 1.099336 6.547857 2.455442 c
|
||||
6.547857 3.811547 7.647198 4.910888 9.003304 4.910888 c
|
||||
10.359408 4.910888 11.458750 3.811547 11.458750 2.455442 c
|
||||
h
|
||||
15.551160 -0.000004 m
|
||||
16.907265 -0.000004 18.006607 1.099336 18.006607 2.455442 c
|
||||
18.006607 3.811547 16.907265 4.910888 15.551160 4.910888 c
|
||||
14.195054 4.910888 13.095714 3.811547 13.095714 2.455442 c
|
||||
13.095714 1.099336 14.195054 -0.000004 15.551160 -0.000004 c
|
||||
h
|
||||
f*
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
8 0 obj
|
||||
6601
|
||||
endobj
|
||||
|
||||
9 0 obj
|
||||
<< /Length 10 0 R
|
||||
/Range [ 0.000000 1.000000 0.000000 1.000000 0.000000 1.000000 ]
|
||||
/Domain [ 0.000000 1.000000 ]
|
||||
/FunctionType 4
|
||||
>>
|
||||
stream
|
||||
{ 0.890196 exch 0.909804 exch 0.941176 exch dup 0.885417 gt { exch pop exch pop exch pop dup 0.885417 sub -1.163636 mul 0.890196 add exch dup 0.885417 sub -1.163636 mul 0.909804 add exch dup 0.885417 sub -1.197861 mul 0.941176 add exch } if dup 1.000000 gt { exch pop exch pop exch pop 0.756863 exch 0.776471 exch 0.803922 exch } if pop }
|
||||
endstream
|
||||
endobj
|
||||
|
||||
10 0 obj
|
||||
339
|
||||
endobj
|
||||
|
||||
11 0 obj
|
||||
<< /Length 12 0 R
|
||||
/Range [ 0.000000 1.000000 0.000000 1.000000 0.000000 1.000000 ]
|
||||
/Domain [ 0.000000 1.000000 ]
|
||||
/FunctionType 4
|
||||
>>
|
||||
stream
|
||||
{ 0.560784 exch 0.592157 exch 0.639216 exch dup 0.436121 gt { exch pop exch pop exch pop dup 0.436121 sub -1.132947 mul 0.560784 add exch dup 0.436121 sub -1.040270 mul 0.592157 add exch dup 0.436121 sub -1.080743 mul 0.639216 add exch } if dup 0.797508 gt { exch pop exch pop exch pop 0.151351 exch 0.216216 exch 0.248649 exch } if pop }
|
||||
endstream
|
||||
endobj
|
||||
|
||||
12 0 obj
|
||||
339
|
||||
endobj
|
||||
|
||||
13 0 obj
|
||||
<< /Length 14 0 R
|
||||
/Range [ 0.000000 1.000000 0.000000 1.000000 0.000000 1.000000 ]
|
||||
/Domain [ 0.000000 1.000000 ]
|
||||
/FunctionType 4
|
||||
>>
|
||||
stream
|
||||
{ 0.211765 exch 0.545098 exch 0.839216 exch dup 0.000000 gt { exch pop exch pop exch pop dup 0.000000 sub 4.324034 mul 0.211765 add exch dup 0.000000 sub -0.215126 mul 0.545098 add exch dup 0.000000 sub -3.635630 mul 0.839216 add exch } if dup 0.182292 gt { exch pop exch pop exch pop dup 0.182292 sub -0.472174 mul 1.000000 add exch dup 0.182292 sub -0.944349 mul 0.505882 add exch dup 0.182292 sub 1.454296 mul 0.176471 add exch } if dup 0.389925 gt { exch pop exch pop exch pop dup 0.389925 sub -4.864687 mul 0.901961 add exch dup 0.389925 sub 2.143034 mul 0.309804 add exch dup 0.389925 sub 0.150013 mul 0.478431 add exch } if dup 0.572917 gt { exch pop exch pop exch pop dup 0.572917 sub 0.810860 mul 0.011765 add exch dup 0.572917 sub 0.289593 mul 0.701961 add exch dup 0.572917 sub 1.312820 mul 0.505882 add exch } if dup 0.776042 gt { exch pop exch pop exch pop dup 0.776042 sub 2.223803 mul 0.176471 add exch dup 0.776042 sub -2.363885 mul 0.760784 add exch dup 0.776042 sub -0.507798 mul 0.772549 add exch } if dup 1.000000 gt { exch pop exch pop exch pop 0.674510 exch 0.231373 exch 0.658824 exch } if pop }
|
||||
endstream
|
||||
endobj
|
||||
|
||||
14 0 obj
|
||||
1119
|
||||
endobj
|
||||
|
||||
15 0 obj
|
||||
<< /Length 16 0 R
|
||||
/Range [ 0.000000 1.000000 ]
|
||||
/Domain [ 0.000000 1.000000 ]
|
||||
/FunctionType 4
|
||||
>>
|
||||
stream
|
||||
{ 0.000000 exch dup 0.885417 gt { exch pop dup 0.885417 sub 8.727274 mul 0.000000 add exch } if dup 1.000000 gt { exch pop 1.000000 exch } if pop }
|
||||
endstream
|
||||
endobj
|
||||
|
||||
16 0 obj
|
||||
148
|
||||
endobj
|
||||
|
||||
17 0 obj
|
||||
<< /BBox [ 0.000000 0.000000 300.000000 300.000000 ]
|
||||
/Resources << /Pattern << /P1 << /Matrix [ -127.403831 248.798080 -248.798080 -127.403831 347.956726 70.673119 ]
|
||||
/Shading << /Coords [ 0.500000 0.500000 0.000000 0.500000 0.500000 0.500000 ]
|
||||
/ColorSpace /DeviceGray
|
||||
/Function 15 0 R
|
||||
/Domain [ 0.000000 1.000000 ]
|
||||
/ShadingType 3
|
||||
/Extend [ true true ]
|
||||
>>
|
||||
/PatternType 2
|
||||
/Type /Pattern
|
||||
>> >> >>
|
||||
/Subtype /Form
|
||||
/Length 18 0 R
|
||||
/Group << /Type /Group
|
||||
/S /Transparency
|
||||
/CS /DeviceGray
|
||||
>>
|
||||
/Type /XObject
|
||||
>>
|
||||
stream
|
||||
/DeviceGray CS
|
||||
/DeviceGray cs
|
||||
1.000000 0.000000 -0.000000 1.000000 25.000000 25.000000 cm
|
||||
250.000000 125.000000 m
|
||||
250.000000 55.964401 194.035599 0.000000 125.000000 0.000000 c
|
||||
55.964405 0.000000 0.000000 55.964401 0.000000 125.000000 c
|
||||
0.000000 194.035599 55.964405 250.000000 125.000000 250.000000 c
|
||||
194.035599 250.000000 250.000000 194.035599 250.000000 125.000000 c
|
||||
h
|
||||
/Pattern cs
|
||||
/P1 scn
|
||||
f
|
||||
n
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
18 0 obj
|
||||
396
|
||||
endobj
|
||||
|
||||
19 0 obj
|
||||
<< /Type /XObject
|
||||
/Length 20 0 R
|
||||
/Group << /Type /Group
|
||||
/S /Transparency
|
||||
>>
|
||||
/Subtype /Form
|
||||
/Resources << /Pattern << /P3 << /Matrix [ -127.403831 248.798080 -248.798080 -127.403831 347.956726 70.673119 ]
|
||||
/Shading << /Coords [ 0.500000 0.500000 0.000000 0.500000 0.500000 0.500000 ]
|
||||
/ColorSpace /DeviceRGB
|
||||
/Function 9 0 R
|
||||
/Domain [ 0.000000 1.000000 ]
|
||||
/ShadingType 3
|
||||
/Extend [ true true ]
|
||||
>>
|
||||
/PatternType 2
|
||||
/Type /Pattern
|
||||
>>
|
||||
/P2 << /Matrix [ 105.999977 -284.000061 361.623688 134.972168 -115.811859 256.513977 ]
|
||||
/Shading << /Coords [ 0.500000 0.500000 0.000000 0.500000 0.500000 0.500000 ]
|
||||
/ColorSpace /DeviceRGB
|
||||
/Function 11 0 R
|
||||
/Domain [ 0.000000 1.000000 ]
|
||||
/ShadingType 3
|
||||
/Extend [ true true ]
|
||||
>>
|
||||
/PatternType 2
|
||||
/Type /Pattern
|
||||
>>
|
||||
/P1 << /Matrix [ 256.865387 -254.788467 254.788467 256.865387 -268.954285 56.983734 ]
|
||||
/Shading << /Coords [ 0.000000 0.000000 1.000000 0.000000 ]
|
||||
/ColorSpace /DeviceRGB
|
||||
/Function 13 0 R
|
||||
/Domain [ 0.000000 1.000000 ]
|
||||
/ShadingType 2
|
||||
/Extend [ true true ]
|
||||
>>
|
||||
/PatternType 2
|
||||
/Type /Pattern
|
||||
>>
|
||||
>>
|
||||
/ExtGState << /E4 << /SMask << /Type /Mask
|
||||
/G 17 0 R
|
||||
/S /Luminosity
|
||||
>>
|
||||
/Type /ExtGState
|
||||
>>
|
||||
/E2 << /ca 0.500000 >>
|
||||
/E3 << /ca 0.400000 >>
|
||||
/E1 << /ca 0.200000 >>
|
||||
>>
|
||||
>>
|
||||
/BBox [ 0.000000 0.000000 300.000000 300.000000 ]
|
||||
>>
|
||||
stream
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 25.000000 25.000000 cm
|
||||
0.098039 0.113725 0.129412 scn
|
||||
250.000000 125.000000 m
|
||||
250.000000 55.964401 194.035599 0.000000 125.000000 0.000000 c
|
||||
55.964405 0.000000 0.000000 55.964401 0.000000 125.000000 c
|
||||
0.000000 194.035599 55.964405 250.000000 125.000000 250.000000 c
|
||||
194.035599 250.000000 250.000000 194.035599 250.000000 125.000000 c
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
/E1 gs
|
||||
1.000000 0.000000 -0.000000 1.000000 25.000000 25.000000 cm
|
||||
/Pattern cs
|
||||
/P1 scn
|
||||
250.000000 125.000000 m
|
||||
250.000000 55.964401 194.035599 0.000000 125.000000 0.000000 c
|
||||
55.964405 0.000000 0.000000 55.964401 0.000000 125.000000 c
|
||||
0.000000 194.035599 55.964405 250.000000 125.000000 250.000000 c
|
||||
194.035599 250.000000 250.000000 194.035599 250.000000 125.000000 c
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
/E2 gs
|
||||
1.000000 0.000000 -0.000000 1.000000 25.000000 25.000000 cm
|
||||
/Pattern cs
|
||||
/P2 scn
|
||||
250.000000 125.000000 m
|
||||
250.000000 55.964401 194.035599 0.000000 125.000000 0.000000 c
|
||||
55.964405 0.000000 0.000000 55.964401 0.000000 125.000000 c
|
||||
0.000000 194.035599 55.964405 250.000000 125.000000 250.000000 c
|
||||
194.035599 250.000000 250.000000 194.035599 250.000000 125.000000 c
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
/E3 gs
|
||||
/E4 gs
|
||||
1.000000 0.000000 -0.000000 1.000000 25.000000 25.000000 cm
|
||||
/Pattern cs
|
||||
/P3 scn
|
||||
250.000000 125.000000 m
|
||||
250.000000 55.964401 194.035599 0.000000 125.000000 0.000000 c
|
||||
55.964405 0.000000 0.000000 55.964401 0.000000 125.000000 c
|
||||
0.000000 194.035599 55.964405 250.000000 125.000000 250.000000 c
|
||||
194.035599 250.000000 250.000000 194.035599 250.000000 125.000000 c
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
20 0 obj
|
||||
1519
|
||||
endobj
|
||||
|
||||
21 0 obj
|
||||
<< /Length 22 0 R
|
||||
/Range [ 0.000000 1.000000 0.000000 1.000000 0.000000 1.000000 ]
|
||||
/Domain [ 0.000000 1.000000 ]
|
||||
/FunctionType 4
|
||||
>>
|
||||
stream
|
||||
{ 1.000000 exch 1.000000 exch 1.000000 exch dup 0.258514 gt { exch pop exch pop exch pop dup 0.258514 sub 0.000000 mul 1.000000 add exch dup 0.258514 sub 0.000000 mul 1.000000 add exch dup 0.258514 sub 0.000000 mul 1.000000 add exch } if dup 0.942462 gt { exch pop exch pop exch pop 1.000000 exch 1.000000 exch 1.000000 exch } if pop }
|
||||
endstream
|
||||
endobj
|
||||
|
||||
22 0 obj
|
||||
336
|
||||
endobj
|
||||
|
||||
23 0 obj
|
||||
<< /Length 24 0 R
|
||||
/Range [ 0.000000 1.000000 ]
|
||||
/Domain [ 0.000000 1.000000 ]
|
||||
/FunctionType 4
|
||||
>>
|
||||
stream
|
||||
{ 1.000000 exch dup 0.258514 gt { exch pop dup 0.258514 sub -1.462099 mul 1.000000 add exch } if dup 0.942462 gt { exch pop 0.000000 exch } if pop }
|
||||
endstream
|
||||
endobj
|
||||
|
||||
24 0 obj
|
||||
149
|
||||
endobj
|
||||
|
||||
25 0 obj
|
||||
<< /BBox [ 0.000000 0.000000 300.000000 300.000000 ]
|
||||
/Resources << /Pattern << /P1 << /Matrix [ 18.000000 -296.999969 296.999969 18.000000 -16.499969 313.000000 ]
|
||||
/Shading << /Coords [ 0.500000 0.500000 0.000000 0.500000 0.500000 0.500000 ]
|
||||
/ColorSpace /DeviceGray
|
||||
/Function 23 0 R
|
||||
/Domain [ 0.000000 1.000000 ]
|
||||
/ShadingType 3
|
||||
/Extend [ true true ]
|
||||
>>
|
||||
/PatternType 2
|
||||
/Type /Pattern
|
||||
>> >> >>
|
||||
/Subtype /Form
|
||||
/Length 26 0 R
|
||||
/Group << /Type /Group
|
||||
/S /Transparency
|
||||
/CS /DeviceGray
|
||||
>>
|
||||
/Type /XObject
|
||||
>>
|
||||
stream
|
||||
/DeviceGray CS
|
||||
/DeviceGray cs
|
||||
1.000000 0.000000 -0.000000 1.000000 25.000000 25.000000 cm
|
||||
250.000000 125.000000 m
|
||||
250.000000 55.964401 194.035599 0.000000 125.000000 0.000000 c
|
||||
55.964405 0.000000 0.000000 55.964401 0.000000 125.000000 c
|
||||
0.000000 194.035599 55.964405 250.000000 125.000000 250.000000 c
|
||||
194.035599 250.000000 250.000000 194.035599 250.000000 125.000000 c
|
||||
h
|
||||
/Pattern cs
|
||||
/P1 scn
|
||||
f
|
||||
n
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
26 0 obj
|
||||
396
|
||||
endobj
|
||||
|
||||
27 0 obj
|
||||
<< /Type /XObject
|
||||
/Length 28 0 R
|
||||
/Group << /Type /Group
|
||||
/S /Transparency
|
||||
>>
|
||||
/Subtype /Form
|
||||
/Resources << /Pattern << /P1 << /Matrix [ 18.000000 -296.999969 296.999969 18.000000 -16.499969 313.000000 ]
|
||||
/Shading << /Coords [ 0.500000 0.500000 0.000000 0.500000 0.500000 0.500000 ]
|
||||
/ColorSpace /DeviceRGB
|
||||
/Function 21 0 R
|
||||
/Domain [ 0.000000 1.000000 ]
|
||||
/ShadingType 3
|
||||
/Extend [ true true ]
|
||||
>>
|
||||
/PatternType 2
|
||||
/Type /Pattern
|
||||
>> >>
|
||||
/ExtGState << /E1 << /SMask << /Type /Mask
|
||||
/G 25 0 R
|
||||
/S /Luminosity
|
||||
>>
|
||||
/Type /ExtGState
|
||||
>> >>
|
||||
>>
|
||||
/BBox [ 0.000000 0.000000 300.000000 300.000000 ]
|
||||
>>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
/E1 gs
|
||||
1.000000 0.000000 -0.000000 1.000000 25.000000 25.000000 cm
|
||||
/Pattern cs
|
||||
/P1 scn
|
||||
250.000000 125.000000 m
|
||||
250.000000 55.964401 194.035599 0.000000 125.000000 0.000000 c
|
||||
55.964405 0.000000 0.000000 55.964401 0.000000 125.000000 c
|
||||
0.000000 194.035599 55.964405 250.000000 125.000000 250.000000 c
|
||||
194.035599 250.000000 250.000000 194.035599 250.000000 125.000000 c
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
28 0 obj
|
||||
405
|
||||
endobj
|
||||
|
||||
29 0 obj
|
||||
<< /XObject << /X2 7 0 R
|
||||
/X1 19 0 R
|
||||
>>
|
||||
/ExtGState << /E2 << /SMask << /Type /Mask
|
||||
/G 27 0 R
|
||||
/S /Alpha
|
||||
>>
|
||||
/Type /ExtGState
|
||||
>>
|
||||
/E1 << /ca 0.600000 >>
|
||||
>>
|
||||
>>
|
||||
endobj
|
||||
|
||||
30 0 obj
|
||||
<< /Length 31 0 R >>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
/E1 gs
|
||||
/X1 Do
|
||||
Q
|
||||
q
|
||||
/E2 gs
|
||||
/X2 Do
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
31 0 obj
|
||||
64
|
||||
endobj
|
||||
|
||||
32 0 obj
|
||||
<< /Annots []
|
||||
/Type /Page
|
||||
/MediaBox [ 0.000000 0.000000 300.000000 300.000000 ]
|
||||
/Resources 29 0 R
|
||||
/Contents 30 0 R
|
||||
/Parent 33 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
33 0 obj
|
||||
<< /Kids [ 32 0 R ]
|
||||
/Count 1
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
34 0 obj
|
||||
<< /Pages 33 0 R
|
||||
/Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 35
|
||||
0000000000 65535 f
|
||||
0000000010 00000 n
|
||||
0000001142 00000 n
|
||||
0000001164 00000 n
|
||||
0000002310 00000 n
|
||||
0000002332 00000 n
|
||||
0000003480 00000 n
|
||||
0000003502 00000 n
|
||||
0000010873 00000 n
|
||||
0000010896 00000 n
|
||||
0000011420 00000 n
|
||||
0000011443 00000 n
|
||||
0000011968 00000 n
|
||||
0000011991 00000 n
|
||||
0000013296 00000 n
|
||||
0000013320 00000 n
|
||||
0000013618 00000 n
|
||||
0000013641 00000 n
|
||||
0000015090 00000 n
|
||||
0000015113 00000 n
|
||||
0000019782 00000 n
|
||||
0000019806 00000 n
|
||||
0000020328 00000 n
|
||||
0000020351 00000 n
|
||||
0000020650 00000 n
|
||||
0000020673 00000 n
|
||||
0000022119 00000 n
|
||||
0000022142 00000 n
|
||||
0000023918 00000 n
|
||||
0000023941 00000 n
|
||||
0000024341 00000 n
|
||||
0000024463 00000 n
|
||||
0000024485 00000 n
|
||||
0000024664 00000 n
|
||||
0000024740 00000 n
|
||||
trailer
|
||||
<< /ID [ (some) (id) ]
|
||||
/Root 34 0 R
|
||||
/Size 35
|
||||
>>
|
||||
startxref
|
||||
24801
|
||||
%%EOF
|
15
Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage2.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "OnboardingSplashScreenPage2.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"preserves-vector-representation" : true
|
||||
}
|
||||
}
|
15
Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage2Dark.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "OnboardingSplashScreenPage2-Dark.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"preserves-vector-representation" : true
|
||||
}
|
||||
}
|
15
Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage3.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "OnboardingSplashScreenPage3.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"preserves-vector-representation" : true
|
||||
}
|
||||
}
|
15
Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage3Dark.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "OnboardingSplashScreenPage3-Dark.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"preserves-vector-representation" : true
|
||||
}
|
||||
}
|
15
Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage4.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "OnboardingSplashScreenPage4.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"preserves-vector-representation" : true
|
||||
}
|
||||
}
|
15
Riot/Assets/Images.xcassets/Onboarding/OnboardingSplashScreenPage4Dark.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "OnboardingSplashScreenPage4-Dark.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"preserves-vector-representation" : true
|
||||
}
|
||||
}
|
|
@ -19,5 +19,8 @@
|
|||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"template-rendering-intent" : "template"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,5 +19,8 @@
|
|||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"template-rendering-intent" : "template"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
23
Riot/Assets/Images.xcassets/Room/ContextMenu/room_context_menu_thread.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "Thread.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "Thread@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "Thread@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
Riot/Assets/Images.xcassets/Room/ContextMenu/room_context_menu_thread.imageset/Thread.png
vendored
Normal file
After Width: | Height: | Size: 432 B |
BIN
Riot/Assets/Images.xcassets/Room/ContextMenu/room_context_menu_thread.imageset/Thread@2x.png
vendored
Normal file
After Width: | Height: | Size: 680 B |
BIN
Riot/Assets/Images.xcassets/Room/ContextMenu/room_context_menu_thread.imageset/Thread@3x.png
vendored
Normal file
After Width: | Height: | Size: 924 B |
6
Riot/Assets/Images.xcassets/Room/Threads/Contents.json
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
23
Riot/Assets/Images.xcassets/Room/Threads/threads_filter.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "filter_list_black_24dp 1.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "filter_list_black_24dp 1@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "filter_list_black_24dp 1@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
Riot/Assets/Images.xcassets/Room/Threads/threads_filter.imageset/filter_list_black_24dp 1.png
vendored
Normal file
After Width: | Height: | Size: 204 B |
BIN
Riot/Assets/Images.xcassets/Room/Threads/threads_filter.imageset/filter_list_black_24dp 1@2x.png
vendored
Normal file
After Width: | Height: | Size: 295 B |
BIN
Riot/Assets/Images.xcassets/Room/Threads/threads_filter.imageset/filter_list_black_24dp 1@3x.png
vendored
Normal file
After Width: | Height: | Size: 377 B |
12
Riot/Assets/Images.xcassets/Room/Threads/threads_filter_applied.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "filter-on.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
6
Riot/Assets/Images.xcassets/Room/Threads/threads_filter_applied.imageset/filter-on.svg
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M13 6H4C3.45 6 3 6.45 3 7C3 7.55 3.45 8 4 8H13.3414C13.1203 7.37444 13 6.70127 13 6Z" fill="#17191C"/>
|
||||
<path d="M15.6822 11C16.3676 11.4557 17.1521 11.7743 17.9965 11.9165C17.9988 11.944 18 11.9719 18 12C18 12.55 17.55 13 17 13H7C6.45 13 6 12.55 6 12C6 11.45 6.45 11 7 11H15.6822Z" fill="#17191C"/>
|
||||
<path d="M11 18H13C13.55 18 14 17.55 14 17C14 16.45 13.55 16 13 16H11C10.45 16 10 16.45 10 17C10 17.55 10.45 18 11 18Z" fill="#17191C"/>
|
||||
<path d="M19 9C20.6569 9 22 7.65685 22 6C22 4.34315 20.6569 3 19 3C17.3431 3 16 4.34315 16 6C16 7.65685 17.3431 9 19 9Z" fill="#17191C"/>
|
||||
</svg>
|
After Width: | Height: | Size: 686 B |
26
Riot/Assets/Images.xcassets/Room/Threads/threads_icon.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "Thread.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "Thread@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "Thread@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"template-rendering-intent" : "template"
|
||||
}
|
||||
}
|
BIN
Riot/Assets/Images.xcassets/Room/Threads/threads_icon.imageset/Thread.png
vendored
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
Riot/Assets/Images.xcassets/Room/Threads/threads_icon.imageset/Thread@2x.png
vendored
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Riot/Assets/Images.xcassets/Room/Threads/threads_icon.imageset/Thread@3x.png
vendored
Normal file
After Width: | Height: | Size: 1.7 KiB |
23
Riot/Assets/Images.xcassets/Room/file_attachment.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "file_attachment.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "file_attachment@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "file_attachment@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
Riot/Assets/Images.xcassets/Room/file_attachment.imageset/file_attachment.png
vendored
Normal file
After Width: | Height: | Size: 503 B |
BIN
Riot/Assets/Images.xcassets/Room/file_attachment.imageset/file_attachment@2x.png
vendored
Normal file
After Width: | Height: | Size: 870 B |
BIN
Riot/Assets/Images.xcassets/Room/file_attachment.imageset/file_attachment@3x.png
vendored
Normal file
After Width: | Height: | Size: 1.3 KiB |
26
Riot/Assets/Images.xcassets/Room/link_icon.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "Link.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "Link@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "Link@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"template-rendering-intent" : "template"
|
||||
}
|
||||
}
|
BIN
Riot/Assets/Images.xcassets/Room/link_icon.imageset/Link.png
vendored
Normal file
After Width: | Height: | Size: 609 B |
BIN
Riot/Assets/Images.xcassets/Room/link_icon.imageset/Link@2x.png
vendored
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Riot/Assets/Images.xcassets/Room/link_icon.imageset/Link@3x.png
vendored
Normal file
After Width: | Height: | Size: 1.6 KiB |
|
@ -1269,7 +1269,7 @@
|
|||
// Social login
|
||||
|
||||
"social_login_list_title_continue" = "Weiter mit";
|
||||
"room_intro_cell_information_multiple_dm_sentence2" = "Nur ihr seid in diesem Gespräch, außer ihr lädt jemanden ein.";
|
||||
"room_intro_cell_information_multiple_dm_sentence2" = "Nur ihr seid in diesem Gespräch, außer ihr ladet jemanden ein.";
|
||||
"room_intro_cell_information_dm_sentence2" = "Nur zwei von euch sind in diesem Gespräch. Keine anderer kann beitreten.";
|
||||
"room_intro_cell_information_dm_sentence1_part3" = ". ";
|
||||
"room_intro_cell_information_dm_sentence1_part1" = "Dies ist der Beginn deiner Direktnachricht mit ";
|
||||
|
@ -1596,3 +1596,10 @@
|
|||
// Onboarding
|
||||
"onboarding_splash_register_button_title" = "Konto erstellen";
|
||||
"settings_enable_room_message_bubbles" = "Nachrichtenblasen";
|
||||
"poll_edit_form_update_failure_subtitle" = "Bitte erneut versuchen";
|
||||
"poll_edit_form_poll_type" = "Umfragetyp";
|
||||
"poll_edit_form_poll_type_closed_description" = "Ergebnisse werden erst angezeigt, wenn du die Umfrage beendest";
|
||||
"poll_edit_form_poll_type_closed" = "Geschlossene Umfrage";
|
||||
"poll_edit_form_poll_type_open_description" = "Ergebnisse werden direkt nach Stimmabgabe angezeigt";
|
||||
"poll_edit_form_poll_type_open" = "Offene Umfrage";
|
||||
"poll_edit_form_update_failure_title" = "Aktualisierung der Umfrage fehlgeschlagen";
|
||||
|
|
|
@ -110,7 +110,7 @@
|
|||
"auth_optional_phone_placeholder" = "Phone number (optional)";
|
||||
"auth_phone_placeholder" = "Phone number";
|
||||
"auth_repeat_password_placeholder" = "Repeat password";
|
||||
"auth_repeat_new_password_placeholder" = "Confirm your new password";
|
||||
"auth_repeat_new_password_placeholder" = "Confirm your new Matrix account password";
|
||||
"auth_home_server_placeholder" = "URL (e.g. https://matrix.org)";
|
||||
"auth_identity_server_placeholder" = "URL (e.g. https://vector.im)";
|
||||
"auth_invalid_login_param" = "Incorrect username and/or password";
|
||||
|
@ -127,13 +127,13 @@
|
|||
"auth_missing_email_or_phone" = "Missing email address or phone number";
|
||||
"auth_email_in_use" = "This email address is already in use";
|
||||
"auth_phone_in_use" = "This phone number is already in use";
|
||||
"auth_email_is_required" = "No identity server is configured so you cannot add an email address in order to reset your password in the future.";
|
||||
"auth_phone_is_required" = "No identity server is configured so you cannot add a phone number in order to reset your password in the future.";
|
||||
"auth_email_is_required" = "No identity server is configured so you cannot add an email address in order to reset your Matrix account password in the future.";
|
||||
"auth_phone_is_required" = "No identity server is configured so you cannot add a phone number in order to reset your Matrix account password in the future.";
|
||||
"auth_untrusted_id_server" = "The identity server is not trusted";
|
||||
"auth_password_dont_match" = "Passwords don't match";
|
||||
"auth_username_in_use" = "Username in use";
|
||||
"auth_forgot_password" = "Forgot password?";
|
||||
"auth_forgot_password_error_no_configured_identity_server" = "No identity server is configured: add one to reset your password.";
|
||||
"auth_forgot_password" = "Forgot Matrix account password?";
|
||||
"auth_forgot_password_error_no_configured_identity_server" = "No identity server is configured: add one to reset your Matrix account password.";
|
||||
"auth_email_not_found" = "Failed to send email: This email address was not found";
|
||||
"auth_use_server_options" = "Use custom server options (advanced)";
|
||||
"auth_email_validation_message" = "Please check your email to continue registration";
|
||||
|
@ -141,15 +141,15 @@
|
|||
"auth_msisdn_validation_message" = "We\'ve sent an SMS with an activation code. Please enter this code below.";
|
||||
"auth_msisdn_validation_error" = "Unable to verify phone number.";
|
||||
"auth_recaptcha_message" = "This homeserver would like to make sure you are not a robot";
|
||||
"auth_reset_password_message" = "To reset your password, enter the email address linked to your account:";
|
||||
"auth_reset_password_message" = "To reset your Matrix account password, enter the email address linked to your account:";
|
||||
"auth_reset_password_missing_email" = "The email address linked to your account must be entered.";
|
||||
"auth_reset_password_missing_password" = "A new password must be entered.";
|
||||
"auth_reset_password_email_validation_message" = "An email has been sent to %@. Once you've followed the link it contains, click below.";
|
||||
"auth_reset_password_next_step_button" = "I have verified my email address";
|
||||
"auth_reset_password_error_unauthorized" = "Failed to verify email address: make sure you clicked the link in the email";
|
||||
"auth_reset_password_error_not_found" = "Your email address does not appear to be associated with a Matrix ID on this homeserver.";
|
||||
"auth_reset_password_error_is_required" = "No identity server is configured: add one in server options to reset your password.";
|
||||
"auth_reset_password_success_message" = "Your password has been reset.\n\nYou have been logged out of all sessions and will no longer receive push notifications. To re-enable notifications, re-log in on each device.";
|
||||
"auth_reset_password_error_is_required" = "No identity server is configured: add one in server options to reset your Matrix account password.";
|
||||
"auth_reset_password_success_message" = "Your Matrix account password has been reset.\n\nYou have been logged out of all sessions and will no longer receive push notifications. To re-enable notifications, re-log in on each device.";
|
||||
"auth_add_email_and_phone_warning" = "Registration with email and phone number at once is not supported yet until the api exists. Only the phone number will be taken into account. You may add your email to your profile in settings.";
|
||||
"auth_accept_policies" = "Please review and accept the policies of this homeserver:";
|
||||
"auth_autodiscover_invalid_response" = "Invalid homeserver discovery response";
|
||||
|
@ -338,7 +338,8 @@ Tap the + to start adding people.";
|
|||
"room_member_power_level_short_moderator" = "Mod";
|
||||
"room_member_power_level_short_custom" = "Custom";
|
||||
|
||||
// Chat
|
||||
// MARK: - Chat
|
||||
|
||||
"room_slide_to_end_group_call" = "Slide to end the call for everyone";
|
||||
"room_jump_to_first_unread" = "Jump to unread";
|
||||
"room_accessiblity_scroll_to_bottom" = "Scroll to bottom";
|
||||
|
@ -378,7 +379,8 @@ Tap the + to start adding people.";
|
|||
"room_event_action_more" = "More";
|
||||
"room_event_action_share" = "Share";
|
||||
"room_event_action_forward" = "Forward";
|
||||
"room_event_action_permalink" = "Permalink";
|
||||
"room_event_action_view_in_room" = "View in room";
|
||||
"room_event_action_permalink" = "Copy link to message";
|
||||
"room_event_action_view_source" = "View Source";
|
||||
"room_event_action_view_decrypted_source" = "View Decrypted Source";
|
||||
"room_event_action_report" = "Report content";
|
||||
|
@ -395,10 +397,12 @@ Tap the + to start adding people.";
|
|||
"room_event_action_cancel_download" = "Cancel Download";
|
||||
"room_event_action_view_encryption" = "Encryption Information";
|
||||
"room_event_action_reply" = "Reply";
|
||||
"room_event_action_reply_in_thread" = "Thread";
|
||||
"room_event_action_edit" = "Edit";
|
||||
"room_event_action_reaction_show_all" = "Show all";
|
||||
"room_event_action_reaction_show_less" = "Show less";
|
||||
"room_event_action_reaction_history" = "Reaction history";
|
||||
"room_event_copy_link_info" = "Link copied to clipboard.";
|
||||
"room_warning_about_encryption" = "End-to-end encryption is in beta and may not be reliable.\n\nYou should not yet trust it to secure data.\n\nDevices will not yet be able to decrypt history from before they joined the room.\n\nEncrypted messages will not be visible on clients that do not yet implement encryption.";
|
||||
"room_event_failed_to_send" = "Failed to send";
|
||||
"room_action_camera" = "Take photo or video";
|
||||
|
@ -423,12 +427,27 @@ Tap the + to start adding people.";
|
|||
"room_accessibility_upload" = "Upload";
|
||||
"room_accessibility_call" = "Call";
|
||||
"room_accessibility_video_call" = "Video Call";
|
||||
"room_accessibility_threads" = "Threads";
|
||||
"room_accessibility_hangup" = "Hang up";
|
||||
"room_accessibility_thread_more" = "More";
|
||||
"room_place_voice_call" = "Voice call";
|
||||
"room_open_dialpad" = "Dial pad";
|
||||
"room_join_group_call" = "Join";
|
||||
"room_no_privileges_to_create_group_call" = "You need to be an admin or a moderator to start a call.";
|
||||
|
||||
// MARK: Threads
|
||||
"room_thread_title" = "Thread";
|
||||
"thread_copy_link_to_thread" = "Copy link to thread";
|
||||
"threads_title" = "Threads";
|
||||
"threads_action_all_threads" = "All threads";
|
||||
"threads_action_my_threads" = "My threads";
|
||||
"threads_empty_title" = "Keep discussions organised with threads";
|
||||
"threads_empty_info_all" = "Threads help keep your conversations on-topic and easy to track.";
|
||||
"threads_empty_info_my" = "Reply to an ongoing thread or tap a message and use “Thread” to start a new one.";
|
||||
"threads_empty_tip" = "Tip: Tap a message and use “Thread” to start one.";
|
||||
"threads_empty_show_all_threads" = "Show all threads";
|
||||
"message_from_a_thread" = "From a thread";
|
||||
|
||||
"media_type_accessibility_image" = "Image";
|
||||
"media_type_accessibility_audio" = "Audio";
|
||||
"media_type_accessibility_video" = "Video";
|
||||
|
@ -512,7 +531,7 @@ Tap the + to start adding people.";
|
|||
"settings_add_email_address" = "Add email address";
|
||||
"settings_phone_number" = "Phone";
|
||||
"settings_add_phone_number" = "Add phone number";
|
||||
"settings_change_password" = "Change password";
|
||||
"settings_change_password" = "Change Matrix account password";
|
||||
"settings_night_mode" = "Night Mode";
|
||||
"settings_fail_to_update_profile" = "Fail to update profile";
|
||||
"settings_three_pids_management_information_part1" = "Manage which email addresses or phone numbers you can use to log in or recover your account here. Control who can find you in ";
|
||||
|
@ -585,6 +604,7 @@ Tap the + to start adding people.";
|
|||
"settings_labs_message_reaction" = "React to messages with emoji";
|
||||
"settings_labs_enable_ringing_for_group_calls" = "Ring for group calls";
|
||||
"settings_labs_enabled_polls" = "Polls";
|
||||
"settings_labs_enable_threads" = "Threaded messaging";
|
||||
|
||||
"settings_version" = "Version %@";
|
||||
"settings_olm_version" = "Olm Version %@";
|
||||
|
@ -596,16 +616,16 @@ Tap the + to start adding people.";
|
|||
"settings_enable_rageshake" = "Rage shake to report bug";
|
||||
"settings_clear_cache" = "Clear cache";
|
||||
|
||||
"settings_change_password" = "Change password";
|
||||
"settings_change_password" = "Change Matrix account password";
|
||||
"settings_old_password" = "old password";
|
||||
"settings_new_password" = "new password";
|
||||
"settings_confirm_password" = "confirm password";
|
||||
"settings_fail_to_update_password" = "Fail to update password";
|
||||
"settings_password_updated" = "Your password has been updated";
|
||||
"settings_fail_to_update_password" = "Fail to update Matrix account password";
|
||||
"settings_password_updated" = "Your Matrix account password has been updated";
|
||||
|
||||
"settings_add_3pid_password_title_email" = "Add email address";
|
||||
"settings_add_3pid_password_title_msidsn" = "Add phone number";
|
||||
"settings_add_3pid_password_message" = "To continue, please enter your password";
|
||||
"settings_add_3pid_password_message" = "To continue, please enter your Matrix account password";
|
||||
"settings_add_3pid_invalid_password_message" = "Invalid credentials";
|
||||
|
||||
"settings_crypto_device_name" = "Session name: ";
|
||||
|
@ -673,7 +693,7 @@ Tap the + to start adding people.";
|
|||
"security_settings_title" = "Security";
|
||||
"security_settings_crypto_sessions" = "MY SESSIONS";
|
||||
"security_settings_crypto_sessions_loading" = "Loading sessions…";
|
||||
"security_settings_crypto_sessions_description_2" = "If you don’t recognise a login, change your password and reset Secure Backup.";
|
||||
"security_settings_crypto_sessions_description_2" = "If you don’t recognise a login, change your Matrix account password and reset Secure Backup.";
|
||||
|
||||
"security_settings_secure_backup" = "SECURE BACKUP";
|
||||
"security_settings_secure_backup_description" = "Back up your encryption keys with your account data in case you lose access to your sessions. Your keys will be secured with a unique Security Key.";
|
||||
|
@ -706,7 +726,7 @@ Tap the + to start adding people.";
|
|||
"security_settings_complete_security_alert_message" = "You should complete security on your current session first.";
|
||||
|
||||
"security_settings_coming_soon" = "Sorry. This action is not available on %@ iOS yet. Please use another Matrix client to set it up. %@ iOS will use it.";
|
||||
"security_settings_user_password_description" = "Confirm your identity by entering your account password";
|
||||
"security_settings_user_password_description" = "Confirm your identity by entering your Matrix account password";
|
||||
|
||||
// Manage session
|
||||
"manage_session_title" = "Manage session";
|
||||
|
@ -919,6 +939,7 @@ Tap the + to start adding people.";
|
|||
"event_formatter_group_call_join" = "Join";
|
||||
"event_formatter_group_call_leave" = "Leave";
|
||||
"event_formatter_group_call_incoming" = "%@ in %@";
|
||||
"event_formatter_message_deleted" = "Message deleted";
|
||||
|
||||
// Events formatter with you
|
||||
"event_formatter_widget_added_by_you" = "You added the widget: %@";
|
||||
|
@ -1103,7 +1124,7 @@ Tap the + to start adding people.";
|
|||
"deactivate_account_validate_action" = "Deactivate account";
|
||||
|
||||
"deactivate_account_password_alert_title" = "Deactivate Account";
|
||||
"deactivate_account_password_alert_message" = "To continue, please enter your password";
|
||||
"deactivate_account_password_alert_message" = "To continue, please enter your Matrix account password";
|
||||
|
||||
// Re-request confirmation dialog
|
||||
"rerequest_keys_alert_title" = "Request Sent";
|
||||
|
@ -1159,7 +1180,7 @@ Tap the + to start adding people.";
|
|||
// Passphrase
|
||||
|
||||
"key_backup_setup_passphrase_title" = "Secure your backup with a Security Phrase";
|
||||
"key_backup_setup_passphrase_info" = "We'll store an encrypted copy of your keys on our server. Protect your backup with a phrase to keep it secure.\n\nFor maximum security, this should be different from your account password.";
|
||||
"key_backup_setup_passphrase_info" = "We'll store an encrypted copy of your keys on our server. Protect your backup with a phrase to keep it secure.\n\nFor maximum security, this should be different from your Matrix account password.";
|
||||
"key_backup_setup_passphrase_passphrase_title" = "Enter";
|
||||
"key_backup_setup_passphrase_passphrase_placeholder" = "Enter phrase";
|
||||
"key_backup_setup_passphrase_passphrase_valid" = "Great!";
|
||||
|
@ -1578,7 +1599,7 @@ Tap the + to start adding people.";
|
|||
|
||||
"secrets_setup_recovery_passphrase_title" = "Set a Security Phrase";
|
||||
"secrets_setup_recovery_passphrase_information" = "Enter a security phrase only you know, used to secure secrets on your server.";
|
||||
"secrets_setup_recovery_passphrase_additional_information" = "Don't use your account password.";
|
||||
"secrets_setup_recovery_passphrase_additional_information" = "Don't use your Matrix account password.";
|
||||
"secrets_setup_recovery_passphrase_validate_action" = "Done";
|
||||
|
||||
"secrets_setup_recovery_passphrase_confirm_information" = "Enter your Security Phrase again to confirm it.";
|
||||
|
@ -1598,7 +1619,7 @@ Tap the + to start adding people.";
|
|||
"secrets_reset_warning_title" = "If you reset everything";
|
||||
"secrets_reset_warning_message" = "You will restart with no history, no messages, trusted devices or trusted users.";
|
||||
"secrets_reset_reset_action" = "Reset";
|
||||
"secrets_reset_authentication_message" = "Enter your account password to confirm";
|
||||
"secrets_reset_authentication_message" = "Enter your Matrix account password to confirm";
|
||||
|
||||
// MARK: - Cross-signing
|
||||
|
||||
|
@ -1704,6 +1725,16 @@ Tap the + to start adding people.";
|
|||
|
||||
"home_empty_view_title" = "Welcome to %@,\n%@";
|
||||
"home_empty_view_information" = "The all-in-one secure chat app for teams, friends and organisations. Tap the + button below to add people and rooms.";
|
||||
"home_context_menu_make_dm" = "Move to People";
|
||||
"home_context_menu_make_room" = "Move to Rooms";
|
||||
"home_context_menu_notifications" = "Notifications";
|
||||
"home_context_menu_mute" = "Mute";
|
||||
"home_context_menu_unmute" = "Unmute";
|
||||
"home_context_menu_favourite" = "Favourite";
|
||||
"home_context_menu_unfavourite" = "Remove from Favourites";
|
||||
"home_context_menu_low_priority" = "Low priority";
|
||||
"home_context_menu_normal_priority" = "Normal priority";
|
||||
"home_context_menu_leave" = "Leave";
|
||||
|
||||
// MARK: - Favourites
|
||||
|
||||
|
@ -1884,6 +1915,10 @@ Tap the + to start adding people.";
|
|||
|
||||
"location_sharing_share_action" = "Share";
|
||||
|
||||
"location_sharing_post_failure_title" = "We couldn’t send your location";
|
||||
|
||||
"location_sharing_post_failure_subtitle" = "%@ could not send your location. Please try again later.";
|
||||
|
||||
"location_sharing_loading_map_error_title" = "%@ could not load the map. Please try again later.";
|
||||
|
||||
"location_sharing_locating_user_error_title" = "%@ could not access your location. Please try again later.";
|
||||
|
|
|
@ -1148,7 +1148,7 @@
|
|||
"create_room_title" = "Uus jututuba";
|
||||
"create_room_section_header_name" = "Jututoa nimi";
|
||||
"create_room_placeholder_name" = "Nimi";
|
||||
"create_room_section_header_topic" = "Jututoa teema (valikuline)";
|
||||
"create_room_section_header_topic" = "Jututoa teema (kui soovid lisada)";
|
||||
"create_room_placeholder_topic" = "Jututoa teema";
|
||||
"create_room_section_header_encryption" = "Krüptimine jututoas";
|
||||
"create_room_enable_encryption" = "Võta krüptimine kasutusele";
|
||||
|
@ -1431,7 +1431,7 @@
|
|||
"spaces_empty_space_title" = "Selles kogukonnakeskuses pole veel jututube";
|
||||
"space_tag" = "kogukonnakeskus";
|
||||
"spaces_suggested_room" = "Soovitatud";
|
||||
"spaces_explore_rooms" = "Uuri jututubasid";
|
||||
"spaces_explore_rooms" = "Tutvu jututubadega";
|
||||
"leave_space_and_all_rooms_action" = "Lahku kõikidest jututubadest ja kogukondadest";
|
||||
"leave_space_only_action" = "Ära lahku ühestki jututoast";
|
||||
"leave_space_message_admin_warning" = "Sa oled selle kogukonnakeskuse haldaja. Enne oma lahkumist palun lisa siia veel vähemalt üks uus haldaja.";
|
||||
|
@ -1556,3 +1556,10 @@
|
|||
|
||||
// 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_open_description" = "Osalejad näevad tulemusi peale oma valiku salvestamist";
|
||||
"poll_edit_form_poll_type_open" = "Ava 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";
|
||||
|
|
|
@ -1356,7 +1356,7 @@
|
|||
"less" = "Moins";
|
||||
"more" = "Plus";
|
||||
"switch" = "Basculer";
|
||||
"joined" = "Rejoint";
|
||||
"joined" = "A rejoint";
|
||||
"store_promotional_text" = "Application de messagerie et collaboration respectueuse de la vie privée, sur un réseau ouvert. Décentralisée pour vous donner le contrôle. Pas d’extraction de vos données, pas de porte dérobée, pas d’accès réservé à des tiers.";
|
||||
"room_details_search" = "Rechercher dans le salon";
|
||||
"room_details_integrations" = "Intégrations";
|
||||
|
@ -1633,3 +1633,10 @@
|
|||
// Onboarding
|
||||
"onboarding_splash_register_button_title" = "Créer un compte";
|
||||
"ok" = "Ok";
|
||||
"poll_edit_form_poll_type_closed_description" = "Les résultats ne sont dévoilés que lorsque vous terminez le sondage";
|
||||
"poll_edit_form_poll_type_closed" = "Sondage fermé";
|
||||
"poll_edit_form_poll_type_open_description" = "Les votants voient les résultats dès qu'ils ont voté";
|
||||
"poll_edit_form_poll_type_open" = "Ouvrir le sondage";
|
||||
"poll_edit_form_update_failure_subtitle" = "Veuillez réessayer";
|
||||
"poll_edit_form_update_failure_title" = "Échec lors de la mise à jour du sondage";
|
||||
"poll_edit_form_poll_type" = "Type de sondage";
|
||||
|
|
|
@ -1619,3 +1619,10 @@
|
|||
|
||||
// Onboarding
|
||||
"onboarding_splash_register_button_title" = "Fiók létrehozása";
|
||||
"poll_edit_form_poll_type_closed_description" = "Az eredmény csak a szavazás végeztével válik láthatóvá";
|
||||
"poll_edit_form_poll_type_closed" = "Lezárt szavazás";
|
||||
"poll_edit_form_poll_type_open_description" = "A szavazók a szavazásuk után látják a szavazatokat";
|
||||
"poll_edit_form_poll_type_open" = "Szavazás megnyitása";
|
||||
"poll_edit_form_update_failure_subtitle" = "Kérlek próbáld újra";
|
||||
"poll_edit_form_update_failure_title" = "A szavazást nem sikerült frissíteni";
|
||||
"poll_edit_form_poll_type" = "Szavazás típusa";
|
||||
|
|
|
@ -1735,3 +1735,10 @@
|
|||
|
||||
// Onboarding
|
||||
"onboarding_splash_register_button_title" = "Buat akun";
|
||||
"poll_edit_form_poll_type_closed_description" = "Hasil akan ditampilkan ketika Anda mengakhiri poll-nya";
|
||||
"poll_edit_form_poll_type_closed" = "Poll tertutup";
|
||||
"poll_edit_form_poll_type_open_description" = "Pemberi suara akan melihat hasilnya ketika telah memberikan suara";
|
||||
"poll_edit_form_poll_type_open" = "Buka poll";
|
||||
"poll_edit_form_update_failure_subtitle" = "Silakan coba lagi";
|
||||
"poll_edit_form_update_failure_title" = "Gagal untuk memperbarui poll";
|
||||
"poll_edit_form_poll_type" = "Tipe poll";
|
||||
|
|
|
@ -1590,3 +1590,10 @@
|
|||
|
||||
// Onboarding
|
||||
"onboarding_splash_register_button_title" = "Crea account";
|
||||
"poll_edit_form_poll_type_closed_description" = "I risultati verranno rivelati solo quando termini il sondaggio";
|
||||
"poll_edit_form_poll_type_closed" = "Sondaggio chiuso";
|
||||
"poll_edit_form_poll_type_open_description" = "I votanti vedono i risultati appena avranno votato";
|
||||
"poll_edit_form_poll_type_open" = "Apri sondaggio";
|
||||
"poll_edit_form_update_failure_subtitle" = "Riprova";
|
||||
"poll_edit_form_update_failure_title" = "Aggiornamento del sondaggio fallito";
|
||||
"poll_edit_form_poll_type" = "Tipo sondaggio";
|
||||
|
|
|
@ -1719,3 +1719,10 @@
|
|||
|
||||
// Onboarding
|
||||
"onboarding_splash_register_button_title" = "Account aanmaken";
|
||||
"poll_edit_form_poll_type_closed_description" = "Resultaten worden pas onthuld als u de poll beëindigt";
|
||||
"poll_edit_form_poll_type_closed" = "Gesloten poll";
|
||||
"poll_edit_form_poll_type_open_description" = "Kiezers zien resultaten zodra ze hebben gestemd";
|
||||
"poll_edit_form_poll_type_open" = "Poll openen";
|
||||
"poll_edit_form_update_failure_subtitle" = "Probeer het opnieuw";
|
||||
"poll_edit_form_update_failure_title" = "Kan poll niet bijwerken";
|
||||
"poll_edit_form_poll_type" = "Poll type";
|
||||
|
|
|
@ -845,7 +845,7 @@
|
|||
"room_accessibility_upload" = "Fazer upload";
|
||||
"room_accessibility_hangup" = "Desligar";
|
||||
"media_type_accessibility_image" = "Imagem";
|
||||
"media_type_accessibility_location" = "Local";
|
||||
"media_type_accessibility_location" = "Localização";
|
||||
"external_link_confirmation_title" = "Cheque duplamente este link";
|
||||
"external_link_confirmation_message" = "O link %@ vai levar você para um outro site: %@↵\n↵\nVocê tem certeza que você quer continuar?";
|
||||
"settings_discovery_settings" = "DESCOBERTA";
|
||||
|
@ -1558,14 +1558,14 @@
|
|||
"settings_analytics_and_crash_data" = "Enviar dados de crash e analítica";
|
||||
"accessibility_button_label" = "botão";
|
||||
"enable" = "Habilitar";
|
||||
"location_sharing_settings_toggle_title" = "Habilitar compartilhamento de local";
|
||||
"location_sharing_settings_header" = "Compartilhamento de local";
|
||||
"location_sharing_invalid_authorization_error_title" = "%@ não tem permissão para acessar seu local. Você pode habilitar acesso em Ajustes > Local";
|
||||
"location_sharing_locating_user_error_title" = "%@ não pôde acessar seu local. Por favor tente de novo mais tarde.";
|
||||
"location_sharing_settings_toggle_title" = "Habilitar compartilhamento de localização";
|
||||
"location_sharing_settings_header" = "Compartilhamento de localização";
|
||||
"location_sharing_invalid_authorization_error_title" = "%@ não tem permissão para acessar sua localização. Você pode habilitar acesso em Ajustes > Localização";
|
||||
"location_sharing_locating_user_error_title" = "%@ não pôde acessar sua localização. Por favor tente de novo mais tarde.";
|
||||
|
||||
// MARK: - Location sharing
|
||||
|
||||
"location_sharing_title" = "Local";
|
||||
"location_sharing_title" = "Localização";
|
||||
"location_sharing_open_google_maps" = "Abrir em Google Maps";
|
||||
"location_sharing_open_apple_maps" = "Abrir em Apple Mapas";
|
||||
"location_sharing_invalid_authorization_settings" = "Ajustes";
|
||||
|
@ -1576,7 +1576,7 @@
|
|||
"ok" = "OK";
|
||||
"onboarding_splash_page_1_message" = "Comunicação segura e independente que lhe dá o mesmo nível de privacidade que uma conversa face-a-face em sua própria casa.";
|
||||
"settings_enable_room_message_bubbles" = "Bolhas de mensagem";
|
||||
"onboarding_splash_page_4_message" = "Elemente também é ótimo para o lugar de trabalho. É confiado pelas organizações mais seguras do mundo.";
|
||||
"onboarding_splash_page_4_message" = "Element também é ótimo para o lugar de trabalho. É confiado pelas organizações mais seguras do mundo.";
|
||||
"onboarding_splash_page_4_title_no_pun" = "Mensageria para seu time.";
|
||||
"onboarding_splash_page_3_message" = "Encriptado ponta-a-ponta e nenhum número de telefone requerido. Sem publicidade ou datamining.";
|
||||
"onboarding_splash_page_3_title" = "Mensageria segura.";
|
||||
|
@ -1587,3 +1587,10 @@
|
|||
|
||||
// Onboarding
|
||||
"onboarding_splash_register_button_title" = "Criar conta";
|
||||
"poll_edit_form_poll_type_closed_description" = "Resultados são somente revelados quando você termina a sondagem";
|
||||
"poll_edit_form_poll_type_open" = "Sondagem aberta";
|
||||
"poll_edit_form_poll_type_closed" = "Sondagem fechada";
|
||||
"poll_edit_form_poll_type_open_description" = "Votantes veem resultados assim que elas(es) têm votado";
|
||||
"poll_edit_form_update_failure_subtitle" = "Por favor tente de novo";
|
||||
"poll_edit_form_update_failure_title" = "Falha para atualizar sondagem";
|
||||
"poll_edit_form_poll_type" = "Tipo de sondagem";
|
||||
|
|
|
@ -5,3 +5,4 @@
|
|||
"NSContactsUsageDescription" = "Element покажет ваши контакты, чтобы вы могли пригласить их в чат.";
|
||||
"NSCalendarsUsageDescription" = "Просматривайте запланированные встречи в приложении.";
|
||||
"NSFaceIDUsageDescription" = "Face ID используется для доступа к вашему приложению.";
|
||||
"NSLocationWhenInUseUsageDescription" = "Когда вы делитесь с людьми своим местоположением, Element необходим доступ, чтобы показать им карту.";
|
||||
|
|
|
@ -116,3 +116,6 @@
|
|||
/** General **/
|
||||
|
||||
"NOTIFICATION" = "Уведомление";
|
||||
|
||||
/* New file message from a specific person, not referencing a room. */
|
||||
"LOCATION_FROM_USER" = "%@ поделились своим местоположением";
|
||||
|
|
|
@ -1341,7 +1341,7 @@
|
|||
"side_menu_app_version" = "Версия %@";
|
||||
"side_menu_action_feedback" = "Отзыв";
|
||||
"side_menu_action_help" = "Помощь";
|
||||
"side_menu_action_settings" = "Настойки";
|
||||
"side_menu_action_settings" = "Настройки";
|
||||
"side_menu_action_invite_friends" = "Пригласить друзей";
|
||||
|
||||
// Mark: - Side menu
|
||||
|
|
|
@ -1388,7 +1388,7 @@
|
|||
|
||||
// Unverified sessions
|
||||
|
||||
"key_verification_self_verify_unverified_sessions_alert_title" = "Zobraziť, kde ste prihlásený";
|
||||
"key_verification_self_verify_unverified_sessions_alert_title" = "Skontrolujte, kde ste prihlásení";
|
||||
"key_verification_self_verify_current_session_alert_message" = "Ostatní používatelia jej nemusia dôverovať.";
|
||||
|
||||
// Current session
|
||||
|
@ -1664,3 +1664,48 @@
|
|||
"onboarding_splash_page_4_title_no_pun" = "Zasielanie správ pre váš tím.";
|
||||
"onboarding_splash_page_4_message" = "Element je skvelý aj na pracovisku. Dôverujú mu najbezpečnejšie organizácie na svete.";
|
||||
"settings_enable_room_message_bubbles" = "Správy v bublinách";
|
||||
"share_extension_failed_to_encrypt" = "Nepodarilo sa odoslať. Skontrolujte v hlavnej aplikácii nastavenia šifrovania pre túto miestnosť";
|
||||
"service_terms_modal_policy_checkbox_accessibility_hint" = "Označte, či chcete prijať %@";
|
||||
|
||||
// Intro
|
||||
|
||||
"key_backup_setup_intro_title" = "Nikdy neprídete o šifrované správy";
|
||||
"key_backup_setup_passphrase_setup_recovery_key_info" = "Alebo zabezpečte zálohu bezpečnostným kľúčom a uložte ju na bezpečné miesto.";
|
||||
"key_verification_user_title" = "Overte ich";
|
||||
"poll_edit_form_poll_question_or_topic" = "Otázka alebo téma ankety";
|
||||
"poll_timeline_total_no_votes" = "Žiadne odovzdané hlasy";
|
||||
"poll_timeline_total_one_vote_not_voted" = "1 odovzdaný hlas. Hlasujte a pozrite si výsledky";
|
||||
"poll_timeline_total_final_results_one_vote" = "Konečný výsledok na základe 1 hlasu";
|
||||
"poll_timeline_total_final_results" = "Konečný výsledok na základe %lu hlasov";
|
||||
"poll_edit_form_poll_type" = "Typ ankety";
|
||||
"poll_edit_form_update_failure_title" = "Nepodarilo sa aktualizovať anketu";
|
||||
"poll_edit_form_update_failure_subtitle" = "Prosím, skúste to znova";
|
||||
"poll_edit_form_poll_type_open" = "Otvoriť anketu";
|
||||
"poll_edit_form_poll_type_open_description" = "Hlasujúci uvidia výsledky hneď po hlasovaní";
|
||||
"poll_edit_form_poll_type_closed_description" = "Výsledky sa zobrazia až po ukončení ankety";
|
||||
"poll_timeline_total_votes_not_voted" = "%lu odovzdaných hlasov. Hlasujte a pozrite si výsledky";
|
||||
"poll_timeline_total_votes" = "%lu odovzdaných hlasov";
|
||||
"poll_timeline_total_one_vote" = "1 odovzdaný hlas";
|
||||
"poll_edit_form_poll_type_closed" = "Uzavretá anketa";
|
||||
"poll_edit_form_post_failure_title" = "Nepodarilo sa odoslať anketu";
|
||||
"call_transfer_error_message" = "Prenos hovoru zlyhal";
|
||||
"user_verification_session_details_information_untrusted_other_user" = " sa prihlásil pomocou novej relácie:";
|
||||
"key_verification_bootstrap_not_setup_message" = "Najprv musíte zaviesť krížové podpisovanie.";
|
||||
"device_verification_emoji_pin" = "Špendlík";
|
||||
"device_verification_emoji_folder" = "Fascikel";
|
||||
"secure_key_backup_setup_existing_backup_error_info" = "Odomknite to a znovu to použite v zabezpečenej zálohe alebo to vymažte a vytvorte novú zálohu správ v zabezpečenej zálohe.";
|
||||
|
||||
// Share extension
|
||||
"share_extension_auth_prompt" = "Prihláste sa v hlavnej aplikácii na zdieľanie obsahu";
|
||||
|
||||
// Widget Integration Manager
|
||||
"widget_integration_need_to_be_able_to_invite" = "Musíte mať možnosť pozvať používateľov, aby ste to mohli urobiť.";
|
||||
"bug_report_logs_description" = "Za účelom diagnostiky problémov budú spolu s týmto hlásením o chybe odoslané protokoly z tohto klienta. Ak chcete radšej posielať len vyššie uvedený text, zrušte prosím označené:";
|
||||
"call_no_stun_server_error_message_1" = "Požiadajte prosím správcu vášho domovského servera %@ o nastavenie servera TURN, aby hovory fungovali spoľahlivo.";
|
||||
"call_no_stun_server_error_title" = "Hovor zlyhal z dôvodu nesprávne nastaveného servera";
|
||||
"room_details_addresses_disable_main_address_prompt_title" = "Upozornenie na hlavnú adresu";
|
||||
"manage_session_trusted" = "Dôveryhodný pre vás";
|
||||
"settings_contacts_phonebook_country" = "Krajina telefónneho zoznamu";
|
||||
"settings_ui_theme_picker_message_invert_colours" = "\"Auto\" používa nastavenia \"Invertovať farby\" vášho zariadenia";
|
||||
"external_link_confirmation_title" = "Prekontrolujte tento odkaz";
|
||||
"callbar_only_single_active_group" = "Ťuknutím sa pripojíte k skupinovému hovoru (%@)";
|
||||
|
|
|
@ -1608,3 +1608,10 @@
|
|||
|
||||
// Onboarding
|
||||
"onboarding_splash_register_button_title" = "Krijoni llogari";
|
||||
"poll_edit_form_poll_type_open" = "Anketim i hapur";
|
||||
"poll_edit_form_poll_type_closed_description" = "Përfundimet shfaqen vetëm kur përfundoni anketimin";
|
||||
"poll_edit_form_poll_type_closed" = "Anketim i mbyllur";
|
||||
"poll_edit_form_poll_type_open_description" = "Votuesit do të shohin përfundime sapo të kenë votuar";
|
||||
"poll_edit_form_update_failure_subtitle" = "Ju lutemi, riprovoni";
|
||||
"poll_edit_form_update_failure_title" = "S’u arrit të përditësohet anketimi";
|
||||
"poll_edit_form_poll_type" = "Lloj anketimi";
|
||||
|
|
|
@ -276,7 +276,7 @@
|
|||
"settings_ignored_users" = "IGNORERADE ANVÄNDARE";
|
||||
"settings_contacts" = "ENHETSKONTAKTER";
|
||||
"settings_advanced" = "AVANCERAT";
|
||||
"settings_other" = "ANNAT";
|
||||
"settings_other" = "Annat";
|
||||
"settings_labs" = "EXPERIMENT";
|
||||
"settings_devices" = "SESSIONER";
|
||||
"settings_cryptography" = "KRYPTOGRAFI";
|
||||
|
@ -430,7 +430,7 @@
|
|||
"room_participants_action_mention" = "Nämn";
|
||||
"room_participants_security_information_room_encrypted" = "Meddelanden i det här rummet är totalsträckskrypterade.\n\nDina meddelanden är säkrade med lås och bara du och mottagaren har de unika nycklarna för att låsa upp dem.";
|
||||
"room_accessiblity_scroll_to_bottom" = "Scrolla till botten";
|
||||
"room_do_not_have_permission_to_post" = "Du har inte behörighet att posta till det här rummet";
|
||||
"room_do_not_have_permission_to_post" = "Du är inte behörig att posta till det här rummet";
|
||||
"room_unsent_messages_notification" = "Meddelanden misslyckades att skickas.";
|
||||
"room_conference_call_no_power" = "Du behöver behörighet för att hantera gruppsamtal i det här rummet";
|
||||
"room_prompt_resend" = "Skicka alla igen";
|
||||
|
@ -704,7 +704,7 @@
|
|||
"event_formatter_jitsi_widget_removed_by_you" = "Du tog bort VoIP-konferens";
|
||||
"public_room_section_title" = "Offentliga rum (på %@):";
|
||||
"bug_report_prompt" = "Appen har kraschat förra gången. Vill du skicka en kraschrapport?";
|
||||
"camera_access_not_granted" = "%@ verkar inte ha behörighet att använda kameran, vänligen ändra integritetsinställningarna";
|
||||
"camera_access_not_granted" = "%@ verkar inte vara behörig att använda kameran, vänligen ändra integritetsinställningarna";
|
||||
"photo_library_access_not_granted" = "%@ verkar inte ha åtkomst till bildbiblioteket, vänligen ändra integritetsinställningarna";
|
||||
"large_badge_value_k_format" = "%.1fK";
|
||||
"call_incoming_voice" = "Inkommande samtal…";
|
||||
|
@ -838,7 +838,7 @@
|
|||
// Widget Integration Manager
|
||||
"widget_integration_need_to_be_able_to_invite" = "Du behöver kunna bjuda in användare för att göra det där.";
|
||||
"widget_integration_positive_power_level" = "Behörighetsnivå måste vara ett positivt heltal.";
|
||||
"widget_integration_no_permission_in_room" = "Du har inte behörighet att göra det där i det här rummet.";
|
||||
"widget_integration_no_permission_in_room" = "Du är inte behörig att göra det där i det här rummet.";
|
||||
"widget_integration_manager_disabled" = "Du behöver aktivera integrationshanteraren i inställningarna";
|
||||
"room_widget_permission_webview_information_title" = "Att använda den kan sätta kakor och dela data med %@:\n";
|
||||
"room_widget_permission_information_title" = "Att använda den kan dela data med %@:\n";
|
||||
|
@ -1452,7 +1452,7 @@
|
|||
"space_home_show_all_rooms" = "Visa alla rum";
|
||||
"space_participants_action_ban" = "Banna från det här utrymmet";
|
||||
"space_participants_action_remove" = "Ta bort från det här utrymmet";
|
||||
"spaces_coming_soon_detail" = "Den här funktionen har inte bjudits in än, men den är på väg. För tillfället så kan du göra det med Element på din dator.";
|
||||
"spaces_coming_soon_detail" = "Den här funktionen har inte implementerats än, men den är på väg. För tillfället så kan du göra det med %@ på din dator.";
|
||||
"spaces_invites_coming_soon_title" = "Inbjudningar kommer snart";
|
||||
"spaces_add_rooms_coming_soon_title" = "Tilläggning av rum kommer snart";
|
||||
"spaces_coming_soon_title" = "Kommer snart";
|
||||
|
|
|
@ -1925,6 +1925,31 @@ Library.
|
|||
SOFTWARE.
|
||||
<br/><br/>
|
||||
</li>
|
||||
<li>
|
||||
<b>UICollectionViewRightAlignedLayout</b> (<a href="https://github.com/mokagio/UICollectionViewRightAlignedLayout">https://github.com/mokagio/UICollectionViewRightAlignedLayout</a>)
|
||||
<br/><br/>
|
||||
The MIT License (MIT)
|
||||
<br/><br/>
|
||||
Copyright (c) 2014 Giovanni Lodi
|
||||
<br/><br/>
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
<br/><br/>
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
<br/><br/>
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
<br/><br/>
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1731,3 +1731,10 @@
|
|||
|
||||
// Onboarding
|
||||
"onboarding_splash_register_button_title" = "Створити обліковий запис";
|
||||
"poll_edit_form_poll_type_open_description" = "Усі, хто проголосує, побачать результати одразу після голосування";
|
||||
"poll_edit_form_poll_type_closed_description" = "Результати можна переглянути лише після завершення опитування";
|
||||
"poll_edit_form_poll_type_closed" = "Закрите опитування";
|
||||
"poll_edit_form_poll_type_open" = "Відкрити опитування";
|
||||
"poll_edit_form_update_failure_subtitle" = "Повторіть спробу";
|
||||
"poll_edit_form_update_failure_title" = "Не вдалося оновити опитування";
|
||||
"poll_edit_form_poll_type" = "Тип опитування";
|
||||
|
|
29
Riot/Categories/MXEvent.swift
Normal file
|
@ -0,0 +1,29 @@
|
|||
//
|
||||
// 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 MatrixSDK
|
||||
|
||||
extension MXEvent {
|
||||
|
||||
/// Get MXMessageType if any
|
||||
var messageType: MXMessageType? {
|
||||
guard let messageTypeString = self.content["msgtype"] as? String else {
|
||||
return nil
|
||||
}
|
||||
return MXMessageType(identifier: messageTypeString)
|
||||
}
|
||||
}
|
|
@ -18,16 +18,13 @@ import Foundation
|
|||
|
||||
extension MXKRoomBubbleCellData {
|
||||
|
||||
/// Indicate true if the sender is the session user
|
||||
var isSenderCurrentUser: Bool {
|
||||
if let senderId = self.senderId, let currentUserId = self.mxSession.myUserId, senderId == currentUserId {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Indicate true if the cell data is collapsable and collapsed
|
||||
var isCollapsableAndCollapsed: Bool {
|
||||
return self.collapsable && self.collapsed
|
||||
}
|
||||
|
||||
var cellDataTag: RoomBubbleCellDataTag {
|
||||
return RoomBubbleCellDataTag(rawValue: self.tag) ?? .message
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -67,6 +67,17 @@ extern NSString *const kMXKRoomBubbleCellKeyVerificationIncomingRequestDeclinePr
|
|||
*/
|
||||
- (void)addTimestampLabelForComponent:(NSUInteger)componentIndex;
|
||||
|
||||
/**
|
||||
Add timestamp label for a component in receiver.
|
||||
|
||||
Note: The label added here is automatically removed when [didEndDisplay] is called.
|
||||
|
||||
@param componentIndex index of the component in bubble message data
|
||||
@param displayOnLeft Indicate true to display label on left and false to display on right
|
||||
*/
|
||||
- (void)addTimestampLabelForComponent:(NSUInteger)componentIndex
|
||||
displayOnLeft:(BOOL)displayOnLeft;
|
||||
|
||||
/**
|
||||
Highlight a component in receiver.
|
||||
|
||||
|
|
|
@ -36,6 +36,29 @@ NSString *const kMXKRoomBubbleCellKeyVerificationIncomingRequestDeclinePressed =
|
|||
@implementation MXKRoomBubbleTableViewCell (Riot)
|
||||
|
||||
- (void)addTimestampLabelForComponent:(NSUInteger)componentIndex
|
||||
{
|
||||
BOOL isFirstDisplayedComponent = (componentIndex == 0);
|
||||
BOOL isLastMessageMostRecentComponent = NO;
|
||||
|
||||
RoomBubbleCellData *roomBubbleCellData;
|
||||
|
||||
if ([bubbleData isKindOfClass:RoomBubbleCellData.class])
|
||||
{
|
||||
roomBubbleCellData = (RoomBubbleCellData*)bubbleData;
|
||||
isFirstDisplayedComponent = (componentIndex == roomBubbleCellData.oldestComponentIndex);
|
||||
isLastMessageMostRecentComponent = roomBubbleCellData.containsLastMessage && (componentIndex == roomBubbleCellData.mostRecentComponentIndex);
|
||||
}
|
||||
|
||||
// Display timestamp on the left for selected component when it cannot overlap other UI elements like user's avatar
|
||||
BOOL displayLabelOnLeft = roomBubbleCellData.displayTimestampForSelectedComponentOnLeftWhenPossible
|
||||
&& !isLastMessageMostRecentComponent
|
||||
&& (!isFirstDisplayedComponent || roomBubbleCellData.shouldHideSenderInformation);
|
||||
|
||||
[self addTimestampLabelForComponent:componentIndex displayOnLeft:displayLabelOnLeft];
|
||||
}
|
||||
|
||||
- (void)addTimestampLabelForComponent:(NSUInteger)componentIndex
|
||||
displayOnLeft:(BOOL)displayLabelOnLeft
|
||||
{
|
||||
MXKRoomBubbleComponent *component;
|
||||
|
||||
|
@ -49,7 +72,6 @@ NSString *const kMXKRoomBubbleCellKeyVerificationIncomingRequestDeclinePressed =
|
|||
if (component && component.date)
|
||||
{
|
||||
BOOL isFirstDisplayedComponent = (componentIndex == 0);
|
||||
BOOL isLastMessageMostRecentComponent = NO;
|
||||
|
||||
RoomBubbleCellData *roomBubbleCellData;
|
||||
|
||||
|
@ -57,14 +79,8 @@ NSString *const kMXKRoomBubbleCellKeyVerificationIncomingRequestDeclinePressed =
|
|||
{
|
||||
roomBubbleCellData = (RoomBubbleCellData*)bubbleData;
|
||||
isFirstDisplayedComponent = (componentIndex == roomBubbleCellData.oldestComponentIndex);
|
||||
isLastMessageMostRecentComponent = roomBubbleCellData.containsLastMessage && (componentIndex == roomBubbleCellData.mostRecentComponentIndex);
|
||||
}
|
||||
|
||||
// Display timestamp on the left for selected component when it cannot overlap other UI elements like user's avatar
|
||||
BOOL displayLabelOnLeft = roomBubbleCellData.displayTimestampForSelectedComponentOnLeftWhenPossible
|
||||
&& !isLastMessageMostRecentComponent
|
||||
&& ( !isFirstDisplayedComponent || roomBubbleCellData.shouldHideSenderInformation);
|
||||
|
||||
[self addTimestampLabelForComponentIndex:componentIndex
|
||||
isFirstDisplayedComponent:isFirstDisplayedComponent
|
||||
viewTag:componentIndex
|
||||
|
|
|
@ -59,6 +59,7 @@ extension UIImage {
|
|||
|
||||
// Based on https://stackoverflow.com/a/31314494
|
||||
@objc func vc_resized(with targetSize: CGSize) -> UIImage? {
|
||||
let originalRenderingMode = self.renderingMode
|
||||
let size = self.size
|
||||
|
||||
let widthRatio = targetSize.width/size.width
|
||||
|
@ -79,7 +80,7 @@ extension UIImage {
|
|||
let newImage = UIGraphicsGetImageFromCurrentImageContext()
|
||||
UIGraphicsEndImageContext()
|
||||
|
||||
return newImage
|
||||
return newImage?.withRenderingMode(originalRenderingMode)
|
||||
}
|
||||
|
||||
@objc func vc_notRenderedImage() -> UIImage {
|
||||
|
|
311
Riot/Categories/UIView+Toast.swift
Normal file
|
@ -0,0 +1,311 @@
|
|||
//
|
||||
// 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
|
||||
|
||||
// MARK: - ToastPosition
|
||||
|
||||
/// Vertical position for a toast
|
||||
@objc
|
||||
enum ToastPosition: Int {
|
||||
/// Toast will be placed at the top of the screen, with a margin to the safe area insets of the superview. Max height is also limited with safe area insets.
|
||||
case top
|
||||
/// Toast will be placed at the middle of the screen vertically. Max height is also limited with safe area insets.
|
||||
case middle
|
||||
/// Toast will be placed at the bottom of the screen, with a margin to the safe area insets of the superview. Max height is also limited with safe area insets.
|
||||
case bottom
|
||||
}
|
||||
|
||||
// MARK: - UIView Extension
|
||||
|
||||
extension UIView {
|
||||
|
||||
private enum Constants {
|
||||
static let defaultDuration: TimeInterval = 2.0
|
||||
static let defaultPosition: ToastPosition = .bottom
|
||||
}
|
||||
|
||||
private static var operationQueue: OperationQueue = {
|
||||
let queue = OperationQueue.vc_createSerialOperationQueue(name: "ToastQueue")
|
||||
queue.qualityOfService = .userInteractive
|
||||
queue.underlyingQueue = .main
|
||||
return queue
|
||||
}()
|
||||
|
||||
/// Show a toast message with the given properties.
|
||||
/// - Parameters:
|
||||
/// - message: Message to be displayed
|
||||
/// - image: Icon to be displayed. Placed left to the message. Will be tinted.
|
||||
/// - duration: Duration of the toast messsage
|
||||
/// - position: Vertical position of the toast message in the view. Toast view spans the receiver view horizontally, taking into account the safe area insets.
|
||||
/// - additionalMargin: By default, a toast placed according to safe area insets, with a margin.
|
||||
/// For `top` and `bottom` positions, adds toast an additional margin from the top and bottom respectively.
|
||||
/// Has no effect for `middle` position.
|
||||
@objc
|
||||
func vc_toast(message: String?,
|
||||
image: UIImage? = nil,
|
||||
duration: TimeInterval = Constants.defaultDuration,
|
||||
position: ToastPosition = Constants.defaultPosition,
|
||||
additionalMargin: CGFloat = 0.0) {
|
||||
let view = ToastView(withMessage: message, image: image)
|
||||
vc_toast(view: view, duration: duration, position: position, additionalMargin: additionalMargin)
|
||||
}
|
||||
|
||||
/// Show a toast view with the given properties.
|
||||
/// - Parameters:
|
||||
/// - view: View to be displayed as a toast
|
||||
/// - duration: Duration of the toast messsage
|
||||
/// - position: Vertical position of the toast message in the view. Toast view spans the receiver view horizontally, taking into account the safe area insets.
|
||||
/// - additionalMargin: By default, a toast placed according to safe area insets, with a margin.
|
||||
/// For `top` and `bottom` positions, adds toast an additional margin from the top and bottom respectively.
|
||||
/// Has no effect for `middle` position.
|
||||
@objc
|
||||
func vc_toast(view: UIView,
|
||||
duration: TimeInterval = Constants.defaultDuration,
|
||||
position: ToastPosition = Constants.defaultPosition,
|
||||
additionalMargin: CGFloat = 0.0) {
|
||||
let operation = ToastOperation(containerView: self,
|
||||
toastView: view,
|
||||
duration: duration,
|
||||
position: position,
|
||||
additionalMargin: additionalMargin,
|
||||
completion: nil)
|
||||
Self.operationQueue.addOperation(operation)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - ToastOperation
|
||||
|
||||
/// Async toast UI operation. Will run on the main thread.
|
||||
private class ToastOperation: AsyncOperation {
|
||||
|
||||
private enum Constants {
|
||||
static let margin: UIEdgeInsets = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16)
|
||||
static let animationDuration: TimeInterval = 0.15
|
||||
static let timeBetweenToasts: TimeInterval = 0.5
|
||||
}
|
||||
|
||||
private var containerView: UIView
|
||||
private var toastView: UIView
|
||||
private var duration: TimeInterval
|
||||
private var position: ToastPosition
|
||||
private var additionalMargin: CGFloat
|
||||
private var completion: (() -> Void)?
|
||||
private var timer: Timer?
|
||||
|
||||
init(containerView: UIView,
|
||||
toastView: UIView,
|
||||
duration: TimeInterval,
|
||||
position: ToastPosition,
|
||||
additionalMargin: CGFloat,
|
||||
completion: (() -> Void)? = nil) {
|
||||
self.containerView = containerView
|
||||
self.toastView = toastView
|
||||
self.duration = duration
|
||||
self.position = position
|
||||
self.additionalMargin = additionalMargin
|
||||
self.completion = completion
|
||||
}
|
||||
|
||||
override func main() {
|
||||
showToast {
|
||||
self.invalidateTimer()
|
||||
let timer = Timer(timeInterval: self.duration,
|
||||
target: self,
|
||||
selector: #selector(self.timerFired(_:)),
|
||||
userInfo: nil,
|
||||
repeats: false)
|
||||
RunLoop.main.add(timer, forMode: .common)
|
||||
self.timer = timer
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
private func timerFired(_ timer: Timer) {
|
||||
invalidateTimer()
|
||||
hideToast()
|
||||
}
|
||||
|
||||
private func showToast(_ completion: @escaping () -> Void) {
|
||||
toastView.alpha = 0.0
|
||||
containerView.addSubview(toastView)
|
||||
toastView.translatesAutoresizingMaskIntoConstraints = false
|
||||
switch position {
|
||||
case .top:
|
||||
NSLayoutConstraint.activate([
|
||||
toastView.leadingAnchor.constraint(equalTo: containerView.safeAreaLayoutGuide.leadingAnchor,
|
||||
constant: Constants.margin.left),
|
||||
toastView.topAnchor.constraint(equalTo: containerView.safeAreaLayoutGuide.topAnchor,
|
||||
constant: Constants.margin.top + additionalMargin),
|
||||
toastView.trailingAnchor.constraint(equalTo: containerView.safeAreaLayoutGuide.trailingAnchor,
|
||||
constant: -Constants.margin.right),
|
||||
toastView.bottomAnchor.constraint(lessThanOrEqualTo: containerView.safeAreaLayoutGuide.bottomAnchor,
|
||||
constant: -Constants.margin.bottom)
|
||||
])
|
||||
case .middle:
|
||||
NSLayoutConstraint.activate([
|
||||
toastView.leadingAnchor.constraint(equalTo: containerView.safeAreaLayoutGuide.leadingAnchor,
|
||||
constant: Constants.margin.left),
|
||||
toastView.topAnchor.constraint(greaterThanOrEqualTo: containerView.safeAreaLayoutGuide.topAnchor,
|
||||
constant: Constants.margin.top),
|
||||
toastView.trailingAnchor.constraint(equalTo: containerView.safeAreaLayoutGuide.trailingAnchor,
|
||||
constant: -Constants.margin.right),
|
||||
toastView.bottomAnchor.constraint(lessThanOrEqualTo: containerView.safeAreaLayoutGuide.bottomAnchor,
|
||||
constant: -Constants.margin.bottom),
|
||||
toastView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor)
|
||||
])
|
||||
case .bottom:
|
||||
NSLayoutConstraint.activate([
|
||||
toastView.leadingAnchor.constraint(equalTo: containerView.safeAreaLayoutGuide.leadingAnchor,
|
||||
constant: Constants.margin.left),
|
||||
toastView.topAnchor.constraint(greaterThanOrEqualTo: containerView.safeAreaLayoutGuide.topAnchor,
|
||||
constant: Constants.margin.top),
|
||||
toastView.trailingAnchor.constraint(equalTo: containerView.safeAreaLayoutGuide.trailingAnchor,
|
||||
constant: -Constants.margin.right),
|
||||
toastView.bottomAnchor.constraint(equalTo: containerView.safeAreaLayoutGuide.bottomAnchor,
|
||||
constant: -Constants.margin.bottom - additionalMargin)
|
||||
])
|
||||
}
|
||||
|
||||
UIView.animate(withDuration: Constants.animationDuration,
|
||||
delay: 0.0,
|
||||
options: [.curveEaseOut, .allowUserInteraction],
|
||||
animations: {
|
||||
self.toastView.alpha = 1.0
|
||||
}, completion: { _ in
|
||||
completion()
|
||||
})
|
||||
}
|
||||
|
||||
private func hideToast() {
|
||||
UIView.animate(withDuration: Constants.animationDuration,
|
||||
delay: 0.0,
|
||||
options: [.curveEaseIn, .beginFromCurrentState],
|
||||
animations: {
|
||||
self.toastView.alpha = 0.0
|
||||
}, completion: { _ in
|
||||
self.toastView.removeFromSuperview()
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + Constants.timeBetweenToasts) {
|
||||
self.finish()
|
||||
self.completion?()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private func invalidateTimer() {
|
||||
timer?.invalidate()
|
||||
timer = nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - ToastView
|
||||
|
||||
/// Default view for a basic toast.
|
||||
private class ToastView: UIView, Themable {
|
||||
|
||||
private enum Constants {
|
||||
static let padding: UIEdgeInsets = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16)
|
||||
static let cornerRadius: CGFloat = 8.0
|
||||
}
|
||||
|
||||
private lazy var imageView: UIImageView = {
|
||||
let view = UIImageView()
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.backgroundColor = .clear
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var messageLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = ThemeService.shared().theme.fonts.body
|
||||
label.backgroundColor = .clear
|
||||
label.numberOfLines = 0
|
||||
label.textAlignment = .left
|
||||
label.translatesAutoresizingMaskIntoConstraints = false
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var stackView: UIStackView = {
|
||||
let result = UIStackView()
|
||||
result.axis = .horizontal
|
||||
result.distribution = .fill
|
||||
result.alignment = .center
|
||||
result.spacing = 8.0
|
||||
result.backgroundColor = .clear
|
||||
|
||||
addSubview(result)
|
||||
result.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
result.leadingAnchor.constraint(equalTo: leadingAnchor, constant: Constants.padding.left),
|
||||
result.topAnchor.constraint(equalTo: topAnchor, constant: Constants.padding.top),
|
||||
result.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -Constants.padding.right),
|
||||
result.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -Constants.padding.bottom)
|
||||
])
|
||||
|
||||
return result
|
||||
}()
|
||||
|
||||
init(withMessage message: String?,
|
||||
image: UIImage? = nil) {
|
||||
super.init(frame: .zero)
|
||||
|
||||
if let image = image {
|
||||
imageView.image = image
|
||||
NSLayoutConstraint.activate([
|
||||
imageView.widthAnchor.constraint(equalToConstant: image.size.width),
|
||||
imageView.heightAnchor.constraint(equalToConstant: image.size.height)
|
||||
])
|
||||
stackView.addArrangedSubview(imageView)
|
||||
}
|
||||
|
||||
messageLabel.text = message
|
||||
stackView.addArrangedSubview(messageLabel)
|
||||
|
||||
stackView.layoutIfNeeded()
|
||||
layer.cornerRadius = Constants.cornerRadius
|
||||
layer.masksToBounds = true
|
||||
registerThemeServiceDidChangeThemeNotification()
|
||||
themeDidChange()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
private func registerThemeServiceDidChangeThemeNotification() {
|
||||
NotificationCenter.default.addObserver(self,
|
||||
selector: #selector(themeDidChange),
|
||||
name: .themeServiceDidChangeTheme,
|
||||
object: nil)
|
||||
}
|
||||
|
||||
@objc
|
||||
private func themeDidChange() {
|
||||
self.update(theme: ThemeService.shared().theme)
|
||||
}
|
||||
|
||||
// MARK: Themable
|
||||
|
||||
func update(theme: Theme) {
|
||||
backgroundColor = theme.colors.quinaryContent
|
||||
imageView.tintColor = theme.colors.tertiaryContent
|
||||
messageLabel.textColor = theme.colors.primaryContent
|
||||
messageLabel.font = theme.fonts.body
|
||||
}
|
||||
|
||||
}
|
|
@ -110,6 +110,14 @@ internal enum Asset {
|
|||
internal static let cameraStop = ImageAsset(name: "camera_stop")
|
||||
internal static let cameraVideoCapture = ImageAsset(name: "camera_video_capture")
|
||||
internal static let videoIcon = ImageAsset(name: "video_icon")
|
||||
internal static let onboardingSplashScreenPage1 = ImageAsset(name: "OnboardingSplashScreenPage1")
|
||||
internal static let onboardingSplashScreenPage1Dark = ImageAsset(name: "OnboardingSplashScreenPage1Dark")
|
||||
internal static let onboardingSplashScreenPage2 = ImageAsset(name: "OnboardingSplashScreenPage2")
|
||||
internal static let onboardingSplashScreenPage2Dark = ImageAsset(name: "OnboardingSplashScreenPage2Dark")
|
||||
internal static let onboardingSplashScreenPage3 = ImageAsset(name: "OnboardingSplashScreenPage3")
|
||||
internal static let onboardingSplashScreenPage3Dark = ImageAsset(name: "OnboardingSplashScreenPage3Dark")
|
||||
internal static let onboardingSplashScreenPage4 = ImageAsset(name: "OnboardingSplashScreenPage4")
|
||||
internal static let onboardingSplashScreenPage4Dark = ImageAsset(name: "OnboardingSplashScreenPage4Dark")
|
||||
internal static let peopleEmptyScreenArtwork = ImageAsset(name: "people_empty_screen_artwork")
|
||||
internal static let peopleEmptyScreenArtworkDark = ImageAsset(name: "people_empty_screen_artwork_dark")
|
||||
internal static let peopleFloatingAction = ImageAsset(name: "people_floating_action")
|
||||
|
@ -135,6 +143,7 @@ internal enum Asset {
|
|||
internal static let roomContextMenuMore = ImageAsset(name: "room_context_menu_more")
|
||||
internal static let roomContextMenuReply = ImageAsset(name: "room_context_menu_reply")
|
||||
internal static let roomContextMenuRetry = ImageAsset(name: "room_context_menu_retry")
|
||||
internal static let roomContextMenuThread = ImageAsset(name: "room_context_menu_thread")
|
||||
internal static let inputCloseIcon = ImageAsset(name: "input_close_icon")
|
||||
internal static let inputEditIcon = ImageAsset(name: "input_edit_icon")
|
||||
internal static let inputReplyIcon = ImageAsset(name: "input_reply_icon")
|
||||
|
@ -158,6 +167,9 @@ internal enum Asset {
|
|||
internal static let pollTypeCheckboxDefault = ImageAsset(name: "poll_type_checkbox_default")
|
||||
internal static let pollTypeCheckboxSelected = ImageAsset(name: "poll_type_checkbox_selected")
|
||||
internal static let pollWinnerIcon = ImageAsset(name: "poll_winner_icon")
|
||||
internal static let threadsFilter = ImageAsset(name: "threads_filter")
|
||||
internal static let threadsFilterApplied = ImageAsset(name: "threads_filter_applied")
|
||||
internal static let threadsIcon = ImageAsset(name: "threads_icon")
|
||||
internal static let urlPreviewClose = ImageAsset(name: "url_preview_close")
|
||||
internal static let urlPreviewCloseDark = ImageAsset(name: "url_preview_close_dark")
|
||||
internal static let voiceMessageCancelGradient = ImageAsset(name: "voice_message_cancel_gradient")
|
||||
|
@ -174,7 +186,9 @@ internal enum Asset {
|
|||
internal static let addParticipants = ImageAsset(name: "add_participants")
|
||||
internal static let detailsIcon = ImageAsset(name: "details_icon")
|
||||
internal static let editIcon = ImageAsset(name: "edit_icon")
|
||||
internal static let fileAttachment = ImageAsset(name: "file_attachment")
|
||||
internal static let integrationsIcon = ImageAsset(name: "integrations_icon")
|
||||
internal static let linkIcon = ImageAsset(name: "link_icon")
|
||||
internal static let mainAliasIcon = ImageAsset(name: "main_alias_icon")
|
||||
internal static let membersListIcon = ImageAsset(name: "members_list_icon")
|
||||
internal static let modIcon = ImageAsset(name: "mod_icon")
|
||||
|
|
|
@ -279,6 +279,11 @@ internal enum StoryboardScene {
|
|||
|
||||
internal static let initialScene = InitialSceneType<Riot.TemplateScreenViewController>(storyboard: TemplateScreenViewController.self)
|
||||
}
|
||||
internal enum ThreadListViewController: StoryboardType {
|
||||
internal static let storyboardName = "ThreadListViewController"
|
||||
|
||||
internal static let initialScene = InitialSceneType<Riot.ThreadListViewController>(storyboard: ThreadListViewController.self)
|
||||
}
|
||||
internal enum UserVerificationSessionStatusViewController: StoryboardType {
|
||||
internal static let storyboardName = "UserVerificationSessionStatusViewController"
|
||||
|
||||
|
|
|
@ -115,7 +115,7 @@ public class VectorL10n: NSObject {
|
|||
public static var authEmailInUse: String {
|
||||
return VectorL10n.tr("Vector", "auth_email_in_use")
|
||||
}
|
||||
/// No identity server is configured so you cannot add an email address in order to reset your password in the future.
|
||||
/// No identity server is configured so you cannot add an email address in order to reset your Matrix account password in the future.
|
||||
public static var authEmailIsRequired: String {
|
||||
return VectorL10n.tr("Vector", "auth_email_is_required")
|
||||
}
|
||||
|
@ -131,11 +131,11 @@ public class VectorL10n: NSObject {
|
|||
public static var authEmailValidationMessage: String {
|
||||
return VectorL10n.tr("Vector", "auth_email_validation_message")
|
||||
}
|
||||
/// Forgot password?
|
||||
/// Forgot Matrix account password?
|
||||
public static var authForgotPassword: String {
|
||||
return VectorL10n.tr("Vector", "auth_forgot_password")
|
||||
}
|
||||
/// No identity server is configured: add one to reset your password.
|
||||
/// No identity server is configured: add one to reset your Matrix account password.
|
||||
public static var authForgotPasswordErrorNoConfiguredIdentityServer: String {
|
||||
return VectorL10n.tr("Vector", "auth_forgot_password_error_no_configured_identity_server")
|
||||
}
|
||||
|
@ -227,7 +227,7 @@ public class VectorL10n: NSObject {
|
|||
public static var authPhoneInUse: String {
|
||||
return VectorL10n.tr("Vector", "auth_phone_in_use")
|
||||
}
|
||||
/// No identity server is configured so you cannot add a phone number in order to reset your password in the future.
|
||||
/// No identity server is configured so you cannot add a phone number in order to reset your Matrix account password in the future.
|
||||
public static var authPhoneIsRequired: String {
|
||||
return VectorL10n.tr("Vector", "auth_phone_is_required")
|
||||
}
|
||||
|
@ -243,7 +243,7 @@ public class VectorL10n: NSObject {
|
|||
public static var authRegister: String {
|
||||
return VectorL10n.tr("Vector", "auth_register")
|
||||
}
|
||||
/// Confirm your new password
|
||||
/// Confirm your new Matrix account password
|
||||
public static var authRepeatNewPasswordPlaceholder: String {
|
||||
return VectorL10n.tr("Vector", "auth_repeat_new_password_placeholder")
|
||||
}
|
||||
|
@ -255,7 +255,7 @@ public class VectorL10n: NSObject {
|
|||
public static func authResetPasswordEmailValidationMessage(_ p1: String) -> String {
|
||||
return VectorL10n.tr("Vector", "auth_reset_password_email_validation_message", p1)
|
||||
}
|
||||
/// No identity server is configured: add one in server options to reset your password.
|
||||
/// No identity server is configured: add one in server options to reset your Matrix account password.
|
||||
public static var authResetPasswordErrorIsRequired: String {
|
||||
return VectorL10n.tr("Vector", "auth_reset_password_error_is_required")
|
||||
}
|
||||
|
@ -267,7 +267,7 @@ public class VectorL10n: NSObject {
|
|||
public static var authResetPasswordErrorUnauthorized: String {
|
||||
return VectorL10n.tr("Vector", "auth_reset_password_error_unauthorized")
|
||||
}
|
||||
/// To reset your password, enter the email address linked to your account:
|
||||
/// To reset your Matrix account password, enter the email address linked to your account:
|
||||
public static var authResetPasswordMessage: String {
|
||||
return VectorL10n.tr("Vector", "auth_reset_password_message")
|
||||
}
|
||||
|
@ -283,7 +283,7 @@ public class VectorL10n: NSObject {
|
|||
public static var authResetPasswordNextStepButton: String {
|
||||
return VectorL10n.tr("Vector", "auth_reset_password_next_step_button")
|
||||
}
|
||||
/// Your password has been reset.\n\nYou have been logged out of all sessions and will no longer receive push notifications. To re-enable notifications, re-log in on each device.
|
||||
/// Your Matrix account password has been reset.\n\nYou have been logged out of all sessions and will no longer receive push notifications. To re-enable notifications, re-log in on each device.
|
||||
public static var authResetPasswordSuccessMessage: String {
|
||||
return VectorL10n.tr("Vector", "auth_reset_password_success_message")
|
||||
}
|
||||
|
@ -747,7 +747,7 @@ public class VectorL10n: NSObject {
|
|||
public static var deactivateAccountInformationsPart5: String {
|
||||
return VectorL10n.tr("Vector", "deactivate_account_informations_part5")
|
||||
}
|
||||
/// To continue, please enter your password
|
||||
/// To continue, please enter your Matrix account password
|
||||
public static var deactivateAccountPasswordAlertMessage: String {
|
||||
return VectorL10n.tr("Vector", "deactivate_account_password_alert_message")
|
||||
}
|
||||
|
@ -1419,6 +1419,10 @@ public class VectorL10n: NSObject {
|
|||
public static func eventFormatterMemberUpdates(_ p1: Int) -> String {
|
||||
return VectorL10n.tr("Vector", "event_formatter_member_updates", p1)
|
||||
}
|
||||
/// Message deleted
|
||||
public static var eventFormatterMessageDeleted: String {
|
||||
return VectorL10n.tr("Vector", "event_formatter_message_deleted")
|
||||
}
|
||||
/// (edited)
|
||||
public static var eventFormatterMessageEditedMention: String {
|
||||
return VectorL10n.tr("Vector", "event_formatter_message_edited_mention")
|
||||
|
@ -1595,6 +1599,46 @@ public class VectorL10n: NSObject {
|
|||
public static var groupSection: String {
|
||||
return VectorL10n.tr("Vector", "group_section")
|
||||
}
|
||||
/// Favourite
|
||||
public static var homeContextMenuFavourite: String {
|
||||
return VectorL10n.tr("Vector", "home_context_menu_favourite")
|
||||
}
|
||||
/// Leave
|
||||
public static var homeContextMenuLeave: String {
|
||||
return VectorL10n.tr("Vector", "home_context_menu_leave")
|
||||
}
|
||||
/// Low priority
|
||||
public static var homeContextMenuLowPriority: String {
|
||||
return VectorL10n.tr("Vector", "home_context_menu_low_priority")
|
||||
}
|
||||
/// Move to People
|
||||
public static var homeContextMenuMakeDm: String {
|
||||
return VectorL10n.tr("Vector", "home_context_menu_make_dm")
|
||||
}
|
||||
/// Move to Rooms
|
||||
public static var homeContextMenuMakeRoom: String {
|
||||
return VectorL10n.tr("Vector", "home_context_menu_make_room")
|
||||
}
|
||||
/// Mute
|
||||
public static var homeContextMenuMute: String {
|
||||
return VectorL10n.tr("Vector", "home_context_menu_mute")
|
||||
}
|
||||
/// Normal priority
|
||||
public static var homeContextMenuNormalPriority: String {
|
||||
return VectorL10n.tr("Vector", "home_context_menu_normal_priority")
|
||||
}
|
||||
/// Notifications
|
||||
public static var homeContextMenuNotifications: String {
|
||||
return VectorL10n.tr("Vector", "home_context_menu_notifications")
|
||||
}
|
||||
/// Remove from Favourites
|
||||
public static var homeContextMenuUnfavourite: String {
|
||||
return VectorL10n.tr("Vector", "home_context_menu_unfavourite")
|
||||
}
|
||||
/// Unmute
|
||||
public static var homeContextMenuUnmute: String {
|
||||
return VectorL10n.tr("Vector", "home_context_menu_unmute")
|
||||
}
|
||||
/// The all-in-one secure chat app for teams, friends and organisations. Tap the + button below to add people and rooms.
|
||||
public static var homeEmptyViewInformation: String {
|
||||
return VectorL10n.tr("Vector", "home_empty_view_information")
|
||||
|
@ -1831,7 +1875,7 @@ public class VectorL10n: NSObject {
|
|||
public static var keyBackupSetupPassphraseConfirmPassphraseValid: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_setup_passphrase_confirm_passphrase_valid")
|
||||
}
|
||||
/// We'll store an encrypted copy of your keys on our server. Protect your backup with a phrase to keep it secure.\n\nFor maximum security, this should be different from your account password.
|
||||
/// We'll store an encrypted copy of your keys on our server. Protect your backup with a phrase to keep it secure.\n\nFor maximum security, this should be different from your Matrix account password.
|
||||
public static var keyBackupSetupPassphraseInfo: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_setup_passphrase_info")
|
||||
}
|
||||
|
@ -2223,6 +2267,14 @@ public class VectorL10n: NSObject {
|
|||
public static var locationSharingOpenGoogleMaps: String {
|
||||
return VectorL10n.tr("Vector", "location_sharing_open_google_maps")
|
||||
}
|
||||
/// %@ could not send your location. Please try again later.
|
||||
public static func locationSharingPostFailureSubtitle(_ p1: String) -> String {
|
||||
return VectorL10n.tr("Vector", "location_sharing_post_failure_subtitle", p1)
|
||||
}
|
||||
/// We couldn’t send your location
|
||||
public static var locationSharingPostFailureTitle: String {
|
||||
return VectorL10n.tr("Vector", "location_sharing_post_failure_title")
|
||||
}
|
||||
/// Location sharing
|
||||
public static var locationSharingSettingsHeader: String {
|
||||
return VectorL10n.tr("Vector", "location_sharing_settings_header")
|
||||
|
@ -2315,6 +2367,10 @@ public class VectorL10n: NSObject {
|
|||
public static var mediaTypeAccessibilityVideo: String {
|
||||
return VectorL10n.tr("Vector", "media_type_accessibility_video")
|
||||
}
|
||||
/// From a thread
|
||||
public static var messageFromAThread: String {
|
||||
return VectorL10n.tr("Vector", "message_from_a_thread")
|
||||
}
|
||||
/// More
|
||||
public static var more: String {
|
||||
return VectorL10n.tr("Vector", "more")
|
||||
|
@ -2687,6 +2743,14 @@ public class VectorL10n: NSObject {
|
|||
public static var roomAccessibilitySearch: String {
|
||||
return VectorL10n.tr("Vector", "room_accessibility_search")
|
||||
}
|
||||
/// More
|
||||
public static var roomAccessibilityThreadMore: String {
|
||||
return VectorL10n.tr("Vector", "room_accessibility_thread_more")
|
||||
}
|
||||
/// Threads
|
||||
public static var roomAccessibilityThreads: String {
|
||||
return VectorL10n.tr("Vector", "room_accessibility_threads")
|
||||
}
|
||||
/// Upload
|
||||
public static var roomAccessibilityUpload: String {
|
||||
return VectorL10n.tr("Vector", "room_accessibility_upload")
|
||||
|
@ -3167,7 +3231,7 @@ public class VectorL10n: NSObject {
|
|||
public static var roomEventActionMore: String {
|
||||
return VectorL10n.tr("Vector", "room_event_action_more")
|
||||
}
|
||||
/// Permalink
|
||||
/// Copy link to message
|
||||
public static var roomEventActionPermalink: String {
|
||||
return VectorL10n.tr("Vector", "room_event_action_permalink")
|
||||
}
|
||||
|
@ -3199,6 +3263,10 @@ public class VectorL10n: NSObject {
|
|||
public static var roomEventActionReply: String {
|
||||
return VectorL10n.tr("Vector", "room_event_action_reply")
|
||||
}
|
||||
/// Thread
|
||||
public static var roomEventActionReplyInThread: String {
|
||||
return VectorL10n.tr("Vector", "room_event_action_reply_in_thread")
|
||||
}
|
||||
/// Report content
|
||||
public static var roomEventActionReport: String {
|
||||
return VectorL10n.tr("Vector", "room_event_action_report")
|
||||
|
@ -3231,10 +3299,18 @@ public class VectorL10n: NSObject {
|
|||
public static var roomEventActionViewEncryption: String {
|
||||
return VectorL10n.tr("Vector", "room_event_action_view_encryption")
|
||||
}
|
||||
/// View in room
|
||||
public static var roomEventActionViewInRoom: String {
|
||||
return VectorL10n.tr("Vector", "room_event_action_view_in_room")
|
||||
}
|
||||
/// View Source
|
||||
public static var roomEventActionViewSource: String {
|
||||
return VectorL10n.tr("Vector", "room_event_action_view_source")
|
||||
}
|
||||
/// Link copied to clipboard.
|
||||
public static var roomEventCopyLinkInfo: String {
|
||||
return VectorL10n.tr("Vector", "room_event_copy_link_info")
|
||||
}
|
||||
/// Failed to send
|
||||
public static var roomEventFailedToSend: String {
|
||||
return VectorL10n.tr("Vector", "room_event_failed_to_send")
|
||||
|
@ -3799,6 +3875,10 @@ public class VectorL10n: NSObject {
|
|||
public static var roomSlideToEndGroupCall: String {
|
||||
return VectorL10n.tr("Vector", "room_slide_to_end_group_call")
|
||||
}
|
||||
/// Thread
|
||||
public static var roomThreadTitle: String {
|
||||
return VectorL10n.tr("Vector", "room_thread_title")
|
||||
}
|
||||
/// Invite members
|
||||
public static var roomTitleInviteMembers: String {
|
||||
return VectorL10n.tr("Vector", "room_title_invite_members")
|
||||
|
@ -4035,7 +4115,7 @@ public class VectorL10n: NSObject {
|
|||
public static var secretsRecoveryWithPassphraseTitle: String {
|
||||
return VectorL10n.tr("Vector", "secrets_recovery_with_passphrase_title")
|
||||
}
|
||||
/// Enter your account password to confirm
|
||||
/// Enter your Matrix account password to confirm
|
||||
public static var secretsResetAuthenticationMessage: String {
|
||||
return VectorL10n.tr("Vector", "secrets_reset_authentication_message")
|
||||
}
|
||||
|
@ -4087,7 +4167,7 @@ public class VectorL10n: NSObject {
|
|||
public static var secretsSetupRecoveryKeyTitle: String {
|
||||
return VectorL10n.tr("Vector", "secrets_setup_recovery_key_title")
|
||||
}
|
||||
/// Don't use your account password.
|
||||
/// Don't use your Matrix account password.
|
||||
public static var secretsSetupRecoveryPassphraseAdditionalInformation: String {
|
||||
return VectorL10n.tr("Vector", "secrets_setup_recovery_passphrase_additional_information")
|
||||
}
|
||||
|
@ -4243,7 +4323,7 @@ public class VectorL10n: NSObject {
|
|||
public static var securitySettingsCryptoSessions: String {
|
||||
return VectorL10n.tr("Vector", "security_settings_crypto_sessions")
|
||||
}
|
||||
/// If you don’t recognise a login, change your password and reset Secure Backup.
|
||||
/// If you don’t recognise a login, change your Matrix account password and reset Secure Backup.
|
||||
public static var securitySettingsCryptoSessionsDescription2: String {
|
||||
return VectorL10n.tr("Vector", "security_settings_crypto_sessions_description_2")
|
||||
}
|
||||
|
@ -4295,7 +4375,7 @@ public class VectorL10n: NSObject {
|
|||
public static var securitySettingsTitle: String {
|
||||
return VectorL10n.tr("Vector", "security_settings_title")
|
||||
}
|
||||
/// Confirm your identity by entering your account password
|
||||
/// Confirm your identity by entering your Matrix account password
|
||||
public static var securitySettingsUserPasswordDescription: String {
|
||||
return VectorL10n.tr("Vector", "security_settings_user_password_description")
|
||||
}
|
||||
|
@ -4367,7 +4447,7 @@ public class VectorL10n: NSObject {
|
|||
public static var settingsAdd3pidInvalidPasswordMessage: String {
|
||||
return VectorL10n.tr("Vector", "settings_add_3pid_invalid_password_message")
|
||||
}
|
||||
/// To continue, please enter your password
|
||||
/// To continue, please enter your Matrix account password
|
||||
public static var settingsAdd3pidPasswordMessage: String {
|
||||
return VectorL10n.tr("Vector", "settings_add_3pid_password_message")
|
||||
}
|
||||
|
@ -4415,7 +4495,7 @@ public class VectorL10n: NSObject {
|
|||
public static func settingsCallsStunServerFallbackDescription(_ p1: String) -> String {
|
||||
return VectorL10n.tr("Vector", "settings_calls_stun_server_fallback_description", p1)
|
||||
}
|
||||
/// Change password
|
||||
/// Change Matrix account password
|
||||
public static var settingsChangePassword: String {
|
||||
return VectorL10n.tr("Vector", "settings_change_password")
|
||||
}
|
||||
|
@ -4619,7 +4699,7 @@ public class VectorL10n: NSObject {
|
|||
public static var settingsEncryptedGroupMessages: String {
|
||||
return VectorL10n.tr("Vector", "settings_encrypted_group_messages")
|
||||
}
|
||||
/// Fail to update password
|
||||
/// Fail to update Matrix account password
|
||||
public static var settingsFailToUpdatePassword: String {
|
||||
return VectorL10n.tr("Vector", "settings_fail_to_update_password")
|
||||
}
|
||||
|
@ -4787,6 +4867,10 @@ public class VectorL10n: NSObject {
|
|||
public static var settingsLabsEnableRingingForGroupCalls: String {
|
||||
return VectorL10n.tr("Vector", "settings_labs_enable_ringing_for_group_calls")
|
||||
}
|
||||
/// Threaded messaging
|
||||
public static var settingsLabsEnableThreads: String {
|
||||
return VectorL10n.tr("Vector", "settings_labs_enable_threads")
|
||||
}
|
||||
/// Polls
|
||||
public static var settingsLabsEnabledPolls: String {
|
||||
return VectorL10n.tr("Vector", "settings_labs_enabled_polls")
|
||||
|
@ -4871,7 +4955,7 @@ public class VectorL10n: NSObject {
|
|||
public static var settingsOther: String {
|
||||
return VectorL10n.tr("Vector", "settings_other")
|
||||
}
|
||||
/// Your password has been updated
|
||||
/// Your Matrix account password has been updated
|
||||
public static var settingsPasswordUpdated: String {
|
||||
return VectorL10n.tr("Vector", "settings_password_updated")
|
||||
}
|
||||
|
@ -5295,6 +5379,42 @@ public class VectorL10n: NSObject {
|
|||
public static var `switch`: String {
|
||||
return VectorL10n.tr("Vector", "switch")
|
||||
}
|
||||
/// Copy link to thread
|
||||
public static var threadCopyLinkToThread: String {
|
||||
return VectorL10n.tr("Vector", "thread_copy_link_to_thread")
|
||||
}
|
||||
/// All threads
|
||||
public static var threadsActionAllThreads: String {
|
||||
return VectorL10n.tr("Vector", "threads_action_all_threads")
|
||||
}
|
||||
/// My threads
|
||||
public static var threadsActionMyThreads: String {
|
||||
return VectorL10n.tr("Vector", "threads_action_my_threads")
|
||||
}
|
||||
/// Threads help keep your conversations on-topic and easy to track.
|
||||
public static var threadsEmptyInfoAll: String {
|
||||
return VectorL10n.tr("Vector", "threads_empty_info_all")
|
||||
}
|
||||
/// Reply to an ongoing thread or tap a message and use “Thread” to start a new one.
|
||||
public static var threadsEmptyInfoMy: String {
|
||||
return VectorL10n.tr("Vector", "threads_empty_info_my")
|
||||
}
|
||||
/// Show all threads
|
||||
public static var threadsEmptyShowAllThreads: String {
|
||||
return VectorL10n.tr("Vector", "threads_empty_show_all_threads")
|
||||
}
|
||||
/// Tip: Tap a message and use “Thread” to start one.
|
||||
public static var threadsEmptyTip: String {
|
||||
return VectorL10n.tr("Vector", "threads_empty_tip")
|
||||
}
|
||||
/// Keep discussions organised with threads
|
||||
public static var threadsEmptyTitle: String {
|
||||
return VectorL10n.tr("Vector", "threads_empty_title")
|
||||
}
|
||||
/// Threads
|
||||
public static var threadsTitle: String {
|
||||
return VectorL10n.tr("Vector", "threads_title")
|
||||
}
|
||||
/// Favourites
|
||||
public static var titleFavourites: String {
|
||||
return VectorL10n.tr("Vector", "title_favourites")
|
||||
|
|
|
@ -136,6 +136,10 @@ final class RiotSettings: NSObject {
|
|||
@UserDefault(key: "enableRingingForGroupCalls", defaultValue: false, storage: defaults)
|
||||
var enableRingingForGroupCalls
|
||||
|
||||
/// Indicates if threads enabled in the timeline.
|
||||
@UserDefault(key: "enableThreads", defaultValue: false, storage: defaults)
|
||||
var enableThreads
|
||||
|
||||
// MARK: Calls
|
||||
|
||||
/// Indicate if `allowStunServerFallback` settings has been set once.
|
||||
|
@ -185,13 +189,10 @@ final class RiotSettings: NSObject {
|
|||
@UserDefault(key: "roomScreenAllowFilesAction", defaultValue: BuildSettings.roomScreenAllowFilesAction, storage: defaults)
|
||||
var roomScreenAllowFilesAction
|
||||
|
||||
@UserDefault(key: "roomScreenAllowLocationAction", defaultValue: false, storage: defaults)
|
||||
var roomScreenAllowLocationAction
|
||||
|
||||
@UserDefault(key: "roomScreenShowsURLPreviews", defaultValue: true, storage: defaults)
|
||||
var roomScreenShowsURLPreviews
|
||||
|
||||
@UserDefault(key: "roomScreenEnableMessageBubbles", defaultValue: BuildSettings.roomScreenEnableMessageBubblesByDefault, storage: defaults)
|
||||
@UserDefault(key: "roomScreenEnableMessageBubbles", defaultValue: BuildSettings.isRoomScreenEnableMessageBubblesByDefault, storage: defaults)
|
||||
var roomScreenEnableMessageBubbles
|
||||
|
||||
var roomTimelineStyleIdentifier: RoomTimelineStyleIdentifier {
|
||||
|
|
|
@ -32,6 +32,7 @@ import DesignKit
|
|||
|
||||
var searchBackgroundColor: UIColor { get }
|
||||
var searchPlaceholderColor: UIColor { get }
|
||||
var searchResultHighlightColor: UIColor { get }
|
||||
|
||||
var headerBackgroundColor: UIColor { get }
|
||||
var headerBorderColor: UIColor { get }
|
||||
|
@ -96,16 +97,22 @@ import DesignKit
|
|||
|
||||
/// Color to use in shadows. Should be contrast to `backgroundColor`.
|
||||
var shadowColor: UIColor { get }
|
||||
|
||||
// Timeline cells
|
||||
|
||||
var roomCellIncomingBubbleBackgroundColor: UIColor { get }
|
||||
|
||||
var roomCellOutgoingBubbleBackgroundColor: UIColor { get }
|
||||
|
||||
// MARK: - Customisation methods
|
||||
|
||||
|
||||
/// Apply the theme on a button.
|
||||
/// Apply the theme on a tab bar.
|
||||
///
|
||||
/// - Parameter tabBar: The tabBar to customise.
|
||||
/// - Parameter tabBar: The tab bar to customise.
|
||||
func applyStyle(onTabBar tabBar: UITabBar)
|
||||
|
||||
/// Apply the theme on a navigation bar
|
||||
/// Apply the theme on a navigation bar.
|
||||
///
|
||||
/// - Parameter navigationBar: the navigation bar to customise.
|
||||
func applyStyle(onNavigationBar navigationBar: UINavigationBar)
|
||||
|
|
|
@ -146,6 +146,12 @@ NSString *const kThemeServiceDidChangeThemeNotification = @"kThemeServiceDidChan
|
|||
{
|
||||
[UIScrollView appearance].indicatorStyle = self.theme.scrollBarStyle;
|
||||
|
||||
// Remove the extra height added to section headers in iOS 15
|
||||
if (@available(iOS 15.0, *))
|
||||
{
|
||||
UITableView.appearance.sectionHeaderTopPadding = 0;
|
||||
}
|
||||
|
||||
// Define the navigation bar text color
|
||||
[[UINavigationBar appearance] setTintColor:self.theme.tintColor];
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ class DarkTheme: NSObject, Theme {
|
|||
|
||||
var searchBackgroundColor: UIColor = UIColor(rgb: 0x15191E)
|
||||
var searchPlaceholderColor: UIColor = UIColor(rgb: 0xA9B2BC)
|
||||
var searchResultHighlightColor: UIColor = UIColor(rgb: 0xFCC639).withAlphaComponent(0.3)
|
||||
|
||||
var headerBackgroundColor: UIColor = UIColor(rgb: 0x21262C)
|
||||
var headerBorderColor: UIColor = UIColor(rgb: 0x15191E)
|
||||
|
@ -91,25 +92,53 @@ class DarkTheme: NSObject, Theme {
|
|||
var shadowColor: UIColor = UIColor(rgb: 0xFFFFFF)
|
||||
|
||||
var messageTickColor: UIColor = .white
|
||||
|
||||
var roomCellIncomingBubbleBackgroundColor: UIColor {
|
||||
return self.colors.system
|
||||
}
|
||||
|
||||
var roomCellOutgoingBubbleBackgroundColor: UIColor = UIColor(rgb: 0x133A34)
|
||||
|
||||
func applyStyle(onTabBar tabBar: UITabBar) {
|
||||
tabBar.unselectedItemTintColor = self.tabBarUnselectedItemTintColor
|
||||
tabBar.tintColor = self.tintColor
|
||||
tabBar.barTintColor = self.baseColor
|
||||
tabBar.isTranslucent = false
|
||||
|
||||
// Support standard scrollEdgeAppearance iOS 15 without visual issues.
|
||||
if #available(iOS 15.0, *) {
|
||||
tabBar.isTranslucent = true
|
||||
} else {
|
||||
tabBar.isTranslucent = false
|
||||
}
|
||||
}
|
||||
|
||||
// Note: We are not using UINavigationBarAppearance on iOS 13+ atm because of UINavigationBar directly include UISearchBar on their titleView that cause crop issues with UINavigationController pop.
|
||||
// Note: We are not using UINavigationBarAppearance on iOS 13/14 because of UINavigationBar directly including UISearchBar on their titleView that cause crop issues with UINavigationController pop.
|
||||
func applyStyle(onNavigationBar navigationBar: UINavigationBar) {
|
||||
navigationBar.tintColor = self.tintColor
|
||||
navigationBar.titleTextAttributes = [
|
||||
NSAttributedString.Key.foregroundColor: self.textPrimaryColor
|
||||
]
|
||||
navigationBar.barTintColor = self.baseColor
|
||||
navigationBar.shadowImage = UIImage() // Remove bottom shadow
|
||||
|
||||
// The navigation bar needs to be opaque so that its background color is the expected one
|
||||
navigationBar.isTranslucent = false
|
||||
|
||||
// On iOS 15 use UINavigationBarAppearance to fix visual issues with the scrollEdgeAppearance style.
|
||||
if #available(iOS 15.0, *) {
|
||||
let appearance = UINavigationBarAppearance()
|
||||
|
||||
appearance.configureWithOpaqueBackground()
|
||||
appearance.backgroundColor = self.baseColor
|
||||
appearance.shadowColor = nil
|
||||
appearance.titleTextAttributes = [
|
||||
NSAttributedString.Key.foregroundColor: self.textPrimaryColor
|
||||
]
|
||||
|
||||
navigationBar.standardAppearance = appearance
|
||||
navigationBar.scrollEdgeAppearance = appearance
|
||||
} else {
|
||||
navigationBar.titleTextAttributes = [
|
||||
NSAttributedString.Key.foregroundColor: self.textPrimaryColor
|
||||
]
|
||||
navigationBar.barTintColor = self.baseColor
|
||||
navigationBar.shadowImage = UIImage() // Remove bottom shadow
|
||||
|
||||
// The navigation bar needs to be opaque so that its background color is the expected one
|
||||
navigationBar.isTranslucent = false
|
||||
}
|
||||
}
|
||||
|
||||
func applyStyle(onSearchBar searchBar: UISearchBar) {
|
||||
|
|
|
@ -33,6 +33,7 @@ class DefaultTheme: NSObject, Theme {
|
|||
|
||||
var searchBackgroundColor: UIColor = UIColor(rgb: 0xFFFFFF)
|
||||
var searchPlaceholderColor: UIColor = UIColor(rgb: 0x8F97A3)
|
||||
var searchResultHighlightColor: UIColor = UIColor(rgb: 0xFCC639).withAlphaComponent(0.2)
|
||||
|
||||
var headerBackgroundColor: UIColor = UIColor(rgb: 0xF5F7FA)
|
||||
var headerBorderColor: UIColor = UIColor(rgb: 0xE9EDF1)
|
||||
|
@ -100,24 +101,50 @@ class DefaultTheme: NSObject, Theme {
|
|||
|
||||
var shadowColor: UIColor = UIColor(rgb: 0x000000)
|
||||
|
||||
var roomCellIncomingBubbleBackgroundColor: UIColor = UIColor(rgb: 0xE8EDF4)
|
||||
|
||||
var roomCellOutgoingBubbleBackgroundColor: UIColor = UIColor(rgb: 0xE7F8F3)
|
||||
|
||||
func applyStyle(onTabBar tabBar: UITabBar) {
|
||||
tabBar.unselectedItemTintColor = self.tabBarUnselectedItemTintColor
|
||||
tabBar.tintColor = self.tintColor
|
||||
tabBar.barTintColor = self.baseColor
|
||||
tabBar.isTranslucent = false
|
||||
|
||||
// Support standard scrollEdgeAppearance iOS 15 without visual issues.
|
||||
if #available(iOS 15.0, *) {
|
||||
tabBar.isTranslucent = true
|
||||
} else {
|
||||
tabBar.isTranslucent = false
|
||||
}
|
||||
}
|
||||
|
||||
// Note: We are not using UINavigationBarAppearance on iOS 13+ atm because of UINavigationBar directly include UISearchBar on their titleView that cause crop issues with UINavigationController pop.
|
||||
// Note: We are not using UINavigationBarAppearance on iOS 13/14 because of UINavigationBar directly including UISearchBar on their titleView that cause crop issues with UINavigationController pop.
|
||||
func applyStyle(onNavigationBar navigationBar: UINavigationBar) {
|
||||
navigationBar.tintColor = self.tintColor
|
||||
navigationBar.titleTextAttributes = [
|
||||
NSAttributedString.Key.foregroundColor: self.textPrimaryColor
|
||||
]
|
||||
navigationBar.barTintColor = self.baseColor
|
||||
navigationBar.shadowImage = UIImage() // Remove bottom shadow
|
||||
|
||||
// The navigation bar needs to be opaque so that its background color is the expected one
|
||||
navigationBar.isTranslucent = false
|
||||
|
||||
// On iOS 15 use UINavigationBarAppearance to fix visual issues with the scrollEdgeAppearance style.
|
||||
if #available(iOS 15.0, *) {
|
||||
let appearance = UINavigationBarAppearance()
|
||||
|
||||
appearance.configureWithOpaqueBackground()
|
||||
appearance.backgroundColor = baseColor
|
||||
appearance.shadowColor = nil
|
||||
appearance.titleTextAttributes = [
|
||||
NSAttributedString.Key.foregroundColor: textPrimaryColor
|
||||
]
|
||||
|
||||
navigationBar.standardAppearance = appearance
|
||||
navigationBar.scrollEdgeAppearance = appearance
|
||||
} else {
|
||||
navigationBar.titleTextAttributes = [
|
||||
NSAttributedString.Key.foregroundColor: textPrimaryColor
|
||||
]
|
||||
navigationBar.barTintColor = baseColor
|
||||
navigationBar.shadowImage = UIImage() // Remove bottom shadow
|
||||
|
||||
// The navigation bar needs to be opaque so that its background color is the expected one
|
||||
navigationBar.isTranslucent = false
|
||||
}
|
||||
}
|
||||
|
||||
func applyStyle(onSearchBar searchBar: UISearchBar) {
|
||||
|
|
|
@ -155,7 +155,7 @@ class UserSessionsService: NSObject {
|
|||
let isSessionStateValid: Bool
|
||||
|
||||
switch mxSession.state {
|
||||
case .closed, .unknownToken:
|
||||
case .closed:
|
||||
isSessionStateValid = false
|
||||
default:
|
||||
isSessionStateValid = true
|
||||
|
|
|
@ -16,19 +16,20 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
/// Represents the homeserver configuration (usually based on HS Well-Known or hardoced values in the project)
|
||||
/// Represents the homeserver configuration (usually based on HS Well-Known or hardcoded values in the project)
|
||||
@objcMembers
|
||||
final class HomeserverConfiguration: NSObject {
|
||||
|
||||
// Note: Use an object per configuration subject when there is multiple properties related
|
||||
let jitsi: HomeserverJitsiConfiguration
|
||||
let isE2EEByDefaultEnabled: Bool
|
||||
let tileServer: HomeserverTileServerConfiguration
|
||||
|
||||
init(jitsi: HomeserverJitsiConfiguration,
|
||||
isE2EEByDefaultEnabled: Bool) {
|
||||
isE2EEByDefaultEnabled: Bool,
|
||||
tileServer: HomeserverTileServerConfiguration) {
|
||||
self.jitsi = jitsi
|
||||
self.isE2EEByDefaultEnabled = isE2EEByDefaultEnabled
|
||||
|
||||
super.init()
|
||||
self.tileServer = tileServer
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,12 +59,26 @@ final class HomeserverConfigurationBuilder: NSObject {
|
|||
jitsiServerURL = hardcodedJitsiServerURL
|
||||
}
|
||||
|
||||
// Tile server configuration
|
||||
|
||||
let tileServerMapStyleURL: URL
|
||||
if let mapStyleURLString = wellKnown?.tileServer?.mapStyleURLString,
|
||||
let mapStyleURL = URL(string: mapStyleURLString) {
|
||||
tileServerMapStyleURL = mapStyleURL
|
||||
} else {
|
||||
tileServerMapStyleURL = BuildSettings.tileServerMapStyleURL
|
||||
}
|
||||
|
||||
let tileServerConfiguration = HomeserverTileServerConfiguration(mapStyleURL: tileServerMapStyleURL)
|
||||
|
||||
// Create HomeserverConfiguration
|
||||
|
||||
let jitsiConfiguration = HomeserverJitsiConfiguration(serverDomain: jitsiPreferredDomain,
|
||||
serverURL: jitsiServerURL)
|
||||
|
||||
return HomeserverConfiguration(jitsi: jitsiConfiguration, isE2EEByDefaultEnabled: isE2EEByDefaultEnabled)
|
||||
return HomeserverConfiguration(jitsi: jitsiConfiguration,
|
||||
isE2EEByDefaultEnabled: isE2EEByDefaultEnabled,
|
||||
tileServer: tileServerConfiguration)
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
//
|
||||
// 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
|
||||
|
||||
/// `HomeserverTileServerConfiguration` defines tile server configuration to be used by the mapping library
|
||||
@objcMembers
|
||||
final class HomeserverTileServerConfiguration: NSObject {
|
||||
let mapStyleURL: URL
|
||||
|
||||
init(mapStyleURL: URL) {
|
||||
self.mapStyleURL = mapStyleURL
|
||||
}
|
||||
}
|
|
@ -96,7 +96,7 @@ import AnalyticsEvents
|
|||
|
||||
// Catch and log crashes
|
||||
MXLogger.logCrashes(true)
|
||||
MXLogger.setBuildVersion(AppDelegate.theDelegate().build)
|
||||
MXLogger.setBuildVersion(AppInfo.current.buildInfo.readableBuildVersion)
|
||||
}
|
||||
|
||||
/// Use the analytics settings from the supplied session to configure analytics.
|
||||
|
@ -213,6 +213,18 @@ extension Analytics {
|
|||
}
|
||||
}
|
||||
|
||||
/// Track when a user becomes unauthenticated without pressing the `sign out` button.
|
||||
/// - Parameters:
|
||||
/// - softLogout: Wether it was a soft/hard logout that was triggered.
|
||||
/// - refreshTokenAuth: Wether it was either an access-token-based or refresh-token-based auth mechanism enabled.
|
||||
/// - errorCode: The error code as returned by the homeserver that triggered the logout.
|
||||
/// - errorReason: The reason for the error as returned by the homeserver that triggered the logout.
|
||||
func trackAuthUnauthenticatedError(softLogout: Bool, refreshTokenAuth: Bool, errorCode: String, errorReason: String) {
|
||||
let errorCode = AnalyticsEvent.UnauthenticatedError.ErrorCode(rawValue: errorCode) ?? .M_UNKNOWN
|
||||
let event = AnalyticsEvent.UnauthenticatedError(errorCode: errorCode, errorReason: errorReason, refreshTokenAuth: refreshTokenAuth, softLogout: softLogout)
|
||||
client.capture(event)
|
||||
}
|
||||
|
||||
/// Track whether the user accepted or declined the terms to an identity server.
|
||||
/// **Note** This method isn't currently implemented.
|
||||
/// - Parameter accepted: Whether the terms were accepted.
|
||||
|
|
|
@ -1130,7 +1130,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
[[NSNotificationCenter defaultCenter] postNotificationName:AppDelegateUniversalLinkDidChangeNotification object:nil];
|
||||
}
|
||||
|
||||
if ([self handleServerProvionningLink:webURL])
|
||||
if ([self handleServerProvisioningLink:webURL])
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
@ -1252,8 +1252,8 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
{
|
||||
NSString *fragment = universalLinkParameters.fragment;
|
||||
NSURL *universalLinkURL = universalLinkParameters.universalLinkURL;
|
||||
ScreenPresentationParameters *screenPresentationParameters = universalLinkParameters.presentationParameters;
|
||||
BOOL restoreInitialDisplay = screenPresentationParameters.restoreInitialDisplay;
|
||||
ScreenPresentationParameters *presentationParameters = universalLinkParameters.presentationParameters;
|
||||
BOOL restoreInitialDisplay = presentationParameters.restoreInitialDisplay;
|
||||
|
||||
BOOL continueUserActivity = NO;
|
||||
MXKAccountManager *accountManager = [MXKAccountManager sharedManager];
|
||||
|
@ -1355,16 +1355,73 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
|
||||
if (room.summary.roomType == MXRoomTypeSpace)
|
||||
{
|
||||
SpaceNavigationParameters *spaceNavigationParameters = [[SpaceNavigationParameters alloc] initWithRoomId:room.roomId mxSession:account.mxSession presentationParameters:screenPresentationParameters];
|
||||
SpaceNavigationParameters *spaceNavigationParameters = [[SpaceNavigationParameters alloc] initWithRoomId:room.roomId mxSession:account.mxSession presentationParameters:presentationParameters];
|
||||
|
||||
[self showSpaceWithParameters:spaceNavigationParameters];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Open the room page
|
||||
RoomNavigationParameters *roomNavigationParameters = [[RoomNavigationParameters alloc] initWithRoomId:roomId eventId:eventId mxSession:account.mxSession presentationParameters: screenPresentationParameters];
|
||||
|
||||
[self showRoomWithParameters:roomNavigationParameters];
|
||||
if (eventId)
|
||||
{
|
||||
__block MXEvent *event = [account.mxSession.store eventWithEventId:eventId inRoom:roomId];
|
||||
dispatch_group_t eventDispatchGroup = dispatch_group_create();
|
||||
|
||||
if (event == nil)
|
||||
{
|
||||
dispatch_group_enter(eventDispatchGroup);
|
||||
// event doesn't exist in the store
|
||||
[account.mxSession eventWithEventId:eventId
|
||||
inRoom:roomId
|
||||
success:^(MXEvent *eventFromServer) {
|
||||
event = eventFromServer;
|
||||
dispatch_group_leave(eventDispatchGroup);
|
||||
} failure:^(NSError *error) {
|
||||
MXLogError(@"[LegacyAppDelegate] handleUniversalLinkWithParameters: event fetch failed: %@", error);
|
||||
dispatch_group_leave(eventDispatchGroup);
|
||||
}];
|
||||
}
|
||||
|
||||
dispatch_group_notify(eventDispatchGroup, dispatch_get_main_queue(), ^{
|
||||
if (event == nil)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ThreadParameters *threadParameters = nil;
|
||||
if (RiotSettings.shared.enableThreads)
|
||||
{
|
||||
if (event.threadId)
|
||||
{
|
||||
threadParameters = [[ThreadParameters alloc] initWithThreadId:event.threadId
|
||||
stackRoomScreen:NO];
|
||||
}
|
||||
else if ([account.mxSession.threadingService threadWithId:eventId])
|
||||
{
|
||||
threadParameters = [[ThreadParameters alloc] initWithThreadId:eventId
|
||||
stackRoomScreen:NO];
|
||||
}
|
||||
}
|
||||
|
||||
RoomNavigationParameters *parameters = [[RoomNavigationParameters alloc] initWithRoomId:roomId
|
||||
eventId:eventId
|
||||
mxSession:account.mxSession
|
||||
threadParameters:threadParameters
|
||||
presentationParameters:presentationParameters];
|
||||
[self showRoomWithParameters:parameters];
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// open the regular room timeline
|
||||
RoomNavigationParameters *parameters = [[RoomNavigationParameters alloc] initWithRoomId:roomId
|
||||
eventId:eventId
|
||||
mxSession:account.mxSession
|
||||
threadParameters:nil
|
||||
presentationParameters:presentationParameters];
|
||||
|
||||
[self showRoomWithParameters:parameters];
|
||||
}
|
||||
}
|
||||
|
||||
continueUserActivity = YES;
|
||||
|
@ -1412,7 +1469,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
{
|
||||
universalLinkFragmentPendingRoomAlias = @{roomId: roomIdOrAlias};
|
||||
|
||||
UniversalLinkParameters *newParameters = [[UniversalLinkParameters alloc] initWithFragment:newUniversalLinkFragment universalLinkURL:universalLinkURL presentationParameters:screenPresentationParameters];
|
||||
UniversalLinkParameters *newParameters = [[UniversalLinkParameters alloc] initWithFragment:newUniversalLinkFragment universalLinkURL:universalLinkURL presentationParameters:presentationParameters];
|
||||
|
||||
[self handleUniversalLinkWithParameters:newParameters];
|
||||
}
|
||||
|
@ -1471,14 +1528,14 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
roomPreviewData.viaServers = queryParams[@"via"];
|
||||
}
|
||||
|
||||
RoomPreviewNavigationParameters *roomPreviewNavigationParameters = [[RoomPreviewNavigationParameters alloc] initWithPreviewData:roomPreviewData presentationParameters:screenPresentationParameters];
|
||||
RoomPreviewNavigationParameters *roomPreviewNavigationParameters = [[RoomPreviewNavigationParameters alloc] initWithPreviewData:roomPreviewData presentationParameters:presentationParameters];
|
||||
|
||||
[account.mxSession.matrixRestClient roomSummaryWith:roomIdOrAlias via:roomPreviewData.viaServers success:^(MXPublicRoom *room) {
|
||||
if ([room.roomTypeString isEqualToString:MXRoomTypeStringSpace])
|
||||
{
|
||||
[homeViewController stopActivityIndicator];
|
||||
|
||||
SpacePreviewNavigationParameters *spacePreviewNavigationParameters = [[SpacePreviewNavigationParameters alloc] initWithPublicRoom:room mxSession:account.mxSession presentationParameters:screenPresentationParameters];
|
||||
SpacePreviewNavigationParameters *spacePreviewNavigationParameters = [[SpacePreviewNavigationParameters alloc] initWithPublicRoom:room mxSession:account.mxSession presentationParameters:presentationParameters];
|
||||
|
||||
[self showSpacePreviewWithParameters:spacePreviewNavigationParameters];
|
||||
}
|
||||
|
@ -1556,7 +1613,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
|
||||
// Create the contact related to this member
|
||||
MXKContact *contact = [[MXKContact alloc] initMatrixContactWithDisplayName:displayName andMatrixID:userId];
|
||||
[self showContact:contact presentationParameters:screenPresentationParameters];
|
||||
[self showContact:contact presentationParameters:presentationParameters];
|
||||
|
||||
continueUserActivity = YES;
|
||||
}
|
||||
|
@ -1575,7 +1632,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
}
|
||||
|
||||
// Display the group details
|
||||
[self showGroup:group withMatrixSession:account.mxSession presentationParamters:screenPresentationParameters];
|
||||
[self showGroup:group withMatrixSession:account.mxSession presentationParamters:presentationParameters];
|
||||
|
||||
continueUserActivity = YES;
|
||||
}
|
||||
|
@ -1592,7 +1649,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
// Check that 'fragment' has not been cancelled
|
||||
if ([universalLinkFragmentPending isEqualToString:fragment])
|
||||
{
|
||||
MXLogDebug(@"[AppDelegate] Universal link: The user is now logged in. Retry the link");
|
||||
MXLogDebug(@"[AppDelegate] Universal link: The user is now logged in. Retry the link");
|
||||
[self handleUniversalLinkWithParameters:universalLinkParameters];
|
||||
}
|
||||
}];
|
||||
|
@ -1604,7 +1661,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
MXLogDebug(@"[AppDelegate] Universal link with registration parameters");
|
||||
continueUserActivity = YES;
|
||||
|
||||
[_masterTabBarController showAuthenticationScreenWithRegistrationParameters:queryParams];
|
||||
[_masterTabBarController showOnboardingFlowWithRegistrationParameters:queryParams];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1744,33 +1801,36 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
*outQueryParams = queryParams;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)handleServerProvionningLink:(NSURL*)link
|
||||
/**
|
||||
Parse and handle a server provisioning link. Returns `YES` if a provisioning link was detected and handled.
|
||||
@param link A link such as https://mobile.element.io/?hs_url=matrix.example.com&is_url=identity.example.com
|
||||
*/
|
||||
- (BOOL)handleServerProvisioningLink:(NSURL*)link
|
||||
{
|
||||
MXLogDebug(@"[AppDelegate] handleServerProvionningLink: %@", link);
|
||||
MXLogDebug(@"[AppDelegate] handleServerProvisioningLink: %@", link);
|
||||
|
||||
NSString *homeserver, *identityServer;
|
||||
[self parseServerProvionningLink:link homeserver:&homeserver identityServer:&identityServer];
|
||||
[self parseServerProvisioningLink:link homeserver:&homeserver identityServer:&identityServer];
|
||||
|
||||
if (homeserver)
|
||||
{
|
||||
if ([MXKAccountManager sharedManager].activeAccounts.count)
|
||||
{
|
||||
[self displayServerProvionningLinkBuyAlreadyLoggedInAlertWithCompletion:^(BOOL logout) {
|
||||
[self displayServerProvisioningLinkBuyAlreadyLoggedInAlertWithCompletion:^(BOOL logout) {
|
||||
|
||||
MXLogDebug(@"[AppDelegate] handleServerProvionningLink: logoutWithConfirmation: logout: %@", @(logout));
|
||||
MXLogDebug(@"[AppDelegate] handleServerProvisioningLink: logoutWithConfirmation: logout: %@", @(logout));
|
||||
if (logout)
|
||||
{
|
||||
[self logoutWithConfirmation:NO completion:^(BOOL isLoggedOut) {
|
||||
[self handleServerProvionningLink:link];
|
||||
[self handleServerProvisioningLink:link];
|
||||
}];
|
||||
}
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
[_masterTabBarController showAuthenticationScreen];
|
||||
[_masterTabBarController.authViewController showCustomHomeserver:homeserver andIdentityServer:identityServer];
|
||||
[_masterTabBarController showOnboardingFlow];
|
||||
[_masterTabBarController.onboardingCoordinatorBridgePresenter updateHomeserver:homeserver andIdentityServer:identityServer];
|
||||
}
|
||||
|
||||
return YES;
|
||||
|
@ -1779,7 +1839,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
return NO;
|
||||
}
|
||||
|
||||
- (void)parseServerProvionningLink:(NSURL*)link homeserver:(NSString**)homeserver identityServer:(NSString**)identityServer
|
||||
- (void)parseServerProvisioningLink:(NSURL*)link homeserver:(NSString**)homeserver identityServer:(NSString**)identityServer
|
||||
{
|
||||
if ([link.path isEqualToString:@"/"])
|
||||
{
|
||||
|
@ -1799,14 +1859,14 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
}
|
||||
else
|
||||
{
|
||||
MXLogDebug(@"[AppDelegate] parseServerProvionningLink: Error: Unknown path: %@", link.path);
|
||||
MXLogDebug(@"[AppDelegate] parseServerProvisioningLink: Error: Unknown path: %@", link.path);
|
||||
}
|
||||
|
||||
|
||||
MXLogDebug(@"[AppDelegate] parseServerProvionningLink: homeserver: %@ - identityServer: %@", *homeserver, *identityServer);
|
||||
MXLogDebug(@"[AppDelegate] parseServerProvisioningLink: homeserver: %@ - identityServer: %@", *homeserver, *identityServer);
|
||||
}
|
||||
|
||||
- (void)displayServerProvionningLinkBuyAlreadyLoggedInAlertWithCompletion:(void (^)(BOOL logout))completion
|
||||
- (void)displayServerProvisioningLinkBuyAlreadyLoggedInAlertWithCompletion:(void (^)(BOOL logout))completion
|
||||
{
|
||||
// Ask confirmation
|
||||
self.logoutConfirmation = [UIAlertController alertControllerWithTitle:[VectorL10n errorUserAlreadyLoggedIn] message:nil preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
@ -1965,7 +2025,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
[self removeMatrixSession:account.mxSession];
|
||||
|
||||
// Return to authentication screen
|
||||
[self.masterTabBarController showAuthenticationScreenAfterSoftLogout:account.mxCredentials];
|
||||
[self.masterTabBarController showSoftLogoutOnboardingFlowWithCredentials:account.mxCredentials];
|
||||
}];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserverForName:kMXSessionIgnoredUsersDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull notif) {
|
||||
|
@ -2259,7 +2319,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
}
|
||||
|
||||
// Return to authentication screen
|
||||
[_masterTabBarController showAuthenticationScreen];
|
||||
[_masterTabBarController showOnboardingFlow];
|
||||
|
||||
// Note: Keep App settings
|
||||
// But enforce usage of member lazy loading
|
||||
|
@ -2298,7 +2358,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
{
|
||||
BOOL isLaunching = NO;
|
||||
|
||||
if (_masterTabBarController.authenticationInProgress)
|
||||
if (_masterTabBarController.isOnboardingInProgress)
|
||||
{
|
||||
MXLogDebug(@"[AppDelegate] handleAppState: Authentication still in progress");
|
||||
|
||||
|
@ -2893,7 +2953,10 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
ScreenPresentationParameters *presentationParameters = [[ScreenPresentationParameters alloc] initWithRestoreInitialDisplay:YES];
|
||||
|
||||
RoomNavigationParameters *parameters = [[RoomNavigationParameters alloc] initWithRoomId:roomId
|
||||
eventId:eventId mxSession:mxSession presentationParameters:presentationParameters];
|
||||
eventId:eventId
|
||||
mxSession:mxSession
|
||||
threadParameters:nil
|
||||
presentationParameters:presentationParameters];
|
||||
|
||||
[self showRoomWithParameters:parameters];
|
||||
}
|
||||
|
@ -3415,7 +3478,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
@"party_id": mxSession.myDeviceId
|
||||
};
|
||||
|
||||
[mxSession.matrixRestClient sendEventToRoom:event.roomId eventType:kMXEventTypeStringCallReject content:content txnId:nil success:nil failure:^(NSError *error) {
|
||||
[mxSession.matrixRestClient sendEventToRoom:event.roomId threadId:nil eventType:kMXEventTypeStringCallReject content:content txnId:nil success:nil failure:^(NSError *error) {
|
||||
MXLogDebug(@"[AppDelegate] enableNoVoIPOnMatrixSession: ERROR: Cannot send m.call.reject event.");
|
||||
}];
|
||||
|
||||
|
@ -3854,7 +3917,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
return;
|
||||
}
|
||||
|
||||
if (_masterTabBarController.authenticationInProgress)
|
||||
if (_masterTabBarController.isOnboardingInProgress)
|
||||
{
|
||||
MXLogDebug(@"[AppDelegate][KeyVerification] keyVerificationNewRequestNotification: Postpone requests during the authentication process");
|
||||
|
||||
|
@ -4496,15 +4559,15 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
|
||||
- (BOOL)continueSSOLoginWithToken:(NSString*)loginToken txnId:(NSString*)txnId
|
||||
{
|
||||
AuthenticationViewController *authVC = self.masterTabBarController.authViewController;
|
||||
OnboardingCoordinatorBridgePresenter *bridgePresenter = self.masterTabBarController.onboardingCoordinatorBridgePresenter;
|
||||
|
||||
if (!authVC)
|
||||
if (!bridgePresenter)
|
||||
{
|
||||
MXLogDebug(@"[AppDelegate] Fail to continue SSO login");
|
||||
return NO;
|
||||
}
|
||||
|
||||
return [authVC continueSSOLoginWithToken:loginToken txnId:txnId];
|
||||
return [bridgePresenter continueSSOLoginWithToken:loginToken transactionID:txnId];
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
|
|
|
@ -16,6 +16,24 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
@objcMembers
|
||||
class ThreadParameters: NSObject {
|
||||
|
||||
/// If not nil, the thread will be opened on this room
|
||||
let threadId: String
|
||||
|
||||
/// If true, related room screen will be stacked in the navigation stack
|
||||
let stackRoomScreen: Bool
|
||||
|
||||
init(threadId: String,
|
||||
stackRoomScreen: Bool) {
|
||||
self.threadId = threadId
|
||||
self.stackRoomScreen = stackRoomScreen
|
||||
super.init()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Navigation parameters to display a room with a provided identifier in a specific matrix session.
|
||||
@objcMembers
|
||||
class RoomNavigationParameters: NSObject {
|
||||
|
@ -31,6 +49,9 @@ class RoomNavigationParameters: NSObject {
|
|||
/// The Matrix session in which the room should be available.
|
||||
let mxSession: MXSession
|
||||
|
||||
/// Navigation parameters for a thread
|
||||
let threadParameters: ThreadParameters?
|
||||
|
||||
/// Screen presentation parameters.
|
||||
let presentationParameters: ScreenPresentationParameters
|
||||
|
||||
|
@ -39,10 +60,12 @@ class RoomNavigationParameters: NSObject {
|
|||
init(roomId: String,
|
||||
eventId: String?,
|
||||
mxSession: MXSession,
|
||||
threadParameters: ThreadParameters?,
|
||||
presentationParameters: ScreenPresentationParameters) {
|
||||
self.roomId = roomId
|
||||
self.eventId = eventId
|
||||
self.mxSession = mxSession
|
||||
self.threadParameters = threadParameters
|
||||
self.presentationParameters = presentationParameters
|
||||
|
||||
super.init()
|
||||
|
|
|
@ -34,6 +34,7 @@ class RoomPreviewNavigationParameters: RoomNavigationParameters {
|
|||
super.init(roomId: previewData.roomId,
|
||||
eventId: previewData.eventId,
|
||||
mxSession: previewData.mxSession,
|
||||
threadParameters: nil,
|
||||
presentationParameters: presentationParameters)
|
||||
}
|
||||
}
|
||||
|
|
87
Riot/Modules/Authentication/AuthenticationCoordinator.swift
Normal file
|
@ -0,0 +1,87 @@
|
|||
// File created from ScreenTemplate
|
||||
// $ createScreen.sh Onboarding Authentication
|
||||
/*
|
||||
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 UIKit
|
||||
|
||||
/// A coordinator that handles authentication, verification and setting a PIN.
|
||||
final class AuthenticationCoordinator: NSObject, AuthenticationCoordinatorProtocol {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let authenticationViewController: AuthenticationViewController
|
||||
|
||||
// MARK: Public
|
||||
|
||||
// Must be used only internally
|
||||
var childCoordinators: [Coordinator] = []
|
||||
var completion: (() -> Void)?
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
override init() {
|
||||
let authenticationViewController = AuthenticationViewController()
|
||||
self.authenticationViewController = authenticationViewController
|
||||
|
||||
// Preload the view as this can a second and lock up the UI at presentation.
|
||||
// The coordinator is initialised early in the onboarding flow to take advantage of this.
|
||||
authenticationViewController.loadViewIfNeeded()
|
||||
|
||||
super.init()
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
func start() {
|
||||
// Listen to the end of the authentication flow
|
||||
authenticationViewController.authVCDelegate = self
|
||||
}
|
||||
|
||||
func toPresentable() -> UIViewController {
|
||||
return self.authenticationViewController
|
||||
}
|
||||
|
||||
func update(authenticationType: MXKAuthenticationType) {
|
||||
authenticationViewController.authType = authenticationType
|
||||
}
|
||||
|
||||
func update(externalRegistrationParameters: [AnyHashable: Any]) {
|
||||
authenticationViewController.externalRegistrationParameters = externalRegistrationParameters
|
||||
}
|
||||
|
||||
func update(softLogoutCredentials: MXCredentials) {
|
||||
authenticationViewController.softLogoutCredentials = softLogoutCredentials
|
||||
}
|
||||
|
||||
func updateHomeserver(_ homeserver: String?, andIdentityServer identityServer: String?) {
|
||||
authenticationViewController.showCustomHomeserver(homeserver, andIdentityServer: identityServer)
|
||||
}
|
||||
|
||||
func continueSSOLogin(withToken loginToken: String, transactionID: String) -> Bool {
|
||||
authenticationViewController.continueSSOLogin(withToken: loginToken, txnId: transactionID)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - AuthenticationViewControllerDelegate
|
||||
extension AuthenticationCoordinator: AuthenticationViewControllerDelegate {
|
||||
func authenticationViewControllerDidDismiss(_ authenticationViewController: AuthenticationViewController!) {
|
||||
completion?()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
// File created from ScreenTemplate
|
||||
// $ createScreen.sh Onboarding Authentication
|
||||
/*
|
||||
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
|
||||
|
||||
/// `AuthenticationCoordinatorProtocol` is a protocol describing a Coordinator that handle's the authentication navigation flow.
|
||||
protocol AuthenticationCoordinatorProtocol: Coordinator, Presentable {
|
||||
var completion: (() -> Void)? { get set }
|
||||
|
||||
/// Update the screen to display registration or login.
|
||||
func update(authenticationType: MXKAuthenticationType)
|
||||
|
||||
/// Force a registration process based on a predefined set of parameters from a server provisioning link.
|
||||
/// For more information see `AuthenticationViewController.externalRegistrationParameters`.
|
||||
func update(externalRegistrationParameters: [AnyHashable: Any])
|
||||
|
||||
/// Update the screen to use any credentials to use after a soft logout has taken place.
|
||||
func update(softLogoutCredentials: MXCredentials)
|
||||
|
||||
/// Set up the authentication screen with the specified homeserver and/or identity server.
|
||||
func updateHomeserver(_ homeserver: String?, andIdentityServer identityServer: String?)
|
||||
|
||||
/// When SSO login succeeded, when SFSafariViewController is used, continue login with success parameters.
|
||||
func continueSSOLogin(withToken loginToken: String, transactionID: String) -> Bool
|
||||
}
|
|
@ -26,13 +26,6 @@
|
|||
// MXKAuthenticationViewController has already a `delegate` member
|
||||
@property (nonatomic, weak) id<AuthenticationViewControllerDelegate> authVCDelegate;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIView *navigationBackView;
|
||||
@property (weak, nonatomic) IBOutlet UINavigationBar *navigationBar;
|
||||
@property (weak, nonatomic) IBOutlet UIView *navigationBarSeparatorView;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UINavigationItem *mainNavigationItem;
|
||||
@property (weak, nonatomic) IBOutlet UIBarButtonItem *rightBarButtonItem;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIView *optionsContainer;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIButton *skipButton;
|
||||
|
|
|
@ -126,8 +126,11 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
|
|||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
self.mainNavigationItem.title = nil;
|
||||
self.rightBarButtonItem.title = [VectorL10n authRegister];
|
||||
self.navigationItem.title = nil;
|
||||
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:VectorL10n.authRegister
|
||||
style:UIBarButtonItemStylePlain
|
||||
target:self
|
||||
action:@selector(onButtonPressed:)];
|
||||
|
||||
self.defaultHomeServerUrl = RiotSettings.shared.homeserverUrlString;
|
||||
|
||||
|
@ -152,8 +155,8 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
|
|||
|
||||
if (!BuildSettings.authScreenShowRegister)
|
||||
{
|
||||
self.rightBarButtonItem.enabled = NO;
|
||||
self.rightBarButtonItem.title = nil;
|
||||
self.navigationItem.rightBarButtonItem.enabled = NO;
|
||||
self.navigationItem.rightBarButtonItem.title = nil;
|
||||
}
|
||||
self.serverOptionsContainer.hidden = !BuildSettings.authScreenShowCustomServerOptions;
|
||||
|
||||
|
@ -211,16 +214,8 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
|
|||
|
||||
- (void)userInterfaceThemeDidChange
|
||||
{
|
||||
self.navigationBackView.backgroundColor = ThemeService.shared.theme.baseColor;
|
||||
[ThemeService.shared.theme applyStyleOnNavigationBar:self.navigationBar];
|
||||
self.navigationBarSeparatorView.backgroundColor = ThemeService.shared.theme.lineBreakColor;
|
||||
|
||||
// This view controller is not part of a navigation controller
|
||||
// so that applyStyleOnNavigationBar does not fully work.
|
||||
// In order to have the right status bar color, use the expected status bar color
|
||||
// as the main view background color.
|
||||
// Hopefully, subviews define their own background color with `theme.backgroundColor`,
|
||||
// which makes all work together.
|
||||
[ThemeService.shared.theme applyStyleOnNavigationBar:self.navigationController.navigationBar];
|
||||
|
||||
self.view.backgroundColor = ThemeService.shared.theme.backgroundColor;
|
||||
|
||||
self.authenticationScrollView.backgroundColor = ThemeService.shared.theme.backgroundColor;
|
||||
|
@ -311,6 +306,7 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
|
|||
[super viewWillAppear:animated];
|
||||
|
||||
[_keyboardAvoider startAvoiding];
|
||||
[self.navigationController setNavigationBarHidden:NO animated:YES];
|
||||
}
|
||||
|
||||
- (void)viewDidAppear:(BOOL)animated
|
||||
|
@ -337,7 +333,7 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
|
|||
didCheckFalseAuthScreenDisplay = YES;
|
||||
|
||||
MXLogDebug(@"[AuthenticationVC] viewDidAppear: Checking false logout");
|
||||
[[MXKAccountManager sharedManager] forceReloadAccounts];
|
||||
[MXKAccountManager sharedManagerWithReload: YES];
|
||||
if ([MXKAccountManager sharedManager].activeAccounts.count)
|
||||
{
|
||||
// For now, we do not have better solution than forcing the user to restart the app
|
||||
|
@ -479,8 +475,8 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
|
|||
{
|
||||
BOOL hideAuthInputView = NO;
|
||||
|
||||
// Hide input view when there is only social login actions to present
|
||||
if ((self.authType == MXKAuthenticationTypeLogin || self.authType == MXKAuthenticationTypeRegister)
|
||||
// Hide input view when there is only social login actions to present at login
|
||||
if ((self.authType == MXKAuthenticationTypeLogin)
|
||||
&& self.currentLoginSSOFlow
|
||||
&& !self.isAuthSessionContainsPasswordFlow
|
||||
&& BuildSettings.authScreenShowSocialLoginSection)
|
||||
|
@ -488,6 +484,9 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
|
|||
hideAuthInputView = YES;
|
||||
}
|
||||
|
||||
// Note: Registration will hide the input view in onFailureDuringMXOperation
|
||||
// if registration has been disabled.
|
||||
|
||||
self.authInputsView.hidden = hideAuthInputView;
|
||||
}
|
||||
|
||||
|
@ -496,7 +495,7 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
|
|||
super.userInteractionEnabled = userInteractionEnabled;
|
||||
|
||||
// Reset
|
||||
self.rightBarButtonItem.enabled = YES;
|
||||
self.navigationItem.rightBarButtonItem.enabled = YES;
|
||||
|
||||
// Show/Hide server options
|
||||
if (_optionsContainer.hidden == userInteractionEnabled)
|
||||
|
@ -510,10 +509,10 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
|
|||
if (!userInteractionEnabled)
|
||||
{
|
||||
// The right bar button is used to cancel the running request.
|
||||
self.rightBarButtonItem.title = [VectorL10n cancel];
|
||||
self.navigationItem.rightBarButtonItem.title = [VectorL10n cancel];
|
||||
|
||||
// Remove the potential back button.
|
||||
self.mainNavigationItem.leftBarButtonItem = nil;
|
||||
self.navigationItem.leftBarButtonItem = nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -530,18 +529,18 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
|
|||
&& !self.softLogoutCredentials
|
||||
&& BuildSettings.authScreenShowRegister)
|
||||
{
|
||||
self.rightBarButtonItem.title = [VectorL10n authRegister];
|
||||
self.navigationItem.rightBarButtonItem.title = [VectorL10n authRegister];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Disable register on SSO
|
||||
self.rightBarButtonItem.enabled = NO;
|
||||
self.rightBarButtonItem.title = nil;
|
||||
self.navigationItem.rightBarButtonItem.enabled = NO;
|
||||
self.navigationItem.rightBarButtonItem.title = nil;
|
||||
}
|
||||
}
|
||||
else if (self.authType == MXKAuthenticationTypeRegister)
|
||||
{
|
||||
self.rightBarButtonItem.title = [VectorL10n authLogin];
|
||||
self.navigationItem.rightBarButtonItem.title = [VectorL10n authLogin];
|
||||
|
||||
// Restore the back button
|
||||
if (authInputsview)
|
||||
|
@ -552,7 +551,7 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
|
|||
else if (self.authType == MXKAuthenticationTypeForgotPassword)
|
||||
{
|
||||
// The right bar button is used to return to login.
|
||||
self.rightBarButtonItem.title = [VectorL10n cancel];
|
||||
self.navigationItem.rightBarButtonItem.title = [VectorL10n cancel];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -562,14 +561,7 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
|
|||
KeyVerificationCoordinatorBridgePresenter *keyVerificationCoordinatorBridgePresenter = [[KeyVerificationCoordinatorBridgePresenter alloc] initWithSession:session];
|
||||
keyVerificationCoordinatorBridgePresenter.delegate = self;
|
||||
|
||||
if (self.navigationController)
|
||||
{
|
||||
[keyVerificationCoordinatorBridgePresenter pushCompleteSecurityFrom:self.navigationController isNewSignIn:YES animated:YES];
|
||||
}
|
||||
else
|
||||
{
|
||||
[keyVerificationCoordinatorBridgePresenter presentCompleteSecurityFrom:self isNewSignIn:YES animated:YES];
|
||||
}
|
||||
[keyVerificationCoordinatorBridgePresenter presentCompleteSecurityFrom:self isNewSignIn:YES animated:YES];
|
||||
|
||||
self.keyVerificationCoordinatorBridgePresenter = keyVerificationCoordinatorBridgePresenter;
|
||||
}
|
||||
|
@ -579,17 +571,8 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
|
|||
self.userInteractionEnabled = YES;
|
||||
[self.authenticationActivityIndicator stopAnimating];
|
||||
|
||||
// Remove auth view controller on successful login
|
||||
if (self.navigationController)
|
||||
{
|
||||
// Pop the view controller
|
||||
[self.navigationController popViewControllerAnimated:YES];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Dismiss on successful login
|
||||
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
// Dismiss (key verification) on successful login
|
||||
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
|
||||
|
||||
if (self.authVCDelegate)
|
||||
{
|
||||
|
@ -607,7 +590,7 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
|
|||
[self loginWithToken:loginToken];
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
MXLogDebug(@"[AuthenticationVC] Fail to continue SSO login");
|
||||
return NO;
|
||||
}
|
||||
|
@ -685,8 +668,8 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
|
|||
|
||||
// Customise the screen for soft logout
|
||||
self.customServersTickButton.hidden = YES;
|
||||
self.rightBarButtonItem.title = nil;
|
||||
self.mainNavigationItem.title = [VectorL10n authSoftlogoutSignedOut];
|
||||
self.navigationItem.rightBarButtonItem.title = nil;
|
||||
self.navigationItem.title = [VectorL10n authSoftlogoutSignedOut];
|
||||
|
||||
[self showSoftLogoutClearDataContainer];
|
||||
}
|
||||
|
@ -830,14 +813,21 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
|
|||
}
|
||||
}
|
||||
|
||||
- (void)handleAuthenticationSession:(MXAuthenticationSession *)authSession
|
||||
- (void)refreshAuthenticationSession
|
||||
{
|
||||
// Hide the social login buttons while the session refreshes
|
||||
[self hideSocialLoginView];
|
||||
[super refreshAuthenticationSession];
|
||||
}
|
||||
|
||||
- (void)handleAuthenticationSession:(MXAuthenticationSession *)authSession withFallbackSSOFlow:(MXLoginSSOFlow *)fallbackSSOFlow
|
||||
{
|
||||
// Make some cleaning from the server response according to what the app supports
|
||||
authSession = [self handleSupportedFlowsInAuthenticationSession:authSession];
|
||||
|
||||
[super handleAuthenticationSession:authSession];
|
||||
[super handleAuthenticationSession:authSession withFallbackSSOFlow:fallbackSSOFlow];
|
||||
|
||||
self.currentLoginSSOFlow = [self logginSSOFlowWithProvidersFromFlows:authSession.flows];
|
||||
self.currentLoginSSOFlow = [self loginSSOFlowWithProvidersFromFlows:authSession.flows] ?: fallbackSSOFlow;
|
||||
|
||||
[self updateAuthInputViewVisibility];
|
||||
[self updateSocialLoginViewVisibility];
|
||||
|
@ -893,27 +883,6 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
|
|||
return NO;
|
||||
}
|
||||
|
||||
- (MXLoginSSOFlow*)logginSSOFlowWithProvidersFromFlows:(NSArray<MXLoginFlow*>*)loginFlows
|
||||
{
|
||||
MXLoginSSOFlow *ssoFlowWithProviders;
|
||||
|
||||
for (MXLoginFlow *loginFlow in loginFlows)
|
||||
{
|
||||
if ([loginFlow isKindOfClass:MXLoginSSOFlow.class])
|
||||
{
|
||||
MXLoginSSOFlow *ssoFlow = (MXLoginSSOFlow *)loginFlow;
|
||||
|
||||
if (ssoFlow.identityProviders.count)
|
||||
{
|
||||
ssoFlowWithProviders = ssoFlow;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ssoFlowWithProviders;
|
||||
}
|
||||
|
||||
- (IBAction)onButtonPressed:(id)sender
|
||||
{
|
||||
if (sender == self.customServersTickButton)
|
||||
|
@ -938,7 +907,7 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
|
|||
self.authType = MXKAuthenticationTypeForgotPassword;
|
||||
}
|
||||
}
|
||||
else if (sender == self.rightBarButtonItem)
|
||||
else if (sender == self.navigationItem.rightBarButtonItem)
|
||||
{
|
||||
// Check whether a request is in progress
|
||||
if (!self.userInteractionEnabled)
|
||||
|
@ -949,15 +918,15 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
|
|||
else if (self.authType == MXKAuthenticationTypeLogin)
|
||||
{
|
||||
self.authType = MXKAuthenticationTypeRegister;
|
||||
self.rightBarButtonItem.title = [VectorL10n authLogin];
|
||||
self.navigationItem.rightBarButtonItem.title = [VectorL10n authLogin];
|
||||
}
|
||||
else
|
||||
{
|
||||
self.authType = MXKAuthenticationTypeLogin;
|
||||
self.rightBarButtonItem.title = [VectorL10n authRegister];
|
||||
self.navigationItem.rightBarButtonItem.title = [VectorL10n authRegister];
|
||||
}
|
||||
}
|
||||
else if (sender == self.mainNavigationItem.leftBarButtonItem)
|
||||
else if (sender == self.navigationItem.leftBarButtonItem)
|
||||
{
|
||||
if ([self.authInputsView isKindOfClass:AuthInputsView.class])
|
||||
{
|
||||
|
@ -1185,15 +1154,18 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
|
|||
[self.submitButton setTitle:[VectorL10n authRegister] forState:UIControlStateNormal];
|
||||
[self.submitButton setTitle:[VectorL10n authRegister] forState:UIControlStateHighlighted];
|
||||
|
||||
self.mainNavigationItem.leftBarButtonItem = nil;
|
||||
self.navigationItem.leftBarButtonItem = nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
[self.submitButton setTitle:[VectorL10n authSubmit] forState:UIControlStateNormal];
|
||||
[self.submitButton setTitle:[VectorL10n authSubmit] forState:UIControlStateHighlighted];
|
||||
|
||||
UIBarButtonItem *leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"back_icon"] style:UIBarButtonItemStylePlain target:self action:@selector(onButtonPressed:)];
|
||||
self.mainNavigationItem.leftBarButtonItem = leftBarButtonItem;
|
||||
UIBarButtonItem *leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:VectorL10n.back
|
||||
style:UIBarButtonItemStylePlain
|
||||
target:self
|
||||
action:@selector(onButtonPressed:)];
|
||||
self.navigationItem.leftBarButtonItem = leftBarButtonItem;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,14 +34,9 @@
|
|||
<outlet property="identityServerLabel" destination="5CT-Ht-Z3v" id="9h4-6J-n3X"/>
|
||||
<outlet property="identityServerSeparator" destination="t08-ua-0mJ" id="Sbf-ps-zeK"/>
|
||||
<outlet property="identityServerTextField" destination="PZC-Hd-Q6a" id="vKg-sd-dzJ"/>
|
||||
<outlet property="mainNavigationItem" destination="rj9-wP-8QS" id="yNN-Dg-4Yw"/>
|
||||
<outlet property="navigationBackView" destination="6q5-bI-9WO" id="edE-wy-DYw"/>
|
||||
<outlet property="navigationBar" destination="k7D-Gy-yBR" id="6Uc-3Q-3dO"/>
|
||||
<outlet property="navigationBarSeparatorView" destination="izX-ya-hXh" id="gY5-Oj-nSl"/>
|
||||
<outlet property="noFlowLabel" destination="54b-4O-ip9" id="f18-H1-cQm"/>
|
||||
<outlet property="optionsContainer" destination="Gg0-TE-OGb" id="RWa-Pl-eaL"/>
|
||||
<outlet property="retryButton" destination="wIH-Kd-r7q" id="42j-Ad-zVS"/>
|
||||
<outlet property="rightBarButtonItem" destination="Kwt-KN-aVL" id="Y3F-wA-tf8"/>
|
||||
<outlet property="serverOptionsContainer" destination="FIn-2w-e6H" id="Z0e-NN-3LY"/>
|
||||
<outlet property="skipButton" destination="wEJ-AF-rdH" id="smu-MS-2IY"/>
|
||||
<outlet property="socialLoginContainerView" destination="TjK-XL-dQS" id="Rte-h1-blp"/>
|
||||
|
@ -59,35 +54,8 @@
|
|||
<rect key="frame" x="0.0" y="0.0" width="375" height="812"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="6q5-bI-9WO">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="88"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</view>
|
||||
<navigationBar contentMode="scaleToFill" translucent="NO" translatesAutoresizingMaskIntoConstraints="NO" id="k7D-Gy-yBR">
|
||||
<rect key="frame" x="0.0" y="44" width="375" height="44"/>
|
||||
<color key="barTintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<items>
|
||||
<navigationItem title="Riot" id="rj9-wP-8QS">
|
||||
<barButtonItem key="rightBarButtonItem" title="Register" id="Kwt-KN-aVL">
|
||||
<connections>
|
||||
<action selector="onButtonPressed:" destination="-1" id="nwk-aV-eBO"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
</items>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="accessibilityIdentifier" value="AuthenticationVCNavigationBar"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</navigationBar>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="izX-ya-hXh">
|
||||
<rect key="frame" x="0.0" y="88" width="375" height="1"/>
|
||||
<color key="backgroundColor" red="0.66666666666666663" green="0.66666666666666663" blue="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="1" id="ZiW-uP-cgo"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" keyboardDismissMode="interactive" translatesAutoresizingMaskIntoConstraints="NO" id="OHV-KQ-Ww0">
|
||||
<rect key="frame" x="0.0" y="89" width="375" height="723"/>
|
||||
<rect key="frame" x="0.0" y="44" width="375" height="768"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="rhx-dD-4EJ" userLabel="Content View">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="485"/>
|
||||
|
@ -129,7 +97,7 @@
|
|||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="wIH-Kd-r7q" userLabel="retryButton">
|
||||
<rect key="frame" x="165" y="46.666666666666686" width="45" height="30"/>
|
||||
<rect key="frame" x="165" y="46.666666666666657" width="45" height="30"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="AuthenticationVCRetryButton"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="30" id="WtO-NT-ei8"/>
|
||||
|
@ -513,24 +481,14 @@ Clear it if you're finished using this device, or want to sign in to another acc
|
|||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="AuthenticationVCView"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="k7D-Gy-yBR" secondAttribute="trailing" id="5VB-NY-mpo"/>
|
||||
<constraint firstAttribute="trailing" secondItem="izX-ya-hXh" secondAttribute="trailing" id="8Ae-F5-jr2"/>
|
||||
<constraint firstItem="k7D-Gy-yBR" firstAttribute="top" secondItem="3h8-75-kcp" secondAttribute="top" id="8Fw-By-vab"/>
|
||||
<constraint firstItem="OHV-KQ-Ww0" firstAttribute="top" secondItem="izX-ya-hXh" secondAttribute="bottom" id="BJv-Y7-VKe"/>
|
||||
<constraint firstItem="OHV-KQ-Ww0" firstAttribute="top" secondItem="3h8-75-kcp" secondAttribute="top" id="1ep-Co-Ook"/>
|
||||
<constraint firstItem="q1e-Wg-6t7" firstAttribute="trailing" secondItem="3h8-75-kcp" secondAttribute="trailing" id="Dcr-ff-OGs"/>
|
||||
<constraint firstItem="q1e-Wg-6t7" firstAttribute="leading" secondItem="3h8-75-kcp" secondAttribute="leading" id="HTS-LJ-eiv"/>
|
||||
<constraint firstItem="OHV-KQ-Ww0" firstAttribute="leading" secondItem="3h8-75-kcp" secondAttribute="leading" id="Lat-3d-ufd"/>
|
||||
<constraint firstItem="izX-ya-hXh" firstAttribute="leading" secondItem="5rn-KE-plm" secondAttribute="leading" id="MrU-gL-vGG"/>
|
||||
<constraint firstAttribute="bottom" secondItem="OHV-KQ-Ww0" secondAttribute="bottom" id="Q6p-jM-1nj"/>
|
||||
<constraint firstItem="6q5-bI-9WO" firstAttribute="leading" secondItem="5rn-KE-plm" secondAttribute="leading" id="SQT-Gz-hp5"/>
|
||||
<constraint firstItem="6q5-bI-9WO" firstAttribute="top" secondItem="5rn-KE-plm" secondAttribute="top" id="TeU-yo-Lbi"/>
|
||||
<constraint firstItem="OHV-KQ-Ww0" firstAttribute="trailing" secondItem="3h8-75-kcp" secondAttribute="trailing" id="cIg-kU-obq"/>
|
||||
<constraint firstAttribute="trailing" secondItem="6q5-bI-9WO" secondAttribute="trailing" id="eZp-eW-PG2"/>
|
||||
<constraint firstItem="k7D-Gy-yBR" firstAttribute="bottom" secondItem="6q5-bI-9WO" secondAttribute="bottom" id="pmI-Og-NJA"/>
|
||||
<constraint firstItem="q1e-Wg-6t7" firstAttribute="bottom" secondItem="3h8-75-kcp" secondAttribute="bottom" id="qqV-Kd-Qs1"/>
|
||||
<constraint firstItem="q1e-Wg-6t7" firstAttribute="top" secondItem="3h8-75-kcp" secondAttribute="top" id="tSe-Uf-qYh"/>
|
||||
<constraint firstItem="izX-ya-hXh" firstAttribute="top" secondItem="k7D-Gy-yBR" secondAttribute="bottom" id="y2h-1T-TZ4"/>
|
||||
<constraint firstItem="k7D-Gy-yBR" firstAttribute="leading" secondItem="5rn-KE-plm" secondAttribute="leading" id="z6D-6L-5Ud"/>
|
||||
</constraints>
|
||||
<point key="canvasLocation" x="138.40000000000001" y="153.69458128078819"/>
|
||||
</view>
|
||||
|
|
|
@ -645,8 +645,8 @@ CallAudioRouteMenuViewDelegate>
|
|||
{
|
||||
CallTransferMainViewController *controller = [CallTransferMainViewController instantiateWithSession:self.mainSession ignoredUserIds:@[self.peer.userId]];
|
||||
controller.delegate = self;
|
||||
|
||||
UINavigationController *navController = [[RiotNavigationController alloc] initWithRootViewController:controller];
|
||||
[self.mxCall hold:YES];
|
||||
[self presentViewController:navController animated:YES completion:nil];
|
||||
}
|
||||
|
||||
|
@ -732,6 +732,7 @@ CallAudioRouteMenuViewDelegate>
|
|||
|
||||
- (void)callTransferMainViewControllerDidCancel:(CallTransferMainViewController *)viewController
|
||||
{
|
||||
[self.mxCall hold:NO];
|
||||
[viewController dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
|
||||
|
|
|
@ -128,9 +128,11 @@ class AvatarView: UIView, Themable {
|
|||
previewImage: defaultAvatarImage,
|
||||
mediaManager: viewData.mediaManager)
|
||||
avatarImageView.contentMode = .scaleAspectFill
|
||||
avatarImageView.imageView?.contentMode = .scaleAspectFill
|
||||
} else {
|
||||
avatarImageView.image = defaultAvatarImage
|
||||
avatarImageView.contentMode = defaultAvatarImageContentMode
|
||||
avatarImageView.imageView?.contentMode = defaultAvatarImageContentMode
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,29 +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 UIKit
|
||||
|
||||
/// UICollectionViewFlowLayout with right align behavior
|
||||
class CollectionViewRightAlignFlowLayout: UICollectionViewFlowLayout {
|
||||
|
||||
override var flipsHorizontallyInOppositeLayoutDirection: Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
override var developmentLayoutDirection: UIUserInterfaceLayoutDirection {
|
||||
return UIUserInterfaceLayoutDirection.rightToLeft
|
||||
}
|
||||
}
|