Skip to content

Commit 2ee2693

Browse files
committed
change the camera view to the new custom camera
1 parent 6fc6033 commit 2ee2693

File tree

3 files changed

+250
-23
lines changed

3 files changed

+250
-23
lines changed

damus.xcodeproj/project.pbxproj

+16-3
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,8 @@
387387
BA4AB0AE2A63B9270070A32A /* AddEmojiView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA4AB0AD2A63B9270070A32A /* AddEmojiView.swift */; };
388388
BA4AB0B02A63B94D0070A32A /* EmojiListItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA4AB0AF2A63B94D0070A32A /* EmojiListItemView.swift */; };
389389
BA693074295D649800ADDB87 /* UserSettingsStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA693073295D649800ADDB87 /* UserSettingsStore.swift */; };
390+
BA8A4F0F2A2D95F70045C48C /* CameraView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA8A4F0E2A2D95F70045C48C /* CameraView.swift */; };
391+
BA8A4F132A2D96AD0045C48C /* CameraPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA8A4F122A2D96AD0045C48C /* CameraPreview.swift */; };
390392
BAB68BED29543FA3007BA466 /* SelectWalletView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAB68BEC29543FA3007BA466 /* SelectWalletView.swift */; };
391393
D2277EEA2A089BD5006C3807 /* Router.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2277EE92A089BD5006C3807 /* Router.swift */; };
392394
D78525252A7B2EA4002FA637 /* NoteContentViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D78525242A7B2EA4002FA637 /* NoteContentViewTests.swift */; };
@@ -945,6 +947,8 @@
945947
BA4AB0AD2A63B9270070A32A /* AddEmojiView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddEmojiView.swift; sourceTree = "<group>"; };
946948
BA4AB0AF2A63B94D0070A32A /* EmojiListItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiListItemView.swift; sourceTree = "<group>"; };
947949
BA693073295D649800ADDB87 /* UserSettingsStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSettingsStore.swift; sourceTree = "<group>"; };
950+
BA8A4F0E2A2D95F70045C48C /* CameraView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraView.swift; sourceTree = "<group>"; };
951+
BA8A4F122A2D96AD0045C48C /* CameraPreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraPreview.swift; sourceTree = "<group>"; };
948952
BAB68BEC29543FA3007BA466 /* SelectWalletView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectWalletView.swift; sourceTree = "<group>"; };
949953
D2277EE92A089BD5006C3807 /* Router.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Router.swift; sourceTree = "<group>"; };
950954
D78525242A7B2EA4002FA637 /* NoteContentViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteContentViewTests.swift; sourceTree = "<group>"; };
@@ -1252,6 +1256,7 @@
12521256
BA3759952ABCCF360018D73B /* Camera */,
12531257
F71694E82A66221E001F4053 /* Onboarding */,
12541258
4C190F232A547D1700027FD5 /* NostrScript */,
1259+
BA8A4F0D2A2D95880045C48C /* Camera */,
12551260
4C7D09692A0AEA0400943473 /* CodeScanner */,
12561261
4C7D095A2A098C5C00943473 /* Wallet */,
12571262
4C8D1A6D29F31E4100ACDF75 /* Buttons */,
@@ -2147,6 +2152,7 @@
21472152
4C190F252A547D2000027FD5 /* LoadScript.swift in Sources */,
21482153
4C59B98C2A76C2550032FFEB /* ProfileUpdatedNotify.swift in Sources */,
21492154
4C363A8C28236B92006E126D /* PubkeyView.swift in Sources */,
2155+
BA3BF28A2A7F156B00600232 /* ImageResizer.swift in Sources */,
21502156
4CDA128A29E9D10C0006FA5A /* SignalView.swift in Sources */,
21512157
4C12535C2A76CA540004F4B8 /* LoginNotify.swift in Sources */,
21522158
4C5C7E68284ED36500A22DF5 /* SearchHomeModel.swift in Sources */,
@@ -2222,6 +2228,7 @@
22222228
4C30AC7629A5770900E2BD5A /* NotificationItemView.swift in Sources */,
22232229
BA3759972ABCCF360018D73B /* CameraPreview.swift in Sources */,
22242230
4C86F7C42A76C44C00EC0817 /* ZappingNotify.swift in Sources */,
2231+
BA27222E2A806E39004CDF52 /* VideoCaptureProcessor.swift in Sources */,
22252232
4C363A8428233689006E126D /* Parser.swift in Sources */,
22262233
3AAA95CA298DF87B00F3D526 /* TranslationService.swift in Sources */,
22272234
4CE4F9E328528C5200C00DD9 /* AddRelayView.swift in Sources */,
@@ -2316,13 +2323,15 @@
23162323
4C4E137D2A76D63600BDD832 /* UnmuteThreadNotify.swift in Sources */,
23172324
4CE4F0F829DB7399005914DB /* ThiccDivider.swift in Sources */,
23182325
4CE0E2B629A3ED5500DB4CA2 /* InnerTimelineView.swift in Sources */,
2326+
BA3BF28C2A7F156B00600232 /* CameraService.swift in Sources */,
23192327
4C363A8828236948006E126D /* BlocksView.swift in Sources */,
23202328
4C06670628FCB08600038D2A /* ImageCarousel.swift in Sources */,
23212329
3A23838E2A297DD200E5AA2E /* ZapButtonModel.swift in Sources */,
23222330
F71694F82A6983AF001F4053 /* GrayGradient.swift in Sources */,
23232331
4C1D4FB12A7958E60024F453 /* VersionInfo.swift in Sources */,
23242332
5053ACA72A56DF3B00851AE3 /* DeveloperSettingsView.swift in Sources */,
23252333
F79C7FAD29D5E9620000F946 /* EditPictureControl.swift in Sources */,
2334+
BA3BF2892A7F156B00600232 /* PhotoCaptureProcessor.swift in Sources */,
23262335
4C9F18E229AA9B6C008C55EC /* CustomizeZapView.swift in Sources */,
23272336
4C2859602A12A2BE004746F7 /* SupporterBadge.swift in Sources */,
23282337
4C1A9A2A29DDF54400516EAC /* DamusVideoPlayer.swift in Sources */,
@@ -2397,6 +2406,7 @@
23972406
4C3EA66028FF5E7700C48A62 /* node_id.c in Sources */,
23982407
4C687C212A5F7ED00092C550 /* DamusBackground.swift in Sources */,
23992408
4CA352A02A76AE80003BB08B /* Notify.swift in Sources */,
2409+
BA3BF28B2A7F156B00600232 /* CameraService+Extensions.swift in Sources */,
24002410
4CE6DEE727F7A08100C66700 /* damusApp.swift in Sources */,
24012411
4C1253582A76C9060004F4B8 /* PresentSheetNotify.swift in Sources */,
24022412
4C363A962827096D006E126D /* PostBlock.swift in Sources */,
@@ -2442,6 +2452,7 @@
24422452
5C513FBA297F72980072348F /* CustomPicker.swift in Sources */,
24432453
4C1253622A76D00B0004F4B8 /* PostNotify.swift in Sources */,
24442454
4CACA9D5280C31E100D9BBE8 /* ReplyView.swift in Sources */,
2455+
BA3BF28F2A7F1B2D00600232 /* CameraModel.swift in Sources */,
24452456
F7908E92298B0F0700AB113A /* RelayDetailView.swift in Sources */,
24462457
4C9147002A2A891E00DDEA40 /* error.c in Sources */,
24472458
4CE879552996BAB900F758CC /* RelayPaidDetail.swift in Sources */,
@@ -2451,6 +2462,7 @@
24512462
4CF0ABD42980996B00D66079 /* Report.swift in Sources */,
24522463
4C06670B28FDE64700038D2A /* damus.c in Sources */,
24532464
4C1253642A76D08F0004F4B8 /* ReportNotify.swift in Sources */,
2465+
BA8A4F0F2A2D95F70045C48C /* CameraView.swift in Sources */,
24542466
4C1A9A2529DDDF2600516EAC /* ZapSettingsView.swift in Sources */,
24552467
4C2CDDF7299D4A5E00879FD5 /* Debouncer.swift in Sources */,
24562468
3AAA95CC298E07E900F3D526 /* DeepLPlan.swift in Sources */,
@@ -2476,6 +2488,7 @@
24762488
3AA59D1D2999B0400061C48E /* DraftsModel.swift in Sources */,
24772489
3169CAED294FCCFC00EE4006 /* Constants.swift in Sources */,
24782490
4C9AA14A2A4587A6003F49FD /* NotificationStatusModel.swift in Sources */,
2491+
BA8A4F132A2D96AD0045C48C /* CameraPreview.swift in Sources */,
24792492
4CB9D4A72992D02B00A9A7E4 /* ProfileNameView.swift in Sources */,
24802493
4CE4F0F429D779B5005914DB /* PostBox.swift in Sources */,
24812494
BA37598E2ABCCE500018D73B /* VideoCaptureProcessor.swift in Sources */,
@@ -2788,7 +2801,7 @@
27882801
CODE_SIGN_STYLE = Automatic;
27892802
CURRENT_PROJECT_VERSION = 11;
27902803
DEVELOPMENT_ASSET_PATHS = "\"damus/Preview Content\"";
2791-
DEVELOPMENT_TEAM = XK7H4JAB3D;
2804+
DEVELOPMENT_TEAM = XL4476DR2X;
27922805
ENABLE_PREVIEWS = YES;
27932806
GENERATE_INFOPLIST_FILE = YES;
27942807
INFOPLIST_FILE = damus/Info.plist;
@@ -2814,7 +2827,7 @@
28142827
"$(PROJECT_DIR)",
28152828
);
28162829
MARKETING_VERSION = 1.6;
2817-
PRODUCT_BUNDLE_IDENTIFIER = com.jb55.damus2;
2830+
PRODUCT_BUNDLE_IDENTIFIER = com.suhail.damus2;
28182831
PRODUCT_NAME = "$(TARGET_NAME)";
28192832
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
28202833
SUPPORTS_MACCATALYST = YES;
@@ -2837,7 +2850,7 @@
28372850
CODE_SIGN_STYLE = Automatic;
28382851
CURRENT_PROJECT_VERSION = 11;
28392852
DEVELOPMENT_ASSET_PATHS = "\"damus/Preview Content\"";
2840-
DEVELOPMENT_TEAM = XK7H4JAB3D;
2853+
DEVELOPMENT_TEAM = XL4476DR2X;
28412854
ENABLE_PREVIEWS = YES;
28422855
GENERATE_INFOPLIST_FILE = YES;
28432856
INFOPLIST_FILE = damus/Info.plist;

