Added timers for the cue card view (can be controlled)
minor other adjustments
This commit is contained in:
parent
d4b1226ef3
commit
1f23a55b51
@ -7,6 +7,8 @@
|
|||||||
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 */; };
|
||||||
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 */; };
|
||||||
@ -63,6 +65,7 @@
|
|||||||
/* 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>"; };
|
||||||
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>"; };
|
||||||
@ -175,6 +178,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>";
|
||||||
@ -339,6 +343,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;
|
||||||
};
|
};
|
||||||
@ -352,6 +357,7 @@
|
|||||||
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 */,
|
||||||
);
|
);
|
||||||
|
42
OnCue/Model/TimerManager.swift
Normal file
42
OnCue/Model/TimerManager.swift
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
@ -32,7 +32,7 @@ struct CardsView: View {
|
|||||||
.swipeActions {
|
.swipeActions {
|
||||||
Button(role: .destructive) { } label: { Image(systemName: "trash.fill") }
|
Button(role: .destructive) { } label: { Image(systemName: "trash.fill") }
|
||||||
.background(Color.red)
|
.background(Color.red)
|
||||||
Button { editCardText = card.content; editCard.toggle() } label: { Image(systemName: "pencil") }
|
Button { editCardText = card.content; editCard.toggle() } label: { Image(systemName: "pencil") }.tint(.blue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} header: {
|
} header: {
|
||||||
|
@ -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,8 +34,7 @@ struct ProjectSlideshowView: View {
|
|||||||
.frame(height: 550)
|
.frame(height: 550)
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
.navigationTitle("\(card.index+1)")
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .always))
|
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .always))
|
||||||
@ -35,7 +46,7 @@ struct ProjectSlideshowView: View {
|
|||||||
} label: {
|
} label: {
|
||||||
Image(systemName: "ellipsis.circle")
|
Image(systemName: "ellipsis.circle")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
ToolbarItem(placement: .topBarTrailing) {
|
ToolbarItem(placement: .topBarTrailing) {
|
||||||
NavigationLink(destination: { CardsView(project: project) }) {
|
NavigationLink(destination: { CardsView(project: project) }) {
|
||||||
|
@ -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,24 +46,31 @@ struct SettingsView: View {
|
|||||||
|
|
||||||
var generalSettings: some View {
|
var generalSettings: some View {
|
||||||
Section {
|
Section {
|
||||||
Text("Theme Color")
|
|
||||||
HStack {
|
HStack {
|
||||||
ForEach(Constants.colors, id: \.self) { color in
|
Text("Theme Color")
|
||||||
if themesColor == color.toHex()! {
|
// TODO: redo this as a grid
|
||||||
ZStack {
|
ScrollView(.horizontal) {
|
||||||
Circle()
|
HStack {
|
||||||
.foregroundStyle(color)
|
ForEach(Constants.colors, id: \.self) { color in
|
||||||
// .strokeBorder(Color.white,lineWidth: 4)
|
if themesColor == color.toHex()! {
|
||||||
// .background(Circle().foregroundStyle(color))
|
ZStack {
|
||||||
Image(systemName: "checkmark")
|
Circle()
|
||||||
|
.foregroundStyle(color)
|
||||||
|
// .strokeBorder(Color.white,lineWidth: 4)
|
||||||
|
// .background(Circle().foregroundStyle(color))
|
||||||
|
Image(systemName: "checkmark")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Circle()
|
||||||
|
.foregroundStyle(color)
|
||||||
|
.onTapGesture { themesColor = color.toHex()! }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Circle()
|
|
||||||
.foregroundStyle(color)
|
|
||||||
.onTapGesture { themesColor = color.toHex()! }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Toggle("Show Timers", isOn: $showTimers)
|
||||||
} header: { Text("General") }
|
} header: { Text("General") }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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"
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user