mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-11-25 09:41:02 +00:00
Add quick look for videos
This commit is contained in:
parent
245d35db82
commit
eeff60bf98
5 changed files with 89 additions and 82 deletions
16
Packages/MediaUI/Sources/MediaUI/DisplayType.swift
Normal file
16
Packages/MediaUI/Sources/MediaUI/DisplayType.swift
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
53
Packages/MediaUI/Sources/MediaUI/QuickLookToolbarItem.swift
Normal file
53
Packages/MediaUI/Sources/MediaUI/QuickLookToolbarItem.swift
Normal 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")
|
||||
}
|
||||
}
|
18
Packages/MediaUI/Sources/MediaUI/ShareToolbarItem.swift
Normal file
18
Packages/MediaUI/Sources/MediaUI/ShareToolbarItem.swift
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue