Merge branch 'master' into master-ghc8107
This commit is contained in:
commit
870f9e42dd
@ -195,18 +195,18 @@ func moveTempFileFromURL(_ url: URL) -> CryptoFile? {
|
||||
}
|
||||
}
|
||||
|
||||
func generateNewFileName(_ prefix: String, _ ext: String) -> String {
|
||||
uniqueCombine("\(prefix)_\(getTimestamp()).\(ext)")
|
||||
func generateNewFileName(_ prefix: String, _ ext: String, fullPath: Bool = false) -> String {
|
||||
uniqueCombine("\(prefix)_\(getTimestamp()).\(ext)", fullPath: fullPath)
|
||||
}
|
||||
|
||||
private func uniqueCombine(_ fileName: String) -> String {
|
||||
private func uniqueCombine(_ fileName: String, fullPath: Bool = false) -> String {
|
||||
func tryCombine(_ fileName: String, _ n: Int) -> String {
|
||||
let ns = fileName as NSString
|
||||
let name = ns.deletingPathExtension
|
||||
let ext = ns.pathExtension
|
||||
let suffix = (n == 0) ? "" : "_\(n)"
|
||||
let f = "\(name)\(suffix).\(ext)"
|
||||
return (FileManager.default.fileExists(atPath: getAppFilePath(f).path)) ? tryCombine(fileName, n + 1) : f
|
||||
return (FileManager.default.fileExists(atPath: fullPath ? f : getAppFilePath(f).path)) ? tryCombine(fileName, n + 1) : f
|
||||
}
|
||||
return tryCombine(fileName, 0)
|
||||
}
|
||||
|
@ -384,10 +384,10 @@ struct ComposeView: View {
|
||||
}
|
||||
}
|
||||
.sheet(isPresented: $showMediaPicker) {
|
||||
LibraryMediaListPicker(media: $chosenMedia, selectionLimit: 10) { itemsSelected in
|
||||
showMediaPicker = false
|
||||
if itemsSelected {
|
||||
DispatchQueue.main.async {
|
||||
LibraryMediaListPicker(addMedia: addMediaContent, selectionLimit: 10) { itemsSelected in
|
||||
await MainActor.run {
|
||||
showMediaPicker = false
|
||||
if itemsSelected {
|
||||
composeState = composeState.copy(preview: .mediaPreviews(mediaPreviews: []))
|
||||
}
|
||||
}
|
||||
@ -488,6 +488,21 @@ struct ComposeView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private func addMediaContent(_ content: UploadContent) async {
|
||||
if let img = resizeImageToStrSize(content.uiImage, maxDataSize: 14000) {
|
||||
var newMedia: [(String, UploadContent?)] = []
|
||||
if case var .mediaPreviews(media) = composeState.preview {
|
||||
media.append((img, content))
|
||||
newMedia = media
|
||||
} else {
|
||||
newMedia = [(img, content)]
|
||||
}
|
||||
await MainActor.run {
|
||||
composeState = composeState.copy(preview: .mediaPreviews(mediaPreviews: newMedia))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var maxFileSize: Int64 {
|
||||
getMaxFileSize(.xftp)
|
||||
}
|
||||
|
@ -103,8 +103,10 @@ struct GroupProfileView: View {
|
||||
}
|
||||
}
|
||||
.sheet(isPresented: $showImagePicker) {
|
||||
LibraryImagePicker(image: $chosenImage) {
|
||||
didSelectItem in showImagePicker = false
|
||||
LibraryImagePicker(image: $chosenImage) { _ in
|
||||
await MainActor.run {
|
||||
showImagePicker = false
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: chosenImage) { image in
|
||||
|
@ -13,112 +13,122 @@ import SimpleXChat
|
||||
|
||||
struct LibraryImagePicker: View {
|
||||
@Binding var image: UIImage?
|
||||
var didFinishPicking: (_ didSelectItems: Bool) -> Void
|
||||
@State var images: [UploadContent] = []
|
||||
var didFinishPicking: (_ didSelectImage: Bool) async -> Void
|
||||
@State var mediaAdded = false
|
||||
|
||||
var body: some View {
|
||||
LibraryMediaListPicker(media: $images, selectionLimit: 1, didFinishPicking: didFinishPicking)
|
||||
.onChange(of: images) { _ in
|
||||
if let img = images.first {
|
||||
image = img.uiImage
|
||||
}
|
||||
}
|
||||
LibraryMediaListPicker(addMedia: addMedia, selectionLimit: 1, didFinishPicking: didFinishPicking)
|
||||
}
|
||||
|
||||
private func addMedia(_ content: UploadContent) async {
|
||||
if mediaAdded { return }
|
||||
await MainActor.run {
|
||||
mediaAdded = true
|
||||
image = content.uiImage
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct LibraryMediaListPicker: UIViewControllerRepresentable {
|
||||
typealias UIViewControllerType = PHPickerViewController
|
||||
@Binding var media: [UploadContent]
|
||||
var addMedia: (_ content: UploadContent) async -> Void
|
||||
var selectionLimit: Int
|
||||
var didFinishPicking: (_ didSelectItems: Bool) -> Void
|
||||
var didFinishPicking: (_ didSelectItems: Bool) async -> Void
|
||||
|
||||
class Coordinator: PHPickerViewControllerDelegate {
|
||||
let parent: LibraryMediaListPicker
|
||||
let dispatchQueue = DispatchQueue(label: "chat.simplex.app.LibraryMediaListPicker")
|
||||
var media: [UploadContent] = []
|
||||
var mediaCount: Int = 0
|
||||
|
||||
init(_ parent: LibraryMediaListPicker) {
|
||||
self.parent = parent
|
||||
}
|
||||
|
||||
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
|
||||
parent.didFinishPicking(!results.isEmpty)
|
||||
guard !results.isEmpty else {
|
||||
return
|
||||
Task {
|
||||
await parent.didFinishPicking(!results.isEmpty)
|
||||
if results.isEmpty { return }
|
||||
for r in results {
|
||||
await loadItem(r.itemProvider)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parent.media = []
|
||||
media = []
|
||||
mediaCount = results.count
|
||||
for result in results {
|
||||
logger.log("LibraryMediaListPicker result")
|
||||
let p = result.itemProvider
|
||||
if p.hasItemConformingToTypeIdentifier(UTType.movie.identifier) {
|
||||
p.loadFileRepresentation(forTypeIdentifier: UTType.movie.identifier) { url, error in
|
||||
if let url = url {
|
||||
let tempUrl = URL(fileURLWithPath: getTempFilesDirectory().path + "/" + generateNewFileName("video", url.pathExtension))
|
||||
if ((try? FileManager.default.copyItem(at: url, to: tempUrl)) != nil) {
|
||||
ChatModel.shared.filesToDelete.insert(tempUrl)
|
||||
self.loadVideo(url: tempUrl, error: error)
|
||||
private func loadItem(_ p: NSItemProvider) async {
|
||||
logger.debug("LibraryMediaListPicker result")
|
||||
if p.hasItemConformingToTypeIdentifier(UTType.movie.identifier) {
|
||||
if let video = await loadVideo(p) {
|
||||
await self.parent.addMedia(video)
|
||||
logger.debug("LibraryMediaListPicker: added video")
|
||||
}
|
||||
} else if p.hasItemConformingToTypeIdentifier(UTType.data.identifier) {
|
||||
if let img = await loadImageData(p) {
|
||||
await self.parent.addMedia(img)
|
||||
logger.debug("LibraryMediaListPicker: added image")
|
||||
}
|
||||
} else if p.canLoadObject(ofClass: UIImage.self) {
|
||||
if let img = await loadImage(p) {
|
||||
await self.parent.addMedia(.simpleImage(image: img))
|
||||
logger.debug("LibraryMediaListPicker: added image")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func loadImageData(_ p: NSItemProvider) async -> UploadContent? {
|
||||
await withCheckedContinuation { cont in
|
||||
loadFileURL(p, type: UTType.data) { url in
|
||||
if let url = url {
|
||||
let img = UploadContent.loadFromURL(url: url)
|
||||
cont.resume(returning: img)
|
||||
} else {
|
||||
cont.resume(returning: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func loadImage(_ p: NSItemProvider) async -> UIImage? {
|
||||
await withCheckedContinuation { cont in
|
||||
p.loadObject(ofClass: UIImage.self) { obj, err in
|
||||
if let err = err {
|
||||
logger.error("LibraryMediaListPicker result image error: \(err.localizedDescription)")
|
||||
cont.resume(returning: nil)
|
||||
} else {
|
||||
cont.resume(returning: obj as? UIImage)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func loadVideo(_ p: NSItemProvider) async -> UploadContent? {
|
||||
await withCheckedContinuation { cont in
|
||||
loadFileURL(p, type: UTType.movie) { url in
|
||||
if let url = url {
|
||||
let tempUrl = URL(fileURLWithPath: generateNewFileName(getTempFilesDirectory().path + "/" + "video", url.pathExtension, fullPath: true))
|
||||
do {
|
||||
// logger.debug("LibraryMediaListPicker copyItem \(url) to \(tempUrl)")
|
||||
try FileManager.default.copyItem(at: url, to: tempUrl)
|
||||
DispatchQueue.main.async {
|
||||
_ = ChatModel.shared.filesToDelete.insert(tempUrl)
|
||||
}
|
||||
let video = UploadContent.loadVideoFromURL(url: tempUrl)
|
||||
cont.resume(returning: video)
|
||||
return
|
||||
} catch let err {
|
||||
logger.error("LibraryMediaListPicker copyItem error: \(err.localizedDescription)")
|
||||
}
|
||||
}
|
||||
} else if p.hasItemConformingToTypeIdentifier(UTType.data.identifier) {
|
||||
p.loadFileRepresentation(forTypeIdentifier: UTType.data.identifier) { url, error in
|
||||
self.loadImage(object: url, error: error)
|
||||
}
|
||||
} else if p.canLoadObject(ofClass: UIImage.self) {
|
||||
p.loadObject(ofClass: UIImage.self) { image, error in
|
||||
DispatchQueue.main.async {
|
||||
self.loadImage(object: image, error: error)
|
||||
}
|
||||
}
|
||||
cont.resume(returning: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func loadFileURL(_ p: NSItemProvider, type: UTType, completion: @escaping (URL?) -> Void) {
|
||||
p.loadFileRepresentation(forTypeIdentifier: type.identifier) { url, err in
|
||||
if let err = err {
|
||||
logger.error("LibraryMediaListPicker loadFileURL error: \(err.localizedDescription)")
|
||||
completion(nil)
|
||||
} else {
|
||||
dispatchQueue.sync { self.mediaCount -= 1}
|
||||
}
|
||||
}
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
|
||||
self.dispatchQueue.sync {
|
||||
if self.parent.media.count == 0 {
|
||||
logger.log("LibraryMediaListPicker: added \(self.media.count) images out of \(results.count)")
|
||||
self.parent.media = self.media
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func loadImage(object: Any?, error: Error? = nil) {
|
||||
if let error = error {
|
||||
logger.error("LibraryMediaListPicker: couldn't load image with error: \(error.localizedDescription)")
|
||||
} else if let image = object as? UIImage {
|
||||
media.append(.simpleImage(image: image))
|
||||
logger.log("LibraryMediaListPicker: added image")
|
||||
} else if let url = object as? URL, let image = UploadContent.loadFromURL(url: url) {
|
||||
media.append(image)
|
||||
}
|
||||
dispatchQueue.sync {
|
||||
self.mediaCount -= 1
|
||||
if self.mediaCount == 0 && self.parent.media.count == 0 {
|
||||
logger.log("LibraryMediaListPicker: added all media")
|
||||
self.parent.media = self.media
|
||||
self.media = []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func loadVideo(url: URL?, error: Error? = nil) {
|
||||
if let error = error {
|
||||
logger.error("LibraryMediaListPicker: couldn't load video with error: \(error.localizedDescription)")
|
||||
} else if let url = url as URL?, let video = UploadContent.loadVideoFromURL(url: url) {
|
||||
media.append(video)
|
||||
}
|
||||
dispatchQueue.sync {
|
||||
self.mediaCount -= 1
|
||||
if self.mediaCount == 0 && self.parent.media.count == 0 {
|
||||
logger.log("LibraryMediaListPicker: added all media")
|
||||
self.parent.media = self.media
|
||||
self.media = []
|
||||
completion(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -130,8 +130,10 @@ struct AddGroupView: View {
|
||||
}
|
||||
}
|
||||
.sheet(isPresented: $showImagePicker) {
|
||||
LibraryImagePicker(image: $chosenImage) {
|
||||
didSelectItem in showImagePicker = false
|
||||
LibraryImagePicker(image: $chosenImage) { _ in
|
||||
await MainActor.run {
|
||||
showImagePicker = false
|
||||
}
|
||||
}
|
||||
}
|
||||
.alert(isPresented: $showInvalidNameAlert) {
|
||||
|
@ -51,9 +51,9 @@ struct AdvancedNetworkSettings: View {
|
||||
}
|
||||
.disabled(currentNetCfg == NetCfg.proxyDefaults)
|
||||
|
||||
timeoutSettingPicker("TCP connection timeout", selection: $netCfg.tcpConnectTimeout, values: [5_000000, 7_500000, 10_000000, 15_000000, 20_000000, 30_000000, 45_000000], label: secondsLabel)
|
||||
timeoutSettingPicker("Protocol timeout", selection: $netCfg.tcpTimeout, values: [3_000000, 5_000000, 7_000000, 10_000000, 15_000000, 20_000000, 30_000000], label: secondsLabel)
|
||||
timeoutSettingPicker("Protocol timeout per KB", selection: $netCfg.tcpTimeoutPerKb, values: [15_000, 30_000, 60_000, 90_000, 120_000], label: secondsLabel)
|
||||
timeoutSettingPicker("TCP connection timeout", selection: $netCfg.tcpConnectTimeout, values: [7_500000, 10_000000, 15_000000, 20_000000, 30_000000, 45_000000], label: secondsLabel)
|
||||
timeoutSettingPicker("Protocol timeout", selection: $netCfg.tcpTimeout, values: [5_000000, 7_000000, 10_000000, 15_000000, 20_000000, 30_000000], label: secondsLabel)
|
||||
timeoutSettingPicker("Protocol timeout per KB", selection: $netCfg.tcpTimeoutPerKb, values: [15_000, 30_000, 45_000, 60_000, 90_000, 120_000], label: secondsLabel)
|
||||
timeoutSettingPicker("PING interval", selection: $netCfg.smpPingInterval, values: [120_000000, 300_000000, 600_000000, 1200_000000, 2400_000000, 3600_000000], label: secondsLabel)
|
||||
intSettingPicker("PING count", selection: $netCfg.smpPingCount, values: [1, 2, 3, 5, 8], label: "")
|
||||
Toggle("Enable TCP keep-alive", isOn: $enableKeepAlive)
|
||||
|
@ -120,8 +120,10 @@ struct UserProfile: View {
|
||||
}
|
||||
}
|
||||
.sheet(isPresented: $showImagePicker) {
|
||||
LibraryImagePicker(image: $chosenImage) {
|
||||
didSelectItem in showImagePicker = false
|
||||
LibraryImagePicker(image: $chosenImage) { _ in
|
||||
await MainActor.run {
|
||||
showImagePicker = false
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: chosenImage) { image in
|
||||
|
@ -63,11 +63,6 @@
|
||||
5C7505A527B679EE00BE3227 /* NavLinkPlain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7505A427B679EE00BE3227 /* NavLinkPlain.swift */; };
|
||||
5C7505A827B6D34800BE3227 /* ChatInfoToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7505A727B6D34800BE3227 /* ChatInfoToolbar.swift */; };
|
||||
5C764E89279CBCB3000C6508 /* ChatModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C764E88279CBCB3000C6508 /* ChatModel.swift */; };
|
||||
5C8EA13D2B25206A001DE5E4 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C8EA1382B25206A001DE5E4 /* libgmp.a */; };
|
||||
5C8EA13E2B25206A001DE5E4 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C8EA1392B25206A001DE5E4 /* libgmpxx.a */; };
|
||||
5C8EA13F2B25206A001DE5E4 /* libHSsimplex-chat-5.4.0.7-1uCDT6bmj7t4ctyD1vFaZX-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C8EA13A2B25206A001DE5E4 /* libHSsimplex-chat-5.4.0.7-1uCDT6bmj7t4ctyD1vFaZX-ghc9.6.3.a */; };
|
||||
5C8EA1402B25206A001DE5E4 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C8EA13B2B25206A001DE5E4 /* libffi.a */; };
|
||||
5C8EA1412B25206A001DE5E4 /* libHSsimplex-chat-5.4.0.7-1uCDT6bmj7t4ctyD1vFaZX.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C8EA13C2B25206A001DE5E4 /* libHSsimplex-chat-5.4.0.7-1uCDT6bmj7t4ctyD1vFaZX.a */; };
|
||||
5C8F01CD27A6F0D8007D2C8D /* CodeScanner in Frameworks */ = {isa = PBXBuildFile; productRef = 5C8F01CC27A6F0D8007D2C8D /* CodeScanner */; };
|
||||
5C93292F29239A170090FFF9 /* ProtocolServersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C93292E29239A170090FFF9 /* ProtocolServersView.swift */; };
|
||||
5C93293129239BED0090FFF9 /* ProtocolServerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C93293029239BED0090FFF9 /* ProtocolServerView.swift */; };
|
||||
@ -121,6 +116,11 @@
|
||||
5CC2C0FF2809BF11000C35E3 /* SimpleX--iOS--InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5CC2C0FD2809BF11000C35E3 /* SimpleX--iOS--InfoPlist.strings */; };
|
||||
5CC868F329EB540C0017BBFD /* CIRcvDecryptionError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CC868F229EB540C0017BBFD /* CIRcvDecryptionError.swift */; };
|
||||
5CCB939C297EFCB100399E78 /* NavStackCompat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CCB939B297EFCB100399E78 /* NavStackCompat.swift */; };
|
||||
5CCD1A602B27927E001A4199 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CCD1A5B2B27927E001A4199 /* libgmpxx.a */; };
|
||||
5CCD1A612B27927E001A4199 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CCD1A5C2B27927E001A4199 /* libgmp.a */; };
|
||||
5CCD1A622B27927E001A4199 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CCD1A5D2B27927E001A4199 /* libffi.a */; };
|
||||
5CCD1A632B27927E001A4199 /* libHSsimplex-chat-5.4.0.7-EoJ0xKOyE47DlSpHXf0V4.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CCD1A5E2B27927E001A4199 /* libHSsimplex-chat-5.4.0.7-EoJ0xKOyE47DlSpHXf0V4.a */; };
|
||||
5CCD1A642B27927E001A4199 /* libHSsimplex-chat-5.4.0.7-EoJ0xKOyE47DlSpHXf0V4-ghc8.10.7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CCD1A5F2B27927E001A4199 /* libHSsimplex-chat-5.4.0.7-EoJ0xKOyE47DlSpHXf0V4-ghc8.10.7.a */; };
|
||||
5CCD403427A5F6DF00368C90 /* AddContactView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CCD403327A5F6DF00368C90 /* AddContactView.swift */; };
|
||||
5CCD403727A5F9A200368C90 /* ScanToConnectView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CCD403627A5F9A200368C90 /* ScanToConnectView.swift */; };
|
||||
5CD67B8F2B0E858A00C510B1 /* hs_init.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CD67B8D2B0E858A00C510B1 /* hs_init.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
@ -338,11 +338,6 @@
|
||||
5C8B41C929AF41BC00888272 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
5C8B41CB29AF44CF00888272 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = "cs.lproj/SimpleX--iOS--InfoPlist.strings"; sourceTree = "<group>"; };
|
||||
5C8B41CC29AF44CF00888272 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
5C8EA1382B25206A001DE5E4 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
|
||||
5C8EA1392B25206A001DE5E4 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
|
||||
5C8EA13A2B25206A001DE5E4 /* libHSsimplex-chat-5.4.0.7-1uCDT6bmj7t4ctyD1vFaZX-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.4.0.7-1uCDT6bmj7t4ctyD1vFaZX-ghc9.6.3.a"; sourceTree = "<group>"; };
|
||||
5C8EA13B2B25206A001DE5E4 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
|
||||
5C8EA13C2B25206A001DE5E4 /* libHSsimplex-chat-5.4.0.7-1uCDT6bmj7t4ctyD1vFaZX.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.4.0.7-1uCDT6bmj7t4ctyD1vFaZX.a"; sourceTree = "<group>"; };
|
||||
5C93292E29239A170090FFF9 /* ProtocolServersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProtocolServersView.swift; sourceTree = "<group>"; };
|
||||
5C93293029239BED0090FFF9 /* ProtocolServerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProtocolServerView.swift; sourceTree = "<group>"; };
|
||||
5C93293E2928E0FD0090FFF9 /* AudioRecPlay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioRecPlay.swift; sourceTree = "<group>"; };
|
||||
@ -412,6 +407,11 @@
|
||||
5CC2C0FE2809BF11000C35E3 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = "ru.lproj/SimpleX--iOS--InfoPlist.strings"; sourceTree = "<group>"; };
|
||||
5CC868F229EB540C0017BBFD /* CIRcvDecryptionError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIRcvDecryptionError.swift; sourceTree = "<group>"; };
|
||||
5CCB939B297EFCB100399E78 /* NavStackCompat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavStackCompat.swift; sourceTree = "<group>"; };
|
||||
5CCD1A5B2B27927E001A4199 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
|
||||
5CCD1A5C2B27927E001A4199 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
|
||||
5CCD1A5D2B27927E001A4199 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
|
||||
5CCD1A5E2B27927E001A4199 /* libHSsimplex-chat-5.4.0.7-EoJ0xKOyE47DlSpHXf0V4.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.4.0.7-EoJ0xKOyE47DlSpHXf0V4.a"; sourceTree = "<group>"; };
|
||||
5CCD1A5F2B27927E001A4199 /* libHSsimplex-chat-5.4.0.7-EoJ0xKOyE47DlSpHXf0V4-ghc8.10.7.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.4.0.7-EoJ0xKOyE47DlSpHXf0V4-ghc8.10.7.a"; sourceTree = "<group>"; };
|
||||
5CCD403327A5F6DF00368C90 /* AddContactView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddContactView.swift; sourceTree = "<group>"; };
|
||||
5CCD403627A5F9A200368C90 /* ScanToConnectView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanToConnectView.swift; sourceTree = "<group>"; };
|
||||
5CD67B8D2B0E858A00C510B1 /* hs_init.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = hs_init.h; sourceTree = "<group>"; };
|
||||
@ -527,13 +527,13 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
5C8EA13F2B25206A001DE5E4 /* libHSsimplex-chat-5.4.0.7-1uCDT6bmj7t4ctyD1vFaZX-ghc9.6.3.a in Frameworks */,
|
||||
5C8EA1402B25206A001DE5E4 /* libffi.a in Frameworks */,
|
||||
5C8EA13E2B25206A001DE5E4 /* libgmpxx.a in Frameworks */,
|
||||
5CCD1A602B27927E001A4199 /* libgmpxx.a in Frameworks */,
|
||||
5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */,
|
||||
5C8EA13D2B25206A001DE5E4 /* libgmp.a in Frameworks */,
|
||||
5C8EA1412B25206A001DE5E4 /* libHSsimplex-chat-5.4.0.7-1uCDT6bmj7t4ctyD1vFaZX.a in Frameworks */,
|
||||
5CCD1A612B27927E001A4199 /* libgmp.a in Frameworks */,
|
||||
5CCD1A622B27927E001A4199 /* libffi.a in Frameworks */,
|
||||
5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */,
|
||||
5CCD1A642B27927E001A4199 /* libHSsimplex-chat-5.4.0.7-EoJ0xKOyE47DlSpHXf0V4-ghc8.10.7.a in Frameworks */,
|
||||
5CCD1A632B27927E001A4199 /* libHSsimplex-chat-5.4.0.7-EoJ0xKOyE47DlSpHXf0V4.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -595,11 +595,11 @@
|
||||
5C764E5C279C70B7000C6508 /* Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5C8EA13B2B25206A001DE5E4 /* libffi.a */,
|
||||
5C8EA1382B25206A001DE5E4 /* libgmp.a */,
|
||||
5C8EA1392B25206A001DE5E4 /* libgmpxx.a */,
|
||||
5C8EA13A2B25206A001DE5E4 /* libHSsimplex-chat-5.4.0.7-1uCDT6bmj7t4ctyD1vFaZX-ghc9.6.3.a */,
|
||||
5C8EA13C2B25206A001DE5E4 /* libHSsimplex-chat-5.4.0.7-1uCDT6bmj7t4ctyD1vFaZX.a */,
|
||||
5CCD1A5D2B27927E001A4199 /* libffi.a */,
|
||||
5CCD1A5C2B27927E001A4199 /* libgmp.a */,
|
||||
5CCD1A5B2B27927E001A4199 /* libgmpxx.a */,
|
||||
5CCD1A5F2B27927E001A4199 /* libHSsimplex-chat-5.4.0.7-EoJ0xKOyE47DlSpHXf0V4-ghc8.10.7.a */,
|
||||
5CCD1A5E2B27927E001A4199 /* libHSsimplex-chat-5.4.0.7-EoJ0xKOyE47DlSpHXf0V4.a */,
|
||||
);
|
||||
path = Libraries;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1207,9 +1207,9 @@ public struct NetCfg: Codable, Equatable {
|
||||
public static let defaults: NetCfg = NetCfg(
|
||||
socksProxy: nil,
|
||||
sessionMode: TransportSessionMode.user,
|
||||
tcpConnectTimeout: 15_000_000,
|
||||
tcpTimeout: 10_000_000,
|
||||
tcpTimeoutPerKb: 30_000,
|
||||
tcpConnectTimeout: 20_000_000,
|
||||
tcpTimeout: 15_000_000,
|
||||
tcpTimeoutPerKb: 45_000,
|
||||
tcpKeepAlive: KeepAliveOpts.defaults,
|
||||
smpPingInterval: 1200_000_000,
|
||||
smpPingCount: 3,
|
||||
|
@ -2800,9 +2800,9 @@ data class NetCfg(
|
||||
hostMode = HostMode.OnionViaSocks,
|
||||
requiredHostMode = false,
|
||||
sessionMode = TransportSessionMode.User,
|
||||
tcpConnectTimeout = 15_000_000,
|
||||
tcpTimeout = 10_000_000,
|
||||
tcpTimeoutPerKb = 30_000,
|
||||
tcpConnectTimeout = 20_000_000,
|
||||
tcpTimeout = 15_000_000,
|
||||
tcpTimeoutPerKb = 45_000,
|
||||
tcpKeepAlive = KeepAliveOpts.defaults,
|
||||
smpPingInterval = 1200_000_000,
|
||||
smpPingCount = 3
|
||||
|
@ -154,20 +154,20 @@ fun AdvancedNetworkSettingsView(chatModel: ChatModel) {
|
||||
SectionItemView {
|
||||
TimeoutSettingRow(
|
||||
stringResource(MR.strings.network_option_tcp_connection_timeout), networkTCPConnectTimeout,
|
||||
listOf(5_000000, 7_500000, 10_000000, 15_000000, 20_000000, 30_000_000, 45_000_000), secondsLabel
|
||||
listOf(7_500000, 10_000000, 15_000000, 20_000000, 30_000_000, 45_000_000), secondsLabel
|
||||
)
|
||||
}
|
||||
SectionItemView {
|
||||
TimeoutSettingRow(
|
||||
stringResource(MR.strings.network_option_protocol_timeout), networkTCPTimeout,
|
||||
listOf(3_000000, 5_000000, 7_000000, 10_000000, 15_000000, 20_000_000, 30_000_000), secondsLabel
|
||||
listOf(5_000000, 7_000000, 10_000000, 15_000000, 20_000_000, 30_000_000), secondsLabel
|
||||
)
|
||||
}
|
||||
SectionItemView {
|
||||
// can't be higher than 130ms to avoid overflow on 32bit systems
|
||||
TimeoutSettingRow(
|
||||
stringResource(MR.strings.network_option_protocol_timeout_per_kb), networkTCPTimeoutPerKb,
|
||||
listOf(15_000, 30_000, 60_000, 90_000, 120_000), secondsLabel
|
||||
listOf(15_000, 30_000, 45_000, 60_000, 90_000, 120_000), secondsLabel
|
||||
)
|
||||
}
|
||||
SectionItemView {
|
||||
|
@ -11,7 +11,7 @@ constraints: zip +disable-bzip2 +disable-zstd
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/simplex-chat/simplexmq.git
|
||||
tag: 560dc553127851fa1fb201d0a9c80dcf1ad6e5dc
|
||||
tag: f576260594b9898e26dbac1bcb4b5061fa4fa242
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
|
@ -7,7 +7,7 @@ revision: 25.11.2023
|
||||
| Updated 25.11.2023 | Languages: EN |
|
||||
# Download SimpleX apps
|
||||
|
||||
The latest stable version is v5.4.0.
|
||||
The latest stable version is v5.4.1.
|
||||
|
||||
You can get the latest beta releases from [GitHub](https://github.com/simplex-chat/simplex-chat/releases).
|
||||
|
||||
@ -21,24 +21,24 @@ You can get the latest beta releases from [GitHub](https://github.com/simplex-ch
|
||||
|
||||
Using the same profile as on mobile device is not yet supported – you need to create a separate profile to use desktop apps.
|
||||
|
||||
**Linux**: [AppImage](https://github.com/simplex-chat/simplex-chat/releases/download/v5.4.0/simplex-desktop-x86_64.AppImage) (most Linux distros), [Ubuntu 20.04](https://github.com/simplex-chat/simplex-chat/releases/download/v5.4.0/simplex-desktop-ubuntu-20_04-x86_64.deb) (and Debian-based distros), [Ubuntu 22.04](https://github.com/simplex-chat/simplex-chat/releases/download/v5.4.0/simplex-desktop-ubuntu-22_04-x86_64.deb).
|
||||
**Linux**: [AppImage](https://github.com/simplex-chat/simplex-chat/releases/download/v5.4.1/simplex-desktop-x86_64.AppImage) (most Linux distros), [Ubuntu 20.04](https://github.com/simplex-chat/simplex-chat/releases/download/v5.4.1/simplex-desktop-ubuntu-20_04-x86_64.deb) (and Debian-based distros), [Ubuntu 22.04](https://github.com/simplex-chat/simplex-chat/releases/download/v5.4.1/simplex-desktop-ubuntu-22_04-x86_64.deb).
|
||||
|
||||
**Mac**: [x86_64](https://github.com/simplex-chat/simplex-chat/releases/download/v5.4.0/simplex-desktop-macos-x86_64.dmg) (Intel), [aarch64](https://github.com/simplex-chat/simplex-chat/releases/download/v5.4.0/simplex-desktop-macos-aarch64.dmg) (Apple Silicon).
|
||||
**Mac**: [x86_64](https://github.com/simplex-chat/simplex-chat/releases/download/v5.4.1/simplex-desktop-macos-x86_64.dmg) (Intel), [aarch64](https://github.com/simplex-chat/simplex-chat/releases/download/v5.4.1/simplex-desktop-macos-aarch64.dmg) (Apple Silicon).
|
||||
|
||||
**Windows**: [x86_64](https://github.com/simplex-chat/simplex-chat/releases/download/v5.4.0/simplex-desktop-windows-x86_64.msi).
|
||||
**Windows**: [x86_64](https://github.com/simplex-chat/simplex-chat/releases/download/v5.4.1/simplex-desktop-windows-x86_64.msi).
|
||||
|
||||
## Mobile apps
|
||||
|
||||
**iOS**: [App store](https://apps.apple.com/us/app/simplex-chat/id1605771084), [TestFlight](https://testflight.apple.com/join/DWuT2LQu).
|
||||
|
||||
**Android**: [Play store](https://play.google.com/store/apps/details?id=chat.simplex.app), [F-Droid](https://simplex.chat/fdroid/), [APK aarch64](https://github.com/simplex-chat/simplex-chat/releases/download/v5.4.0/simplex.apk), [APK armv7](https://github.com/simplex-chat/simplex-chat/releases/download/v5.4.0/simplex-armv7a.apk).
|
||||
**Android**: [Play store](https://play.google.com/store/apps/details?id=chat.simplex.app), [F-Droid](https://simplex.chat/fdroid/), [APK aarch64](https://github.com/simplex-chat/simplex-chat/releases/download/v5.4.1/simplex.apk), [APK armv7](https://github.com/simplex-chat/simplex-chat/releases/download/v5.4.1/simplex-armv7a.apk).
|
||||
|
||||
## Terminal (console) app
|
||||
|
||||
See [Using terminal app](/docs/CLI.md).
|
||||
|
||||
**Linux**: [Ubuntu 20.04](https://github.com/simplex-chat/simplex-chat/releases/download/v5.4.0/simplex-chat-ubuntu-20_04-x86-64), [Ubuntu 22.04](https://github.com/simplex-chat/simplex-chat/releases/download/v5.4.0/simplex-chat-ubuntu-22_04-x86-64).
|
||||
**Linux**: [Ubuntu 20.04](https://github.com/simplex-chat/simplex-chat/releases/download/v5.4.1/simplex-chat-ubuntu-20_04-x86-64), [Ubuntu 22.04](https://github.com/simplex-chat/simplex-chat/releases/download/v5.4.1/simplex-chat-ubuntu-22_04-x86-64).
|
||||
|
||||
**Mac** [x86_64](https://github.com/simplex-chat/simplex-chat/releases/download/v5.4.0/simplex-chat-macos-x86-64), aarch64 - [compile from source](./CLI.md#).
|
||||
**Mac** [x86_64](https://github.com/simplex-chat/simplex-chat/releases/download/v5.4.1/simplex-chat-macos-x86-64), aarch64 - [compile from source](./CLI.md#).
|
||||
|
||||
**Windows**: [x86_64](https://github.com/simplex-chat/simplex-chat/releases/download/v5.4.0/simplex-chat-windows-x86-64).
|
||||
**Windows**: [x86_64](https://github.com/simplex-chat/simplex-chat/releases/download/v5.4.1/simplex-chat-windows-x86-64).
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"https://github.com/simplex-chat/simplexmq.git"."560dc553127851fa1fb201d0a9c80dcf1ad6e5dc" = "1xz3lw5dsh7gm136jzwmsbqjigsqsnjlbhg38mpc6lm586lg8f9x";
|
||||
"https://github.com/simplex-chat/simplexmq.git"."f576260594b9898e26dbac1bcb4b5061fa4fa242" = "0lmfncha6dxxg5ck9f4a155kyd6267k5m9w5mli121lir6ikvk7z";
|
||||
"https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38";
|
||||
"https://github.com/kazu-yamamoto/http2.git"."f5525b755ff2418e6e6ecc69e877363b0d0bcaeb" = "0fyx0047gvhm99ilp212mmz37j84cwrfnpmssib5dw363fyb88b6";
|
||||
"https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "0kiwhvml42g9anw4d2v0zd1fpc790pj9syg5x3ik4l97fnkbbwpp";
|
||||
|
Loading…
Reference in New Issue
Block a user