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 SwiftData
|
||||
|
||||
struct WorldListToolbarModifier : ViewModifier {
|
||||
@Binding var isSelecting : Bool
|
||||
@Binding var selectedWorlds : Set<World.ID>
|
||||
|
||||
@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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<World.ID>()
|
||||
|
||||
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<World.ID>()
|
||||
|
||||
|
||||
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
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user