├── BodyScan
├── BodyScan.entitlements
├── BodyScan.xcassets
│ ├── Contents.json
│ └── ToolbarIcon.imageset
│ │ ├── Contents.json
│ │ └── ToolbarIcon 2.pdf
├── ComposeSessionHandler.swift
├── ComposeSessionView.swift
├── Info.plist
├── MailExtension.swift
└── SessionStore.swift
├── Checkpoint.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
│ └── xcuserdata
│ │ └── linus.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
├── xcshareddata
│ └── xcschemes
│ │ ├── BodyScan.xcscheme
│ │ └── Checkpoint.xcscheme
└── xcuserdata
│ └── linus.xcuserdatad
│ ├── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ └── xcschememanagement.plist
├── Checkpoint
├── Assets.xcassets
│ ├── AccentColor.colorset
│ │ └── Contents.json
│ ├── AppIcon.appiconset
│ │ ├── Artwork-18 1.png
│ │ ├── Artwork-18.png
│ │ ├── Artwork-19.png
│ │ ├── Artwork-21.png
│ │ ├── Artwork-22 1.png
│ │ ├── Artwork-22.png
│ │ ├── Artwork-23.png
│ │ ├── Artwork-6.png
│ │ ├── Artwork-7 1.png
│ │ ├── Artwork-7.png
│ │ └── Contents.json
│ └── Contents.json
├── Checkpoint.entitlements
├── CheckpointApp.swift
├── ContentView.swift
├── Info.plist
└── Preview Content
│ └── Preview Assets.xcassets
│ └── Contents.json
├── LICENSE
└── README.md
/BodyScan/BodyScan.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.application-groups
8 |
9 | $(TeamIdentifierPrefix)sh.linus.Checkpoint
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/BodyScan/BodyScan.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/BodyScan/BodyScan.xcassets/ToolbarIcon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "ToolbarIcon 2.pdf",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/BodyScan/BodyScan.xcassets/ToolbarIcon.imageset/ToolbarIcon 2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinusSkucas/Checkpoint/414ddf6726671c7354f00f511663e8f280e17c98/BodyScan/BodyScan.xcassets/ToolbarIcon.imageset/ToolbarIcon 2.pdf
--------------------------------------------------------------------------------
/BodyScan/ComposeSessionHandler.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ComposeSessionHandler.swift
3 | // BodyScan
4 | //
5 | // Created by Linus Skucas on 5/13/22.
6 | //
7 |
8 | import MailKit
9 | import SwiftUI
10 |
11 | class ComposeSessionHandler: NSObject, MEComposeSessionHandler {
12 |
13 | let sessionStore = SessionStore.shared
14 |
15 | func mailComposeSessionDidBegin(_ session: MEComposeSession) {
16 | // Perform any setup necessary for handling the compose session.
17 | sessionStore.newSession(session.sessionID)
18 | }
19 |
20 | func mailComposeSessionDidEnd(_ session: MEComposeSession) {
21 | // Perform any cleanup now that the compose session is over.
22 | sessionStore.removeSession(session.sessionID)
23 | }
24 |
25 | // MARK: - Displaying Custom Compose Options
26 |
27 | func viewController(for session: MEComposeSession) -> MEExtensionViewController {
28 | let viewController = MEExtensionViewController()
29 | let rootView = ComposeSessionView(sessionID: session.sessionID).environmentObject(sessionStore)
30 | viewController.view = NSHostingView(rootView: rootView)
31 | return viewController
32 | }
33 |
34 | func allowMessageSendForSession(_ session: MEComposeSession, completion: @escaping (Error?) -> Void) {
35 | if sessionStore.shouldPromptForSession(session.sessionID) {
36 | let checkpointError = MEComposeSessionError(MEComposeSessionError.Code.invalidBody, userInfo: [NSLocalizedDescriptionKey: "Checkpoint! Confirm that you want to send this."])
37 | completion(checkpointError)
38 | } else {
39 | return completion(nil)
40 | }
41 | }
42 | }
43 |
44 |
--------------------------------------------------------------------------------
/BodyScan/ComposeSessionView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ComposeSessionView.swift
3 | // BodyScan
4 | //
5 | // Created by Linus Skucas on 6/10/23.
6 | //
7 |
8 | import SwiftUI
9 |
10 | struct ComposeSessionView: View {
11 | @AppStorage(SessionStore.shouldDefaultToPromptingKey) var shouldDefaultToPrompting: Bool = false
12 | @EnvironmentObject var sessionStore: SessionStore
13 | @State var shouldWhitelistSession = true
14 | var sessionID: UUID
15 |
16 | var body: some View {
17 | VStack {
18 | Toggle(isOn: $shouldWhitelistSession) {
19 | ZStack {
20 | Text("\(shouldWhitelistSession ? "Enable" : "Disable") Checkpoint")
21 | Text("Disable Checkpoint") // Make the button big enough so it doesn't clip
22 | .hidden()
23 | }
24 | }
25 | .controlSize(.large)
26 | .toggleStyle(.button)
27 | .keyboardShortcut(.defaultAction)
28 | .padding(.bottom, 9)
29 |
30 | Spacer()
31 |
32 | Toggle(isOn: $shouldDefaultToPrompting) {
33 | Text("Enable by default")
34 | }
35 | .controlSize(.small)
36 | }
37 | .onAppear {
38 | if sessionStore.shouldPromptForSession(sessionID) {
39 | shouldWhitelistSession = false
40 | } else {
41 | shouldWhitelistSession = true
42 | }
43 | }
44 | .onChange(of: shouldWhitelistSession, perform: { newValue in
45 | if shouldWhitelistSession {
46 | sessionStore.addSession(sessionID)
47 | } else {
48 | sessionStore.removeSession(sessionID)
49 | }
50 | })
51 | .padding()
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/BodyScan/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSExtension
6 |
7 | NSExtensionAttributes
8 |
9 | MEComposeSession
10 |
11 | MEComposeIcon
12 | ToolbarIcon
13 | MEComposeIconToolTip
14 | Checkpoint Clearance
15 |
16 | MEExtensionCapabilities
17 |
18 | MEComposeSessionHandler
19 |
20 |
21 | NSExtensionPointIdentifier
22 | com.apple.email.extension
23 | NSExtensionPrincipalClass
24 | $(PRODUCT_MODULE_NAME).MailExtension
25 |
26 | NSHumanReadableDescription
27 | Enable Checkpoint in the toolbar when composing emails.
28 |
29 |
30 |
--------------------------------------------------------------------------------
/BodyScan/MailExtension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MailExtension.swift
3 | // BodyScan
4 | //
5 | // Created by Linus Skucas on 5/13/22.
6 | //
7 |
8 | import MailKit
9 |
10 | class MailExtension: NSObject, MEExtension {
11 |
12 |
13 | func handler(for session: MEComposeSession) -> MEComposeSessionHandler {
14 | // Create a unique instance, since each compose window is separate.
15 | return ComposeSessionHandler()
16 | }
17 |
18 |
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/BodyScan/SessionStore.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SessionStore.swift
3 | // BodyScan
4 | //
5 | // Created by Linus Skucas on 6/10/23.
6 | //
7 |
8 | import SwiftUI
9 |
10 | class SessionStore: ObservableObject {
11 | var whitelistedSessions = [UUID]()
12 |
13 | static var shared = SessionStore()
14 | static let shouldDefaultToPromptingKey = "shouldDefaultToPrompting"
15 |
16 | /// When a new session is started, determine what to do to it
17 | /// If Checkpoint is not autoenabled, the session will be added to the whitelist
18 | func newSession(_ sessionID: UUID) {
19 | guard !UserDefaults.standard.bool(forKey: Self.shouldDefaultToPromptingKey) else { return }
20 | addSession(sessionID)
21 | }
22 |
23 | func addSession(_ sessionID: UUID) {
24 | guard !whitelistedSessions.contains(sessionID) else { return }
25 | whitelistedSessions.append(sessionID)
26 | }
27 |
28 | func removeSession(_ sessionID: UUID) {
29 | whitelistedSessions.removeAll { $0 == sessionID }
30 | }
31 |
32 | /// Determine if Checkpoint should stop the message.
33 | /// Checks if the session exists in the whitelist. If it does not, Checkpoint should prompt.
34 | func shouldPromptForSession(_ sessionID: UUID) -> Bool {
35 | return !whitelistedSessions.contains(sessionID)
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Checkpoint.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 55;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 152423EA2A3590A900BFBD33 /* ComposeSessionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 152423E92A3590A900BFBD33 /* ComposeSessionView.swift */; };
11 | 152423ED2A35928A00BFBD33 /* SessionStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 152423EC2A35928A00BFBD33 /* SessionStore.swift */; };
12 | 155C6123282F6DF200E26A22 /* CheckpointApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 155C6122282F6DF200E26A22 /* CheckpointApp.swift */; };
13 | 155C6125282F6DF200E26A22 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 155C6124282F6DF200E26A22 /* ContentView.swift */; };
14 | 155C6127282F6DF600E26A22 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 155C6126282F6DF600E26A22 /* Assets.xcassets */; };
15 | 155C612A282F6DF600E26A22 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 155C6129282F6DF600E26A22 /* Preview Assets.xcassets */; };
16 | 1599F9882A3453A900645DBA /* BodyScan.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1599F9872A3453A900645DBA /* BodyScan.xcassets */; };
17 | 15E0F465282F6F6B0073F2E8 /* MailExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15E0F464282F6F6B0073F2E8 /* MailExtension.swift */; };
18 | 15E0F467282F6F6B0073F2E8 /* ComposeSessionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15E0F466282F6F6B0073F2E8 /* ComposeSessionHandler.swift */; };
19 | 15E0F470282F6F6B0073F2E8 /* BodyScan.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 15E0F462282F6F6B0073F2E8 /* BodyScan.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
20 | /* End PBXBuildFile section */
21 |
22 | /* Begin PBXContainerItemProxy section */
23 | 15E0F46E282F6F6B0073F2E8 /* PBXContainerItemProxy */ = {
24 | isa = PBXContainerItemProxy;
25 | containerPortal = 155C6117282F6DF200E26A22 /* Project object */;
26 | proxyType = 1;
27 | remoteGlobalIDString = 15E0F461282F6F6B0073F2E8;
28 | remoteInfo = BodyScan;
29 | };
30 | /* End PBXContainerItemProxy section */
31 |
32 | /* Begin PBXCopyFilesBuildPhase section */
33 | 15E0F471282F6F6B0073F2E8 /* Embed Foundation Extensions */ = {
34 | isa = PBXCopyFilesBuildPhase;
35 | buildActionMask = 2147483647;
36 | dstPath = "";
37 | dstSubfolderSpec = 13;
38 | files = (
39 | 15E0F470282F6F6B0073F2E8 /* BodyScan.appex in Embed Foundation Extensions */,
40 | );
41 | name = "Embed Foundation Extensions";
42 | runOnlyForDeploymentPostprocessing = 0;
43 | };
44 | /* End PBXCopyFilesBuildPhase section */
45 |
46 | /* Begin PBXFileReference section */
47 | 151DB2E42A36CE5D00B836ED /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; };
48 | 152423E92A3590A900BFBD33 /* ComposeSessionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeSessionView.swift; sourceTree = ""; };
49 | 152423EC2A35928A00BFBD33 /* SessionStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionStore.swift; sourceTree = ""; };
50 | 155C611F282F6DF200E26A22 /* Checkpoint.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Checkpoint.app; sourceTree = BUILT_PRODUCTS_DIR; };
51 | 155C6122282F6DF200E26A22 /* CheckpointApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckpointApp.swift; sourceTree = ""; };
52 | 155C6124282F6DF200E26A22 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
53 | 155C6126282F6DF600E26A22 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
54 | 155C6129282F6DF600E26A22 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
55 | 155C612B282F6DF600E26A22 /* Checkpoint.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Checkpoint.entitlements; sourceTree = ""; };
56 | 1599F9872A3453A900645DBA /* BodyScan.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = BodyScan.xcassets; sourceTree = ""; };
57 | 15E0F462282F6F6B0073F2E8 /* BodyScan.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = BodyScan.appex; sourceTree = BUILT_PRODUCTS_DIR; };
58 | 15E0F464282F6F6B0073F2E8 /* MailExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MailExtension.swift; sourceTree = ""; };
59 | 15E0F466282F6F6B0073F2E8 /* ComposeSessionHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeSessionHandler.swift; sourceTree = ""; };
60 | 15E0F46C282F6F6B0073F2E8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
61 | 15E0F46D282F6F6B0073F2E8 /* BodyScan.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = BodyScan.entitlements; sourceTree = ""; };
62 | /* End PBXFileReference section */
63 |
64 | /* Begin PBXFrameworksBuildPhase section */
65 | 155C611C282F6DF200E26A22 /* Frameworks */ = {
66 | isa = PBXFrameworksBuildPhase;
67 | buildActionMask = 2147483647;
68 | files = (
69 | );
70 | runOnlyForDeploymentPostprocessing = 0;
71 | };
72 | 15E0F45F282F6F6B0073F2E8 /* Frameworks */ = {
73 | isa = PBXFrameworksBuildPhase;
74 | buildActionMask = 2147483647;
75 | files = (
76 | );
77 | runOnlyForDeploymentPostprocessing = 0;
78 | };
79 | /* End PBXFrameworksBuildPhase section */
80 |
81 | /* Begin PBXGroup section */
82 | 155C6116282F6DF200E26A22 = {
83 | isa = PBXGroup;
84 | children = (
85 | 155C6121282F6DF200E26A22 /* Checkpoint */,
86 | 15E0F463282F6F6B0073F2E8 /* BodyScan */,
87 | 155C6120282F6DF200E26A22 /* Products */,
88 | );
89 | sourceTree = "";
90 | };
91 | 155C6120282F6DF200E26A22 /* Products */ = {
92 | isa = PBXGroup;
93 | children = (
94 | 155C611F282F6DF200E26A22 /* Checkpoint.app */,
95 | 15E0F462282F6F6B0073F2E8 /* BodyScan.appex */,
96 | );
97 | name = Products;
98 | sourceTree = "";
99 | };
100 | 155C6121282F6DF200E26A22 /* Checkpoint */ = {
101 | isa = PBXGroup;
102 | children = (
103 | 151DB2E42A36CE5D00B836ED /* Info.plist */,
104 | 155C6122282F6DF200E26A22 /* CheckpointApp.swift */,
105 | 155C6124282F6DF200E26A22 /* ContentView.swift */,
106 | 155C6126282F6DF600E26A22 /* Assets.xcassets */,
107 | 155C612B282F6DF600E26A22 /* Checkpoint.entitlements */,
108 | 155C6128282F6DF600E26A22 /* Preview Content */,
109 | );
110 | path = Checkpoint;
111 | sourceTree = "";
112 | };
113 | 155C6128282F6DF600E26A22 /* Preview Content */ = {
114 | isa = PBXGroup;
115 | children = (
116 | 155C6129282F6DF600E26A22 /* Preview Assets.xcassets */,
117 | );
118 | path = "Preview Content";
119 | sourceTree = "";
120 | };
121 | 15E0F463282F6F6B0073F2E8 /* BodyScan */ = {
122 | isa = PBXGroup;
123 | children = (
124 | 15E0F464282F6F6B0073F2E8 /* MailExtension.swift */,
125 | 15E0F466282F6F6B0073F2E8 /* ComposeSessionHandler.swift */,
126 | 152423E92A3590A900BFBD33 /* ComposeSessionView.swift */,
127 | 152423EC2A35928A00BFBD33 /* SessionStore.swift */,
128 | 15E0F46C282F6F6B0073F2E8 /* Info.plist */,
129 | 15E0F46D282F6F6B0073F2E8 /* BodyScan.entitlements */,
130 | 1599F9872A3453A900645DBA /* BodyScan.xcassets */,
131 | );
132 | path = BodyScan;
133 | sourceTree = "";
134 | };
135 | /* End PBXGroup section */
136 |
137 | /* Begin PBXNativeTarget section */
138 | 155C611E282F6DF200E26A22 /* Checkpoint */ = {
139 | isa = PBXNativeTarget;
140 | buildConfigurationList = 155C612E282F6DF600E26A22 /* Build configuration list for PBXNativeTarget "Checkpoint" */;
141 | buildPhases = (
142 | 155C611B282F6DF200E26A22 /* Sources */,
143 | 155C611C282F6DF200E26A22 /* Frameworks */,
144 | 155C611D282F6DF200E26A22 /* Resources */,
145 | 15E0F471282F6F6B0073F2E8 /* Embed Foundation Extensions */,
146 | );
147 | buildRules = (
148 | );
149 | dependencies = (
150 | 15E0F46F282F6F6B0073F2E8 /* PBXTargetDependency */,
151 | );
152 | name = Checkpoint;
153 | productName = Checkpoint;
154 | productReference = 155C611F282F6DF200E26A22 /* Checkpoint.app */;
155 | productType = "com.apple.product-type.application";
156 | };
157 | 15E0F461282F6F6B0073F2E8 /* BodyScan */ = {
158 | isa = PBXNativeTarget;
159 | buildConfigurationList = 15E0F474282F6F6B0073F2E8 /* Build configuration list for PBXNativeTarget "BodyScan" */;
160 | buildPhases = (
161 | 15E0F45E282F6F6B0073F2E8 /* Sources */,
162 | 15E0F45F282F6F6B0073F2E8 /* Frameworks */,
163 | 15E0F460282F6F6B0073F2E8 /* Resources */,
164 | );
165 | buildRules = (
166 | );
167 | dependencies = (
168 | );
169 | name = BodyScan;
170 | productName = BodyScan;
171 | productReference = 15E0F462282F6F6B0073F2E8 /* BodyScan.appex */;
172 | productType = "com.apple.product-type.app-extension";
173 | };
174 | /* End PBXNativeTarget section */
175 |
176 | /* Begin PBXProject section */
177 | 155C6117282F6DF200E26A22 /* Project object */ = {
178 | isa = PBXProject;
179 | attributes = {
180 | BuildIndependentTargetsInParallel = 1;
181 | LastSwiftUpdateCheck = 1310;
182 | LastUpgradeCheck = 1430;
183 | TargetAttributes = {
184 | 155C611E282F6DF200E26A22 = {
185 | CreatedOnToolsVersion = 13.1;
186 | };
187 | 15E0F461282F6F6B0073F2E8 = {
188 | CreatedOnToolsVersion = 13.1;
189 | };
190 | };
191 | };
192 | buildConfigurationList = 155C611A282F6DF200E26A22 /* Build configuration list for PBXProject "Checkpoint" */;
193 | compatibilityVersion = "Xcode 13.0";
194 | developmentRegion = en;
195 | hasScannedForEncodings = 0;
196 | knownRegions = (
197 | en,
198 | Base,
199 | );
200 | mainGroup = 155C6116282F6DF200E26A22;
201 | productRefGroup = 155C6120282F6DF200E26A22 /* Products */;
202 | projectDirPath = "";
203 | projectRoot = "";
204 | targets = (
205 | 155C611E282F6DF200E26A22 /* Checkpoint */,
206 | 15E0F461282F6F6B0073F2E8 /* BodyScan */,
207 | );
208 | };
209 | /* End PBXProject section */
210 |
211 | /* Begin PBXResourcesBuildPhase section */
212 | 155C611D282F6DF200E26A22 /* Resources */ = {
213 | isa = PBXResourcesBuildPhase;
214 | buildActionMask = 2147483647;
215 | files = (
216 | 155C612A282F6DF600E26A22 /* Preview Assets.xcassets in Resources */,
217 | 155C6127282F6DF600E26A22 /* Assets.xcassets in Resources */,
218 | );
219 | runOnlyForDeploymentPostprocessing = 0;
220 | };
221 | 15E0F460282F6F6B0073F2E8 /* Resources */ = {
222 | isa = PBXResourcesBuildPhase;
223 | buildActionMask = 2147483647;
224 | files = (
225 | 1599F9882A3453A900645DBA /* BodyScan.xcassets in Resources */,
226 | );
227 | runOnlyForDeploymentPostprocessing = 0;
228 | };
229 | /* End PBXResourcesBuildPhase section */
230 |
231 | /* Begin PBXSourcesBuildPhase section */
232 | 155C611B282F6DF200E26A22 /* Sources */ = {
233 | isa = PBXSourcesBuildPhase;
234 | buildActionMask = 2147483647;
235 | files = (
236 | 155C6125282F6DF200E26A22 /* ContentView.swift in Sources */,
237 | 155C6123282F6DF200E26A22 /* CheckpointApp.swift in Sources */,
238 | );
239 | runOnlyForDeploymentPostprocessing = 0;
240 | };
241 | 15E0F45E282F6F6B0073F2E8 /* Sources */ = {
242 | isa = PBXSourcesBuildPhase;
243 | buildActionMask = 2147483647;
244 | files = (
245 | 15E0F467282F6F6B0073F2E8 /* ComposeSessionHandler.swift in Sources */,
246 | 152423EA2A3590A900BFBD33 /* ComposeSessionView.swift in Sources */,
247 | 152423ED2A35928A00BFBD33 /* SessionStore.swift in Sources */,
248 | 15E0F465282F6F6B0073F2E8 /* MailExtension.swift in Sources */,
249 | );
250 | runOnlyForDeploymentPostprocessing = 0;
251 | };
252 | /* End PBXSourcesBuildPhase section */
253 |
254 | /* Begin PBXTargetDependency section */
255 | 15E0F46F282F6F6B0073F2E8 /* PBXTargetDependency */ = {
256 | isa = PBXTargetDependency;
257 | target = 15E0F461282F6F6B0073F2E8 /* BodyScan */;
258 | targetProxy = 15E0F46E282F6F6B0073F2E8 /* PBXContainerItemProxy */;
259 | };
260 | /* End PBXTargetDependency section */
261 |
262 | /* Begin XCBuildConfiguration section */
263 | 155C612C282F6DF600E26A22 /* Debug */ = {
264 | isa = XCBuildConfiguration;
265 | buildSettings = {
266 | ALWAYS_SEARCH_USER_PATHS = NO;
267 | CLANG_ANALYZER_NONNULL = YES;
268 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
269 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
270 | CLANG_CXX_LIBRARY = "libc++";
271 | CLANG_ENABLE_MODULES = YES;
272 | CLANG_ENABLE_OBJC_ARC = YES;
273 | CLANG_ENABLE_OBJC_WEAK = YES;
274 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
275 | CLANG_WARN_BOOL_CONVERSION = YES;
276 | CLANG_WARN_COMMA = YES;
277 | CLANG_WARN_CONSTANT_CONVERSION = YES;
278 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
279 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
280 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
281 | CLANG_WARN_EMPTY_BODY = YES;
282 | CLANG_WARN_ENUM_CONVERSION = YES;
283 | CLANG_WARN_INFINITE_RECURSION = YES;
284 | CLANG_WARN_INT_CONVERSION = YES;
285 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
286 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
287 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
288 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
289 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
290 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
291 | CLANG_WARN_STRICT_PROTOTYPES = YES;
292 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
293 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
294 | CLANG_WARN_UNREACHABLE_CODE = YES;
295 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
296 | COPY_PHASE_STRIP = NO;
297 | DEAD_CODE_STRIPPING = YES;
298 | DEBUG_INFORMATION_FORMAT = dwarf;
299 | ENABLE_STRICT_OBJC_MSGSEND = YES;
300 | ENABLE_TESTABILITY = YES;
301 | GCC_C_LANGUAGE_STANDARD = gnu11;
302 | GCC_DYNAMIC_NO_PIC = NO;
303 | GCC_NO_COMMON_BLOCKS = YES;
304 | GCC_OPTIMIZATION_LEVEL = 0;
305 | GCC_PREPROCESSOR_DEFINITIONS = (
306 | "DEBUG=1",
307 | "$(inherited)",
308 | );
309 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
310 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
311 | GCC_WARN_UNDECLARED_SELECTOR = YES;
312 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
313 | GCC_WARN_UNUSED_FUNCTION = YES;
314 | GCC_WARN_UNUSED_VARIABLE = YES;
315 | MACOSX_DEPLOYMENT_TARGET = 12.0;
316 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
317 | MTL_FAST_MATH = YES;
318 | ONLY_ACTIVE_ARCH = YES;
319 | SDKROOT = macosx;
320 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
321 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
322 | };
323 | name = Debug;
324 | };
325 | 155C612D282F6DF600E26A22 /* Release */ = {
326 | isa = XCBuildConfiguration;
327 | buildSettings = {
328 | ALWAYS_SEARCH_USER_PATHS = NO;
329 | CLANG_ANALYZER_NONNULL = YES;
330 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
331 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
332 | CLANG_CXX_LIBRARY = "libc++";
333 | CLANG_ENABLE_MODULES = YES;
334 | CLANG_ENABLE_OBJC_ARC = YES;
335 | CLANG_ENABLE_OBJC_WEAK = YES;
336 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
337 | CLANG_WARN_BOOL_CONVERSION = YES;
338 | CLANG_WARN_COMMA = YES;
339 | CLANG_WARN_CONSTANT_CONVERSION = YES;
340 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
341 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
342 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
343 | CLANG_WARN_EMPTY_BODY = YES;
344 | CLANG_WARN_ENUM_CONVERSION = YES;
345 | CLANG_WARN_INFINITE_RECURSION = YES;
346 | CLANG_WARN_INT_CONVERSION = YES;
347 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
348 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
349 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
350 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
351 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
352 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
353 | CLANG_WARN_STRICT_PROTOTYPES = YES;
354 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
355 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
356 | CLANG_WARN_UNREACHABLE_CODE = YES;
357 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
358 | COPY_PHASE_STRIP = NO;
359 | DEAD_CODE_STRIPPING = YES;
360 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
361 | ENABLE_NS_ASSERTIONS = NO;
362 | ENABLE_STRICT_OBJC_MSGSEND = YES;
363 | GCC_C_LANGUAGE_STANDARD = gnu11;
364 | GCC_NO_COMMON_BLOCKS = YES;
365 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
366 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
367 | GCC_WARN_UNDECLARED_SELECTOR = YES;
368 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
369 | GCC_WARN_UNUSED_FUNCTION = YES;
370 | GCC_WARN_UNUSED_VARIABLE = YES;
371 | MACOSX_DEPLOYMENT_TARGET = 12.0;
372 | MTL_ENABLE_DEBUG_INFO = NO;
373 | MTL_FAST_MATH = YES;
374 | SDKROOT = macosx;
375 | SWIFT_COMPILATION_MODE = wholemodule;
376 | SWIFT_OPTIMIZATION_LEVEL = "-O";
377 | };
378 | name = Release;
379 | };
380 | 155C612F282F6DF600E26A22 /* Debug */ = {
381 | isa = XCBuildConfiguration;
382 | buildSettings = {
383 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
384 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
385 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
386 | ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
387 | CODE_SIGN_ENTITLEMENTS = Checkpoint/Checkpoint.entitlements;
388 | CODE_SIGN_STYLE = Automatic;
389 | COMBINE_HIDPI_IMAGES = YES;
390 | CURRENT_PROJECT_VERSION = 14;
391 | DEAD_CODE_STRIPPING = YES;
392 | DEVELOPMENT_ASSET_PATHS = "\"Checkpoint/Preview Content\"";
393 | DEVELOPMENT_TEAM = 39UWSCXL32;
394 | ENABLE_HARDENED_RUNTIME = YES;
395 | ENABLE_PREVIEWS = YES;
396 | GENERATE_INFOPLIST_FILE = YES;
397 | INFOPLIST_FILE = Checkpoint/Info.plist;
398 | INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
399 | INFOPLIST_KEY_NSHumanReadableCopyright = "";
400 | LD_RUNPATH_SEARCH_PATHS = (
401 | "$(inherited)",
402 | "@executable_path/../Frameworks",
403 | );
404 | MARKETING_VERSION = 1.1;
405 | PRODUCT_BUNDLE_IDENTIFIER = sh.linus.Checkpoint;
406 | PRODUCT_NAME = "$(TARGET_NAME)";
407 | SWIFT_EMIT_LOC_STRINGS = YES;
408 | SWIFT_VERSION = 5.0;
409 | };
410 | name = Debug;
411 | };
412 | 155C6130282F6DF600E26A22 /* Release */ = {
413 | isa = XCBuildConfiguration;
414 | buildSettings = {
415 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
416 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
417 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
418 | ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
419 | CODE_SIGN_ENTITLEMENTS = Checkpoint/Checkpoint.entitlements;
420 | CODE_SIGN_STYLE = Automatic;
421 | COMBINE_HIDPI_IMAGES = YES;
422 | CURRENT_PROJECT_VERSION = 14;
423 | DEAD_CODE_STRIPPING = YES;
424 | DEVELOPMENT_ASSET_PATHS = "\"Checkpoint/Preview Content\"";
425 | DEVELOPMENT_TEAM = 39UWSCXL32;
426 | ENABLE_HARDENED_RUNTIME = YES;
427 | ENABLE_PREVIEWS = YES;
428 | GENERATE_INFOPLIST_FILE = YES;
429 | INFOPLIST_FILE = Checkpoint/Info.plist;
430 | INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
431 | INFOPLIST_KEY_NSHumanReadableCopyright = "";
432 | LD_RUNPATH_SEARCH_PATHS = (
433 | "$(inherited)",
434 | "@executable_path/../Frameworks",
435 | );
436 | MARKETING_VERSION = 1.1;
437 | PRODUCT_BUNDLE_IDENTIFIER = sh.linus.Checkpoint;
438 | PRODUCT_NAME = "$(TARGET_NAME)";
439 | SWIFT_EMIT_LOC_STRINGS = YES;
440 | SWIFT_VERSION = 5.0;
441 | };
442 | name = Release;
443 | };
444 | 15E0F472282F6F6B0073F2E8 /* Debug */ = {
445 | isa = XCBuildConfiguration;
446 | buildSettings = {
447 | ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
448 | CODE_SIGN_ENTITLEMENTS = BodyScan/BodyScan.entitlements;
449 | CODE_SIGN_STYLE = Automatic;
450 | COMBINE_HIDPI_IMAGES = YES;
451 | CURRENT_PROJECT_VERSION = 14;
452 | DEAD_CODE_STRIPPING = YES;
453 | DEVELOPMENT_TEAM = 39UWSCXL32;
454 | ENABLE_HARDENED_RUNTIME = YES;
455 | GENERATE_INFOPLIST_FILE = YES;
456 | INFOPLIST_FILE = BodyScan/Info.plist;
457 | INFOPLIST_KEY_CFBundleDisplayName = Checkpoint;
458 | INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 Linus Skucas. All rights reserved.";
459 | LD_RUNPATH_SEARCH_PATHS = (
460 | "$(inherited)",
461 | "@executable_path/../Frameworks",
462 | "@executable_path/../../../../Frameworks",
463 | );
464 | MACOSX_DEPLOYMENT_TARGET = 12.0;
465 | MARKETING_VERSION = 1.1;
466 | PRODUCT_BUNDLE_IDENTIFIER = sh.linus.Checkpoint.BodyScan;
467 | PRODUCT_NAME = "$(TARGET_NAME)";
468 | SKIP_INSTALL = YES;
469 | SWIFT_EMIT_LOC_STRINGS = YES;
470 | SWIFT_VERSION = 5.0;
471 | };
472 | name = Debug;
473 | };
474 | 15E0F473282F6F6B0073F2E8 /* Release */ = {
475 | isa = XCBuildConfiguration;
476 | buildSettings = {
477 | ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
478 | CODE_SIGN_ENTITLEMENTS = BodyScan/BodyScan.entitlements;
479 | CODE_SIGN_STYLE = Automatic;
480 | COMBINE_HIDPI_IMAGES = YES;
481 | CURRENT_PROJECT_VERSION = 14;
482 | DEAD_CODE_STRIPPING = YES;
483 | DEVELOPMENT_TEAM = 39UWSCXL32;
484 | ENABLE_HARDENED_RUNTIME = YES;
485 | GENERATE_INFOPLIST_FILE = YES;
486 | INFOPLIST_FILE = BodyScan/Info.plist;
487 | INFOPLIST_KEY_CFBundleDisplayName = Checkpoint;
488 | INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 Linus Skucas. All rights reserved.";
489 | LD_RUNPATH_SEARCH_PATHS = (
490 | "$(inherited)",
491 | "@executable_path/../Frameworks",
492 | "@executable_path/../../../../Frameworks",
493 | );
494 | MACOSX_DEPLOYMENT_TARGET = 12.0;
495 | MARKETING_VERSION = 1.1;
496 | PRODUCT_BUNDLE_IDENTIFIER = sh.linus.Checkpoint.BodyScan;
497 | PRODUCT_NAME = "$(TARGET_NAME)";
498 | SKIP_INSTALL = YES;
499 | SWIFT_EMIT_LOC_STRINGS = YES;
500 | SWIFT_VERSION = 5.0;
501 | };
502 | name = Release;
503 | };
504 | /* End XCBuildConfiguration section */
505 |
506 | /* Begin XCConfigurationList section */
507 | 155C611A282F6DF200E26A22 /* Build configuration list for PBXProject "Checkpoint" */ = {
508 | isa = XCConfigurationList;
509 | buildConfigurations = (
510 | 155C612C282F6DF600E26A22 /* Debug */,
511 | 155C612D282F6DF600E26A22 /* Release */,
512 | );
513 | defaultConfigurationIsVisible = 0;
514 | defaultConfigurationName = Release;
515 | };
516 | 155C612E282F6DF600E26A22 /* Build configuration list for PBXNativeTarget "Checkpoint" */ = {
517 | isa = XCConfigurationList;
518 | buildConfigurations = (
519 | 155C612F282F6DF600E26A22 /* Debug */,
520 | 155C6130282F6DF600E26A22 /* Release */,
521 | );
522 | defaultConfigurationIsVisible = 0;
523 | defaultConfigurationName = Release;
524 | };
525 | 15E0F474282F6F6B0073F2E8 /* Build configuration list for PBXNativeTarget "BodyScan" */ = {
526 | isa = XCConfigurationList;
527 | buildConfigurations = (
528 | 15E0F472282F6F6B0073F2E8 /* Debug */,
529 | 15E0F473282F6F6B0073F2E8 /* Release */,
530 | );
531 | defaultConfigurationIsVisible = 0;
532 | defaultConfigurationName = Release;
533 | };
534 | /* End XCConfigurationList section */
535 | };
536 | rootObject = 155C6117282F6DF200E26A22 /* Project object */;
537 | }
538 |
--------------------------------------------------------------------------------
/Checkpoint.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Checkpoint.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Checkpoint.xcodeproj/project.xcworkspace/xcuserdata/linus.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinusSkucas/Checkpoint/414ddf6726671c7354f00f511663e8f280e17c98/Checkpoint.xcodeproj/project.xcworkspace/xcuserdata/linus.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Checkpoint.xcodeproj/xcshareddata/xcschemes/BodyScan.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
6 |
9 |
10 |
16 |
22 |
23 |
24 |
30 |
36 |
37 |
38 |
39 |
40 |
46 |
47 |
59 |
61 |
67 |
68 |
69 |
70 |
78 |
80 |
86 |
87 |
88 |
89 |
91 |
92 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/Checkpoint.xcodeproj/xcshareddata/xcschemes/Checkpoint.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
42 |
44 |
50 |
51 |
52 |
53 |
59 |
61 |
67 |
68 |
69 |
70 |
72 |
73 |
76 |
77 |
79 |
82 |
83 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/Checkpoint.xcodeproj/xcuserdata/linus.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/Checkpoint.xcodeproj/xcuserdata/linus.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | BodyScan.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 1
11 |
12 | Checkpoint.xcscheme_^#shared#^_
13 |
14 | orderHint
15 | 0
16 |
17 |
18 | SuppressBuildableAutocreation
19 |
20 | 155C611E282F6DF200E26A22
21 |
22 | primary
23 |
24 |
25 | 15E0F461282F6F6B0073F2E8
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Checkpoint/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "color" : {
5 | "platform" : "universal",
6 | "reference" : "systemRedColor"
7 | },
8 | "idiom" : "universal"
9 | }
10 | ],
11 | "info" : {
12 | "author" : "xcode",
13 | "version" : 1
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Checkpoint/Assets.xcassets/AppIcon.appiconset/Artwork-18 1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinusSkucas/Checkpoint/414ddf6726671c7354f00f511663e8f280e17c98/Checkpoint/Assets.xcassets/AppIcon.appiconset/Artwork-18 1.png
--------------------------------------------------------------------------------
/Checkpoint/Assets.xcassets/AppIcon.appiconset/Artwork-18.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinusSkucas/Checkpoint/414ddf6726671c7354f00f511663e8f280e17c98/Checkpoint/Assets.xcassets/AppIcon.appiconset/Artwork-18.png
--------------------------------------------------------------------------------
/Checkpoint/Assets.xcassets/AppIcon.appiconset/Artwork-19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinusSkucas/Checkpoint/414ddf6726671c7354f00f511663e8f280e17c98/Checkpoint/Assets.xcassets/AppIcon.appiconset/Artwork-19.png
--------------------------------------------------------------------------------
/Checkpoint/Assets.xcassets/AppIcon.appiconset/Artwork-21.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinusSkucas/Checkpoint/414ddf6726671c7354f00f511663e8f280e17c98/Checkpoint/Assets.xcassets/AppIcon.appiconset/Artwork-21.png
--------------------------------------------------------------------------------
/Checkpoint/Assets.xcassets/AppIcon.appiconset/Artwork-22 1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinusSkucas/Checkpoint/414ddf6726671c7354f00f511663e8f280e17c98/Checkpoint/Assets.xcassets/AppIcon.appiconset/Artwork-22 1.png
--------------------------------------------------------------------------------
/Checkpoint/Assets.xcassets/AppIcon.appiconset/Artwork-22.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinusSkucas/Checkpoint/414ddf6726671c7354f00f511663e8f280e17c98/Checkpoint/Assets.xcassets/AppIcon.appiconset/Artwork-22.png
--------------------------------------------------------------------------------
/Checkpoint/Assets.xcassets/AppIcon.appiconset/Artwork-23.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinusSkucas/Checkpoint/414ddf6726671c7354f00f511663e8f280e17c98/Checkpoint/Assets.xcassets/AppIcon.appiconset/Artwork-23.png
--------------------------------------------------------------------------------
/Checkpoint/Assets.xcassets/AppIcon.appiconset/Artwork-6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinusSkucas/Checkpoint/414ddf6726671c7354f00f511663e8f280e17c98/Checkpoint/Assets.xcassets/AppIcon.appiconset/Artwork-6.png
--------------------------------------------------------------------------------
/Checkpoint/Assets.xcassets/AppIcon.appiconset/Artwork-7 1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinusSkucas/Checkpoint/414ddf6726671c7354f00f511663e8f280e17c98/Checkpoint/Assets.xcassets/AppIcon.appiconset/Artwork-7 1.png
--------------------------------------------------------------------------------
/Checkpoint/Assets.xcassets/AppIcon.appiconset/Artwork-7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinusSkucas/Checkpoint/414ddf6726671c7354f00f511663e8f280e17c98/Checkpoint/Assets.xcassets/AppIcon.appiconset/Artwork-7.png
--------------------------------------------------------------------------------
/Checkpoint/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "Artwork-23.png",
5 | "idiom" : "mac",
6 | "scale" : "1x",
7 | "size" : "16x16"
8 | },
9 | {
10 | "filename" : "Artwork-22 1.png",
11 | "idiom" : "mac",
12 | "scale" : "2x",
13 | "size" : "16x16"
14 | },
15 | {
16 | "filename" : "Artwork-22.png",
17 | "idiom" : "mac",
18 | "scale" : "1x",
19 | "size" : "32x32"
20 | },
21 | {
22 | "filename" : "Artwork-21.png",
23 | "idiom" : "mac",
24 | "scale" : "2x",
25 | "size" : "32x32"
26 | },
27 | {
28 | "filename" : "Artwork-19.png",
29 | "idiom" : "mac",
30 | "scale" : "1x",
31 | "size" : "128x128"
32 | },
33 | {
34 | "filename" : "Artwork-18 1.png",
35 | "idiom" : "mac",
36 | "scale" : "2x",
37 | "size" : "128x128"
38 | },
39 | {
40 | "filename" : "Artwork-18.png",
41 | "idiom" : "mac",
42 | "scale" : "1x",
43 | "size" : "256x256"
44 | },
45 | {
46 | "filename" : "Artwork-7 1.png",
47 | "idiom" : "mac",
48 | "scale" : "2x",
49 | "size" : "256x256"
50 | },
51 | {
52 | "filename" : "Artwork-7.png",
53 | "idiom" : "mac",
54 | "scale" : "1x",
55 | "size" : "512x512"
56 | },
57 | {
58 | "filename" : "Artwork-6.png",
59 | "idiom" : "mac",
60 | "scale" : "2x",
61 | "size" : "512x512"
62 | }
63 | ],
64 | "info" : {
65 | "author" : "xcode",
66 | "version" : 1
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/Checkpoint/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Checkpoint/Checkpoint.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.application-groups
8 |
9 | $(TeamIdentifierPrefix)sh.linus.Checkpoint
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Checkpoint/CheckpointApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CheckpointApp.swift
3 | // Checkpoint
4 | //
5 | // Created by Linus Skucas on 5/13/22.
6 | //
7 |
8 | import SwiftUI
9 |
10 | @main
11 | struct CheckpointApp: App {
12 | var body: some Scene {
13 | WindowGroup {
14 | ContentView()
15 | .frame(minWidth: 300, maxWidth: 320, minHeight:450, maxHeight: 470)
16 | }
17 | .windowResizabilityContentSize()
18 | }
19 | }
20 |
21 | extension Scene {
22 | func windowResizabilityContentSize() -> some Scene {
23 | if #available(macOS 13.0, *) {
24 | return windowResizability(.contentSize)
25 | } else {
26 | return self
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Checkpoint/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // Checkpoint
4 | //
5 | // Created by Linus Skucas on 5/13/22.
6 | //
7 |
8 | import SwiftUI
9 |
10 | struct ContentView: View {
11 | let mailIcon = NSWorkspace.shared.icon(forFile: "/System/Applications/Mail.app")
12 |
13 | var body: some View {
14 | VStack(alignment: .leading) {
15 | VStack(alignment: .leading) {
16 | Text("Welcome to")
17 | Text("Checkpoint")
18 | .foregroundColor(.red)
19 | .fontWeight(.bold)
20 | }
21 | .font(.system(.largeTitle, design: .rounded))
22 |
23 | Spacer()
24 |
25 | GroupBox {
26 | VStack(alignment: .symbolInstructionAlignmentGuide) {
27 | InstructionView(image: Image(nsImage: mailIcon), instructionText: "Open **Mail**")
28 | InstructionView(symbol: "puzzlepiece", instructionText: "In **Settings**, select **Extensions**")
29 | InstructionView(symbol: "checkmark", instructionText: "Enable **Checkpoint**")
30 | InstructionView(symbol: "checkerboard.shield", instructionText: "While **composing**, click the **shield** in the toolbar to enable Checkpoint.")
31 | }
32 | } label: {
33 | Text("To get started:")
34 | .textCase(.uppercase)
35 | .foregroundColor(.secondary)
36 | .font(.callout)
37 | }
38 | }
39 | .padding()
40 | }
41 | }
42 |
43 | struct ContentView_Previews: PreviewProvider {
44 | static var previews: some View {
45 | ContentView()
46 | }
47 | }
48 |
49 | struct InstructionView: View {
50 | var symbol: Image
51 | var instructionText: String
52 |
53 | init(image: Image, instructionText: String) {
54 | self.symbol = image
55 | self.instructionText = instructionText
56 | }
57 |
58 | init(symbol: String, instructionText: String) {
59 | self.symbol = Image(systemName: symbol)
60 | self.instructionText = instructionText
61 | }
62 |
63 | var body: some View {
64 | HStack(alignment: .center) { // TODO: Fix the alignment of symbols and text (text should align with other text and symbols align with other symbols)
65 | symbol
66 | .font(.title) // TODO: Add color to the symbols
67 | .alignmentGuide(.symbolInstructionAlignmentGuide) { context in
68 | context[HorizontalAlignment.center]
69 | }
70 | Text(.init(instructionText))
71 | }
72 | .padding(.bottom, 5) // FIXME: More space between mail icon and other symbols
73 | }
74 | }
75 |
76 | extension HorizontalAlignment {
77 | private struct SymbolInstructionAlignment: AlignmentID {
78 | static func defaultValue(in context: ViewDimensions) -> CGFloat {
79 | context[HorizontalAlignment.leading]
80 | }
81 | }
82 |
83 | private struct SymbolAlignment: AlignmentID {
84 | static func defaultValue(in context: ViewDimensions) -> CGFloat {
85 | context[HorizontalAlignment.center]
86 | }
87 | }
88 |
89 | static let symbolInstructionAlignmentGuide = HorizontalAlignment(SymbolInstructionAlignment.self)
90 | static let symbolAlignmentGuide = HorizontalAlignment(SymbolAlignment.self)
91 | }
92 |
--------------------------------------------------------------------------------
/Checkpoint/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ITSAppUsesNonExemptEncryption
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Checkpoint/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Linus Skucas
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Checkpoint
2 | Proofread your emails before your boss does
3 |
4 | 🧠 Have you ever meant to reread an email before sending it but then forgot and just sent it anyways?
5 |
6 | 🍗 Now with Checkpoint you don’t have to worry about it!
7 |
8 | 🎄 Checkpoint is an extension for Apple Mail that reminds you to reread your emails. Just click a button (or check a box to do it for all emails) and you’ll be on your way!
9 |
10 | 🚨 Mail started supporting official extensions with macOS Monterey meaning this does not inject stuff into mail and is officially supported!
11 |
12 | 👁 The code is pretty messy, it’ll be cleaned up _“in the future”_
13 |
14 |
--------------------------------------------------------------------------------