Compare commits

..

4 Commits

4 changed files with 68 additions and 23 deletions

View File

@ -2968,7 +2968,7 @@
repositoryURL = "https://git.shadowfacts.net/shadowfacts/HTMLStreamer.git"; repositoryURL = "https://git.shadowfacts.net/shadowfacts/HTMLStreamer.git";
requirement = { requirement = {
kind = exactVersion; kind = exactVersion;
version = 0.2.1; version = 0.2.3;
}; };
}; };
D63CC700290EC0B8000E19DE /* XCRemoteSwiftPackageReference "sentry-cocoa" */ = { D63CC700290EC0B8000E19DE /* XCRemoteSwiftPackageReference "sentry-cocoa" */ = {

View File

@ -197,7 +197,7 @@ class LargeImageGifvContentView: GifvAttachmentView, LargeImageContentView {
} }
fileprivate class ImageActivityItemSource: NSObject, UIActivityItemSource { class ImageActivityItemSource: NSObject, UIActivityItemSource {
let data: Data let data: Data
let url: URL let url: URL
let image: UIImage? let image: UIImage?
@ -231,7 +231,7 @@ fileprivate class ImageActivityItemSource: NSObject, UIActivityItemSource {
} }
} }
fileprivate class GifvActivityItemSource: NSObject, UIActivityItemSource { class GifvActivityItemSource: NSObject, UIActivityItemSource {
let asset: AVAsset let asset: AVAsset
let attachment: Attachment let attachment: Attachment

View File

@ -48,7 +48,7 @@ extension MenuActionProvider {
var shareSection = [ var shareSection = [
openInSafariAction(url: account.url), openInSafariAction(url: account.url),
createAction(identifier: "share", title: "Share", systemImageName: "square.and.arrow.up", handler: { [weak self] (_) in createAction(identifier: "share", title: "Share", systemImageName: "square.and.arrow.up", handler: { [weak self] (_) in
guard let self = self else { return } guard let self = self else { return }
self.navigationDelegate?.showMoreOptions(forAccount: accountID, source: source) self.navigationDelegate?.showMoreOptions(forAccount: accountID, source: source)
}) })
@ -121,7 +121,7 @@ extension MenuActionProvider {
func actionsForURL(_ url: URL, source: PopoverSource) -> [UIAction] { func actionsForURL(_ url: URL, source: PopoverSource) -> [UIAction] {
return [ return [
openInSafariAction(url: url), openInSafariAction(url: url),
createAction(identifier: "share", title: "Share", systemImageName: "square.and.arrow.up", handler: { [weak self] (_) in createAction(identifier: "share", title: "Share", systemImageName: "square.and.arrow.up", handler: { [weak self] (_) in
guard let self = self else { return } guard let self = self else { return }
self.navigationDelegate?.showMoreOptions(forURL: url, source: source) self.navigationDelegate?.showMoreOptions(forURL: url, source: source)
}) })
@ -182,7 +182,7 @@ extension MenuActionProvider {
if let url = status.url { if let url = status.url {
return [ return [
openInSafariAction(url: url), openInSafariAction(url: url),
createAction(identifier: "share", title: "Share", systemImageName: "square.and.arrow.up", handler: { [weak self] (_) in createAction(identifier: "share", title: "Share", systemImageName: "square.and.arrow.up", handler: { [weak self] (_) in
guard let self = self else { return } guard let self = self else { return }
self.navigationDelegate?.showMoreOptions(forStatus: status.id, source: source) self.navigationDelegate?.showMoreOptions(forStatus: status.id, source: source)
}), }),
@ -366,7 +366,7 @@ extension MenuActionProvider {
} else { } else {
Logging.general.fault("Status missing URL: id=\(status.id, privacy: .public), reblog=\((status.reblog?.id).debugDescription, privacy: .public)") Logging.general.fault("Status missing URL: id=\(status.id, privacy: .public), reblog=\((status.reblog?.id).debugDescription, privacy: .public)")
} }
shareSection.append(createAction(identifier: "share", title: "Share", systemImageName: "square.and.arrow.up", handler: { [weak self] (_) in shareSection.append(createAction(identifier: "share", title: "Share", systemImageName: "square.and.arrow.up", handler: { [weak self] (_) in
guard let self = self else { return } guard let self = self else { return }
self.navigationDelegate?.showMoreOptions(forStatus: status.id, source: source) self.navigationDelegate?.showMoreOptions(forStatus: status.id, source: source)
})) }))
@ -394,7 +394,7 @@ extension MenuActionProvider {
} }
return [ return [
openInSafariAction(url: url), openInSafariAction(url: url),
createAction(identifier: "share", title: "Share", systemImageName: "square.and.arrow.up", handler: { [weak self] (_) in createAction(identifier: "share", title: "Share", systemImageName: "square.and.arrow.up", handler: { [weak self] (_) in
guard let self else { return } guard let self else { return }
self.navigationDelegate?.showMoreOptions(forURL: url, source: source) self.navigationDelegate?.showMoreOptions(forURL: url, source: source)
}), }),

View File

@ -203,7 +203,7 @@ class AttachmentView: GIFImageView {
await displayImage() await displayImage()
} }
} else if let image { } else if let image {
source = .image(attachment.url, image) source = .image(attachment.url, data, image)
await displayImage() await displayImage()
} }
} }
@ -225,7 +225,7 @@ class AttachmentView: GIFImageView {
return return
} }
source = .image(previewURL, image) source = .image(previewURL, nil, image)
await displayImage() await displayImage()
} else { } else {
let asset = AVURLAsset(url: attachment.url) let asset = AVURLAsset(url: attachment.url)
@ -246,7 +246,7 @@ class AttachmentView: GIFImageView {
!Task.isCancelled else { !Task.isCancelled else {
return return
} }
source = .image(attachment.url, prepared) source = .image(attachment.url, nil, prepared)
await displayImage() await displayImage()
} }
} }
@ -315,7 +315,7 @@ class AttachmentView: GIFImageView {
case nil: case nil:
self.image = nil self.image = nil
case let .image(url, sourceImage): case let .image(url, _, sourceImage):
if isGrayscale { if isGrayscale {
self.image = await ImageGrayscalifier.convert(url: url, image: sourceImage) self.image = await ImageGrayscalifier.convert(url: url, image: sourceImage)
} else { } else {
@ -329,13 +329,6 @@ class AttachmentView: GIFImageView {
} else { } else {
self.image = sourceImage self.image = sourceImage
} }
case let .cgImage(url, cgImage):
if isGrayscale {
self.image = await ImageGrayscalifier.convert(url: url, cgImage: cgImage)
} else {
self.image = UIImage(cgImage: cgImage)
}
} }
} }
@ -424,9 +417,9 @@ class AttachmentView: GIFImageView {
fileprivate extension AttachmentView { fileprivate extension AttachmentView {
enum Source { enum Source {
case image(URL, UIImage) case image(URL, Data?, UIImage)
case gifData(URL, Data, UIImage?) case gifData(URL, Data, UIImage?)
case cgImage(URL, CGImage) // case cgImage(URL, CGImage)
} }
struct Badges: OptionSet { struct Badges: OptionSet {
@ -439,7 +432,7 @@ fileprivate extension AttachmentView {
extension AttachmentView: UIContextMenuInteractionDelegate { extension AttachmentView: UIContextMenuInteractionDelegate {
func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? { func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
return UIContextMenuConfiguration(identifier: nil, previewProvider: { () -> UIViewController? in return UIContextMenuConfiguration { [unowned self] () -> UIViewController? in
if self.attachment.kind == .image { if self.attachment.kind == .image {
return AttachmentPreviewViewController(sourceView: self) return AttachmentPreviewViewController(sourceView: self)
} else if self.attachment.kind == .gifv { } else if self.attachment.kind == .gifv {
@ -449,8 +442,60 @@ extension AttachmentView: UIContextMenuInteractionDelegate {
} else { } else {
return self.delegate?.attachmentViewGallery(startingAt: self.index) return self.delegate?.attachmentViewGallery(startingAt: self.index)
} }
}, actionProvider: nil) } actionProvider: { [unowned self] _ in
let itemSource: UIActivityItemSource
let itemData: Task<Data?, Never>
if self.attachment.kind == .image,
let source {
switch source {
case .image(let url, let data, let image):
let imageData: Data
if let data {
imageData = data
} else if let data = image.pngData() {
imageData = data
} else {
return nil
} }
itemSource = ImageActivityItemSource(data: imageData, url: url, image: image)
itemData = Task { imageData }
case .gifData(let url, let data, let image):
itemSource = ImageActivityItemSource(data: data, url: url, image: image)
itemData = Task { data }
}
} else if self.attachment.kind == .gifv {
itemSource = GifvActivityItemSource(asset: AVAsset(url: self.attachment.url), attachment: self.attachment)
itemData = Task {
try? await URLSession.shared.data(from: self.attachment.url).0
}
} else {
return nil
}
var actions = [
UIAction(title: "Share…", image: UIImage(systemName: "square.and.arrow.up")) { [unowned self] _ in
let vc = UIActivityViewController(activityItems: [itemSource], applicationActivities: [SaveToPhotosActivity()])
self.delegate?.attachmentViewPresent(vc, animated: true)
}
]
let activity = SaveToPhotosActivity()
if activity.canPerform(withActivityItems: [self.attachment.url]) {
actions.append(UIAction(title: "Save to Photos", image: UIImage(systemName: "square.and.arrow.down"), handler: { _ in
Task {
guard let itemData = await itemData.value else {
return
}
let tempURL = FileManager.default.temporaryDirectory.appendingPathComponent(self.attachment.url.lastPathComponent)
try itemData.write(to: tempURL)
activity.prepare(withActivityItems: [tempURL])
activity.perform()
}
}))
}
return UIMenu(children: actions)
}
}
func contextMenuInteraction(_ interaction: UIContextMenuInteraction, willPerformPreviewActionForMenuWith configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionCommitAnimating) { func contextMenuInteraction(_ interaction: UIContextMenuInteraction, willPerformPreviewActionForMenuWith configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionCommitAnimating) {
animator.addCompletion { animator.addCompletion {
animator.preferredCommitStyle = .pop animator.preferredCommitStyle = .pop