mirror of
https://github.com/dscyrescotti/Memola.git
synced 2026-06-29 13:26:30 +02:00
feat: scroll to new added pen
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
// Created by Dscyre Scotti on 5/4/24.
|
// Created by Dscyre Scotti on 5/4/24.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import CoreData
|
import CoreData
|
||||||
import Foundation
|
import Foundation
|
||||||
@@ -19,6 +20,8 @@ public class Tool: NSObject, ObservableObject {
|
|||||||
@Published var isShaking: Bool = false
|
@Published var isShaking: Bool = false
|
||||||
@Published var shakingId: UUID = UUID()
|
@Published var shakingId: UUID = UUID()
|
||||||
|
|
||||||
|
let scrollPublisher = PassthroughSubject<String, Never>()
|
||||||
|
|
||||||
init(object: ToolObject) {
|
init(object: ToolObject) {
|
||||||
self.object = object
|
self.object = object
|
||||||
}
|
}
|
||||||
@@ -61,6 +64,7 @@ public class Tool: NSObject, ObservableObject {
|
|||||||
if let _pen = pen.object {
|
if let _pen = pen.object {
|
||||||
object.pens.add(_pen)
|
object.pens.add(_pen)
|
||||||
}
|
}
|
||||||
|
scrollPublisher.send(pen.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func removePen(_ pen: Pen) {
|
func removePen(_ pen: Pen) {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ struct PenToolView: View {
|
|||||||
let factor: CGFloat = 1.22
|
let factor: CGFloat = 1.22
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .trailing, spacing: 0) {
|
ScrollViewReader { proxy in
|
||||||
ScrollView(.vertical, showsIndicators: false) {
|
ScrollView(.vertical, showsIndicators: false) {
|
||||||
if tool.isReordering {
|
if tool.isReordering {
|
||||||
LazyVStack(spacing: 0) {
|
LazyVStack(spacing: 0) {
|
||||||
@@ -23,12 +23,14 @@ struct PenToolView: View {
|
|||||||
if pen.strokeStyle == .marker {
|
if pen.strokeStyle == .marker {
|
||||||
penView(pen)
|
penView(pen)
|
||||||
.offset(y: tool.isShaking ? 1.5 : -1.5)
|
.offset(y: tool.isShaking ? 1.5 : -1.5)
|
||||||
|
.id(pen.id)
|
||||||
} else {
|
} else {
|
||||||
penView(pen)
|
penView(pen)
|
||||||
|
.id(pen.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(.vertical, 5)
|
.padding(.vertical, 10)
|
||||||
.padding(.leading, 40)
|
.padding(.leading, 40)
|
||||||
.onAppear {
|
.onAppear {
|
||||||
withAnimation(.easeInOut.repeatForever().speed(5)) {
|
withAnimation(.easeInOut.repeatForever().speed(5)) {
|
||||||
@@ -40,23 +42,22 @@ struct PenToolView: View {
|
|||||||
LazyVStack(spacing: 0) {
|
LazyVStack(spacing: 0) {
|
||||||
ForEach(tool.pens) { pen in
|
ForEach(tool.pens) { pen in
|
||||||
penView(pen)
|
penView(pen)
|
||||||
|
.id(pen.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(.vertical, 5)
|
.padding(.vertical, 10)
|
||||||
.padding(.leading, 40)
|
.padding(.leading, 40)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
VStack(spacing: 0) {
|
.onReceive(tool.scrollPublisher) { id in
|
||||||
Divider()
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||||
if tool.isReordering {
|
withAnimation {
|
||||||
reorderCancelButton
|
proxy.scrollTo(id)
|
||||||
} else {
|
}
|
||||||
newPenButton
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.frame(width: width * factor - 20)
|
|
||||||
}
|
}
|
||||||
.frame(maxHeight: (height * factor + 10) * 8)
|
.frame(maxHeight:( (height * factor + 10) * 7) + 20)
|
||||||
.fixedSize()
|
.fixedSize()
|
||||||
.background {
|
.background {
|
||||||
HStack(spacing: 0) {
|
HStack(spacing: 0) {
|
||||||
@@ -66,6 +67,16 @@ struct PenToolView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.clipShape(.rect(cornerRadii: .init(bottomTrailing: 20, topTrailing: 20)))
|
.clipShape(.rect(cornerRadii: .init(bottomTrailing: 20, topTrailing: 20)))
|
||||||
|
.overlay(alignment: .bottomLeading) {
|
||||||
|
Group {
|
||||||
|
if tool.isReordering {
|
||||||
|
doneButton
|
||||||
|
} else {
|
||||||
|
newPenButton
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.offset(x: 60, y: 10)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
@@ -125,25 +136,33 @@ struct PenToolView: View {
|
|||||||
let _pen = Pen(object: pen)
|
let _pen = Pen(object: pen)
|
||||||
tool.addPen(_pen)
|
tool.addPen(_pen)
|
||||||
} label: {
|
} label: {
|
||||||
Image(systemName: "pencil.tip.crop.circle.badge.plus")
|
Image(systemName: "plus.circle.fill")
|
||||||
.font(.title2)
|
.font(.title2)
|
||||||
|
.padding(1)
|
||||||
.contentShape(.circle)
|
.contentShape(.circle)
|
||||||
|
.background {
|
||||||
|
Circle()
|
||||||
|
.fill(.white)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.foregroundStyle(.green)
|
.foregroundStyle(.green)
|
||||||
.hoverEffect(.lift)
|
.hoverEffect(.lift)
|
||||||
.padding(10)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var reorderCancelButton: some View {
|
var doneButton: some View {
|
||||||
Button {
|
Button {
|
||||||
tool.isReordering = false
|
tool.isReordering = false
|
||||||
} label: {
|
} label: {
|
||||||
Image(systemName: "xmark.circle")
|
Image(systemName: "xmark.circle")
|
||||||
.font(.title2)
|
.font(.title2)
|
||||||
|
.padding(1)
|
||||||
.contentShape(.circle)
|
.contentShape(.circle)
|
||||||
|
.background {
|
||||||
|
Circle()
|
||||||
|
.fill(.white)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.hoverEffect(.lift)
|
.hoverEffect(.lift)
|
||||||
.padding(10)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func penPreview(_ pen: Pen) -> some View {
|
func penPreview(_ pen: Pen) -> some View {
|
||||||
|
|||||||
Reference in New Issue
Block a user