Made Console and Game name Mandatory. Implemented currently all game details with import&export
This commit is contained in:
@@ -19,7 +19,7 @@ extension Console {
|
|||||||
|
|
||||||
@NSManaged public var generation: Int64
|
@NSManaged public var generation: Int64
|
||||||
@NSManaged public var manufacturer: String?
|
@NSManaged public var manufacturer: String?
|
||||||
@NSManaged public var name: String?
|
@NSManaged public var name: String
|
||||||
@NSManaged public var shortName: String?
|
@NSManaged public var shortName: String?
|
||||||
@NSManaged public var uuid: UUID
|
@NSManaged public var uuid: UUID
|
||||||
@NSManaged public var accessories: NSSet?
|
@NSManaged public var accessories: NSSet?
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ extension Game : Encodable {
|
|||||||
case createdAt
|
case createdAt
|
||||||
case publisher
|
case publisher
|
||||||
case isFinished
|
case isFinished
|
||||||
|
case finishedDate
|
||||||
case inWishlist
|
case inWishlist
|
||||||
case console
|
case console
|
||||||
case cover_icloud_path
|
case cover_icloud_path
|
||||||
@@ -67,6 +68,7 @@ extension Game : Encodable {
|
|||||||
try container.encode(pickupDescription ?? "", forKey: .pickupDescription)
|
try container.encode(pickupDescription ?? "", forKey: .pickupDescription)
|
||||||
try container.encode(publisher ?? "", forKey: .publisher)
|
try container.encode(publisher ?? "", forKey: .publisher)
|
||||||
try container.encode(isFinished, forKey: .isFinished)
|
try container.encode(isFinished, forKey: .isFinished)
|
||||||
|
try container.encode(finishedDate, forKey: .finishedDate)
|
||||||
try container.encode(inWishlist, forKey: .inWishlist)
|
try container.encode(inWishlist, forKey: .inWishlist)
|
||||||
try container.encode(cover_icloud_path ?? "", forKey: .cover_icloud_path)
|
try container.encode(cover_icloud_path ?? "", forKey: .cover_icloud_path)
|
||||||
|
|
||||||
|
|||||||
@@ -23,8 +23,9 @@ extension Game {
|
|||||||
@NSManaged public var inWishlist: Bool
|
@NSManaged public var inWishlist: Bool
|
||||||
@NSManaged public var isDigital: Bool
|
@NSManaged public var isDigital: Bool
|
||||||
@NSManaged public var isFinished: Bool
|
@NSManaged public var isFinished: Bool
|
||||||
|
@NSManaged public var finishedDate : Date?
|
||||||
@NSManaged public var lentTo: String?
|
@NSManaged public var lentTo: String?
|
||||||
@NSManaged public var name: String?
|
@NSManaged public var name: String
|
||||||
@NSManaged public var notes: String?
|
@NSManaged public var notes: String?
|
||||||
@NSManaged public var publisher: String?
|
@NSManaged public var publisher: String?
|
||||||
@NSManaged public var uuid: UUID
|
@NSManaged public var uuid: UUID
|
||||||
|
|||||||
@@ -71,13 +71,15 @@ class LibraryImport {
|
|||||||
private func makeCDGame(from game: BHLGame, _ gameDict: inout [UUID : Game], _ cdConsole: Console) {
|
private func makeCDGame(from game: BHLGame, _ gameDict: inout [UUID : Game], _ cdConsole: Console) {
|
||||||
let cdGame = Game(context: CDManager.shared.viewContext)
|
let cdGame = Game(context: CDManager.shared.viewContext)
|
||||||
gameDict[game.uuid] = cdGame
|
gameDict[game.uuid] = cdGame
|
||||||
cdGame.name = game.name
|
cdGame.name = game.name ?? "n/a"
|
||||||
cdGame.uuid = game.uuid
|
cdGame.uuid = game.uuid
|
||||||
cdGame.inWishlist = game.inWishlist
|
cdGame.inWishlist = game.inWishlist
|
||||||
cdGame.isFinished = game.isFinished
|
cdGame.isFinished = game.isFinished
|
||||||
|
cdGame.finishedDate = game.finishedDate
|
||||||
cdGame.lentTo = game.lentTo
|
cdGame.lentTo = game.lentTo
|
||||||
cdGame.cover_icloud_path = game.cover_icloud_path
|
cdGame.cover_icloud_path = game.cover_icloud_path
|
||||||
cdGame.pickupDescription = game.pickupDescription
|
cdGame.pickupDescription = game.pickupDescription
|
||||||
|
cdGame.isDigital = game.isDigital
|
||||||
|
|
||||||
if let date = Date.from(string: game.createdAt) {
|
if let date = Date.from(string: game.createdAt) {
|
||||||
cdGame.createdAt = date
|
cdGame.createdAt = date
|
||||||
@@ -85,8 +87,6 @@ class LibraryImport {
|
|||||||
print("Could not decode date '\(game.createdAt)' for game '\(cdGame.name)'")
|
print("Could not decode date '\(game.createdAt)' for game '\(cdGame.name)'")
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: cdGame.createdAt = game.createdAt.
|
|
||||||
|
|
||||||
cdConsole.addToGames(cdGame)
|
cdConsole.addToGames(cdGame)
|
||||||
cdGame.console = cdConsole
|
cdGame.console = cdConsole
|
||||||
print("Imported: \(cdGame.name) for \(cdConsole.name)")
|
print("Imported: \(cdGame.name) for \(cdConsole.name)")
|
||||||
@@ -108,7 +108,7 @@ class LibraryImport {
|
|||||||
|
|
||||||
private func makeCDConsole(from console : BHLConsole) -> Console {
|
private func makeCDConsole(from console : BHLConsole) -> Console {
|
||||||
let cdConsole = Console(context: CDManager.shared.viewContext)
|
let cdConsole = Console(context: CDManager.shared.viewContext)
|
||||||
cdConsole.name = console.name
|
cdConsole.name = console.name ?? "n/a"
|
||||||
cdConsole.uuid = console.uuid
|
cdConsole.uuid = console.uuid
|
||||||
cdConsole.manufacturer = console.manufacturer
|
cdConsole.manufacturer = console.manufacturer
|
||||||
cdConsole.shortName = console.shortName
|
cdConsole.shortName = console.shortName
|
||||||
@@ -190,11 +190,12 @@ struct BHLibrary : Decodable {
|
|||||||
|
|
||||||
struct BHLGame : Decodable {
|
struct BHLGame : Decodable {
|
||||||
let uuid : UUID
|
let uuid : UUID
|
||||||
let name : String
|
let name : String?
|
||||||
let lentTo : String?
|
let lentTo : String?
|
||||||
let isDigital : Bool
|
let isDigital : Bool
|
||||||
let inWishlist : Bool
|
let inWishlist : Bool
|
||||||
let isFinished : Bool
|
let isFinished : Bool
|
||||||
|
let finishedDate : Date?
|
||||||
let notes : String?
|
let notes : String?
|
||||||
let createdAt : String
|
let createdAt : String
|
||||||
let pickupDescription : String?
|
let pickupDescription : String?
|
||||||
@@ -222,7 +223,7 @@ struct BHLGameSeries : Decodable {
|
|||||||
|
|
||||||
struct BHLConsole : Decodable {
|
struct BHLConsole : Decodable {
|
||||||
let uuid : UUID
|
let uuid : UUID
|
||||||
let name : String
|
let name : String?
|
||||||
let logo_icloud_path : String?
|
let logo_icloud_path : String?
|
||||||
let manufacturer : String?
|
let manufacturer : String?
|
||||||
let releaseDate : Date
|
let releaseDate : Date
|
||||||
|
|||||||
@@ -125,13 +125,13 @@ struct GridCell: View {
|
|||||||
.scaledToFit()
|
.scaledToFit()
|
||||||
//.shadow(color: .primary, radius: 5)
|
//.shadow(color: .primary, radius: 5)
|
||||||
.padding([.horizontal, .top], 7)
|
.padding([.horizontal, .top], 7)
|
||||||
Text(console.shortName ?? console.name!).lineLimit(1)
|
Text(console.shortName ?? console.name).lineLimit(1)
|
||||||
}
|
}
|
||||||
}.buttonStyle(PlainButtonStyle())
|
}.buttonStyle(PlainButtonStyle())
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
NavigationLink(destination: ConsoleLibraryView(console: console)) {
|
NavigationLink(destination: ConsoleLibraryView(console: console)) {
|
||||||
Text(console.shortName ?? console.name!)
|
Text(console.shortName ?? console.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ struct ConsoleEditView: View {
|
|||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Form {
|
Form {
|
||||||
TextField("Name der Konsole", text: $console.name ?? "n/a")
|
TextField("Name der Konsole", text: $console.name)
|
||||||
TextField("Abkürzung", text: $console.shortName ?? "")
|
TextField("Abkürzung", text: $console.shortName ?? "")
|
||||||
TextField("Hersteller", text: $console.manufacturer ?? "")
|
TextField("Hersteller", text: $console.manufacturer ?? "")
|
||||||
DatePicker(selection: $console.releaseDate, in: ...Date(), displayedComponents: .date) {
|
DatePicker(selection: $console.releaseDate, in: ...Date(), displayedComponents: .date) {
|
||||||
|
|||||||
@@ -42,18 +42,42 @@ struct GameSeriesPicker: View {
|
|||||||
|
|
||||||
struct GameDetailView : View {
|
struct GameDetailView : View {
|
||||||
@ObservedObject var game : Game
|
@ObservedObject var game : Game
|
||||||
|
|
||||||
@State private var showDeleteAlert : Bool = false
|
|
||||||
@State var hasFinishedDate : Bool = false
|
|
||||||
@State var playthroughDate : Date = Date()
|
|
||||||
|
|
||||||
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
|
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
|
||||||
|
|
||||||
|
@State private var showDeleteAlert : Bool = false
|
||||||
|
|
||||||
@State var isImportingCover : Bool = false
|
@State var isImportingCover : Bool = false
|
||||||
@State var isLent : Bool = false
|
|
||||||
|
|
||||||
let defaultImage = UIImage()
|
let defaultImage = UIImage()
|
||||||
|
|
||||||
|
@State var hasFinishedDate_raw : Bool = false
|
||||||
|
private var hasFinishedDate: Binding<Bool> {
|
||||||
|
Binding<Bool>(
|
||||||
|
get: { self.hasFinishedDate_raw || self.game.finishedDate != .none },
|
||||||
|
set: {
|
||||||
|
hasFinishedDate_raw = $0
|
||||||
|
if !$0 { self.game.finishedDate = .none }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@State var isLent_raw : Bool = false
|
||||||
|
private var isLent: Binding<Bool> {
|
||||||
|
Binding<Bool>(
|
||||||
|
get: { self.isLent_raw || (self.game.lentTo != .none && self.game.lentTo != "") },
|
||||||
|
set: {
|
||||||
|
isLent_raw = $0
|
||||||
|
if !$0 { self.game.lentTo = .none }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
var finishedDateBinding: Binding<Date> {
|
||||||
|
Binding<Date>(
|
||||||
|
get: { self.game.finishedDate ?? Date() },
|
||||||
|
set: { self.game.finishedDate = $0 })
|
||||||
|
}
|
||||||
|
|
||||||
var GameIsFinished : some View {
|
var GameIsFinished : some View {
|
||||||
Group {
|
Group {
|
||||||
Toggle(isOn: $game.isFinished , label: {
|
Toggle(isOn: $game.isFinished , label: {
|
||||||
@@ -61,16 +85,16 @@ struct GameDetailView : View {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if game.isFinished {
|
if game.isFinished {
|
||||||
Toggle(isOn: $hasFinishedDate, label: {
|
Toggle(isOn: hasFinishedDate, label: {
|
||||||
Text("Gibts ein Datum")
|
Text("Gibts ein Datum")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if hasFinishedDate && game.isFinished {
|
if self.hasFinishedDate.wrappedValue && game.isFinished {
|
||||||
DatePicker("Durchgezockt am",
|
DatePicker("Durchgezockt am",
|
||||||
selection: $playthroughDate,
|
selection: finishedDateBinding,
|
||||||
in: ...Date(),
|
in: ...Date(),
|
||||||
displayedComponents: [.date])
|
displayedComponents: [.date])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -78,7 +102,7 @@ struct GameDetailView : View {
|
|||||||
var body: some View {
|
var body: some View {
|
||||||
Form {
|
Form {
|
||||||
Section {
|
Section {
|
||||||
TextField("Videogame name", text: $game.name ?? "")
|
TextField("Videogame name", text: $game.name)
|
||||||
|
|
||||||
//Gray color should indicate immutable data
|
//Gray color should indicate immutable data
|
||||||
Text("\(game.console?.name ?? "No console")").foregroundColor(.gray)
|
Text("\(game.console?.name ?? "No console")").foregroundColor(.gray)
|
||||||
@@ -101,15 +125,11 @@ struct GameDetailView : View {
|
|||||||
Text("In Wunschliste")
|
Text("In Wunschliste")
|
||||||
})
|
})
|
||||||
|
|
||||||
Toggle(isOn: $isLent, label: {
|
Toggle(isOn: isLent, label: {
|
||||||
Text("Verliehen?")
|
Text("Verliehen?")
|
||||||
}).onReceive(game.objectWillChange) { _ in
|
})
|
||||||
self.isLent = self.game.lentTo != "";
|
|
||||||
}.onAppear() {
|
|
||||||
self.isLent = self.game.lentTo != "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if isLent {
|
if isLent.wrappedValue {
|
||||||
TextField("Verliehen an", text: $game.lentTo ?? "")
|
TextField("Verliehen an", text: $game.lentTo ?? "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ struct GamePickupsView: View {
|
|||||||
var body: some View {
|
var body: some View {
|
||||||
List(games) { game in
|
List(games) { game in
|
||||||
NavigationLink(destination: GameDetailView(game: game)) {
|
NavigationLink(destination: GameDetailView(game: game)) {
|
||||||
Text("\(game.name!)")
|
Text("\(game.name)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(.top) // Workaround, damit die Liste beim scrollen nicht unter der NavigationView angezeigt wird
|
.padding(.top) // Workaround, damit die Liste beim scrollen nicht unter der NavigationView angezeigt wird
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ struct GameSeriesLibraryView: View {
|
|||||||
var body: some View {
|
var body: some View {
|
||||||
List(games) { game in
|
List(games) { game in
|
||||||
NavigationLink(destination: GameDetailView(game: game)) {
|
NavigationLink(destination: GameDetailView(game: game)) {
|
||||||
Text("\(game.name!)")
|
Text("\(game.name)")
|
||||||
|
|
||||||
if game.isDigital {
|
if game.isDigital {
|
||||||
Image("digitalGame")
|
Image("digitalGame")
|
||||||
|
|||||||
@@ -83,12 +83,13 @@ struct Overview: View {
|
|||||||
Group {
|
Group {
|
||||||
Image(uiImage: ICloudManager.imageFrom(path: console.logo_icloud_path) ?? defaultImage)
|
Image(uiImage: ICloudManager.imageFrom(path: console.logo_icloud_path) ?? defaultImage)
|
||||||
.resizable()
|
.resizable()
|
||||||
|
.scaledToFit()
|
||||||
.padding(10)
|
.padding(10)
|
||||||
.cornerRadius(5)
|
.cornerRadius(5)
|
||||||
}
|
}
|
||||||
.frame(width: 100, height: 100)
|
.frame(width: 100, height: 100)
|
||||||
|
|
||||||
Text("\(console.name!)")
|
Text("\(console.name)")
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.frame(width: 100)
|
.frame(width: 100)
|
||||||
|
|
||||||
@@ -122,7 +123,7 @@ struct Overview: View {
|
|||||||
}
|
}
|
||||||
.frame(width: 100, height: 100)
|
.frame(width: 100, height: 100)
|
||||||
|
|
||||||
Text("\(game.name!)")
|
Text("\(game.name)")
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.frame(width: 100)
|
.frame(width: 100)
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
<entity name="Game" representedClassName="Game" syncable="YES">
|
<entity name="Game" representedClassName="Game" syncable="YES">
|
||||||
<attribute name="cover_icloud_path" optional="YES" attributeType="String"/>
|
<attribute name="cover_icloud_path" optional="YES" attributeType="String"/>
|
||||||
<attribute name="createdAt" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
<attribute name="createdAt" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||||
|
<attribute name="finishedDate" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||||
<attribute name="inWishlist" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
<attribute name="inWishlist" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||||
<attribute name="isDigital" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
<attribute name="isDigital" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||||
<attribute name="isFinished" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
<attribute name="isFinished" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||||
@@ -51,7 +52,7 @@
|
|||||||
<elements>
|
<elements>
|
||||||
<element name="Accessory" positionX="-265.9140625" positionY="29.15625" width="128" height="149"/>
|
<element name="Accessory" positionX="-265.9140625" positionY="29.15625" width="128" height="149"/>
|
||||||
<element name="Console" positionX="-535.7890625" positionY="56.03515625" width="128" height="164"/>
|
<element name="Console" positionX="-535.7890625" positionY="56.03515625" width="128" height="164"/>
|
||||||
<element name="Game" positionX="-288.828125" positionY="276.7421875" width="128" height="245"/>
|
<element name="Game" positionX="-288.828125" positionY="276.7421875" width="128" height="260"/>
|
||||||
<element name="GameSeries" positionX="-686.828125" positionY="359.20703125" width="128" height="89"/>
|
<element name="GameSeries" positionX="-686.828125" positionY="359.20703125" width="128" height="89"/>
|
||||||
<element name="GameSeriesCover" positionX="-477" positionY="180" width="128" height="44"/>
|
<element name="GameSeriesCover" positionX="-477" positionY="180" width="128" height="44"/>
|
||||||
</elements>
|
</elements>
|
||||||
|
|||||||
Reference in New Issue
Block a user