mirror of
https://github.com/codybrom/blankie.git
synced 2026-05-14 07:40:35 +00:00
feat(audio): Load sounds from JSON
This commit is contained in:
@@ -85,23 +85,46 @@ class AudioManager: ObservableObject {
|
||||
}
|
||||
}
|
||||
private func loadSounds() {
|
||||
sounds = [
|
||||
Sound(title: "Rain", systemIconName: "cloud.rain", fileName: "rain"),
|
||||
Sound(title: "Storm", systemIconName: "cloud.bolt.rain", fileName: "storm"),
|
||||
Sound(title: "Wind", systemIconName: "wind", fileName: "wind"),
|
||||
Sound(title: "Waves", systemIconName: "water.waves", fileName: "waves"),
|
||||
Sound(title: "Stream", systemIconName: "humidity", fileName: "stream"),
|
||||
Sound(title: "Birds", systemIconName: "bird", fileName: "birds"),
|
||||
Sound(title: "Summer Night", systemIconName: "moon.stars.fill", fileName: "summer-night"),
|
||||
Sound(title: "Train", systemIconName: "tram.fill", fileName: "train"),
|
||||
Sound(title: "Boat", systemIconName: "sailboat.fill", fileName: "boat"),
|
||||
Sound(title: "City", systemIconName: "building.2", fileName: "city"),
|
||||
Sound(title: "Coffee Shop", systemIconName: "cup.and.saucer.fill", fileName: "coffee-shop"),
|
||||
Sound(title: "Fireplace", systemIconName: "fireplace", fileName: "fireplace"),
|
||||
Sound(title: "Pink Noise", systemIconName: "waveform.path", fileName: "pink-noise"),
|
||||
Sound(title: "White Noise", systemIconName: "waveform", fileName: "white-noise"),
|
||||
]
|
||||
print("🎵 AudioManager: Loading sounds from JSON")
|
||||
let bundlePath = Bundle.main.bundlePath
|
||||
print("📦 Bundle path: \(bundlePath)")
|
||||
|
||||
if let resourcePath = Bundle.main.resourcePath {
|
||||
print("📂 Resource path: \(resourcePath)")
|
||||
do {
|
||||
let resources = try FileManager.default.contentsOfDirectory(atPath: resourcePath)
|
||||
print("📑 Resources in bundle: \(resources)")
|
||||
} catch {
|
||||
print("❌ Error listing resources: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
guard let url = Bundle.main.url(forResource: "sounds", withExtension: "json") else {
|
||||
print("❌ AudioManager: sounds.json file not found in Resources folder")
|
||||
ErrorReporter.shared.report(AudioError.fileNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
do {
|
||||
let data = try Data(contentsOf: url)
|
||||
let decoder = JSONDecoder()
|
||||
let soundsContainer = try decoder.decode(SoundsContainer.self, from: data)
|
||||
|
||||
self.sounds = soundsContainer.sounds
|
||||
.sorted(by: { $0.defaultOrder < $1.defaultOrder })
|
||||
.map { soundData in
|
||||
Sound(
|
||||
title: soundData.title,
|
||||
systemIconName: soundData.systemIconName,
|
||||
fileName: soundData.fileName
|
||||
)
|
||||
}
|
||||
} catch {
|
||||
print("❌ AudioManager: Failed to parse sounds.json: \(error)")
|
||||
ErrorReporter.shared.report(error)
|
||||
}
|
||||
}
|
||||
|
||||
private func setupMediaControls() {
|
||||
print("🎵 AudioManager: Setting up media controls")
|
||||
// Remove all previous handlers
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// SoundCreditsManager.swift
|
||||
// Blankie
|
||||
//
|
||||
// Created by Cody Bromley on 1/10/25.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
class SoundCreditsManager: ObservableObject {
|
||||
static let shared = SoundCreditsManager()
|
||||
@Published private(set) var credits: [SoundCredit] = []
|
||||
@Published private(set) var loadError: Error?
|
||||
|
||||
private init() {
|
||||
loadCredits()
|
||||
}
|
||||
|
||||
private func loadCredits() {
|
||||
guard let url = Bundle.main.url(forResource: "sounds", withExtension: "json") else {
|
||||
print("Error: sounds.json not found in bundle")
|
||||
return
|
||||
}
|
||||
|
||||
do {
|
||||
let data = try Data(contentsOf: url)
|
||||
let container = try JSONDecoder().decode(SoundsContainer.self, from: data)
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.credits = container.sounds.map { sound in
|
||||
SoundCredit(
|
||||
name: sound.title,
|
||||
author: sound.author,
|
||||
license: License(rawValue: sound.license.lowercased()) ?? .cc0,
|
||||
editor: sound.editor,
|
||||
soundUrl: URL(string: sound.soundUrl)
|
||||
)
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
print("Error loading sounds.json: \(error)")
|
||||
loadError = error
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// License.swift
|
||||
// Blankie
|
||||
//
|
||||
// Created by Cody Bromley on 1/10/25.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum License: String {
|
||||
case cc0 = "cc0"
|
||||
case ccBy = "ccby"
|
||||
case ccBySa = "ccbysa"
|
||||
case ccBy3 = "ccby3"
|
||||
case publicDomain = "publicdomain"
|
||||
|
||||
var linkText: String {
|
||||
switch self {
|
||||
case .cc0: return "CC0"
|
||||
case .ccBy: return "CC BY"
|
||||
case .ccBySa: return "CC BY-SA"
|
||||
case .ccBy3: return "CC BY 3.0"
|
||||
case .publicDomain: return "Public Domain"
|
||||
}
|
||||
}
|
||||
|
||||
var url: URL? {
|
||||
switch self {
|
||||
case .cc0: return URL(string: "https://creativecommons.org/publicdomain/zero/1.0/")
|
||||
case .ccBy: return URL(string: "https://creativecommons.org/licenses/by/4.0/")
|
||||
case .ccBySa: return URL(string: "https://creativecommons.org/licenses/by-sa/4.0/")
|
||||
case .ccBy3: return URL(string: "https://creativecommons.org/licenses/by/3.0/")
|
||||
case .publicDomain: return URL(string: "https://wiki.creativecommons.org/wiki/Public_domain")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,80 +20,3 @@ struct SoundCredit {
|
||||
return text
|
||||
}
|
||||
}
|
||||
|
||||
enum License {
|
||||
case cc0
|
||||
case ccBy
|
||||
case ccBySa
|
||||
case ccBy3
|
||||
case publicDomain
|
||||
|
||||
var linkText: String {
|
||||
switch self {
|
||||
case .cc0: return "CC0"
|
||||
case .ccBy: return "CC BY"
|
||||
case .ccBySa: return "CC BY-SA"
|
||||
case .ccBy3: return "CC BY 3.0"
|
||||
case .publicDomain: return "Public Domain"
|
||||
}
|
||||
}
|
||||
|
||||
var url: URL? {
|
||||
switch self {
|
||||
case .cc0: return URL(string: "https://creativecommons.org/publicdomain/zero/1.0/")
|
||||
case .ccBy: return URL(string: "https://creativecommons.org/licenses/by/4.0/")
|
||||
case .ccBySa: return URL(string: "https://creativecommons.org/licenses/by-sa/4.0/")
|
||||
case .ccBy3: return URL(string: "https://creativecommons.org/licenses/by/3.0/")
|
||||
case .publicDomain: return URL(string: "https://wiki.creativecommons.org/wiki/Public_domain")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sound credits data
|
||||
let soundCredits: [SoundCredit] = [
|
||||
SoundCredit(
|
||||
name: "Birds", author: "kvgarlic", license: .cc0, editor: "Porrumentzio",
|
||||
soundUrl: URL(string: "https://freesound.org/people/kvgarlic/sounds/156826/")),
|
||||
SoundCredit(
|
||||
name: "Boat", author: "Falcet", license: .cc0, editor: "Porrumentzio",
|
||||
soundUrl: URL(string: "https://freesound.org/people/Falcet/sounds/439365/")),
|
||||
SoundCredit(
|
||||
name: "City", author: "gezortenplotz", license: .ccBy, editor: "Porrumentzio",
|
||||
soundUrl: URL(string: "https://freesound.org/people/gezortenplotz/sounds/44796/")),
|
||||
SoundCredit(
|
||||
name: "Coffee Shop", author: "stephan", license: .publicDomain, editor: nil,
|
||||
soundUrl: URL(string: "https://soundbible.com/1664-Restaurant-Ambiance.html")),
|
||||
SoundCredit(
|
||||
name: "Fireplace", author: "ezwa", license: .publicDomain, editor: nil,
|
||||
soundUrl: URL(string: "https://soundbible.com/1543-Fireplace.html")),
|
||||
SoundCredit(
|
||||
name: "Pink noise", author: "Omegatron", license: .ccBySa, editor: nil,
|
||||
soundUrl: URL(string: "https://es.wikipedia.org/wiki/Archivo:Pink_noise.ogg")),
|
||||
SoundCredit(
|
||||
name: "Rain", author: "alex36917", license: .ccBy, editor: "Porrumentzio",
|
||||
soundUrl: URL(string: "https://freesound.org/people/alex36917/sounds/524605/")),
|
||||
SoundCredit(
|
||||
name: "Summer night", author: "Lisa Redfern", license: .publicDomain, editor: nil,
|
||||
soundUrl: URL(string: "https://soundbible.com/2083-Crickets-Chirping-At-Night.html")),
|
||||
SoundCredit(
|
||||
name: "Storm", author: "Digifish music", license: .ccBy, editor: "Porrumentzio",
|
||||
soundUrl: URL(string: "https://freesound.org/people/digifishmusic/sounds/41739/")),
|
||||
SoundCredit(
|
||||
name: "Stream", author: "gluckose", license: .cc0, editor: nil,
|
||||
soundUrl: URL(string: "https://freesound.org/people/gluckose/sounds/333987/")),
|
||||
SoundCredit(
|
||||
name: "Train", author: "SDLx", license: .ccBy3, editor: nil,
|
||||
soundUrl: URL(string: "https://freesound.org/people/SDLx/sounds/259988/")),
|
||||
SoundCredit(
|
||||
name: "Waves", author: "Luftrum", license: .ccBy, editor: "Porrumentzio",
|
||||
soundUrl: URL(string: "https://freesound.org/people/Luftrum/sounds/48412/")),
|
||||
SoundCredit(
|
||||
name: "White noise", author: "Jorge Stolfi", license: .ccBySa, editor: nil,
|
||||
soundUrl: URL(
|
||||
string:
|
||||
"https://commons.wikimedia.org/w/index.php?title=File%3AWhite-noise-sound-20sec-mono-44100Hz.ogg"
|
||||
)),
|
||||
SoundCredit(
|
||||
name: "Wind", author: "felix.blume", license: .cc0, editor: "Porrumentzio",
|
||||
soundUrl: URL(string: "https://freesound.org/people/felix.blume/sounds/217506/")),
|
||||
]
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// SoundData.swift
|
||||
// Blankie
|
||||
//
|
||||
// Created by Cody Bromley on 1/10/25.
|
||||
//
|
||||
|
||||
struct SoundData: Codable {
|
||||
let defaultOrder: Int
|
||||
let title: String
|
||||
let systemIconName: String
|
||||
let fileName: String
|
||||
let author: String
|
||||
let authorUrl: String?
|
||||
let license: String
|
||||
let editor: String?
|
||||
let editorUrl: String?
|
||||
let soundUrl: String
|
||||
}
|
||||
|
||||
struct SoundsContainer: Codable {
|
||||
let sounds: [SoundData]
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
import SwiftUI
|
||||
|
||||
struct AboutView: View {
|
||||
@ObservedObject private var creditsManager = SoundCreditsManager.shared
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
private let appVersion =
|
||||
Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "1.0"
|
||||
@@ -129,7 +130,7 @@ struct AboutView: View {
|
||||
.font(.system(size: 13, weight: .bold))
|
||||
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
ForEach(soundCredits, id: \.name) { credit in
|
||||
ForEach(creditsManager.credits, id: \.name) { credit in
|
||||
CreditRow(credit: credit)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user