damus/Views/Camera/CameraView.swift

+212
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
//
2+
// CameraView.swift
3+
// damus
4+
//
5+
// Created by Suhail Saqan on 8/5/23.
6+
//
7+
8+
import SwiftUI
9+
import Combine
10+
import AVFoundation
11+
12+
struct CameraView: View {
13+
let damus_state: DamusState
14+
let action: (([MediaItem]) -> Void)
15+
16+
@Environment(\.presentationMode) var presentationMode
17+
18+
@StateObject var model: CameraModel
19+
20+
@State var currentZoomFactor: CGFloat = 1.0
21+
22+
public init(damus_state: DamusState, action: @escaping (([MediaItem]) -> Void)) {
23+
self.damus_state = damus_state
24+
self.action = action
25+
_model = StateObject(wrappedValue: CameraModel())
26+
}
27+
28+
var captureButton: some View {
29+
Button {
30+
if model.isRecording {
31+
withAnimation {
32+
model.stopRecording()
33+
}
34+
} else {
35+
withAnimation {
36+
model.capturePhoto()
37+
}
38+
}
39+
UIImpactFeedbackGenerator(style: .medium).impactOccurred()
40+
} label: {
41+
ZStack {
42+
Circle()
43+
.fill( model.isRecording ? .red : DamusColors.black)
44+
.frame(width: model.isRecording ? 85 : 65, height: model.isRecording ? 85 : 65, alignment: .center)
45+
46+
Circle()
47+
.stroke( model.isRecording ? .red : DamusColors.white, lineWidth: 4)
48+
.frame(width: model.isRecording ? 95 : 75, height: model.isRecording ? 95 : 75, alignment: .center)
49+
}
50+
.frame(alignment: .center)
51+
}
52+
.simultaneousGesture(
53+
LongPressGesture(minimumDuration: 0.5).onEnded({ value in
54+
if (!model.isCameraButtonDisabled) {
55+
withAnimation {
56+
model.startRecording()
57+
model.captureMode = .video
58+
}
59+
}
60+
})
61+
)
62+
.buttonStyle(.plain)
63+
}
64+
65+
var capturedPhotoThumbnail: some View {
66+
ZStack {
67+
if model.thumbnail != nil {
68+
Image(uiImage: model.thumbnail.thumbnailImage!)
69+
.resizable()
70+
.aspectRatio(contentMode: .fill)
71+
.frame(width: 60, height: 60)
72+
.clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous))
73+
}
74+
if model.isPhotoProcessing {
75+
ProgressView()
76+
.progressViewStyle(CircularProgressViewStyle(tint: DamusColors.white))
77+
}
78+
}
79+
}
80+
81+
var closeButton: some View {
82+
Button {
83+
presentationMode.wrappedValue.dismiss()
84+
model.stop()
85+
} label: {
86+
HStack {
87+
Image(systemName: "xmark")
88+
.font(.system(size: 24))
89+
}
90+
.frame(minWidth: 40, minHeight: 40)
91+
}
92+
.accentColor(DamusColors.white)
93+
}
94+
95+
var flipCameraButton: some View {
96+
Button(action: {
97+
model.flipCamera()
98+
}, label: {
99+
HStack {
100+
Image(systemName: "camera.rotate.fill")
101+
.font(.system(size: 20))
102+
}
103+
.frame(minWidth: 40, minHeight: 40)
104+
})
105+
.accentColor(DamusColors.white)
106+
}
107+
108+
var toggleFlashButton: some View {
109+
Button(action: {
110+
model.switchFlash()
111+
}, label: {
112+
HStack {
113+
Image(systemName: model.isFlashOn ? "bolt.fill" : "bolt.slash.fill")
114+
.font(.system(size: 20))
115+
}
116+
.frame(minWidth: 40, minHeight: 40)
117+
})
118+
.accentColor(model.isFlashOn ? .yellow : DamusColors.white)
119+
}
120+
121+
var body: some View {
122+
NavigationView {
123+
GeometryReader { reader in
124+
ZStack {
125+
DamusColors.black.edgesIgnoringSafeArea(.all)
126+
127+
CameraPreview(session: model.session)
128+
.padding(.bottom, 175)
129+
.edgesIgnoringSafeArea(.all)
130+
.gesture(
131+
DragGesture().onChanged({ (val) in
132+
if abs(val.translation.height) > abs(val.translation.width) {
133+
let percentage: CGFloat = -(val.translation.height / reader.size.height)
134+
let calc = currentZoomFactor + percentage
135+
let zoomFactor: CGFloat = min(max(calc, 1), 5)
136+
137+
currentZoomFactor = zoomFactor
138+
model.zoom(with: zoomFactor)
139+
}
140+
})
141+
)
142+
.onAppear {
143+
model.configure()
144+
}
145+
.alert(isPresented: $model.showAlertError, content: {
146+
Alert(title: Text(model.alertError.title), message: Text(model.alertError.message), dismissButton: .default(Text(model.alertError.primaryButtonTitle), action: {
147+
model.alertError.primaryAction?()
148+
}))
149+
})
150+
.overlay(
151+
Group {
152+
if model.willCapturePhoto {
153+
Color.black
154+
}
155+
}
156+
)
157+
158+
VStack {
159+
if !model.isRecording {
160+
HStack {
161+
closeButton
162+
163+
Spacer()
164+
165+
HStack {
166+
flipCameraButton
167+
toggleFlashButton
168+
}
169+
}
170+
.padding(.horizontal, 20)
171+
}
172+
173+
Spacer()
174+
175+
HStack(alignment: .center) {
176+
if !model.mediaItems.isEmpty {
177+
NavigationLink(destination: Text(model.mediaItems.map { $0.url.absoluteString }.joined(separator: ", "))) {
178+
capturedPhotoThumbnail
179+
}
180+
.frame(width: 100, alignment: .leading)
181+
}
182+
183+
Spacer()
184+
185+
captureButton
186+
187+
Spacer()
188+
189+
if !model.mediaItems.isEmpty {
190+
Button(action: {
191+
action(model.mediaItems)
192+
presentationMode.wrappedValue.dismiss()
193+
model.stop()
194+
}) {
195+
Text("Upload")
196+
.frame(width: 100, height: 40, alignment: .center)
197+
.foregroundColor(DamusColors.white)
198+
.overlay {
199+
RoundedRectangle(cornerRadius: 24)
200+
.stroke(DamusColors.white, lineWidth: 2)
201+
}
202+
}
203+
}
204+
}
205+
.frame(height: 100)
206+
.padding([.horizontal, .vertical], 20)
207+
}
208+
}
209+
}
210+
}
211+
}
212+
}

0 commit comments

Comments
 (0)