mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-10-31 08:15:24 +00:00
Add SwiftFormat to the project. (#129)
* Run swiftformat for whitespace. * Run swiftformat with some rules.
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
--swiftversion 5.6
|
||||
|
||||
--exclude ElementX/Sources/Generated
|
||||
|
||||
--disable wrapMultiLineStatementBraces
|
||||
--disable blankLinesAtStartOfScope
|
||||
--disable blankLinesAtEndOfScope
|
||||
--disable hoistPatternLet
|
||||
|
||||
--commas inline
|
||||
--ifdef no-indent
|
||||
--nospaceoperators ...,..<
|
||||
--stripunusedargs closure-only
|
||||
--trimwhitespace nonblank-lines
|
||||
--wrapparameters after-first
|
||||
--redundanttype inferred
|
||||
--emptybraces spaced
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
import Foundation
|
||||
import Danger
|
||||
import Foundation
|
||||
|
||||
SwiftLint.lint(inline: true)
|
||||
|
||||
@@ -19,7 +19,7 @@ if danger.github.pullRequest.body?.isEmpty ?? true {
|
||||
let editedFiles = danger.git.modifiedFiles + danger.git.createdFiles
|
||||
let changelogFiles = editedFiles.filter { $0.hasPrefix("changelog.d/") }
|
||||
|
||||
if editedFiles.count > 0 && changelogFiles.isEmpty {
|
||||
if editedFiles.count > 0, changelogFiles.isEmpty {
|
||||
warn("Please add a changelog.")
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ if requiresSignOff {
|
||||
!$0.message.contains(signOff)
|
||||
}.isEmpty
|
||||
|
||||
if !hasPRBodySignOff && isMissingCommitsSignOff {
|
||||
if !hasPRBodySignOff, isMissingCommitsSignOff {
|
||||
fail("Please add a sign-off to either the PR description or to the commits themselves.")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import DesignTokens
|
||||
import SwiftUI
|
||||
|
||||
public extension ButtonStyle where Self == ElementActionButtonStyle {
|
||||
/// The CTA button style as defined in Compound.
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import DesignTokens
|
||||
import SwiftUI
|
||||
|
||||
public extension ButtonStyle where Self == ElementGhostButtonStyle {
|
||||
/// The Ghost button style as defined in Compound.
|
||||
|
||||
@@ -35,110 +35,111 @@ public class ElementSharedFonts {
|
||||
|
||||
/// Returns an instance of the font associated with the text style and scaled appropriately for the content size category defined in the trait collection.
|
||||
/// Keep this method private method at the moment and create a DesignKit.Fonts.TextStyle if needed.
|
||||
fileprivate func font(forTextStyle textStyle: UIFont.TextStyle, compatibleWith traitCollection: UITraitCollection? = nil) -> UIFont {
|
||||
return UIFont.preferredFont(forTextStyle: textStyle, compatibleWith: traitCollection)
|
||||
private func font(forTextStyle textStyle: UIFont.TextStyle, compatibleWith traitCollection: UITraitCollection? = nil) -> UIFont {
|
||||
UIFont.preferredFont(forTextStyle: textStyle, compatibleWith: traitCollection)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Fonts protocol
|
||||
extension ElementSharedFonts {
|
||||
|
||||
public var largeTitle: SharedFont {
|
||||
public extension ElementSharedFonts {
|
||||
|
||||
var largeTitle: SharedFont {
|
||||
let uiFont = font(forTextStyle: .largeTitle)
|
||||
return SharedFont(uiFont: uiFont, font: .largeTitle)
|
||||
}
|
||||
|
||||
public var largeTitleB: SharedFont {
|
||||
var largeTitleB: SharedFont {
|
||||
let uiFont = largeTitle.uiFont.bold
|
||||
return SharedFont(uiFont: uiFont, font: .largeTitle.bold())
|
||||
}
|
||||
|
||||
public var title1: SharedFont {
|
||||
var title1: SharedFont {
|
||||
let uiFont = font(forTextStyle: .title1)
|
||||
return SharedFont(uiFont: uiFont, font: .title)
|
||||
}
|
||||
|
||||
public var title1B: SharedFont {
|
||||
var title1B: SharedFont {
|
||||
let uiFont = title1.uiFont.bold
|
||||
return SharedFont(uiFont: uiFont, font: .title.bold())
|
||||
}
|
||||
|
||||
public var title2: SharedFont {
|
||||
var title2: SharedFont {
|
||||
let uiFont = font(forTextStyle: .title2)
|
||||
return SharedFont(uiFont: uiFont, font: .title2)
|
||||
}
|
||||
|
||||
public var title2B: SharedFont {
|
||||
var title2B: SharedFont {
|
||||
let uiFont = title2.uiFont.bold
|
||||
return SharedFont(uiFont: uiFont, font: .title2.bold())
|
||||
}
|
||||
|
||||
public var title3: SharedFont {
|
||||
var title3: SharedFont {
|
||||
let uiFont = font(forTextStyle: .title3)
|
||||
return SharedFont(uiFont: uiFont, font: .title3)
|
||||
}
|
||||
|
||||
public var title3SB: SharedFont {
|
||||
var title3SB: SharedFont {
|
||||
let uiFont = title3.uiFont.semiBold
|
||||
return SharedFont(uiFont: uiFont, font: .title3.weight(.semibold))
|
||||
}
|
||||
|
||||
public var headline: SharedFont {
|
||||
var headline: SharedFont {
|
||||
let uiFont = font(forTextStyle: .headline)
|
||||
return SharedFont(uiFont: uiFont, font: .headline)
|
||||
}
|
||||
|
||||
public var subheadline: SharedFont {
|
||||
var subheadline: SharedFont {
|
||||
let uiFont = font(forTextStyle: .subheadline)
|
||||
return SharedFont(uiFont: uiFont, font: .subheadline)
|
||||
}
|
||||
|
||||
public var body: SharedFont {
|
||||
var body: SharedFont {
|
||||
let uiFont = font(forTextStyle: .body)
|
||||
return SharedFont(uiFont: uiFont, font: .body)
|
||||
}
|
||||
|
||||
public var bodySB: SharedFont {
|
||||
var bodySB: SharedFont {
|
||||
let uiFont = body.uiFont.semiBold
|
||||
return SharedFont(uiFont: uiFont, font: .body.weight(.semibold))
|
||||
}
|
||||
|
||||
public var callout: SharedFont {
|
||||
var callout: SharedFont {
|
||||
let uiFont = font(forTextStyle: .callout)
|
||||
return SharedFont(uiFont: uiFont, font: .callout)
|
||||
}
|
||||
|
||||
public var calloutSB: SharedFont {
|
||||
var calloutSB: SharedFont {
|
||||
let uiFont = callout.uiFont.semiBold
|
||||
return SharedFont(uiFont: uiFont, font: .callout.weight(.semibold))
|
||||
}
|
||||
|
||||
public var footnote: SharedFont {
|
||||
var footnote: SharedFont {
|
||||
let uiFont = font(forTextStyle: .footnote)
|
||||
return SharedFont(uiFont: uiFont, font: .footnote)
|
||||
}
|
||||
|
||||
public var footnoteSB: SharedFont {
|
||||
var footnoteSB: SharedFont {
|
||||
let uiFont = footnote.uiFont.semiBold
|
||||
return SharedFont(uiFont: uiFont, font: .footnote.weight(.semibold))
|
||||
}
|
||||
|
||||
public var caption1: SharedFont {
|
||||
var caption1: SharedFont {
|
||||
let uiFont = font(forTextStyle: .caption1)
|
||||
return SharedFont(uiFont: uiFont, font: .caption)
|
||||
}
|
||||
|
||||
public var caption1SB: SharedFont {
|
||||
var caption1SB: SharedFont {
|
||||
let uiFont = caption1.uiFont.semiBold
|
||||
return SharedFont(uiFont: uiFont, font: .caption.weight(.semibold))
|
||||
}
|
||||
|
||||
public var caption2: SharedFont {
|
||||
var caption2: SharedFont {
|
||||
let uiFont = font(forTextStyle: .caption2)
|
||||
return SharedFont(uiFont: uiFont, font: .caption2)
|
||||
}
|
||||
|
||||
public var caption2SB: SharedFont {
|
||||
var caption2SB: SharedFont {
|
||||
let uiFont = caption2.uiFont.semiBold
|
||||
return SharedFont(uiFont: uiFont, font: .caption2.weight(.semibold))
|
||||
}
|
||||
|
||||
@@ -44,14 +44,14 @@ public extension UIFont {
|
||||
// MARK: - Shortcuts
|
||||
|
||||
var bold: UIFont {
|
||||
return withTraits(.traitBold)
|
||||
withTraits(.traitBold)
|
||||
}
|
||||
|
||||
var semiBold: UIFont {
|
||||
return withWeight(weight: .semibold)
|
||||
withWeight(weight: .semibold)
|
||||
}
|
||||
|
||||
var italic: UIFont {
|
||||
return withTraits(.traitItalic)
|
||||
withTraits(.traitItalic)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import DesignTokens
|
||||
import Introspect
|
||||
import SwiftUI
|
||||
|
||||
/// A bordered style of text input
|
||||
///
|
||||
@@ -48,7 +48,7 @@ public struct BorderedInputFieldStyle: TextFieldStyle {
|
||||
}
|
||||
|
||||
private var backgroundColor: Color {
|
||||
if !isEnabled && colorScheme == .dark {
|
||||
if !isEnabled, colorScheme == .dark {
|
||||
return .element.quinaryContent
|
||||
}
|
||||
return .element.background
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import DesignTokens
|
||||
import SwiftUI
|
||||
|
||||
@available(iOS 15.0, *)
|
||||
public extension TextFieldStyle where Self == ElementTextFieldStyle {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import XCTest
|
||||
@testable import DesignKit
|
||||
import XCTest
|
||||
|
||||
final class DesignKitTests: XCTestCase {
|
||||
func testExample() throws {
|
||||
|
||||
@@ -130,6 +130,7 @@
|
||||
62BBF5BE7B905222F0477FF2 /* MediaSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8210612D17A39369480FC183 /* MediaSource.swift */; };
|
||||
63C9AF0FB8278AF1C0388A0C /* TemplateModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAB10E673916D2B8D21FD197 /* TemplateModels.swift */; };
|
||||
6647430A45B4A8E692909A8F /* EmoteRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F77C060C2ACC4CB7336A29E7 /* EmoteRoomTimelineItem.swift */; };
|
||||
67C05C50AD734283374605E3 /* MatrixEntityRegex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AD1A853D605C2146B0DC028 /* MatrixEntityRegex.swift */; };
|
||||
67E391A2E00709FB41903B36 /* MockMediaProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6920A4869821BF72FFC58842 /* MockMediaProvider.swift */; };
|
||||
6832733838C57A7D3FE8FEB5 /* Introspect in Frameworks */ = {isa = PBXBuildFile; productRef = 04C28663564E008DB32B5972 /* Introspect */; };
|
||||
684BDE198AE5AA1392288A73 /* SplashScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32CE6D4FF64C9A3C18619224 /* SplashScreen.swift */; };
|
||||
@@ -279,7 +280,6 @@
|
||||
EE8491AD81F47DF3C192497B /* DecorationTimelineItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 184CF8C196BE143AE226628D /* DecorationTimelineItemProtocol.swift */; };
|
||||
EEC40663922856C65D1E0DF5 /* KeychainControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDB9C37196A4C79F24CE80C6 /* KeychainControllerTests.swift */; };
|
||||
EF99A92701E401C4CD5ADC50 /* SplashScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCE978A6118C131D7F2A04B3 /* SplashScreenModels.swift */; };
|
||||
F03E16ED043C62FED5A07AE0 /* MatrixEntityRegex.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7B81C8227BBEA95CCE86037 /* MatrixEntityRegex.swift */; };
|
||||
F040ABFEB0A2B142D948BA12 /* Untranslated.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = F75DF9500D69A3AAF8339E69 /* Untranslated.stringsdict */; };
|
||||
F2DD8661B5C0BA2BB526FA6C /* KeychainControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CD51F9FDC91C231906D76C8 /* KeychainControllerProtocol.swift */; };
|
||||
F4C3FEDB1B3A05376A1723A3 /* KeychainController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A4427F9E0571B4E6E048A2B /* KeychainController.swift */; };
|
||||
@@ -479,6 +479,7 @@
|
||||
6920A4869821BF72FFC58842 /* MockMediaProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockMediaProvider.swift; sourceTree = "<group>"; };
|
||||
6A152791A2F56BD193BFE986 /* MemberDetailsProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemberDetailsProvider.swift; sourceTree = "<group>"; };
|
||||
6A901D95158B02CA96C79C7F /* InfoPlist.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoPlist.swift; sourceTree = "<group>"; };
|
||||
6AD1A853D605C2146B0DC028 /* MatrixEntityRegex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatrixEntityRegex.swift; sourceTree = "<group>"; };
|
||||
6B73A8C3118EAC7BF3F3EE7A /* SplashScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
6D4777F0142E330A75C46FE4 /* SessionVerificationUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationUITests.swift; sourceTree = "<group>"; };
|
||||
6DB53055CB130F0651C70763 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
@@ -691,7 +692,6 @@
|
||||
F6A8C632CEF4600107792899 /* TextRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||
F73FF1A33198F5FAE9D34B1F /* FormattedBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormattedBodyText.swift; sourceTree = "<group>"; };
|
||||
F77C060C2ACC4CB7336A29E7 /* EmoteRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||
F7B81C8227BBEA95CCE86037 /* MatrixEntityRegex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatrixEntityRegex.swift; sourceTree = "<group>"; };
|
||||
F9E785D5137510481733A3E8 /* TextRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||
FA154570F693D93513E584C1 /* RoomMessageFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMessageFactory.swift; sourceTree = "<group>"; };
|
||||
FAB10E673916D2B8D21FD197 /* TemplateModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateModels.swift; sourceTree = "<group>"; };
|
||||
@@ -1443,7 +1443,7 @@
|
||||
CF4B39D52CAE7D21D276ABEE /* ElementNavigationController.swift */,
|
||||
1027BB9A852F445B7623897F /* ElementSettings.swift */,
|
||||
12A626D74BBE9F4A60763B45 /* ImageAnonymizer.swift */,
|
||||
F7B81C8227BBEA95CCE86037 /* MatrixEntityRegex.swift */,
|
||||
6AD1A853D605C2146B0DC028 /* MatrixEntityRegex.swift */,
|
||||
44BBB96FAA2F0D53C507396B /* Extensions */,
|
||||
8F9A844EB44B6AD7CA18FD96 /* HTMLParsing */,
|
||||
06501F0E978B2D5C92771DC7 /* Logging */,
|
||||
@@ -1659,6 +1659,7 @@
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = B15427F8699AD5A5FC75C17E /* Build configuration list for PBXNativeTarget "ElementX" */;
|
||||
buildPhases = (
|
||||
B35AB66424BB30087EEE408C /* 🧹 SwiftFormat */,
|
||||
A7130911BCB2DF3D249A1836 /* 🛠 SwiftGen */,
|
||||
9797D588420FCBBC228A63C9 /* Sources */,
|
||||
215E1D91B98672C856F559D0 /* Resources */,
|
||||
@@ -1886,6 +1887,24 @@
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "export PATH=\"$PATH:/opt/homebrew/bin\"\nif which swiftgen >/dev/null; then\n swiftgen config run --config Tools/SwiftGen/swiftgen-config.yml\nelse\n echo \"warning: SwiftGen not installed, download from https://github.com/SwiftGen/SwiftGen\"\nfi\n";
|
||||
};
|
||||
B35AB66424BB30087EEE408C /* 🧹 SwiftFormat */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "🧹 SwiftFormat";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "export PATH=\"$PATH:/opt/homebrew/bin\"\nif which swiftformat >/dev/null; then\n swiftformat $PROJECT_DIR\nelse\n echo \"warning: SwiftFormat not installed, download from https://github.com/nicklockwood/SwiftFormat\"\nfi\n";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
@@ -1997,7 +2016,7 @@
|
||||
2F30EFEB7BD39242D1AD96F3 /* LoginViewModelProtocol.swift in Sources */,
|
||||
B94368839BDB69172E28E245 /* MXLog.swift in Sources */,
|
||||
BCC3EDB7AD0902797CB4BBC2 /* MXLogger.m in Sources */,
|
||||
F03E16ED043C62FED5A07AE0 /* MatrixEntityRegex.swift in Sources */,
|
||||
67C05C50AD734283374605E3 /* MatrixEntityRegex.swift in Sources */,
|
||||
EA1E7949533E19C6D862680A /* MediaProvider.swift in Sources */,
|
||||
7002C55A4C917F3715765127 /* MediaProviderProtocol.swift in Sources */,
|
||||
62BBF5BE7B905222F0477FF2 /* MediaSource.swift in Sources */,
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Combine
|
||||
import UIKit
|
||||
|
||||
class AppCoordinator: AuthenticationCoordinatorDelegate, Coordinator {
|
||||
private let window: UIWindow
|
||||
@@ -149,6 +149,7 @@ class AppCoordinator: AuthenticationCoordinatorDelegate, Coordinator {
|
||||
fatalError("Failed transition with context: \(context)")
|
||||
}
|
||||
}
|
||||
|
||||
// swiftlint:enable cyclomatic_complexity function_body_length
|
||||
|
||||
private func restoreUserSession() {
|
||||
|
||||
@@ -14,8 +14,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
private lazy var appCoordinator: Coordinator = isRunningUITests ? UITestsAppCoordinator() : AppCoordinator()
|
||||
|
||||
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
|
||||
|
||||
// fixme: Use `Bundle.elementLanguage = ".."` when we have the functionality
|
||||
// use `en` as fallback language
|
||||
Bundle.elementFallbackLanguage = "en"
|
||||
|
||||
|
||||
@@ -11,22 +11,26 @@ import Foundation
|
||||
final class BuildSettings {
|
||||
|
||||
// MARK: - Servers
|
||||
|
||||
static let defaultHomeserverURLString = "https://matrix.org"
|
||||
|
||||
// MARK: - Bug report
|
||||
|
||||
static let bugReportServiceBaseUrlString = "https://riot.im/bugreports"
|
||||
static let bugReportSentryEndpoint = "https://f39ac49e97714316965b777d9f3d6cd8@sentry.tools.element.io/44"
|
||||
// Use the name allocated by the bug report server
|
||||
static let bugReportApplicationId = "riot-ios"
|
||||
static let bugReportUISIId = "element-auto-uisi"
|
||||
|
||||
static let bugReportGHLabels: [String] = ["Element-X"]
|
||||
static let bugReportGHLabels = ["Element-X"]
|
||||
|
||||
// MARK: - Settings screen
|
||||
static let settingsCrashButtonVisible: Bool = true
|
||||
static let settingsShowTimelineStyle: Bool = true
|
||||
|
||||
static let settingsCrashButtonVisible = true
|
||||
static let settingsShowTimelineStyle = true
|
||||
|
||||
// MARK: - Room screen
|
||||
|
||||
static let defaultRoomTimelineStyle: TimelineStyle = .bubbles
|
||||
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
import Foundation
|
||||
|
||||
struct Benchmark {
|
||||
static private var trackingIdentifiers = [String: CFAbsoluteTime]()
|
||||
private static var trackingIdentifiers = [String: CFAbsoluteTime]()
|
||||
|
||||
static public var trackingEnabled = false
|
||||
public static var trackingEnabled = false
|
||||
|
||||
static func startTrackingForIdentifier(_ identifier: String, message: String? = nil) {
|
||||
guard trackingEnabled else {
|
||||
|
||||
@@ -2,8 +2,8 @@ import UIKit
|
||||
|
||||
// swiftlint:disable all
|
||||
|
||||
extension UIImage {
|
||||
public convenience init?(blurHash: String, size: CGSize, punch: Float = 1) {
|
||||
public extension UIImage {
|
||||
convenience init?(blurHash: String, size: CGSize, punch: Float = 1) {
|
||||
guard blurHash.count >= 6 else { return nil }
|
||||
|
||||
let sizeFlag = String(blurHash[0]).decode83()
|
||||
@@ -90,7 +90,7 @@ private func decodeAC(_ value: Int, maximumValue: Float) -> (Float, Float, Float
|
||||
}
|
||||
|
||||
private func signPow(_ value: Float, _ exp: Float) -> Float {
|
||||
return copysign(pow(abs(value), exp), value)
|
||||
copysign(pow(abs(value), exp), value)
|
||||
}
|
||||
|
||||
private func linearTosRGB(_ value: Float) -> Int {
|
||||
@@ -105,9 +105,7 @@ private func sRGBToLinear<Type: BinaryInteger>(_ value: Type) -> Float {
|
||||
else { return pow((v + 0.055) / 1.055, 2.4) }
|
||||
}
|
||||
|
||||
private let encodeCharacters: [String] = {
|
||||
return "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~".map { String($0) }
|
||||
}()
|
||||
private let encodeCharacters: [String] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~".map { String($0) }
|
||||
|
||||
private let decodeCharacters: [String: Int] = {
|
||||
var dict: [String: Int] = [:]
|
||||
@@ -119,7 +117,7 @@ private let decodeCharacters: [String: Int] = {
|
||||
|
||||
extension String {
|
||||
func decode83() -> Int {
|
||||
var value: Int = 0
|
||||
var value = 0
|
||||
for character in self {
|
||||
if let digit = decodeCharacters[String(character)] {
|
||||
value = value * 83 + digit
|
||||
@@ -131,7 +129,7 @@ extension String {
|
||||
|
||||
private extension String {
|
||||
subscript(offset: Int) -> Character {
|
||||
return self[index(startIndex, offsetBy: offset)]
|
||||
self[index(startIndex, offsetBy: offset)]
|
||||
}
|
||||
|
||||
subscript(bounds: CountableClosedRange<Int>) -> Substring {
|
||||
|
||||
@@ -47,6 +47,6 @@ extension Coordinator {
|
||||
}
|
||||
|
||||
func remove(childCoordinator: Coordinator) {
|
||||
self.childCoordinators = self.childCoordinators.filter { $0 !== childCoordinator }
|
||||
childCoordinators = childCoordinators.filter { $0 !== childCoordinator }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ public extension Bundle {
|
||||
}
|
||||
|
||||
/// Preferred languages in the priority order.
|
||||
static private(set) var preferredLanguages: [String] = calculatePreferredLanguages()
|
||||
private(set) static var preferredLanguages: [String] = calculatePreferredLanguages()
|
||||
|
||||
private static func calculatePreferredLanguages() -> [String] {
|
||||
var set = Set<String>()
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import DTCoreText
|
||||
import Foundation
|
||||
|
||||
struct AttributedStringBuilder: AttributedStringBuilderProtocol {
|
||||
|
||||
@@ -65,7 +65,7 @@ struct AttributedStringBuilder: AttributedStringBuilderProtocol {
|
||||
DTDefaultFontFamily: defaultFont.familyName,
|
||||
DTDefaultFontName: defaultFont.fontName,
|
||||
DTDefaultFontSize: defaultFont.pointSize,
|
||||
DTDefaultStyleSheet: DTCSSStylesheet(styleBlock: self.defaultCSS) as Any
|
||||
DTDefaultStyleSheet: DTCSSStylesheet(styleBlock: defaultCSS) as Any
|
||||
]
|
||||
|
||||
guard let builder = DTHTMLAttributedStringBuilder(html: data, options: parsingOptions, documentAttributes: nil) else {
|
||||
@@ -96,7 +96,7 @@ struct AttributedStringBuilder: AttributedStringBuilderProtocol {
|
||||
return nil
|
||||
}
|
||||
|
||||
return attributedString.runs[\.blockquote].map { (value, range) in
|
||||
return attributedString.runs[\.blockquote].map { value, range in
|
||||
var attributedString = AttributedString(attributedString[range])
|
||||
|
||||
// Remove trailing new lines if any
|
||||
@@ -240,7 +240,7 @@ extension UIColor {
|
||||
|
||||
getRed(&red, green: &green, blue: &blue, alpha: &alpha)
|
||||
|
||||
let rgb: Int = (Int)(red*255)<<16 | (Int)(green*255)<<8 | (Int)(blue*255)<<0
|
||||
let rgb = Int(red * 255) << 16 | Int(green * 255) << 8 | Int(blue * 255) << 0
|
||||
|
||||
return NSString(format: "#%06x", rgb) as String
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import DTCoreText
|
||||
import Foundation
|
||||
|
||||
public extension DTHTMLElement {
|
||||
/// Sanitize the element using the given parameters.
|
||||
|
||||
@@ -26,6 +26,6 @@ extension AttributeScopes {
|
||||
|
||||
extension AttributeDynamicLookup {
|
||||
subscript<T: AttributedStringKey>(dynamicMember keyPath: KeyPath<AttributeScopes.ElementXAttributes, T>) -> T {
|
||||
return self[T.self]
|
||||
self[T.self]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,14 +7,14 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Vision
|
||||
import UIKit
|
||||
import Vision
|
||||
|
||||
enum ImageAnonymizerError: Error {
|
||||
case noCgImageBased
|
||||
}
|
||||
|
||||
struct ImageAnonymizer {
|
||||
enum ImageAnonymizer {
|
||||
|
||||
private static var allowedTextItems: [String] = [
|
||||
"#",
|
||||
|
||||
@@ -21,10 +21,10 @@ import SwiftyBeaver
|
||||
@objc public class MXLogConfiguration: NSObject {
|
||||
|
||||
/// the desired log level. `.verbose` by default.
|
||||
@objc public var logLevel: MXLogLevel = MXLogLevel.verbose
|
||||
@objc public var logLevel = MXLogLevel.verbose
|
||||
|
||||
/// whether logs should be written directly to files. `false` by default.
|
||||
@objc public var redirectLogsToFiles: Bool = false
|
||||
@objc public var redirectLogsToFiles = false
|
||||
|
||||
/// the maximum total space to use for log files in bytes. `100MB` by default.
|
||||
@objc public var logFilesSizeLimit: UInt = 100 * 1024 * 1024 // 100MB
|
||||
@@ -64,7 +64,7 @@ private var logger: SwiftyBeaver.Type = {
|
||||
/// Please see `MXLogConfiguration` for all available options.
|
||||
/// - Parameters:
|
||||
/// - configuration: the `MXLogConfiguration` instance to use
|
||||
@objc static public func configure(_ configuration: MXLogConfiguration) {
|
||||
@objc public static func configure(_ configuration: MXLogConfiguration) {
|
||||
configureLogger(logger, withConfiguration: configuration)
|
||||
}
|
||||
|
||||
@@ -107,8 +107,8 @@ private var logger: SwiftyBeaver.Type = {
|
||||
logger.info(message, file, function, line: line)
|
||||
}
|
||||
|
||||
public static func warning(_ message: @autoclosure () -> Any, _
|
||||
file: String = #file,
|
||||
public static func warning(_ message: @autoclosure () -> Any,
|
||||
_ file: String = #file,
|
||||
_ function: String = #function,
|
||||
line: Int = #line,
|
||||
context: Any? = nil) {
|
||||
@@ -133,8 +133,8 @@ private var logger: SwiftyBeaver.Type = {
|
||||
logger.error(message, file, function, line: line)
|
||||
}
|
||||
|
||||
public static func failure(_ message: @autoclosure () -> Any, _
|
||||
file: String = #file,
|
||||
public static func failure(_ message: @autoclosure () -> Any,
|
||||
_ file: String = #file,
|
||||
_ function: String = #function,
|
||||
line: Int = #line,
|
||||
context: Any? = nil) {
|
||||
|
||||
@@ -30,7 +30,7 @@ struct NavigationModule {
|
||||
extension NavigationModule: CustomStringConvertible {
|
||||
|
||||
var description: String {
|
||||
return "NavigationModule: \(presentable), pop completion: \(String(describing: popCompletion))"
|
||||
"NavigationModule: \(presentable), pop completion: \(String(describing: popCompletion))"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,21 +34,21 @@ final class NavigationRouter: NSObject, NavigationRouterType {
|
||||
|
||||
/// Returns the presentables associated to each view controller
|
||||
var modules: [Presentable] {
|
||||
return self.viewControllers.map { (viewController) -> Presentable in
|
||||
return self.module(for: viewController)
|
||||
viewControllers.map { viewController -> Presentable in
|
||||
self.module(for: viewController)
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the view controllers stack
|
||||
var viewControllers: [UIViewController] {
|
||||
return navigationController.viewControllers
|
||||
navigationController.viewControllers
|
||||
}
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
init(navigationController: UINavigationController) {
|
||||
self.navigationController = navigationController
|
||||
self.completions = [:]
|
||||
completions = [:]
|
||||
super.init()
|
||||
self.navigationController.delegate = self
|
||||
|
||||
@@ -88,9 +88,9 @@ final class NavigationRouter: NSObject, NavigationRouterType {
|
||||
return
|
||||
}
|
||||
|
||||
self.addModule(module, for: controller)
|
||||
addModule(module, for: controller)
|
||||
|
||||
let controllersToPop = self.navigationController.viewControllers.reversed()
|
||||
let controllersToPop = navigationController.viewControllers.reversed()
|
||||
|
||||
controllersToPop.forEach {
|
||||
self.willPopViewController($0)
|
||||
@@ -100,7 +100,7 @@ final class NavigationRouter: NSObject, NavigationRouterType {
|
||||
completions[controller] = popCompletion
|
||||
}
|
||||
|
||||
self.willPushViewController(controller)
|
||||
willPushViewController(controller)
|
||||
|
||||
navigationController.setViewControllers([controller], animated: animated)
|
||||
navigationController.isNavigationBarHidden = hideNavigationBar
|
||||
@@ -111,22 +111,22 @@ final class NavigationRouter: NSObject, NavigationRouterType {
|
||||
}
|
||||
|
||||
// Add again controller to module association, in case same module instance is added back
|
||||
self.addModule(module, for: controller)
|
||||
addModule(module, for: controller)
|
||||
|
||||
self.didPushViewController(controller)
|
||||
didPushViewController(controller)
|
||||
}
|
||||
|
||||
func setModules(_ modules: [NavigationModule], hideNavigationBar: Bool, animated: Bool) {
|
||||
|
||||
MXLog.debug("[NavigationRouter] Set modules \(modules)")
|
||||
|
||||
let controllers = modules.map { (module) -> UIViewController in
|
||||
let controllers = modules.map { module -> UIViewController in
|
||||
let controller = module.presentable.toPresentable()
|
||||
self.addModule(module.presentable, for: controller)
|
||||
return controller
|
||||
}
|
||||
|
||||
let controllersToPop = self.navigationController.viewControllers.reversed()
|
||||
let controllersToPop = navigationController.viewControllers.reversed()
|
||||
|
||||
controllersToPop.forEach {
|
||||
self.willPopViewController($0)
|
||||
@@ -146,7 +146,7 @@ final class NavigationRouter: NSObject, NavigationRouterType {
|
||||
}
|
||||
|
||||
// Add again controller to module association, in case same modules instance are added back
|
||||
modules.forEach { (module) in
|
||||
modules.forEach { module in
|
||||
self.addModule(module.presentable, for: module.presentable.toPresentable())
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ final class NavigationRouter: NSObject, NavigationRouterType {
|
||||
func popToRootModule(animated: Bool) {
|
||||
MXLog.debug("[NavigationRouter] Pop to root module")
|
||||
|
||||
let controllers = self.navigationController.viewControllers
|
||||
let controllers = navigationController.viewControllers
|
||||
|
||||
if controllers.count > 1 {
|
||||
let controllersToPop = controllers[1..<controllers.count]
|
||||
@@ -179,7 +179,7 @@ final class NavigationRouter: NSObject, NavigationRouterType {
|
||||
MXLog.debug("[NavigationRouter] Pop to module \(module)")
|
||||
|
||||
let controller = module.toPresentable()
|
||||
let controllersBeforePop = self.navigationController.viewControllers
|
||||
let controllersBeforePop = navigationController.viewControllers
|
||||
|
||||
if let controllerIndex = controllersBeforePop.firstIndex(of: controller) {
|
||||
let controllersToPop = controllersBeforePop[controllerIndex..<controllersBeforePop.count]
|
||||
@@ -207,17 +207,17 @@ final class NavigationRouter: NSObject, NavigationRouterType {
|
||||
return
|
||||
}
|
||||
|
||||
self.addModule(module, for: controller)
|
||||
addModule(module, for: controller)
|
||||
|
||||
if let completion = popCompletion {
|
||||
completions[controller] = completion
|
||||
}
|
||||
|
||||
self.willPushViewController(controller)
|
||||
willPushViewController(controller)
|
||||
|
||||
navigationController.pushViewController(controller, animated: animated)
|
||||
|
||||
self.didPushViewController(controller)
|
||||
didPushViewController(controller)
|
||||
}
|
||||
|
||||
func push(_ modules: [NavigationModule], animated: Bool) {
|
||||
@@ -231,22 +231,22 @@ final class NavigationRouter: NSObject, NavigationRouterType {
|
||||
|
||||
for module in modules {
|
||||
let controller = module.presentable.toPresentable()
|
||||
self.addModule(module.presentable, for: controller)
|
||||
addModule(module.presentable, for: controller)
|
||||
|
||||
if let completion = module.popCompletion {
|
||||
completions[controller] = completion
|
||||
}
|
||||
|
||||
self.willPushViewController(controller)
|
||||
willPushViewController(controller)
|
||||
}
|
||||
|
||||
var viewControllers = navigationController.viewControllers
|
||||
viewControllers.append(contentsOf: modules.map({ $0.presentable.toPresentable() }))
|
||||
viewControllers.append(contentsOf: modules.map { $0.presentable.toPresentable() })
|
||||
navigationController.setViewControllers(viewControllers, animated: animated)
|
||||
|
||||
for module in modules {
|
||||
let controller = module.presentable.toPresentable()
|
||||
self.didPushViewController(controller)
|
||||
didPushViewController(controller)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,18 +254,18 @@ final class NavigationRouter: NSObject, NavigationRouterType {
|
||||
MXLog.debug("[NavigationRouter] Pop module")
|
||||
|
||||
if let lastController = navigationController.viewControllers.last {
|
||||
self.willPopViewController(lastController)
|
||||
willPopViewController(lastController)
|
||||
}
|
||||
|
||||
if let controller = navigationController.popViewController(animated: animated) {
|
||||
self.didPopViewController(controller)
|
||||
didPopViewController(controller)
|
||||
}
|
||||
}
|
||||
|
||||
func popAllModules(animated: Bool) {
|
||||
MXLog.debug("[NavigationRouter] Pop all modules")
|
||||
|
||||
let controllersToPop = self.navigationController.viewControllers.reversed()
|
||||
let controllersToPop = navigationController.viewControllers.reversed()
|
||||
|
||||
controllersToPop.forEach {
|
||||
self.willPopViewController($0)
|
||||
@@ -281,31 +281,31 @@ final class NavigationRouter: NSObject, NavigationRouterType {
|
||||
func contains(_ module: Presentable) -> Bool {
|
||||
|
||||
let controller = module.toPresentable()
|
||||
return self.navigationController.viewControllers.contains(controller)
|
||||
return navigationController.viewControllers.contains(controller)
|
||||
}
|
||||
|
||||
// MARK: Presentable
|
||||
|
||||
func toPresentable() -> UIViewController {
|
||||
return navigationController
|
||||
navigationController
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func module(for viewController: UIViewController) -> Presentable {
|
||||
|
||||
guard let module = self.storedModules[viewController] as? Presentable else {
|
||||
guard let module = storedModules[viewController] as? Presentable else {
|
||||
return viewController
|
||||
}
|
||||
return module
|
||||
}
|
||||
|
||||
private func addModule(_ module: Presentable, for viewController: UIViewController) {
|
||||
self.storedModules[viewController] = module as AnyObject
|
||||
storedModules[viewController] = module as AnyObject
|
||||
}
|
||||
|
||||
private func removeModule(for viewController: UIViewController) {
|
||||
self.storedModules[viewController] = nil
|
||||
storedModules[viewController] = nil
|
||||
}
|
||||
|
||||
private func runCompletion(for controller: UIViewController) {
|
||||
@@ -317,30 +317,30 @@ final class NavigationRouter: NSObject, NavigationRouterType {
|
||||
}
|
||||
|
||||
private func willPushViewController(_ viewController: UIViewController) {
|
||||
self.postNotification(withName: NavigationRouter.willPushModule, for: viewController)
|
||||
postNotification(withName: NavigationRouter.willPushModule, for: viewController)
|
||||
}
|
||||
|
||||
private func didPushViewController(_ viewController: UIViewController) {
|
||||
self.postNotification(withName: NavigationRouter.didPushModule, for: viewController)
|
||||
postNotification(withName: NavigationRouter.didPushModule, for: viewController)
|
||||
}
|
||||
|
||||
private func willPopViewController(_ viewController: UIViewController) {
|
||||
self.postNotification(withName: NavigationRouter.willPopModule, for: viewController)
|
||||
postNotification(withName: NavigationRouter.willPopModule, for: viewController)
|
||||
}
|
||||
|
||||
private func didPopViewController(_ viewController: UIViewController) {
|
||||
self.postNotification(withName: NavigationRouter.didPopModule, for: viewController)
|
||||
postNotification(withName: NavigationRouter.didPopModule, for: viewController)
|
||||
|
||||
// Call completion closure associated to the view controller
|
||||
// So associated coordinator can be deallocated
|
||||
runCompletion(for: viewController)
|
||||
|
||||
self.removeModule(for: viewController)
|
||||
removeModule(for: viewController)
|
||||
}
|
||||
|
||||
private func postNotification(withName name: Notification.Name, for viewController: UIViewController) {
|
||||
|
||||
let module = self.module(for: viewController)
|
||||
let module = module(for: viewController)
|
||||
|
||||
let userInfo: [String: Any] = [
|
||||
NotificationUserInfoKey.navigationRouter: self,
|
||||
@@ -352,6 +352,7 @@ final class NavigationRouter: NSObject, NavigationRouterType {
|
||||
}
|
||||
|
||||
// MARK: - UINavigationControllerDelegate
|
||||
|
||||
extension NavigationRouter: UINavigationControllerDelegate {
|
||||
|
||||
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
|
||||
@@ -369,11 +370,12 @@ extension NavigationRouter: UINavigationControllerDelegate {
|
||||
|
||||
MXLog.debug("[NavigationRouter] Popped module: \(poppedViewController)")
|
||||
|
||||
self.didPopViewController(poppedViewController)
|
||||
didPopViewController(poppedViewController)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - NavigationRouter notification constants
|
||||
|
||||
extension NavigationRouter {
|
||||
|
||||
// MARK: Notification names
|
||||
@@ -388,7 +390,7 @@ extension NavigationRouter {
|
||||
|
||||
// MARK: Notification keys
|
||||
|
||||
public struct NotificationUserInfoKey {
|
||||
public enum NotificationUserInfoKey {
|
||||
|
||||
/// The associated view controller (UIViewController).
|
||||
static let viewController = "viewController"
|
||||
|
||||
@@ -33,14 +33,14 @@ class NavigationRouterStore: NavigationRouterStoreProtocol {
|
||||
|
||||
/// As we are ensuring that there is only one navigation controller per NavigationRouter, the class here should be used as a singleton.
|
||||
private init() {
|
||||
self.registerNavigationRouterNotifications()
|
||||
registerNavigationRouterNotifications()
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
func navigationRouter(for navigationController: UINavigationController) -> NavigationRouterType {
|
||||
|
||||
if let existingNavigationRouter = self.findNavigationRouter(for: navigationController) {
|
||||
if let existingNavigationRouter = findNavigationRouter(for: navigationController) {
|
||||
return existingNavigationRouter
|
||||
}
|
||||
|
||||
@@ -51,11 +51,11 @@ class NavigationRouterStore: NavigationRouterStoreProtocol {
|
||||
// MARK: - Private
|
||||
|
||||
private func findNavigationRouter(for navigationController: UINavigationController) -> NavigationRouterType? {
|
||||
return self.navigationRouters[navigationController]
|
||||
navigationRouters[navigationController]
|
||||
}
|
||||
|
||||
private func removeNavigationRouter(for navigationController: UINavigationController) {
|
||||
self.navigationRouters[navigationController] = nil
|
||||
navigationRouters[navigationController] = nil
|
||||
}
|
||||
|
||||
private func registerNavigationRouterNotifications() {
|
||||
@@ -71,12 +71,12 @@ class NavigationRouterStore: NavigationRouterStoreProtocol {
|
||||
return
|
||||
}
|
||||
|
||||
if let existingNavigationRouter = self.findNavigationRouter(for: navigationController) {
|
||||
if let existingNavigationRouter = findNavigationRouter(for: navigationController) {
|
||||
fatalError("\(existingNavigationRouter) is already tied to the same navigation controller as \(navigationRouter). We should have only one NavigationRouter per navigation controller")
|
||||
} else {
|
||||
// WeakDictionary does not work with protocol
|
||||
// Find a way to avoid this cast
|
||||
self.navigationRouters[navigationController] = navigationRouter as? NavigationRouter
|
||||
navigationRouters[navigationController] = navigationRouter as? NavigationRouter
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,10 +87,10 @@ class NavigationRouterStore: NavigationRouterStoreProtocol {
|
||||
return
|
||||
}
|
||||
|
||||
if let existingNavigationRouter = self.findNavigationRouter(for: navigationController), existingNavigationRouter !== navigationRouter {
|
||||
if let existingNavigationRouter = findNavigationRouter(for: navigationController), existingNavigationRouter !== navigationRouter {
|
||||
fatalError("\(existingNavigationRouter) is already tied to the same navigation controller as \(navigationRouter). We should have only one NavigationRouter per navigation controller")
|
||||
}
|
||||
|
||||
self.removeNavigationRouter(for: navigationController)
|
||||
removeNavigationRouter(for: navigationController)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ protocol Presentable {
|
||||
|
||||
extension UIViewController: Presentable {
|
||||
public func toPresentable() -> UIViewController {
|
||||
return self
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ extension Presentable {
|
||||
/// Returns a new module from the presentable without a pop completion block
|
||||
/// - Returns: Module
|
||||
func toModule() -> NavigationModule {
|
||||
return NavigationModule(presentable: self, popCompletion: nil)
|
||||
NavigationModule(presentable: self, popCompletion: nil)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ final class RootRouter: RootRouterType {
|
||||
|
||||
/// The root view controller currently presented
|
||||
var rootViewController: UIViewController? {
|
||||
return self.window.rootViewController
|
||||
window.rootViewController
|
||||
}
|
||||
|
||||
// MARK: - Setup
|
||||
@@ -47,23 +47,23 @@ final class RootRouter: RootRouterType {
|
||||
// MARK: - Public methods
|
||||
|
||||
func setRootModule(_ module: Presentable) {
|
||||
self.updateRootViewController(rootViewController: module.toPresentable(), animated: false, completion: nil)
|
||||
self.window.makeKeyAndVisible()
|
||||
updateRootViewController(rootViewController: module.toPresentable(), animated: false, completion: nil)
|
||||
window.makeKeyAndVisible()
|
||||
}
|
||||
|
||||
func dismissRootModule(animated: Bool, completion: (() -> Void)?) {
|
||||
self.updateRootViewController(rootViewController: nil, animated: animated, completion: completion)
|
||||
updateRootViewController(rootViewController: nil, animated: animated, completion: completion)
|
||||
}
|
||||
|
||||
func presentModule(_ module: Presentable, animated: Bool, completion: (() -> Void)?) {
|
||||
let viewControllerPresenter = self.rootViewController?.presentedViewController ?? self.rootViewController
|
||||
let viewControllerPresenter = rootViewController?.presentedViewController ?? rootViewController
|
||||
|
||||
viewControllerPresenter?.present(module.toPresentable(), animated: animated, completion: completion)
|
||||
self.presentedModule = module
|
||||
presentedModule = module
|
||||
}
|
||||
|
||||
func dismissModule(animated: Bool, completion: (() -> Void)?) {
|
||||
self.presentedModule?.toPresentable().dismiss(animated: animated, completion: completion)
|
||||
presentedModule?.toPresentable().dismiss(animated: animated, completion: completion)
|
||||
}
|
||||
|
||||
// MARK: - Private methods
|
||||
@@ -76,11 +76,11 @@ final class RootRouter: RootRouterType {
|
||||
UIView.setAnimationsEnabled(false)
|
||||
self.window.rootViewController = rootViewController
|
||||
UIView.setAnimationsEnabled(oldState)
|
||||
}, completion: { (_: Bool) -> Void in
|
||||
}, completion: { _ in
|
||||
completion?()
|
||||
})
|
||||
} else {
|
||||
self.window.rootViewController = rootViewController
|
||||
window.rootViewController = rootViewController
|
||||
completion?()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,11 +16,9 @@
|
||||
|
||||
import SwiftUI
|
||||
|
||||
// swiftlint:disable private_over_fileprivate
|
||||
|
||||
/// Positions this view within an invisible frame that fills the width of its parent view,
|
||||
/// whilst limiting the width of the content to a readable size (which is customizable).
|
||||
fileprivate struct ReadableFrameModifier: ViewModifier {
|
||||
private struct ReadableFrameModifier: ViewModifier {
|
||||
var maxWidth: CGFloat
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
|
||||
@@ -27,9 +27,7 @@ extension BindableState where BindStateType == Void {
|
||||
/// We provide a default implementation for the Void type so that we can have `ViewState` that
|
||||
/// just doesn't include/take advantage of the bindings.
|
||||
var bindings: Void {
|
||||
get {
|
||||
|
||||
}
|
||||
get { }
|
||||
set {
|
||||
fatalError("Can't bind to the default Void binding.")
|
||||
}
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
import Foundation
|
||||
|
||||
/// A constrained and concise interface for interacting with the ViewModel.
|
||||
///
|
||||
@@ -96,8 +96,8 @@ class StateStoreViewModel<State: BindableState, ViewAction> {
|
||||
// MARK: Setup
|
||||
|
||||
init(initialViewState: State) {
|
||||
self.context = Context(initialViewState: initialViewState)
|
||||
self.context.viewActions.sink { [weak self] action in
|
||||
context = Context(initialViewState: initialViewState)
|
||||
context.viewActions.sink { [weak self] action in
|
||||
guard let self = self else { return }
|
||||
|
||||
Task { await self.process(viewAction: action) }
|
||||
|
||||
@@ -52,7 +52,7 @@ final class ActivityIndicatorPresenter: ActivityIndicatorPresenterType {
|
||||
|
||||
view.isUserInteractionEnabled = false
|
||||
|
||||
let backgroundOverlayView = self.createBackgroundOverlayView(with: view.frame)
|
||||
let backgroundOverlayView = createBackgroundOverlayView(with: view.frame)
|
||||
|
||||
let activityIndicatorView = ActivityIndicatorView()
|
||||
|
||||
@@ -89,9 +89,9 @@ final class ActivityIndicatorPresenter: ActivityIndicatorPresenterType {
|
||||
}
|
||||
|
||||
func removeCurrentActivityIndicator(animated: Bool, completion: (() -> Void)? = nil) {
|
||||
guard let presentingView = self.presentingView,
|
||||
let backgroundOverlayView = self.backgroundOverlayView,
|
||||
let activityIndicatorView = self.activityIndicatorView else {
|
||||
guard let presentingView = presentingView,
|
||||
let backgroundOverlayView = backgroundOverlayView,
|
||||
let activityIndicatorView = activityIndicatorView else {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -29,14 +29,14 @@ final class ActivityIndicatorView: UIView {
|
||||
|
||||
// MARK: Outlets
|
||||
|
||||
@IBOutlet private weak var activityIndicatorView: UIActivityIndicatorView!
|
||||
@IBOutlet private weak var activityIndicatorBackgroundView: UIView!
|
||||
@IBOutlet private var activityIndicatorView: UIActivityIndicatorView!
|
||||
@IBOutlet private var activityIndicatorBackgroundView: UIView!
|
||||
|
||||
// MARK: Public
|
||||
|
||||
var color: UIColor? {
|
||||
get {
|
||||
return activityIndicatorView.color
|
||||
activityIndicatorView.color
|
||||
}
|
||||
set {
|
||||
activityIndicatorView.color = newValue
|
||||
@@ -68,7 +68,7 @@ final class ActivityIndicatorView: UIView {
|
||||
// MARK: - Overrides
|
||||
|
||||
override var intrinsicContentSize: CGSize {
|
||||
return CGSize(width: activityIndicatorView.intrinsicContentSize.width + Constants.activityIndicatorMargin.width,
|
||||
CGSize(width: activityIndicatorView.intrinsicContentSize.width + Constants.activityIndicatorMargin.width,
|
||||
height: activityIndicatorView.intrinsicContentSize.height + Constants.activityIndicatorMargin.height)
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ final class ActivityIndicatorView: UIView {
|
||||
|
||||
private extension UIView {
|
||||
static var nib: UINib {
|
||||
return UINib(nibName: String(describing: self), bundle: Bundle(for: self))
|
||||
UINib(nibName: String(describing: self), bundle: Bundle(for: self))
|
||||
}
|
||||
|
||||
func loadNibContent() {
|
||||
|
||||
@@ -49,15 +49,14 @@ final class LabelledActivityIndicatorView: UIView {
|
||||
return view
|
||||
}()
|
||||
|
||||
private let label: UILabel = {
|
||||
UILabel()
|
||||
}()
|
||||
private let label = UILabel()
|
||||
|
||||
init(text: String) {
|
||||
super.init(frame: .zero)
|
||||
setup(text: text)
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import UIKit
|
||||
class RectangleToastView: UIView {
|
||||
|
||||
private enum Constants {
|
||||
static let padding: UIEdgeInsets = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16)
|
||||
static let padding = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16)
|
||||
static let cornerRadius: CGFloat = 8.0
|
||||
}
|
||||
|
||||
@@ -81,6 +81,7 @@ class RectangleToastView: UIView {
|
||||
layer.masksToBounds = true
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ class RoundedToastView: UIView {
|
||||
let opacity: Float
|
||||
}
|
||||
|
||||
private struct Constants {
|
||||
private enum Constants {
|
||||
static let padding = UIEdgeInsets(top: 10, left: 12, bottom: 10, right: 12)
|
||||
static let activityIndicatorScale = CGFloat(0.75)
|
||||
static let imageViewSize = CGFloat(15)
|
||||
@@ -57,15 +57,14 @@ class RoundedToastView: UIView {
|
||||
return stack
|
||||
}()
|
||||
|
||||
private let label: UILabel = {
|
||||
UILabel()
|
||||
}()
|
||||
private let label = UILabel()
|
||||
|
||||
init(viewState: ToastViewState) {
|
||||
super.init(frame: .zero)
|
||||
setup(viewState: viewState)
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import UIKit
|
||||
/// A presenter responsible for showing / hiding a toast view for loading spinners or success messages.
|
||||
/// It is managed by an `UserIndicator`, meaning the `present` and `dismiss` methods will be called when the parent `UserIndicator` starts or completes.
|
||||
class ToastViewPresenter: UserIndicatorViewPresentable {
|
||||
struct Constants {
|
||||
enum Constants {
|
||||
static let navigationBarPatting = CGFloat(10)
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ public struct WeakDictionary<Key: Hashable, Value: AnyObject> {
|
||||
|
||||
public init(dictionary: [Key: Value]) {
|
||||
var newStorage = [Key: WeakDictionaryReference<Value>]()
|
||||
dictionary.forEach({ key, value in newStorage[key] = WeakDictionaryReference<Value>(value: value) })
|
||||
dictionary.forEach { key, value in newStorage[key] = WeakDictionaryReference<Value>(value: value) }
|
||||
self.init(storage: newStorage)
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public struct WeakDictionary<Key: Hashable, Value: AnyObject> {
|
||||
}
|
||||
|
||||
public func weakDictionary() -> WeakDictionary<Key, Value> {
|
||||
return self[startIndex ..< endIndex]
|
||||
self[startIndex..<endIndex]
|
||||
}
|
||||
|
||||
public func dictionary() -> [Key: Value] {
|
||||
@@ -52,15 +52,15 @@ extension WeakDictionary: Collection {
|
||||
public typealias Index = DictionaryIndex<Key, WeakDictionaryReference<Value>>
|
||||
|
||||
public var startIndex: Index {
|
||||
return storage.startIndex
|
||||
storage.startIndex
|
||||
}
|
||||
|
||||
public var endIndex: Index {
|
||||
return storage.endIndex
|
||||
storage.endIndex
|
||||
}
|
||||
|
||||
public func index(after index: Index) -> Index {
|
||||
return storage.index(after: index)
|
||||
storage.index(after: index)
|
||||
}
|
||||
|
||||
public subscript(position: Index) -> (Key, WeakDictionaryReference<Value>) {
|
||||
@@ -90,15 +90,15 @@ extension WeakDictionary: Collection {
|
||||
let subStorage = storage[bounds.lowerBound..<bounds.upperBound]
|
||||
var newStorage = [Key: WeakDictionaryReference<Value>]()
|
||||
|
||||
subStorage.filter { _, value in return value.value != nil }
|
||||
subStorage.filter { _, value in value.value != nil }
|
||||
.forEach { key, value in newStorage[key] = value }
|
||||
|
||||
return WeakDictionary<Key, Value>(storage: newStorage)
|
||||
}
|
||||
}
|
||||
|
||||
extension Dictionary where Value: AnyObject {
|
||||
public func weakDictionary() -> WeakDictionary<Key, Value> {
|
||||
return WeakDictionary<Key, Value>(dictionary: self)
|
||||
public extension Dictionary where Value: AnyObject {
|
||||
func weakDictionary() -> WeakDictionary<Key, Value> {
|
||||
WeakDictionary<Key, Value>(dictionary: self)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ public struct WeakDictionaryKey<Key: AnyObject & Hashable, Value: AnyObject> : H
|
||||
}
|
||||
|
||||
public static func == (lhs: WeakDictionaryKey, rhs: WeakDictionaryKey) -> Bool {
|
||||
return (lhs.baseKey != nil && rhs.baseKey != nil && lhs.baseKey == rhs.baseKey)
|
||||
(lhs.baseKey != nil && rhs.baseKey != nil && lhs.baseKey == rhs.baseKey)
|
||||
|| lhs.hashValue == rhs.hashValue
|
||||
}
|
||||
|
||||
@@ -35,6 +35,6 @@ public struct WeakDictionaryKey<Key: AnyObject & Hashable, Value: AnyObject> : H
|
||||
}
|
||||
|
||||
public var key: Key? {
|
||||
return baseKey
|
||||
baseKey
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,6 @@ public struct WeakDictionaryReference<Value: AnyObject> {
|
||||
}
|
||||
|
||||
public var value: Value? {
|
||||
return referencedValue
|
||||
referencedValue
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,11 +48,11 @@ public struct WeakKeyDictionary<Key: AnyObject & Hashable, Value: AnyObject> {
|
||||
}
|
||||
|
||||
public func weakDictionary() -> WeakDictionary<Key, Value> {
|
||||
return dictionary().weakDictionary()
|
||||
dictionary().weakDictionary()
|
||||
}
|
||||
|
||||
public func weakKeyDictionary() -> WeakKeyDictionary<Key, Value> {
|
||||
return self[startIndex ..< endIndex]
|
||||
self[startIndex..<endIndex]
|
||||
}
|
||||
|
||||
public func dictionary() -> [Key: Value] {
|
||||
@@ -73,15 +73,15 @@ extension WeakKeyDictionary: Collection {
|
||||
public typealias Index = DictionaryIndex<WeakDictionaryKey<Key, Value>, WeakDictionaryReference<Value>>
|
||||
|
||||
public var startIndex: Index {
|
||||
return storage.startIndex
|
||||
storage.startIndex
|
||||
}
|
||||
|
||||
public var endIndex: Index {
|
||||
return storage.endIndex
|
||||
storage.endIndex
|
||||
}
|
||||
|
||||
public func index(after index: Index) -> Index {
|
||||
return storage.index(after: index)
|
||||
storage.index(after: index)
|
||||
}
|
||||
|
||||
public subscript(position: Index) -> (WeakDictionaryKey<Key, Value>, WeakDictionaryReference<Value>) {
|
||||
@@ -90,7 +90,7 @@ extension WeakKeyDictionary: Collection {
|
||||
|
||||
public subscript(key: Key) -> Value? {
|
||||
get {
|
||||
return storage[WeakDictionaryKey<Key, Value>(key: key)]
|
||||
storage[WeakDictionaryKey<Key, Value>(key: key)]
|
||||
}
|
||||
|
||||
set {
|
||||
@@ -104,21 +104,21 @@ extension WeakKeyDictionary: Collection {
|
||||
let subStorage = storage[bounds.lowerBound..<bounds.upperBound]
|
||||
var newStorage = WeakDictionary<WeakDictionaryKey<Key, Value>, Value>()
|
||||
|
||||
subStorage.filter { key, value in return key.key != nil && value.value != nil }
|
||||
subStorage.filter { key, value in key.key != nil && value.value != nil }
|
||||
.forEach { key, value in newStorage[key] = value.value }
|
||||
|
||||
return WeakKeyDictionary<Key, Value>(storage: newStorage)
|
||||
}
|
||||
}
|
||||
|
||||
extension WeakDictionary where Key: AnyObject {
|
||||
public func weakKeyDictionary(valuesRetainedByKey: Bool = false) -> WeakKeyDictionary<Key, Value> {
|
||||
return WeakKeyDictionary<Key, Value>(dictionary: dictionary(), valuesRetainedByKey: valuesRetainedByKey)
|
||||
public extension WeakDictionary where Key: AnyObject {
|
||||
func weakKeyDictionary(valuesRetainedByKey: Bool = false) -> WeakKeyDictionary<Key, Value> {
|
||||
WeakKeyDictionary<Key, Value>(dictionary: dictionary(), valuesRetainedByKey: valuesRetainedByKey)
|
||||
}
|
||||
}
|
||||
|
||||
extension Dictionary where Key: AnyObject, Value: AnyObject {
|
||||
public func weakKeyDictionary(valuesRetainedByKey: Bool = false) -> WeakKeyDictionary<Key, Value> {
|
||||
return WeakKeyDictionary<Key, Value>(dictionary: self, valuesRetainedByKey: valuesRetainedByKey)
|
||||
public extension Dictionary where Key: AnyObject, Value: AnyObject {
|
||||
func weakKeyDictionary(valuesRetainedByKey: Bool = false) -> WeakKeyDictionary<Key, Value> {
|
||||
WeakKeyDictionary<Key, Value>(dictionary: self, valuesRetainedByKey: valuesRetainedByKey)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import MatrixRustSDK
|
||||
import UIKit
|
||||
|
||||
@MainActor
|
||||
protocol AuthenticationCoordinatorDelegate: AnyObject {
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import MatrixRustSDK
|
||||
import SwiftUI
|
||||
|
||||
struct LoginCoordinatorParameters {
|
||||
/// The service used to authenticate the user.
|
||||
@@ -73,6 +73,7 @@ final class LoginCoordinator: Coordinator, Presentable {
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
func start() {
|
||||
MXLog.debug("[LoginCoordinator] did start.")
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ struct LoginViewState: BindableState {
|
||||
/// Data about the selected homeserver.
|
||||
var homeserver: LoginHomeserver
|
||||
/// Whether a new homeserver is currently being loaded.
|
||||
var isLoading: Bool = false
|
||||
var isLoading = false
|
||||
/// View state that can be bound to from SwiftUI.
|
||||
var bindings: LoginBindings
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ class BugReportViewModel: BugReportViewModelType, BugReportViewModelProtocol {
|
||||
files: files)
|
||||
MXLog.info("[BugReportViewModel] submitBugReport succeeded, result: \(result.reportUrl)")
|
||||
callback?(.submitFinished)
|
||||
} catch let error {
|
||||
} catch {
|
||||
MXLog.error("[BugReportViewModel] submitBugReport failed: \(error)")
|
||||
callback?(.submitFailed(error: error))
|
||||
}
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
struct HomeScreenCoordinatorParameters {
|
||||
let userSession: UserSessionProtocol
|
||||
@@ -108,12 +108,11 @@ final class HomeScreenCoordinator: Coordinator, Presentable {
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
func start() {
|
||||
|
||||
}
|
||||
func start() { }
|
||||
|
||||
func toPresentable() -> UIViewController {
|
||||
return self.hostingController
|
||||
hostingController
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
@@ -34,14 +34,14 @@ struct HomeScreenViewState: BindableState {
|
||||
var userDisplayName: String?
|
||||
var userAvatar: UIImage?
|
||||
|
||||
var showSessionVerificationBanner: Bool = false
|
||||
var showSessionVerificationBanner = false
|
||||
|
||||
var rooms: [HomeScreenRoom] = []
|
||||
|
||||
var isLoadingRooms: Bool = false
|
||||
var isLoadingRooms = false
|
||||
|
||||
var visibleDMs: [HomeScreenRoom] {
|
||||
searchFilteredRooms.filter { $0.isDirect }
|
||||
searchFilteredRooms.filter(\.isDirect)
|
||||
}
|
||||
|
||||
var visibleRooms: [HomeScreenRoom] {
|
||||
@@ -62,7 +62,7 @@ struct HomeScreenViewState: BindableState {
|
||||
}
|
||||
|
||||
struct HomeScreenViewStateBindings {
|
||||
var searchQuery: String = ""
|
||||
var searchQuery = ""
|
||||
}
|
||||
|
||||
struct HomeScreenRoom: Identifiable, Equatable {
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
typealias HomeScreenViewModelType = StateStoreViewModel<HomeScreenViewState, HomeScreenViewAction>
|
||||
|
||||
@@ -65,7 +65,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
|
||||
roomUpdateListeners.removeAll()
|
||||
|
||||
roomSummaries.forEach({ roomSummary in
|
||||
roomSummaries.forEach { roomSummary in
|
||||
roomSummary.callbacks
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { [weak self] callback in
|
||||
@@ -81,7 +81,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
}
|
||||
}
|
||||
.store(in: &roomUpdateListeners)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -55,11 +55,10 @@ final class RoomScreenCoordinator: Coordinator, Presentable {
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
func start() {
|
||||
|
||||
}
|
||||
func start() { }
|
||||
|
||||
func toPresentable() -> UIViewController {
|
||||
return self.roomScreenHostingController
|
||||
roomScreenHostingController
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,7 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
enum RoomScreenViewModelAction {
|
||||
|
||||
}
|
||||
enum RoomScreenViewModelAction { }
|
||||
|
||||
enum TimelineItemContextMenuAction: Hashable {
|
||||
case copy
|
||||
@@ -35,7 +33,7 @@ enum RoomScreenViewAction {
|
||||
}
|
||||
|
||||
struct RoomScreenViewState: BindableState {
|
||||
var roomTitle: String = ""
|
||||
var roomTitle = ""
|
||||
var roomAvatar: UIImage?
|
||||
var roomEncryptionBadge: UIImage?
|
||||
var items: [RoomTimelineViewProvider] = []
|
||||
|
||||
@@ -20,7 +20,7 @@ typealias RoomScreenViewModelType = StateStoreViewModel<RoomScreenViewState, Roo
|
||||
|
||||
class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol {
|
||||
|
||||
private struct Constants {
|
||||
private enum Constants {
|
||||
static let backPaginationPageSize: UInt = 30
|
||||
}
|
||||
|
||||
@@ -106,13 +106,13 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
// MARK: ContextMenus
|
||||
|
||||
private func buildContexMenuForItemId(_ itemId: String) -> TimelineItemContextMenu {
|
||||
TimelineItemContextMenu(contextMenuActions: self.contextMenuActionsForItemId(itemId)) { [weak self] action in
|
||||
TimelineItemContextMenu(contextMenuActions: contextMenuActionsForItemId(itemId)) { [weak self] action in
|
||||
self?.processContentMenuAction(action, itemId: itemId)
|
||||
}
|
||||
}
|
||||
|
||||
private func contextMenuActionsForItemId(_ itemId: String) -> [TimelineItemContextMenuAction] {
|
||||
guard let timelineItem = self.timelineController.timelineItems.first(where: { $0.id == itemId }),
|
||||
guard let timelineItem = timelineController.timelineItems.first(where: { $0.id == itemId }),
|
||||
timelineItem is EventBasedTimelineItemProtocol else {
|
||||
return []
|
||||
}
|
||||
@@ -121,7 +121,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
}
|
||||
|
||||
private func processContentMenuAction(_ action: TimelineItemContextMenuAction, itemId: String) {
|
||||
guard let timelineItem = self.timelineController.timelineItems.first(where: { $0.id == itemId }),
|
||||
guard let timelineItem = timelineController.timelineItems.first(where: { $0.id == itemId }),
|
||||
let item = timelineItem as? EventBasedTimelineItemProtocol else {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Combine
|
||||
import UIKit
|
||||
|
||||
class ListTableViewAdapter: NSObject, UITableViewDelegate {
|
||||
|
||||
@@ -89,7 +89,7 @@ class ListTableViewAdapter: NSObject, UITableViewDelegate {
|
||||
case .bottomOffset:
|
||||
tableView.scrollToRow(at: .init(row: max(0, currentItemCount - 1), section: 0), at: .bottom, animated: false)
|
||||
case .topOffset(let indexPath, let previousItemCount):
|
||||
let row = indexPath.row + max(0, (currentItemCount - previousItemCount))
|
||||
let row = indexPath.row + max(0, currentItemCount - previousItemCount)
|
||||
if row < currentItemCount {
|
||||
tableView.scrollToRow(at: .init(row: row, section: 0), at: .top, animated: false)
|
||||
}
|
||||
@@ -180,9 +180,9 @@ class ListTableViewAdapter: NSObject, UITableViewDelegate {
|
||||
scrollViewBottomVisiblePublisher.send(isBottomVisible)
|
||||
}
|
||||
|
||||
if !draggingInitiated && tableView.isDragging {
|
||||
if !draggingInitiated, tableView.isDragging {
|
||||
draggingInitiated = true
|
||||
} else if draggingInitiated && !tableView.isDragging {
|
||||
} else if draggingInitiated, !tableView.isDragging {
|
||||
draggingInitiated = false
|
||||
scrollViewDidRestPublisher.send(())
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ struct MessageComposerTextField: View {
|
||||
|
||||
init(placeholder: String, text: Binding<String>, maxHeight: CGFloat) {
|
||||
self.placeholder = placeholder
|
||||
self._text = text
|
||||
_text = text
|
||||
self.maxHeight = maxHeight
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ struct MessageComposerTextField: View {
|
||||
}
|
||||
|
||||
private var borderWidth: CGFloat {
|
||||
return isEditing ? 2.0 : 1.0
|
||||
isEditing ? 2.0 : 1.0
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
@@ -89,15 +89,15 @@ private struct UITextViewWrapper: UIViewRepresentable {
|
||||
}
|
||||
|
||||
func updateUIView(_ view: UITextView, context: UIViewRepresentableContext<UITextViewWrapper>) {
|
||||
if view.text != self.text {
|
||||
view.text = self.text
|
||||
if view.text != text {
|
||||
view.text = text
|
||||
}
|
||||
|
||||
UITextViewWrapper.recalculateHeight(view: view, result: $calculatedHeight, maxHeight: maxHeight)
|
||||
}
|
||||
|
||||
func makeCoordinator() -> Coordinator {
|
||||
return Coordinator(text: $text,
|
||||
Coordinator(text: $text,
|
||||
height: $calculatedHeight,
|
||||
isEditing: $isEditing,
|
||||
maxHeight: maxHeight)
|
||||
@@ -124,7 +124,7 @@ private struct UITextViewWrapper: UIViewRepresentable {
|
||||
|
||||
init(text: Binding<String>, height: Binding<CGFloat>, isEditing: Binding<Bool>, maxHeight: CGFloat) {
|
||||
self.text = text
|
||||
self.calculatedHeight = height
|
||||
calculatedHeight = height
|
||||
self.isEditing = isEditing
|
||||
self.maxHeight = maxHeight
|
||||
}
|
||||
@@ -137,7 +137,7 @@ private struct UITextViewWrapper: UIViewRepresentable {
|
||||
}
|
||||
|
||||
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
|
||||
return true
|
||||
true
|
||||
}
|
||||
|
||||
func textViewDidBeginEditing(_ textView: UITextView) {
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
import Combine
|
||||
|
||||
import Introspect
|
||||
|
||||
@@ -65,8 +65,7 @@ struct RoomHeaderView_Previews: PreviewProvider {
|
||||
let viewModel = RoomScreenViewModel(timelineController: MockRoomTimelineController(),
|
||||
timelineViewFactory: RoomTimelineViewFactory(),
|
||||
roomName: "Some Room name",
|
||||
roomAvatar: Asset.Images.appLogo.image
|
||||
)
|
||||
roomAvatar: Asset.Images.appLogo.image)
|
||||
|
||||
RoomHeaderView(context: viewModel.context)
|
||||
.previewLayout(.sizeThatFits)
|
||||
@@ -79,8 +78,7 @@ struct RoomHeaderView_Previews: PreviewProvider {
|
||||
timelineViewFactory: RoomTimelineViewFactory(),
|
||||
roomName: "Some Room name",
|
||||
roomAvatar: nil,
|
||||
roomEncryptionBadge: Asset.Images.encryptionTrusted.image
|
||||
)
|
||||
roomEncryptionBadge: Asset.Images.encryptionTrusted.image)
|
||||
|
||||
RoomHeaderView(context: viewModel.context)
|
||||
.previewLayout(.sizeThatFits)
|
||||
|
||||
@@ -89,7 +89,7 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
|
||||
}
|
||||
|
||||
private var shouldAvoidBubbling: Bool {
|
||||
return timelineItem is ImageRoomTimelineItem
|
||||
timelineItem is ImageRoomTimelineItem
|
||||
}
|
||||
|
||||
private var bubbleColor: Color {
|
||||
@@ -108,7 +108,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider {
|
||||
@ViewBuilder
|
||||
static var body: some View {
|
||||
VStack(alignment: .leading) {
|
||||
ForEach((1..<MockRoomTimelineController().timelineItems.count), id: \.self) { index in
|
||||
ForEach(1..<MockRoomTimelineController().timelineItems.count, id: \.self) { index in
|
||||
let item = MockRoomTimelineController().timelineItems[index]
|
||||
RoomTimelineViewFactory().buildTimelineViewFor(timelineItem: item)
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ struct TimelineItemPlainStylerView_Previews: PreviewProvider {
|
||||
@ViewBuilder
|
||||
static var body: some View {
|
||||
VStack(alignment: .leading) {
|
||||
ForEach((1..<MockRoomTimelineController().timelineItems.count), id: \.self) { index in
|
||||
ForEach(1..<MockRoomTimelineController().timelineItems.count, id: \.self) { index in
|
||||
let item = MockRoomTimelineController().timelineItems[index]
|
||||
RoomTimelineViewFactory().buildTimelineViewFor(timelineItem: item)
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ struct EmoteRoomTimelineView_Previews: PreviewProvider {
|
||||
}
|
||||
|
||||
private static func itemWith(text: String, timestamp: String, senderId: String) -> EmoteRoomTimelineItem {
|
||||
return EmoteRoomTimelineItem(id: UUID().uuidString,
|
||||
EmoteRoomTimelineItem(id: UUID().uuidString,
|
||||
text: text,
|
||||
timestamp: timestamp,
|
||||
shouldShowSenderDetails: true,
|
||||
|
||||
@@ -63,7 +63,8 @@ Text after blockquote
|
||||
<code><b>Hello</b> <i>world</i></code>
|
||||
<p>Text</p>
|
||||
<code>Hello world</code>
|
||||
"""]
|
||||
"""
|
||||
]
|
||||
|
||||
let attributedStringBuilder = AttributedStringBuilder()
|
||||
VStack(alignment: .leading, spacing: 24.0) {
|
||||
|
||||
@@ -49,7 +49,7 @@ struct NoticeRoomTimelineView_Previews: PreviewProvider {
|
||||
}
|
||||
|
||||
private static func itemWith(text: String, timestamp: String, senderId: String) -> NoticeRoomTimelineItem {
|
||||
return NoticeRoomTimelineItem(id: UUID().uuidString,
|
||||
NoticeRoomTimelineItem(id: UUID().uuidString,
|
||||
text: text,
|
||||
timestamp: timestamp,
|
||||
shouldShowSenderDetails: true,
|
||||
|
||||
@@ -65,7 +65,7 @@ struct TextRoomTimelineView_Previews: PreviewProvider {
|
||||
}
|
||||
|
||||
private static func itemWith(text: String, timestamp: String, shouldShowSenderDetails: Bool, isOutgoing: Bool, senderId: String) -> TextRoomTimelineItem {
|
||||
return TextRoomTimelineItem(id: UUID().uuidString,
|
||||
TextRoomTimelineItem(id: UUID().uuidString,
|
||||
text: text,
|
||||
timestamp: timestamp,
|
||||
shouldShowSenderDetails: shouldShowSenderDetails,
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Combine
|
||||
import Introspect
|
||||
import SwiftUI
|
||||
|
||||
struct TimelineItemList: View {
|
||||
|
||||
@State private var tableViewObserver: ListTableViewAdapter = ListTableViewAdapter()
|
||||
@State private var tableViewObserver = ListTableViewAdapter()
|
||||
@State private var timelineItems: [RoomTimelineViewProvider] = []
|
||||
@State private var hasPendingChanges = false
|
||||
@ObservedObject private var settings = ElementSettings.shared
|
||||
@@ -65,7 +65,7 @@ struct TimelineItemList: View {
|
||||
}
|
||||
|
||||
tableViewObserver = ListTableViewAdapter(tableView: tableView,
|
||||
topDetectionOffset: (tableView.bounds.size.height / 3.0),
|
||||
topDetectionOffset: tableView.bounds.size.height / 3.0,
|
||||
bottomDetectionOffset: 10.0)
|
||||
|
||||
tableViewObserver.scrollToBottom()
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
import Combine
|
||||
|
||||
import Introspect
|
||||
|
||||
|
||||
@@ -115,6 +115,7 @@ class SessionVerificationStateMachine {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// swiftlint:enable cyclomatic_complexity
|
||||
|
||||
/// Attempt to move the state machine to another state through an event
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import MatrixRustSDK
|
||||
import SwiftUI
|
||||
|
||||
struct SessionVerificationScreen: View {
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ final class SettingsCoordinator: Coordinator, Presentable {
|
||||
|
||||
add(childCoordinator: coordinator)
|
||||
coordinator.start()
|
||||
self.parameters.navigationRouter.push(coordinator, animated: true) { [weak self] in
|
||||
parameters.navigationRouter.push(coordinator, animated: true) { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.remove(childCoordinator: coordinator)
|
||||
|
||||
@@ -32,9 +32,7 @@ struct SettingsViewState: BindableState {
|
||||
var bindings: SettingsViewStateBindings
|
||||
}
|
||||
|
||||
struct SettingsViewStateBindings {
|
||||
|
||||
}
|
||||
struct SettingsViewStateBindings { }
|
||||
|
||||
enum SettingsViewAction {
|
||||
case reportBug
|
||||
|
||||
@@ -8,6 +8,4 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
class SplashViewController: UIViewController {
|
||||
|
||||
}
|
||||
class SplashViewController: UIViewController { }
|
||||
|
||||
@@ -46,6 +46,7 @@ final class SplashScreenCoordinator: Coordinator, Presentable {
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
func start() {
|
||||
MXLog.debug("[SplashScreenCoordinator] did start.")
|
||||
splashScreenViewModel.callback = { [weak self] action in
|
||||
@@ -59,7 +60,7 @@ final class SplashScreenCoordinator: Coordinator, Presentable {
|
||||
}
|
||||
|
||||
func toPresentable() -> UIViewController {
|
||||
return splashScreenHostingController
|
||||
splashScreenHostingController
|
||||
}
|
||||
|
||||
/// Stops any ongoing activities in the coordinator.
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
typealias SplashScreenViewModelType = StateStoreViewModel<SplashScreenViewState, SplashScreenViewAction>
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import DesignKit
|
||||
import SwiftUI
|
||||
|
||||
/// The splash screen shown at the beginning of the onboarding flow.
|
||||
struct SplashScreen: View {
|
||||
@@ -152,7 +152,7 @@ struct SplashScreen: View {
|
||||
|
||||
private func showPreviousPage() {
|
||||
// Prevent the hidden page at index -1 from being shown.
|
||||
context.pageIndex = max(0, (context.pageIndex - 1))
|
||||
context.pageIndex = max(0, context.pageIndex - 1)
|
||||
}
|
||||
|
||||
private func showHiddenPage() {
|
||||
|
||||
@@ -15,7 +15,7 @@ class AuthenticationService: AuthenticationServiceProtocol {
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private(set) var homeserver: LoginHomeserver = LoginHomeserver(address: BuildSettings.defaultHomeserverURLString)
|
||||
private(set) var homeserver = LoginHomeserver(address: BuildSettings.defaultHomeserverURLString)
|
||||
private let userSessionStore: UserSessionStoreProtocol
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
@@ -19,20 +19,20 @@ protocol BackgroundTaskServiceProtocol {
|
||||
extension BackgroundTaskServiceProtocol {
|
||||
|
||||
func startBackgroundTask(withName name: String) -> BackgroundTaskProtocol? {
|
||||
return startBackgroundTask(withName: name,
|
||||
startBackgroundTask(withName: name,
|
||||
expirationHandler: nil)
|
||||
}
|
||||
|
||||
func startBackgroundTask(withName name: String,
|
||||
isReusable: Bool) -> BackgroundTaskProtocol? {
|
||||
return startBackgroundTask(withName: name,
|
||||
startBackgroundTask(withName: name,
|
||||
isReusable: isReusable,
|
||||
expirationHandler: nil)
|
||||
}
|
||||
|
||||
func startBackgroundTask(withName name: String,
|
||||
expirationHandler: (() -> Void)?) -> BackgroundTaskProtocol? {
|
||||
return startBackgroundTask(withName: name,
|
||||
startBackgroundTask(withName: name,
|
||||
isReusable: false,
|
||||
expirationHandler: expirationHandler)
|
||||
}
|
||||
|
||||
@@ -15,16 +15,17 @@ class UIKitBackgroundTask: BackgroundTaskProtocol {
|
||||
var isRunning: Bool {
|
||||
identifier != .invalid
|
||||
}
|
||||
|
||||
let isReusable: Bool
|
||||
let expirationHandler: BackgroundTaskExpirationHandler?
|
||||
var elapsedTime: TimeInterval {
|
||||
return Date().timeIntervalSince(startDate) * 1000
|
||||
Date().timeIntervalSince(startDate) * 1000
|
||||
}
|
||||
|
||||
private let application: ApplicationProtocol
|
||||
private var identifier: UIBackgroundTaskIdentifier = .invalid
|
||||
private var useCounter: Int = 0
|
||||
private let startDate: Date = Date()
|
||||
private var useCounter = 0
|
||||
private let startDate = Date()
|
||||
|
||||
/// Initializes and starts a new background task
|
||||
/// - Parameters:
|
||||
|
||||
@@ -35,7 +35,7 @@ class UIKitBackgroundTaskService: BackgroundTaskServiceProtocol {
|
||||
expirationHandler?()
|
||||
return nil
|
||||
}
|
||||
var created: Bool = false
|
||||
var created = false
|
||||
var result: BackgroundTaskProtocol?
|
||||
|
||||
if isReusable {
|
||||
@@ -85,8 +85,8 @@ class UIKitBackgroundTaskService: BackgroundTaskServiceProtocol {
|
||||
}
|
||||
|
||||
private func avoidStartingNewTasks(for application: ApplicationProtocol) -> Bool {
|
||||
if application.applicationState == .background
|
||||
&& application.backgroundTimeRemaining < .backgroundTimeRemainingThresholdToStartTasks {
|
||||
if application.applicationState == .background,
|
||||
application.backgroundTimeRemaining < .backgroundTimeRemainingThresholdToStartTasks {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
import UIKit
|
||||
import GZIP
|
||||
import MatrixRustSDK
|
||||
import Sentry
|
||||
import UIKit
|
||||
|
||||
enum BugReportServiceError: Error {
|
||||
case invalidBaseUrlString
|
||||
@@ -33,7 +33,7 @@ class BugReportService: BugReportServiceProtocol {
|
||||
guard !sentryEndpoint.isEmpty else {
|
||||
throw BugReportServiceError.invalidSentryEndpoint
|
||||
}
|
||||
self.baseURL = url
|
||||
baseURL = url
|
||||
self.sentryEndpoint = sentryEndpoint
|
||||
self.applicationId = applicationId
|
||||
self.session = session
|
||||
@@ -69,7 +69,7 @@ class BugReportService: BugReportServiceProtocol {
|
||||
// MARK: - BugReportServiceProtocol
|
||||
|
||||
var crashedLastRun: Bool {
|
||||
return SentrySDK.crashedLastRun
|
||||
SentrySDK.crashedLastRun
|
||||
}
|
||||
|
||||
func crash() {
|
||||
@@ -182,8 +182,8 @@ class BugReportService: BugReportServiceProtocol {
|
||||
filesToCompress.append(URL(fileURLWithPath: crashLogFile))
|
||||
}
|
||||
|
||||
var totalSize: Int = 0
|
||||
var totalZippedSize: Int = 0
|
||||
var totalSize = 0
|
||||
var totalZippedSize = 0
|
||||
var zippedFiles: [URL] = []
|
||||
|
||||
for url in filesToCompress {
|
||||
|
||||
@@ -16,10 +16,10 @@ class MockBugReportService: BugReportServiceProtocol {
|
||||
includeCrashLog: Bool,
|
||||
githubLabels: [String],
|
||||
files: [URL]) async throws -> SubmitBugReportResponse {
|
||||
return SubmitBugReportResponse(reportUrl: "https://www.example/com/123")
|
||||
SubmitBugReportResponse(reportUrl: "https://www.example/com/123")
|
||||
}
|
||||
|
||||
var crashedLastRun: Bool = false
|
||||
var crashedLastRun = false
|
||||
|
||||
func crash() {
|
||||
// no-op
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Photos
|
||||
import UIKit
|
||||
|
||||
enum ScreenshotDetectorError: String, Error {
|
||||
case loadFailed
|
||||
@@ -38,7 +38,7 @@ class ScreenshotDetector {
|
||||
let authStatus = PHPhotoLibrary.authorizationStatus(for: .readWrite)
|
||||
if authStatus == .authorized {
|
||||
findScreenshot()
|
||||
} else if authStatus == .notDetermined && autoRequestPHAuthorization {
|
||||
} else if authStatus == .notDetermined, autoRequestPHAuthorization {
|
||||
Task {
|
||||
self.handleAuthStatus(await PHPhotoLibrary.requestAuthorization(for: .readWrite))
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
import Combine
|
||||
import UIKit
|
||||
|
||||
private class WeakClientProxyWrapper: ClientDelegate {
|
||||
@@ -128,7 +128,7 @@ class ClientProxy: ClientProxyProtocol {
|
||||
Benchmark.endTrackingForIdentifier("ClientRooms", message: "Retrieved \(sdkRooms.count) rooms")
|
||||
|
||||
Benchmark.startTrackingForIdentifier("ProcessingRooms", message: "Started processing \(sdkRooms.count) rooms")
|
||||
let diff = sdkRooms.map({ $0.id() }).difference(from: currentRooms.map(\.id))
|
||||
let diff = sdkRooms.map { $0.id() }.difference(from: currentRooms.map(\.id))
|
||||
|
||||
for change in diff {
|
||||
switch change {
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
import Combine
|
||||
|
||||
enum ClientProxyCallback {
|
||||
case updatedRoomsList
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Kingfisher
|
||||
import UIKit
|
||||
|
||||
struct MediaProvider: MediaProviderProtocol {
|
||||
private let clientProxy: ClientProxyProtocol
|
||||
@@ -21,7 +21,7 @@ struct MediaProvider: MediaProviderProtocol {
|
||||
self.clientProxy = clientProxy
|
||||
self.imageCache = imageCache
|
||||
self.backgroundTaskService = backgroundTaskService
|
||||
self.processingQueue = DispatchQueue(label: "MediaProviderProcessingQueue", attributes: .concurrent)
|
||||
processingQueue = DispatchQueue(label: "MediaProviderProcessingQueue", attributes: .concurrent)
|
||||
}
|
||||
|
||||
func imageFromSource(_ source: MediaSource?) -> UIImage? {
|
||||
|
||||
@@ -23,6 +23,6 @@ struct MediaSource: Equatable {
|
||||
// MARK: - Equatable
|
||||
|
||||
static func == (lhs: MediaSource, rhs: MediaSource) -> Bool {
|
||||
return lhs.underlyingSource.url() == rhs.underlyingSource.url()
|
||||
lhs.underlyingSource.url() == rhs.underlyingSource.url()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,18 +12,18 @@ import UIKit
|
||||
struct MockMediaProvider: MediaProviderProtocol {
|
||||
|
||||
func imageFromSource(_ source: MediaSource?) -> UIImage? {
|
||||
return nil
|
||||
nil
|
||||
}
|
||||
|
||||
func loadImageFromSource(_ source: MediaSource) async -> Result<UIImage, MediaProviderError> {
|
||||
return .failure(.failedRetrievingImage)
|
||||
.failure(.failedRetrievingImage)
|
||||
}
|
||||
|
||||
func imageFromURLString(_ urlString: String?) -> UIImage? {
|
||||
return nil
|
||||
nil
|
||||
}
|
||||
|
||||
func loadImageFromURLString(_ urlString: String) async -> Result<UIImage, MediaProviderError> {
|
||||
return .failure(.failedRetrievingImage)
|
||||
.failure(.failedRetrievingImage)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import MatrixRustSDK
|
||||
import UIKit
|
||||
|
||||
struct EmoteRoomMessage: RoomMessageProtocol {
|
||||
private let message: MatrixRustSDK.EmoteMessage
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import MatrixRustSDK
|
||||
import UIKit
|
||||
|
||||
struct ImageRoomMessage: RoomMessageProtocol {
|
||||
private let message: MatrixRustSDK.ImageMessage
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import MatrixRustSDK
|
||||
import UIKit
|
||||
|
||||
struct NoticeRoomMessage: RoomMessageProtocol {
|
||||
private let message: MatrixRustSDK.NoticeMessage
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import MatrixRustSDK
|
||||
import UIKit
|
||||
|
||||
struct TextRoomMessage: RoomMessageProtocol {
|
||||
private let message: MatrixRustSDK.TextMessage
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Combine
|
||||
|
||||
struct MockRoomProxy: RoomProxyProtocol {
|
||||
let id = UUID().uuidString
|
||||
@@ -29,26 +29,24 @@ struct MockRoomProxy: RoomProxyProtocol {
|
||||
var callbacks = PassthroughSubject<RoomProxyCallback, Never>()
|
||||
|
||||
func loadDisplayNameForUserId(_ userId: String) async -> Result<String?, RoomProxyError> {
|
||||
return .failure(.failedRetrievingMemberDisplayName)
|
||||
.failure(.failedRetrievingMemberDisplayName)
|
||||
}
|
||||
|
||||
func loadAvatarURLForUserId(_ userId: String) async -> Result<String?, RoomProxyError> {
|
||||
return .failure(.failedRetrievingMemberAvatarURL)
|
||||
.failure(.failedRetrievingMemberAvatarURL)
|
||||
}
|
||||
|
||||
func loadDisplayName() async -> Result<String, RoomProxyError> {
|
||||
return .failure(.failedRetrievingDisplayName)
|
||||
.failure(.failedRetrievingDisplayName)
|
||||
}
|
||||
|
||||
func startLiveEventListener() {
|
||||
|
||||
}
|
||||
func startLiveEventListener() { }
|
||||
|
||||
func paginateBackwards(count: UInt) async -> Result<Void, RoomProxyError> {
|
||||
return .failure(.backwardStreamNotAvailable)
|
||||
.failure(.backwardStreamNotAvailable)
|
||||
}
|
||||
|
||||
func sendMessage(_ message: String) async -> Result<Void, RoomProxyError> {
|
||||
return .failure(.failedSendingMessage)
|
||||
.failure(.failedSendingMessage)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Combine
|
||||
|
||||
import MatrixRustSDK
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Combine
|
||||
import UIKit
|
||||
|
||||
enum RoomProxyError: Error {
|
||||
case failedRetrievingDisplayName
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Combine
|
||||
import UIKit
|
||||
|
||||
struct MockRoomSummary: RoomSummaryProtocol {
|
||||
var id: String = UUID().uuidString
|
||||
@@ -18,21 +18,19 @@ struct MockRoomSummary: RoomSummaryProtocol {
|
||||
|
||||
var topic: String?
|
||||
|
||||
var isDirect: Bool = false
|
||||
var isDirect = false
|
||||
|
||||
var isEncrypted: Bool = false
|
||||
var isEncrypted = false
|
||||
|
||||
var isSpace: Bool = false
|
||||
var isSpace = false
|
||||
|
||||
var isTombstoned: Bool = false
|
||||
var isTombstoned = false
|
||||
|
||||
var lastMessage: EventBrief?
|
||||
|
||||
var avatar: UIImage?
|
||||
|
||||
func loadDetails() async {
|
||||
|
||||
}
|
||||
func loadDetails() async { }
|
||||
|
||||
var callbacks = PassthroughSubject<RoomSummaryCallback, Never>()
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Combine
|
||||
|
||||
class RoomSummary: RoomSummaryProtocol {
|
||||
private let roomProxy: RoomProxyProtocol
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Combine
|
||||
import UIKit
|
||||
|
||||
enum RoomSummaryCallback {
|
||||
case updatedData
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
import Foundation
|
||||
|
||||
class UserSession: UserSessionProtocol {
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
import Foundation
|
||||
|
||||
enum UserSessionCallback {
|
||||
case sessionVerificationNeeded
|
||||
|
||||
+4
-3
@@ -6,14 +6,14 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
import Combine
|
||||
|
||||
struct MockSessionVerificationControllerProxy: SessionVerificationControllerProxyProtocol {
|
||||
var callbacks = PassthroughSubject<SessionVerificationControllerProxyCallback, Never>()
|
||||
|
||||
var isVerified: Bool = false
|
||||
var isVerified = false
|
||||
|
||||
func requestVerification() async -> Result<Void, SessionVerificationControllerProxyError> {
|
||||
DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + 2.0) {
|
||||
@@ -50,7 +50,8 @@ struct MockSessionVerificationControllerProxy: SessionVerificationControllerProx
|
||||
// MARK: - Private
|
||||
|
||||
static var emojis: [SessionVerificationEmoji] {
|
||||
[SessionVerificationEmoji(symbol: "🦋", description: "Butterfly"),
|
||||
[
|
||||
SessionVerificationEmoji(symbol: "🦋", description: "Butterfly"),
|
||||
SessionVerificationEmoji(symbol: "🐘", description: "Elephant"),
|
||||
SessionVerificationEmoji(symbol: "🦋", description: "Butterfly"),
|
||||
SessionVerificationEmoji(symbol: "🎂", description: "Cake"),
|
||||
|
||||
+1
-1
@@ -6,9 +6,9 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
import Combine
|
||||
|
||||
private class WeakSessionVerificationControllerProxy: SessionVerificationControllerDelegate {
|
||||
private weak var proxy: SessionVerificationControllerProxy?
|
||||
|
||||
+1
-1
@@ -6,8 +6,8 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
import Foundation
|
||||
|
||||
enum SessionVerificationControllerProxyError: Error {
|
||||
case failedRequestingVerification
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
import Foundation
|
||||
|
||||
class MockRoomTimelineController: RoomTimelineControllerProtocol {
|
||||
|
||||
@@ -40,18 +40,12 @@ class MockRoomTimelineController: RoomTimelineControllerProtocol {
|
||||
senderDisplayName: "Bob")]
|
||||
|
||||
func paginateBackwards(_ count: UInt) async -> Result<Void, RoomTimelineControllerError> {
|
||||
return .failure(.generic)
|
||||
.failure(.generic)
|
||||
}
|
||||
|
||||
func processItemAppearance(_ itemId: String) async {
|
||||
func processItemAppearance(_ itemId: String) async { }
|
||||
|
||||
}
|
||||
|
||||
func processItemDisappearance(_ itemId: String) async {
|
||||
|
||||
}
|
||||
|
||||
func sendMessage(_ message: String) async {
|
||||
|
||||
}
|
||||
func processItemDisappearance(_ itemId: String) async { }
|
||||
|
||||
func sendMessage(_ message: String) async { }
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
class RoomTimelineController: RoomTimelineControllerProtocol {
|
||||
@@ -79,9 +79,7 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
func processItemDisappearance(_ itemId: String) {
|
||||
|
||||
}
|
||||
func processItemDisappearance(_ itemId: String) { }
|
||||
|
||||
func sendMessage(_ message: String) async {
|
||||
switch await timelineProvider.sendMessage(message) {
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
import Foundation
|
||||
|
||||
enum RoomTimelineControllerCallback {
|
||||
case updatedTimelineItems
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
import Foundation
|
||||
|
||||
class RoomTimelineProvider: RoomTimelineProviderProtocol {
|
||||
private let roomProxy: RoomProxyProtocol
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user