Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Promptly.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = Promptly/Promptly.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 20;
CURRENT_PROJECT_VERSION = 5;
DEVELOPMENT_TEAM = 8Y3J97SYZG;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
Expand All @@ -444,7 +444,7 @@
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 15.5;
MARKETING_VERSION = 1.0.4;
MARKETING_VERSION = 1.0.5;
PRODUCT_BUNDLE_IDENTIFIER = com.urbanmechanicsltd.Promptly;
PRODUCT_NAME = "$(TARGET_NAME)";
REGISTER_APP_GROUPS = YES;
Expand All @@ -464,7 +464,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = Promptly/Promptly.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 20;
CURRENT_PROJECT_VERSION = 5;
DEVELOPMENT_TEAM = 8Y3J97SYZG;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
Expand All @@ -489,7 +489,7 @@
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 15.5;
MARKETING_VERSION = 1.0.4;
MARKETING_VERSION = 1.0.5;
PRODUCT_BUNDLE_IDENTIFIER = com.urbanmechanicsltd.Promptly;
PRODUCT_NAME = "$(TARGET_NAME)";
REGISTER_APP_GROUPS = YES;
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
<key>Promptly-WatchOS Watch App.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>1</integer>
<integer>0</integer>
</dict>
<key>Promptly.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
<integer>1</integer>
</dict>
</dict>
</dict>
Expand Down
26 changes: 1 addition & 25 deletions Promptly/PromptlyApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,40 +53,16 @@ extension PromptlyApp: WhatsNewCollectionProvider {
/// A WhatsNewCollection
var whatsNewCollection: WhatsNewCollection {
WhatsNew(
version: "1.0.4",
version: "1.0.5",
title: "DSMPrompt",
features: [
.init(
image: .init(
systemName: "square.and.arrow.down.on.square",
foregroundColor: .orange
),
title: "Import & Export Show Files",
subtitle: "Import and export show files to have manual backups / share between members."
),
.init(
image: .init(
systemName: "wand.and.stars",
foregroundColor: .cyan
),
title: "What's New View",
subtitle: "Find out what's changed between versions."
),
.init(
image: .init(
systemName: "hammer",
foregroundColor: .gray
),
title: "Bug Fixes",
subtitle: "Bug fixes and stability improvements."
),
.init(
image: .init(
systemName: "hammer",
foregroundColor: .red
),
title: "PDF Rendering",
subtitle: "Fixed bug where if you were in dark mode the text would not show in PDF exports."
)
],
primaryAction: .init(
Expand Down
182 changes: 110 additions & 72 deletions Promptly/Views/Scripts/Edit Contents/EditScriptView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ struct EditScriptView: View {
@State private var lineBeingFlagged: ScriptLine?
@StateObject private var refreshTrigger = RefreshTrigger()

@State private var lineGroups: [LineGroup] = []


var sortedLines: [ScriptLine] {
script.lines.sorted { $0.lineNumber < $1.lineNumber }
}
Expand Down Expand Up @@ -126,7 +129,7 @@ struct EditScriptView: View {
}
}
.sheet(isPresented: $showingFlagEditor) {
if selectedLines.count == 1, let line = lineBeingFlagged {
if selectedLines.count == 1, let line = selectedLinesArray.first {
FlagEditorView(line: line) {
try? modelContext.save()
refreshTrigger.refresh()
Expand Down Expand Up @@ -195,6 +198,9 @@ struct EditScriptView: View {
}
.navigationTitle(Text(script.name))
.navigationBarTitleDisplayMode(.inline)
.task {
lineGroups = await groupLinesBySection(lines: sortedLines, sections: sortedSections)
}
}

// MARK: - View Components
Expand Down Expand Up @@ -287,95 +293,127 @@ struct EditScriptView: View {
}

private var scriptContentView: some View {
ScrollView {
LazyVStack(spacing: 8) {
ForEach(groupLinesBySection(), id: \.id) { group in
if let section = group.section {
SectionHeaderView(section: section)
.padding(.horizontal)
.padding(.top, 8)
}

ForEach(group.lines, id: \.id) { line in
EditableScriptLineView(
line: line,
isEditing: isEditing,
isSelected: selectedLines.contains(line.id),
isEditingText: editingLineId == line.id,
isSelectingForSection: isSelectingLineForSection,
editingText: $editingText
) { selectedLine in
if isSelectingLineForSection {
selectedLineForSection = selectedLine
showingLineConfirmation = true
isSelectingLineForSection = false
} else {
toggleLineSelection(selectedLine)
}
} onStartTextEdit: { lineToEdit in
startEditing(line: lineToEdit)
} onFinishTextEdit: { newText in
finishEditing(newText: newText)
} onInsertAfter: { lineToInsertAfter in
insertAfterLineNumber = lineToInsertAfter.lineNumber
showingAddLine = true
} onEditFlags: { lineToFlag in
lineBeingFlagged = lineToFlag
showingFlagEditor = true
}
}
ScriptTableView(
lineGroups: lineGroups,
isEditing: isEditing,
selectedLines: selectedLines,
editingLineId: editingLineId,
isSelectingForSection: isSelectingLineForSection,
editingText: $editingText,
onToggleSelection: { selectedLine in
if isSelectingLineForSection {
selectedLineForSection = selectedLine
showingLineConfirmation = true
isSelectingLineForSection = false
} else {
toggleLineSelection(selectedLine)
}
},
onStartTextEdit: { lineToEdit in
startEditing(line: lineToEdit)
},
onFinishTextEdit: { newText in
finishEditing(newText: newText)
},
onInsertAfter: { lineToInsertAfter in
insertAfterLineNumber = lineToInsertAfter.lineNumber
showingAddLine = true
},
onEditFlags: { lineToFlag in
lineBeingFlagged = lineToFlag
showingFlagEditor = true
},
onSectionTap: { section in
print("sec tap")
// dismiss()
// NotificationCenter.default.post(
// name: NSNotification.Name("ScrollToSection"),
// object: section.id
// )
}
.padding()
}
)
}

// MARK: - Actions

private func groupLinesBySection() -> [LineGroup] {
// For performance, only process visible sections
let maxVisibleSections = 20
let limitedSections = Array(sortedSections.prefix(maxVisibleSections))
private func groupLinesBySection(lines: [ScriptLine], sections: [ScriptSection]) async -> [LineGroup] {
guard !lines.isEmpty else { return [] }
guard !sections.isEmpty else {
return [LineGroup(section: nil, lines: lines)]
}

let sectionRanges = await withTaskGroup(of: (Int, Int, Int).self) { group in
for (index, section) in sections.enumerated() {
group.addTask {
let startLine = section.startLineNumber
let endLine = (index + 1 < sections.count) ?
sections[index + 1].startLineNumber - 1 :
lines.last?.lineNumber ?? startLine
return (index, startLine, endLine)
}
}

var ranges: [(Int, Int, Int)] = []
for await range in group {
ranges.append(range)
}
return ranges.sorted { $0.0 < $1.0 }
}

var groups: [LineGroup] = []
var lastProcessedLine = 0
var processedLines = Set<Int>()

for section in limitedSections {
let startLine = section.startLineNumber
for (index, startLine, endLine) in sectionRanges {
let section = sections[index]

// Find the next section's start line (or end of script)
let nextSectionStart = sortedSections.first {
$0.startLineNumber > startLine
}?.startLineNumber ?? (sortedLines.last?.lineNumber ?? 0) + 1
let startIdx = binarySearchStart(lines: lines, lineNumber: startLine)
let endIdx = binarySearchEnd(lines: lines, lineNumber: endLine)

// Add ungrouped lines before this section
if startLine > lastProcessedLine + 1 {
let ungroupedLines = sortedLines.filter {
$0.lineNumber > lastProcessedLine && $0.lineNumber < startLine
}
if !ungroupedLines.isEmpty {
groups.append(LineGroup(section: nil, lines: ungroupedLines))
}
}
guard startIdx < lines.count && endIdx >= 0 else { continue }

// Add this section's lines (only up to next section)
let sectionLines = sortedLines.filter {
$0.lineNumber >= startLine && $0.lineNumber < nextSectionStart
}
let sectionLines = lines[startIdx...min(endIdx, lines.count - 1)]
.filter { !processedLines.contains($0.lineNumber) }

if !sectionLines.isEmpty {
groups.append(LineGroup(section: section, lines: sectionLines))
lastProcessedLine = sectionLines.last?.lineNumber ?? lastProcessedLine
groups.append(LineGroup(section: section, lines: Array(sectionLines)))
processedLines.formUnion(sectionLines.map { $0.lineNumber })
}
}

// Add remaining ungrouped lines
let remainingLines = sortedLines.filter { $0.lineNumber > lastProcessedLine }
if !remainingLines.isEmpty {
groups.append(LineGroup(section: nil, lines: remainingLines))
let ungroupedLines = lines.filter { !processedLines.contains($0.lineNumber) }
if !ungroupedLines.isEmpty {
groups.append(LineGroup(section: nil, lines: ungroupedLines))
}

return groups
return groups.sorted {
($0.lines.first?.lineNumber ?? 0) < ($1.lines.first?.lineNumber ?? 0)
}
}

private func binarySearchStart(lines: [ScriptLine], lineNumber: Int) -> Int {
var left = 0, right = lines.count - 1
while left <= right {
let mid = (left + right) / 2
if lines[mid].lineNumber >= lineNumber {
right = mid - 1
} else {
left = mid + 1
}
}
return left
}

private func binarySearchEnd(lines: [ScriptLine], lineNumber: Int) -> Int {
var left = 0, right = lines.count - 1
while left <= right {
let mid = (left + right) / 2
if lines[mid].lineNumber <= lineNumber {
left = mid + 1
} else {
right = mid - 1
}
}
return right
}

private func updateSectionsAfterLineChange(at changePoint: Int, delta: Int) {
Expand Down Expand Up @@ -667,7 +705,7 @@ struct EditableScriptLineView: View {

private var backgroundOpacity: Double {
if isSelected && isEditing {
return 0.6
return 1.0
} else if line.isMarked {
return 0.3
} else {
Expand Down
53 changes: 19 additions & 34 deletions Promptly/Views/Scripts/ScriptEditorView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -180,41 +180,26 @@ struct ScriptEditorView: View {
}

private var scriptContentView: some View {
ScrollViewReader { proxy in
ScrollView {
LazyVStack(alignment: .leading, spacing: 12) {
ForEach(lineGroups, id: \.id) { group in
if let section = group.section {
SectionHeaderView(section: section)
.padding(.horizontal, 16)
.padding(.top, 8)
}

ForEach(group.lines, id: \.id) { line in
ScriptLineView(
line: line,
isSelected: selectedLine?.id == line.id,
isEditing: editingLineId == line.id,
editingText: $editingText,
onElementTap: { element in
handleElementTap(element: element, line: line)
},
onLineTap: {
handleLineTap(line: line)
},
onEditComplete: { newText in
updateLineContent(line: line, newText: newText)
},
onCueDelete: handleCueDelete,
onCueEdit: handleCueEdit
)
.id("line-\(line.id)")
}
}
}
.padding()
ScriptTableView(
lineGroups: lineGroups,
selectedLine: selectedLine,
editingLineId: editingLineId,
editingText: $editingText,
onElementTap: { element, line in
handleElementTap(element: element, line: line)
},
onLineTap: { line in
handleLineTap(line: line)
},
onEditComplete: { line, newText in
updateLineContent(line: line, newText: newText)
},
onCueDelete: handleCueDelete,
onCueEdit: handleCueEdit,
onSectionTap: { section in

}
}
)
}

private func handleElementTap(element: LineElement, line: ScriptLine) {
Expand Down
Loading
Loading