Skip to content

Commit

Permalink
change the camera view to the new custom camera
Browse files Browse the repository at this point in the history
  • Loading branch information
suhailsaqan committed Oct 27, 2023
1 parent 7a6a6df commit 5510996
Show file tree
Hide file tree
Showing 3 changed files with 237 additions and 28 deletions.
11 changes: 3 additions & 8 deletions damus.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1120,6 +1120,7 @@
BA4AB0AD2A63B9270070A32A /* AddEmojiView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddEmojiView.swift; sourceTree = "<group>"; };
BA4AB0AF2A63B94D0070A32A /* EmojiListItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiListItemView.swift; sourceTree = "<group>"; };
BA693073295D649800ADDB87 /* UserSettingsStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSettingsStore.swift; sourceTree = "<group>"; };
BAA8C3262AEC570800696158 /* CameraView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CameraView.swift; sourceTree = "<group>"; };
BAB68BEC29543FA3007BA466 /* SelectWalletView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectWalletView.swift; sourceTree = "<group>"; };
D2277EE92A089BD5006C3807 /* Router.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Router.swift; sourceTree = "<group>"; };
D71DC1EB2A9129C3006E207C /* PostViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostViewTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2301,14 +2302,7 @@
BA3759952ABCCF360018D73B /* Camera */ = {
isa = PBXGroup;
children = (
BA3759962ABCCF360018D73B /* CameraPreview.swift */,
);
path = Camera;
sourceTree = "<group>";
};
BA3759952ABCCF360018D73B /* Camera */ = {
isa = PBXGroup;
children = (
BAA8C3262AEC570800696158 /* CameraView.swift */,
BA3759962ABCCF360018D73B /* CameraPreview.swift */,
);
path = Camera;
Expand Down Expand Up @@ -2767,6 +2761,7 @@
4C1D4FB12A7958E60024F453 /* VersionInfo.swift in Sources */,
D7FF94002AC7AC5300FD969D /* RelayURL.swift in Sources */,
4C64305C2A945AFF00B0C0E9 /* MusicController.swift in Sources */,
BAA8C3272AEC570800696158 /* CameraView.swift in Sources */,
5053ACA72A56DF3B00851AE3 /* DeveloperSettingsView.swift in Sources */,
F79C7FAD29D5E9620000F946 /* EditPictureControl.swift in Sources */,
4C9F18E229AA9B6C008C55EC /* CustomizeZapView.swift in Sources */,
Expand Down
212 changes: 212 additions & 0 deletions damus/Views/Camera/CameraView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
//
// CameraView.swift
// damus
//
// Created by Suhail Saqan on 8/5/23.
//

import SwiftUI
import Combine
import AVFoundation

struct CameraView: View {
let damus_state: DamusState
let action: (([MediaItem]) -> Void)

@Environment(\.presentationMode) var presentationMode

@StateObject var model: CameraModel

@State var currentZoomFactor: CGFloat = 1.0

public init(damus_state: DamusState, action: @escaping (([MediaItem]) -> Void)) {
self.damus_state = damus_state
self.action = action
_model = StateObject(wrappedValue: CameraModel())
}

var captureButton: some View {
Button {
if model.isRecording {
withAnimation {
model.stopRecording()
}
} else {
withAnimation {
model.capturePhoto()
}
}
UIImpactFeedbackGenerator(style: .medium).impactOccurred()
} label: {
ZStack {
Circle()
.fill( model.isRecording ? .red : DamusColors.black)
.frame(width: model.isRecording ? 85 : 65, height: model.isRecording ? 85 : 65, alignment: .center)

Circle()
.stroke( model.isRecording ? .red : DamusColors.white, lineWidth: 4)
.frame(width: model.isRecording ? 95 : 75, height: model.isRecording ? 95 : 75, alignment: .center)
}
.frame(alignment: .center)
}
.simultaneousGesture(
LongPressGesture(minimumDuration: 0.5).onEnded({ value in
if (!model.isCameraButtonDisabled) {
withAnimation {
model.startRecording()
model.captureMode = .video
}
}
})
)
.buttonStyle(.plain)
}

var capturedPhotoThumbnail: some View {
ZStack {
if model.thumbnail != nil {
Image(uiImage: model.thumbnail.thumbnailImage!)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 60, height: 60)
.clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous))
}
if model.isPhotoProcessing {
ProgressView()
.progressViewStyle(CircularProgressViewStyle(tint: DamusColors.white))
}
}
}

var closeButton: some View {
Button {
presentationMode.wrappedValue.dismiss()
model.stop()
} label: {
HStack {
Image(systemName: "xmark")
.font(.system(size: 24))
}
.frame(minWidth: 40, minHeight: 40)
}
.accentColor(DamusColors.white)
}

var flipCameraButton: some View {
Button(action: {
model.flipCamera()
}, label: {
HStack {
Image(systemName: "camera.rotate.fill")
.font(.system(size: 20))
}
.frame(minWidth: 40, minHeight: 40)
})
.accentColor(DamusColors.white)
}

var toggleFlashButton: some View {
Button(action: {
model.switchFlash()
}, label: {
HStack {
Image(systemName: model.isFlashOn ? "bolt.fill" : "bolt.slash.fill")
.font(.system(size: 20))
}
.frame(minWidth: 40, minHeight: 40)
})
.accentColor(model.isFlashOn ? .yellow : DamusColors.white)
}

