ios: initial commit

This commit is contained in:
2026-02-20 00:09:02 -08:00
parent b91b03b74f
commit c47646a48c
24 changed files with 3406 additions and 19 deletions

View File

@@ -0,0 +1,113 @@
import Observation
import SwiftUI
struct SybilConnectionView: View {
@Bindable var viewModel: SybilViewModel
var body: some View {
@Bindable var settings = viewModel.settings
VStack(spacing: 20) {
HStack(alignment: .top, spacing: 12) {
Image(systemName: "shield.lefthalf.filled")
.font(.title3.weight(.semibold))
.foregroundStyle(SybilTheme.primary)
.frame(width: 34, height: 34)
.background(
RoundedRectangle(cornerRadius: 10)
.fill(SybilTheme.primary.opacity(0.18))
)
VStack(alignment: .leading, spacing: 4) {
Text("Connect to Sybil")
.font(.title3.weight(.semibold))
.foregroundStyle(SybilTheme.text)
Text("Point the app at your backend and sign in with ADMIN_TOKEN if token mode is enabled.")
.font(.callout)
.foregroundStyle(SybilTheme.textMuted)
.fixedSize(horizontal: false, vertical: true)
}
}
VStack(alignment: .leading, spacing: 10) {
Text("API URL")
.font(.caption.weight(.semibold))
.foregroundStyle(SybilTheme.textMuted)
TextField("http://127.0.0.1:8787/api", text: $settings.apiBaseURL)
.textInputAutocapitalization(.never)
.autocorrectionDisabled()
.keyboardType(.URL)
.padding(12)
.background(
RoundedRectangle(cornerRadius: 12)
.fill(SybilTheme.surface)
)
.overlay(
RoundedRectangle(cornerRadius: 12)
.stroke(SybilTheme.border, lineWidth: 1)
)
Text("Admin Token")
.font(.caption.weight(.semibold))
.foregroundStyle(SybilTheme.textMuted)
SecureField("ADMIN_TOKEN (optional in open mode)", text: $settings.adminToken)
.textInputAutocapitalization(.never)
.autocorrectionDisabled()
.padding(12)
.background(
RoundedRectangle(cornerRadius: 12)
.fill(SybilTheme.surface)
)
.overlay(
RoundedRectangle(cornerRadius: 12)
.stroke(SybilTheme.border, lineWidth: 1)
)
}
VStack(spacing: 10) {
Button {
Task {
await viewModel.refreshAfterSettingsChange()
}
} label: {
Text("Connect")
.frame(maxWidth: .infinity)
}
.buttonStyle(.borderedProminent)
.tint(SybilTheme.primarySoft)
Button {
settings.adminToken = ""
Task {
await viewModel.refreshAfterSettingsChange()
}
} label: {
Text("Continue Without Token")
.frame(maxWidth: .infinity)
}
.buttonStyle(.bordered)
.tint(SybilTheme.textMuted)
}
if let authError = viewModel.authError {
Text(authError)
.font(.footnote)
.foregroundStyle(SybilTheme.danger)
.frame(maxWidth: .infinity, alignment: .leading)
}
}
.padding(20)
.frame(maxWidth: 520)
.background(
RoundedRectangle(cornerRadius: 20)
.fill(SybilTheme.card)
.overlay(
RoundedRectangle(cornerRadius: 20)
.stroke(SybilTheme.border, lineWidth: 1)
)
)
}
}