mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2024-12-17 17:20:21 +01:00
ios: prevent image encoding from blocking the UI (#4966)
* ios: prevent image encoding from blocking the UI * let --------- Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
This commit is contained in:
@@ -122,7 +122,7 @@ extension ThemeWallpaper {
|
||||
let preset: String? = if case let WallpaperType.preset(filename, _) = type { filename } else { nil }
|
||||
let scale: Float? = if case let WallpaperType.preset(_, scale) = type { scale } else { if case let WallpaperType.image(_, scale, _) = type { scale } else { 1.0 } }
|
||||
let scaleType: WallpaperScaleType? = if case let WallpaperType.image(_, _, scaleType) = type { scaleType } else { nil }
|
||||
let image: String? = if case WallpaperType.image = type, let image = type.uiImage { resizeImageToStrSize(image, maxDataSize: 5_000_000) } else { nil }
|
||||
let image: String? = if case WallpaperType.image = type, let image = type.uiImage { resizeImageToStrSizeSync(image, maxDataSize: 5_000_000) } else { nil }
|
||||
return ThemeWallpaper (
|
||||
preset: preset,
|
||||
scale: scale,
|
||||
|
||||
@@ -459,7 +459,7 @@ struct ComposeView: View {
|
||||
Task {
|
||||
var media: [(String, UploadContent)] = []
|
||||
for content in selected {
|
||||
if let img = resizeImageToStrSize(content.uiImage, maxDataSize: 14000) {
|
||||
if let img = await resizeImageToStrSize(content.uiImage, maxDataSize: 14000) {
|
||||
media.append((img, content))
|
||||
await MainActor.run {
|
||||
composeState = composeState.copy(preview: .mediaPreviews(mediaPreviews: media))
|
||||
@@ -551,7 +551,7 @@ struct ComposeView: View {
|
||||
}
|
||||
|
||||
private func addMediaContent(_ content: UploadContent) async {
|
||||
if let img = resizeImageToStrSize(content.uiImage, maxDataSize: 14000) {
|
||||
if let img = await resizeImageToStrSize(content.uiImage, maxDataSize: 14000) {
|
||||
var newMedia: [(String, UploadContent?)] = []
|
||||
if case var .mediaPreviews(media) = composeState.preview {
|
||||
media.append((img, content))
|
||||
|
||||
@@ -110,10 +110,13 @@ struct GroupProfileView: View {
|
||||
}
|
||||
}
|
||||
.onChange(of: chosenImage) { image in
|
||||
if let image = image {
|
||||
groupProfile.image = resizeImageToStrSize(cropToSquare(image), maxDataSize: 12500)
|
||||
} else {
|
||||
groupProfile.image = nil
|
||||
Task {
|
||||
let resized: String? = if let image {
|
||||
await resizeImageToStrSize(cropToSquare(image), maxDataSize: 12500)
|
||||
} else {
|
||||
nil
|
||||
}
|
||||
await MainActor.run { groupProfile.image = resized }
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
|
||||
@@ -137,10 +137,13 @@ struct AddGroupView: View {
|
||||
createInvalidNameAlert(mkValidName(profile.displayName), $profile.displayName)
|
||||
}
|
||||
.onChange(of: chosenImage) { image in
|
||||
if let image = image {
|
||||
profile.image = resizeImageToStrSize(cropToSquare(image), maxDataSize: 12500)
|
||||
} else {
|
||||
profile.image = nil
|
||||
Task {
|
||||
let resized: String? = if let image {
|
||||
await resizeImageToStrSize(cropToSquare(image), maxDataSize: 12500)
|
||||
} else {
|
||||
nil
|
||||
}
|
||||
await MainActor.run { profile.image = resized }
|
||||
}
|
||||
}
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
|
||||
@@ -94,10 +94,13 @@ struct UserProfile: View {
|
||||
}
|
||||
}
|
||||
.onChange(of: chosenImage) { image in
|
||||
if let image {
|
||||
profile.image = resizeImageToStrSize(cropToSquare(image), maxDataSize: 12500)
|
||||
} else {
|
||||
profile.image = nil
|
||||
Task {
|
||||
let resized: String? = if let image {
|
||||
await resizeImageToStrSize(cropToSquare(image), maxDataSize: 12500)
|
||||
} else {
|
||||
nil
|
||||
}
|
||||
await MainActor.run { profile.image = resized }
|
||||
}
|
||||
}
|
||||
// Modals
|
||||
|
||||
@@ -417,7 +417,7 @@ fileprivate func getSharedContent(_ ip: NSItemProvider) async -> Result<SharedCo
|
||||
let data = try? Data(contentsOf: url),
|
||||
let image = UIImage(data: data),
|
||||
let cryptoFile = saveFile(data, generateNewFileName("IMG", "gif"), encrypted: privacyEncryptLocalFilesGroupDefault.get()),
|
||||
let preview = resizeImageToStrSize(image, maxDataSize: MAX_DATA_SIZE) {
|
||||
let preview = await resizeImageToStrSize(image, maxDataSize: MAX_DATA_SIZE) {
|
||||
.success(.image(preview: preview, cryptoFile: cryptoFile))
|
||||
} else { .failure(ErrorAlert("Error preparing message")) }
|
||||
|
||||
@@ -425,7 +425,7 @@ fileprivate func getSharedContent(_ ip: NSItemProvider) async -> Result<SharedCo
|
||||
} else {
|
||||
if let image = await staticImage(),
|
||||
let cryptoFile = saveImage(image),
|
||||
let preview = resizeImageToStrSize(image, maxDataSize: MAX_DATA_SIZE) {
|
||||
let preview = await resizeImageToStrSize(image, maxDataSize: MAX_DATA_SIZE) {
|
||||
.success(.image(preview: preview, cryptoFile: cryptoFile))
|
||||
} else { .failure(ErrorAlert("Error preparing message")) }
|
||||
}
|
||||
@@ -435,7 +435,7 @@ fileprivate func getSharedContent(_ ip: NSItemProvider) async -> Result<SharedCo
|
||||
if let url = try? await inPlaceUrl(type: type),
|
||||
let trancodedUrl = await transcodeVideo(from: url),
|
||||
let (image, duration) = AVAsset(url: trancodedUrl).generatePreview(),
|
||||
let preview = resizeImageToStrSize(image, maxDataSize: MAX_DATA_SIZE),
|
||||
let preview = await resizeImageToStrSize(image, maxDataSize: MAX_DATA_SIZE),
|
||||
let cryptoFile = moveTempFileFromURL(trancodedUrl) {
|
||||
try? FileManager.default.removeItem(at: trancodedUrl)
|
||||
return .success(.movie(preview: preview, duration: duration, cryptoFile: cryptoFile))
|
||||
|
||||
@@ -100,7 +100,7 @@ public func resizeImageToDataSize(_ image: UIImage, maxDataSize: Int64, hasAlpha
|
||||
return data
|
||||
}
|
||||
|
||||
public func resizeImageToStrSize(_ image: UIImage, maxDataSize: Int64) -> String? {
|
||||
public func resizeImageToStrSizeSync(_ image: UIImage, maxDataSize: Int64) -> String? {
|
||||
var img = image
|
||||
let hasAlpha = imageHasAlpha(image)
|
||||
var str = compressImageStr(img, hasAlpha: hasAlpha)
|
||||
@@ -116,7 +116,15 @@ public func resizeImageToStrSize(_ image: UIImage, maxDataSize: Int64) -> String
|
||||
return str
|
||||
}
|
||||
|
||||
public func resizeImageToStrSize(_ image: UIImage, maxDataSize: Int64) async -> String? {
|
||||
resizeImageToStrSizeSync(image, maxDataSize: maxDataSize)
|
||||
}
|
||||
|
||||
public func compressImageStr(_ image: UIImage, _ compressionQuality: CGFloat = 0.85, hasAlpha: Bool) -> String? {
|
||||
// // Heavy workload to verify if UI gets blocked by the call
|
||||
// for i in 0..<100 {
|
||||
// print(image.jpegData(compressionQuality: Double(i) / 100)?.count ?? 0, terminator: ", ")
|
||||
// }
|
||||
let ext = hasAlpha ? "png" : "jpg"
|
||||
if let data = hasAlpha ? image.pngData() : image.jpegData(compressionQuality: compressionQuality) {
|
||||
return "data:image/\(ext);base64,\(data.base64EncodedString())"
|
||||
@@ -426,7 +434,7 @@ public func getLinkPreview(url: URL, cb: @escaping (LinkPreview?) -> Void) {
|
||||
logger.error("Couldn't load image preview from link metadata with error: \(error.localizedDescription)")
|
||||
} else {
|
||||
if let image = object as? UIImage,
|
||||
let resized = resizeImageToStrSize(image, maxDataSize: 14000),
|
||||
let resized = resizeImageToStrSizeSync(image, maxDataSize: 14000),
|
||||
let title = metadata.title,
|
||||
let uri = metadata.originalURL {
|
||||
linkPreview = LinkPreview(uri: uri, title: title, image: resized)
|
||||
|
||||
Reference in New Issue
Block a user