[WIP] Started work fixing XCode 15 build issues
Reworked the EmojiGenerator to structure the 'EmojiWithSkinTones+String" file as the original structure was causing XCode 15 to build forever Reworked the seed node certificate loading in an effort to fix a crash Updated to the latest version of webp Commented out a line causing build issues Fixed a number of build warnings Fixed an issue which could cause migration issues when upgrading from certain old versions
This commit is contained in:
parent
67ab1e5194
commit
4c934d2fda
21
Podfile.lock
21
Podfile.lock
|
@ -13,15 +13,18 @@ PODS:
|
|||
- DifferenceKit/Core
|
||||
- GRDB.swift/SQLCipher (6.13.0):
|
||||
- SQLCipher (>= 3.4.2)
|
||||
- libwebp (1.2.1):
|
||||
- libwebp/demux (= 1.2.1)
|
||||
- libwebp/mux (= 1.2.1)
|
||||
- libwebp/webp (= 1.2.1)
|
||||
- libwebp/demux (1.2.1):
|
||||
- libwebp (1.3.2):
|
||||
- libwebp/demux (= 1.3.2)
|
||||
- libwebp/mux (= 1.3.2)
|
||||
- libwebp/sharpyuv (= 1.3.2)
|
||||
- libwebp/webp (= 1.3.2)
|
||||
- libwebp/demux (1.3.2):
|
||||
- libwebp/webp
|
||||
- libwebp/mux (1.2.1):
|
||||
- libwebp/mux (1.3.2):
|
||||
- libwebp/demux
|
||||
- libwebp/webp (1.2.1)
|
||||
- libwebp/sharpyuv (1.3.2)
|
||||
- libwebp/webp (1.3.2):
|
||||
- libwebp/sharpyuv
|
||||
- Nimble (10.0.0)
|
||||
- NVActivityIndicatorView (5.1.1):
|
||||
- NVActivityIndicatorView/Base (= 5.1.1)
|
||||
|
@ -134,7 +137,6 @@ SPEC REPOS:
|
|||
- CocoaLumberjack
|
||||
- DifferenceKit
|
||||
- GRDB.swift
|
||||
- libwebp
|
||||
- Nimble
|
||||
- NVActivityIndicatorView
|
||||
- OpenSSL-Universal
|
||||
|
@ -146,6 +148,7 @@ SPEC REPOS:
|
|||
- SwiftProtobuf
|
||||
- WebRTC-lib
|
||||
trunk:
|
||||
- libwebp
|
||||
- xcbeautify
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
|
@ -186,7 +189,7 @@ SPEC CHECKSUMS:
|
|||
Curve25519Kit: e63f9859ede02438ae3defc5e1a87e09d1ec7ee6
|
||||
DifferenceKit: ab185c4d7f9cef8af3fcf593e5b387fb81e999ca
|
||||
GRDB.swift: fe420b1af49ec519c7e96e07887ee44f5dfa2b78
|
||||
libwebp: 98a37e597e40bfdb4c911fc98f2c53d0b12d05fc
|
||||
libwebp: 1786c9f4ff8a279e4dac1e8f385004d5fc253009
|
||||
Nimble: 5316ef81a170ce87baf72dd961f22f89a602ff84
|
||||
NVActivityIndicatorView: 1f6c5687f1171810aa27a3296814dc2d7dec3667
|
||||
OpenSSL-Universal: e7311447fd2419f57420c79524b641537387eff2
|
||||
|
|
|
@ -263,26 +263,43 @@ extension EmojiGenerator {
|
|||
}
|
||||
}
|
||||
|
||||
static func writeStringConversionsFile(from emojiModel: EmojiModel) {
|
||||
// Inline helpers:
|
||||
var firstItem = true
|
||||
func conditionalCheckForEmojiItem(_ item: EmojiModel.EmojiDefinition.Emoji) -> String {
|
||||
let isFirst = (firstItem == true)
|
||||
firstItem = false
|
||||
|
||||
let prefix = isFirst ? "" : "} else "
|
||||
let suffix = "if rawValue == \"\(item.emojiChar)\" {"
|
||||
return prefix + suffix
|
||||
}
|
||||
func conversionForEmojiItem(_ item: EmojiModel.EmojiDefinition.Emoji, definition: EmojiModel.EmojiDefinition) -> String {
|
||||
let skinToneString: String
|
||||
if item.skintoneSequence.isEmpty {
|
||||
skinToneString = "nil"
|
||||
} else {
|
||||
skinToneString = "[\(item.skintoneSequence.map { ".\($0)" }.joined(separator: ", "))]"
|
||||
indirect enum Structure {
|
||||
enum ChunkType {
|
||||
case firstScalar
|
||||
case scalarSum
|
||||
|
||||
func chunk(_ character: Character, into size: UInt32) -> UInt32 {
|
||||
guard size > 0 else { return 0 }
|
||||
|
||||
let scalarValues: [UInt32] = character.unicodeScalars.map { $0.value }
|
||||
|
||||
switch self {
|
||||
case .firstScalar: return (scalarValues.first.map { $0 / size } ?? 0)
|
||||
case .scalarSum: return (scalarValues.reduce(0, +) / size)
|
||||
}
|
||||
}
|
||||
|
||||
func switchString(with variableName: String = "rawValue") -> String {
|
||||
switch self {
|
||||
case .firstScalar: return "rawValue.unicodeScalars.map({ $0.value }).first"
|
||||
case .scalarSum: return "rawValue.unicodeScalars.map({ $0.value }).reduce(0, +)"
|
||||
}
|
||||
}
|
||||
return "self.init(baseEmoji: .\(definition.enumName), skinTones: \(skinToneString))"
|
||||
}
|
||||
|
||||
case ifElse // XCode 15 taking over 10 min with M1 Pro (gave up)
|
||||
case switchStatement // XCode 15 taking over 10 min with M1 Pro (gave up)
|
||||
case directLookup // XCode 15 taking 93 sec with M1 Pro
|
||||
case chunked(UInt32, Structure, ChunkType) // XCode 15 taking <10 sec with M1 Pro (chunk by 100)
|
||||
}
|
||||
typealias ChunkedEmojiInfo = (
|
||||
variant: EmojiModel.EmojiDefinition.Emoji,
|
||||
baseName: String
|
||||
)
|
||||
|
||||
static func writeStringConversionsFile(from emojiModel: EmojiModel) {
|
||||
// This combination seems to have the smallest compile time (~2.2 sec out of all of the combinations)
|
||||
let desiredStructure: Structure = .chunked(100, .directLookup, .scalarSum)
|
||||
|
||||
// Conversion from String: Creates an initializer mapping a single character emoji string to an EmojiWithSkinTones
|
||||
// e.g.
|
||||
|
@ -291,30 +308,131 @@ extension EmojiGenerator {
|
|||
writeBlock(fileName: "EmojiWithSkinTones+String.swift") { fileHandle in
|
||||
fileHandle.writeLine("extension EmojiWithSkinTones {")
|
||||
fileHandle.indent {
|
||||
fileHandle.writeLine("init?(rawValue: String) {")
|
||||
fileHandle.indent {
|
||||
fileHandle.writeLine("guard rawValue.isSingleEmoji else { return nil }")
|
||||
|
||||
emojiModel.definitions.forEach { definition in
|
||||
definition.variants.forEach { emoji in
|
||||
fileHandle.writeLine(conditionalCheckForEmojiItem(emoji))
|
||||
fileHandle.indent {
|
||||
fileHandle.writeLine(conversionForEmojiItem(emoji, definition: definition))
|
||||
switch desiredStructure {
|
||||
case .chunked(let chunkSize, let childStructure, let chunkType):
|
||||
let chunkedEmojiInfo = emojiModel.definitions
|
||||
.reduce(into: [UInt32: [ChunkedEmojiInfo]]()) { result, next in
|
||||
next.variants.forEach { emoji in
|
||||
let chunk: UInt32 = chunkType.chunk(emoji.emojiChar, into: chunkSize)
|
||||
result[chunk] = ((result[chunk] ?? []) + [(emoji, next.enumName)])
|
||||
.sorted { lhs, rhs in lhs.variant < rhs.variant }
|
||||
}
|
||||
}
|
||||
.sorted { lhs, rhs in lhs.key < rhs.key }
|
||||
|
||||
fileHandle.writeLine("init?(rawValue: String) {")
|
||||
fileHandle.indent {
|
||||
fileHandle.writeLine("guard rawValue.isSingleEmoji else { return nil }")
|
||||
fileHandle.writeLine("switch \(chunkType.switchString()) {")
|
||||
fileHandle.indent {
|
||||
chunkedEmojiInfo.forEach { chunk, _ in
|
||||
fileHandle.writeLine("case \(chunk): self = EmojiWithSkinTones.emojiFrom\(chunk)(rawValue)")
|
||||
}
|
||||
fileHandle.writeLine("default: self = EmojiWithSkinTones(unsupportedValue: rawValue)")
|
||||
}
|
||||
fileHandle.writeLine("}")
|
||||
}
|
||||
}
|
||||
|
||||
fileHandle.writeLine("} else {")
|
||||
fileHandle.indent {
|
||||
fileHandle.writeLine("self.init(unsupportedValue: rawValue)")
|
||||
}
|
||||
fileHandle.writeLine("}")
|
||||
fileHandle.writeLine("}")
|
||||
|
||||
chunkedEmojiInfo.forEach { chunk, emojiInfo in
|
||||
fileHandle.writeLine("")
|
||||
fileHandle.writeLine("private static func emojiFrom\(chunk)(_ rawValue: String) -> EmojiWithSkinTones {")
|
||||
fileHandle.indent {
|
||||
switch emojiInfo.count {
|
||||
case 0:
|
||||
fileHandle.writeLine("return EmojiWithSkinTones(unsupportedValue: rawValue)")
|
||||
|
||||
default:
|
||||
writeStructure(
|
||||
childStructure,
|
||||
for: emojiInfo,
|
||||
using: fileHandle,
|
||||
assignmentPrefix: "return "
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fileHandle.writeLine("}")
|
||||
}
|
||||
|
||||
default:
|
||||
fileHandle.writeLine("init?(rawValue: String) {")
|
||||
fileHandle.indent {
|
||||
fileHandle.writeLine("guard rawValue.isSingleEmoji else { return nil }")
|
||||
writeStructure(
|
||||
desiredStructure,
|
||||
for: emojiModel.definitions
|
||||
.flatMap { definition in
|
||||
definition.variants.map { ($0, definition.enumName) }
|
||||
},
|
||||
using: fileHandle
|
||||
)
|
||||
}
|
||||
fileHandle.writeLine("}")
|
||||
}
|
||||
fileHandle.writeLine("}")
|
||||
}
|
||||
fileHandle.writeLine("}")
|
||||
}
|
||||
}
|
||||
|
||||
private static func writeStructure(
|
||||
_ structure: Structure,
|
||||
for emojiInfo: [ChunkedEmojiInfo],
|
||||
using fileHandle: WriteHandle,
|
||||
assignmentPrefix: String = "self = "
|
||||
) {
|
||||
func initItem(_ info: ChunkedEmojiInfo) -> String {
|
||||
let skinToneString: String = {
|
||||
guard !info.variant.skintoneSequence.isEmpty else { return "nil" }
|
||||
return "[\(info.variant.skintoneSequence.map { ".\($0)" }.joined(separator: ", "))]"
|
||||
}()
|
||||
|
||||
return "EmojiWithSkinTones(baseEmoji: .\(info.baseName), skinTones: \(skinToneString))"
|
||||
}
|
||||
|
||||
switch structure {
|
||||
case .ifElse:
|
||||
emojiInfo.enumerated().forEach { index, info in
|
||||
switch index {
|
||||
case 0: fileHandle.writeLine("if rawValue == \"\(info.variant.emojiChar)\" {")
|
||||
default: fileHandle.writeLine("} else if rawValue == \"\(info.variant.emojiChar)\" {")
|
||||
}
|
||||
|
||||
fileHandle.indent {
|
||||
fileHandle.writeLine("\(assignmentPrefix)\(initItem(info))")
|
||||
}
|
||||
}
|
||||
|
||||
fileHandle.writeLine("} else {")
|
||||
fileHandle.indent {
|
||||
fileHandle.writeLine("\(assignmentPrefix)EmojiWithSkinTones(unsupportedValue: rawValue)")
|
||||
}
|
||||
fileHandle.writeLine("}")
|
||||
|
||||
case .switchStatement:
|
||||
fileHandle.writeLine("switch rawValue {")
|
||||
fileHandle.indent {
|
||||
emojiInfo.forEach { info in
|
||||
fileHandle.writeLine("case \"\(info.variant.emojiChar)\": \(assignmentPrefix)\(initItem(info))")
|
||||
}
|
||||
fileHandle.writeLine("default: \(assignmentPrefix)EmojiWithSkinTones(unsupportedValue: rawValue)")
|
||||
}
|
||||
fileHandle.writeLine("}")
|
||||
|
||||
case .directLookup:
|
||||
fileHandle.writeLine("let lookup: [String: EmojiWithSkinTones] = [")
|
||||
fileHandle.indent {
|
||||
emojiInfo.enumerated().forEach { index, info in
|
||||
let isLast: Bool = (index == (emojiInfo.count - 1))
|
||||
fileHandle.writeLine("\"\(info.variant.emojiChar)\": \(initItem(info))\(isLast ? "" : ",")")
|
||||
}
|
||||
}
|
||||
fileHandle.writeLine("]")
|
||||
fileHandle.writeLine("\(assignmentPrefix)(lookup[rawValue] ?? EmojiWithSkinTones(unsupportedValue: rawValue))")
|
||||
|
||||
case .chunked: break // Provide one of the other types
|
||||
}
|
||||
}
|
||||
|
||||
static func writeSkinToneLookupFile(from emojiModel: EmojiModel) {
|
||||
writeBlock(fileName: "Emoji+SkinTones.swift") { fileHandle in
|
||||
|
@ -514,7 +632,7 @@ extension EmojiGenerator {
|
|||
fileHandle.indent {
|
||||
fileHandle.writeLine("switch self {")
|
||||
emojiModel.definitions.forEach {
|
||||
fileHandle.writeLine("case .\($0.enumName): return \"\($0.shortNames.joined(separator:", "))\"")
|
||||
fileHandle.writeLine("case .\($0.enumName): return \"\($0.shortNames.sorted().joined(separator:", "))\"")
|
||||
}
|
||||
fileHandle.writeLine("}")
|
||||
}
|
||||
|
|
|
@ -572,7 +572,7 @@ public func serializedData() throws -> Data {
|
|||
# if self.can_field_be_optional(field):
|
||||
writer.add('guard proto.%s else {' % field.has_accessor_name() )
|
||||
writer.push_indent()
|
||||
writer.add('throw %s.invalidProtobuf(description: "\(logTag) missing required field: %s")' % ( writer.invalid_protobuf_error_name, field.name_swift, ) )
|
||||
writer.add('throw %s.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: %s")' % ( writer.invalid_protobuf_error_name, field.name_swift, ) )
|
||||
writer.pop_indent()
|
||||
writer.add('}')
|
||||
|
||||
|
|
|
@ -1924,6 +1924,7 @@
|
|||
FDC438CA27BB7DB100C60D73 /* UpdateMessageRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateMessageRequest.swift; sourceTree = "<group>"; };
|
||||
FDC438CC27BC641200C60D73 /* Set+Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Set+Utilities.swift"; sourceTree = "<group>"; };
|
||||
FDC6D75F2862B3F600B04575 /* Dependencies.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dependencies.swift; sourceTree = "<group>"; };
|
||||
FDCCC6E82ABA7402002BBEF5 /* EmojiGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiGenerator.swift; sourceTree = "<group>"; };
|
||||
FDCD2E022A41294E00964D6A /* LegacyGroupOnlyRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacyGroupOnlyRequest.swift; sourceTree = "<group>"; };
|
||||
FDCDB8DD2810F73B00352A0C /* Differentiable+Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Differentiable+Utilities.swift"; sourceTree = "<group>"; };
|
||||
FDCDB8DF2811007F00352A0C /* HomeViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeViewModel.swift; sourceTree = "<group>"; };
|
||||
|
@ -4315,6 +4316,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
FDE7214F287E50D50093DF33 /* ProtoWrappers.py */,
|
||||
FDCCC6E82ABA7402002BBEF5 /* EmojiGenerator.swift */,
|
||||
FDE72150287E50D50093DF33 /* LintLocalizableStrings.swift */,
|
||||
FD5CE3442A3C5D96001A6DE3 /* DecryptExportedKey.swift */,
|
||||
);
|
||||
|
|
|
@ -105,7 +105,6 @@ final class QuoteView: UIView {
|
|||
availableWidth -= cancelButtonSize
|
||||
}
|
||||
|
||||
let availableSpace = CGSize(width: availableWidth, height: .greatestFiniteMagnitude)
|
||||
var body: String? = quotedText
|
||||
|
||||
// Main stack view
|
||||
|
|
|
@ -112,7 +112,6 @@ public final class VoiceMessageView: UIView {
|
|||
}
|
||||
|
||||
private func setUpViewHierarchy() {
|
||||
let toggleContainerSize = VoiceMessageView.toggleContainerSize
|
||||
let inset = VoiceMessageView.inset
|
||||
|
||||
// Width & height
|
||||
|
|
|
@ -86,6 +86,7 @@ extension Emoji {
|
|||
.grimacing,
|
||||
.faceExhaling,
|
||||
.lyingFace,
|
||||
.shakingFace,
|
||||
.relieved,
|
||||
.pensive,
|
||||
.sleepy,
|
||||
|
@ -163,7 +164,6 @@ extension Emoji {
|
|||
.seeNoEvil,
|
||||
.hearNoEvil,
|
||||
.speakNoEvil,
|
||||
.kiss,
|
||||
.loveLetter,
|
||||
.cupid,
|
||||
.giftHeart,
|
||||
|
@ -178,14 +178,18 @@ extension Emoji {
|
|||
.heartOnFire,
|
||||
.mendingHeart,
|
||||
.heart,
|
||||
.pinkHeart,
|
||||
.orangeHeart,
|
||||
.yellowHeart,
|
||||
.greenHeart,
|
||||
.blueHeart,
|
||||
.lightBlueHeart,
|
||||
.purpleHeart,
|
||||
.brownHeart,
|
||||
.blackHeart,
|
||||
.greyHeart,
|
||||
.whiteHeart,
|
||||
.kiss,
|
||||
.oneHundred,
|
||||
.anger,
|
||||
.boom,
|
||||
|
@ -193,7 +197,6 @@ extension Emoji {
|
|||
.sweatDrops,
|
||||
.dash,
|
||||
.hole,
|
||||
.bomb,
|
||||
.speechBalloon,
|
||||
.eyeInSpeechBubble,
|
||||
.leftSpeechBubble,
|
||||
|
@ -209,6 +212,8 @@ extension Emoji {
|
|||
.leftwardsHand,
|
||||
.palmDownHand,
|
||||
.palmUpHand,
|
||||
.leftwardsPushingHand,
|
||||
.rightwardsPushingHand,
|
||||
.okHand,
|
||||
.pinchedFingers,
|
||||
.pinchingHand,
|
||||
|
@ -584,6 +589,8 @@ extension Emoji {
|
|||
.tiger2,
|
||||
.leopard,
|
||||
.horse,
|
||||
.moose,
|
||||
.donkey,
|
||||
.racehorse,
|
||||
.unicornFace,
|
||||
.zebraFace,
|
||||
|
@ -646,6 +653,9 @@ extension Emoji {
|
|||
.flamingo,
|
||||
.peacock,
|
||||
.parrot,
|
||||
.wing,
|
||||
.blackBird,
|
||||
.goose,
|
||||
.frog,
|
||||
.crocodile,
|
||||
.turtle,
|
||||
|
@ -666,6 +676,7 @@ extension Emoji {
|
|||
.octopus,
|
||||
.shell,
|
||||
.coral,
|
||||
.jellyfish,
|
||||
.snail,
|
||||
.butterfly,
|
||||
.bug,
|
||||
|
@ -693,6 +704,7 @@ extension Emoji {
|
|||
.sunflower,
|
||||
.blossom,
|
||||
.tulip,
|
||||
.hyacinth,
|
||||
.seedling,
|
||||
.pottedPlant,
|
||||
.evergreenTree,
|
||||
|
@ -708,6 +720,7 @@ extension Emoji {
|
|||
.leaves,
|
||||
.emptyNest,
|
||||
.nestWithEggs,
|
||||
.mushroom,
|
||||
]
|
||||
case .food:
|
||||
return [
|
||||
|
@ -742,10 +755,11 @@ extension Emoji {
|
|||
.broccoli,
|
||||
.garlic,
|
||||
.onion,
|
||||
.mushroom,
|
||||
.peanuts,
|
||||
.beans,
|
||||
.chestnut,
|
||||
.gingerRoot,
|
||||
.peaPod,
|
||||
.bread,
|
||||
.croissant,
|
||||
.baguetteBread,
|
||||
|
@ -903,11 +917,10 @@ extension Emoji {
|
|||
.dart,
|
||||
.yoYo,
|
||||
.kite,
|
||||
.gun,
|
||||
.eightBall,
|
||||
.crystalBall,
|
||||
.magicWand,
|
||||
.nazarAmulet,
|
||||
.hamsa,
|
||||
.videoGame,
|
||||
.joystick,
|
||||
.slotMachine,
|
||||
|
@ -1176,6 +1189,7 @@ extension Emoji {
|
|||
.shorts,
|
||||
.bikini,
|
||||
.womansClothes,
|
||||
.foldingHandFan,
|
||||
.purse,
|
||||
.handbag,
|
||||
.pouch,
|
||||
|
@ -1190,6 +1204,7 @@ extension Emoji {
|
|||
.sandal,
|
||||
.balletShoes,
|
||||
.boot,
|
||||
.hairPick,
|
||||
.crown,
|
||||
.womansHat,
|
||||
.tophat,
|
||||
|
@ -1228,6 +1243,8 @@ extension Emoji {
|
|||
.banjo,
|
||||
.drumWithDrumsticks,
|
||||
.longDrum,
|
||||
.maracas,
|
||||
.flute,
|
||||
.iphone,
|
||||
.calling,
|
||||
.phone,
|
||||
|
@ -1347,7 +1364,7 @@ extension Emoji {
|
|||
.hammerAndWrench,
|
||||
.daggerKnife,
|
||||
.crossedSwords,
|
||||
.gun,
|
||||
.bomb,
|
||||
.boomerang,
|
||||
.bowAndArrow,
|
||||
.shield,
|
||||
|
@ -1408,6 +1425,8 @@ extension Emoji {
|
|||
.coffin,
|
||||
.headstone,
|
||||
.funeralUrn,
|
||||
.nazarAmulet,
|
||||
.hamsa,
|
||||
.moyai,
|
||||
.placard,
|
||||
.identificationCard,
|
||||
|
@ -1473,6 +1492,7 @@ extension Emoji {
|
|||
.peaceSymbol,
|
||||
.menorahWithNineBranches,
|
||||
.sixPointedStar,
|
||||
.khanda,
|
||||
.aries,
|
||||
.taurus,
|
||||
.gemini,
|
||||
|
@ -1508,6 +1528,7 @@ extension Emoji {
|
|||
.lowBrightness,
|
||||
.highBrightness,
|
||||
.signalStrength,
|
||||
.wireless,
|
||||
.vibrationMode,
|
||||
.mobilePhoneOff,
|
||||
.femaleSign,
|
||||
|
@ -1962,6 +1983,7 @@ extension Emoji {
|
|||
case .grimacing: return .smileysAndPeople
|
||||
case .faceExhaling: return .smileysAndPeople
|
||||
case .lyingFace: return .smileysAndPeople
|
||||
case .shakingFace: return .smileysAndPeople
|
||||
case .relieved: return .smileysAndPeople
|
||||
case .pensive: return .smileysAndPeople
|
||||
case .sleepy: return .smileysAndPeople
|
||||
|
@ -2039,7 +2061,6 @@ extension Emoji {
|
|||
case .seeNoEvil: return .smileysAndPeople
|
||||
case .hearNoEvil: return .smileysAndPeople
|
||||
case .speakNoEvil: return .smileysAndPeople
|
||||
case .kiss: return .smileysAndPeople
|
||||
case .loveLetter: return .smileysAndPeople
|
||||
case .cupid: return .smileysAndPeople
|
||||
case .giftHeart: return .smileysAndPeople
|
||||
|
@ -2054,14 +2075,18 @@ extension Emoji {
|
|||
case .heartOnFire: return .smileysAndPeople
|
||||
case .mendingHeart: return .smileysAndPeople
|
||||
case .heart: return .smileysAndPeople
|
||||
case .pinkHeart: return .smileysAndPeople
|
||||
case .orangeHeart: return .smileysAndPeople
|
||||
case .yellowHeart: return .smileysAndPeople
|
||||
case .greenHeart: return .smileysAndPeople
|
||||
case .blueHeart: return .smileysAndPeople
|
||||
case .lightBlueHeart: return .smileysAndPeople
|
||||
case .purpleHeart: return .smileysAndPeople
|
||||
case .brownHeart: return .smileysAndPeople
|
||||
case .blackHeart: return .smileysAndPeople
|
||||
case .greyHeart: return .smileysAndPeople
|
||||
case .whiteHeart: return .smileysAndPeople
|
||||
case .kiss: return .smileysAndPeople
|
||||
case .oneHundred: return .smileysAndPeople
|
||||
case .anger: return .smileysAndPeople
|
||||
case .boom: return .smileysAndPeople
|
||||
|
@ -2069,7 +2094,6 @@ extension Emoji {
|
|||
case .sweatDrops: return .smileysAndPeople
|
||||
case .dash: return .smileysAndPeople
|
||||
case .hole: return .smileysAndPeople
|
||||
case .bomb: return .smileysAndPeople
|
||||
case .speechBalloon: return .smileysAndPeople
|
||||
case .eyeInSpeechBubble: return .smileysAndPeople
|
||||
case .leftSpeechBubble: return .smileysAndPeople
|
||||
|
@ -2085,6 +2109,8 @@ extension Emoji {
|
|||
case .leftwardsHand: return .smileysAndPeople
|
||||
case .palmDownHand: return .smileysAndPeople
|
||||
case .palmUpHand: return .smileysAndPeople
|
||||
case .leftwardsPushingHand: return .smileysAndPeople
|
||||
case .rightwardsPushingHand: return .smileysAndPeople
|
||||
case .okHand: return .smileysAndPeople
|
||||
case .pinchedFingers: return .smileysAndPeople
|
||||
case .pinchingHand: return .smileysAndPeople
|
||||
|
@ -2457,6 +2483,8 @@ extension Emoji {
|
|||
case .tiger2: return .animals
|
||||
case .leopard: return .animals
|
||||
case .horse: return .animals
|
||||
case .moose: return .animals
|
||||
case .donkey: return .animals
|
||||
case .racehorse: return .animals
|
||||
case .unicornFace: return .animals
|
||||
case .zebraFace: return .animals
|
||||
|
@ -2519,6 +2547,9 @@ extension Emoji {
|
|||
case .flamingo: return .animals
|
||||
case .peacock: return .animals
|
||||
case .parrot: return .animals
|
||||
case .wing: return .animals
|
||||
case .blackBird: return .animals
|
||||
case .goose: return .animals
|
||||
case .frog: return .animals
|
||||
case .crocodile: return .animals
|
||||
case .turtle: return .animals
|
||||
|
@ -2539,6 +2570,7 @@ extension Emoji {
|
|||
case .octopus: return .animals
|
||||
case .shell: return .animals
|
||||
case .coral: return .animals
|
||||
case .jellyfish: return .animals
|
||||
case .snail: return .animals
|
||||
case .butterfly: return .animals
|
||||
case .bug: return .animals
|
||||
|
@ -2566,6 +2598,7 @@ extension Emoji {
|
|||
case .sunflower: return .animals
|
||||
case .blossom: return .animals
|
||||
case .tulip: return .animals
|
||||
case .hyacinth: return .animals
|
||||
case .seedling: return .animals
|
||||
case .pottedPlant: return .animals
|
||||
case .evergreenTree: return .animals
|
||||
|
@ -2581,6 +2614,7 @@ extension Emoji {
|
|||
case .leaves: return .animals
|
||||
case .emptyNest: return .animals
|
||||
case .nestWithEggs: return .animals
|
||||
case .mushroom: return .animals
|
||||
case .grapes: return .food
|
||||
case .melon: return .food
|
||||
case .watermelon: return .food
|
||||
|
@ -2612,10 +2646,11 @@ extension Emoji {
|
|||
case .broccoli: return .food
|
||||
case .garlic: return .food
|
||||
case .onion: return .food
|
||||
case .mushroom: return .food
|
||||
case .peanuts: return .food
|
||||
case .beans: return .food
|
||||
case .chestnut: return .food
|
||||
case .gingerRoot: return .food
|
||||
case .peaPod: return .food
|
||||
case .bread: return .food
|
||||
case .croissant: return .food
|
||||
case .baguetteBread: return .food
|
||||
|
@ -2988,11 +3023,10 @@ extension Emoji {
|
|||
case .dart: return .activities
|
||||
case .yoYo: return .activities
|
||||
case .kite: return .activities
|
||||
case .gun: return .activities
|
||||
case .eightBall: return .activities
|
||||
case .crystalBall: return .activities
|
||||
case .magicWand: return .activities
|
||||
case .nazarAmulet: return .activities
|
||||
case .hamsa: return .activities
|
||||
case .videoGame: return .activities
|
||||
case .joystick: return .activities
|
||||
case .slotMachine: return .activities
|
||||
|
@ -3037,6 +3071,7 @@ extension Emoji {
|
|||
case .shorts: return .objects
|
||||
case .bikini: return .objects
|
||||
case .womansClothes: return .objects
|
||||
case .foldingHandFan: return .objects
|
||||
case .purse: return .objects
|
||||
case .handbag: return .objects
|
||||
case .pouch: return .objects
|
||||
|
@ -3051,6 +3086,7 @@ extension Emoji {
|
|||
case .sandal: return .objects
|
||||
case .balletShoes: return .objects
|
||||
case .boot: return .objects
|
||||
case .hairPick: return .objects
|
||||
case .crown: return .objects
|
||||
case .womansHat: return .objects
|
||||
case .tophat: return .objects
|
||||
|
@ -3089,6 +3125,8 @@ extension Emoji {
|
|||
case .banjo: return .objects
|
||||
case .drumWithDrumsticks: return .objects
|
||||
case .longDrum: return .objects
|
||||
case .maracas: return .objects
|
||||
case .flute: return .objects
|
||||
case .iphone: return .objects
|
||||
case .calling: return .objects
|
||||
case .phone: return .objects
|
||||
|
@ -3208,7 +3246,7 @@ extension Emoji {
|
|||
case .hammerAndWrench: return .objects
|
||||
case .daggerKnife: return .objects
|
||||
case .crossedSwords: return .objects
|
||||
case .gun: return .objects
|
||||
case .bomb: return .objects
|
||||
case .boomerang: return .objects
|
||||
case .bowAndArrow: return .objects
|
||||
case .shield: return .objects
|
||||
|
@ -3269,6 +3307,8 @@ extension Emoji {
|
|||
case .coffin: return .objects
|
||||
case .headstone: return .objects
|
||||
case .funeralUrn: return .objects
|
||||
case .nazarAmulet: return .objects
|
||||
case .hamsa: return .objects
|
||||
case .moyai: return .objects
|
||||
case .placard: return .objects
|
||||
case .identificationCard: return .objects
|
||||
|
@ -3331,6 +3371,7 @@ extension Emoji {
|
|||
case .peaceSymbol: return .symbols
|
||||
case .menorahWithNineBranches: return .symbols
|
||||
case .sixPointedStar: return .symbols
|
||||
case .khanda: return .symbols
|
||||
case .aries: return .symbols
|
||||
case .taurus: return .symbols
|
||||
case .gemini: return .symbols
|
||||
|
@ -3366,6 +3407,7 @@ extension Emoji {
|
|||
case .lowBrightness: return .symbols
|
||||
case .highBrightness: return .symbols
|
||||
case .signalStrength: return .symbols
|
||||
case .wireless: return .symbols
|
||||
case .vibrationMode: return .symbols
|
||||
case .mobilePhoneOff: return .symbols
|
||||
case .femaleSign: return .symbols
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -106,6 +106,22 @@ extension Emoji {
|
|||
[.mediumDark]: "🫴🏾",
|
||||
[.dark]: "🫴🏿",
|
||||
]
|
||||
case .leftwardsPushingHand:
|
||||
return [
|
||||
[.light]: "🫷🏻",
|
||||
[.mediumLight]: "🫷🏼",
|
||||
[.medium]: "🫷🏽",
|
||||
[.mediumDark]: "🫷🏾",
|
||||
[.dark]: "🫷🏿",
|
||||
]
|
||||
case .rightwardsPushingHand:
|
||||
return [
|
||||
[.light]: "🫸🏻",
|
||||
[.mediumLight]: "🫸🏼",
|
||||
[.medium]: "🫸🏽",
|
||||
[.mediumDark]: "🫸🏾",
|
||||
[.dark]: "🫸🏿",
|
||||
]
|
||||
case .okHand:
|
||||
return [
|
||||
[.light]: "👌🏻",
|
||||
|
|
|
@ -54,6 +54,7 @@ enum Emoji: String, CaseIterable, Equatable {
|
|||
case grimacing = "😬"
|
||||
case faceExhaling = "😮💨"
|
||||
case lyingFace = "🤥"
|
||||
case shakingFace = "🫨"
|
||||
case relieved = "😌"
|
||||
case pensive = "😔"
|
||||
case sleepy = "😪"
|
||||
|
@ -131,7 +132,6 @@ enum Emoji: String, CaseIterable, Equatable {
|
|||
case seeNoEvil = "🙈"
|
||||
case hearNoEvil = "🙉"
|
||||
case speakNoEvil = "🙊"
|
||||
case kiss = "💋"
|
||||
case loveLetter = "💌"
|
||||
case cupid = "💘"
|
||||
case giftHeart = "💝"
|
||||
|
@ -146,14 +146,18 @@ enum Emoji: String, CaseIterable, Equatable {
|
|||
case heartOnFire = "❤️🔥"
|
||||
case mendingHeart = "❤️🩹"
|
||||
case heart = "❤️"
|
||||
case pinkHeart = "🩷"
|
||||
case orangeHeart = "🧡"
|
||||
case yellowHeart = "💛"
|
||||
case greenHeart = "💚"
|
||||
case blueHeart = "💙"
|
||||
case lightBlueHeart = "🩵"
|
||||
case purpleHeart = "💜"
|
||||
case brownHeart = "🤎"
|
||||
case blackHeart = "🖤"
|
||||
case greyHeart = "🩶"
|
||||
case whiteHeart = "🤍"
|
||||
case kiss = "💋"
|
||||
case oneHundred = "💯"
|
||||
case anger = "💢"
|
||||
case boom = "💥"
|
||||
|
@ -161,7 +165,6 @@ enum Emoji: String, CaseIterable, Equatable {
|
|||
case sweatDrops = "💦"
|
||||
case dash = "💨"
|
||||
case hole = "🕳️"
|
||||
case bomb = "💣"
|
||||
case speechBalloon = "💬"
|
||||
case eyeInSpeechBubble = "👁️🗨️"
|
||||
case leftSpeechBubble = "🗨️"
|
||||
|
@ -177,6 +180,8 @@ enum Emoji: String, CaseIterable, Equatable {
|
|||
case leftwardsHand = "🫲"
|
||||
case palmDownHand = "🫳"
|
||||
case palmUpHand = "🫴"
|
||||
case leftwardsPushingHand = "🫷"
|
||||
case rightwardsPushingHand = "🫸"
|
||||
case okHand = "👌"
|
||||
case pinchedFingers = "🤌"
|
||||
case pinchingHand = "🤏"
|
||||
|
@ -554,6 +559,8 @@ enum Emoji: String, CaseIterable, Equatable {
|
|||
case tiger2 = "🐅"
|
||||
case leopard = "🐆"
|
||||
case horse = "🐴"
|
||||
case moose = "🫎"
|
||||
case donkey = "🫏"
|
||||
case racehorse = "🐎"
|
||||
case unicornFace = "🦄"
|
||||
case zebraFace = "🦓"
|
||||
|
@ -616,6 +623,9 @@ enum Emoji: String, CaseIterable, Equatable {
|
|||
case flamingo = "🦩"
|
||||
case peacock = "🦚"
|
||||
case parrot = "🦜"
|
||||
case wing = "🪽"
|
||||
case blackBird = "🐦⬛"
|
||||
case goose = "🪿"
|
||||
case frog = "🐸"
|
||||
case crocodile = "🐊"
|
||||
case turtle = "🐢"
|
||||
|
@ -636,6 +646,7 @@ enum Emoji: String, CaseIterable, Equatable {
|
|||
case octopus = "🐙"
|
||||
case shell = "🐚"
|
||||
case coral = "🪸"
|
||||
case jellyfish = "🪼"
|
||||
case snail = "🐌"
|
||||
case butterfly = "🦋"
|
||||
case bug = "🐛"
|
||||
|
@ -663,6 +674,7 @@ enum Emoji: String, CaseIterable, Equatable {
|
|||
case sunflower = "🌻"
|
||||
case blossom = "🌼"
|
||||
case tulip = "🌷"
|
||||
case hyacinth = "🪻"
|
||||
case seedling = "🌱"
|
||||
case pottedPlant = "🪴"
|
||||
case evergreenTree = "🌲"
|
||||
|
@ -678,6 +690,7 @@ enum Emoji: String, CaseIterable, Equatable {
|
|||
case leaves = "🍃"
|
||||
case emptyNest = "🪹"
|
||||
case nestWithEggs = "🪺"
|
||||
case mushroom = "🍄"
|
||||
case grapes = "🍇"
|
||||
case melon = "🍈"
|
||||
case watermelon = "🍉"
|
||||
|
@ -709,10 +722,11 @@ enum Emoji: String, CaseIterable, Equatable {
|
|||
case broccoli = "🥦"
|
||||
case garlic = "🧄"
|
||||
case onion = "🧅"
|
||||
case mushroom = "🍄"
|
||||
case peanuts = "🥜"
|
||||
case beans = "🫘"
|
||||
case chestnut = "🌰"
|
||||
case gingerRoot = "🫚"
|
||||
case peaPod = "🫛"
|
||||
case bread = "🍞"
|
||||
case croissant = "🥐"
|
||||
case baguetteBread = "🥖"
|
||||
|
@ -1085,11 +1099,10 @@ enum Emoji: String, CaseIterable, Equatable {
|
|||
case dart = "🎯"
|
||||
case yoYo = "🪀"
|
||||
case kite = "🪁"
|
||||
case gun = "🔫"
|
||||
case eightBall = "🎱"
|
||||
case crystalBall = "🔮"
|
||||
case magicWand = "🪄"
|
||||
case nazarAmulet = "🧿"
|
||||
case hamsa = "🪬"
|
||||
case videoGame = "🎮"
|
||||
case joystick = "🕹️"
|
||||
case slotMachine = "🎰"
|
||||
|
@ -1134,6 +1147,7 @@ enum Emoji: String, CaseIterable, Equatable {
|
|||
case shorts = "🩳"
|
||||
case bikini = "👙"
|
||||
case womansClothes = "👚"
|
||||
case foldingHandFan = "🪭"
|
||||
case purse = "👛"
|
||||
case handbag = "👜"
|
||||
case pouch = "👝"
|
||||
|
@ -1148,6 +1162,7 @@ enum Emoji: String, CaseIterable, Equatable {
|
|||
case sandal = "👡"
|
||||
case balletShoes = "🩰"
|
||||
case boot = "👢"
|
||||
case hairPick = "🪮"
|
||||
case crown = "👑"
|
||||
case womansHat = "👒"
|
||||
case tophat = "🎩"
|
||||
|
@ -1186,6 +1201,8 @@ enum Emoji: String, CaseIterable, Equatable {
|
|||
case banjo = "🪕"
|
||||
case drumWithDrumsticks = "🥁"
|
||||
case longDrum = "🪘"
|
||||
case maracas = "🪇"
|
||||
case flute = "🪈"
|
||||
case iphone = "📱"
|
||||
case calling = "📲"
|
||||
case phone = "☎️"
|
||||
|
@ -1305,7 +1322,7 @@ enum Emoji: String, CaseIterable, Equatable {
|
|||
case hammerAndWrench = "🛠️"
|
||||
case daggerKnife = "🗡️"
|
||||
case crossedSwords = "⚔️"
|
||||
case gun = "🔫"
|
||||
case bomb = "💣"
|
||||
case boomerang = "🪃"
|
||||
case bowAndArrow = "🏹"
|
||||
case shield = "🛡️"
|
||||
|
@ -1366,6 +1383,8 @@ enum Emoji: String, CaseIterable, Equatable {
|
|||
case coffin = "⚰️"
|
||||
case headstone = "🪦"
|
||||
case funeralUrn = "⚱️"
|
||||
case nazarAmulet = "🧿"
|
||||
case hamsa = "🪬"
|
||||
case moyai = "🗿"
|
||||
case placard = "🪧"
|
||||
case identificationCard = "🪪"
|
||||
|
@ -1428,6 +1447,7 @@ enum Emoji: String, CaseIterable, Equatable {
|
|||
case peaceSymbol = "☮️"
|
||||
case menorahWithNineBranches = "🕎"
|
||||
case sixPointedStar = "🔯"
|
||||
case khanda = "🪯"
|
||||
case aries = "♈"
|
||||
case taurus = "♉"
|
||||
case gemini = "♊"
|
||||
|
@ -1463,6 +1483,7 @@ enum Emoji: String, CaseIterable, Equatable {
|
|||
case lowBrightness = "🔅"
|
||||
case highBrightness = "🔆"
|
||||
case signalStrength = "📶"
|
||||
case wireless = "🛜"
|
||||
case vibrationMode = "📳"
|
||||
case mobilePhoneOff = "📴"
|
||||
case femaleSign = "♀️"
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -275,14 +275,11 @@ class PhotoCaptureViewController: OWSViewController {
|
|||
|
||||
let transformFromOrientation: CGAffineTransform
|
||||
switch captureOrientation {
|
||||
case .portrait:
|
||||
transformFromOrientation = .identity
|
||||
case .portraitUpsideDown:
|
||||
transformFromOrientation = CGAffineTransform(rotationAngle: .pi)
|
||||
case .landscapeLeft:
|
||||
transformFromOrientation = CGAffineTransform(rotationAngle: .halfPi)
|
||||
case .landscapeRight:
|
||||
transformFromOrientation = CGAffineTransform(rotationAngle: -1 * .halfPi)
|
||||
case .portrait: transformFromOrientation = .identity
|
||||
case .portraitUpsideDown: transformFromOrientation = CGAffineTransform(rotationAngle: .pi)
|
||||
case .landscapeLeft: transformFromOrientation = CGAffineTransform(rotationAngle: .halfPi)
|
||||
case .landscapeRight: transformFromOrientation = CGAffineTransform(rotationAngle: -1 * .halfPi)
|
||||
@unknown default: transformFromOrientation = .identity
|
||||
}
|
||||
|
||||
// Don't "unrotate" the switch camera icon if the front facing camera had been selected.
|
||||
|
|
|
@ -59,8 +59,7 @@ public enum PushRegistrationError: Error {
|
|||
.tryFlatMap { _ -> AnyPublisher<(pushToken: String, voipToken: String), Error> in
|
||||
#if targetEnvironment(simulator)
|
||||
throw PushRegistrationError.pushNotSupported(description: "Push not supported on simulators")
|
||||
#endif
|
||||
|
||||
#else
|
||||
return self.registerForVanillaPushToken()
|
||||
.flatMap { vanillaPushToken -> AnyPublisher<(pushToken: String, voipToken: String), Error> in
|
||||
self.registerForVoipPushToken()
|
||||
|
@ -68,6 +67,7 @@ public enum PushRegistrationError: Error {
|
|||
.eraseToAnyPublisher()
|
||||
}
|
||||
.eraseToAnyPublisher()
|
||||
#endif
|
||||
}
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
|
|
@ -160,9 +160,7 @@ public final class WebRTCSession : NSObject, RTCPeerConnectionDelegate {
|
|||
return Deferred {
|
||||
Future<Void, Error> { [weak self] resolver in
|
||||
self?.peerConnection?.offer(for: mediaConstraints) { sdp, error in
|
||||
if let error = error {
|
||||
return
|
||||
}
|
||||
guard error == nil else { return }
|
||||
|
||||
guard let sdp: RTCSessionDescription = self?.correctSessionDescription(sdp: sdp) else {
|
||||
preconditionFailure()
|
||||
|
|
|
@ -61,7 +61,7 @@ public struct SessionThread: Codable, Identifiable, Equatable, FetchableRecord,
|
|||
public let shouldBeVisible: Bool
|
||||
|
||||
/// A flag indicating whether the thread is pinned
|
||||
@available(*, unavailable, message: "use 'pinnedPriority' instead")
|
||||
// @available(*, unavailable, message: "use 'pinnedPriority' instead")
|
||||
public let isPinned: Bool = false
|
||||
|
||||
/// The value the user started entering into the input field before they left the conversation screen
|
||||
|
|
|
@ -165,12 +165,12 @@ public enum SNProtoError: Error {
|
|||
|
||||
fileprivate class func parseProto(_ proto: SessionProtos_Envelope) throws -> SNProtoEnvelope {
|
||||
guard proto.hasType else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: type")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: type")
|
||||
}
|
||||
let type = SNProtoEnvelopeTypeWrap(proto.type)
|
||||
|
||||
guard proto.hasTimestamp else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: timestamp")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: timestamp")
|
||||
}
|
||||
let timestamp = proto.timestamp
|
||||
|
||||
|
@ -298,12 +298,12 @@ extension SNProtoEnvelope.SNProtoEnvelopeBuilder {
|
|||
|
||||
fileprivate class func parseProto(_ proto: SessionProtos_TypingMessage) throws -> SNProtoTypingMessage {
|
||||
guard proto.hasTimestamp else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: timestamp")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: timestamp")
|
||||
}
|
||||
let timestamp = proto.timestamp
|
||||
|
||||
guard proto.hasAction else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: action")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: action")
|
||||
}
|
||||
let action = SNProtoTypingMessageActionWrap(proto.action)
|
||||
|
||||
|
@ -410,12 +410,12 @@ extension SNProtoTypingMessage.SNProtoTypingMessageBuilder {
|
|||
|
||||
fileprivate class func parseProto(_ proto: SessionProtos_UnsendRequest) throws -> SNProtoUnsendRequest {
|
||||
guard proto.hasTimestamp else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: timestamp")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: timestamp")
|
||||
}
|
||||
let timestamp = proto.timestamp
|
||||
|
||||
guard proto.hasAuthor else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: author")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: author")
|
||||
}
|
||||
let author = proto.author
|
||||
|
||||
|
@ -541,7 +541,7 @@ extension SNProtoUnsendRequest.SNProtoUnsendRequestBuilder {
|
|||
|
||||
fileprivate class func parseProto(_ proto: SessionProtos_MessageRequestResponse) throws -> SNProtoMessageRequestResponse {
|
||||
guard proto.hasIsApproved else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: isApproved")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: isApproved")
|
||||
}
|
||||
let isApproved = proto.isApproved
|
||||
|
||||
|
@ -961,12 +961,12 @@ extension SNProtoContent.SNProtoContentBuilder {
|
|||
|
||||
fileprivate class func parseProto(_ proto: SessionProtos_CallMessage) throws -> SNProtoCallMessage {
|
||||
guard proto.hasType else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: type")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: type")
|
||||
}
|
||||
let type = SNProtoCallMessageTypeWrap(proto.type)
|
||||
|
||||
guard proto.hasUuid else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: uuid")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: uuid")
|
||||
}
|
||||
let uuid = proto.uuid
|
||||
|
||||
|
@ -1073,12 +1073,12 @@ extension SNProtoCallMessage.SNProtoCallMessageBuilder {
|
|||
|
||||
fileprivate class func parseProto(_ proto: SessionProtos_KeyPair) throws -> SNProtoKeyPair {
|
||||
guard proto.hasPublicKey else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: publicKey")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: publicKey")
|
||||
}
|
||||
let publicKey = proto.publicKey
|
||||
|
||||
guard proto.hasPrivateKey else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: privateKey")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: privateKey")
|
||||
}
|
||||
let privateKey = proto.privateKey
|
||||
|
||||
|
@ -1211,7 +1211,7 @@ extension SNProtoKeyPair.SNProtoKeyPairBuilder {
|
|||
|
||||
fileprivate class func parseProto(_ proto: SessionProtos_DataExtractionNotification) throws -> SNProtoDataExtractionNotification {
|
||||
guard proto.hasType else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: type")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: type")
|
||||
}
|
||||
let type = SNProtoDataExtractionNotificationTypeWrap(proto.type)
|
||||
|
||||
|
@ -1620,12 +1620,12 @@ extension SNProtoDataMessageQuoteQuotedAttachment.SNProtoDataMessageQuoteQuotedA
|
|||
|
||||
fileprivate class func parseProto(_ proto: SessionProtos_DataMessage.Quote) throws -> SNProtoDataMessageQuote {
|
||||
guard proto.hasID else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: id")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: id")
|
||||
}
|
||||
let id = proto.id
|
||||
|
||||
guard proto.hasAuthor else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: author")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: author")
|
||||
}
|
||||
let author = proto.author
|
||||
|
||||
|
@ -1755,7 +1755,7 @@ extension SNProtoDataMessageQuote.SNProtoDataMessageQuoteBuilder {
|
|||
|
||||
fileprivate class func parseProto(_ proto: SessionProtos_DataMessage.Preview) throws -> SNProtoDataMessagePreview {
|
||||
guard proto.hasURL else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: url")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: url")
|
||||
}
|
||||
let url = proto.url
|
||||
|
||||
|
@ -1914,17 +1914,17 @@ extension SNProtoDataMessagePreview.SNProtoDataMessagePreviewBuilder {
|
|||
|
||||
fileprivate class func parseProto(_ proto: SessionProtos_DataMessage.Reaction) throws -> SNProtoDataMessageReaction {
|
||||
guard proto.hasID else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: id")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: id")
|
||||
}
|
||||
let id = proto.id
|
||||
|
||||
guard proto.hasAuthor else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: author")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: author")
|
||||
}
|
||||
let author = proto.author
|
||||
|
||||
guard proto.hasAction else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: action")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: action")
|
||||
}
|
||||
let action = SNProtoDataMessageReactionActionWrap(proto.action)
|
||||
|
||||
|
@ -2032,12 +2032,12 @@ extension SNProtoDataMessageReaction.SNProtoDataMessageReactionBuilder {
|
|||
|
||||
fileprivate class func parseProto(_ proto: SessionProtos_DataMessage.OpenGroupInvitation) throws -> SNProtoDataMessageOpenGroupInvitation {
|
||||
guard proto.hasURL else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: url")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: url")
|
||||
}
|
||||
let url = proto.url
|
||||
|
||||
guard proto.hasName else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: name")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: name")
|
||||
}
|
||||
let name = proto.name
|
||||
|
||||
|
@ -2144,12 +2144,12 @@ extension SNProtoDataMessageOpenGroupInvitation.SNProtoDataMessageOpenGroupInvit
|
|||
|
||||
fileprivate class func parseProto(_ proto: SessionProtos_DataMessage.ClosedGroupControlMessage.KeyPairWrapper) throws -> SNProtoDataMessageClosedGroupControlMessageKeyPairWrapper {
|
||||
guard proto.hasPublicKey else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: publicKey")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: publicKey")
|
||||
}
|
||||
let publicKey = proto.publicKey
|
||||
|
||||
guard proto.hasEncryptedKeyPair else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: encryptedKeyPair")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: encryptedKeyPair")
|
||||
}
|
||||
let encryptedKeyPair = proto.encryptedKeyPair
|
||||
|
||||
|
@ -2387,7 +2387,7 @@ extension SNProtoDataMessageClosedGroupControlMessageKeyPairWrapper.SNProtoDataM
|
|||
|
||||
fileprivate class func parseProto(_ proto: SessionProtos_DataMessage.ClosedGroupControlMessage) throws -> SNProtoDataMessageClosedGroupControlMessage {
|
||||
guard proto.hasType else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: type")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: type")
|
||||
}
|
||||
let type = SNProtoDataMessageClosedGroupControlMessageTypeWrap(proto.type)
|
||||
|
||||
|
@ -3076,12 +3076,12 @@ extension SNProtoConfigurationMessageClosedGroup.SNProtoConfigurationMessageClos
|
|||
|
||||
fileprivate class func parseProto(_ proto: SessionProtos_ConfigurationMessage.Contact) throws -> SNProtoConfigurationMessageContact {
|
||||
guard proto.hasPublicKey else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: publicKey")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: publicKey")
|
||||
}
|
||||
let publicKey = proto.publicKey
|
||||
|
||||
guard proto.hasName else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: name")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: name")
|
||||
}
|
||||
let name = proto.name
|
||||
|
||||
|
@ -3396,7 +3396,7 @@ extension SNProtoConfigurationMessage.SNProtoConfigurationMessageBuilder {
|
|||
|
||||
fileprivate class func parseProto(_ proto: SessionProtos_ReceiptMessage) throws -> SNProtoReceiptMessage {
|
||||
guard proto.hasType else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: type")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: type")
|
||||
}
|
||||
let type = SNProtoReceiptMessageTypeWrap(proto.type)
|
||||
|
||||
|
@ -3686,7 +3686,7 @@ extension SNProtoReceiptMessage.SNProtoReceiptMessageBuilder {
|
|||
|
||||
fileprivate class func parseProto(_ proto: SessionProtos_AttachmentPointer) throws -> SNProtoAttachmentPointer {
|
||||
guard proto.hasID else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: id")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: id")
|
||||
}
|
||||
let id = proto.id
|
||||
|
||||
|
@ -3828,17 +3828,17 @@ extension SNProtoAttachmentPointer.SNProtoAttachmentPointerBuilder {
|
|||
|
||||
fileprivate class func parseProto(_ proto: SessionProtos_SharedConfigMessage) throws -> SNProtoSharedConfigMessage {
|
||||
guard proto.hasKind else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: kind")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: kind")
|
||||
}
|
||||
let kind = SNProtoSharedConfigMessageKindWrap(proto.kind)
|
||||
|
||||
guard proto.hasSeqno else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: seqno")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: seqno")
|
||||
}
|
||||
let seqno = proto.seqno
|
||||
|
||||
guard proto.hasData else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: data")
|
||||
throw SNProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: data")
|
||||
}
|
||||
let data = proto.data
|
||||
|
||||
|
|
|
@ -123,17 +123,17 @@ public enum WebSocketProtoError: Error {
|
|||
|
||||
fileprivate class func parseProto(_ proto: WebSocketProtos_WebSocketRequestMessage) throws -> WebSocketProtoWebSocketRequestMessage {
|
||||
guard proto.hasVerb else {
|
||||
throw WebSocketProtoError.invalidProtobuf(description: "\(logTag) missing required field: verb")
|
||||
throw WebSocketProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: verb")
|
||||
}
|
||||
let verb = proto.verb
|
||||
|
||||
guard proto.hasPath else {
|
||||
throw WebSocketProtoError.invalidProtobuf(description: "\(logTag) missing required field: path")
|
||||
throw WebSocketProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: path")
|
||||
}
|
||||
let path = proto.path
|
||||
|
||||
guard proto.hasRequestID else {
|
||||
throw WebSocketProtoError.invalidProtobuf(description: "\(logTag) missing required field: requestID")
|
||||
throw WebSocketProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: requestID")
|
||||
}
|
||||
let requestID = proto.requestID
|
||||
|
||||
|
@ -290,12 +290,12 @@ extension WebSocketProtoWebSocketRequestMessage.WebSocketProtoWebSocketRequestMe
|
|||
|
||||
fileprivate class func parseProto(_ proto: WebSocketProtos_WebSocketResponseMessage) throws -> WebSocketProtoWebSocketResponseMessage {
|
||||
guard proto.hasRequestID else {
|
||||
throw WebSocketProtoError.invalidProtobuf(description: "\(logTag) missing required field: requestID")
|
||||
throw WebSocketProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: requestID")
|
||||
}
|
||||
let requestID = proto.requestID
|
||||
|
||||
guard proto.hasStatus else {
|
||||
throw WebSocketProtoError.invalidProtobuf(description: "\(logTag) missing required field: status")
|
||||
throw WebSocketProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: status")
|
||||
}
|
||||
let status = proto.status
|
||||
|
||||
|
@ -439,7 +439,7 @@ extension WebSocketProtoWebSocketResponseMessage.WebSocketProtoWebSocketResponse
|
|||
|
||||
fileprivate class func parseProto(_ proto: WebSocketProtos_WebSocketMessage) throws -> WebSocketProtoWebSocketMessage {
|
||||
guard proto.hasType else {
|
||||
throw WebSocketProtoError.invalidProtobuf(description: "\(logTag) missing required field: type")
|
||||
throw WebSocketProtoError.invalidProtobuf(description: "\(String(describing: logTag)) missing required field: type")
|
||||
}
|
||||
let type = WebSocketProtoWebSocketMessageTypeWrap(proto.type)
|
||||
|
||||
|
|
|
@ -88,11 +88,9 @@ extension MessageReceiver {
|
|||
// Need to check if the blinded id matches for open groups
|
||||
switch senderSessionId.prefix {
|
||||
case .blinded15, .blinded25:
|
||||
let sodium: Sodium = Sodium()
|
||||
|
||||
guard
|
||||
let userEdKeyPair: KeyPair = Identity.fetchUserEd25519KeyPair(db),
|
||||
let blindedKeyPair: KeyPair = try? dependencies.crypto.generate(
|
||||
let blindedKeyPair: KeyPair = dependencies.crypto.generate(
|
||||
.blindedKeyPair(
|
||||
serverPublicKey: openGroup.publicKey,
|
||||
edKeyPair: userEdKeyPair,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import SessionUtilitiesKit
|
||||
|
||||
public extension Notification.Name {
|
||||
static let missedCall = Notification.Name("missedCall")
|
||||
|
|
|
@ -4,6 +4,11 @@ import Foundation
|
|||
import Combine
|
||||
|
||||
public enum HTTP {
|
||||
private struct Certificates {
|
||||
let isValid: Bool
|
||||
let certificates: [SecCertificate]
|
||||
}
|
||||
|
||||
private static let seedNodeURLSession = URLSession(configuration: .ephemeral, delegate: seedNodeURLSessionDelegate, delegateQueue: nil)
|
||||
private static let seedNodeURLSessionDelegate = SeedNodeURLSessionDelegateImplementation()
|
||||
private static let snodeURLSession = URLSession(configuration: .ephemeral, delegate: snodeURLSessionDelegate, delegateQueue: nil)
|
||||
|
@ -14,22 +19,21 @@ public enum HTTP {
|
|||
/// **Note:** These certificates will need to be regenerated and replaced at the start of April 2025, iOS has a restriction after iOS 13
|
||||
/// where certificates can have a maximum lifetime of 825 days (https://support.apple.com/en-au/HT210176) as a result we
|
||||
/// can't use the 10 year certificates that the other platforms use
|
||||
private static let storageSeed1Cert: SecCertificate = {
|
||||
let path = Bundle.main.path(forResource: "seed1-2023-2y", ofType: "der")!
|
||||
let data = try! Data(contentsOf: URL(fileURLWithPath: path))
|
||||
return SecCertificateCreateWithData(nil, data as CFData)!
|
||||
}()
|
||||
|
||||
private static let storageSeed2Cert: SecCertificate = {
|
||||
let path = Bundle.main.path(forResource: "seed2-2023-2y", ofType: "der")!
|
||||
let data = try! Data(contentsOf: URL(fileURLWithPath: path))
|
||||
return SecCertificateCreateWithData(nil, data as CFData)!
|
||||
}()
|
||||
|
||||
private static let storageSeed3Cert: SecCertificate = {
|
||||
let path = Bundle.main.path(forResource: "seed3-2023-2y", ofType: "der")!
|
||||
let data = try! Data(contentsOf: URL(fileURLWithPath: path))
|
||||
return SecCertificateCreateWithData(nil, data as CFData)!
|
||||
private static let storageSeedCertificates: Atomic<Certificates> = {
|
||||
let certFileNames: [String] = [
|
||||
"seed1-2023-2y",
|
||||
"seed2-2023-2y",
|
||||
"seed3-2023-2y"
|
||||
]
|
||||
let paths: [String] = certFileNames.compactMap { Bundle.main.path(forResource: $0, ofType: "der") }
|
||||
let certData: [Data] = paths.compactMap { try? Data(contentsOf: URL(fileURLWithPath: $0)) }
|
||||
let certificates: [SecCertificate] = certData.compactMap { SecCertificateCreateWithData(nil, $0 as CFData) }
|
||||
|
||||
guard certificates.count == certFileNames.count else {
|
||||
return Atomic(Certificates(isValid: false, certificates: []))
|
||||
}
|
||||
|
||||
return Atomic(Certificates(isValid: true, certificates: certificates))
|
||||
}()
|
||||
|
||||
// MARK: - Settings
|
||||
|
@ -41,12 +45,15 @@ public enum HTTP {
|
|||
private final class SeedNodeURLSessionDelegateImplementation : NSObject, URLSessionDelegate {
|
||||
|
||||
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
|
||||
guard HTTP.storageSeedCertificates.wrappedValue.isValid else {
|
||||
SNLog("Failed to set load seed node certificates.")
|
||||
return completionHandler(.cancelAuthenticationChallenge, nil)
|
||||
}
|
||||
guard let trust = challenge.protectionSpace.serverTrust else {
|
||||
return completionHandler(.cancelAuthenticationChallenge, nil)
|
||||
}
|
||||
// Mark the seed node certificates as trusted
|
||||
let certificates = [ storageSeed1Cert, storageSeed2Cert, storageSeed3Cert ]
|
||||
guard SecTrustSetAnchorCertificates(trust, certificates as CFArray) == errSecSuccess else {
|
||||
guard SecTrustSetAnchorCertificates(trust, HTTP.storageSeedCertificates.wrappedValue.certificates as CFArray) == errSecSuccess else {
|
||||
SNLog("Failed to set seed node certificates.")
|
||||
return completionHandler(.cancelAuthenticationChallenge, nil)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue