Files
jarvis/Jarvis/Views/Feeds/AddFeedSheet.swift
Robin Kutesa 27d0e22767 Initial commit: Jarvis iOS app
SwiftUI client for a self-hosted RSS news-correlation platform: signal feed,
story detail, article reader, feed manager, and LAN⇄Tailscale connectivity.
Project generated from project.yml via XcodeGen.

Includes CI build matrix (macOS 14/15 × Debug/Release), issue templates,
backlog, and API/backend handoff docs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 18:04:59 +03:00

115 lines
4.3 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// AddFeedSheet.swift
// Jarvis add a new RSS feed: URL + name + confirm.
import SwiftUI
struct AddFeedSheet: View {
/// Returns true on success.
let onAdd: (String, String) async -> Bool
@Environment(\.dismiss) private var dismiss
@State private var url = ""
@State private var name = ""
@State private var isSubmitting = false
@State private var errorMessage: String?
private var canSubmit: Bool {
!url.trimmingCharacters(in: .whitespaces).isEmpty &&
!name.trimmingCharacters(in: .whitespaces).isEmpty &&
!isSubmitting
}
var body: some View {
ZStack {
Color.black.ignoresSafeArea()
VStack(alignment: .leading, spacing: 0) {
HStack {
Text("Add feed")
.font(.system(size: 22, weight: .heavy))
.foregroundStyle(.white)
Spacer()
Button { dismiss() } label: {
Image(systemName: "xmark")
.font(.system(size: 15, weight: .bold))
.foregroundStyle(Color(hex: "888888"))
.frame(width: 44, height: 44)
}
}
.padding(.top, 8)
field(label: "FEED URL", text: $url,
placeholder: "https://example.com/rss",
mono: true, keyboard: .URL)
.padding(.top, 12)
field(label: "DISPLAY NAME", text: $name,
placeholder: "Example News",
mono: false, keyboard: .default)
.padding(.top, 16)
if let errorMessage {
Text(errorMessage)
.font(.system(size: 13))
.foregroundStyle(Color(hex: "C25555"))
.padding(.top, 14)
}
Button {
Task { await submit() }
} label: {
HStack {
Spacer()
if isSubmitting {
ProgressView().tint(.black)
} else {
Text("Add feed").font(.system(size: 16, weight: .bold)).foregroundStyle(.black)
}
Spacer()
}
.frame(height: 52)
.background(canSubmit ? Palette.orange : Palette.surface2)
.clipShape(RoundedRectangle(cornerRadius: 14))
}
.disabled(!canSubmit)
.padding(.top, 28)
Spacer()
}
.padding(.horizontal, 20)
}
.preferredColorScheme(.dark)
.presentationDetents([.medium])
.presentationDragIndicator(.visible)
}
private func field(label: String, text: Binding<String>, placeholder: String,
mono: Bool, keyboard: UIKeyboardType) -> some View {
VStack(alignment: .leading, spacing: 8) {
Text(label)
.font(.system(size: 10, weight: .bold, design: .monospaced))
.kerning(0.8)
.foregroundStyle(Color(hex: "666666"))
TextField("", text: text,
prompt: Text(placeholder).foregroundColor(Color(hex: "444444")))
.font(.system(size: 15, weight: .regular, design: mono ? .monospaced : .default))
.foregroundStyle(mono ? Palette.orange : .white)
.autocorrectionDisabled()
.textInputAutocapitalization(.never)
.keyboardType(keyboard)
.padding(14)
.background(Palette.surface)
.overlay(RoundedRectangle(cornerRadius: 12).stroke(Palette.surface2, lineWidth: 1))
.clipShape(RoundedRectangle(cornerRadius: 12))
}
}
private func submit() async {
isSubmitting = true
errorMessage = nil
let ok = await onAdd(url.trimmingCharacters(in: .whitespaces),
name.trimmingCharacters(in: .whitespaces))
isSubmitting = false
if ok { dismiss() } else { errorMessage = "Couldnt add feed. Check the URL and try again." }
}
}