var body: some View {
NavigationView {
GeometryReader { reader in
ZStack {
DamusColors.black.edgesIgnoringSafeArea(.all)

CameraPreview(session: model.session)
.padding(.bottom, 175)
.edgesIgnoringSafeArea(.all)
.gesture(
DragGesture().onChanged({ (val) in
if abs(val.translation.height) > abs(val.translation.width) {
let percentage: CGFloat = -(val.translation.height / reader.size.height)
let calc = currentZoomFactor + percentage
let zoomFactor: CGFloat = min(max(calc, 1), 5)

currentZoomFactor = zoomFactor
model.zoom(with: zoomFactor)
}
})
)
.onAppear {
model.configure()
}
.alert(isPresented: $model.showAlertError, content: {
Alert(title: Text(model.alertError.title), message: Text(model.alertError.message), dismissButton: .default(Text(model.alertError.primaryButtonTitle), action: {
model.alertError.primaryAction?()
}))
})
.overlay(
Group {
if model.willCapturePhoto {
Color.black
}
}
)

VStack {
if !model.isRecording {
HStack {
closeButton

Spacer()

HStack {
flipCameraButton
toggleFlashButton
}
}
.padding(.horizontal, 20)
}

Spacer()

HStack(alignment: .center) {
if !model.mediaItems.isEmpty {
NavigationLink(destination: Text(model.mediaItems.map { $0.url.absoluteString }.joined(separator: ", "))) {
capturedPhotoThumbnail
}
.frame(width: 100, alignment: .leading)
}

Spacer()

captureButton

Spacer()

if !model.mediaItems.isEmpty {
Button(action: {
action(model.mediaItems)
presentationMode.wrappedValue.dismiss()
model.stop()
}) {
Text("Upload")
.frame(width: 100, height: 40, alignment: .center)
.foregroundColor(DamusColors.white)
.overlay {
RoundedRectangle(cornerRadius: 24)
.stroke(DamusColors.white, lineWidth: 2)
}
}
}
}
.frame(height: 100)
.padding([.horizontal, .vertical], 20)
}
}
}
}
}
}
42 changes: 22 additions & 20 deletions damus/Views/PostView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ struct PostView: View {
@State var newCursorIndex: Int?
@State var textHeight: CGFloat? = nil

@State var mediaToUpload: MediaUpload? = nil
@State var mediaToUpload: [MediaUpload] = []

@StateObject var image_upload: ImageUploadModel = ImageUploadModel()
@StateObject var tagModel: TagModel = TagModel()
Expand Down Expand Up @@ -343,6 +343,15 @@ struct PostView: View {
pks.append(pk)
}
}

func addToMediaToUpload(mediaItem: MediaItem) {
switch mediaItem.type {
case .image:
mediaToUpload.append(.image(mediaItem.url))
case .video:
mediaToUpload.append(.video(mediaItem.url))
}
}

var body: some View {
GeometryReader { (deviceSize: GeometryProxy) in
Expand Down Expand Up @@ -384,36 +393,29 @@ struct PostView: View {
}
.sheet(isPresented: $attach_media) {
ImagePicker(uploader: damus_state.settings.default_media_uploader, sourceType: .photoLibrary, pubkey: damus_state.pubkey, image_upload_confirm: $image_upload_confirm) { img in
self.mediaToUpload = .image(img)
self.mediaToUpload.append(.image(img))
} onVideoPicked: { url in
self.mediaToUpload = .video(url)
self.mediaToUpload.append(.video(url))
}
.alert(NSLocalizedString("Are you sure you want to upload this media?", comment: "Alert message asking if the user wants to upload media."), isPresented: $image_upload_confirm) {
Button(NSLocalizedString("Upload", comment: "Button to proceed with uploading."), role: .none) {
if let mediaToUpload {
self.handle_upload(media: mediaToUpload)
if !mediaToUpload.isEmpty {
self.handle_upload(media: mediaToUpload[0])
self.attach_media = false
}
}
Button(NSLocalizedString("Cancel", comment: "Button to cancel the upload."), role: .cancel) {}
}
}
.sheet(isPresented: $attach_camera) {

ImagePicker(uploader: damus_state.settings.default_media_uploader, sourceType: .camera, pubkey: damus_state.pubkey, image_upload_confirm: $image_upload_confirm) { img in
self.mediaToUpload = .image(img)
} onVideoPicked: { url in
self.mediaToUpload = .video(url)
}
.alert(NSLocalizedString("Are you sure you want to upload this media?", comment: "Alert message asking if the user wants to upload media."), isPresented: $image_upload_confirm) {
Button(NSLocalizedString("Upload", comment: "Button to proceed with uploading."), role: .none) {
if let mediaToUpload {
self.handle_upload(media: mediaToUpload)
self.attach_camera = false
}
.fullScreenCover(isPresented: $attach_camera) {
CameraView(damus_state: damus_state, action: { items in
for item in items {
addToMediaToUpload(mediaItem: item)
}
Button(NSLocalizedString("Cancel", comment: "Button to cancel the upload."), role: .cancel) {}
}
for media in mediaToUpload {
self.handle_upload(media: media)
}
})
}
.onAppear() {
let loaded_draft = load_draft()
Expand Down

0 comments on commit 5510996

Please sign in to comment.