quick fix

This commit is contained in:
Dallas Groot 2026-04-12 19:34:58 -07:00
parent b9844b23cd
commit b8f3544395
5 changed files with 218 additions and 11 deletions

View file

@ -146,8 +146,6 @@ struct WaveformBar: View {
var body: some View {
GeometryReader { geo in
let w = geo.size.width
let barWidth: CGFloat = max((w - CGFloat(barCount - 1) * 1.5) / CGFloat(barCount), 1.5)
let playedCount = Int(Double(barCount) * progress)
ZStack {

View file

@ -115,10 +115,24 @@ class BackupManager {
// 5. Visualizer settings
let visSettings = VisualizerSettings.shared
let visDict: [String: Any] = [
"enabled": visSettings.enabled,
"nowPlayingEnabled": visSettings.nowPlayingEnabled,
"miniPlayerEnabled": visSettings.miniPlayerEnabled,
"realAudioAnalysis": visSettings.realAudioAnalysis,
"barCount": visSettings.barCount,
"gain": visSettings.gain,
"colorScheme": visSettings.colorScheme,
"dynamicGainEnabled": visSettings.dynamicGainEnabled,
"fps": visSettings.fps,
"viscosity": visSettings.viscosity,
"frequencyCutoff": visSettings.frequencyCutoff,
"baseMultiplier": visSettings.baseMultiplier,
"waveStrokeThickness": visSettings.waveStrokeThickness,
"barSpacing": visSettings.barSpacing,
"barCornerRadius": visSettings.barCornerRadius,
"lineThickness": visSettings.lineThickness,
"nowPlayingHeightPct": visSettings.nowPlayingHeightPct,
"waveOffsetTop": visSettings.waveOffsetTop,
"npAmplitude": visSettings.npAmplitude,
"npBaseLift": visSettings.npBaseLift,
"depthOffset": visSettings.depthOffset,
]
let visData = try JSONSerialization.data(withJSONObject: visDict, options: .prettyPrinted)
try visData.write(to: tempDir.appendingPathComponent("visualizer_settings.json"))
@ -243,10 +257,24 @@ class BackupManager {
let data = try? Data(contentsOf: visURL),
let dict = try? JSONSerialization.jsonObject(with: data) as? [String: Any] {
let vis = VisualizerSettings.shared
if let v = dict["realAudioAnalysis"] as? Bool { vis.realAudioAnalysis = v }
if let v = dict["barCount"] as? Int { vis.barCount = v }
if let v = dict["gain"] as? Double { vis.gain = Float(v) }
if let v = dict["colorScheme"] as? String { vis.colorScheme = v }
if let v = dict["enabled"] as? Bool { vis.enabled = v }
if let v = dict["nowPlayingEnabled"] as? Bool { vis.nowPlayingEnabled = v }
if let v = dict["miniPlayerEnabled"] as? Bool { vis.miniPlayerEnabled = v }
if let v = dict["realAudioAnalysis"] as? Bool { vis.realAudioAnalysis = v }
if let v = dict["dynamicGainEnabled"] as? Bool { vis.dynamicGainEnabled = v }
if let v = dict["fps"] as? Double { vis.fps = v }
if let v = dict["viscosity"] as? Double { vis.viscosity = v }
if let v = dict["frequencyCutoff"] as? Int { vis.frequencyCutoff = v }
if let v = dict["baseMultiplier"] as? Double { vis.baseMultiplier = v }
if let v = dict["waveStrokeThickness"] as? Double { vis.waveStrokeThickness = v }
if let v = dict["barSpacing"] as? Double { vis.barSpacing = v }
if let v = dict["barCornerRadius"] as? Double { vis.barCornerRadius = v }
if let v = dict["lineThickness"] as? Double { vis.lineThickness = v }
if let v = dict["nowPlayingHeightPct"] as? Double { vis.nowPlayingHeightPct = v }
if let v = dict["waveOffsetTop"] as? Double { vis.waveOffsetTop = v }
if let v = dict["npAmplitude"] as? Double { vis.npAmplitude = v }
if let v = dict["npBaseLift"] as? Double { vis.npBaseLift = v }
if let v = dict["depthOffset"] as? Double { vis.depthOffset = v }
}
// 6. Restore playback state

View file

@ -17,9 +17,9 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>1</string>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>LSRequiresIPhoneOS</key>
<true/>

View file

@ -726,6 +726,15 @@ struct SettingsView: View {
Spacer()
Text("1.16.1").foregroundColor(.gray)
}
NavigationLink {
LicensesView()
} label: {
HStack {
Image(systemName: "doc.text")
.foregroundStyle(accentPink)
Text("Licenses & Acknowledgments")
}
}
}
// Logout

View file

@ -0,0 +1,172 @@
import SwiftUI
//
// LicensesView.swift
// Displays all open-source licenses for dependencies used in the app
// and the Companion API server.
//
struct LicenseItem: Identifiable {
let id = UUID()
let name: String
let description: String
let license: String
let url: String
let category: String // "App" or "Companion API"
}
struct LicensesView: View {
private let accentPink = Color(red: 1.0, green: 0.176, blue: 0.333)
private let licenses: [LicenseItem] = [
// iOS App
LicenseItem(
name: "ZIPFoundation",
description: "Effortless ZIP handling in Swift",
license: "MIT License",
url: "https://github.com/weichsel/ZIPFoundation",
category: "App"
),
// Companion API (Python)
LicenseItem(
name: "FastAPI",
description: "Modern, fast web framework for building APIs with Python",
license: "MIT License",
url: "https://github.com/tiangolo/fastapi",
category: "Companion API"
),
LicenseItem(
name: "Uvicorn",
description: "Lightning-fast ASGI server for Python",
license: "BSD License",
url: "https://github.com/encode/uvicorn",
category: "Companion API"
),
LicenseItem(
name: "Mutagen",
description: "Python module to handle audio metadata",
license: "GPL-2.0 License",
url: "https://github.com/quodlibet/mutagen",
category: "Companion API"
),
LicenseItem(
name: "httpx",
description: "Fully featured HTTP client for Python 3",
license: "BSD License",
url: "https://github.com/encode/httpx",
category: "Companion API"
),
LicenseItem(
name: "NumPy",
description: "Fundamental package for scientific computing with Python",
license: "BSD License",
url: "https://github.com/numpy/numpy",
category: "Companion API"
),
LicenseItem(
name: "Pydantic",
description: "Data validation using Python type annotations",
license: "MIT License",
url: "https://github.com/pydantic/pydantic",
category: "Companion API"
),
LicenseItem(
name: "librosa",
description: "Python library for audio and music analysis",
license: "ISC License",
url: "https://github.com/librosa/librosa",
category: "Companion API"
),
]
private var appLicenses: [LicenseItem] {
licenses.filter { $0.category == "App" }
}
private var companionLicenses: [LicenseItem] {
licenses.filter { $0.category == "Companion API" }
}
var body: some View {
List {
Section {
VStack(alignment: .leading, spacing: 6) {
Text("NavidromePlayer uses the following open-source libraries. We're grateful to the developers and communities behind these projects.")
.font(.system(size: 13))
.foregroundStyle(.secondary)
}
.padding(.vertical, 4)
}
Section("App") {
ForEach(appLicenses) { item in
licenseRow(item)
}
}
Section("Companion API") {
ForEach(companionLicenses) { item in
licenseRow(item)
}
}
Section {
VStack(alignment: .leading, spacing: 6) {
Text("Visualizer")
.font(.system(size: 15, weight: .semibold))
Text("The audio visualizer is inspired by Mitsuha, originally created by c0ldra1n for jailbroken iOS. This is an independent reimplementation using Apple frameworks.")
.font(.system(size: 13))
.foregroundStyle(.secondary)
}
.padding(.vertical, 4)
} header: {
Text("Acknowledgments")
}
}
.navigationTitle("Licenses")
}
private func licenseRow(_ item: LicenseItem) -> some View {
VStack(alignment: .leading, spacing: 4) {
HStack {
Text(item.name)
.font(.system(size: 15, weight: .semibold))
Spacer()
Text(item.license)
.font(.system(size: 11, weight: .medium))
.foregroundStyle(accentPink)
.padding(.horizontal, 8)
.padding(.vertical, 3)
.background(
Capsule()
.fill(accentPink.opacity(0.12))
)
}
Text(item.description)
.font(.system(size: 13))
.foregroundStyle(.secondary)
.lineLimit(2)
if let url = URL(string: item.url) {
Link(destination: url) {
Text(item.url.replacingOccurrences(of: "https://", with: ""))
.font(.system(size: 11))
.foregroundStyle(.blue.opacity(0.8))
.lineLimit(1)
.truncationMode(.middle)
}
}
}
.padding(.vertical, 4)
}
}
#if DEBUG
#Preview {
NavigationStack {
LicensesView()
}
}
#endif