Add quick look for videos

This commit is contained in:
Thomas Ricouard 2024-01-22 21:54:28 +01:00
parent 245d35db82
commit eeff60bf98
5 changed files with 89 additions and 82 deletions

View file

@ -0,0 +1,16 @@
import SwiftUI
import Models
enum DisplayType {
case image
case av
init(from attachmentType: MediaAttachment.SupportedType) {
switch attachmentType {
case .image:
self = .image
case .video, .gifv, .audio:
self = .av
}
}
}

View file

@ -7,7 +7,7 @@ import SwiftUI
@MainActor
@Observable public class MediaUIAttachmentVideoViewModel {
var player: AVPlayer?
private let url: URL
let url: URL
let forceAutoPlay: Bool
var isPlaying: Bool = false
@ -112,6 +112,7 @@ public struct MediaUIAttachmentVideoView: View {
Image(systemName: "xmark.circle")
}
}
QuickLookToolbarItem(itemUrl: viewModel.url)
}
}
.onAppear {

View file

@ -189,73 +189,6 @@ private struct SavePhotoToolbarItem: ToolbarContent, @unchecked Sendable {
}
}
private struct QuickLookToolbarItem: ToolbarContent, @unchecked Sendable {
let itemUrl: URL
@State private var localPath: URL?
@State private var isLoading = false
var body: some ToolbarContent {
ToolbarItem(placement: .topBarTrailing) {
Button {
Task {
isLoading = true
localPath = await localPathFor(url: itemUrl)
isLoading = false
}
} label: {
if isLoading {
ProgressView()
} else {
Image(systemName: "info.circle")
}
}
.quickLookPreview($localPath)
}
}
private func imageData(_ url: URL) async -> Data? {
var data = ImagePipeline.shared.cache.cachedData(for: .init(url: url))
if data == nil {
data = try? await URLSession.shared.data(from: url).0
}
return data
}
private func localPathFor(url: URL) async -> URL {
try? FileManager.default.removeItem(at: quickLookDir)
try? FileManager.default.createDirectory(at: quickLookDir, withIntermediateDirectories: true)
let path = quickLookDir.appendingPathComponent(url.lastPathComponent)
let data = await imageData(url)
try? data?.write(to: path)
return path
}
private var quickLookDir: URL {
try! FileManager.default.url(for: .cachesDirectory,
in: .userDomainMask,
appropriateFor: nil,
create: false)
.appending(component: "quicklook")
}
}
private struct ShareToolbarItem: ToolbarContent, @unchecked Sendable {
let url: URL
let type: DisplayType
var body: some ToolbarContent {
ToolbarItem(placement: .topBarTrailing) {
if type == .image {
let transferable = MediaUIImageTransferable(url: url)
ShareLink(item: transferable, preview: .init("status.media.contextmenu.share",
image: transferable))
} else {
ShareLink(item: url)
}
}
}
}
private struct DisplayData: Identifiable, Hashable {
let id: String
let url: URL
@ -273,20 +206,6 @@ private struct DisplayData: Identifiable, Hashable {
}
}
private enum DisplayType {
case image
case av
init(from attachmentType: MediaAttachment.SupportedType) {
switch attachmentType {
case .image:
self = .image
case .video, .gifv, .audio:
self = .av
}
}
}
private struct DisplayView: View {
let data: DisplayData

View file

@ -0,0 +1,53 @@
import SwiftUI
import NukeUI
import Nuke
struct QuickLookToolbarItem: ToolbarContent, @unchecked Sendable {
let itemUrl: URL
@State private var localPath: URL?
@State private var isLoading = false
var body: some ToolbarContent {
ToolbarItem(placement: .topBarTrailing) {
Button {
Task {
isLoading = true
localPath = await localPathFor(url: itemUrl)
isLoading = false
}
} label: {
if isLoading {
ProgressView()
} else {
Image(systemName: "info.circle")
}
}
.quickLookPreview($localPath)
}
}
private func imageData(_ url: URL) async -> Data? {
var data = ImagePipeline.shared.cache.cachedData(for: .init(url: url))
if data == nil {
data = try? await URLSession.shared.data(from: url).0
}
return data
}
private func localPathFor(url: URL) async -> URL {
try? FileManager.default.removeItem(at: quickLookDir)
try? FileManager.default.createDirectory(at: quickLookDir, withIntermediateDirectories: true)
let path = quickLookDir.appendingPathComponent(url.lastPathComponent)
let data = await imageData(url)
try? data?.write(to: path)
return path
}
private var quickLookDir: URL {
try! FileManager.default.url(for: .cachesDirectory,
in: .userDomainMask,
appropriateFor: nil,
create: false)
.appending(component: "quicklook")
}
}

View file

@ -0,0 +1,18 @@
import SwiftUI
struct ShareToolbarItem: ToolbarContent, @unchecked Sendable {
let url: URL
let type: DisplayType
var body: some ToolbarContent {
ToolbarItem(placement: .topBarTrailing) {
if type == .image {
let transferable = MediaUIImageTransferable(url: url)
ShareLink(item: transferable, preview: .init("status.media.contextmenu.share",
image: transferable))
} else {
ShareLink(item: url)
}
}
}
}