Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions apple/InlineIOS/Features/Compose/AttachmentOptionsSheet.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import SwiftUI

enum AttachmentOption {
case library
case camera
case file
}

struct AttachmentOptionsSheet: View {
let onSelect: (AttachmentOption) -> Void

var body: some View {
VStack(alignment: .leading, spacing: 12) {
Text("Attach")
.font(.headline)
.foregroundStyle(.secondary)
.padding(.bottom, 4)

optionButton(title: "Library", icon: "photo.on.rectangle.angled", option: .library)
optionButton(title: "Camera", icon: "camera", option: .camera)
optionButton(title: "File", icon: "folder", option: .file)
}
.padding(16)
.presentationDragIndicator(.visible)
.background(Color(UIColor.systemBackground))
}

private func optionButton(title: String, icon: String, option: AttachmentOption) -> some View {
Button {
onSelect(option)
} label: {
HStack(spacing: 12) {
Image(systemName: icon)
.font(.system(size: 16, weight: .semibold))
.frame(width: 24)
Text(title)
.font(.system(size: 17, weight: .medium))
Spacer()
}
.padding(.horizontal, 12)
.padding(.vertical, 12)
.background(Color(UIColor.secondarySystemBackground))
.clipShape(RoundedRectangle(cornerRadius: 12, style: .continuous))
}
.buttonStyle(.plain)
}
}
35 changes: 1 addition & 34 deletions apple/InlineIOS/Features/Compose/ComposeView+UIViews.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,40 +90,7 @@ extension ComposeView {
button.configuration = config
button.layer.cornerRadius = 20
button.clipsToBounds = true

let libraryAction = UIAction(
title: "Photos",
image: UIImage(systemName: "photo.on.rectangle.angled"),
handler: { [weak self] _ in
self?.presentPicker()
}
)

let videoAction = UIAction(
title: "Video",
image: UIImage(systemName: "video"),
handler: { [weak self] _ in
self?.presentVideoPicker()
}
)

let cameraAction = UIAction(
title: "Camera",
image: UIImage(systemName: "camera"),
handler: { [weak self] _ in
self?.presentCamera()
}
)

let fileAction = UIAction(
title: "File",
image: UIImage(systemName: "folder"),
handler: { [weak self] _ in
self?.presentFileManager()
}
)
button.menu = UIMenu(children: [libraryAction, videoAction, cameraAction, fileAction])
button.showsMenuAsPrimaryAction = true
button.addTarget(self, action: #selector(attachmentButtonTapped), for: .touchUpInside)

return button
}
Expand Down
9 changes: 6 additions & 3 deletions apple/InlineIOS/Features/Compose/ComposeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,13 @@ class ComposeView: UIView, NSTextLayoutManagerDelegate {

var isButtonVisible = false
var selectedImage: UIImage?
var pendingVideoURLs: [URL] = []
var pendingMixedMediaItems: [MixedMediaPreviewItem] = []
var showingPhotoPreview: Bool = false
var imageCaption: String = ""

enum MediaPickerMode {
case photos
case videos
case library
}

var attachmentItems: [String: FileMediaItem] = [:]
Expand Down Expand Up @@ -79,9 +80,11 @@ class ComposeView: UIView, NSTextLayoutManagerDelegate {

let previewViewModel = SwiftUIPhotoPreviewViewModel()
let multiPhotoPreviewViewModel = SwiftUIPhotoPreviewViewModel()
let videoPreviewViewModel = VideoPreviewViewModel()
let mixedMediaPreviewViewModel = MixedMediaPreviewViewModel()
let draftSaveInterval: TimeInterval = 2.0 // Save every 2 seconds
var isPickerPresented = false
var activePickerMode: MediaPickerMode = .photos
var activePickerMode: MediaPickerMode = .library

// MARK: - UI Components

Expand Down
8 changes: 8 additions & 0 deletions apple/InlineIOS/Features/Compose/DocumentPicker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ extension ComposeView: UIDocumentPickerDelegate {

func addFile(_ url: URL) {
if isVideoFile(url) {
guard url.startAccessingSecurityScopedResource() else {
Log.shared.error("Failed to access security-scoped resource for video: \(url)")
return
}
defer {
url.stopAccessingSecurityScopedResource()
}

addVideo(url)
return
}
Expand Down
Loading
Loading