Files
libnovel/ios/LibNovel/LibNovel/ViewModels/ProfileViewModel.swift
Admin f51113a2f8
Some checks failed
Deploy / Deploy Production (push) Has been skipped
Deploy / Cleanup Preview (push) Has been skipped
Deploy / Deploy Preview (push) Failing after 0s
CI / Scraper / Test (pull_request) Successful in 11s
CI / UI / Build (pull_request) Failing after 14s
CI / Scraper / Lint (pull_request) Successful in 23s
CI / Scraper / Build (pull_request) Successful in 24s
iOS CI / Build (push) Has been cancelled
iOS CI / Test (push) Has been cancelled
iOS CI / Build (pull_request) Failing after 2s
iOS CI / Test (pull_request) Has been skipped
Add iOS app, SvelteKit JSON API endpoints, and Gitea CI workflow
- iOS SwiftUI app (ios/LibNovel/) targeting iOS 17+, generated via xcodegen
  - Full feature set: auth, home, library, book detail, chapter reader, browse, audio player, profile
  - Kingfisher for image loading, swift-markdown-ui for chapter rendering
  - Base URL: https://v2.libnovel.kalekber.cc
- SvelteKit JSON API routes (ui/src/routes/api/) for iOS consumption:
  auth/login, auth/register, auth/me, auth/logout, auth/change-password,
  home, library, book/[slug], chapter/[slug]/[n], search, ranking,
  progress/[slug], presign/audio (updated)
- Gitea Actions CI: .gitea/workflows/ios.yaml (build + test on macos-latest)
- justfile: ios-gen, ios-build, ios-test recipes
2026-03-07 18:17:51 +05:00

41 lines
1.2 KiB
Swift

import Foundation
@MainActor
final class ProfileViewModel: ObservableObject {
@Published var sessions: [UserSession] = []
@Published var voices: [String] = []
@Published var sessionsLoading = false
@Published var error: String?
func loadSessions() async {
sessionsLoading = true
do {
sessions = try await APIClient.shared.sessions()
} catch {
self.error = error.localizedDescription
}
sessionsLoading = false
}
func loadVoices() async {
guard voices.isEmpty else { return }
do {
voices = try await APIClient.shared.voices()
} catch {
// Use hardcoded fallback same as Go server helpers.go
voices = ["af_bella", "af_sky", "af_sarah", "af_nicole",
"am_adam", "am_michael", "bf_emma", "bf_isabella",
"bm_george", "bm_lewis"]
}
}
func revokeSession(id: String) async {
do {
try await APIClient.shared.revokeSession(id: id)
sessions.removeAll { $0.id == id }
} catch {
self.error = error.localizedDescription
}
}
}