2024-08-17 11:22:47 +00:00
|
|
|
import SwiftUI
|
|
|
|
|
|
|
|
struct GalleryView: View {
|
2024-08-17 13:54:54 +00:00
|
|
|
@EnvironmentObject var store: FileStore
|
|
|
|
@Binding var selectedItems: [String]
|
2024-08-17 11:22:47 +00:00
|
|
|
|
|
|
|
var body: some View {
|
2024-08-17 13:54:54 +00:00
|
|
|
Group {
|
|
|
|
if store.galleryAccessGranted {
|
|
|
|
ForEach(store.galleryItems) { item in
|
|
|
|
GridViewItem(item: item, selected: $selectedItems)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
Button {
|
|
|
|
openAppSettings()
|
|
|
|
} label: {
|
|
|
|
ZStack {
|
|
|
|
Rectangle()
|
|
|
|
.fill(Color.Material.Background.light)
|
|
|
|
.overlay {
|
|
|
|
VStack {
|
|
|
|
Image(systemName: "photo")
|
|
|
|
.foregroundColor(.Material.Elements.active)
|
|
|
|
.font(.system(size: 30))
|
|
|
|
Text("Allow gallery access")
|
|
|
|
.foregroundColor(.Material.Text.main)
|
|
|
|
.font(.body3)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.frame(height: 100)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.task {
|
|
|
|
await store.checkGalleryAuthorization()
|
|
|
|
}
|
|
|
|
.onChange(of: store.galleryAccessGranted) { flag in
|
|
|
|
if flag {
|
|
|
|
Task {
|
|
|
|
await store.fetchGalleryItems()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-08-17 11:22:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private struct GridViewItem: View {
|
2024-08-17 13:54:54 +00:00
|
|
|
@State var item: GalleryItem
|
2024-08-17 11:22:47 +00:00
|
|
|
@Binding var selected: [String]
|
|
|
|
|
|
|
|
var body: some View {
|
2024-08-17 13:54:54 +00:00
|
|
|
if let img = item.thumbnail {
|
|
|
|
ZStack {
|
|
|
|
img
|
|
|
|
.resizable()
|
|
|
|
.aspectRatio(contentMode: .fill)
|
|
|
|
.frame(width: Const.galleryGridSize, height: Const.galleryGridSize)
|
|
|
|
.clipped()
|
|
|
|
if let duration = item.duration {
|
|
|
|
VStack {
|
|
|
|
Spacer()
|
|
|
|
HStack {
|
|
|
|
Spacer()
|
|
|
|
Text(duration)
|
|
|
|
.foregroundColor(.Material.Text.white)
|
|
|
|
.font(.sub1)
|
|
|
|
.shadow(color: .black, radius: 2)
|
|
|
|
.padding(4)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-08-17 15:47:21 +00:00
|
|
|
if isSelected {
|
|
|
|
VStack {
|
|
|
|
HStack {
|
|
|
|
Spacer()
|
|
|
|
Circle()
|
|
|
|
.frame(width: 30, height: 30)
|
|
|
|
.shadow(color: .black, radius: 2)
|
|
|
|
.foregroundColor(.Material.Shape.white)
|
|
|
|
.overlay {
|
|
|
|
Image(systemName: "checkmark")
|
|
|
|
.foregroundColor(.Material.Elements.active)
|
|
|
|
.font(.body3)
|
|
|
|
}
|
|
|
|
.padding(4)
|
|
|
|
}
|
|
|
|
Spacer()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.onTapGesture {
|
|
|
|
if isSelected {
|
|
|
|
selected.removeAll { $0 == item.id }
|
|
|
|
} else {
|
|
|
|
selected.append(item.id)
|
|
|
|
}
|
2024-08-17 13:54:54 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ZStack {
|
|
|
|
Rectangle()
|
|
|
|
.fill(Color.Material.Background.light)
|
|
|
|
.overlay {
|
|
|
|
ProgressView()
|
|
|
|
.foregroundColor(.Material.Elements.active)
|
|
|
|
}
|
|
|
|
.frame(width: Const.galleryGridSize, height: Const.galleryGridSize)
|
|
|
|
}
|
|
|
|
.task {
|
|
|
|
if item.thumbnail == nil {
|
|
|
|
try? await item.fetchThumbnail()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private var isSelected: Bool {
|
|
|
|
selected.contains(item.id)
|
2024-08-17 11:22:47 +00:00
|
|
|
}
|
|
|
|
}
|