finish first version of World list page

This commit is contained in:
Giovanni committed 2026-09-03 18:59:13 +02:00
1 parent 844c4d7587
commit 2e4dfa48cd
7 files changed
+178 -5

No files matched your search

+31 -2
View File
@@ -9,11 +9,40 @@ import SwiftUI
struct WorldCardView : View {
var world : World
var isSelected = false
var body : some View {
VStack {
ZStack(alignment: .bottom) {
LinearGradient(
colors: [.clear, .black.opacity(0.5)],
startPoint: .top,
endPoint: .bottom
)
HStack(alignment: .bottom) {
Text(world.name)
.foregroundStyle(.white)
.font(.headline)
Spacer()
if isSelected {
Image(systemName: "checkmark.circle.fill")
.font(.system(size: 28))
.foregroundStyle(.white, .indigo)
}
.background(.red)
}
.padding(.vertical, 8)
.padding(.horizontal, 4)
}
.frame(height: 220)
.background {
Image(systemName: "globe.europe.africa")
.resizable()
.scaledToFill()
}
.clipShape(RoundedRectangle(cornerRadius: 20))
.contentShape(RoundedRectangle(cornerRadius: 20))
}
}
File renamed without changes.
+9
View File
@@ -23,4 +23,13 @@ class World {
self.createdAt = Date()
self.updatedAt = Date()
}
func duplicate() -> World {
let newWorld = World(
name: self.name, overview: self.overview
)
return newWorld
}
}
@@ -20,9 +20,6 @@ struct WorldListHeaderView : View {
)
.font(.subheadline)
.foregroundStyle(.secondary)
}
.padding(.vertical, 50)
.padding(.horizontal, 10)
}
}
@@ -0,0 +1,51 @@
//
// WorldListAreaInsetModifier.swift
// WorldBuilder
//
// Created by Giovanni Josserand on 03/09/2026.
//
import SwiftUI
import SwiftData
struct WorldListAreaInsetModifier : ViewModifier {
let isSelecting : Bool
@Binding var selectedWorlds : Set<World.ID>
let worlds : [World]
@Environment(\.modelContext) private var context
func body(content: Content) -> some View {
content
.safeAreaInset(edge: .bottom){
if isSelecting && !selectedWorlds.isEmpty {
HStack {
let worldsToAction = worlds.filter { world in
selectedWorlds.contains(world.id)
}
Spacer()
Button {
for world in worldsToAction {
context.insert(world.duplicate())
}
} label: {
Label("Dupliquer", systemImage: "plus.square.on.square")
}
Spacer()
Button(role: .destructive){
for world in worldsToAction {
context.delete(world)
}
}label : {
Label("Supprimer", systemImage: "trash")
}
Spacer()
}
}
}
}
}
@@ -0,0 +1,41 @@
//
// WorldListToolbarView.swift
// WorldBuilder
//
// Created by Giovanni Josserand on 03/09/2026.
//
import SwiftUI
struct WorldListToolbarModifier : ViewModifier {
@Binding var isSelecting : Bool
@Binding var selectedWorlds : Set<World.ID>
func body(content: Content) -> some View {
content
.toolbar{
ToolbarItem(placement: .topBarLeading) {
if isSelecting {
Button("Annuler") {
selectedWorlds.removeAll()
isSelecting = false
}
} else {
Button("Sélectionner") {
isSelecting = true
}
}
}
ToolbarItem(placement: .topBarTrailing) {
if !isSelecting {
NavigationLink {
CreateWorldView()
} label: {
Image(systemName: "plus")
}
}
}
}
}
}
@@ -14,6 +14,10 @@ struct WorldListView: View {
private var worlds: [World]
let columns = [GridItem(.flexible()), GridItem(.flexible())]
@State private var isSelecting = false
@State private var selectedWorlds = Set<World.ID>()
var body: some View {
ScrollView {
VStack(alignment: .leading, spacing: 24){
@@ -24,16 +28,58 @@ struct WorldListView: View {
}else{
LazyVGrid(columns: columns){
ForEach(worlds) {world in
if isSelecting {
WorldCardView(
world: world,
isSelected: selectedWorlds.contains(world.id)
)
.onTapGesture {
if selectedWorlds.contains(world.id) {
selectedWorlds.remove(world.id)
} else {
selectedWorlds.insert(world.id)
}
}
}else {
NavigationLink{
WorldOverviewView()
} label: {
WorldCardView(world: world)
}
.contextMenu{
Button {
context.insert(world.duplicate())
} label: {
Label("Dupliquer", systemImage: "plus.square.on.square")
}
Button(role: .destructive){
context.delete(world)
}label : {
Label("Supprimer", systemImage: "trash")
}
}
}
}
}
}
}
.padding(.horizontal, 8)
.frame(maxHeight: .infinity, alignment: .topLeading)
.modifier(
WorldListAreaInsetModifier(
isSelecting: isSelecting,
selectedWorlds: $selectedWorlds,
worlds: worlds
)
)
}
.modifier(
WorldListToolbarModifier(
isSelecting: $isSelecting,
selectedWorlds: $selectedWorlds
)
)
}
}