session-ios/SessionMessagingKit/Database/Models/Capability.swift
Morgan Pretty 1224e539ea Reduced unneeded DB write operations and fixed a few minor UI bugs
Updated the database to better support the application getting suspended (0xdead10cc crash)
Updated the SOGS message handling to delete messages based on a new 'deleted' flag instead of 'data' being null
Updated the code to prevent the typing indicator from needing a DB write block as frequently
Updated the code to stop any pending jobs when entering the background (in an attempt to prevent the database suspension from causing issues)
Removed the duplicate 'Capabilities.Capability' type (updated 'Capability.Variant' to work in the same way)
Fixed a bug where a number of icons (inc. the "download document" icon) were the wrong colour in dark mode
Fixed a bug where the '@You' highlight could incorrectly have it's width reduced in some cases (had protection to prevent it being larger than the line, but that is a valid case)
Fixed a bug where the JobRunner was starting the background (which could lead to trying to access the database once it had been suspended)
Updated to the latest version of GRDB
Added some logic to the BackgroundPoller process to try and stop processing if the timeout is triggered (will catch some cases but others will end up logging a bunch of "Database is suspended" errors)
Added in some protection to prevent future deferral loops in the JobRunner
2022-08-05 17:10:01 +10:00

95 lines
3.1 KiB
Swift

// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
import Foundation
import GRDB
import SessionUtilitiesKit
public struct Capability: Codable, FetchableRecord, PersistableRecord, TableRecord, ColumnExpressible {
public static var databaseTableName: String { "capability" }
public typealias Columns = CodingKeys
public enum CodingKeys: String, CodingKey, ColumnExpression {
case openGroupServer
case variant
case isMissing
}
public enum Variant: Equatable, Hashable, CaseIterable, Codable, DatabaseValueConvertible {
public static var allCases: [Variant] {
[.sogs, .blind]
}
case sogs
case blind
/// Fallback case if the capability isn't supported by this version of the app
case unsupported(String)
// MARK: - Convenience
public var rawValue: String {
switch self {
case .unsupported(let originalValue): return originalValue
default: return "\(self)"
}
}
// MARK: - Initialization
public init(from valueString: String) {
let maybeValue: Variant? = Variant.allCases.first { $0.rawValue == valueString }
self = (maybeValue ?? .unsupported(valueString))
}
}
public let openGroupServer: String
public let variant: Variant
public let isMissing: Bool
// MARK: - Initialization
public init(
openGroupServer: String,
variant: Variant,
isMissing: Bool
) {
self.openGroupServer = openGroupServer
self.variant = variant
self.isMissing = isMissing
}
}
extension Capability.Variant {
// MARK: - Codable
public init(from decoder: Decoder) throws {
let container: SingleValueDecodingContainer = try decoder.singleValueContainer()
let valueString: String = try container.decode(String.self)
// FIXME: Remove this code
// There was a point where we didn't have custom Codable handling for the Capability.Variant
// which resulted in the data being encoded into the database as a JSON dict - this code catches
// that case and extracts the standard string value so it can be processed the same as the
// "proper" custom Codable logic)
if valueString.starts(with: "{") {
self = Capability.Variant(
from: valueString
.replacingOccurrences(of: "\":{}}", with: "")
.replacingOccurrences(of: "\"}}", with: "")
.replacingOccurrences(of: "{\"unsupported\":{\"_0\":\"", with: "")
.replacingOccurrences(of: "{\"", with: "")
)
return
}
// FIXME: Remove this code ^^^
self = Capability.Variant(from: valueString)
}
public func encode(to encoder: Encoder) throws {
var container: SingleValueEncodingContainer = encoder.singleValueContainer()
try container.encode(rawValue)
}
}