Skip to content

Commit a0af916

Browse files
committed
camera
1 parent 5029170 commit a0af916

10 files changed

+1444
-23
lines changed

damus.xcodeproj/project.pbxproj

+51-3
Original file line numberDiff line numberDiff line change
@@ -377,9 +377,17 @@
377377
9609F058296E220800069BF3 /* BannerImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9609F057296E220800069BF3 /* BannerImageView.swift */; };
378378
9C83F89329A937B900136C08 /* TextViewWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C83F89229A937B900136C08 /* TextViewWrapper.swift */; };
379379
9CA876E229A00CEA0003B9A3 /* AttachMediaUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CA876E129A00CE90003B9A3 /* AttachMediaUtility.swift */; };
380+
BA27222E2A806E39004CDF52 /* VideoCaptureProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA27222D2A806E39004CDF52 /* VideoCaptureProcessor.swift */; };
381+
BA3BF2892A7F156B00600232 /* PhotoCaptureProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA3BF2842A7F156900600232 /* PhotoCaptureProcessor.swift */; };
382+
BA3BF28A2A7F156B00600232 /* ImageResizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA3BF2852A7F156900600232 /* ImageResizer.swift */; };
383+
BA3BF28B2A7F156B00600232 /* CameraService+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA3BF2862A7F156A00600232 /* CameraService+Extensions.swift */; };
384+
BA3BF28C2A7F156B00600232 /* CameraService.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA3BF2872A7F156A00600232 /* CameraService.swift */; };
385+
BA3BF28F2A7F1B2D00600232 /* CameraModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA3BF28E2A7F1B2D00600232 /* CameraModel.swift */; };
380386
BA4AB0AE2A63B9270070A32A /* AddEmojiView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA4AB0AD2A63B9270070A32A /* AddEmojiView.swift */; };
381387
BA4AB0B02A63B94D0070A32A /* EmojiListItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA4AB0AF2A63B94D0070A32A /* EmojiListItemView.swift */; };
382388
BA693074295D649800ADDB87 /* UserSettingsStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA693073295D649800ADDB87 /* UserSettingsStore.swift */; };
389+
BA8A4F0F2A2D95F70045C48C /* CameraView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA8A4F0E2A2D95F70045C48C /* CameraView.swift */; };
390+
BA8A4F132A2D96AD0045C48C /* CameraPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA8A4F122A2D96AD0045C48C /* CameraPreview.swift */; };
383391
BAB68BED29543FA3007BA466 /* SelectWalletView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAB68BEC29543FA3007BA466 /* SelectWalletView.swift */; };
384392
D2277EEA2A089BD5006C3807 /* Router.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2277EE92A089BD5006C3807 /* Router.swift */; };
385393
D78525252A7B2EA4002FA637 /* NoteContentViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D78525242A7B2EA4002FA637 /* NoteContentViewTests.swift */; };
@@ -928,9 +936,17 @@
928936
9609F057296E220800069BF3 /* BannerImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BannerImageView.swift; sourceTree = "<group>"; };
929937
9C83F89229A937B900136C08 /* TextViewWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextViewWrapper.swift; sourceTree = "<group>"; };
930938
9CA876E129A00CE90003B9A3 /* AttachMediaUtility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachMediaUtility.swift; sourceTree = "<group>"; };
939+
BA27222D2A806E39004CDF52 /* VideoCaptureProcessor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VideoCaptureProcessor.swift; sourceTree = "<group>"; };
940+
BA3BF2842A7F156900600232 /* PhotoCaptureProcessor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotoCaptureProcessor.swift; sourceTree = "<group>"; };
941+
BA3BF2852A7F156900600232 /* ImageResizer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageResizer.swift; sourceTree = "<group>"; };
942+
BA3BF2862A7F156A00600232 /* CameraService+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CameraService+Extensions.swift"; sourceTree = "<group>"; };
943+
BA3BF2872A7F156A00600232 /* CameraService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CameraService.swift; sourceTree = "<group>"; };
944+
BA3BF28E2A7F1B2D00600232 /* CameraModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraModel.swift; sourceTree = "<group>"; };
931945
BA4AB0AD2A63B9270070A32A /* AddEmojiView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddEmojiView.swift; sourceTree = "<group>"; };
932946
BA4AB0AF2A63B94D0070A32A /* EmojiListItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiListItemView.swift; sourceTree = "<group>"; };
933947
BA693073295D649800ADDB87 /* UserSettingsStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSettingsStore.swift; sourceTree = "<group>"; };
948+
BA8A4F0E2A2D95F70045C48C /* CameraView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraView.swift; sourceTree = "<group>"; };
949+
BA8A4F122A2D96AD0045C48C /* CameraPreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraPreview.swift; sourceTree = "<group>"; };
934950
BAB68BEC29543FA3007BA466 /* SelectWalletView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectWalletView.swift; sourceTree = "<group>"; };
935951
D2277EE92A089BD5006C3807 /* Router.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Router.swift; sourceTree = "<group>"; };
936952
D78525242A7B2EA4002FA637 /* NoteContentViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteContentViewTests.swift; sourceTree = "<group>"; };
@@ -1071,6 +1087,7 @@
10711087
4C0A3F8D280F63FF000448DE /* Models */ = {
10721088
isa = PBXGroup;
10731089
children = (
1090+
BA3BF2832A7F151300600232 /* Camera */,
10741091
4C190F1E2A535FC200027FD5 /* Zaps */,
10751092
4C54AA0829A55416003E4487 /* Notifications */,
10761093
3AA247FC297E3CFF0090C62D /* RepostsModel.swift */,
@@ -1236,6 +1253,7 @@
12361253
children = (
12371254
F71694E82A66221E001F4053 /* Onboarding */,
12381255
4C190F232A547D1700027FD5 /* NostrScript */,
1256+
BA8A4F0D2A2D95880045C48C /* Camera */,
12391257
4C7D09692A0AEA0400943473 /* CodeScanner */,
12401258
4C7D095A2A098C5C00943473 /* Wallet */,
12411259
4C8D1A6D29F31E4100ACDF75 /* Buttons */,
@@ -1860,6 +1878,28 @@
18601878
path = Extensions;
18611879
sourceTree = "<group>";
18621880
};
1881+
BA3BF2832A7F151300600232 /* Camera */ = {
1882+
isa = PBXGroup;
1883+
children = (
1884+
BA27222D2A806E39004CDF52 /* VideoCaptureProcessor.swift */,
1885+
BA3BF2872A7F156A00600232 /* CameraService.swift */,
1886+
BA3BF2862A7F156A00600232 /* CameraService+Extensions.swift */,
1887+
BA3BF2852A7F156900600232 /* ImageResizer.swift */,
1888+
BA3BF2842A7F156900600232 /* PhotoCaptureProcessor.swift */,
1889+
BA3BF28E2A7F1B2D00600232 /* CameraModel.swift */,
1890+
);
1891+
path = Camera;
1892+
sourceTree = "<group>";
1893+
};
1894+
BA8A4F0D2A2D95880045C48C /* Camera */ = {
1895+
isa = PBXGroup;
1896+
children = (
1897+
BA8A4F0E2A2D95F70045C48C /* CameraView.swift */,
1898+
BA8A4F122A2D96AD0045C48C /* CameraPreview.swift */,
1899+
);
1900+
path = Camera;
1901+
sourceTree = "<group>";
1902+
};
18631903
F71694E82A66221E001F4053 /* Onboarding */ = {
18641904
isa = PBXGroup;
18651905
children = (
@@ -2110,6 +2150,7 @@
21102150
4C190F252A547D2000027FD5 /* LoadScript.swift in Sources */,
21112151
4C59B98C2A76C2550032FFEB /* ProfileUpdatedNotify.swift in Sources */,
21122152
4C363A8C28236B92006E126D /* PubkeyView.swift in Sources */,
2153+
BA3BF28A2A7F156B00600232 /* ImageResizer.swift in Sources */,
21132154
4CDA128A29E9D10C0006FA5A /* SignalView.swift in Sources */,
21142155
4C12535C2A76CA540004F4B8 /* LoginNotify.swift in Sources */,
21152156
4C5C7E68284ED36500A22DF5 /* SearchHomeModel.swift in Sources */,
@@ -2184,6 +2225,7 @@
21842225
4CA2EFA0280E37AC0044ACD8 /* TimelineView.swift in Sources */,
21852226
4C30AC7629A5770900E2BD5A /* NotificationItemView.swift in Sources */,
21862227
4C86F7C42A76C44C00EC0817 /* ZappingNotify.swift in Sources */,
2228+
BA27222E2A806E39004CDF52 /* VideoCaptureProcessor.swift in Sources */,
21872229
4C363A8428233689006E126D /* Parser.swift in Sources */,
21882230
3AAA95CA298DF87B00F3D526 /* TranslationService.swift in Sources */,
21892231
4CE4F9E328528C5200C00DD9 /* AddRelayView.swift in Sources */,
@@ -2276,13 +2318,15 @@
22762318
4C4E137D2A76D63600BDD832 /* UnmuteThreadNotify.swift in Sources */,
22772319
4CE4F0F829DB7399005914DB /* ThiccDivider.swift in Sources */,
22782320
4CE0E2B629A3ED5500DB4CA2 /* InnerTimelineView.swift in Sources */,
2321+
BA3BF28C2A7F156B00600232 /* CameraService.swift in Sources */,
22792322
4C363A8828236948006E126D /* BlocksView.swift in Sources */,
22802323
4C06670628FCB08600038D2A /* ImageCarousel.swift in Sources */,
22812324
3A23838E2A297DD200E5AA2E /* ZapButtonModel.swift in Sources */,
22822325
F71694F82A6983AF001F4053 /* GrayGradient.swift in Sources */,
22832326
4C1D4FB12A7958E60024F453 /* VersionInfo.swift in Sources */,
22842327
5053ACA72A56DF3B00851AE3 /* DeveloperSettingsView.swift in Sources */,
22852328
F79C7FAD29D5E9620000F946 /* EditPictureControl.swift in Sources */,
2329+
BA3BF2892A7F156B00600232 /* PhotoCaptureProcessor.swift in Sources */,
22862330
4C9F18E229AA9B6C008C55EC /* CustomizeZapView.swift in Sources */,
22872331
4C2859602A12A2BE004746F7 /* SupporterBadge.swift in Sources */,
22882332
4C1A9A2A29DDF54400516EAC /* DamusVideoPlayer.swift in Sources */,
@@ -2355,6 +2399,7 @@
23552399
4C3EA66028FF5E7700C48A62 /* node_id.c in Sources */,
23562400
4C687C212A5F7ED00092C550 /* DamusBackground.swift in Sources */,
23572401
4CA352A02A76AE80003BB08B /* Notify.swift in Sources */,
2402+
BA3BF28B2A7F156B00600232 /* CameraService+Extensions.swift in Sources */,
23582403
4CE6DEE727F7A08100C66700 /* damusApp.swift in Sources */,
23592404
4C1253582A76C9060004F4B8 /* PresentSheetNotify.swift in Sources */,
23602405
4C363A962827096D006E126D /* PostBlock.swift in Sources */,
@@ -2399,6 +2444,7 @@
23992444
5C513FBA297F72980072348F /* CustomPicker.swift in Sources */,
24002445
4C1253622A76D00B0004F4B8 /* PostNotify.swift in Sources */,
24012446
4CACA9D5280C31E100D9BBE8 /* ReplyView.swift in Sources */,
2447+
BA3BF28F2A7F1B2D00600232 /* CameraModel.swift in Sources */,
24022448
F7908E92298B0F0700AB113A /* RelayDetailView.swift in Sources */,
24032449
4C9147002A2A891E00DDEA40 /* error.c in Sources */,
24042450
4CE879552996BAB900F758CC /* RelayPaidDetail.swift in Sources */,
@@ -2408,6 +2454,7 @@
24082454
4CF0ABD42980996B00D66079 /* Report.swift in Sources */,
24092455
4C06670B28FDE64700038D2A /* damus.c in Sources */,
24102456
4C1253642A76D08F0004F4B8 /* ReportNotify.swift in Sources */,
2457+
BA8A4F0F2A2D95F70045C48C /* CameraView.swift in Sources */,
24112458
4C1A9A2529DDDF2600516EAC /* ZapSettingsView.swift in Sources */,
24122459
4C2CDDF7299D4A5E00879FD5 /* Debouncer.swift in Sources */,
24132460
3AAA95CC298E07E900F3D526 /* DeepLPlan.swift in Sources */,
@@ -2433,6 +2480,7 @@
24332480
3AA59D1D2999B0400061C48E /* DraftsModel.swift in Sources */,
24342481
3169CAED294FCCFC00EE4006 /* Constants.swift in Sources */,
24352482
4C9AA14A2A4587A6003F49FD /* NotificationStatusModel.swift in Sources */,
2483+
BA8A4F132A2D96AD0045C48C /* CameraPreview.swift in Sources */,
24362484
4CB9D4A72992D02B00A9A7E4 /* ProfileNameView.swift in Sources */,
24372485
4CE4F0F429D779B5005914DB /* PostBox.swift in Sources */,
24382486
4C9B0DF32A65C46800CBDA21 /* ProfileEditButton.swift in Sources */,
@@ -2744,7 +2792,7 @@
27442792
CODE_SIGN_STYLE = Automatic;
27452793
CURRENT_PROJECT_VERSION = 11;
27462794
DEVELOPMENT_ASSET_PATHS = "\"damus/Preview Content\"";
2747-
DEVELOPMENT_TEAM = XK7H4JAB3D;
2795+
DEVELOPMENT_TEAM = XL4476DR2X;
27482796
ENABLE_PREVIEWS = YES;
27492797
GENERATE_INFOPLIST_FILE = YES;
27502798
INFOPLIST_FILE = damus/Info.plist;
@@ -2770,7 +2818,7 @@
27702818
"$(PROJECT_DIR)",
27712819
);
27722820
MARKETING_VERSION = 1.6;
2773-
PRODUCT_BUNDLE_IDENTIFIER = com.jb55.damus2;
2821+
PRODUCT_BUNDLE_IDENTIFIER = com.suhail.damus2;
27742822
PRODUCT_NAME = "$(TARGET_NAME)";
27752823
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
27762824
SUPPORTS_MACCATALYST = YES;
@@ -2793,7 +2841,7 @@
27932841
CODE_SIGN_STYLE = Automatic;
27942842
CURRENT_PROJECT_VERSION = 11;
27952843
DEVELOPMENT_ASSET_PATHS = "\"damus/Preview Content\"";
2796-
DEVELOPMENT_TEAM = XK7H4JAB3D;
2844+
DEVELOPMENT_TEAM = XL4476DR2X;
27972845
ENABLE_PREVIEWS = YES;
27982846
GENERATE_INFOPLIST_FILE = YES;
27992847
INFOPLIST_FILE = damus/Info.plist;

damus/Models/Camera/CameraModel.swift

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
//
2+
// CameraModel.swift
3+
// damus
4+
//
5+
// Created by Suhail Saqan on 8/5/23.
6+
//
7+
8+
import Foundation
9+
import AVFoundation
10+
import Combine
11+
12+
final class CameraModel: ObservableObject {
13+
private let service = CameraService()
14+
15+
@Published var showAlertError = false
16+
17+
@Published var isFlashOn = false
18+
19+
@Published var willCapturePhoto = false
20+
21+
@Published var isCameraButtonDisabled = false
22+
23+
@Published var isPhotoProcessing = false
24+
25+
@Published var isRecording = false
26+
27+
@Published var captureMode: CameraMediaType = .image
28+
29+
@Published public var mediaItems: [MediaItem] = []
30+
31+
@Published var thumbnail: Thumbnail!
32+
33+
var alertError: AlertError!
34+
35+
var session: AVCaptureSession
36+
37+
private var subscriptions = Set<AnyCancellable>()
38+
39+
init() {
40+
self.session = service.session
41+
42+
service.$shouldShowAlertView.sink { [weak self] (val) in
43+
self?.alertError = self?.service.alertError
44+
self?.showAlertError = val
45+
}
46+
.store(in: &self.subscriptions)
47+
48+
service.$flashMode.sink { [weak self] (mode) in
49+
self?.isFlashOn = mode == .on
50+
}
51+
.store(in: &self.subscriptions)
52+
53+
service.$willCapturePhoto.sink { [weak self] (val) in
54+
self?.willCapturePhoto = val
55+
}
56+
.store(in: &self.subscriptions)
57+
58+
service.$isCameraButtonDisabled.sink { [weak self] (val) in
59+
self?.isCameraButtonDisabled = val
60+
}
61+
.store(in: &self.subscriptions)
62+
63+
service.$isPhotoProcessing.sink { [weak self] (val) in
64+
self?.isPhotoProcessing = val
65+
}
66+
.store(in: &self.subscriptions)
67+
68+
service.$isRecording.sink { [weak self] (val) in
69+
self?.isRecording = val
70+
}
71+
.store(in: &self.subscriptions)
72+
73+
service.$captureMode.sink { [weak self] (mode) in
74+
self?.captureMode = mode
75+
}
76+
.store(in: &self.subscriptions)
77+
78+
service.$mediaItems.sink { [weak self] (mode) in
79+
self?.mediaItems = mode
80+
}
81+
.store(in: &self.subscriptions)
82+
83+
service.$thumbnail.sink { [weak self] (thumbnail) in
84+
guard let pic = thumbnail else { return }
85+
self?.thumbnail = pic
86+
}
87+
.store(in: &self.subscriptions)
88+
}
89+
90+
func configure() {
91+
service.checkForPermissions()
92+
service.configure()
93+
}
94+
95+
func stop() {
96+
service.stop()
97+
}
98+
99+
func capturePhoto() {
100+
service.capturePhoto()
101+
}
102+
103+
func startRecording() {
104+
service.startRecording()
105+
}
106+
107+
func stopRecording() {
108+
service.stopRecording()
109+
}
110+
111+
func flipCamera() {
112+
service.changeCamera()
113+
}
114+
115+
func zoom(with factor: CGFloat) {
116+
service.set(zoom: factor)
117+
}
118+
119+
func switchFlash() {
120+
service.flashMode = service.flashMode == .on ? .off : .on
121+
}
122+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//
2+
// CameraService+Extensions.swift
3+
// damus
4+
//
5+
// Created by Suhail Saqan on 8/5/23.
6+
//
7+
8+
import Foundation
9+
import UIKit
10+
import AVFoundation
11+
12+
extension AVCaptureVideoOrientation {
13+
init?(deviceOrientation: UIDeviceOrientation) {
14+
switch deviceOrientation {
15+
case .portrait: self = .portrait
16+
case .portraitUpsideDown: self = .portraitUpsideDown
17+
case .landscapeLeft: self = .landscapeRight
18+
case .landscapeRight: self = .landscapeLeft
19+
default: return nil
20+
}
21+
}
22+
23+
init?(interfaceOrientation: UIInterfaceOrientation) {
24+
switch interfaceOrientation {
25+
case .portrait: self = .portrait
26+
case .portraitUpsideDown: self = .portraitUpsideDown
27+
case .landscapeLeft: self = .landscapeLeft
28+
case .landscapeRight: self = .landscapeRight
29+
default: return nil
30+
}
31+
}
32+
}

0 commit comments

Comments
 (0)