132 lines
3.6 KiB
Swift
132 lines
3.6 KiB
Swift
|
import SwiftUI
|
||
|
|
||
|
enum AttachmentTab: Int, CaseIterable {
|
||
|
case media
|
||
|
case files
|
||
|
case location
|
||
|
case contacts
|
||
|
}
|
||
|
|
||
|
struct AttachmentPickerScreen: View {
|
||
|
@Environment(\.router) var router
|
||
|
|
||
|
@State private var selectedTab: AttachmentTab = .media
|
||
|
|
||
|
var body: some View {
|
||
|
ZStack {
|
||
|
// Background color
|
||
|
Color.Material.Background.light
|
||
|
.ignoresSafeArea()
|
||
|
|
||
|
// Content
|
||
|
VStack(spacing: 0) {
|
||
|
// Header
|
||
|
SharedNavigationBar(
|
||
|
leftButton: .init(
|
||
|
image: Image(systemName: "xmark"),
|
||
|
action: {
|
||
|
router.dismissScreen()
|
||
|
}
|
||
|
),
|
||
|
centerText: .init(text: L10n.Attachment.Prompt.main)
|
||
|
)
|
||
|
|
||
|
// Pickers
|
||
|
switch selectedTab {
|
||
|
case .media:
|
||
|
MediaPickerView()
|
||
|
|
||
|
case .files:
|
||
|
FilesPickerView()
|
||
|
|
||
|
case .location:
|
||
|
LocationPickerView()
|
||
|
|
||
|
case .contacts:
|
||
|
ContactsPickerView()
|
||
|
}
|
||
|
|
||
|
// Tab bar
|
||
|
AttachmentTabBar(selectedTab: $selectedTab)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
struct AttachmentTabBar: View {
|
||
|
@Binding var selectedTab: AttachmentTab
|
||
|
|
||
|
var body: some View {
|
||
|
VStack(spacing: 0) {
|
||
|
Rectangle()
|
||
|
.frame(maxWidth: .infinity)
|
||
|
.frame(height: 0.2)
|
||
|
.foregroundColor(.Material.Shape.separator)
|
||
|
HStack(spacing: 0) {
|
||
|
AttachmentTabBarButton(tab: .media, selected: $selectedTab)
|
||
|
AttachmentTabBarButton(tab: .files, selected: $selectedTab)
|
||
|
AttachmentTabBarButton(tab: .location, selected: $selectedTab)
|
||
|
AttachmentTabBarButton(tab: .contacts, selected: $selectedTab)
|
||
|
}
|
||
|
.background(Color.Material.Background.dark)
|
||
|
}
|
||
|
.frame(height: 50)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private struct AttachmentTabBarButton: View {
|
||
|
let tab: AttachmentTab
|
||
|
@Binding var selected: AttachmentTab
|
||
|
|
||
|
var body: some View {
|
||
|
ZStack {
|
||
|
VStack(spacing: 2) {
|
||
|
buttonImg
|
||
|
.foregroundColor(selected == tab ? .Material.Elements.active : .Material.Elements.inactive)
|
||
|
.font(.system(size: 24, weight: .light))
|
||
|
.symbolRenderingMode(.hierarchical)
|
||
|
Text(buttonTitle)
|
||
|
.font(.sub1)
|
||
|
.foregroundColor(selected == tab ? .Material.Text.main : .Material.Elements.inactive)
|
||
|
}
|
||
|
Rectangle()
|
||
|
.foregroundColor(.white.opacity(0.01))
|
||
|
.onTapGesture {
|
||
|
selected = tab
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var buttonImg: Image {
|
||
|
switch tab {
|
||
|
case .media:
|
||
|
return Image(systemName: "photo.on.rectangle.angled")
|
||
|
|
||
|
case .files:
|
||
|
return Image(systemName: "doc.on.doc")
|
||
|
|
||
|
case .location:
|
||
|
return Image(systemName: "location.circle")
|
||
|
|
||
|
case .contacts:
|
||
|
return Image(systemName: "person.crop.circle")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var buttonTitle: String {
|
||
|
switch tab {
|
||
|
case .media:
|
||
|
return L10n.Attachment.Tab.media
|
||
|
|
||
|
case .files:
|
||
|
return L10n.Attachment.Tab.files
|
||
|
|
||
|
case .location:
|
||
|
return L10n.Attachment.Tab.location
|
||
|
|
||
|
case .contacts:
|
||
|
return L10n.Attachment.Tab.contacts
|
||
|
}
|
||
|
}
|
||
|
}
|