Files
ShhShell/ShhShell/Views/Settings/SettingsView.swift
neon443 a7783eab47 added backgrounder.swift
more stuff
and stuff

tried to add background location tracking
 - it didnt work
2025-08-24 20:38:12 +01:00

180 lines
4.7 KiB
Swift

//
// SettingsView.swift
// ShhShell
//
// Created by neon443 on 19/08/2025.
//
import SwiftUI
import SwiftTerm
struct SettingsView: View {
@ObservedObject var hostsManager: HostsManager
@ObservedObject var keyManager: KeyManager
@State private var blinkCursor: Int = 0
@State var blinkTimer: Timer?
func startBlinkingIfNeeded() {
if hostsManager.settings.cursorType.blink {
blinkTimer?.invalidate()
blinkTimer = nil
blinkTimer = Timer(timeInterval: 1, repeats: true) { timer in
Task { @MainActor in
blinkCursor += 1
}
}
RunLoop.main.add(blinkTimer!, forMode: .common)
} else {
blinkTimer?.invalidate()
if blinkCursor % 2 != 0 {
blinkCursor += 1
}
}
}
var body: some View {
ZStack {
hostsManager.selectedTheme.background.suiColor.opacity(0.7)
.ignoresSafeArea(.all)
List {
Section("Terminal") {
VStack(alignment: .leading) {
HStack {
Label("Scrollback", systemImage: "scroll")
Spacer()
Text("\(Int(hostsManager.settings.scrollback))")
.contentTransition(.numericText())
}
Slider(
value: $hostsManager.settings.scrollback,
in: 250...10_000,
step: 250
)
}
}
Section("Cursor") {
ZStack(alignment: .leading) {
HStack(spacing: 0) {
Text("neon443")
.font(.largeTitle).monospaced()
.foregroundStyle(.terminalGreen)
Text(" ~ ")
.font(.largeTitle).monospaced()
.foregroundStyle(.blue)
Text(">")
.font(.largeTitle).monospaced()
.foregroundStyle(.blue)
}
Group {
switch hostsManager.settings.cursorType.cursorShape {
case .block:
Rectangle()
.frame(width: 20, height: 40)
case .bar:
Rectangle()
.frame(width: 4, height: 40)
case .underline:
Rectangle()
.frame(width: 20, height: 4)
.padding(.top, 36)
}
}
.padding(.leading, 248)
.onChange(of: hostsManager.settings.cursorType.blink) { _ in
startBlinkingIfNeeded()
}
.onAppear() {
startBlinkingIfNeeded()
}
.opacity(blinkCursor % 2 == 0 ? 1 : 0)
.animation(
Animation.spring(duration: 1),
value: blinkCursor
)
}
Picker("Blink", selection: $hostsManager.settings.cursorType.blink) {
Text("Blink").tag(true)
Text("Steady").tag(false)
}
.pickerStyle(.segmented)
Picker("", selection: $hostsManager.settings.cursorType.cursorShape) {
ForEach(CursorShape.allCases, id: \.self) { type in
Text(type.description).tag(type)
}
}
.pickerStyle(.inline)
.labelsHidden()
}
Toggle("location persistence", systemImage: "location.fill", isOn: $hostsManager.settings.locationPersist)
.onChange(of: hostsManager.settings.locationPersist) { _ in
if hostsManager.settings.locationPersist && !Backgrounder.shared.checkPermsStatus() {
Backgrounder.shared.requestPerms()
}
}
Toggle("bell sound", systemImage: "bell.and.waves.left.and.right", isOn: $hostsManager.settings.bellSound)
Toggle("bell haptic",systemImage: "iphone.radiowaves.left.and.right", isOn: $hostsManager.settings.bellHaptic)
Toggle("keep screen awake", systemImage: "cup.and.saucer.fill", isOn: $hostsManager.settings.caffeinate)
Picker("terminal filter", selection: $hostsManager.settings.filter) {
ForEach(TerminalFilter.allCases, id: \.self) { filter in
Text(filter.description).tag(filter)
}
}
.pickerStyle(.inline)
Section("App Icon") {
ScrollView(.horizontal) {
HStack {
ForEach(AppIcon.allCases, id: \.self) { icon in
let isSelected = hostsManager.settings.appIcon == icon
ZStack(alignment: .top) {
RoundedRectangle(cornerRadius: 21.5)
.foregroundStyle(.gray.opacity(0.5))
.opacity(isSelected ? 1 : 0)
VStack(spacing: 0) {
icon.image
.resizable().scaledToFit()
.clipShape(RoundedRectangle(cornerRadius: 16.5))
.padding(5)
Text(icon.description).tag(icon)
.font(.caption)
.padding(.bottom, 5)
.padding(.horizontal, 5)
.multilineTextAlignment(.center)
}
}
.frame(maxWidth: 85, maxHeight: 110)
.onTapGesture {
withAnimation {
hostsManager.settings.appIcon = icon
hostsManager.setAppIcon()
}
}
}
}
}
}
}
.listStyle(.sidebar)
.scrollContentBackground(.hidden)
.onChange(of: hostsManager.settings) { _ in
hostsManager.saveSettings()
}
}
}
}
#Preview {
SettingsView(
hostsManager: HostsManager(previews: true),
keyManager: KeyManager()
)
}