mirror of
https://github.com/writeas/writefreely-swiftui-multiplatform.git
synced 2024-11-15 01:11:02 +00:00
Refactor text-editing views out of PostEditorView [Mac]
This commit is contained in:
parent
fea9160a15
commit
a542afa405
@ -1,6 +1,12 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import CoreData
|
import CoreData
|
||||||
|
|
||||||
|
enum PostAppearance: String {
|
||||||
|
case sans = "OpenSans-Regular"
|
||||||
|
case mono = "Hack"
|
||||||
|
case serif = "Lora"
|
||||||
|
}
|
||||||
|
|
||||||
struct PostEditorModel {
|
struct PostEditorModel {
|
||||||
let lastDraftObjectURLKey = "lastDraftObjectURLKey"
|
let lastDraftObjectURLKey = "lastDraftObjectURLKey"
|
||||||
private(set) var lastDraft: WFAPost?
|
private(set) var lastDraft: WFAPost?
|
||||||
|
@ -91,6 +91,7 @@
|
|||||||
17DFDE8A251D309400A25F31 /* Lora-Cyrillic-OFL.txt in Resources */ = {isa = PBXBuildFile; fileRef = 17DFDE85251D309400A25F31 /* Lora-Cyrillic-OFL.txt */; };
|
17DFDE8A251D309400A25F31 /* Lora-Cyrillic-OFL.txt in Resources */ = {isa = PBXBuildFile; fileRef = 17DFDE85251D309400A25F31 /* Lora-Cyrillic-OFL.txt */; };
|
||||||
17DFDE8B251D309400A25F31 /* OpenSans-License.txt in Resources */ = {isa = PBXBuildFile; fileRef = 17DFDE86251D309400A25F31 /* OpenSans-License.txt */; };
|
17DFDE8B251D309400A25F31 /* OpenSans-License.txt in Resources */ = {isa = PBXBuildFile; fileRef = 17DFDE86251D309400A25F31 /* OpenSans-License.txt */; };
|
||||||
17DFDE8C251D309400A25F31 /* OpenSans-License.txt in Resources */ = {isa = PBXBuildFile; fileRef = 17DFDE86251D309400A25F31 /* OpenSans-License.txt */; };
|
17DFDE8C251D309400A25F31 /* OpenSans-License.txt in Resources */ = {isa = PBXBuildFile; fileRef = 17DFDE86251D309400A25F31 /* OpenSans-License.txt */; };
|
||||||
|
17E5DF8A2543610700DCDC9B /* PostTextEditingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17E5DF892543610700DCDC9B /* PostTextEditingView.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
@ -174,6 +175,7 @@
|
|||||||
17DFDE84251D309400A25F31 /* Hack-License.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "Hack-License.txt"; sourceTree = "<group>"; };
|
17DFDE84251D309400A25F31 /* Hack-License.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "Hack-License.txt"; sourceTree = "<group>"; };
|
||||||
17DFDE85251D309400A25F31 /* Lora-Cyrillic-OFL.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "Lora-Cyrillic-OFL.txt"; sourceTree = "<group>"; };
|
17DFDE85251D309400A25F31 /* Lora-Cyrillic-OFL.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "Lora-Cyrillic-OFL.txt"; sourceTree = "<group>"; };
|
||||||
17DFDE86251D309400A25F31 /* OpenSans-License.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "OpenSans-License.txt"; sourceTree = "<group>"; };
|
17DFDE86251D309400A25F31 /* OpenSans-License.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "OpenSans-License.txt"; sourceTree = "<group>"; };
|
||||||
|
17E5DF892543610700DCDC9B /* PostTextEditingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostTextEditingView.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@ -300,6 +302,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
17A67CAE251A5DD7002F163D /* PostEditorView.swift */,
|
17A67CAE251A5DD7002F163D /* PostEditorView.swift */,
|
||||||
|
17E5DF892543610700DCDC9B /* PostTextEditingView.swift */,
|
||||||
);
|
);
|
||||||
path = PostEditor;
|
path = PostEditor;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -733,6 +736,7 @@
|
|||||||
17480CA6251272EE00EB7765 /* Bundle+AppVersion.swift in Sources */,
|
17480CA6251272EE00EB7765 /* Bundle+AppVersion.swift in Sources */,
|
||||||
17C42E662509237800072984 /* PostListFilteredView.swift in Sources */,
|
17C42E662509237800072984 /* PostListFilteredView.swift in Sources */,
|
||||||
17120DAD24E1B99F002B9F6C /* AccountLoginView.swift in Sources */,
|
17120DAD24E1B99F002B9F6C /* AccountLoginView.swift in Sources */,
|
||||||
|
17E5DF8A2543610700DCDC9B /* PostTextEditingView.swift in Sources */,
|
||||||
17C42E71250AAFD500072984 /* NSManagedObjectContext+ExecuteAndMergeChanges.swift in Sources */,
|
17C42E71250AAFD500072984 /* NSManagedObjectContext+ExecuteAndMergeChanges.swift in Sources */,
|
||||||
1756AE7B24CB65DF00FD7257 /* PostListView.swift in Sources */,
|
1756AE7B24CB65DF00FD7257 /* PostListView.swift in Sources */,
|
||||||
1753F6AC24E431CC00309365 /* MacPreferencesView.swift in Sources */,
|
1753F6AC24E431CC00309365 /* MacPreferencesView.swift in Sources */,
|
||||||
|
@ -1,11 +1,5 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
enum PostAppearance: String {
|
|
||||||
case sans = "OpenSans-Regular"
|
|
||||||
case mono = "Hack"
|
|
||||||
case serif = "Lora"
|
|
||||||
}
|
|
||||||
|
|
||||||
struct PostTextEditingView: View {
|
struct PostTextEditingView: View {
|
||||||
@Environment(\.horizontalSizeClass) var horizontalSizeClass
|
@Environment(\.horizontalSizeClass) var horizontalSizeClass
|
||||||
@ObservedObject var post: WFAPost
|
@ObservedObject var post: WFAPost
|
||||||
@ -45,7 +39,11 @@ struct PostTextEditingView: View {
|
|||||||
}
|
}
|
||||||
TextEditor(text: $post.body)
|
TextEditor(text: $post.body)
|
||||||
.font(.custom(appearance.rawValue, size: 17, relativeTo: .body))
|
.font(.custom(appearance.rawValue, size: 17, relativeTo: .body))
|
||||||
.lineSpacing(17 * (horizontalSizeClass == .compact ? 0.25 : bodyLineSpacingMultiplier))
|
.lineSpacing(
|
||||||
|
17 * (
|
||||||
|
horizontalSizeClass == .compact ? bodyLineSpacingMultiplier / 2 : bodyLineSpacingMultiplier
|
||||||
|
)
|
||||||
|
)
|
||||||
.onChange(of: post.body) { _ in
|
.onChange(of: post.body) { _ in
|
||||||
if post.status == PostStatus.published.rawValue && !updatingBodyFromServer {
|
if post.status == PostStatus.published.rawValue && !updatingBodyFromServer {
|
||||||
post.status = PostStatus.edited.rawValue
|
post.status = PostStatus.edited.rawValue
|
||||||
|
@ -10,129 +10,12 @@ struct PostEditorView: View {
|
|||||||
@State private var updatingBodyFromServer: Bool = false
|
@State private var updatingBodyFromServer: Bool = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack {
|
PostTextEditingView(
|
||||||
switch post.appearance {
|
post: post,
|
||||||
case "sans":
|
updatingTitleFromServer: $updatingTitleFromServer,
|
||||||
TextField("Title (optional)", text: $post.title)
|
updatingBodyFromServer: $updatingBodyFromServer
|
||||||
.textFieldStyle(PlainTextFieldStyle())
|
)
|
||||||
.padding(.horizontal, 4)
|
|
||||||
.padding(.bottom)
|
|
||||||
.font(.custom("OpenSans-Regular", size: 26, relativeTo: Font.TextStyle.largeTitle))
|
|
||||||
.onChange(of: post.title) { _ in
|
|
||||||
if post.status == PostStatus.published.rawValue && !updatingTitleFromServer {
|
|
||||||
post.status = PostStatus.edited.rawValue
|
|
||||||
}
|
|
||||||
if updatingTitleFromServer {
|
|
||||||
updatingTitleFromServer = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ZStack(alignment: .topLeading) {
|
|
||||||
if post.body.count == 0 {
|
|
||||||
Text("Write...")
|
|
||||||
.foregroundColor(Color(NSColor.placeholderTextColor))
|
|
||||||
.padding(.horizontal, 4)
|
|
||||||
.padding(.vertical, 2)
|
|
||||||
.font(.custom("OpenSans-Regular", size: 17, relativeTo: Font.TextStyle.body))
|
|
||||||
}
|
|
||||||
TextEditor(text: $post.body)
|
|
||||||
.font(.custom("OpenSans-Regular", size: 17, relativeTo: Font.TextStyle.body))
|
|
||||||
.lineSpacing(bodyLineSpacing)
|
|
||||||
.opacity(post.body.count == 0 && !isHovering ? 0.0 : 1.0)
|
|
||||||
.onChange(of: post.body) { _ in
|
|
||||||
if post.status == PostStatus.published.rawValue && !updatingBodyFromServer {
|
|
||||||
post.status = PostStatus.edited.rawValue
|
|
||||||
}
|
|
||||||
if updatingBodyFromServer {
|
|
||||||
updatingBodyFromServer = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.onHover(perform: { hovering in
|
|
||||||
self.isHovering = hovering
|
|
||||||
})
|
|
||||||
}
|
|
||||||
.background(Color(NSColor.controlBackgroundColor))
|
|
||||||
case "wrap", "mono", "code":
|
|
||||||
TextField("Title (optional)", text: $post.title)
|
|
||||||
.textFieldStyle(PlainTextFieldStyle())
|
|
||||||
.padding(.horizontal, 4)
|
|
||||||
.padding(.bottom)
|
|
||||||
.font(.custom("Hack", size: 26, relativeTo: Font.TextStyle.largeTitle))
|
|
||||||
.onChange(of: post.title) { _ in
|
|
||||||
if post.status == PostStatus.published.rawValue && !updatingTitleFromServer {
|
|
||||||
post.status = PostStatus.edited.rawValue
|
|
||||||
}
|
|
||||||
if updatingTitleFromServer {
|
|
||||||
updatingTitleFromServer = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ZStack(alignment: .topLeading) {
|
|
||||||
if post.body.count == 0 {
|
|
||||||
Text("Write...")
|
|
||||||
.foregroundColor(Color(NSColor.placeholderTextColor))
|
|
||||||
.padding(.horizontal, 4)
|
|
||||||
.padding(.vertical, 2)
|
|
||||||
.font(.custom("Hack", size: 17, relativeTo: Font.TextStyle.body))
|
|
||||||
}
|
|
||||||
TextEditor(text: $post.body)
|
|
||||||
.font(.custom("Hack", size: 17, relativeTo: Font.TextStyle.body))
|
|
||||||
.lineSpacing(bodyLineSpacing)
|
|
||||||
.opacity(post.body.count == 0 && !isHovering ? 0.0 : 1.0)
|
|
||||||
.onChange(of: post.body) { _ in
|
|
||||||
if post.status == PostStatus.published.rawValue && !updatingBodyFromServer {
|
|
||||||
post.status = PostStatus.edited.rawValue
|
|
||||||
}
|
|
||||||
if updatingBodyFromServer {
|
|
||||||
updatingBodyFromServer = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.onHover(perform: { hovering in
|
|
||||||
self.isHovering = hovering
|
|
||||||
})
|
|
||||||
}
|
|
||||||
.background(Color(NSColor.controlBackgroundColor))
|
|
||||||
default:
|
|
||||||
TextField("Title (optional)", text: $post.title)
|
|
||||||
.textFieldStyle(PlainTextFieldStyle())
|
|
||||||
.padding(.horizontal, 4)
|
|
||||||
.padding(.bottom)
|
|
||||||
.font(.custom("Lora", size: 26, relativeTo: Font.TextStyle.largeTitle))
|
|
||||||
.onChange(of: post.title) { _ in
|
|
||||||
if post.status == PostStatus.published.rawValue && !updatingTitleFromServer {
|
|
||||||
post.status = PostStatus.edited.rawValue
|
|
||||||
}
|
|
||||||
if updatingTitleFromServer {
|
|
||||||
updatingTitleFromServer = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ZStack(alignment: .topLeading) {
|
|
||||||
if post.body.count == 0 {
|
|
||||||
Text("Write...")
|
|
||||||
.foregroundColor(Color(NSColor.placeholderTextColor))
|
|
||||||
.padding(.horizontal, 4)
|
|
||||||
.padding(.vertical, 2)
|
|
||||||
.font(.custom("Lora", size: 17, relativeTo: Font.TextStyle.body))
|
|
||||||
}
|
|
||||||
TextEditor(text: $post.body)
|
|
||||||
.font(.custom("Lora", size: 17, relativeTo: Font.TextStyle.body))
|
|
||||||
.lineSpacing(bodyLineSpacing)
|
|
||||||
.opacity(post.body.count == 0 && !isHovering ? 0.0 : 1.0)
|
|
||||||
.onChange(of: post.body) { _ in
|
|
||||||
if post.status == PostStatus.published.rawValue && !updatingBodyFromServer {
|
|
||||||
post.status = PostStatus.edited.rawValue
|
|
||||||
}
|
|
||||||
if updatingBodyFromServer {
|
|
||||||
updatingBodyFromServer = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.onHover(perform: { hovering in
|
|
||||||
self.isHovering = hovering
|
|
||||||
})
|
|
||||||
}
|
|
||||||
.background(Color(NSColor.controlBackgroundColor))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.padding()
|
.padding()
|
||||||
.background(Color.white)
|
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarItem(placement: .status) {
|
ToolbarItem(placement: .status) {
|
||||||
PostEditorStatusToolbarView(post: post)
|
PostEditorStatusToolbarView(post: post)
|
||||||
@ -150,7 +33,7 @@ struct PostEditorView: View {
|
|||||||
}, label: {
|
}, label: {
|
||||||
Image(systemName: "paperplane")
|
Image(systemName: "paperplane")
|
||||||
})
|
})
|
||||||
.disabled(post.status == PostStatus.published.rawValue || || post.body.count == 0)
|
.disabled(post.status == PostStatus.published.rawValue || post.body.count == 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onChange(of: post.hasNewerRemoteCopy, perform: { _ in
|
.onChange(of: post.hasNewerRemoteCopy, perform: { _ in
|
||||||
|
66
macOS/PostEditor/PostTextEditingView.swift
Normal file
66
macOS/PostEditor/PostTextEditingView.swift
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct PostTextEditingView: View {
|
||||||
|
@ObservedObject var post: WFAPost
|
||||||
|
@Binding var updatingTitleFromServer: Bool
|
||||||
|
@Binding var updatingBodyFromServer: Bool
|
||||||
|
@State private var isHovering: Bool = false
|
||||||
|
@State private var appearance: PostAppearance = .serif
|
||||||
|
private let bodyLineSpacingMultiplier: CGFloat = 0.5
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack {
|
||||||
|
TextField("Title (optional)", text: $post.title)
|
||||||
|
.textFieldStyle(PlainTextFieldStyle())
|
||||||
|
.padding(.horizontal, 4)
|
||||||
|
.font(.custom(appearance.rawValue, size: 26, relativeTo: .largeTitle))
|
||||||
|
.onChange(of: post.title) { _ in
|
||||||
|
if post.status == PostStatus.published.rawValue && !updatingTitleFromServer {
|
||||||
|
post.status = PostStatus.edited.rawValue
|
||||||
|
}
|
||||||
|
if updatingTitleFromServer {
|
||||||
|
updatingTitleFromServer = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding(4)
|
||||||
|
.background(Color(NSColor.controlBackgroundColor))
|
||||||
|
.padding(.bottom)
|
||||||
|
ZStack(alignment: .topLeading) {
|
||||||
|
if post.body.count == 0 {
|
||||||
|
Text("Write…")
|
||||||
|
.foregroundColor(Color(NSColor.placeholderTextColor))
|
||||||
|
.padding(.horizontal, 4)
|
||||||
|
.padding(.vertical, 2)
|
||||||
|
.font(.custom(appearance.rawValue, size: 17, relativeTo: .body))
|
||||||
|
}
|
||||||
|
TextEditor(text: $post.body)
|
||||||
|
.font(.custom(appearance.rawValue, size: 17, relativeTo: .body))
|
||||||
|
.lineSpacing(17 * bodyLineSpacingMultiplier)
|
||||||
|
.opacity(post.body.count == 0 && !isHovering ? 0.0 : 1.0)
|
||||||
|
.onChange(of: post.body) { _ in
|
||||||
|
if post.status == PostStatus.published.rawValue && !updatingBodyFromServer {
|
||||||
|
post.status = PostStatus.edited.rawValue
|
||||||
|
}
|
||||||
|
if updatingBodyFromServer {
|
||||||
|
updatingBodyFromServer = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onHover(perform: { hovering in
|
||||||
|
self.isHovering = hovering
|
||||||
|
})
|
||||||
|
}
|
||||||
|
.padding(4)
|
||||||
|
.background(Color(NSColor.controlBackgroundColor))
|
||||||
|
}
|
||||||
|
.onAppear(perform: {
|
||||||
|
switch post.appearance {
|
||||||
|
case "sans":
|
||||||
|
self.appearance = .sans
|
||||||
|
case "wrap", "mono", "code":
|
||||||
|
self.appearance = .mono
|
||||||
|
default:
|
||||||
|
self.appearance = .serif
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user