From ae6197d855249bb774892d5ab7a5a8ca10d8f2f7 Mon Sep 17 00:00:00 2001 From: Giovanni Date: Sat, 5 Sep 2026 14:10:16 +0200 Subject: [PATCH] change List view UI disposition --- .../WorldListAreaInsetModifier.swift | 58 -------- .../Modifiers/WorldListToolbarModifier.swift | 51 ++++++- .../Views/WorldList/WorldListView.swift | 129 +++++++++--------- 3 files changed, 112 insertions(+), 126 deletions(-) delete mode 100644 WorldBuilder/Views/WorldList/Modifiers/WorldListAreaInsetModifier.swift diff --git a/WorldBuilder/Views/WorldList/Modifiers/WorldListAreaInsetModifier.swift b/WorldBuilder/Views/WorldList/Modifiers/WorldListAreaInsetModifier.swift deleted file mode 100644 index 8360bfc..0000000 --- a/WorldBuilder/Views/WorldList/Modifiers/WorldListAreaInsetModifier.swift +++ /dev/null @@ -1,58 +0,0 @@ -// -// WorldListAreaInsetModifier.swift -// WorldBuilder -// -// Created by Giovanni Josserand on 03/09/2026. -// - -import SwiftUI -import SwiftData - -struct WorldListAreaInsetModifier : ViewModifier { - @Binding var isSelecting : Bool - @Binding var selectedWorlds : Set - 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){ - let shouldExitSelection = worldsToAction.count == worlds.count - - for world in worldsToAction { - context.delete(world) - } - selectedWorlds.removeAll() - - if shouldExitSelection { - isSelecting = false - } - }label : { - Label("Supprimer", systemImage: "trash") - } - Spacer() - } - } - } - - } -} diff --git a/WorldBuilder/Views/WorldList/Modifiers/WorldListToolbarModifier.swift b/WorldBuilder/Views/WorldList/Modifiers/WorldListToolbarModifier.swift index 8ac6dca..7a7e34a 100644 --- a/WorldBuilder/Views/WorldList/Modifiers/WorldListToolbarModifier.swift +++ b/WorldBuilder/Views/WorldList/Modifiers/WorldListToolbarModifier.swift @@ -6,11 +6,17 @@ // import SwiftUI +import SwiftData struct WorldListToolbarModifier : ViewModifier { @Binding var isSelecting : Bool @Binding var selectedWorlds : Set + + @Environment(\.modelContext) private var context + let worldsIsEmpty : Bool + let worlds : [World] + func body(content: Content) -> some View { content @@ -23,15 +29,18 @@ struct WorldListToolbarModifier : ViewModifier { isSelecting = false } } else { - Button("Sélectionner") { - isSelecting = true + Button { + // + }label: { + Image(systemName: "line.3.horizontal.decrease") } } } } - ToolbarItem(placement: .topBarTrailing) { - if !isSelecting { + + if !isSelecting { + ToolbarItem(placement: .topBarTrailing) { NavigationLink { CreateWorldView() } label: { @@ -39,6 +48,40 @@ struct WorldListToolbarModifier : ViewModifier { } } } + + if isSelecting && !selectedWorlds.isEmpty { + ToolbarItemGroup(placement: .bottomBar) { + Button { + let worldsToAction = worlds.filter { selectedWorlds.contains($0.id) } + for world in worldsToAction { + context.insert(world.duplicate()) + } + } label: { + Image(systemName: "plus.square.on.square") + } + .disabled(selectedWorlds.isEmpty) + + Spacer() + + + Button(role: .destructive) { + let worldsToAction = worlds.filter { selectedWorlds.contains($0.id) } + let shouldExitSelection = worldsToAction.count == worlds.count + + for world in worldsToAction { + context.delete(world) + } + selectedWorlds.removeAll() + + if shouldExitSelection { + isSelecting = false + } + } label: { + Image(systemName: "trash") + } + .disabled(selectedWorlds.isEmpty) + } + } } } } diff --git a/WorldBuilder/Views/WorldList/WorldListView.swift b/WorldBuilder/Views/WorldList/WorldListView.swift index 10d45b6..7cff455 100644 --- a/WorldBuilder/Views/WorldList/WorldListView.swift +++ b/WorldBuilder/Views/WorldList/WorldListView.swift @@ -1,52 +1,60 @@ -// -// WorldListView.swift -// -// -// Created by Giovanni Josserand on 01/09/2026. -// + // + // WorldListView.swift + // + // + // Created by Giovanni Josserand on 01/09/2026. + // -import SwiftUI -import SwiftData + import SwiftUI + import SwiftData -struct WorldListView: View { - @Environment(\.modelContext) private var context - @Query(sort: \World.createdAt, order: .reverse) - private var worlds: [World] - let columns = [GridItem(.flexible()), GridItem(.flexible())] - - @State private var isSelecting = false - @State private var selectedWorlds = Set() - + struct WorldListView: View { + @Environment(\.modelContext) private var context + @Query(sort: \World.createdAt, order: .reverse) + private var worlds: [World] + let columns = [GridItem(.flexible()), GridItem(.flexible())] + + @State private var isSelecting = false + @State private var selectedWorlds = Set() + - var body: some View { - VStack(alignment: .leading, spacing: 24){ - - if worlds.isEmpty { - EmptyWorldView() - }else{ - ScrollView { - 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) + var body: some View { + VStack(alignment: .leading, spacing: 24){ + + if worlds.isEmpty { + EmptyWorldView() + }else{ + ScrollView { + LazyVGrid(columns: columns){ + ForEach(worlds) {world in + Group { + 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) + } } } - - }else { - NavigationLink{ - WorldOverviewView() - } label: { - WorldCardView(world: world) - } .contextMenu{ + Button { + isSelecting = true + selectedWorlds.insert(world.id) + } label: { + Label("Sélectionner", systemImage: "checkmark.circle") + } Button { context.insert(world.duplicate()) } label: { @@ -62,28 +70,21 @@ struct WorldListView: View { } } } + .scrollIndicators(.hidden) } - .scrollIndicators(.hidden) } - } - .navigationTitle("Bibliothèque") - .navigationBarTitleDisplayMode(.inline) - .padding(.horizontal, 8) - .frame(maxHeight: .infinity, alignment: .topLeading) - .modifier( - WorldListAreaInsetModifier( - isSelecting: $isSelecting, - selectedWorlds: $selectedWorlds, - worlds: worlds + .navigationTitle("Mes mondes") + .navigationBarTitleDisplayMode(.inline) + .padding(.horizontal, 8) + .frame(maxHeight: .infinity, alignment: .topLeading) + .modifier( + WorldListToolbarModifier( + isSelecting: $isSelecting, + selectedWorlds: $selectedWorlds, + worldsIsEmpty: worlds.isEmpty, + worlds: worlds + ) ) - ) - .modifier( - WorldListToolbarModifier( - isSelecting: $isSelecting, - selectedWorlds: $selectedWorlds, - worldsIsEmpty: worlds.isEmpty - ) - ) - + + } } -}