change List view UI disposition
This commit is contained in:
1 parent
21614116fc
commit
ae6197d855
3 files changed
+112
-126
No files matched your search
@@ -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<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){
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -6,11 +6,17 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import SwiftData
|
||||||
|
|
||||||
struct WorldListToolbarModifier : ViewModifier {
|
struct WorldListToolbarModifier : ViewModifier {
|
||||||
@Binding var isSelecting : Bool
|
@Binding var isSelecting : Bool
|
||||||
@Binding var selectedWorlds : Set<World.ID>
|
@Binding var selectedWorlds : Set<World.ID>
|
||||||
|
|
||||||
|
@Environment(\.modelContext) private var context
|
||||||
|
|
||||||
let worldsIsEmpty : Bool
|
let worldsIsEmpty : Bool
|
||||||
|
let worlds : [World]
|
||||||
|
|
||||||
|
|
||||||
func body(content: Content) -> some View {
|
func body(content: Content) -> some View {
|
||||||
content
|
content
|
||||||
@@ -23,15 +29,18 @@ struct WorldListToolbarModifier : ViewModifier {
|
|||||||
isSelecting = false
|
isSelecting = false
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Button("Sélectionner") {
|
Button {
|
||||||
isSelecting = true
|
//
|
||||||
|
}label: {
|
||||||
|
Image(systemName: "line.3.horizontal.decrease")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolbarItem(placement: .topBarTrailing) {
|
|
||||||
if !isSelecting {
|
if !isSelecting {
|
||||||
|
ToolbarItem(placement: .topBarTrailing) {
|
||||||
NavigationLink {
|
NavigationLink {
|
||||||
CreateWorldView()
|
CreateWorldView()
|
||||||
} label: {
|
} 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,52 +1,60 @@
|
|||||||
//
|
//
|
||||||
// WorldListView.swift
|
// WorldListView.swift
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Created by Giovanni Josserand on 01/09/2026.
|
// Created by Giovanni Josserand on 01/09/2026.
|
||||||
//
|
//
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import SwiftData
|
import SwiftData
|
||||||
|
|
||||||
struct WorldListView: View {
|
struct WorldListView: View {
|
||||||
@Environment(\.modelContext) private var context
|
@Environment(\.modelContext) private var context
|
||||||
@Query(sort: \World.createdAt, order: .reverse)
|
@Query(sort: \World.createdAt, order: .reverse)
|
||||||
private var worlds: [World]
|
private var worlds: [World]
|
||||||
let columns = [GridItem(.flexible()), GridItem(.flexible())]
|
let columns = [GridItem(.flexible()), GridItem(.flexible())]
|
||||||
|
|
||||||
@State private var isSelecting = false
|
@State private var isSelecting = false
|
||||||
@State private var selectedWorlds = Set<World.ID>()
|
@State private var selectedWorlds = Set<World.ID>()
|
||||||
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading, spacing: 24){
|
VStack(alignment: .leading, spacing: 24){
|
||||||
|
|
||||||
if worlds.isEmpty {
|
if worlds.isEmpty {
|
||||||
EmptyWorldView()
|
EmptyWorldView()
|
||||||
}else{
|
}else{
|
||||||
ScrollView {
|
ScrollView {
|
||||||
LazyVGrid(columns: columns){
|
LazyVGrid(columns: columns){
|
||||||
ForEach(worlds) {world in
|
ForEach(worlds) {world in
|
||||||
if isSelecting {
|
Group {
|
||||||
WorldCardView(
|
if isSelecting {
|
||||||
world: world,
|
WorldCardView(
|
||||||
isSelected: selectedWorlds.contains(world.id)
|
world: world,
|
||||||
)
|
isSelected: selectedWorlds.contains(world.id)
|
||||||
.onTapGesture {
|
)
|
||||||
if selectedWorlds.contains(world.id) {
|
.onTapGesture {
|
||||||
selectedWorlds.remove(world.id)
|
if selectedWorlds.contains(world.id) {
|
||||||
} else {
|
selectedWorlds.remove(world.id)
|
||||||
selectedWorlds.insert(world.id)
|
} else {
|
||||||
|
selectedWorlds.insert(world.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
NavigationLink{
|
||||||
|
WorldOverviewView()
|
||||||
|
} label: {
|
||||||
|
WorldCardView(world: world)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}else {
|
|
||||||
NavigationLink{
|
|
||||||
WorldOverviewView()
|
|
||||||
} label: {
|
|
||||||
WorldCardView(world: world)
|
|
||||||
}
|
|
||||||
.contextMenu{
|
.contextMenu{
|
||||||
|
Button {
|
||||||
|
isSelecting = true
|
||||||
|
selectedWorlds.insert(world.id)
|
||||||
|
} label: {
|
||||||
|
Label("Sélectionner", systemImage: "checkmark.circle")
|
||||||
|
}
|
||||||
Button {
|
Button {
|
||||||
context.insert(world.duplicate())
|
context.insert(world.duplicate())
|
||||||
} label: {
|
} label: {
|
||||||
@@ -62,28 +70,21 @@ struct WorldListView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.scrollIndicators(.hidden)
|
||||||
}
|
}
|
||||||
.scrollIndicators(.hidden)
|
|
||||||
}
|
}
|
||||||
}
|
.navigationTitle("Mes mondes")
|
||||||
.navigationTitle("Bibliothèque")
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.padding(.horizontal, 8)
|
||||||
.padding(.horizontal, 8)
|
.frame(maxHeight: .infinity, alignment: .topLeading)
|
||||||
.frame(maxHeight: .infinity, alignment: .topLeading)
|
.modifier(
|
||||||
.modifier(
|
WorldListToolbarModifier(
|
||||||
WorldListAreaInsetModifier(
|
isSelecting: $isSelecting,
|
||||||
isSelecting: $isSelecting,
|
selectedWorlds: $selectedWorlds,
|
||||||
selectedWorlds: $selectedWorlds,
|
worldsIsEmpty: worlds.isEmpty,
|
||||||
worlds: worlds
|
worlds: worlds
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
.modifier(
|
}
|
||||||
WorldListToolbarModifier(
|
|
||||||
isSelecting: $isSelecting,
|
|
||||||
selectedWorlds: $selectedWorlds,
|
|
||||||
worldsIsEmpty: worlds.isEmpty
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Reference in new issue
Block a user