Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to disable image resizing when uploading attachments #317

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Localizations/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@
"preferences.notifications.include-pictures" = "Include pictures";
"preferences.notifications.grouping" = "Group follow, favourite, and boost notifications";
"preferences.notifications.sounds" = "Sounds";
"preferences.optimize-images-before-upload" = "Optimize images before upload";
"preferences.muted-users" = "Muted Users";
"preferences.home-timeline-position-on-startup" = "Home timeline position on startup";
"preferences.notifications-position-on-startup" = "Notifications position on startup";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ enum AltTextError: String, Error {
public enum MediaProcessingService {}

public extension MediaProcessingService {
static func dataAndMimeType(itemProvider: NSItemProvider) -> AnyPublisher<(data: InputStream, mimeType: String), Error> {
static func dataAndMimeType(itemProvider: NSItemProvider, optimizeImages: Bool) -> AnyPublisher<(data: InputStream, mimeType: String), Error> {
let registeredTypes = itemProvider.registeredTypeIdentifiers.compactMap(UTType.init)

let mimeType: String
Expand All @@ -47,10 +47,10 @@ public extension MediaProcessingService {
return uploadableMimeTypes.contains(mimeType)
}), let preferredMIMEType = type.preferredMIMEType {
mimeType = preferredMIMEType
dataPublisher = fileRepresentationDataPublisher(itemProvider: itemProvider, type: type)
dataPublisher = fileRepresentationDataPublisher(itemProvider: itemProvider, type: type, optimizeImages: optimizeImages)
} else if registeredTypes == [UTType.image], let pngMIMEType = UTType.png.preferredMIMEType { // screenshot
mimeType = pngMIMEType
dataPublisher = UIImagePNGDataPublisher(itemProvider: itemProvider)
dataPublisher = UIImagePNGDataPublisher(itemProvider: itemProvider, optimize: optimizeImages)
} else {
return Fail(error: MediaProcessingError.invalidMimeType).eraseToAnyPublisher()
}
Expand Down Expand Up @@ -105,15 +105,16 @@ private extension MediaProcessingService {
] as [CFString: Any] as CFDictionary

static func fileRepresentationDataPublisher(itemProvider: NSItemProvider,
type: UTType) -> AnyPublisher<InputStream, Error> {
type: UTType,
optimizeImages: Bool) -> AnyPublisher<InputStream, Error> {
Future<InputStream, Error> { promise in
itemProvider.loadFileRepresentation(forTypeIdentifier: type.identifier) { url, error in
if let error = error {
promise(.failure(error))
} else if let url = url {
promise(Result {
if type.conforms(to: .image) && type != .gif {
return try imageData(url: url, type: type)
return try imageData(url: url, type: type, optimize: optimizeImages)
} else {
guard let stream = InputStream(url: url) else { throw MediaProcessingError.fileURLNotFound }
// The temporary file will be removed upon return. Opening a stream gives us a file descriptor, which allows
Expand All @@ -130,7 +131,7 @@ private extension MediaProcessingService {
.eraseToAnyPublisher()
}

static func UIImagePNGDataPublisher(itemProvider: NSItemProvider) -> AnyPublisher<InputStream, Error> {
static func UIImagePNGDataPublisher(itemProvider: NSItemProvider, optimize: Bool) -> AnyPublisher<InputStream, Error> {
#if canImport(UIKit)
return Future<InputStream, Error> { promise in
itemProvider.loadItem(forTypeIdentifier: UTType.image.identifier, options: nil) { item, error in
Expand All @@ -143,7 +144,7 @@ private extension MediaProcessingService {

try data.write(to: url)

return try imageData(url: url, type: .png)
return try imageData(url: url, type: .png, optimize: optimize)
})
} else {
promise(.failure(MediaProcessingError.imageNotFound))
Expand All @@ -156,7 +157,11 @@ private extension MediaProcessingService {
#endif
}

static func imageData(url: URL, type: UTType) throws -> InputStream {
static func imageData(url: URL, type: UTType, optimize: Bool) throws -> InputStream {
if !optimize, let stream = InputStream(url: url) {
stream.open()
return stream
}
guard let source = CGImageSourceCreateWithURL(url as CFURL, Self.imageSourceOptions) else {
throw MediaProcessingError.unableToCreateImageSource
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,11 @@ public extension AppPreferences {
}
set { self[.postingLanguages] = newValue }
}

var optimizeImagesBeforeUpload: Bool {
get { self[.optimizeImagesBeforeUpload] ?? true }
set { self[.optimizeImagesBeforeUpload] = newValue }
}
}

private extension AppPreferences {
Expand Down Expand Up @@ -288,6 +293,7 @@ private extension AppPreferences {
case useMediaDescriptionMetadata
case visibilityIconColors
case postingLanguages
case optimizeImagesBeforeUpload
}

subscript<T>(index: Item) -> T? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ public extension CompositionViewModel {

func attach(itemProviders: [NSItemProvider], parentViewModel: ComposeStatusViewModel) {
Publishers.MergeMany(itemProviders.map {
MediaProcessingService.dataAndMimeType(itemProvider: $0)
MediaProcessingService.dataAndMimeType(itemProvider: $0, optimizeImages: identityContext.appPreferences.optimizeImagesBeforeUpload)
.zip(
identityContext.appPreferences.useMediaDescriptionMetadata
? MediaProcessingService.description(itemProvider: $0)
Expand Down
4 changes: 4 additions & 0 deletions Views/SwiftUI/Preferences/AppPreferencesSection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ struct AppPreferencesSection: View {
}
}
}
Group {
Toggle("preferences.optimize-images-before-upload",
isOn: $identityContext.appPreferences.optimizeImagesBeforeUpload)
}
}
Section(header: Text("preferences.app.advanced")) {
Picker("preferences.api-compatibility-mode", selection: Binding<APICompatibilityMode?>(
Expand Down