Compare commits

...

10 Commits

Author SHA1 Message Date
june
9319e8904b
idek what i was doing bruh 2025-02-14 23:34:59 +13:00
breadone
154c02ca6c
please please please 2024-07-10 13:25:36 +12:00
breadone
a174b096fd
working on getting watch app to actually work 2024-07-10 11:44:58 +12:00
breadone
f2de4ae7cc
...i think i got icloud syncing working the first go? 2024-07-10 11:01:38 +12:00
breadone
2a7dadc939
Add temporary app icon 2024-07-10 10:35:33 +12:00
breadone
3edd8cf6a9
Made theme colour projects persist across theme changes 2024-06-27 10:30:26 +12:00
breadone
1f23a55b51
Added timers for the cue card view (can be controlled)
minor other adjustments
2024-06-26 00:24:16 +12:00
breadone
d4b1226ef3
improved the text editors (replaced em with textfields) 2024-06-25 20:33:46 +12:00
breadone
c49db28ff6
implemented card editing functionality although im not sure that's the final version yet 2024-06-25 18:16:27 +12:00
breadone
a4302ef65d
Updated add project screen to use the theme colour if none selected 2024-06-24 14:16:48 +12:00
28 changed files with 379 additions and 140 deletions

View File

@ -7,6 +7,9 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
460D7DF62C2AE788002B623C /* TimerManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 460D7DF52C2AE788002B623C /* TimerManager.swift */; };
460D7DF72C2AE788002B623C /* TimerManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 460D7DF52C2AE788002B623C /* TimerManager.swift */; };
4614D4032C3DFD3E000799F5 /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46D3E1432C27DFCE0060722E /* Preferences.swift */; };
464787CB2C269CAF00A9C462 /* TeleprompterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 464787CA2C269CAF00A9C462 /* TeleprompterView.swift */; }; 464787CB2C269CAF00A9C462 /* TeleprompterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 464787CA2C269CAF00A9C462 /* TeleprompterView.swift */; };
464787CC2C26A2E100A9C462 /* ColorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46AD30F12C2672BD00486C25 /* ColorModel.swift */; }; 464787CC2C26A2E100A9C462 /* ColorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46AD30F12C2672BD00486C25 /* ColorModel.swift */; };
464787CD2C26A2E500A9C462 /* PreviewData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46AD30F32C267D6400486C25 /* PreviewData.swift */; }; 464787CD2C26A2E500A9C462 /* PreviewData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46AD30F32C267D6400486C25 /* PreviewData.swift */; };
@ -19,7 +22,7 @@
46AD30D32C26559B00486C25 /* MainViewPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46AD30D22C26559B00486C25 /* MainViewPresenter.swift */; }; 46AD30D32C26559B00486C25 /* MainViewPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46AD30D22C26559B00486C25 /* MainViewPresenter.swift */; };
46AD30D52C26559D00486C25 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 46AD30D42C26559D00486C25 /* Assets.xcassets */; }; 46AD30D52C26559D00486C25 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 46AD30D42C26559D00486C25 /* Assets.xcassets */; };
46AD30D82C26559D00486C25 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 46AD30D72C26559D00486C25 /* Preview Assets.xcassets */; }; 46AD30D82C26559D00486C25 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 46AD30D72C26559D00486C25 /* Preview Assets.xcassets */; };
46AD30DB2C26559D00486C25 /* OnCuePresenter Watch App.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 46AD30CE2C26559B00486C25 /* OnCuePresenter Watch App.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 46AD30DB2C26559D00486C25 /* OnCue.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 46AD30CE2C26559B00486C25 /* OnCue.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
46AD30E22C2656CB00486C25 /* OCCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46AD30E12C2656CB00486C25 /* OCCard.swift */; }; 46AD30E22C2656CB00486C25 /* OCCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46AD30E12C2656CB00486C25 /* OCCard.swift */; };
46AD30E32C2656CB00486C25 /* OCCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46AD30E12C2656CB00486C25 /* OCCard.swift */; }; 46AD30E32C2656CB00486C25 /* OCCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46AD30E12C2656CB00486C25 /* OCCard.swift */; };
46AD30E52C2656D100486C25 /* OCProject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46AD30E42C2656D100486C25 /* OCProject.swift */; }; 46AD30E52C2656D100486C25 /* OCProject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46AD30E42C2656D100486C25 /* OCProject.swift */; };
@ -28,7 +31,7 @@
46AD30EF2C266F1900486C25 /* NewProjectForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46AD30EE2C266F1900486C25 /* NewProjectForm.swift */; }; 46AD30EF2C266F1900486C25 /* NewProjectForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46AD30EE2C266F1900486C25 /* NewProjectForm.swift */; };
46AD30F22C2672BD00486C25 /* ColorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46AD30F12C2672BD00486C25 /* ColorModel.swift */; }; 46AD30F22C2672BD00486C25 /* ColorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46AD30F12C2672BD00486C25 /* ColorModel.swift */; };
46AD30F42C267D6400486C25 /* PreviewData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46AD30F32C267D6400486C25 /* PreviewData.swift */; }; 46AD30F42C267D6400486C25 /* PreviewData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46AD30F32C267D6400486C25 /* PreviewData.swift */; };
46AD30F62C26823B00486C25 /* AddNewCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46AD30F52C26823B00486C25 /* AddNewCardView.swift */; }; 46AD30F62C26823B00486C25 /* EditCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46AD30F52C26823B00486C25 /* EditCardView.swift */; };
46AD30F82C2689B900486C25 /* ProjectSlideshowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46AD30F72C2689B900486C25 /* ProjectSlideshowView.swift */; }; 46AD30F82C2689B900486C25 /* ProjectSlideshowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46AD30F72C2689B900486C25 /* ProjectSlideshowView.swift */; };
46D3E13F2C26D6430060722E /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46D3E13E2C26D6430060722E /* Constants.swift */; }; 46D3E13F2C26D6430060722E /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46D3E13E2C26D6430060722E /* Constants.swift */; };
46D3E1402C26D6430060722E /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46D3E13E2C26D6430060722E /* Constants.swift */; }; 46D3E1402C26D6430060722E /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46D3E13E2C26D6430060722E /* Constants.swift */; };
@ -55,7 +58,7 @@
dstPath = "$(CONTENTS_FOLDER_PATH)/Watch"; dstPath = "$(CONTENTS_FOLDER_PATH)/Watch";
dstSubfolderSpec = 16; dstSubfolderSpec = 16;
files = ( files = (
46AD30DB2C26559D00486C25 /* OnCuePresenter Watch App.app in Embed Watch Content */, 46AD30DB2C26559D00486C25 /* OnCue.app in Embed Watch Content */,
); );
name = "Embed Watch Content"; name = "Embed Watch Content";
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -63,6 +66,10 @@
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
460D7DF52C2AE788002B623C /* TimerManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimerManager.swift; sourceTree = "<group>"; };
4614D4022C3DF680000799F5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
4614D4042C3DFEE8000799F5 /* OnCuePresenter.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = OnCuePresenter.entitlements; sourceTree = "<group>"; };
4614D4052C3DFF16000799F5 /* OnCuePresenter-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = "OnCuePresenter-Info.plist"; sourceTree = "<group>"; };
464787CA2C269CAF00A9C462 /* TeleprompterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TeleprompterView.swift; sourceTree = "<group>"; }; 464787CA2C269CAF00A9C462 /* TeleprompterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TeleprompterView.swift; sourceTree = "<group>"; };
46AD30B72C26557500486C25 /* OnCue.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OnCue.app; sourceTree = BUILT_PRODUCTS_DIR; }; 46AD30B72C26557500486C25 /* OnCue.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OnCue.app; sourceTree = BUILT_PRODUCTS_DIR; };
46AD30BA2C26557500486C25 /* OnCueApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnCueApp.swift; sourceTree = "<group>"; }; 46AD30BA2C26557500486C25 /* OnCueApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnCueApp.swift; sourceTree = "<group>"; };
@ -70,7 +77,7 @@
46AD30BE2C26557500486C25 /* Item.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Item.swift; sourceTree = "<group>"; }; 46AD30BE2C26557500486C25 /* Item.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Item.swift; sourceTree = "<group>"; };
46AD30C02C26557600486C25 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; 46AD30C02C26557600486C25 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
46AD30C32C26557600486C25 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; }; 46AD30C32C26557600486C25 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
46AD30CE2C26559B00486C25 /* OnCuePresenter Watch App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "OnCuePresenter Watch App.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 46AD30CE2C26559B00486C25 /* OnCue.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OnCue.app; sourceTree = BUILT_PRODUCTS_DIR; };
46AD30D02C26559B00486C25 /* OnCuePresenterApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnCuePresenterApp.swift; sourceTree = "<group>"; }; 46AD30D02C26559B00486C25 /* OnCuePresenterApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnCuePresenterApp.swift; sourceTree = "<group>"; };
46AD30D22C26559B00486C25 /* MainViewPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainViewPresenter.swift; sourceTree = "<group>"; }; 46AD30D22C26559B00486C25 /* MainViewPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainViewPresenter.swift; sourceTree = "<group>"; };
46AD30D42C26559D00486C25 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; 46AD30D42C26559D00486C25 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
@ -81,7 +88,7 @@
46AD30EE2C266F1900486C25 /* NewProjectForm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewProjectForm.swift; sourceTree = "<group>"; }; 46AD30EE2C266F1900486C25 /* NewProjectForm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewProjectForm.swift; sourceTree = "<group>"; };
46AD30F12C2672BD00486C25 /* ColorModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorModel.swift; sourceTree = "<group>"; }; 46AD30F12C2672BD00486C25 /* ColorModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorModel.swift; sourceTree = "<group>"; };
46AD30F32C267D6400486C25 /* PreviewData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewData.swift; sourceTree = "<group>"; }; 46AD30F32C267D6400486C25 /* PreviewData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewData.swift; sourceTree = "<group>"; };
46AD30F52C26823B00486C25 /* AddNewCardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddNewCardView.swift; sourceTree = "<group>"; }; 46AD30F52C26823B00486C25 /* EditCardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditCardView.swift; sourceTree = "<group>"; };
46AD30F72C2689B900486C25 /* ProjectSlideshowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProjectSlideshowView.swift; sourceTree = "<group>"; }; 46AD30F72C2689B900486C25 /* ProjectSlideshowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProjectSlideshowView.swift; sourceTree = "<group>"; };
46D3E13E2C26D6430060722E /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; }; 46D3E13E2C26D6430060722E /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
46D3E1412C27DD5C0060722E /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; }; 46D3E1412C27DD5C0060722E /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
@ -112,6 +119,8 @@
46AD30AE2C26557500486C25 = { 46AD30AE2C26557500486C25 = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4614D4052C3DFF16000799F5 /* OnCuePresenter-Info.plist */,
4614D4042C3DFEE8000799F5 /* OnCuePresenter.entitlements */,
46AD30F02C2672AC00486C25 /* Shared */, 46AD30F02C2672AC00486C25 /* Shared */,
46AD30B92C26557500486C25 /* OnCue */, 46AD30B92C26557500486C25 /* OnCue */,
46AD30CF2C26559B00486C25 /* OnCuePresenter Watch App */, 46AD30CF2C26559B00486C25 /* OnCuePresenter Watch App */,
@ -123,7 +132,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
46AD30B72C26557500486C25 /* OnCue.app */, 46AD30B72C26557500486C25 /* OnCue.app */,
46AD30CE2C26559B00486C25 /* OnCuePresenter Watch App.app */, 46AD30CE2C26559B00486C25 /* OnCue.app */,
); );
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
@ -131,6 +140,7 @@
46AD30B92C26557500486C25 /* OnCue */ = { 46AD30B92C26557500486C25 /* OnCue */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4614D4022C3DF680000799F5 /* Info.plist */,
46D3E1472C27FAFC0060722E /* OnCue.entitlements */, 46D3E1472C27FAFC0060722E /* OnCue.entitlements */,
46AD30BA2C26557500486C25 /* OnCueApp.swift */, 46AD30BA2C26557500486C25 /* OnCueApp.swift */,
46AD30E82C266AB900486C25 /* View */, 46AD30E82C266AB900486C25 /* View */,
@ -175,6 +185,7 @@
46AD30BE2C26557500486C25 /* Item.swift */, 46AD30BE2C26557500486C25 /* Item.swift */,
46AD30E12C2656CB00486C25 /* OCCard.swift */, 46AD30E12C2656CB00486C25 /* OCCard.swift */,
46AD30E42C2656D100486C25 /* OCProject.swift */, 46AD30E42C2656D100486C25 /* OCProject.swift */,
460D7DF52C2AE788002B623C /* TimerManager.swift */,
); );
path = Model; path = Model;
sourceTree = "<group>"; sourceTree = "<group>";
@ -185,7 +196,7 @@
46AD30BC2C26557500486C25 /* MainView.swift */, 46AD30BC2C26557500486C25 /* MainView.swift */,
46AD30EC2C266C0B00486C25 /* CardsView.swift */, 46AD30EC2C266C0B00486C25 /* CardsView.swift */,
46AD30EE2C266F1900486C25 /* NewProjectForm.swift */, 46AD30EE2C266F1900486C25 /* NewProjectForm.swift */,
46AD30F52C26823B00486C25 /* AddNewCardView.swift */, 46AD30F52C26823B00486C25 /* EditCardView.swift */,
46AD30F72C2689B900486C25 /* ProjectSlideshowView.swift */, 46AD30F72C2689B900486C25 /* ProjectSlideshowView.swift */,
464787CA2C269CAF00A9C462 /* TeleprompterView.swift */, 464787CA2C269CAF00A9C462 /* TeleprompterView.swift */,
46D3E1412C27DD5C0060722E /* SettingsView.swift */, 46D3E1412C27DD5C0060722E /* SettingsView.swift */,
@ -243,9 +254,9 @@
productReference = 46AD30B72C26557500486C25 /* OnCue.app */; productReference = 46AD30B72C26557500486C25 /* OnCue.app */;
productType = "com.apple.product-type.application"; productType = "com.apple.product-type.application";
}; };
46AD30CD2C26559B00486C25 /* OnCuePresenter Watch App */ = { 46AD30CD2C26559B00486C25 /* OnCuePresenter */ = {
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 46AD30DC2C26559D00486C25 /* Build configuration list for PBXNativeTarget "OnCuePresenter Watch App" */; buildConfigurationList = 46AD30DC2C26559D00486C25 /* Build configuration list for PBXNativeTarget "OnCuePresenter" */;
buildPhases = ( buildPhases = (
46AD30CA2C26559B00486C25 /* Sources */, 46AD30CA2C26559B00486C25 /* Sources */,
46AD30CB2C26559B00486C25 /* Frameworks */, 46AD30CB2C26559B00486C25 /* Frameworks */,
@ -255,9 +266,9 @@
); );
dependencies = ( dependencies = (
); );
name = "OnCuePresenter Watch App"; name = OnCuePresenter;
productName = "OnCuePresenter Watch App"; productName = "OnCuePresenter Watch App";
productReference = 46AD30CE2C26559B00486C25 /* OnCuePresenter Watch App.app */; productReference = 46AD30CE2C26559B00486C25 /* OnCue.app */;
productType = "com.apple.product-type.application"; productType = "com.apple.product-type.application";
}; };
/* End PBXNativeTarget section */ /* End PBXNativeTarget section */
@ -292,7 +303,7 @@
projectRoot = ""; projectRoot = "";
targets = ( targets = (
46AD30B62C26557500486C25 /* OnCue */, 46AD30B62C26557500486C25 /* OnCue */,
46AD30CD2C26559B00486C25 /* OnCuePresenter Watch App */, 46AD30CD2C26559B00486C25 /* OnCuePresenter */,
); );
}; };
/* End PBXProject section */ /* End PBXProject section */
@ -326,7 +337,7 @@
46AD30F82C2689B900486C25 /* ProjectSlideshowView.swift in Sources */, 46AD30F82C2689B900486C25 /* ProjectSlideshowView.swift in Sources */,
46AD30EF2C266F1900486C25 /* NewProjectForm.swift in Sources */, 46AD30EF2C266F1900486C25 /* NewProjectForm.swift in Sources */,
46D3E1462C27EC3B0060722E /* AutoScrollView.swift in Sources */, 46D3E1462C27EC3B0060722E /* AutoScrollView.swift in Sources */,
46AD30F62C26823B00486C25 /* AddNewCardView.swift in Sources */, 46AD30F62C26823B00486C25 /* EditCardView.swift in Sources */,
464787CB2C269CAF00A9C462 /* TeleprompterView.swift in Sources */, 464787CB2C269CAF00A9C462 /* TeleprompterView.swift in Sources */,
46AD30ED2C266C0B00486C25 /* CardsView.swift in Sources */, 46AD30ED2C266C0B00486C25 /* CardsView.swift in Sources */,
46AD30BD2C26557500486C25 /* MainView.swift in Sources */, 46AD30BD2C26557500486C25 /* MainView.swift in Sources */,
@ -339,6 +350,7 @@
46AD30BB2C26557500486C25 /* OnCueApp.swift in Sources */, 46AD30BB2C26557500486C25 /* OnCueApp.swift in Sources */,
46AD30E52C2656D100486C25 /* OCProject.swift in Sources */, 46AD30E52C2656D100486C25 /* OCProject.swift in Sources */,
46AD30E22C2656CB00486C25 /* OCCard.swift in Sources */, 46AD30E22C2656CB00486C25 /* OCCard.swift in Sources */,
460D7DF62C2AE788002B623C /* TimerManager.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -348,10 +360,12 @@
files = ( files = (
46AD30E32C2656CB00486C25 /* OCCard.swift in Sources */, 46AD30E32C2656CB00486C25 /* OCCard.swift in Sources */,
46AD30D32C26559B00486C25 /* MainViewPresenter.swift in Sources */, 46AD30D32C26559B00486C25 /* MainViewPresenter.swift in Sources */,
4614D4032C3DFD3E000799F5 /* Preferences.swift in Sources */,
46E5FFD92C26A50D001191C9 /* CueCardViewPresenter.swift in Sources */, 46E5FFD92C26A50D001191C9 /* CueCardViewPresenter.swift in Sources */,
464787CD2C26A2E500A9C462 /* PreviewData.swift in Sources */, 464787CD2C26A2E500A9C462 /* PreviewData.swift in Sources */,
46AD30D12C26559B00486C25 /* OnCuePresenterApp.swift in Sources */, 46AD30D12C26559B00486C25 /* OnCuePresenterApp.swift in Sources */,
46AD30E62C2656D100486C25 /* OCProject.swift in Sources */, 46AD30E62C2656D100486C25 /* OCProject.swift in Sources */,
460D7DF72C2AE788002B623C /* TimerManager.swift in Sources */,
464787CC2C26A2E100A9C462 /* ColorModel.swift in Sources */, 464787CC2C26A2E100A9C462 /* ColorModel.swift in Sources */,
46D3E1402C26D6430060722E /* Constants.swift in Sources */, 46D3E1402C26D6430060722E /* Constants.swift in Sources */,
); );
@ -362,7 +376,7 @@
/* Begin PBXTargetDependency section */ /* Begin PBXTargetDependency section */
46AD30DA2C26559D00486C25 /* PBXTargetDependency */ = { 46AD30DA2C26559D00486C25 /* PBXTargetDependency */ = {
isa = PBXTargetDependency; isa = PBXTargetDependency;
target = 46AD30CD2C26559B00486C25 /* OnCuePresenter Watch App */; target = 46AD30CD2C26559B00486C25 /* OnCuePresenter */;
targetProxy = 46AD30D92C26559D00486C25 /* PBXContainerItemProxy */; targetProxy = 46AD30D92C26559D00486C25 /* PBXContainerItemProxy */;
}; };
/* End PBXTargetDependency section */ /* End PBXTargetDependency section */
@ -495,11 +509,12 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = OnCue/OnCue.entitlements; CODE_SIGN_ENTITLEMENTS = OnCue/OnCue.entitlements;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 3;
DEVELOPMENT_ASSET_PATHS = "\"OnCue/Preview Content\""; DEVELOPMENT_ASSET_PATHS = "\"OnCue/Preview Content\"";
DEVELOPMENT_TEAM = 9MP5435PRF; DEVELOPMENT_TEAM = 9MP5435PRF;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = OnCue/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = OnCue; INFOPLIST_KEY_CFBundleDisplayName = OnCue;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
@ -531,11 +546,12 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = OnCue/OnCue.entitlements; CODE_SIGN_ENTITLEMENTS = OnCue/OnCue.entitlements;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 3;
DEVELOPMENT_ASSET_PATHS = "\"OnCue/Preview Content\""; DEVELOPMENT_ASSET_PATHS = "\"OnCue/Preview Content\"";
DEVELOPMENT_TEAM = 9MP5435PRF; DEVELOPMENT_TEAM = 9MP5435PRF;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = OnCue/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = OnCue; INFOPLIST_KEY_CFBundleDisplayName = OnCue;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
@ -564,13 +580,14 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = OnCuePresenter.entitlements;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"OnCuePresenter Watch App/Preview Content\""; DEVELOPMENT_ASSET_PATHS = "\"OnCuePresenter Watch App/Preview Content\"";
DEVELOPMENT_TEAM = 9MP5435PRF; DEVELOPMENT_TEAM = 9MP5435PRF;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_CFBundleDisplayName = OnCuePresenter; INFOPLIST_FILE = "OnCuePresenter-Info.plist";
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
INFOPLIST_KEY_WKCompanionAppBundleIdentifier = xyz.breadone.oncue; INFOPLIST_KEY_WKCompanionAppBundleIdentifier = xyz.breadone.oncue;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
@ -578,14 +595,14 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0; MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = xyz.breadone.oncue.watchkitapp; PRODUCT_BUNDLE_IDENTIFIER = xyz.breadone.oncue.presenter;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = OnCue;
SDKROOT = watchos; SDKROOT = watchos;
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 4; TARGETED_DEVICE_FAMILY = 4;
WATCHOS_DEPLOYMENT_TARGET = 10.5; WATCHOS_DEPLOYMENT_TARGET = 10.0;
}; };
name = Debug; name = Debug;
}; };
@ -594,13 +611,14 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = OnCuePresenter.entitlements;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"OnCuePresenter Watch App/Preview Content\""; DEVELOPMENT_ASSET_PATHS = "\"OnCuePresenter Watch App/Preview Content\"";
DEVELOPMENT_TEAM = 9MP5435PRF; DEVELOPMENT_TEAM = 9MP5435PRF;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_CFBundleDisplayName = OnCuePresenter; INFOPLIST_FILE = "OnCuePresenter-Info.plist";
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
INFOPLIST_KEY_WKCompanionAppBundleIdentifier = xyz.breadone.oncue; INFOPLIST_KEY_WKCompanionAppBundleIdentifier = xyz.breadone.oncue;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
@ -608,14 +626,14 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0; MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = xyz.breadone.oncue.watchkitapp; PRODUCT_BUNDLE_IDENTIFIER = xyz.breadone.oncue.presenter;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = OnCue;
SDKROOT = watchos; SDKROOT = watchos;
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 4; TARGETED_DEVICE_FAMILY = 4;
WATCHOS_DEPLOYMENT_TARGET = 10.5; WATCHOS_DEPLOYMENT_TARGET = 10.0;
}; };
name = Release; name = Release;
}; };
@ -640,7 +658,7 @@
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release; defaultConfigurationName = Release;
}; };
46AD30DC2C26559D00486C25 /* Build configuration list for PBXNativeTarget "OnCuePresenter Watch App" */ = { 46AD30DC2C26559D00486C25 /* Build configuration list for PBXNativeTarget "OnCuePresenter" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
46AD30DD2C26559D00486C25 /* Debug */, 46AD30DD2C26559D00486C25 /* Debug */,

View File

@ -16,8 +16,8 @@
<BuildableReference <BuildableReference
BuildableIdentifier = "primary" BuildableIdentifier = "primary"
BlueprintIdentifier = "46AD30CD2C26559B00486C25" BlueprintIdentifier = "46AD30CD2C26559B00486C25"
BuildableName = "OnCuePresenter Watch App.app" BuildableName = "OnCue.app"
BlueprintName = "OnCuePresenter Watch App" BlueprintName = "OnCuePresenter"
ReferencedContainer = "container:OnCue.xcodeproj"> ReferencedContainer = "container:OnCue.xcodeproj">
</BuildableReference> </BuildableReference>
</BuildActionEntry> </BuildActionEntry>
@ -59,8 +59,8 @@
<BuildableReference <BuildableReference
BuildableIdentifier = "primary" BuildableIdentifier = "primary"
BlueprintIdentifier = "46AD30CD2C26559B00486C25" BlueprintIdentifier = "46AD30CD2C26559B00486C25"
BuildableName = "OnCuePresenter Watch App.app" BuildableName = "OnCue.app"
BlueprintName = "OnCuePresenter Watch App" BlueprintName = "OnCuePresenter"
ReferencedContainer = "container:OnCue.xcodeproj"> ReferencedContainer = "container:OnCue.xcodeproj">
</BuildableReference> </BuildableReference>
</BuildableProductRunnable> </BuildableProductRunnable>
@ -76,8 +76,8 @@
<BuildableReference <BuildableReference
BuildableIdentifier = "primary" BuildableIdentifier = "primary"
BlueprintIdentifier = "46AD30CD2C26559B00486C25" BlueprintIdentifier = "46AD30CD2C26559B00486C25"
BuildableName = "OnCuePresenter Watch App.app" BuildableName = "OnCue.app"
BlueprintName = "OnCuePresenter Watch App" BlueprintName = "OnCuePresenter"
ReferencedContainer = "container:OnCue.xcodeproj"> ReferencedContainer = "container:OnCue.xcodeproj">
</BuildableReference> </BuildableReference>
</BuildableProductRunnable> </BuildableProductRunnable>

View File

@ -1,6 +1,7 @@
{ {
"images" : [ "images" : [
{ {
"filename" : "oncue_icon.png",
"idiom" : "universal", "idiom" : "universal",
"platform" : "ios", "platform" : "ios",
"size" : "1024x1024" "size" : "1024x1024"

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

11
OnCue/Info.plist Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>remote-notification</string>
</array>
</dict>
</plist>

View File

@ -11,11 +11,13 @@ import SwiftData
@Model @Model
final class OCCard: Identifiable { final class OCCard: Identifiable {
let id = UUID() let id = UUID()
var content: String var content: String = ""
var index: Int var index: Int = 0
var parentProject: OCProject? = nil
init(content: String, index: Int) { init(content: String, index: Int, parent: OCProject) {
self.content = content self.content = content
self.index = index self.index = index
self.parentProject = parent
} }
} }

View File

@ -7,14 +7,15 @@
import Foundation import Foundation
import SwiftData import SwiftData
import CloudKit
@Model @Model
final class OCProject { final class OCProject {
var name: String var name: String = "No Name"
var cards: [OCCard] var cards: [OCCard]? = []
let creationDate: Date let creationDate: Date = Date()
var lastEditedDate: Date var lastEditedDate: Date = Date()
var color: String var color: String = "ff7e30"
var script: String { var script: String {
var txt = "" var txt = ""
@ -24,7 +25,7 @@ final class OCProject {
var sortedCards: [OCCard] { var sortedCards: [OCCard] {
get { get {
return self.cards.sorted(by: { $0.index < $1.index }) return self.cards?.sorted(by: { $0.index < $1.index }) ?? []
} }
} }
@ -36,15 +37,26 @@ final class OCProject {
self.color = color self.color = color
} }
init(name: String, color: String, tCards: [String] = []) {
self.name = name
self.creationDate = Date()
self.lastEditedDate = Date()
self.color = color
for i in 0 ..< tCards.count {
self.cards?.append(OCCard(content: tCards[i], index: i, parent: self))
}
}
func updateEditedDate(newDate: Date = Date()) { func updateEditedDate(newDate: Date = Date()) {
self.lastEditedDate = newDate self.lastEditedDate = newDate
} }
func addCards(cards: OCCard...) { func addCards(cards: OCCard...) {
cards.forEach({ self.cards.append($0) }) cards.forEach({ self.cards?.append($0) })
} }
func removeCard(_ card: OCCard) { func removeCard(_ card: OCCard) {
self.cards.removeAll { $0.id == card.id } self.cards?.removeAll { $0.id == card.id }
} }
} }

View File

@ -0,0 +1,42 @@
//
// TimerManager.swift
// OnCue
//
// Created by Pradyun Setti on 25/06/2024.
//
import Foundation
public class TimerManager: ObservableObject {
@Published public var secondsElapsed: Int = 0
@Published public var formattedTime: String = "00:00"
private var timer: Timer? = nil
public func startTimer() {
self.timer?.invalidate()
self.timer = Timer.scheduledTimer(timeInterval: 1,
target: self,
selector: #selector(update),
userInfo: nil,
repeats: true)
}
public func stopTimer() {
self.timer?.invalidate()
self.timer = nil
}
@objc public func update() {
secondsElapsed += 1
formattedTime = formatSeconds(secondsElapsed)
}
private func formatSeconds(_ seconds: Int) -> String {
let minutes = floor(Double(seconds) / 60)
let rSeconds = Double(seconds) - (minutes * 60)
return String(format: "%02.0f:%02.0f", minutes, rSeconds)
}
}

View File

@ -1,5 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict/> <dict>
<key>aps-environment</key>
<string>development</string>
<key>com.apple.developer.icloud-container-identifiers</key>
<array>
<string>iCloud.xyz.breadone.oncue</string>
</array>
<key>com.apple.developer.icloud-services</key>
<array>
<string>CloudKit</string>
</array>
</dict>
</plist> </plist>

View File

@ -7,6 +7,7 @@
import SwiftUI import SwiftUI
import SwiftData import SwiftData
import CoreData
@main @main
struct OnCueApp: App { struct OnCueApp: App {
@ -19,6 +20,34 @@ struct OnCueApp: App {
let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false) let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false)
do { do {
// #if DEBUG
// // Use an autorelease pool to make sure Swift deallocates the persistent
// // container before setting up the SwiftData stack.
// try autoreleasepool {
// let desc = NSPersistentStoreDescription(url: modelConfiguration.url)
// let opts = NSPersistentCloudKitContainerOptions(containerIdentifier: "iCloud.xyz.breadone.oncue")
// desc.cloudKitContainerOptions = opts
// // Load the store synchronously so it completes before initializing the
// // CloudKit schema.
// desc.shouldAddStoreAsynchronously = false
// if let mom = NSManagedObjectModel.makeManagedObjectModel(for: [OCProject.self, OCCard.self]) {
// let container = NSPersistentCloudKitContainer(name: "OnCue", managedObjectModel: mom)
// container.persistentStoreDescriptions = [desc]
// container.loadPersistentStores {_, err in
// if let err {
// fatalError(err.localizedDescription)
// }
// }
// // Initialize the CloudKit schema after the store finishes loading.
// try container.initializeCloudKitSchema()
// // Remove and unload the store from the persistent container.
// if let store = container.persistentStoreCoordinator.persistentStores.first {
// try container.persistentStoreCoordinator.remove(store)
// }
// }
// }
// #endif
return try ModelContainer(for: schema, configurations: [modelConfiguration]) return try ModelContainer(for: schema, configurations: [modelConfiguration])
} catch { } catch {
fatalError("Could not create ModelContainer: \(error)") fatalError("Could not create ModelContainer: \(error)")

View File

@ -10,29 +10,37 @@ import SwiftData
struct CardsView: View { struct CardsView: View {
let project: OCProject let project: OCProject
@State private var addNewCard = false @State private var editCard = false
@State private var newCardText = "" @State private var newCardText = ""
@State private var editCardText = ""
@Environment(\.modelContext) private var ctx @Environment(\.modelContext) private var ctx
@State private var showNoTextInNewCardError = false @State private var showNoTextInNewCardError = false
var body: some View { var body: some View {
List { List {
Section { // Section {
TextEditor(text: $newCardText) // TextEditor(text: $newCardText)
} header: { // } header: {
Text("Add new card") // Text("Add new card")
} // }
TextField("Add New Card", text: $newCardText, axis: .vertical)
.lineLimit(.max)
Section { Section {
ForEach(project.sortedCards) { card in ForEach(project.sortedCards) { card in
Text(card.content) Text(card.content)
.swipeActions {
Button(role: .destructive) { } label: { Image(systemName: "trash.fill") }
.background(Color.red)
Button { editCardText = card.content; editCard.toggle() } label: { Image(systemName: "pencil") }.tint(.blue)
}
} }
.onDelete(perform: deleteItems)
} header: { } header: {
Text("\(project.cards.count) \(project.cards.count == 1 ? "Card" : "Cards")") Text("\(project.cards?.count ?? 0) \(project.cards?.count ?? 0 == 1 ? "Card" : "Cards")")
} }
} }
.scrollDismissesKeyboard(.immediately)
.navigationTitle(project.name) .navigationTitle(project.name)
.navigationBarTitleDisplayMode(.inline) .navigationBarTitleDisplayMode(.inline)
.toolbar { .toolbar {
@ -55,8 +63,8 @@ struct CardsView: View {
} }
} }
.sheet(isPresented: $addNewCard) { .sheet(isPresented: $editCard) {
AddNewCardView(completionHandler: addNewCard) EditCardView(text: $editCardText) { editCard(txt: $0, offset: []) }
} }
.alert("No Text In Card", isPresented: $showNoTextInNewCardError) { .alert("No Text In Card", isPresented: $showNoTextInNewCardError) {
Button("OK", role: .cancel) {} Button("OK", role: .cancel) {}
@ -66,15 +74,22 @@ struct CardsView: View {
} }
func editCard(txt: String, offset: IndexSet) {
}
func addNewCard(txt: String) { func addNewCard(txt: String) {
guard txt != "" else { guard txt != "" else {
showNoTextInNewCardError.toggle() showNoTextInNewCardError.toggle()
return return
} }
let card = OCCard(content: txt, index: (project.sortedCards.last?.index ?? -1) + 1) // adds one to the index, unless there arent any cards in which case default to 0 // adds one to the index, unless there arent any cards in which case default to 0
project.cards.append(card) let card = OCCard(content: txt,
try! ctx.save() index: (project.sortedCards.last?.index ?? -1) + 1,
parent: project)
project.cards?.append(card)
try? ctx.save()
newCardText = "" newCardText = ""
} }

View File

@ -1,5 +1,5 @@
// //
// AddNewCardView.swift // EditCardView.swift
// OnCue // OnCue
// //
// Created by Pradyun Setti on 22/06/2024. // Created by Pradyun Setti on 22/06/2024.
@ -7,8 +7,8 @@
import SwiftUI import SwiftUI
struct AddNewCardView: View { struct EditCardView: View {
@State private var newCardText = "" @Binding var text: String
@Environment(\.dismiss) var dismiss @Environment(\.dismiss) var dismiss
let completionHandler: (String) -> Void let completionHandler: (String) -> Void
@ -16,10 +16,12 @@ struct AddNewCardView: View {
var body: some View { var body: some View {
NavigationView { NavigationView {
Form { Form {
TextEditor(text: $newCardText) // TextEditor(text: $text)
.frame(minHeight: 100) // .foregroundStyle(.secondary)
TextField("Edit Card Text", text: $text, axis: .vertical)
.lineLimit(.max)
} }
.navigationTitle("Add New Card") .navigationTitle("Edit Card")
.navigationBarTitleDisplayMode(.inline) .navigationBarTitleDisplayMode(.inline)
.toolbar { .toolbar {
ToolbarItem(placement: .topBarLeading) { ToolbarItem(placement: .topBarLeading) {
@ -28,7 +30,7 @@ struct AddNewCardView: View {
} }
ToolbarItem(placement: .topBarTrailing) { ToolbarItem(placement: .topBarTrailing) {
Button("Done") { Button("Done") {
completionHandler(newCardText) completionHandler(text)
dismiss() dismiss()
} }
} }
@ -38,5 +40,6 @@ struct AddNewCardView: View {
} }
#Preview { #Preview {
AddNewCardView(completionHandler: {_ in}) @State var test = "PreviewData.project.cards[4].con\ntentblabla\nksbdlaskdlaksd\naklsdbal\nkbsdal\nkbsdlasbd\nsdkfnsdlkfm"
return EditCardView(text: $test) { _ in }
} }

View File

@ -24,6 +24,7 @@ struct MainView: View {
ProjectListView(sort: SortDescriptor(\.creationDate, order: .reverse), ProjectListView(sort: SortDescriptor(\.creationDate, order: .reverse),
searchString: searchText, searchString: searchText,
color: filterColor) color: filterColor)
.swipeActions {}
} }
.searchable(text: $searchText) .searchable(text: $searchText)
.toolbar { .toolbar {
@ -52,7 +53,14 @@ struct MainView: View {
private func addItem(name: String, color: String) { private func addItem(name: String, color: String) {
withAnimation { withAnimation {
let newProject = OCProject(name: name, color: color) var newProject: OCProject
// if color == Color.clear.toHex()! {
// newProject = OCProject(name: name, color: themeColor)
// } else {
// newProject = OCProject(name: name, color: color)
// }
newProject = OCProject(name: name, color: color, cards: [])
modelContext.insert(newProject) modelContext.insert(newProject)
} }
} }
@ -62,6 +70,8 @@ private struct ProjectListView: View {
@Environment(\.modelContext) private var modelContext @Environment(\.modelContext) private var modelContext
@Query private var projects: [OCProject] @Query private var projects: [OCProject]
@AppStorage(Preferences.themeColour) var themeColor = Color.blue.toHex()!
init(sort: SortDescriptor<OCProject>, searchString: String, color: String) { init(sort: SortDescriptor<OCProject>, searchString: String, color: String) {
_projects = Query(filter: #Predicate { _projects = Query(filter: #Predicate {
if searchString.isEmpty { if searchString.isEmpty {
@ -78,11 +88,18 @@ private struct ProjectListView: View {
CardsView(project: project) CardsView(project: project)
} label: { } label: {
VStack(alignment: .leading) { VStack(alignment: .leading) {
if (project.color == Color.clear.toHex()!) {
Text("\(project.name)")
.bold()
.font(.title2)
.foregroundStyle(Color(hex: themeColor) ?? .blue)
} else {
Text("\(project.name)") Text("\(project.name)")
.bold() .bold()
.font(.title2) .font(.title2)
.foregroundStyle(Color(hex: project.color) ?? .white) .foregroundStyle(Color(hex: project.color) ?? .white)
Text("\(project.cards.count) \(project.cards.count == 1 ? "Card" : "Cards")") }
Text("\(project.cards?.count ?? 0) \(project.cards?.count ?? 0 == 1 ? "Card" : "Cards")")
} }
} }
.padding(.vertical, 3) .padding(.vertical, 3)

View File

@ -10,28 +10,41 @@ import SwiftUI
struct NewProjectForm: View { struct NewProjectForm: View {
@State private var newProjectName = "" @State private var newProjectName = ""
@State private var chosenColor: Color = .blue @State private var chosenColor = Color.clear
@Environment(\.dismiss) var dismiss @Environment(\.dismiss) var dismiss
let completionHandler: (String, String) -> Void let completionHandler: (String, String) -> Void
let availColours: [String] = {
var c = Constants.colors.map { $0.toHex()! }
c.insert("Theme", at: 0)
return c
}()
var body: some View { var body: some View {
NavigationView { NavigationView {
Form { Form {
TextField("Project Name", text: $newProjectName) TextField("Project Name", text: $newProjectName)
Section(header: Text("Project Colour")) { Section {
HStack { HStack {
ForEach(Constants.colors, id: \.self) { clr in ForEach(Constants.colors, id: \.self) { color in
ColorChooserCircle(color: clr) if chosenColor == color {
.padding(.vertical) ZStack {
.onTapGesture { Circle()
self.chosenColor = clr .foregroundStyle(color)
Image(systemName: "checkmark")
}
.onTapGesture { chooseColour(color) }
} else {
Circle()
.foregroundStyle(color)
.onTapGesture { chooseColour(color) }
} }
} }
} }
} header: { Text("Project Colour") } footer: { Text("Leave unselected to use theme colour in settings" )}
} }
} .navigationTitle("Add New Project")
.navigationTitle("Add New Project").foregroundStyle(chosenColor)
.navigationBarTitleDisplayMode(.inline) .navigationBarTitleDisplayMode(.inline)
.toolbar { .toolbar {
ToolbarItem(placement: .topBarLeading) { ToolbarItem(placement: .topBarLeading) {
@ -47,16 +60,13 @@ struct NewProjectForm: View {
} }
} }
} }
private func chooseColour(_ color: Color) {
if color == chosenColor {
chosenColor = .clear
} else {
chosenColor = color
} }
struct ColorChooserCircle: View {
var color: Color
var body: some View {
Circle()
.strokeBorder(Color.gray,lineWidth: 2)
.background(Circle().foregroundColor(color))
.frame(minHeight: 25)
} }
} }

View File

@ -9,9 +9,21 @@ import SwiftUI
struct ProjectSlideshowView: View { struct ProjectSlideshowView: View {
let project: OCProject let project: OCProject
@State private var textSize = 25.0 @AppStorage(Preferences.cueDefaultSize) private var textSize = 25.0
@AppStorage(Preferences.showTimers) var showTimers = true
@StateObject private var timer = TimerManager()
var body: some View { var body: some View {
if showTimers {
mainView
.navigationTitle(timer.formattedTime)
.onAppear { timer.startTimer() }
} else {
mainView
}
}
var mainView: some View {
TabView() { TabView() {
ForEach(project.sortedCards) { card in ForEach(project.sortedCards) { card in
VStack(alignment: .leading) { VStack(alignment: .leading) {
@ -22,7 +34,6 @@ struct ProjectSlideshowView: View {
.frame(height: 550) .frame(height: 550)
Spacer() Spacer()
} }
.navigationTitle("\(card.index+1)")
.navigationBarTitleDisplayMode(.inline) .navigationBarTitleDisplayMode(.inline)
} }
} }

View File

@ -23,6 +23,7 @@ struct SettingsView: View {
// @State private var themesColor: Color = .blue // @State private var themesColor: Color = .blue
@AppStorage(Preferences.themeColour) var themesColor = Color.blue.toHex()! @AppStorage(Preferences.themeColour) var themesColor = Color.blue.toHex()!
@AppStorage(Preferences.showTimers) var showTimers = true
var body: some View { var body: some View {
NavigationView { NavigationView {
@ -45,7 +46,11 @@ struct SettingsView: View {
var generalSettings: some View { var generalSettings: some View {
Section { Section {
HStack {
Text("Theme Color") Text("Theme Color")
// TODO: redo this as a grid
ScrollView(.horizontal) {
HStack { HStack {
ForEach(Constants.colors, id: \.self) { color in ForEach(Constants.colors, id: \.self) { color in
if themesColor == color.toHex()! { if themesColor == color.toHex()! {
@ -63,6 +68,10 @@ struct SettingsView: View {
} }
} }
} }
}
.scrollIndicators(.hidden)
}
Toggle("Show Timers", isOn: $showTimers)
} header: { Text("General") } } header: { Text("General") }
} }

View File

@ -1,6 +1,7 @@
{ {
"images" : [ "images" : [
{ {
"filename" : "oncue_icon.png",
"idiom" : "universal", "idiom" : "universal",
"platform" : "watchos", "platform" : "watchos",
"size" : "1024x1024" "size" : "1024x1024"

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

View File

@ -7,6 +7,7 @@
import SwiftUI import SwiftUI
import SwiftData import SwiftData
import CoreData
@main @main
struct OnCuePresenter_Watch_AppApp: App { struct OnCuePresenter_Watch_AppApp: App {
@ -14,11 +15,37 @@ struct OnCuePresenter_Watch_AppApp: App {
let schema = Schema([ let schema = Schema([
OCProject.self, OCProject.self,
OCCard.self, OCCard.self,
// Item.self,
]) ])
let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false) let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false)
do { do {
// #if DEBUG
// // Use an autorelease pool to make sure Swift deallocates the persistent
// // container before setting up the SwiftData stack.
// try autoreleasepool {
// let desc = NSPersistentStoreDescription(url: modelConfiguration.url)
// let opts = NSPersistentCloudKitContainerOptions(containerIdentifier: "iCloud.xyz.breadone.oncue")
// desc.cloudKitContainerOptions = opts
// // Load the store synchronously so it completes before initializing the
// // CloudKit schema.
// desc.shouldAddStoreAsynchronously = false
// if let mom = NSManagedObjectModel.makeManagedObjectModel(for: [OCProject.self, OCCard.self]) {
// let container = NSPersistentCloudKitContainer(name: "OnCue", managedObjectModel: mom)
// container.persistentStoreDescriptions = [desc]
// container.loadPersistentStores {_, err in
// if let err {
// fatalError(err.localizedDescription)
// }
// }
// // Initialize the CloudKit schema after the store finishes loading.
// try container.initializeCloudKitSchema()
// // Remove and unload the store from the persistent container.
// if let store = container.persistentStoreCoordinator.persistentStores.first {
// try container.persistentStoreCoordinator.remove(store)
// }
// }
// }
// #endif
return try ModelContainer(for: schema, configurations: [modelConfiguration]) return try ModelContainer(for: schema, configurations: [modelConfiguration])
} catch { } catch {
fatalError("Could not create ModelContainer: \(error)") fatalError("Could not create ModelContainer: \(error)")

View File

@ -12,7 +12,7 @@ struct CueCardViewPresenter: View {
var body: some View { var body: some View {
TabView() { TabView() {
ForEach(project.cards) { card in ForEach(project.cards ?? []) { card in
CueCardView(card: card) CueCardView(card: card)
} }
} }

View File

@ -16,37 +16,19 @@ struct MainViewPresenter: View {
@State private var addNewProject = false @State private var addNewProject = false
var body: some View { var body: some View {
NavigationSplitView { NavigationView {
List { List {
ForEach(items) { project in ForEach(items) { project in
NavigationLink { NavigationLink {
CueCardViewPresenter(project: project) CueCardViewPresenter(project: project)
} label: { } label: {
VStack(alignment: .leading) { ProjectCard(project: project)
Text("\(project.name)")
.bold()
.font(.title2)
.foregroundStyle(Color(hex: project.color) ?? .white)
Text("\(project.cards.count) \(project.cards.count == 1 ? "Card" : "Cards")")
}
} }
.padding(.vertical, 3) .padding(.vertical, 3)
} }
} }
.toolbar {
ToolbarItem(placement: .primaryAction) {
Button {
} label: {
Label("Sync", systemImage: "arrow.triangle.2.circlepath")
}
}
}
.navigationTitle("Projects") .navigationTitle("Projects")
} detail: {
Text("Select an item")
} }
} }
} }
@ -60,3 +42,25 @@ struct MainViewPresenter: View {
return MainViewPresenter() return MainViewPresenter()
.modelContainer(container) .modelContainer(container)
} }
struct ProjectCard: View {
@AppStorage(Preferences.themeColour) var themeColor = Color.blue.toHex()!
let project: OCProject
var body: some View {
VStack(alignment: .leading) {
if (project.color == Color.clear.toHex()!) {
Text("\(project.name)")
.bold()
.font(.title2)
.foregroundStyle(Color(hex: themeColor) ?? .blue)
} else {
Text("\(project.name)")
.bold()
.font(.title2)
.foregroundStyle(Color(hex: project.color) ?? .white)
}
Text("\(project.cards?.count ?? 0) \(project.cards?.count ?? 0 == 1 ? "Card" : "Cards")")
}
}
}

10
OnCuePresenter-Info.plist Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIBackgroundModes</key>
<array>
<string>remote-notification</string>
</array>
</dict>
</plist>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>development</string>
<key>com.apple.developer.icloud-container-identifiers</key>
<array>
<string>iCloud.xyz.breadone.oncue</string>
</array>
<key>com.apple.developer.icloud-services</key>
<array>
<string>CloudKit</string>
</array>
</dict>
</plist>

View File

@ -9,5 +9,4 @@ import SwiftUI
public struct Constants { public struct Constants {
static let colors: [Color] = [.red, .orange, .yellow, .green, .blue, .indigo] static let colors: [Color] = [.red, .orange, .yellow, .green, .blue, .indigo]
static let colorText = ["None", "Red", "Orange", "Yellow", "Green", "Blue", "Indigo"]
} }

View File

@ -18,4 +18,6 @@ public struct Preferences {
static let cueDefaultSize = "cueDefaultSize" static let cueDefaultSize = "cueDefaultSize"
static let themeColour = "themeColour" static let themeColour = "themeColour"
static let showTimers = "showTimers"
} }

View File

@ -12,16 +12,5 @@ public struct PreviewData {
private static let lorem = "colon three" private static let lorem = "colon three"
static let project = OCProject(name: "Test Project", color: "007AFF", cards: [ static let project = OCProject(name: "Test Project", color: "007AFF", tCards: Array<String>(repeating: lorem, count: 10) )
OCCard(content: lorem, index: 0),
OCCard(content: lorem, index: 1),
OCCard(content: lorem, index: 2),
OCCard(content: loreml, index: 3),
OCCard(content: lorem, index: 4),
OCCard(content: lorem, index: 5),
OCCard(content: lorem, index: 6),
OCCard(content: lorem, index: 7),
OCCard(content: lorem, index: 8),
OCCard(content: lorem, index: 9),
])
} }

BIN
oncue_icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

BIN
oncue_icon.pxd Normal file

Binary file not shown.