More UI Stuff

This commit is contained in:
Stephen B 2025-09-07 20:50:04 -04:00
parent 9b16cf35de
commit f7e83376e2
2 changed files with 84 additions and 30 deletions

View file

@ -25,7 +25,7 @@ struct ScriptEditorView: View {
text: $scriptContent,
position: $position,
messages: $messages,
language: .swift()
language: .swift() // ← JavaScript syntax highlighting
)
.font(.system(.footnote, design: .monospaced))
.frame(maxWidth: .infinity, maxHeight: .infinity)
@ -36,22 +36,18 @@ struct ScriptEditorView: View {
Divider()
HStack {
Button("Cancel") {
// Equal-width, centered, rounded-rectangle buttons
HStack(spacing: 12) {
WideGlassyButton(title: "Cancel", systemImage: "xmark") {
dismiss()
}
.buttonStyle(.bordered)
Spacer()
Button("Save") {
WideGlassyButton(title: "Save", systemImage: "checkmark") {
saveScript()
dismiss()
}
.buttonStyle(.borderedProminent)
.foregroundColor(.black)
}
.padding()
.padding(.horizontal)
.padding(.vertical, 12)
}
.navigationTitle(scriptURL.lastPathComponent)
.navigationBarTitleDisplayMode(.inline)
@ -67,3 +63,39 @@ struct ScriptEditorView: View {
try? scriptContent.write(to: scriptURL, atomically: true, encoding: .utf8)
}
}
// MARK: - Equal-width rounded-rectangle button (centered content)
private struct WideGlassyButton: View {
let title: String
let systemImage: String
let action: () -> Void
var body: some View {
Button(action: action) {
HStack(spacing: 8) {
Image(systemName: systemImage)
.imageScale(.medium)
.font(.body.weight(.semibold))
Text(title)
.font(.body.weight(.semibold))
.lineLimit(1)
.minimumScaleFactor(0.85)
}
.frame(maxWidth: .infinity, alignment: .center) // center label+icon
.padding(.vertical, 10)
.padding(.horizontal, 14)
}
.frame(height: 44)
.frame(maxWidth: .infinity) // equal widths within HStack
.background(
RoundedRectangle(cornerRadius: 12, style: .continuous)
.fill(.ultraThinMaterial)
)
.overlay(
RoundedRectangle(cornerRadius: 12, style: .continuous)
.strokeBorder(Color.white.opacity(0.12), lineWidth: 1)
)
.contentShape(RoundedRectangle(cornerRadius: 12, style: .continuous))
.buttonStyle(.plain)
}
}

View file

@ -127,9 +127,7 @@ struct ScriptListView: View {
Button("Cancel", role: .cancel) { }
}
.alert("Delete Script?", isPresented: $showDeleteConfirmation, presenting: pendingDelete) { script in
Button("Delete", role: .destructive) {
deleteScript(script)
}
Button("Delete", role: .destructive) { deleteScript(script) }
Button("Cancel", role: .cancel) { pendingDelete = nil }
} message: { script in
Text("Are you sure you want to delete \(script.lastPathComponent)? This cannot be undone.")
@ -158,23 +156,13 @@ struct ScriptListView: View {
.strokeBorder(Color.white.opacity(0.12), lineWidth: 1)
)
HStack {
Button {
// Equal-width rounded-rectangle buttons with centered content
HStack(spacing: 12) {
WideGlassyButton(title: "New", systemImage: "doc.badge.plus") {
showNewFileAlert = true
} label: {
Label("New", systemImage: "doc.badge.plus")
.font(.callout.weight(.semibold))
.padding(10)
.background(.ultraThinMaterial, in: Capsule())
}
Button {
WideGlassyButton(title: "Import", systemImage: "tray.and.arrow.down") {
showImporter = true
} label: {
Label("Import", systemImage: "tray.and.arrow.down")
.font(.callout.weight(.semibold))
.padding(10)
.background(.ultraThinMaterial, in: Capsule())
}
}
}
@ -259,9 +247,8 @@ struct ScriptListView: View {
do {
if exists && !isDir.boolValue {
try FileManager.default.removeItem(at: dir)
exists = false
}
if !exists {
if !exists || !isDir.boolValue {
try FileManager.default.createDirectory(at: dir, withIntermediateDirectories: true)
if let bundleURL = Bundle.main.url(forResource: "attachDetach", withExtension: "js") {
let dest = dir.appendingPathComponent("attachDetach.js")
@ -370,3 +357,38 @@ struct ScriptListView: View {
}
}
}
// MARK: - Equal-width rounded-rectangle button (centered content)
private struct WideGlassyButton: View {
let title: String
let systemImage: String
let action: () -> Void
var body: some View {
Button(action: action) {
HStack(spacing: 8) {
Image(systemName: systemImage)
.imageScale(.medium)
.font(.body.weight(.semibold))
Text(title)
.font(.body.weight(.semibold))
.lineLimit(1)
.minimumScaleFactor(0.8)
}
.frame(maxWidth: .infinity, alignment: .center) // center contents horizontally
.padding(.horizontal, 14)
}
.frame(height: 44)
.frame(maxWidth: .infinity) // make both buttons equal width
.background(
RoundedRectangle(cornerRadius: 12, style: .continuous)
.fill(.ultraThinMaterial)
)
.overlay(
RoundedRectangle(cornerRadius: 12, style: .continuous)
.strokeBorder(Color.white.opacity(0.12), lineWidth: 1)
)
.contentShape(RoundedRectangle(cornerRadius: 12, style: .continuous))
.buttonStyle(.plain)
}
}