eden-miror/src/ios/LibraryView.swift
2026-04-01 07:38:04 +00:00

191 lines
7 KiB
Swift

// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 Pomelo, Stossy11
// SPDX-License-Identifier: GPL-3.0-or-later
import SwiftUI
import CryptoKit
import AppUI
struct LibraryView: View {
@Binding var core: Core
@State var isGridView: Bool = true
@State var doesitexist = (false, false)
@State var importedgame: EmulationGame? = nil
@State var importgame: Bool = false
@State var isimportingfirm: Bool = false
@State var launchGame: Bool = false
var body: some View {
NavigationStack {
if let importedgame = importedgame {
NavigationLink(
isActive: $launchGame,
destination: {
EmulationView(game: importedgame).toolbar(.hidden, for: .tabBar)
},
label: {
EmptyView() // This keeps the link hidden
}
)
}
VStack {
if doesitexist.0, doesitexist.1 {
HomeView(core: core)
} else {
let (doesKeyExist, doesProdExist) = doeskeysexist()
ScrollView {
Text("You Are Missing These Files:")
.font(.headline)
.foregroundColor(.red)
HStack {
if !doesProdExist {
Text("Prod.keys")
.font(.subheadline)
.foregroundColor(.red)
}
if !doesKeyExist {
Text("Title.keys")
.font(.subheadline)
.foregroundColor(.red)
}
}
Text("These goes into the Keys folder")
.font(.caption)
.foregroundColor(.red)
.padding(.bottom)
if !LibraryManager.shared.homebrewroms().isEmpty {
Text("Homebrew Roms:")
.font(.headline)
LazyVGrid(columns: [GridItem(.adaptive(minimum: 160))], spacing: 10) {
ForEach(LibraryManager.shared.homebrewroms()) { game in
NavigationLink(destination: EmulationView(game: game).toolbar(.hidden, for: .tabBar)) {
// GameButtonView(game: game)
// .frame(maxWidth: .infinity, minHeight: 200)
}
.contextMenu {
NavigationLink(destination: EmulationView(game: game)) {
Text("Launch")
}
}
}
}
}
}
.refreshable {
doesitexist = doeskeysexist()
}
}
}
.fileImporter(isPresented: $isimportingfirm, allowedContentTypes: [.zip], onCompletion: { result in
switch result {
case .success(let elements):
core.AddFirmware(at: elements)
case .failure(let error):
print(error.localizedDescription)
}
})
.fileImporter(isPresented: $importgame, allowedContentTypes: [.item], onCompletion: { result in
switch result {
case .success(let elements):
let iscustom = elements.startAccessingSecurityScopedResource()
let information = AppUI.shared.information(for: elements)
let game = EmulationGame(developer: information.developer, fileURL: elements,
imageData: information.iconData,
title: information.title)
importedgame = game
DispatchQueue.main.async {
if iscustom {
elements.stopAccessingSecurityScopedResource()
}
launchGame = true
}
case .failure(let error):
print(error.localizedDescription)
}
})
.onAppear() {
doesitexist = doeskeysexist()
}
.navigationBarTitle("Library", displayMode: .inline)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) { // why did this take me so long to figure out lmfao
Button(action: {
isGridView.toggle()
}) {
Image(systemName: isGridView ? "rectangle.grid.1x2" : "square.grid.2x2")
.imageScale(.large)
.padding()
}
}
ToolbarItem(placement: .navigationBarTrailing) { // funsies
Menu {
Button(action: {
importgame = true // this part took a while
}) {
Text("Launch Game")
}
Button(action: {
isimportingfirm = true
}) {
Text("Import Firmware")
}
} label: {
Image(systemName: "plus.circle.fill")
.imageScale(.large)
.padding()
}
}
}
}
}
func doeskeysexist() -> (Bool, Bool) {
var doesprodexist = false
var doestitleexist = false
let title = core.root.appendingPathComponent("keys").appendingPathComponent("title.keys")
let prod = core.root.appendingPathComponent("keys").appendingPathComponent("prod.keys")
let fileManager = FileManager.default
let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
if fileManager.fileExists(atPath: prod.path) {
doesprodexist = true
} else {
print("File does not exist")
}
if fileManager.fileExists(atPath: title.path) {
doestitleexist = true
} else {
print("File does not exist")
}
return (doestitleexist, doesprodexist)
}
}
func getDeveloperNames() -> String {
guard let s = infoDictionary?["CFBundleIdentifier"] as? String else {
return "Unknown"
}
return s
}