mirror of
https://github.com/dscyrescotti/Memola.git
synced 2026-07-06 12:55:14 +02:00
feat: add placeholder for empty state
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
EC0D14282BF7BF20009BFE5F /* ContextMenuViewModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC0D14272BF7BF20009BFE5F /* ContextMenuViewModifier.swift */; };
|
EC0D14282BF7BF20009BFE5F /* ContextMenuViewModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC0D14272BF7BF20009BFE5F /* ContextMenuViewModifier.swift */; };
|
||||||
EC1815082C2D980B00541369 /* Sort.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC1815072C2D980B00541369 /* Sort.swift */; };
|
EC1815082C2D980B00541369 /* Sort.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC1815072C2D980B00541369 /* Sort.swift */; };
|
||||||
EC18150A2C2DA09E00541369 /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC1815092C2DA09E00541369 /* Filter.swift */; };
|
EC18150A2C2DA09E00541369 /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC1815092C2DA09E00541369 /* Filter.swift */; };
|
||||||
|
EC18150D2C2DAC3700541369 /* Placeholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC18150C2C2DAC3700541369 /* Placeholder.swift */; };
|
||||||
EC1B783D2BFA0AC9005A34E2 /* Toolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC1B783C2BFA0AC9005A34E2 /* Toolbar.swift */; };
|
EC1B783D2BFA0AC9005A34E2 /* Toolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC1B783C2BFA0AC9005A34E2 /* Toolbar.swift */; };
|
||||||
EC2106AD2C10C2A700FBE27C /* AnyStroke.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC2106AC2C10C2A700FBE27C /* AnyStroke.swift */; };
|
EC2106AD2C10C2A700FBE27C /* AnyStroke.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC2106AC2C10C2A700FBE27C /* AnyStroke.swift */; };
|
||||||
EC2BEBF42C0F5FF7005DB0AF /* RTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC2BEBF32C0F5FF7005DB0AF /* RTree.swift */; };
|
EC2BEBF42C0F5FF7005DB0AF /* RTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC2BEBF32C0F5FF7005DB0AF /* RTree.swift */; };
|
||||||
@@ -121,6 +122,7 @@
|
|||||||
EC0D14272BF7BF20009BFE5F /* ContextMenuViewModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextMenuViewModifier.swift; sourceTree = "<group>"; };
|
EC0D14272BF7BF20009BFE5F /* ContextMenuViewModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextMenuViewModifier.swift; sourceTree = "<group>"; };
|
||||||
EC1815072C2D980B00541369 /* Sort.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sort.swift; sourceTree = "<group>"; };
|
EC1815072C2D980B00541369 /* Sort.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sort.swift; sourceTree = "<group>"; };
|
||||||
EC1815092C2DA09E00541369 /* Filter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Filter.swift; sourceTree = "<group>"; };
|
EC1815092C2DA09E00541369 /* Filter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Filter.swift; sourceTree = "<group>"; };
|
||||||
|
EC18150C2C2DAC3700541369 /* Placeholder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Placeholder.swift; sourceTree = "<group>"; };
|
||||||
EC1B783C2BFA0AC9005A34E2 /* Toolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Toolbar.swift; sourceTree = "<group>"; };
|
EC1B783C2BFA0AC9005A34E2 /* Toolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Toolbar.swift; sourceTree = "<group>"; };
|
||||||
EC2106AC2C10C2A700FBE27C /* AnyStroke.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyStroke.swift; sourceTree = "<group>"; };
|
EC2106AC2C10C2A700FBE27C /* AnyStroke.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyStroke.swift; sourceTree = "<group>"; };
|
||||||
EC2BEBF32C0F5FF7005DB0AF /* RTree.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RTree.swift; sourceTree = "<group>"; };
|
EC2BEBF32C0F5FF7005DB0AF /* RTree.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RTree.swift; sourceTree = "<group>"; };
|
||||||
@@ -251,9 +253,18 @@
|
|||||||
path = ViewController;
|
path = ViewController;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
EC18150B2C2DA3AD00541369 /* Placeholder */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
EC18150C2C2DAC3700541369 /* Placeholder.swift */,
|
||||||
|
);
|
||||||
|
path = Placeholder;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
EC1B783A2BF9C68C005A34E2 /* Views */ = {
|
EC1B783A2BF9C68C005A34E2 /* Views */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
EC18150B2C2DA3AD00541369 /* Placeholder */,
|
||||||
ECBE529B2C1D94A4006BDB3D /* CameraView */,
|
ECBE529B2C1D94A4006BDB3D /* CameraView */,
|
||||||
ECFC51252BF8885000D0D051 /* ColorPicker */,
|
ECFC51252BF8885000D0D051 /* ColorPicker */,
|
||||||
);
|
);
|
||||||
@@ -973,6 +984,7 @@
|
|||||||
ECA738BC2BE60E0300A4542E /* Tool.swift in Sources */,
|
ECA738BC2BE60E0300A4542E /* Tool.swift in Sources */,
|
||||||
ECA738972BE6014200A4542E /* Graphic.metal in Sources */,
|
ECA738972BE6014200A4542E /* Graphic.metal in Sources */,
|
||||||
ECA7388A2BE6006A00A4542E /* PipelineStates.swift in Sources */,
|
ECA7388A2BE6006A00A4542E /* PipelineStates.swift in Sources */,
|
||||||
|
EC18150D2C2DAC3700541369 /* Placeholder.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
//
|
||||||
|
// Placeholder.swift
|
||||||
|
// Memola
|
||||||
|
//
|
||||||
|
// Created by Dscyre Scotti on 6/27/24.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct Placeholder: View {
|
||||||
|
let info: Info
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack(spacing: 15) {
|
||||||
|
Image(systemName: info.icon)
|
||||||
|
.font(.system(size: 50))
|
||||||
|
.frame(width: 55, height: 55)
|
||||||
|
VStack(spacing: 3) {
|
||||||
|
Text(info.title)
|
||||||
|
.font(.title2)
|
||||||
|
.fontWeight(.bold)
|
||||||
|
.foregroundStyle(.primary)
|
||||||
|
Text(info.description)
|
||||||
|
.font(.callout)
|
||||||
|
.fontWeight(.regular)
|
||||||
|
.frame(minHeight: 50, alignment: .top)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
.padding()
|
||||||
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Placeholder {
|
||||||
|
struct Info {
|
||||||
|
let title: String
|
||||||
|
let description: String
|
||||||
|
let icon: String
|
||||||
|
|
||||||
|
static let memoNotFound: Info = {
|
||||||
|
let icon: String = "sparkle.magnifyingglass"
|
||||||
|
let title: String = "No Memos Found"
|
||||||
|
let description: String = "Explore your other memos or create your own."
|
||||||
|
return Placeholder.Info(title: title, description: description, icon: icon)
|
||||||
|
}()
|
||||||
|
|
||||||
|
static let memoEmpty: Info = {
|
||||||
|
let icon: String = "wand.and.stars"
|
||||||
|
let title: String = "No Memos"
|
||||||
|
let description: String = "Create a new memo to jot your thoughts or notes down."
|
||||||
|
return Placeholder.Info(title: title, description: description, icon: icon)
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -37,7 +37,7 @@ struct MemosView: View {
|
|||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationStack {
|
NavigationStack {
|
||||||
memoGrid
|
memoGrid
|
||||||
.navigationTitle("Memos")
|
.navigationTitle("Memola")
|
||||||
.searchable(text: $query, placement: .toolbar, prompt: Text("Search"))
|
.searchable(text: $query, placement: .toolbar, prompt: Text("Search"))
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarItemGroup(placement: .primaryAction) {
|
ToolbarItemGroup(placement: .primaryAction) {
|
||||||
@@ -98,17 +98,22 @@ struct MemosView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
var memoGrid: some View {
|
var memoGrid: some View {
|
||||||
GeometryReader { proxy in
|
if memoObjects.isEmpty {
|
||||||
let count = Int(proxy.size.width / cellWidth)
|
Placeholder(info: query.isEmpty ? .memoEmpty : .memoNotFound)
|
||||||
let columns: [GridItem] = .init(repeating: GridItem(.flexible(), spacing: 15), count: count)
|
} else {
|
||||||
ScrollView {
|
GeometryReader { proxy in
|
||||||
LazyVGrid(columns: columns, spacing: 15) {
|
let count = Int(proxy.size.width / cellWidth)
|
||||||
ForEach(memoObjects) { memo in
|
let columns: [GridItem] = .init(repeating: GridItem(.flexible(), spacing: 15), count: count)
|
||||||
memoCard(memo)
|
ScrollView {
|
||||||
|
LazyVGrid(columns: columns, spacing: 15) {
|
||||||
|
ForEach(memoObjects) { memo in
|
||||||
|
memoCard(memo)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
.padding()
|
||||||
}
|
}
|
||||||
.padding()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user