86d9659056
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
129 lines
3.0 KiB
Swift
129 lines
3.0 KiB
Swift
import SwiftUI
|
|
|
|
struct AddPackView: View {
|
|
@State private var urlText = ""
|
|
@State private var isLoading = false
|
|
@State private var errorMessage: String?
|
|
@State private var packs: [SavedPack]
|
|
|
|
var onPacksChanged: () -> Void
|
|
|
|
init(onPacksChanged: @escaping () -> Void) {
|
|
self.onPacksChanged = onPacksChanged
|
|
_packs = State(initialValue: StickerStore.shared.savedPacks)
|
|
}
|
|
|
|
var body: some View {
|
|
NavigationView {
|
|
List {
|
|
Section {
|
|
HStack {
|
|
TextField("t.me/addstickers/PackName", text: $urlText)
|
|
.textContentType(.URL)
|
|
.autocorrectionDisabled()
|
|
.textInputAutocapitalization(.never)
|
|
|
|
Button {
|
|
addPack()
|
|
} label: {
|
|
if isLoading {
|
|
ProgressView()
|
|
} else {
|
|
Text("Add")
|
|
}
|
|
}
|
|
.disabled(urlText.isEmpty || isLoading)
|
|
}
|
|
|
|
if let errorMessage {
|
|
Text(errorMessage)
|
|
.foregroundStyle(.red)
|
|
.font(.caption)
|
|
}
|
|
} header: {
|
|
Text("Add Sticker Pack")
|
|
} footer: {
|
|
Text("Paste a Telegram sticker link or pack name.")
|
|
}
|
|
|
|
if !packs.isEmpty {
|
|
Section("Saved Packs") {
|
|
ForEach(packs, id: \.name) { pack in
|
|
HStack {
|
|
VStack(alignment: .leading) {
|
|
Text(pack.title)
|
|
Text("\(pack.stickerCount) stickers")
|
|
.font(.caption)
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
Spacer()
|
|
}
|
|
}
|
|
.onDelete(perform: deletePacks)
|
|
}
|
|
}
|
|
}
|
|
.navigationTitle("Sticker Packs")
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
}
|
|
}
|
|
|
|
// MARK: - Actions
|
|
|
|
private func addPack() {
|
|
let name = extractPackName(from: urlText)
|
|
guard !name.isEmpty else {
|
|
errorMessage = "Could not parse pack name from input."
|
|
return
|
|
}
|
|
|
|
isLoading = true
|
|
errorMessage = nil
|
|
|
|
Task {
|
|
do {
|
|
let response = try await StickerClonerAPI.fetchStickerSet(name: name)
|
|
try await StickerStore.shared.addPack(response: response)
|
|
packs = StickerStore.shared.savedPacks
|
|
urlText = ""
|
|
onPacksChanged()
|
|
} catch {
|
|
errorMessage = error.localizedDescription
|
|
}
|
|
isLoading = false
|
|
}
|
|
}
|
|
|
|
private func deletePacks(at offsets: IndexSet) {
|
|
for index in offsets {
|
|
StickerStore.shared.removePack(name: packs[index].name)
|
|
}
|
|
packs = StickerStore.shared.savedPacks
|
|
onPacksChanged()
|
|
}
|
|
|
|
private func extractPackName(from input: String) -> String {
|
|
let trimmed = input.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
|
|
// Handle full URL: https://t.me/addstickers/PackName
|
|
if let url = URL(string: trimmed),
|
|
let host = url.host,
|
|
host.hasSuffix("t.me") {
|
|
let components = url.pathComponents
|
|
if let addstickersIndex = components.firstIndex(of: "addstickers"),
|
|
addstickersIndex + 1 < components.count {
|
|
return components[addstickersIndex + 1]
|
|
}
|
|
return url.lastPathComponent
|
|
}
|
|
|
|
// Handle bare URL without scheme
|
|
if trimmed.contains("t.me/addstickers/") {
|
|
return trimmed.components(separatedBy: "t.me/addstickers/").last ?? ""
|
|
}
|
|
|
|
// Treat as bare pack name
|
|
return trimmed
|
|
}
|
|
}
|