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 } }