ios: SimpleXChat framework to be shared by app/NSE (#714)

* ios: SimpleXChat framework to be shared by app/NSE

* remove bridging headers from pp/NSE

* embed & sign
This commit is contained in:
Evgeny Poberezkin
2022-05-31 07:55:13 +01:00
committed by GitHub
parent 7e96da95f9
commit fa844c48e9
61 changed files with 733 additions and 409 deletions
+1
View File
@@ -8,6 +8,7 @@
import Foundation
import UIKit
import SimpleXChat
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
+1
View File
@@ -10,6 +10,7 @@ import Foundation
import Combine
import SwiftUI
import WebKit
import SimpleXChat
final class ChatModel: ObservableObject {
@Published var onboardingStage: OnboardingStage?
+1
View File
@@ -9,6 +9,7 @@
import Foundation
import UserNotifications
import UIKit
import SimpleXChat
let ntfActionAcceptContact = "NTF_ACT_ACCEPT_CONTACT"
let ntfActionAcceptCall = "NTF_ACT_ACCEPT_CALL"
@@ -1,72 +0,0 @@
//
// CallTypes.swift
// SimpleX (iOS)
//
// Created by Evgeny on 05/05/2022.
// Copyright © 2022 SimpleX Chat. All rights reserved.
//
import Foundation
import SwiftUI
struct WebRTCCallOffer: Encodable {
var callType: CallType
var rtcSession: WebRTCSession
}
struct WebRTCSession: Codable {
var rtcSession: String
var rtcIceCandidates: String
}
struct WebRTCExtraInfo: Codable {
var rtcIceCandidates: String
}
struct CallInvitation {
var contact: Contact
var callkitUUID: UUID?
var peerMedia: CallMediaType
var sharedKey: String?
var callTs: Date
var callTypeText: LocalizedStringKey {
get {
switch peerMedia {
case .video: return sharedKey == nil ? "video call (not e2e encrypted)" : "**e2e encrypted** video call"
case .audio: return sharedKey == nil ? "audio call (not e2e encrypted)" : "**e2e encrypted** audio call"
}
}
}
static let sampleData = CallInvitation(
contact: Contact.sampleData,
peerMedia: .audio,
callTs: .now
)
}
struct CallType: Codable {
var media: CallMediaType
var capabilities: CallCapabilities
}
enum CallMediaType: String, Codable, Equatable {
case video = "video"
case audio = "audio"
}
enum VideoCamera: String, Codable, Equatable {
case user = "user"
case environment = "environment"
}
struct CallCapabilities: Codable, Equatable {
var encryption: Bool
}
enum WebRTCCallStatus: String, Encodable {
case connected = "connected"
case connecting = "connecting"
case disconnected = "disconnected"
case failed = "failed"
}
+1
View File
@@ -12,6 +12,7 @@ import Dispatch
import BackgroundTasks
import SwiftUI
import CallKit
import SimpleXChat
private var chatController: chat_ctrl?
@@ -1,11 +0,0 @@
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//
extern void hs_init(int argc, char **argv[]);
typedef void* chat_ctrl;
extern chat_ctrl chat_init(char *path);
extern char *chat_send_cmd(chat_ctrl ctl, char *cmd);
extern char *chat_recv_msg(chat_ctrl ctl);
+1
View File
@@ -7,6 +7,7 @@
import SwiftUI
import OSLog
import SimpleXChat
let logger = Logger()
@@ -8,6 +8,7 @@
import SwiftUI
import WebKit
import SimpleXChat
struct ActiveCallView: View {
@EnvironmentObject var m: ChatModel
@@ -9,6 +9,7 @@
import Foundation
import CallKit
import AVFoundation
import SimpleXChat
class CallController: NSObject, CXProviderDelegate, ObservableObject {
static let useCallKit = false
@@ -7,6 +7,7 @@
//
import Foundation
import SimpleXChat
class CallManager {
func newOutgoingCall(_ contact: Contact, _ media: CallMediaType) -> UUID {
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
struct IncomingCallView: View {
@EnvironmentObject var m: ChatModel
+1
View File
@@ -8,6 +8,7 @@
import Foundation
import SwiftUI
import SimpleXChat
class Call: ObservableObject, Equatable {
static func == (lhs: Call, rhs: Call) -> Bool {
@@ -8,6 +8,7 @@
import SwiftUI
import WebKit
import SimpleXChat
class WebRTCCoordinator: NSObject, WKNavigationDelegate, WKScriptMessageHandler, WKUIDelegate {
var rtcWebView: Binding<WKWebView?>
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
private let chatImageColorLight = Color(red: 0.9, green: 0.9, blue: 0.9)
private let chatImageColorDark = Color(red: 0.2, green: 0.2, blue: 0.2 )
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
struct ChatInfoView: View {
@EnvironmentObject var chatModel: ChatModel
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
struct CICallItemView: View {
@EnvironmentObject var m: ChatModel
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
struct CIFileView: View {
@Environment(\.colorScheme) var colorScheme
@@ -133,7 +134,7 @@ struct CIFileView: View {
struct CIFileView_Previews: PreviewProvider {
static var previews: some View {
let sentFile = ChatItem(
let sentFile: ChatItem = ChatItem(
chatDir: .directSnd,
meta: CIMeta.getSample(1, .now, "", .sndSent, false, true, false),
content: .sndMsgContent(msgContent: .file("")),
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
struct CIImageView: View {
@Environment(\.colorScheme) var colorScheme
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
struct CILinkView: View {
@Environment(\.colorScheme) var colorScheme
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
struct CIMetaView: View {
var chatItem: ChatItem
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
struct DeletedItemView: View {
var chatItem: ChatItem
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
struct EmojiItemView: View {
var chatItem: ChatItem
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
let sentColorLight = Color(.sRGB, red: 0.27, green: 0.72, blue: 1, opacity: 0.12)
let sentColorDark = Color(.sRGB, red: 0.27, green: 0.72, blue: 1, opacity: 0.17)
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
struct IntegrityErrorItemView: View {
var chatItem: ChatItem
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
private let uiLinkColor = UIColor(red: 0, green: 0.533, blue: 1, alpha: 1)
private let linkColor = Color(uiColor: uiLinkColor)
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
struct ChatItemView: View {
var chatInfo: ChatInfo
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
private let memberImageSize: CGFloat = 34
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
struct ComposeImageView: View {
@Environment(\.colorScheme) var colorScheme
@@ -8,7 +8,7 @@
import SwiftUI
import LinkPresentation
import SimpleXChat
func getLinkPreview(url: URL, cb: @escaping (LinkPreview?) -> Void) {
logger.debug("getLinkMetadata: fetching URL preview")
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
enum ComposePreview {
case noPreview
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
struct ContextItemView: View {
@Environment(\.colorScheme) var colorScheme
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
struct SendMessageView: View {
@Binding var composeState: ComposeState
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
struct ChatListNavLink: View {
@EnvironmentObject var chatModel: ChatModel
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
struct ChatListView: View {
@EnvironmentObject var chatModel: ChatModel
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
struct ChatPreviewView: View {
@ObservedObject var chat: Chat
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
struct ContactConnectionView: View {
var contactConnection: PendingContactConnection
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
struct ContactRequestView: View {
var contactRequest: UserContactRequest
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
struct ChatInfoImage: View {
@ObservedObject var chat: Chat
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
struct ProfileImage: View {
var imageStr: String? = nil
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
enum NewChatAction: Identifiable {
case createLink
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
struct CreateProfile: View {
@EnvironmentObject var m: ChatModel
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
struct MakeConnection: View {
@EnvironmentObject var m: ChatModel
+1
View File
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
private let terminalFont = Font.custom("Menlo", size: 16)
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
private let serversFont = Font.custom("Menlo", size: 14)
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
let simplexTeamURL = URL(string: "simplex:/contact#/?v=1&smp=smp%3A%2F%2FPQUV2eL0t7OStZOoAsPEV2QYWt4-xilbakvGUGOItUo%3D%40smp6.simplex.im%2FK1rslx-m5bpXVIdMZg9NLUZ_8JBm8xTt%23MCowBQYDK2VuAyEALDeVe-sG8mRY22LsXlPgiwTNs9dbiLrNuA7f3ZMAJ2w%3D")!
@@ -7,6 +7,7 @@
//
import SwiftUI
import SimpleXChat
struct UserProfile: View {
@EnvironmentObject var chatModel: ChatModel
-23
View File
@@ -1,23 +0,0 @@
//
// dummy.m
// SimpleX
//
// Created by Evgeny Poberezkin on 22/01/2022.
//
#import <Foundation/Foundation.h>
#if defined(__x86_64__) && TARGET_IPHONE_SIMULATOR
#import <dirent.h>
int readdir_r$INODE64(DIR *restrict dirp, struct dirent *restrict entry,
struct dirent **restrict result) {
return readdir_r(dirp, entry, result);
}
DIR *opendir$INODE64(const char *name) {
return opendir(name);
}
#endif
@@ -8,6 +8,7 @@
import UserNotifications
import OSLog
import SimpleXChat
let logger = Logger()
@@ -59,7 +60,7 @@ func startChat() -> User? {
try apiSetFilesFolder(filesFolder: getAppFilesDirectory().path)
return user
} catch {
logger.error("NotificationService startChat error: \(responseError(error))")
logger.error("NotificationService startChat error: \(responseError(error), privacy: .public)")
}
} else {
logger.debug("no active user")
@@ -120,8 +121,11 @@ func apiGetActiveUser() -> User? {
func apiStartChat() throws {
let r = sendSimpleXCmd(.startChat)
if case .chatStarted = r { return }
throw r
switch r {
case .chatStarted: return
case .chatRunning: return
default: throw r
}
}
func apiSetFilesFolder(filesFolder: String) throws {
+290 -78
View File
@@ -38,23 +38,17 @@
5C55A92E283D0FDE00C4E99E /* sounds in Resources */ = {isa = PBXBuildFile; fileRef = 5C55A92D283D0FDE00C4E99E /* sounds */; };
5C577F7D27C83AA10006112D /* MarkdownHelp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C577F7C27C83AA10006112D /* MarkdownHelp.swift */; };
5C5E5D3B2824468B00B0488A /* ActiveCallView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C5E5D3A2824468B00B0488A /* ActiveCallView.swift */; };
5C5E5D3D282447AB00B0488A /* CallTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C5E5D3C282447AB00B0488A /* CallTypes.swift */; };
5C5E5D3E282447BF00B0488A /* CallTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C5E5D3C282447AB00B0488A /* CallTypes.swift */; };
5C5F2B6D27EBC3FE006A9D5F /* ImagePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C5F2B6C27EBC3FE006A9D5F /* ImagePicker.swift */; };
5C5F2B7027EBC704006A9D5F /* ProfileImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C5F2B6F27EBC704006A9D5F /* ProfileImage.swift */; };
5C6AD81327A834E300348BD7 /* NewChatButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C6AD81227A834E300348BD7 /* NewChatButton.swift */; };
5C7505A227B65FDB00BE3227 /* CIMetaView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7505A127B65FDB00BE3227 /* CIMetaView.swift */; };
5C7505A527B679EE00BE3227 /* NavLinkPlain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7505A427B679EE00BE3227 /* NavLinkPlain.swift */; };
5C7505A827B6D34800BE3227 /* ChatInfoToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7505A727B6D34800BE3227 /* ChatInfoToolbar.swift */; };
5C764E80279C7276000C6508 /* dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C764E7F279C7276000C6508 /* dummy.m */; };
5C764E82279C748B000C6508 /* libiconv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C764E7B279C71D4000C6508 /* libiconv.tbd */; };
5C764E83279C748B000C6508 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C764E7C279C71DB000C6508 /* libz.tbd */; };
5C764E89279CBCB3000C6508 /* ChatModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C764E88279CBCB3000C6508 /* ChatModel.swift */; };
5C8F01CD27A6F0D8007D2C8D /* CodeScanner in Frameworks */ = {isa = PBXBuildFile; productRef = 5C8F01CC27A6F0D8007D2C8D /* CodeScanner */; };
5C971E1D27AEBEF600C8A3CE /* ChatInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C971E1C27AEBEF600C8A3CE /* ChatInfoView.swift */; };
5C971E2127AEBF8300C8A3CE /* ChatInfoImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C971E2027AEBF8300C8A3CE /* ChatInfoImage.swift */; };
5C9D13A3282187BB00AB8B43 /* WebRTC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C9D13A2282187BB00AB8B43 /* WebRTC.swift */; };
5C9FD96B27A56D4D0075386C /* JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C9FD96A27A56D4D0075386C /* JSON.swift */; };
5C9FD96E27A5D6ED0075386C /* SendMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C9FD96D27A5D6ED0075386C /* SendMessageView.swift */; };
5CA059DC279559F40002BEB4 /* Tests_iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CA059DB279559F40002BEB4 /* Tests_iOS.swift */; };
5CA059DE279559F40002BEB4 /* Tests_iOSLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CA059DD279559F40002BEB4 /* Tests_iOSLaunchTests.swift */; };
@@ -81,21 +75,29 @@
5CCD403727A5F9A200368C90 /* ScanToConnectView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CCD403627A5F9A200368C90 /* ScanToConnectView.swift */; };
5CCD403A27A5F9BE00368C90 /* CreateGroupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CCD403927A5F9BE00368C90 /* CreateGroupView.swift */; };
5CDCAD482818589900503DA2 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD472818589900503DA2 /* NotificationService.swift */; };
5CDCAD5328186F9500503DA2 /* GroupDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD5228186F9500503DA2 /* GroupDefaults.swift */; };
5CDCAD5428186F9700503DA2 /* GroupDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD5228186F9500503DA2 /* GroupDefaults.swift */; };
5CDCAD5828187C7500503DA2 /* dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD5728187C7500503DA2 /* dummy.m */; };
5CDCAD5F28187D6900503DA2 /* libiconv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CDCAD5E28187D4A00503DA2 /* libiconv.tbd */; };
5CDCAD6128187D8000503DA2 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CDCAD6028187D7900503DA2 /* libz.tbd */; };
5CDCAD682818876500503DA2 /* JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C9FD96A27A56D4D0075386C /* JSON.swift */; };
5CDCAD7628188D3600503DA2 /* APITypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD7428188D2900503DA2 /* APITypes.swift */; };
5CDCAD7728188D3800503DA2 /* ChatTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD7228188CFF00503DA2 /* ChatTypes.swift */; };
5CDCAD7828188FD300503DA2 /* ChatTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD7228188CFF00503DA2 /* ChatTypes.swift */; };
5CDCAD7928188FD600503DA2 /* APITypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD7428188D2900503DA2 /* APITypes.swift */; };
5CDCAD7C2818924D00503DA2 /* FileUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64DAE1502809D9F5000DA960 /* FileUtils.swift */; };
5CDCAD7E2818941F00503DA2 /* API.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD7D2818941F00503DA2 /* API.swift */; };
5CDCAD7F281894FB00503DA2 /* API.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD7D2818941F00503DA2 /* API.swift */; };
5CDCAD81281A7E2700503DA2 /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD80281A7E2700503DA2 /* Notifications.swift */; };
5CDCAD82281A7E2700503DA2 /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD80281A7E2700503DA2 /* Notifications.swift */; };
5CE2BA702845308900EC33A6 /* SimpleXChat.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */; };
5CE2BA712845308900EC33A6 /* SimpleXChat.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
5CE2BA77284530BF00EC33A6 /* SimpleXChat.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CE2BA76284530BF00EC33A6 /* SimpleXChat.h */; };
5CE2BA79284530CC00EC33A6 /* SimpleXChat.docc in Sources */ = {isa = PBXBuildFile; fileRef = 5CE2BA78284530CC00EC33A6 /* SimpleXChat.docc */; };
5CE2BA85284532AD00EC33A6 /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6908028376BB90076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a */; };
5CE2BA86284532AD00EC33A6 /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907C28376BB90076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a */; };
5CE2BA87284532AD00EC33A6 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907D28376BB90076573F /* libffi.a */; };
5CE2BA88284532AD00EC33A6 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907F28376BB90076573F /* libgmp.a */; };
5CE2BA89284532AD00EC33A6 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907E28376BB90076573F /* libgmpxx.a */; };
5CE2BA8B284533A300EC33A6 /* ChatTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD7228188CFF00503DA2 /* ChatTypes.swift */; };
5CE2BA8C284533A300EC33A6 /* GroupDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD5228186F9500503DA2 /* GroupDefaults.swift */; };
5CE2BA8D284533A300EC33A6 /* CallTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C5E5D3C282447AB00B0488A /* CallTypes.swift */; };
5CE2BA8E284533A300EC33A6 /* API.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD7D2818941F00503DA2 /* API.swift */; };
5CE2BA8F284533A300EC33A6 /* APITypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD7428188D2900503DA2 /* APITypes.swift */; };
5CE2BA90284533A300EC33A6 /* JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C9FD96A27A56D4D0075386C /* JSON.swift */; };
5CE2BA91284533A300EC33A6 /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD80281A7E2700503DA2 /* Notifications.swift */; };
5CE2BA922845340900EC33A6 /* FileUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64DAE1502809D9F5000DA960 /* FileUtils.swift */; };
5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CDCAD5E28187D4A00503DA2 /* libiconv.tbd */; };
5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CDCAD6028187D7900503DA2 /* libz.tbd */; };
5CE2BA952845354B00EC33A6 /* SimpleX.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CE2BA8A2845332200EC33A6 /* SimpleX.h */; settings = {ATTRIBUTES = (Public, ); }; };
5CE2BA97284537A800EC33A6 /* dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 5CE2BA96284537A800EC33A6 /* dummy.m */; };
5CE2BA9D284555F500EC33A6 /* SimpleX NSE.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 5CDCAD452818589900503DA2 /* SimpleX NSE.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
5CE2BAA62845617C00EC33A6 /* SimpleXChat.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */; platformFilter = ios; };
5CE4407227ADB1D0007B033A /* Emoji.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CE4407127ADB1D0007B033A /* Emoji.swift */; };
5CE4407927ADB701007B033A /* EmojiItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CE4407827ADB701007B033A /* EmojiItemView.swift */; };
5CEACCE327DE9246000BD591 /* ComposeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CEACCE227DE9246000BD591 /* ComposeView.swift */; };
@@ -109,19 +111,8 @@
648010AB281ADD15009009B9 /* CIFileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 648010AA281ADD15009009B9 /* CIFileView.swift */; };
649BCDA0280460FD00C3A862 /* ComposeImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 649BCD9F280460FD00C3A862 /* ComposeImageView.swift */; };
649BCDA22805D6EF00C3A862 /* CIImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 649BCDA12805D6EF00C3A862 /* CIImageView.swift */; };
64A6908128376BB90076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907C28376BB90076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a */; };
64A6908228376BBA0076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907C28376BB90076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a */; };
64A6908328376BBA0076573F /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907D28376BB90076573F /* libffi.a */; };
64A6908428376BBA0076573F /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907D28376BB90076573F /* libffi.a */; };
64A6908528376BBA0076573F /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907E28376BB90076573F /* libgmpxx.a */; };
64A6908628376BBA0076573F /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907E28376BB90076573F /* libgmpxx.a */; };
64A6908728376BBA0076573F /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907F28376BB90076573F /* libgmp.a */; };
64A6908828376BBA0076573F /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907F28376BB90076573F /* libgmp.a */; };
64A6908928376BBA0076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6908028376BB90076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a */; };
64A6908A28376BBA0076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6908028376BB90076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a */; };
64AA1C6927EE10C800AC7277 /* ContextItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AA1C6827EE10C800AC7277 /* ContextItemView.swift */; };
64AA1C6C27F3537400AC7277 /* DeletedItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AA1C6B27F3537400AC7277 /* DeletedItemView.swift */; };
64DAE1512809D9F5000DA960 /* FileUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64DAE1502809D9F5000DA960 /* FileUtils.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -132,8 +123,54 @@
remoteGlobalIDString = 5CA059C9279559F40002BEB4;
remoteInfo = "SimpleX (iOS)";
};
5CE2BA6E2845308900EC33A6 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 5CA059BE279559F40002BEB4 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 5CE2BA672845308900EC33A6;
remoteInfo = SimpleXChat;
};
5CE2BA9E284555F500EC33A6 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 5CA059BE279559F40002BEB4 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 5CDCAD442818589900503DA2;
remoteInfo = "SimpleX NSE";
};
5CE2BAA82845617C00EC33A6 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 5CA059BE279559F40002BEB4 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 5CE2BA672845308900EC33A6;
remoteInfo = SimpleXChat;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
5CE2BA722845308900EC33A6 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
5CE2BA712845308900EC33A6 /* SimpleXChat.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
5CE2BAA0284555F500EC33A6 /* Embed App Extensions */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 13;
files = (
5CE2BA9D284555F500EC33A6 /* SimpleX NSE.appex in Embed App Extensions */,
);
name = "Embed App Extensions";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
3C714776281C081000CB4D4B /* WebRTCView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebRTCView.swift; sourceTree = "<group>"; };
3C714779281C0F6800CB4D4B /* www */ = {isa = PBXFileReference; lastKnownFileType = folder; name = www; path = ../android/app/src/main/assets/www; sourceTree = "<group>"; };
@@ -177,8 +214,6 @@
5C7505A727B6D34800BE3227 /* ChatInfoToolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatInfoToolbar.swift; sourceTree = "<group>"; };
5C764E7B279C71D4000C6508 /* libiconv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libiconv.tbd; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.2.sdk/usr/lib/libiconv.tbd; sourceTree = DEVELOPER_DIR; };
5C764E7C279C71DB000C6508 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.2.sdk/usr/lib/libz.tbd; sourceTree = DEVELOPER_DIR; };
5C764E7D279C7275000C6508 /* SimpleX (iOS)-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SimpleX (iOS)-Bridging-Header.h"; sourceTree = "<group>"; };
5C764E7F279C7276000C6508 /* dummy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = dummy.m; sourceTree = "<group>"; };
5C764E88279CBCB3000C6508 /* ChatModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatModel.swift; sourceTree = "<group>"; };
5C971E1C27AEBEF600C8A3CE /* ChatInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatInfoView.swift; sourceTree = "<group>"; };
5C971E2027AEBF8300C8A3CE /* ChatInfoImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatInfoImage.swift; sourceTree = "<group>"; };
@@ -216,14 +251,17 @@
5CDCAD492818589900503DA2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
5CDCAD5128186DE400503DA2 /* SimpleX NSE.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "SimpleX NSE.entitlements"; sourceTree = "<group>"; };
5CDCAD5228186F9500503DA2 /* GroupDefaults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupDefaults.swift; sourceTree = "<group>"; };
5CDCAD5628187C7500503DA2 /* SimpleX NSE-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SimpleX NSE-Bridging-Header.h"; sourceTree = "<group>"; };
5CDCAD5728187C7500503DA2 /* dummy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = dummy.m; sourceTree = "<group>"; };
5CDCAD5E28187D4A00503DA2 /* libiconv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libiconv.tbd; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.4.sdk/usr/lib/libiconv.tbd; sourceTree = DEVELOPER_DIR; };
5CDCAD6028187D7900503DA2 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.4.sdk/usr/lib/libz.tbd; sourceTree = DEVELOPER_DIR; };
5CDCAD7228188CFF00503DA2 /* ChatTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatTypes.swift; sourceTree = "<group>"; };
5CDCAD7428188D2900503DA2 /* APITypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APITypes.swift; sourceTree = "<group>"; };
5CDCAD7D2818941F00503DA2 /* API.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = API.swift; sourceTree = "<group>"; };
5CDCAD80281A7E2700503DA2 /* Notifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = "<group>"; };
5CE2BA682845308900EC33A6 /* SimpleXChat.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SimpleXChat.framework; sourceTree = BUILT_PRODUCTS_DIR; };
5CE2BA76284530BF00EC33A6 /* SimpleXChat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleXChat.h; sourceTree = "<group>"; };
5CE2BA78284530CC00EC33A6 /* SimpleXChat.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = SimpleXChat.docc; sourceTree = "<group>"; };
5CE2BA8A2845332200EC33A6 /* SimpleX.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SimpleX.h; sourceTree = "<group>"; };
5CE2BA96284537A800EC33A6 /* dummy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = dummy.m; sourceTree = "<group>"; };
5CE4407127ADB1D0007B033A /* Emoji.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Emoji.swift; sourceTree = "<group>"; };
5CE4407827ADB701007B033A /* EmojiItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiItemView.swift; sourceTree = "<group>"; };
5CEACCE227DE9246000BD591 /* ComposeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeView.swift; sourceTree = "<group>"; };
@@ -252,15 +290,9 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
64A6908928376BBA0076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a in Frameworks */,
5CE2BA702845308900EC33A6 /* SimpleXChat.framework in Frameworks */,
646BB38C283BEEB9001CE359 /* LocalAuthentication.framework in Frameworks */,
64A6908528376BBA0076573F /* libgmpxx.a in Frameworks */,
64A6908728376BBA0076573F /* libgmp.a in Frameworks */,
5C8F01CD27A6F0D8007D2C8D /* CodeScanner in Frameworks */,
5C764E83279C748B000C6508 /* libz.tbd in Frameworks */,
5C764E82279C748B000C6508 /* libiconv.tbd in Frameworks */,
64A6908328376BBA0076573F /* libffi.a in Frameworks */,
64A6908128376BB90076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -275,13 +307,21 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
5CDCAD5F28187D6900503DA2 /* libiconv.tbd in Frameworks */,
64A6908628376BBA0076573F /* libgmpxx.a in Frameworks */,
64A6908A28376BBA0076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a in Frameworks */,
5CDCAD6128187D8000503DA2 /* libz.tbd in Frameworks */,
64A6908228376BBA0076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a in Frameworks */,
64A6908828376BBA0076573F /* libgmp.a in Frameworks */,
64A6908428376BBA0076573F /* libffi.a in Frameworks */,
5CE2BAA62845617C00EC33A6 /* SimpleXChat.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
5CE2BA652845308900EC33A6 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */,
5CE2BA85284532AD00EC33A6 /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a in Frameworks */,
5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */,
5CE2BA89284532AD00EC33A6 /* libgmpxx.a in Frameworks */,
5CE2BA87284532AD00EC33A6 /* libffi.a in Frameworks */,
5CE2BA88284532AD00EC33A6 /* libgmp.a in Frameworks */,
5CE2BA86284532AD00EC33A6 /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -394,6 +434,7 @@
5CA059C2279559F40002BEB4 /* Shared */,
5CDCAD462818589900503DA2 /* SimpleX NSE */,
5CA059DA279559F40002BEB4 /* Tests iOS */,
5CE2BA692845308900EC33A6 /* SimpleXChat */,
5CA059CB279559F40002BEB4 /* Products */,
5C764E7A279C71D4000C6508 /* Frameworks */,
);
@@ -405,12 +446,9 @@
5CA059C3279559F40002BEB4 /* SimpleXApp.swift */,
5C36027227F47AD5009F19D9 /* AppDelegate.swift */,
5CA059C4279559F40002BEB4 /* ContentView.swift */,
64DAE1502809D9F5000DA960 /* FileUtils.swift */,
5C764E87279CBC8E000C6508 /* Model */,
5C2E260D27A30E2400F70299 /* Views */,
5CA059C5279559F40002BEB4 /* Assets.xcassets */,
5C764E7D279C7275000C6508 /* SimpleX (iOS)-Bridging-Header.h */,
5C764E7F279C7276000C6508 /* dummy.m */,
5C13730C2815740A00F43030 /* DebugJSON.playground */,
);
path = Shared;
@@ -422,6 +460,7 @@
5CA059CA279559F40002BEB4 /* SimpleX.app */,
5CA059D7279559F40002BEB4 /* Tests iOS.xctest */,
5CDCAD452818589900503DA2 /* SimpleX NSE.appex */,
5CE2BA682845308900EC33A6 /* SimpleXChat.framework */,
);
name = Products;
sourceTree = "<group>";
@@ -497,13 +536,18 @@
5CDCAD492818589900503DA2 /* Info.plist */,
5CB0BA892826CB3A00B3292C /* Localizable.strings */,
5CB0BA862826CB3A00B3292C /* InfoPlist.strings */,
5CDCAD5728187C7500503DA2 /* dummy.m */,
5CDCAD5628187C7500503DA2 /* SimpleX NSE-Bridging-Header.h */,
);
path = "SimpleX NSE";
sourceTree = "<group>";
};
5CDCAD7128188CEB00503DA2 /* Shared */ = {
isa = PBXGroup;
children = (
);
path = Shared;
sourceTree = "<group>";
};
5CE2BA692845308900EC33A6 /* SimpleXChat */ = {
isa = PBXGroup;
children = (
5CDCAD5228186F9500503DA2 /* GroupDefaults.swift */,
@@ -513,8 +557,13 @@
5C9FD96A27A56D4D0075386C /* JSON.swift */,
5CDCAD7D2818941F00503DA2 /* API.swift */,
5CDCAD80281A7E2700503DA2 /* Notifications.swift */,
64DAE1502809D9F5000DA960 /* FileUtils.swift */,
5CE2BA76284530BF00EC33A6 /* SimpleXChat.h */,
5CE2BA8A2845332200EC33A6 /* SimpleX.h */,
5CE2BA78284530CC00EC33A6 /* SimpleXChat.docc */,
5CE2BA96284537A800EC33A6 /* dummy.m */,
);
path = Shared;
path = SimpleXChat;
sourceTree = "<group>";
};
5CE4407427ADB657007B033A /* ChatItem */ = {
@@ -549,6 +598,18 @@
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
5CE2BA632845308900EC33A6 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
5CE2BA77284530BF00EC33A6 /* SimpleXChat.h in Headers */,
5CE2BA952845354B00EC33A6 /* SimpleX.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
5CA059C9279559F40002BEB4 /* SimpleX (iOS) */ = {
isa = PBXNativeTarget;
@@ -557,10 +618,14 @@
5CA059C6279559F40002BEB4 /* Sources */,
5CA059C7279559F40002BEB4 /* Frameworks */,
5CA059C8279559F40002BEB4 /* Resources */,
5CE2BA722845308900EC33A6 /* Embed Frameworks */,
5CE2BAA0284555F500EC33A6 /* Embed App Extensions */,
);
buildRules = (
);
dependencies = (
5CE2BA6F2845308900EC33A6 /* PBXTargetDependency */,
5CE2BA9F284555F500EC33A6 /* PBXTargetDependency */,
);
name = "SimpleX (iOS)";
packageProductDependencies = (
@@ -599,12 +664,31 @@
buildRules = (
);
dependencies = (
5CE2BAA92845617C00EC33A6 /* PBXTargetDependency */,
);
name = "SimpleX NSE";
productName = "SimpleX NSE";
productReference = 5CDCAD452818589900503DA2 /* SimpleX NSE.appex */;
productType = "com.apple.product-type.app-extension";
};
5CE2BA672845308900EC33A6 /* SimpleXChat */ = {
isa = PBXNativeTarget;
buildConfigurationList = 5CE2BA752845308900EC33A6 /* Build configuration list for PBXNativeTarget "SimpleXChat" */;
buildPhases = (
5CE2BA632845308900EC33A6 /* Headers */,
5CE2BA642845308900EC33A6 /* Sources */,
5CE2BA652845308900EC33A6 /* Frameworks */,
5CE2BA662845308900EC33A6 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = SimpleXChat;
productName = SimpleXChat;
productReference = 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
@@ -628,6 +712,10 @@
CreatedOnToolsVersion = 13.3;
LastSwiftMigration = 1330;
};
5CE2BA672845308900EC33A6 = {
CreatedOnToolsVersion = 13.3;
LastSwiftMigration = 1330;
};
};
};
buildConfigurationList = 5CA059C1279559F40002BEB4 /* Build configuration list for PBXProject "SimpleX" */;
@@ -649,6 +737,7 @@
5CA059C9279559F40002BEB4 /* SimpleX (iOS) */,
5CA059D6279559F40002BEB4 /* Tests iOS */,
5CDCAD442818589900503DA2 /* SimpleX NSE */,
5CE2BA672845308900EC33A6 /* SimpleXChat */,
);
};
/* End PBXProject section */
@@ -682,6 +771,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
5CE2BA662845308900EC33A6 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -691,16 +787,12 @@
files = (
5C6AD81327A834E300348BD7 /* NewChatButton.swift in Sources */,
5C3F1D58284363C400EC8A82 /* PrivacySettings.swift in Sources */,
5CDCAD7F281894FB00503DA2 /* API.swift in Sources */,
5C55A923283CEDE600C4E99E /* SoundPlayer.swift in Sources */,
5CDCAD81281A7E2700503DA2 /* Notifications.swift in Sources */,
5CB924D727A8563F00ACCCDD /* SettingsView.swift in Sources */,
5CEACCE327DE9246000BD591 /* ComposeView.swift in Sources */,
5CDCAD7728188D3800503DA2 /* ChatTypes.swift in Sources */,
5C36027327F47AD5009F19D9 /* AppDelegate.swift in Sources */,
5CB924E127A867BA00ACCCDD /* UserProfile.swift in Sources */,
5CB0BA9A2827FD8800B3292C /* HowItWorks.swift in Sources */,
5CDCAD5328186F9500503DA2 /* GroupDefaults.swift in Sources */,
5C13730B28156D2700F43030 /* ContactConnectionView.swift in Sources */,
5CE4407927ADB701007B033A /* EmojiItemView.swift in Sources */,
5C3F1D562842B68D00EC8A82 /* IntegrityErrorItemView.swift in Sources */,
@@ -709,7 +801,6 @@
648010AB281ADD15009009B9 /* CIFileView.swift in Sources */,
3CDBCF4227FAE51000354CDD /* ComposeLinkView.swift in Sources */,
3CDBCF4827FF621E00354CDD /* CILinkView.swift in Sources */,
5C764E80279C7276000C6508 /* dummy.m in Sources */,
5C7505A827B6D34800BE3227 /* ChatInfoToolbar.swift in Sources */,
5C3A88D127DF57800060F1C2 /* FramedItemView.swift in Sources */,
5CB924E427A8683A00ACCCDD /* UserAddress.swift in Sources */,
@@ -721,8 +812,6 @@
5C9D13A3282187BB00AB8B43 /* WebRTC.swift in Sources */,
5CB0BA8E2827126500B3292C /* OnboardingView.swift in Sources */,
5C2E261227A30FEA00F70299 /* TerminalView.swift in Sources */,
5CDCAD7628188D3600503DA2 /* APITypes.swift in Sources */,
5C9FD96B27A56D4D0075386C /* JSON.swift in Sources */,
5C9FD96E27A5D6ED0075386C /* SendMessageView.swift in Sources */,
5CC1C99227A6C7F5000D9FF6 /* QRCode.swift in Sources */,
5C116CDC27AABE0400E66D01 /* ContactRequestView.swift in Sources */,
@@ -751,7 +840,6 @@
649BCDA22805D6EF00C3A862 /* CIImageView.swift in Sources */,
5CCD403A27A5F9BE00368C90 /* CreateGroupView.swift in Sources */,
5CEACCED27DEA495000BD591 /* MsgContentView.swift in Sources */,
64DAE1512809D9F5000DA960 /* FileUtils.swift in Sources */,
5C764E89279CBCB3000C6508 /* ChatModel.swift in Sources */,
5C971E1D27AEBEF600C8A3CE /* ChatInfoView.swift in Sources */,
5CC1C99527A6CF7F000D9FF6 /* ShareSheet.swift in Sources */,
@@ -761,7 +849,6 @@
3C714777281C081000CB4D4B /* WebRTCView.swift in Sources */,
5CB0BA92282713FD00B3292C /* CreateProfile.swift in Sources */,
5C5F2B7027EBC704006A9D5F /* ProfileImage.swift in Sources */,
5C5E5D3D282447AB00B0488A /* CallTypes.swift in Sources */,
64AA1C6C27F3537400AC7277 /* DeletedItemView.swift in Sources */,
5C029EA82837DBB3004A9677 /* CICallItemView.swift in Sources */,
5CE4407227ADB1D0007B033A /* Emoji.swift in Sources */,
@@ -784,17 +871,25 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
5CDCAD7928188FD600503DA2 /* APITypes.swift in Sources */,
5C5E5D3E282447BF00B0488A /* CallTypes.swift in Sources */,
5CDCAD5828187C7500503DA2 /* dummy.m in Sources */,
5CDCAD482818589900503DA2 /* NotificationService.swift in Sources */,
5CDCAD82281A7E2700503DA2 /* Notifications.swift in Sources */,
5CDCAD7C2818924D00503DA2 /* FileUtils.swift in Sources */,
5CDCAD682818876500503DA2 /* JSON.swift in Sources */,
5CFE0922282EEAF60002594B /* ZoomableScrollView.swift in Sources */,
5CDCAD7828188FD300503DA2 /* ChatTypes.swift in Sources */,
5CDCAD7E2818941F00503DA2 /* API.swift in Sources */,
5CDCAD5428186F9700503DA2 /* GroupDefaults.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
5CE2BA642845308900EC33A6 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
5CE2BA97284537A800EC33A6 /* dummy.m in Sources */,
5CE2BA922845340900EC33A6 /* FileUtils.swift in Sources */,
5CE2BA91284533A300EC33A6 /* Notifications.swift in Sources */,
5CE2BA79284530CC00EC33A6 /* SimpleXChat.docc in Sources */,
5CE2BA90284533A300EC33A6 /* JSON.swift in Sources */,
5CE2BA8B284533A300EC33A6 /* ChatTypes.swift in Sources */,
5CE2BA8F284533A300EC33A6 /* APITypes.swift in Sources */,
5CE2BA8C284533A300EC33A6 /* GroupDefaults.swift in Sources */,
5CE2BA8D284533A300EC33A6 /* CallTypes.swift in Sources */,
5CE2BA8E284533A300EC33A6 /* API.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -806,6 +901,22 @@
target = 5CA059C9279559F40002BEB4 /* SimpleX (iOS) */;
targetProxy = 5CA059D8279559F40002BEB4 /* PBXContainerItemProxy */;
};
5CE2BA6F2845308900EC33A6 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 5CE2BA672845308900EC33A6 /* SimpleXChat */;
targetProxy = 5CE2BA6E2845308900EC33A6 /* PBXContainerItemProxy */;
};
5CE2BA9F284555F500EC33A6 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 5CDCAD442818589900503DA2 /* SimpleX NSE */;
targetProxy = 5CE2BA9E284555F500EC33A6 /* PBXContainerItemProxy */;
};
5CE2BAA92845617C00EC33A6 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
platformFilter = ios;
target = 5CE2BA672845308900EC33A6 /* SimpleXChat */;
targetProxy = 5CE2BAA82845617C00EC33A6 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
@@ -961,6 +1072,7 @@
5CA059F4279559F40002BEB4 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_ENABLE_MODULES = YES;
@@ -994,7 +1106,6 @@
PRODUCT_NAME = SimpleX;
SDKROOT = iphoneos;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OBJC_BRIDGING_HEADER = "Shared/SimpleX (iOS)-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
@@ -1004,6 +1115,7 @@
5CA059F5279559F40002BEB4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_ENABLE_MODULES = YES;
@@ -1037,7 +1149,6 @@
PRODUCT_NAME = SimpleX;
SDKROOT = iphoneos;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OBJC_BRIDGING_HEADER = "Shared/SimpleX (iOS)-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
VALIDATE_PRODUCT = YES;
@@ -1118,7 +1229,6 @@
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OBJC_BRIDGING_HEADER = "SimpleX NSE/SimpleX NSE-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
@@ -1158,13 +1268,106 @@
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OBJC_BRIDGING_HEADER = "SimpleX NSE/SimpleX NSE-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
5CE2BA732845308900EC33A6 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_BITCODE = NO;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022 SimpleX Chat. All rights reserved.";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
"LIBRARY_SEARCH_PATHS[sdk=iphoneos*]" = (
"$(inherited)",
"$(PROJECT_DIR)/Libraries/ios",
);
"LIBRARY_SEARCH_PATHS[sdk=iphonesimulator*]" = (
"$(inherited)",
"$(PROJECT_DIR)/Libraries/sim",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SUPPORTS_MACCATALYST = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_INCLUDE_PATHS = "";
SWIFT_OBJC_BRIDGING_HEADER = ./SimpleXChat/SimpleX.h;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
5CE2BA742845308900EC33A6 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_BITCODE = NO;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022 SimpleX Chat. All rights reserved.";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
"LIBRARY_SEARCH_PATHS[sdk=iphoneos*]" = (
"$(inherited)",
"$(PROJECT_DIR)/Libraries/ios",
);
"LIBRARY_SEARCH_PATHS[sdk=iphonesimulator*]" = (
"$(inherited)",
"$(PROJECT_DIR)/Libraries/sim",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SUPPORTS_MACCATALYST = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_INCLUDE_PATHS = "";
SWIFT_OBJC_BRIDGING_HEADER = ./SimpleXChat/SimpleX.h;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@@ -1204,6 +1407,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
5CE2BA752845308900EC33A6 /* Build configuration list for PBXNativeTarget "SimpleXChat" */ = {
isa = XCConfigurationList;
buildConfigurations = (
5CE2BA732845308900EC33A6 /* Debug */,
5CE2BA742845308900EC33A6 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
@@ -10,7 +10,7 @@ import Foundation
private var chatController: chat_ctrl?
func getChatCtrl() -> chat_ctrl {
public func getChatCtrl() -> chat_ctrl {
if let controller = chatController { return controller }
let dataDir = getDocumentsDirectory().path + "/mobile_v1"
logger.debug("documents directory \(dataDir)")
@@ -20,12 +20,12 @@ func getChatCtrl() -> chat_ctrl {
return chatController!
}
func sendSimpleXCmd(_ cmd: ChatCommand) -> ChatResponse {
public func sendSimpleXCmd(_ cmd: ChatCommand) -> ChatResponse {
var c = cmd.cmdString.cString(using: .utf8)!
return chatResponse(chat_send_cmd(getChatCtrl(), &c))
}
func chatResponse(_ cjson: UnsafeMutablePointer<CChar>) -> ChatResponse {
public func chatResponse(_ cjson: UnsafeMutablePointer<CChar>) -> ChatResponse {
let s = String.init(cString: cjson)
let d = s.data(using: .utf8)!
// TODO is there a way to do it without copying the data? e.g:
@@ -57,7 +57,7 @@ func prettyJSON(_ obj: NSDictionary) -> String? {
return nil
}
func responseError(_ err: Error) -> String {
public func responseError(_ err: Error) -> String {
if let r = err as? ChatResponse {
return String(describing: r)
} else {
@@ -11,7 +11,7 @@ import Foundation
let jsonDecoder = getJSONDecoder()
let jsonEncoder = getJSONEncoder()
enum ChatCommand {
public enum ChatCommand {
case showActiveUser
case createActiveUser(profile: Profile)
case startChat
@@ -50,7 +50,7 @@ enum ChatCommand {
case receiveFile(fileId: Int64)
case string(String)
var cmdString: String {
public var cmdString: String {
get {
switch self {
case .showActiveUser: return "/u"
@@ -95,7 +95,7 @@ enum ChatCommand {
}
}
var cmdType: String {
public var cmdType: String {
get {
switch self {
case .showActiveUser: return "showActiveUser"
@@ -151,7 +151,7 @@ struct APIResponse: Decodable {
var resp: ChatResponse
}
enum ChatResponse: Decodable, Error {
public enum ChatResponse: Decodable, Error {
case response(type: String, json: String)
case activeUser(user: User)
case chatStarted
@@ -211,7 +211,7 @@ enum ChatResponse: Decodable, Error {
case chatCmdError(chatError: ChatError)
case chatError(chatError: ChatError)
var responseType: String {
public var responseType: String {
get {
switch self {
case let .response(type, _): return "* \(type)"
@@ -274,7 +274,7 @@ enum ChatResponse: Decodable, Error {
}
}
var details: String {
public var details: String {
get {
switch self {
case let .response(_, json): return json
@@ -346,7 +346,7 @@ struct ComposedMessage: Encodable {
var msgContent: MsgContent
}
func decodeJSON<T: Decodable>(_ json: String) -> T? {
public func decodeJSON<T: Decodable>(_ json: String) -> T? {
if let data = json.data(using: .utf8) {
return try? jsonDecoder.decode(T.self, from: data)
}
@@ -366,7 +366,7 @@ private func getJSONObject(_ cjson: UnsafePointer<CChar>) -> NSDictionary? {
return try? JSONSerialization.jsonObject(with: d) as? NSDictionary
}
func encodeJSON<T: Encodable>(_ value: T) -> String {
public func encodeJSON<T: Encodable>(_ value: T) -> String {
let data = try! jsonEncoder.encode(value)
return String(decoding: data, as: UTF8.self)
}
@@ -375,13 +375,13 @@ private func encodeCJSON<T: Encodable>(_ value: T) -> [CChar] {
encodeJSON(value).cString(using: .utf8)!
}
enum ChatError: Decodable {
public enum ChatError: Decodable {
case error(errorType: ChatErrorType)
case errorAgent(agentError: AgentErrorType)
case errorStore(storeError: StoreError)
}
enum ChatErrorType: Decodable {
public enum ChatErrorType: Decodable {
case noActiveUser
case activeUserExists
case chatNotStarted
@@ -415,7 +415,7 @@ enum ChatErrorType: Decodable {
case commandError(message: String)
}
enum StoreError: Decodable {
public enum StoreError: Decodable {
case duplicateName
case contactNotFound(contactId: Int64)
case contactNotFoundByName(contactName: ContactName)
@@ -448,7 +448,7 @@ enum StoreError: Decodable {
case chatItemNotFoundByFileId(fileId: Int64)
}
enum AgentErrorType: Decodable {
public enum AgentErrorType: Decodable {
case CMD(cmdErr: CommandErrorType)
case CONN(connErr: ConnectionErrorType)
case SMP(smpErr: ProtocolErrorType)
@@ -458,7 +458,7 @@ enum AgentErrorType: Decodable {
case INTERNAL(internalErr: String)
}
enum CommandErrorType: Decodable {
public enum CommandErrorType: Decodable {
case PROHIBITED
case SYNTAX
case NO_CONN
@@ -466,7 +466,7 @@ enum CommandErrorType: Decodable {
case LARGE
}
enum ConnectionErrorType: Decodable {
public enum ConnectionErrorType: Decodable {
case NOT_FOUND
case DUPLICATE
case SIMPLEX
@@ -474,7 +474,7 @@ enum ConnectionErrorType: Decodable {
case NOT_AVAILABLE
}
enum BrokerErrorType: Decodable {
public enum BrokerErrorType: Decodable {
case RESPONSE(smpErr: ProtocolErrorType)
case UNEXPECTED
case NETWORK
@@ -482,7 +482,7 @@ enum BrokerErrorType: Decodable {
case TIMEOUT
}
enum ProtocolErrorType: Decodable {
public enum ProtocolErrorType: Decodable {
case BLOCK
case SESSION
case CMD(cmdErr: ProtocolCommandError)
@@ -493,7 +493,7 @@ enum ProtocolErrorType: Decodable {
case INTERNAL
}
enum ProtocolCommandError: Decodable {
public enum ProtocolCommandError: Decodable {
case UNKNOWN
case SYNTAX
case NO_AUTH
@@ -501,20 +501,20 @@ enum ProtocolCommandError: Decodable {
case NO_ENTITY
}
enum ProtocolTransportError: Decodable {
public enum ProtocolTransportError: Decodable {
case badBlock
case largeMsg
case badSession
case handshake(handshakeErr: SMPHandshakeError)
}
enum SMPHandshakeError: Decodable {
public enum SMPHandshakeError: Decodable {
case PARSE
case VERSION
case IDENTITY
}
enum SMPAgentError: Decodable {
public enum SMPAgentError: Decodable {
case A_MESSAGE
case A_PROHIBITED
case A_VERSION
+99
View File
@@ -0,0 +1,99 @@
//
// CallTypes.swift
// SimpleX (iOS)
//
// Created by Evgeny on 05/05/2022.
// Copyright © 2022 SimpleX Chat. All rights reserved.
//
import Foundation
import SwiftUI
public struct WebRTCCallOffer: Encodable {
public init(callType: CallType, rtcSession: WebRTCSession) {
self.callType = callType
self.rtcSession = rtcSession
}
public var callType: CallType
public var rtcSession: WebRTCSession
}
public struct WebRTCSession: Codable {
public init(rtcSession: String, rtcIceCandidates: String) {
self.rtcSession = rtcSession
self.rtcIceCandidates = rtcIceCandidates
}
public var rtcSession: String
public var rtcIceCandidates: String
}
public struct WebRTCExtraInfo: Codable {
public init(rtcIceCandidates: String) {
self.rtcIceCandidates = rtcIceCandidates
}
public var rtcIceCandidates: String
}
public struct CallInvitation {
public init(contact: Contact, callkitUUID: UUID? = nil, peerMedia: CallMediaType, sharedKey: String? = nil, callTs: Date) {
self.contact = contact
self.callkitUUID = callkitUUID
self.peerMedia = peerMedia
self.sharedKey = sharedKey
self.callTs = callTs
}
public var contact: Contact
public var callkitUUID: UUID?
public var peerMedia: CallMediaType
public var sharedKey: String?
public var callTs: Date
public var callTypeText: LocalizedStringKey {
get {
switch peerMedia {
case .video: return sharedKey == nil ? "video call (not e2e encrypted)" : "**e2e encrypted** video call"
case .audio: return sharedKey == nil ? "audio call (not e2e encrypted)" : "**e2e encrypted** audio call"
}
}
}
public static let sampleData = CallInvitation(
contact: Contact.sampleData,
peerMedia: .audio,
callTs: .now
)
}
public struct CallType: Codable {
public init(media: CallMediaType, capabilities: CallCapabilities) {
self.media = media
self.capabilities = capabilities
}
public var media: CallMediaType
public var capabilities: CallCapabilities
}
public enum CallMediaType: String, Codable, Equatable {
case video = "video"
case audio = "audio"
}
public enum VideoCamera: String, Codable, Equatable {
case user = "user"
case environment = "environment"
}
public struct CallCapabilities: Codable, Equatable {
public var encryption: Bool
}
public enum WebRTCCallStatus: String, Encodable {
case connected = "connected"
case connecting = "connecting"
case disconnected = "disconnected"
case failed = "failed"
}
@@ -9,18 +9,18 @@
import Foundation
import SwiftUI
struct User: Decodable, NamedChat {
public struct User: Decodable, NamedChat {
var userId: Int64
var userContactId: Int64
var localDisplayName: ContactName
var profile: Profile
public var profile: Profile
var activeUser: Bool
var displayName: String { get { profile.displayName } }
var fullName: String { get { profile.fullName } }
var image: String? { get { profile.image } }
public var displayName: String { get { profile.displayName } }
public var fullName: String { get { profile.fullName } }
public var image: String? { get { profile.image } }
static let sampleData = User(
public static let sampleData = User(
userId: 1,
userContactId: 1,
localDisplayName: "alice",
@@ -29,14 +29,20 @@ struct User: Decodable, NamedChat {
)
}
typealias ContactName = String
public typealias ContactName = String
typealias GroupName = String
public typealias GroupName = String
struct Profile: Codable, NamedChat {
var displayName: String
var fullName: String
var image: String?
public struct Profile: Codable, NamedChat {
public init(displayName: String, fullName: String, image: String? = nil) {
self.displayName = displayName
self.fullName = fullName
self.image = image
}
public var displayName: String
public var fullName: String
public var image: String?
static let sampleData = Profile(
displayName: "alice",
@@ -44,34 +50,34 @@ struct Profile: Codable, NamedChat {
)
}
enum ChatType: String {
public enum ChatType: String {
case direct = "@"
case group = "#"
case contactRequest = "<@"
case contactConnection = ":"
}
protocol NamedChat {
public protocol NamedChat {
var displayName: String { get }
var fullName: String { get }
var image: String? { get }
}
extension NamedChat {
var chatViewName: String {
public var chatViewName: String {
get { displayName + (fullName == "" || fullName == displayName ? "" : " / \(fullName)") }
}
}
typealias ChatId = String
public typealias ChatId = String
enum ChatInfo: Identifiable, Decodable, NamedChat {
public enum ChatInfo: Identifiable, Decodable, NamedChat {
case direct(contact: Contact)
case group(groupInfo: GroupInfo)
case contactRequest(contactRequest: UserContactRequest)
case contactConnection(contactConnection: PendingContactConnection)
var localDisplayName: String {
public var localDisplayName: String {
get {
switch self {
case let .direct(contact): return contact.localDisplayName
@@ -82,7 +88,7 @@ enum ChatInfo: Identifiable, Decodable, NamedChat {
}
}
var displayName: String {
public var displayName: String {
get {
switch self {
case let .direct(contact): return contact.displayName
@@ -93,7 +99,7 @@ enum ChatInfo: Identifiable, Decodable, NamedChat {
}
}
var fullName: String {
public var fullName: String {
get {
switch self {
case let .direct(contact): return contact.fullName
@@ -104,7 +110,7 @@ enum ChatInfo: Identifiable, Decodable, NamedChat {
}
}
var image: String? {
public var image: String? {
get {
switch self {
case let .direct(contact): return contact.image
@@ -115,7 +121,7 @@ enum ChatInfo: Identifiable, Decodable, NamedChat {
}
}
var id: ChatId {
public var id: ChatId {
get {
switch self {
case let .direct(contact): return contact.id
@@ -126,7 +132,7 @@ enum ChatInfo: Identifiable, Decodable, NamedChat {
}
}
var chatType: ChatType {
public var chatType: ChatType {
get {
switch self {
case .direct: return .direct
@@ -137,7 +143,7 @@ enum ChatInfo: Identifiable, Decodable, NamedChat {
}
}
var apiId: Int64 {
public var apiId: Int64 {
get {
switch self {
case let .direct(contact): return contact.apiId
@@ -148,7 +154,7 @@ enum ChatInfo: Identifiable, Decodable, NamedChat {
}
}
var ready: Bool {
public var ready: Bool {
get {
switch self {
case let .direct(contact): return contact.ready
@@ -168,7 +174,7 @@ enum ChatInfo: Identifiable, Decodable, NamedChat {
}
}
var updatedAt: Date {
public var updatedAt: Date {
switch self {
case let .direct(contact): return contact.updatedAt
case let .group(groupInfo): return groupInfo.updatedAt
@@ -177,49 +183,54 @@ enum ChatInfo: Identifiable, Decodable, NamedChat {
}
}
struct SampleData {
var direct: ChatInfo
var group: ChatInfo
var contactRequest: ChatInfo
public struct SampleData {
public var direct: ChatInfo
public var group: ChatInfo
public var contactRequest: ChatInfo
}
static var sampleData: ChatInfo.SampleData = SampleData(
public static var sampleData: ChatInfo.SampleData = SampleData(
direct: ChatInfo.direct(contact: Contact.sampleData),
group: ChatInfo.group(groupInfo: GroupInfo.sampleData),
contactRequest: ChatInfo.contactRequest(contactRequest: UserContactRequest.sampleData)
)
}
struct ChatData: Decodable, Identifiable {
var chatInfo: ChatInfo
var chatItems: [ChatItem]
var chatStats: ChatStats
public struct ChatData: Decodable, Identifiable {
public var chatInfo: ChatInfo
public var chatItems: [ChatItem]
public var chatStats: ChatStats
var id: ChatId { get { chatInfo.id } }
public var id: ChatId { get { chatInfo.id } }
}
struct ChatStats: Decodable {
var unreadCount: Int = 0
var minUnreadItemId: Int64 = 0
public struct ChatStats: Decodable {
public init(unreadCount: Int = 0, minUnreadItemId: Int64 = 0) {
self.unreadCount = unreadCount
self.minUnreadItemId = minUnreadItemId
}
public var unreadCount: Int = 0
public var minUnreadItemId: Int64 = 0
}
struct Contact: Identifiable, Decodable, NamedChat {
public struct Contact: Identifiable, Decodable, NamedChat {
var contactId: Int64
var localDisplayName: ContactName
var profile: Profile
var activeConn: Connection
public var profile: Profile
public var activeConn: Connection
var viaGroup: Int64?
var createdAt: Date
var updatedAt: Date
var id: ChatId { get { "@\(contactId)" } }
var apiId: Int64 { get { contactId } }
var ready: Bool { get { activeConn.connStatus == .ready } }
var displayName: String { get { profile.displayName } }
var fullName: String { get { profile.fullName } }
var image: String? { get { profile.image } }
public var id: ChatId { get { "@\(contactId)" } }
public var apiId: Int64 { get { contactId } }
public var ready: Bool { get { activeConn.connStatus == .ready } }
public var displayName: String { get { profile.displayName } }
public var fullName: String { get { profile.fullName } }
public var image: String? { get { profile.image } }
static let sampleData = Contact(
public static let sampleData = Contact(
contactId: 1,
localDisplayName: "alice",
profile: Profile.sampleData,
@@ -229,23 +240,23 @@ struct Contact: Identifiable, Decodable, NamedChat {
)
}
struct ContactRef: Decodable, Equatable {
public struct ContactRef: Decodable, Equatable {
var contactId: Int64
var localDisplayName: ContactName
var id: ChatId { get { "@\(contactId)" } }
public var id: ChatId { get { "@\(contactId)" } }
}
struct ContactSubStatus: Decodable {
var contact: Contact
var contactError: ChatError?
public struct ContactSubStatus: Decodable {
public var contact: Contact
public var contactError: ChatError?
}
struct Connection: Decodable {
public struct Connection: Decodable {
var connId: Int64
var connStatus: ConnStatus
var id: ChatId { get { ":\(connId)" } }
public var id: ChatId { get { ":\(connId)" } }
static let sampleData = Connection(
connId: 1,
@@ -253,21 +264,21 @@ struct Connection: Decodable {
)
}
struct UserContactRequest: Decodable, NamedChat {
public struct UserContactRequest: Decodable, NamedChat {
var contactRequestId: Int64
var localDisplayName: ContactName
var profile: Profile
var createdAt: Date
var updatedAt: Date
public var updatedAt: Date
var id: ChatId { get { "<@\(contactRequestId)" } }
var apiId: Int64 { get { contactRequestId } }
public var id: ChatId { get { "<@\(contactRequestId)" } }
public var apiId: Int64 { get { contactRequestId } }
var ready: Bool { get { true } }
var displayName: String { get { profile.displayName } }
var fullName: String { get { profile.fullName } }
var image: String? { get { profile.image } }
public var displayName: String { get { profile.displayName } }
public var fullName: String { get { profile.fullName } }
public var image: String? { get { profile.image } }
static let sampleData = UserContactRequest(
public static let sampleData = UserContactRequest(
contactRequestId: 1,
localDisplayName: "alice",
profile: Profile.sampleData,
@@ -276,21 +287,21 @@ struct UserContactRequest: Decodable, NamedChat {
)
}
struct PendingContactConnection: Decodable, NamedChat {
public struct PendingContactConnection: Decodable, NamedChat {
var pccConnId: Int64
var pccAgentConnId: String
var pccConnStatus: ConnStatus
var viaContactUri: Bool
public var viaContactUri: Bool
var createdAt: Date
var updatedAt: Date
public var updatedAt: Date
var id: ChatId { get { ":\(pccConnId)" } }
var apiId: Int64 { get { pccConnId } }
public var id: ChatId { get { ":\(pccConnId)" } }
public var apiId: Int64 { get { pccConnId } }
var ready: Bool { get { false } }
var localDisplayName: String {
get { String.localizedStringWithFormat(NSLocalizedString("connection:%@", comment: "connection information"), pccConnId) }
}
var displayName: String {
public var displayName: String {
get {
if let initiated = pccConnStatus.initiated {
return initiated && !viaContactUri
@@ -302,11 +313,11 @@ struct PendingContactConnection: Decodable, NamedChat {
}
}
}
var fullName: String { get { "" } }
var image: String? { get { nil } }
var initiated: Bool { get { (pccConnStatus.initiated ?? false) && !viaContactUri } }
public var fullName: String { get { "" } }
public var image: String? { get { nil } }
public var initiated: Bool { get { (pccConnStatus.initiated ?? false) && !viaContactUri } }
var description: String {
public var description: String {
get {
if let initiated = pccConnStatus.initiated {
return initiated && !viaContactUri
@@ -320,7 +331,7 @@ struct PendingContactConnection: Decodable, NamedChat {
}
}
static func getSampleData(_ status: ConnStatus = .new, viaContactUri: Bool = false) -> PendingContactConnection {
public static func getSampleData(_ status: ConnStatus = .new, viaContactUri: Bool = false) -> PendingContactConnection {
PendingContactConnection(
pccConnId: 1,
pccAgentConnId: "abcd",
@@ -332,7 +343,7 @@ struct PendingContactConnection: Decodable, NamedChat {
}
}
enum ConnStatus: String, Decodable {
public enum ConnStatus: String, Decodable {
case new = "new"
case joined = "joined"
case requested = "requested"
@@ -356,19 +367,19 @@ enum ConnStatus: String, Decodable {
}
}
struct GroupInfo: Identifiable, Decodable, NamedChat {
public struct GroupInfo: Identifiable, Decodable, NamedChat {
var groupId: Int64
var localDisplayName: GroupName
var groupProfile: GroupProfile
var createdAt: Date
var updatedAt: Date
var id: ChatId { get { "#\(groupId)" } }
public var id: ChatId { get { "#\(groupId)" } }
var apiId: Int64 { get { groupId } }
var ready: Bool { get { true } }
var displayName: String { get { groupProfile.displayName } }
var fullName: String { get { groupProfile.fullName } }
var image: String? { get { groupProfile.image } }
public var ready: Bool { get { true } }
public var displayName: String { get { groupProfile.displayName } }
public var fullName: String { get { groupProfile.fullName } }
public var image: String? { get { groupProfile.image } }
static let sampleData = GroupInfo(
groupId: 1,
@@ -379,10 +390,10 @@ struct GroupInfo: Identifiable, Decodable, NamedChat {
)
}
struct GroupProfile: Codable, NamedChat {
var displayName: String
var fullName: String
var image: String?
public struct GroupProfile: Codable, NamedChat {
public var displayName: String
public var fullName: String
public var image: String?
static let sampleData = GroupProfile(
displayName: "team",
@@ -390,15 +401,15 @@ struct GroupProfile: Codable, NamedChat {
)
}
struct GroupMember: Decodable {
var groupMemberId: Int64
public struct GroupMember: Decodable {
public var groupMemberId: Int64
var memberId: String
// var memberRole: GroupMemberRole
// var memberCategory: GroupMemberCategory
// var memberStatus: GroupMemberStatus
// var invitedBy: InvitedBy
var localDisplayName: ContactName
var memberProfile: Profile
public var memberProfile: Profile
var memberContactId: Int64?
// var activeConn: Connection?
@@ -412,7 +423,7 @@ struct GroupMember: Decodable {
}
}
static let sampleData = GroupMember(
public static let sampleData = GroupMember(
groupMemberId: 1,
memberId: "abcd",
localDisplayName: "alice",
@@ -421,29 +432,38 @@ struct GroupMember: Decodable {
)
}
struct MemberSubError: Decodable {
public struct MemberSubError: Decodable {
var member: GroupMember
var memberError: ChatError
}
struct AChatItem: Decodable {
var chatInfo: ChatInfo
var chatItem: ChatItem
public struct AChatItem: Decodable {
public var chatInfo: ChatInfo
public var chatItem: ChatItem
}
struct ChatItem: Identifiable, Decodable {
var chatDir: CIDirection
var meta: CIMeta
var content: CIContent
var formattedText: [FormattedText]?
var quotedItem: CIQuote?
var file: CIFile?
public struct ChatItem: Identifiable, Decodable {
public init(chatDir: CIDirection, meta: CIMeta, content: CIContent, formattedText: [FormattedText]? = nil, quotedItem: CIQuote? = nil, file: CIFile? = nil) {
self.chatDir = chatDir
self.meta = meta
self.content = content
self.formattedText = formattedText
self.quotedItem = quotedItem
self.file = file
}
public var chatDir: CIDirection
public var meta: CIMeta
public var content: CIContent
public var formattedText: [FormattedText]?
public var quotedItem: CIQuote?
public var file: CIFile?
var id: Int64 { get { meta.itemId } }
public var id: Int64 { get { meta.itemId } }
var timestampText: Text { get { meta.timestampText } }
public var timestampText: Text { get { meta.timestampText } }
var text: String {
public var text: String {
get {
switch (content.text, file) {
case let ("", .some(file)): return file.fileName
@@ -452,12 +472,12 @@ struct ChatItem: Identifiable, Decodable {
}
}
func isRcvNew() -> Bool {
public func isRcvNew() -> Bool {
if case .rcvNew = meta.itemStatus { return true }
return false
}
func isMsgContent() -> Bool {
public func isMsgContent() -> Bool {
switch content {
case .sndMsgContent: return true
case .rcvMsgContent: return true
@@ -465,7 +485,7 @@ struct ChatItem: Identifiable, Decodable {
}
}
func isDeletedContent() -> Bool {
public func isDeletedContent() -> Bool {
switch content {
case .sndDeleted: return true
case .rcvDeleted: return true
@@ -473,7 +493,7 @@ struct ChatItem: Identifiable, Decodable {
}
}
func isCall() -> Bool {
public func isCall() -> Bool {
switch content {
case .sndCall: return true
case .rcvCall: return true
@@ -481,7 +501,7 @@ struct ChatItem: Identifiable, Decodable {
}
}
var memberDisplayName: String? {
public var memberDisplayName: String? {
get {
if case let .groupRcv(groupMember) = chatDir {
return groupMember.memberProfile.displayName
@@ -491,7 +511,7 @@ struct ChatItem: Identifiable, Decodable {
}
}
static func getSample (_ id: Int64, _ dir: CIDirection, _ ts: Date, _ text: String, _ status: CIStatus = .sndNew, quotedItem: CIQuote? = nil, file: CIFile? = nil, _ itemDeleted: Bool = false, _ itemEdited: Bool = false, _ editable: Bool = true) -> ChatItem {
public static func getSample (_ id: Int64, _ dir: CIDirection, _ ts: Date, _ text: String, _ status: CIStatus = .sndNew, quotedItem: CIQuote? = nil, file: CIFile? = nil, _ itemDeleted: Bool = false, _ itemEdited: Bool = false, _ editable: Bool = true) -> ChatItem {
ChatItem(
chatDir: dir,
meta: CIMeta.getSample(id, ts, text, status, itemDeleted, itemEdited, editable),
@@ -501,7 +521,7 @@ struct ChatItem: Identifiable, Decodable {
)
}
static func getFileMsgContentSample (id: Int64 = 1, text: String = "", fileName: String = "test.txt", fileSize: Int64 = 100, fileStatus: CIFileStatus = .rcvComplete) -> ChatItem {
public static func getFileMsgContentSample (id: Int64 = 1, text: String = "", fileName: String = "test.txt", fileSize: Int64 = 100, fileStatus: CIFileStatus = .rcvComplete) -> ChatItem {
ChatItem(
chatDir: .directRcv,
meta: CIMeta.getSample(id, .now, text, .rcvRead, false, false, false),
@@ -511,7 +531,7 @@ struct ChatItem: Identifiable, Decodable {
)
}
static func getDeletedContentSample (_ id: Int64 = 1, dir: CIDirection = .directRcv, _ ts: Date = .now, _ text: String = "this item is deleted", _ status: CIStatus = .rcvRead) -> ChatItem {
public static func getDeletedContentSample (_ id: Int64 = 1, dir: CIDirection = .directRcv, _ ts: Date = .now, _ text: String = "this item is deleted", _ status: CIStatus = .rcvRead) -> ChatItem {
ChatItem(
chatDir: dir,
meta: CIMeta.getSample(id, ts, text, status, false, false, false),
@@ -521,7 +541,7 @@ struct ChatItem: Identifiable, Decodable {
)
}
static func getIntegrityErrorSample (_ status: CIStatus = .rcvRead, fromMsgId: Int64 = 1, toMsgId: Int64 = 2) -> ChatItem {
public static func getIntegrityErrorSample (_ status: CIStatus = .rcvRead, fromMsgId: Int64 = 1, toMsgId: Int64 = 2) -> ChatItem {
ChatItem(
chatDir: .directRcv,
meta: CIMeta.getSample(1, .now, "1 skipped message", status, false, false, false),
@@ -532,13 +552,13 @@ struct ChatItem: Identifiable, Decodable {
}
}
enum CIDirection: Decodable {
public enum CIDirection: Decodable {
case directSnd
case directRcv
case groupSnd
case groupRcv(groupMember: GroupMember)
var sent: Bool {
public var sent: Bool {
get {
switch self {
case .directSnd: return true
@@ -550,19 +570,19 @@ enum CIDirection: Decodable {
}
}
struct CIMeta: Decodable {
public struct CIMeta: Decodable {
var itemId: Int64
var itemTs: Date
var itemText: String
var itemStatus: CIStatus
public var itemStatus: CIStatus
var createdAt: Date
var itemDeleted: Bool
var itemEdited: Bool
var editable: Bool
public var itemDeleted: Bool
public var itemEdited: Bool
public var editable: Bool
var timestampText: Text { get { formatTimestampText(itemTs) } }
static func getSample(_ id: Int64, _ ts: Date, _ text: String, _ status: CIStatus = .sndNew, _ itemDeleted: Bool = false, _ itemEdited: Bool = false, _ editable: Bool = true) -> CIMeta {
public static func getSample(_ id: Int64, _ ts: Date, _ text: String, _ status: CIStatus = .sndNew, _ itemDeleted: Bool = false, _ itemEdited: Bool = false, _ editable: Bool = true) -> CIMeta {
CIMeta(
itemId: id,
itemTs: ts,
@@ -579,14 +599,14 @@ struct CIMeta: Decodable {
let msgTimeFormat = Date.FormatStyle.dateTime.hour().minute()
let msgDateFormat = Date.FormatStyle.dateTime.day(.twoDigits).month(.twoDigits)
func formatTimestampText(_ date: Date) -> Text {
public func formatTimestampText(_ date: Date) -> Text {
let now = Calendar.current.dateComponents([.day, .hour], from: .now)
let dc = Calendar.current.dateComponents([.day, .hour], from: date)
let recent = now.day == dc.day || ((now.day ?? 0) - (dc.day ?? 0) == 1 && (dc.hour ?? 0) >= 18 && (now.hour ?? 0) < 12)
return Text(date, format: recent ? msgTimeFormat : msgDateFormat)
}
enum CIStatus: Decodable {
public enum CIStatus: Decodable {
case sndNew
case sndSent
case sndErrorAuth
@@ -595,7 +615,7 @@ enum CIStatus: Decodable {
case rcvRead
}
enum CIDeleteMode: String, Decodable {
public enum CIDeleteMode: String, Decodable {
case cidmBroadcast = "broadcast"
case cidmInternal = "internal"
}
@@ -604,7 +624,7 @@ protocol ItemContent {
var text: String { get }
}
enum CIContent: Decodable, ItemContent {
public enum CIContent: Decodable, ItemContent {
case sndMsgContent(msgContent: MsgContent)
case rcvMsgContent(msgContent: MsgContent)
case sndDeleted(deleteMode: CIDeleteMode)
@@ -613,7 +633,7 @@ enum CIContent: Decodable, ItemContent {
case rcvCall(status: CICallStatus, duration: Int)
case rcvIntegrityError(msgError: MsgErrorType)
var text: String {
public var text: String {
get {
switch self {
case let .sndMsgContent(mc): return mc.text
@@ -627,7 +647,7 @@ enum CIContent: Decodable, ItemContent {
}
}
var msgContent: MsgContent? {
public var msgContent: MsgContent? {
get {
switch self {
case let .sndMsgContent(mc): return mc
@@ -638,17 +658,17 @@ enum CIContent: Decodable, ItemContent {
}
}
struct CIQuote: Decodable, ItemContent {
public struct CIQuote: Decodable, ItemContent {
var chatDir: CIDirection?
var itemId: Int64?
var sharedMsgId: String? = nil
var sentAt: Date
var content: MsgContent
var formattedText: [FormattedText]?
public var content: MsgContent
public var formattedText: [FormattedText]?
var text: String { get { content.text } }
public var text: String { get { content.text } }
func getSender(_ currentUser: User?) -> String? {
public func getSender(_ currentUser: User?) -> String? {
switch (chatDir) {
case .directSnd: return "you"
case .directRcv: return nil
@@ -658,7 +678,7 @@ struct CIQuote: Decodable, ItemContent {
}
}
static func getSample(_ itemId: Int64?, _ sentAt: Date, _ text: String, chatDir: CIDirection?, image: String? = nil) -> CIQuote {
public static func getSample(_ itemId: Int64?, _ sentAt: Date, _ text: String, chatDir: CIDirection?, image: String? = nil) -> CIQuote {
let mc: MsgContent
if let image = image {
mc = .image(text: text, image: image)
@@ -669,14 +689,14 @@ struct CIQuote: Decodable, ItemContent {
}
}
struct CIFile: Decodable {
var fileId: Int64
var fileName: String
var fileSize: Int64
var filePath: String?
var fileStatus: CIFileStatus
public struct CIFile: Decodable {
public var fileId: Int64
public var fileName: String
public var fileSize: Int64
public var filePath: String?
public var fileStatus: CIFileStatus
static func getSample(fileId: Int64 = 1, fileName: String = "test.txt", fileSize: Int64 = 100, filePath: String? = "test.txt", fileStatus: CIFileStatus = .rcvComplete) -> CIFile {
public static func getSample(fileId: Int64 = 1, fileName: String = "test.txt", fileSize: Int64 = 100, filePath: String? = "test.txt", fileStatus: CIFileStatus = .rcvComplete) -> CIFile {
CIFile(fileId: fileId, fileName: fileName, fileSize: fileSize, filePath: filePath, fileStatus: fileStatus)
}
@@ -697,7 +717,7 @@ struct CIFile: Decodable {
}
}
enum CIFileStatus: String, Decodable {
public enum CIFileStatus: String, Decodable {
case sndStored = "snd_stored"
case sndTransfer = "snd_transfer"
case sndComplete = "snd_complete"
@@ -709,7 +729,7 @@ enum CIFileStatus: String, Decodable {
case rcvCancelled = "rcv_cancelled"
}
enum MsgContent {
public enum MsgContent {
case text(String)
case link(text: String, preview: LinkPreview)
case image(text: String, image: String)
@@ -738,7 +758,7 @@ enum MsgContent {
}
}
func isFile() -> Bool {
public func isFile() -> Bool {
switch self {
case .file: return true
default: return false
@@ -754,7 +774,7 @@ enum MsgContent {
}
extension MsgContent: Decodable {
init(from decoder: Decoder) throws {
public init(from decoder: Decoder) throws {
do {
let container = try decoder.container(keyedBy: CodingKeys.self)
let type = try container.decode(String.self, forKey: CodingKeys.type)
@@ -784,7 +804,7 @@ extension MsgContent: Decodable {
}
extension MsgContent: Encodable {
func encode(to encoder: Encoder) throws {
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
switch self {
case let .text(text):
@@ -809,12 +829,12 @@ extension MsgContent: Encodable {
}
}
struct FormattedText: Decodable {
var text: String
var format: Format?
public struct FormattedText: Decodable {
public var text: String
public var format: Format?
}
enum Format: Decodable, Equatable {
public enum Format: Decodable, Equatable {
case bold
case italic
case strikeThrough
@@ -826,7 +846,7 @@ enum Format: Decodable, Equatable {
case phone
}
enum FormatColor: String, Decodable {
public enum FormatColor: String, Decodable {
case red = "red"
case green = "green"
case blue = "blue"
@@ -836,7 +856,7 @@ enum FormatColor: String, Decodable {
case black = "black"
case white = "white"
var uiColor: Color {
public var uiColor: Color {
get {
switch (self) {
case .red: return .red
@@ -853,15 +873,22 @@ enum FormatColor: String, Decodable {
}
// Struct to use with simplex API
struct LinkPreview: Codable {
var uri: URL
var title: String
public struct LinkPreview: Codable {
public init(uri: URL, title: String, description: String = "", image: String) {
self.uri = uri
self.title = title
self.description = description
self.image = image
}
public var uri: URL
public var title: String
// TODO remove once optional in haskell
var description: String = ""
var image: String
public var description: String = ""
public var image: String
}
enum NtfTknStatus: String, Decodable {
public enum NtfTknStatus: String, Decodable {
case new = "NEW"
case registered = "REGISTERED"
case invalid = "INVALID"
@@ -870,15 +897,15 @@ enum NtfTknStatus: String, Decodable {
case expired = "EXPIRED"
}
struct SndFileTransfer: Decodable {
public struct SndFileTransfer: Decodable {
}
struct FileTransferMeta: Decodable {
public struct FileTransferMeta: Decodable {
}
enum CICallStatus: String, Decodable {
public enum CICallStatus: String, Decodable {
case pending
case missed
case rejected
@@ -901,12 +928,12 @@ enum CICallStatus: String, Decodable {
}
}
static func durationText(_ sec: Int) -> String {
public static func durationText(_ sec: Int) -> String {
String(format: "%02d:%02d", sec / 60, sec % 60)
}
}
enum MsgErrorType: Decodable {
public enum MsgErrorType: Decodable {
case msgSkipped(fromMsgId: Int64, toMsgId: Int64)
case msgBadId(msgId: Int64)
case msgBadHash
@@ -8,17 +8,21 @@
import Foundation
import SwiftUI
import OSLog
let logger = Logger()
// maximum image file size to be auto-accepted
let maxImageSize: Int64 = 236700
public let maxImageSize: Int64 = 236700
let maxFileSize: Int64 = 8000000
public let maxFileSize: Int64 = 8000000
func getDocumentsDirectory() -> URL {
FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
// FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.chat.simplex.app")!
}
func getAppFilesDirectory() -> URL {
public func getAppFilesDirectory() -> URL {
getDocumentsDirectory().appendingPathComponent("app_files", isDirectory: true)
}
@@ -26,7 +30,7 @@ func getAppFilePath(_ fileName: String) -> URL {
getAppFilesDirectory().appendingPathComponent(fileName)
}
func getLoadedFilePath(_ file: CIFile?) -> String? {
public func getLoadedFilePath(_ file: CIFile?) -> String? {
if let file = file,
file.loaded,
let savedFile = file.filePath {
@@ -35,14 +39,14 @@ func getLoadedFilePath(_ file: CIFile?) -> String? {
return nil
}
func getLoadedImage(_ file: CIFile?) -> UIImage? {
public func getLoadedImage(_ file: CIFile?) -> UIImage? {
if let filePath = getLoadedFilePath(file) {
return UIImage(contentsOfFile: filePath)
}
return nil
}
func saveFileFromURL(_ url: URL) -> String? {
public func saveFileFromURL(_ url: URL) -> String? {
let savedFile: String?
if url.startAccessingSecurityScopedResource() {
do {
@@ -61,7 +65,7 @@ func saveFileFromURL(_ url: URL) -> String? {
return savedFile
}
func saveImage(_ uiImage: UIImage) -> String? {
public func saveImage(_ uiImage: UIImage) -> String? {
if let imageDataResized = resizeImageToDataSize(uiImage, maxDataSize: maxImageSize) {
let timestamp = Date().getFormattedDate("yyyyMMdd_HHmmss")
let fileName = uniqueCombine("IMG_\(timestamp).jpg")
@@ -113,7 +117,7 @@ private extension String {
}
}
func removeFile(_ fileName: String) {
public func removeFile(_ fileName: String) {
do {
try FileManager.default.removeItem(atPath: getAppFilePath(fileName).path)
} catch {
@@ -123,7 +127,7 @@ func removeFile(_ fileName: String) {
// image utils
func dropImagePrefix(_ s: String) -> String {
public func dropImagePrefix(_ s: String) -> String {
dropPrefix(dropPrefix(s, "data:image/png;base64,"), "data:image/jpg;base64,")
}
@@ -131,7 +135,7 @@ private func dropPrefix(_ s: String, _ prefix: String) -> String {
s.hasPrefix(prefix) ? String(s.dropFirst(prefix.count)) : s
}
func cropToSquare(_ image: UIImage) -> UIImage {
public func cropToSquare(_ image: UIImage) -> UIImage {
let size = image.size
let side = min(size.width, size.height)
let newSize = CGSize(width: side, height: side)
@@ -159,7 +163,7 @@ func resizeImageToDataSize(_ image: UIImage, maxDataSize: Int64) -> Data? {
return data
}
func resizeImageToStrSize(_ image: UIImage, maxDataSize: Int64) -> String? {
public func resizeImageToStrSize(_ image: UIImage, maxDataSize: Int64) -> String? {
var img = image
var str = compressImageStr(img)
var dataSize = str?.count ?? 0
@@ -9,20 +9,22 @@
import Foundation
import SwiftUI
let GROUP_DEFAULT_APP_IN_BACKGROUND = "appInBackground"
func getGroupDefaults() -> UserDefaults? {
UserDefaults(suiteName: "5NN7GUYB6T.group.chat.simplex.app")
UserDefaults(suiteName: "group.chat.simplex.app")
}
func setAppState(_ phase: ScenePhase) {
public func setAppState(_ phase: ScenePhase) {
if let defaults = getGroupDefaults() {
defaults.set(phase == .background, forKey: "appInBackground")
defaults.set(phase == .background, forKey: GROUP_DEFAULT_APP_IN_BACKGROUND)
defaults.synchronize()
}
}
func getAppState() -> ScenePhase {
public func getAppState() -> ScenePhase {
if let defaults = getGroupDefaults() {
if defaults.bool(forKey: "appInBackground") {
if defaults.bool(forKey: GROUP_DEFAULT_APP_IN_BACKGROUND) {
return .background
}
}
@@ -8,7 +8,7 @@
import Foundation
func getJSONDecoder() -> JSONDecoder {
public func getJSONDecoder() -> JSONDecoder {
let jd = JSONDecoder()
let fracSeconds = getDateFormatter("yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ")
let noFracSeconds = getDateFormatter("yyyy-MM-dd'T'HH:mm:ssZZZZZ")
@@ -23,7 +23,7 @@ func getJSONDecoder() -> JSONDecoder {
return jd
}
func getJSONEncoder() -> JSONEncoder {
public func getJSONEncoder() -> JSONEncoder {
let je = JSONEncoder()
je.dateEncodingStrategy = .iso8601
return je
@@ -10,17 +10,17 @@ import Foundation
import UserNotifications
import SwiftUI
let ntfCategoryContactRequest = "NTF_CAT_CONTACT_REQUEST"
let ntfCategoryContactConnected = "NTF_CAT_CONTACT_CONNECTED"
let ntfCategoryMessageReceived = "NTF_CAT_MESSAGE_RECEIVED"
let ntfCategoryCallInvitation = "NTF_CAT_CALL_INVITATION"
let ntfCategoryCheckMessage = "NTF_CAT_CHECK_MESSAGE"
public let ntfCategoryContactRequest = "NTF_CAT_CONTACT_REQUEST"
public let ntfCategoryContactConnected = "NTF_CAT_CONTACT_CONNECTED"
public let ntfCategoryMessageReceived = "NTF_CAT_MESSAGE_RECEIVED"
public let ntfCategoryCallInvitation = "NTF_CAT_CALL_INVITATION"
public let ntfCategoryCheckMessage = "NTF_CAT_CHECK_MESSAGE"
// TODO remove
let ntfCategoryCheckingMessages = "NTF_CAT_CHECKING_MESSAGES"
public let ntfCategoryCheckingMessages = "NTF_CAT_CHECKING_MESSAGES"
let appNotificationId = "chat.simplex.app.notification"
public let appNotificationId = "chat.simplex.app.notification"
func createContactRequestNtf(_ contactRequest: UserContactRequest) -> UNMutableNotificationContent {
public func createContactRequestNtf(_ contactRequest: UserContactRequest) -> UNMutableNotificationContent {
createNotification(
categoryIdentifier: ntfCategoryContactRequest,
title: String.localizedStringWithFormat(NSLocalizedString("%@ wants to connect!", comment: "notification title"), contactRequest.displayName),
@@ -30,7 +30,7 @@ func createContactRequestNtf(_ contactRequest: UserContactRequest) -> UNMutableN
)
}
func createContactConnectedNtf(_ contact: Contact) -> UNMutableNotificationContent {
public func createContactConnectedNtf(_ contact: Contact) -> UNMutableNotificationContent {
createNotification(
categoryIdentifier: ntfCategoryContactConnected,
title: String.localizedStringWithFormat(NSLocalizedString("%@ is connected!", comment: "notification title"), contact.displayName),
@@ -40,7 +40,7 @@ func createContactConnectedNtf(_ contact: Contact) -> UNMutableNotificationConte
)
}
func createMessageReceivedNtf(_ cInfo: ChatInfo, _ cItem: ChatItem) -> UNMutableNotificationContent {
public func createMessageReceivedNtf(_ cInfo: ChatInfo, _ cItem: ChatItem) -> UNMutableNotificationContent {
createNotification(
categoryIdentifier: ntfCategoryMessageReceived,
title: "\(cInfo.chatViewName):",
@@ -50,7 +50,7 @@ func createMessageReceivedNtf(_ cInfo: ChatInfo, _ cItem: ChatItem) -> UNMutable
)
}
func createCallInvitationNtf(_ invitation: CallInvitation) -> UNMutableNotificationContent {
public func createCallInvitationNtf(_ invitation: CallInvitation) -> UNMutableNotificationContent {
let text = invitation.peerMedia == .video
? NSLocalizedString("Incoming video call", comment: "notification")
: NSLocalizedString("Incoming audio call", comment: "notification")
@@ -63,7 +63,7 @@ func createCallInvitationNtf(_ invitation: CallInvitation) -> UNMutableNotificat
)
}
func createNotification(categoryIdentifier: String, title: String, subtitle: String? = nil, body: String? = nil,
public func createNotification(categoryIdentifier: String, title: String, subtitle: String? = nil, body: String? = nil,
targetContentIdentifier: String? = nil, userInfo: [AnyHashable : Any] = [:]) -> UNMutableNotificationContent {
let content = UNMutableNotificationContent()
content.categoryIdentifier = categoryIdentifier
@@ -1,6 +1,15 @@
//
// Use this file to import your target's public headers that you would like to expose to Swift.
// SimpleX.h
// SimpleX
//
// Created by Evgeny on 30/05/2022.
// Copyright © 2022 SimpleX Chat. All rights reserved.
//
#ifndef SimpleX_h
#define SimpleX_h
#endif /* SimpleX_h */
extern void hs_init(int argc, char **argv[]);
+13
View File
@@ -0,0 +1,13 @@
# ``SimpleXChat``
<!--@START_MENU_TOKEN@-->Summary<!--@END_MENU_TOKEN@-->
## Overview
<!--@START_MENU_TOKEN@-->Text<!--@END_MENU_TOKEN@-->
## Topics
### <!--@START_MENU_TOKEN@-->Group<!--@END_MENU_TOKEN@-->
- <!--@START_MENU_TOKEN@-->``Symbol``<!--@END_MENU_TOKEN@-->
+17
View File
@@ -0,0 +1,17 @@
//
// SimpleXChat.h
// SimpleXChat
//
// Created by Evgeny on 30/05/2022.
// Copyright © 2022 SimpleX Chat. All rights reserved.
//
#import <Foundation/Foundation.h>
//! Project version number for SimpleXChat.
FOUNDATION_EXPORT double SimpleXChatVersionNumber;
//! Project version string for SimpleXChat.
FOUNDATION_EXPORT const unsigned char SimpleXChatVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <SimpleXChat/PublicHeader.h>
@@ -1,8 +1,8 @@
//
// dummy.m
// SimpleX NSE
// SimpleXChat
//
// Created by Evgeny on 26/04/2022.
// Created by Evgeny on 30/05/2022.
// Copyright © 2022 SimpleX Chat. All rights reserved.
//