version 1.0.0

This commit is contained in:
diyaa
2026-05-24 20:53:42 +02:00
commit 4b8701e55b
6577 changed files with 25019 additions and 0 deletions
@@ -0,0 +1,10 @@
import SwiftUI
@main
struct VelodyiPhoneApp: App {
var body: some Scene {
WindowGroup {
iPhoneLibraryView()
}
}
}
@@ -0,0 +1,48 @@
import SwiftUI
struct iPhoneLibraryView: View {
@State private var viewModel = iPhoneLibraryViewModel()
var body: some View {
NavigationStack {
List(viewModel.tracks) { track in
VStack(alignment: .leading, spacing: 4) {
Text(track.title)
.font(.headline)
Text(track.artist)
.foregroundStyle(.secondary)
}
}
.overlay {
if viewModel.tracks.isEmpty {
ContentUnavailableView(
"No Local Tracks Yet",
systemImage: "music.note.list",
description: Text("This iPhone target currently exposes the offline catalog shell only.")
)
}
}
.navigationTitle("Velody")
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button("Sync") {
Task {
await viewModel.refreshSync()
}
}
}
}
.safeAreaInset(edge: .bottom) {
Text(viewModel.syncStatus)
.font(.footnote)
.foregroundStyle(.secondary)
.padding()
.frame(maxWidth: .infinity, alignment: .leading)
.background(.ultraThinMaterial)
}
}
.task {
await viewModel.loadIfNeeded()
}
}
}
@@ -0,0 +1,48 @@
import Foundation
import Observation
import VelodyDomain
import VelodyNetworking
import VelodyPersistence
import VelodySync
import VelodyUtilities
@MainActor
@Observable
final class iPhoneLibraryViewModel {
var tracks: [LibraryTrack] = []
var syncStatus = "Offline library not synced yet"
private let store = InMemoryLocalLibraryStore()
private let keychainService = MemoryKeychainService()
private let syncCoordinator: PlaceholderSyncCoordinator
private var hasLoaded = false
init() {
let environment = ServerEnvironment(
baseURL: URL(string: "http://localhost:3000")!,
appVersion: "0.1.0"
)
let apiClient = StubVelodyAPIClient(environment: environment)
self.syncCoordinator = PlaceholderSyncCoordinator(
apiClient: apiClient,
store: store
)
}
func loadIfNeeded() async {
guard !hasLoaded else { return }
hasLoaded = true
await keychainService.save("placeholder-bootstrap-token", forKey: "bootstrap-token")
await refreshSync()
}
func refreshSync() async {
do {
let result = try await syncCoordinator.performInitialSync()
tracks = result.tracks
syncStatus = result.statusMessage
} catch {
syncStatus = "Sync placeholder failed: \(error.localizedDescription)"
}
}
}