Page MenuHomeMusing Studio

No OneTemporary

diff --git a/Shared/WriteFreely_MultiPlatformApp.swift b/Shared/WriteFreely_MultiPlatformApp.swift
index c05344a..bca2dd9 100644
--- a/Shared/WriteFreely_MultiPlatformApp.swift
+++ b/Shared/WriteFreely_MultiPlatformApp.swift
@@ -1,147 +1,149 @@
import SwiftUI
#if os(macOS)
import Sparkle
#endif
@main
struct CheckForDebugModifier {
static func main() {
#if os(macOS)
if NSEvent.modifierFlags.contains(.shift) {
// Clear the launch-to-last-draft values to load a new draft.
UserDefaults.standard.setValue(false, forKey: "showAllPostsFlag")
UserDefaults.standard.setValue(nil, forKey: "selectedCollectionURL")
UserDefaults.standard.setValue(nil, forKey: "lastDraftURL")
} else {
// No-op
}
#endif
WriteFreely_MultiPlatformApp.main()
}
}
struct WriteFreely_MultiPlatformApp: App {
@StateObject private var model = WriteFreelyModel()
#if os(macOS)
// swiftlint:disable:next weak_delegate
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
@State private var selectedTab = 0
#endif
var body: some Scene {
WindowGroup {
ContentView()
.onAppear(perform: {
if model.editor.showAllPostsFlag {
DispatchQueue.main.async {
self.model.selectedCollection = nil
self.model.showAllPosts = true
}
} else {
DispatchQueue.main.async {
self.model.selectedCollection = model.editor.fetchSelectedCollectionFromAppStorage()
self.model.showAllPosts = false
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
if model.editor.lastDraftURL != nil {
self.model.selectedPost = model.editor.fetchLastDraftFromAppStorage()
} else {
createNewLocalPost()
}
}
})
.environmentObject(model)
.environment(\.managedObjectContext, LocalStorageManager.persistentContainer.viewContext)
// .preferredColorScheme(preferences.selectedColorScheme) // See PreferencesModel for info.
}
.commands {
#if os(macOS)
CommandGroup(after: .appInfo, addition: {
Button("Check For Updates") {
SUUpdater.shared()?.checkForUpdates(self)
}
})
#endif
CommandGroup(replacing: .newItem, addition: {
Button("New Post") {
createNewLocalPost()
}
.keyboardShortcut("n", modifiers: [.command])
})
CommandGroup(after: .newItem) {
Button("Refresh Posts") {
DispatchQueue.main.async {
model.fetchUserCollections()
model.fetchUserPosts()
}
}
.disabled(!model.account.isLoggedIn)
.keyboardShortcut("r", modifiers: [.command])
}
SidebarCommands()
#if os(macOS)
PostCommands(model: model)
#endif
CommandGroup(after: .help) {
Button("Visit Support Forum") {
#if os(macOS)
NSWorkspace().open(model.helpURL)
#else
UIApplication.shared.open(model.helpURL)
#endif
}
}
+ ToolbarCommands()
+ TextEditingCommands()
}
#if os(macOS)
Settings {
TabView(selection: $selectedTab) {
MacAccountView()
.environmentObject(model)
.tabItem {
Image(systemName: "person.crop.circle")
Text("Account")
}
.tag(0)
MacPreferencesView(preferences: model.preferences)
.tabItem {
Image(systemName: "gear")
Text("Preferences")
}
.tag(1)
MacUpdatesView()
.tabItem {
Image(systemName: "arrow.down.circle")
Text("Updates")
}
.tag(2)
}
.frame(minWidth: 500, maxWidth: 500, minHeight: 200)
.padding()
// .preferredColorScheme(preferences.selectedColorScheme) // See PreferencesModel for info.
}
#endif
}
private func createNewLocalPost() {
withAnimation {
// Un-set the currently selected post
self.model.selectedPost = nil
// Navigate to the Drafts list
self.model.showAllPosts = false
self.model.selectedCollection = nil
}
// Create the new-post managed object
let managedPost = model.editor.generateNewLocalPost(withFont: model.preferences.font)
withAnimation {
// Set it as the selectedPost
DispatchQueue.main.asyncAfter(deadline: .now()) {
self.model.selectedPost = managedPost
}
}
}
}
diff --git a/macOS/PostEditor/MacEditorTextView.swift b/macOS/PostEditor/MacEditorTextView.swift
index 96bacc9..e5f8808 100644
--- a/macOS/PostEditor/MacEditorTextView.swift
+++ b/macOS/PostEditor/MacEditorTextView.swift
@@ -1,208 +1,212 @@
// Based on:
//
// MacEditorTextView
// Copyright (c) Thiago Holanda 2020
// https://twitter.com/tholanda
//
// MIT license
//
// See: https://gist.github.com/unnamedd/6e8c3fbc806b8deb60fa65d6b9affab0
import Combine
import SwiftUI
struct MacEditorTextView: NSViewRepresentable {
@Binding var text: String
var isFirstResponder: Bool = false
var isEditable: Bool = true
var font: NSFont? = NSFont(name: PostAppearance.serif.rawValue, size: 17)
var onEditingChanged: () -> Void = {}
var onCommit: () -> Void = {}
var onTextChange: (String) -> Void = { _ in }
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeNSView(context: Context) -> CustomTextView {
let textView = CustomTextView(
text: text,
isEditable: isEditable,
isFirstResponder: isFirstResponder,
font: font
)
textView.delegate = context.coordinator
return textView
}
func updateNSView(_ view: CustomTextView, context: Context) {
view.text = text
view.selectedRanges = context.coordinator.selectedRanges
}
}
// MARK: - Coordinator
extension MacEditorTextView {
class Coordinator: NSObject, NSTextViewDelegate {
var parent: MacEditorTextView
var selectedRanges: [NSValue] = []
var didBecomeFirstResponder: Bool = false
init(_ parent: MacEditorTextView) {
self.parent = parent
}
func textDidBeginEditing(_ notification: Notification) {
guard let textView = notification.object as? NSTextView else {
return
}
self.parent.text = textView.string
self.parent.onEditingChanged()
}
func textDidChange(_ notification: Notification) {
guard let textView = notification.object as? NSTextView else {
return
}
self.parent.text = textView.string
self.selectedRanges = textView.selectedRanges
self.parent.onTextChange(textView.string)
}
func textDidEndEditing(_ notification: Notification) {
guard let textView = notification.object as? NSTextView else {
return
}
self.parent.text = textView.string
self.parent.onCommit()
}
}
}
// MARK: - CustomTextView
final class CustomTextView: NSView {
private var isFirstResponder: Bool
private var isEditable: Bool
private var font: NSFont?
weak var delegate: NSTextViewDelegate?
var text: String {
didSet {
textView.string = text
}
}
var selectedRanges: [NSValue] = [] {
didSet {
guard selectedRanges.count > 0 else {
return
}
textView.selectedRanges = selectedRanges
}
}
private lazy var scrollView: NSScrollView = {
let scrollView = NSScrollView()
scrollView.drawsBackground = false
scrollView.borderType = .noBorder
scrollView.hasVerticalScroller = true
scrollView.hasHorizontalRuler = false
scrollView.autoresizingMask = [.width, .height]
scrollView.translatesAutoresizingMaskIntoConstraints = false
return scrollView
}()
private lazy var textView: NSTextView = {
let contentSize = scrollView.contentSize
let textStorage = NSTextStorage()
let layoutManager = NSLayoutManager()
textStorage.addLayoutManager(layoutManager)
let textContainer = NSTextContainer(containerSize: scrollView.frame.size)
textContainer.widthTracksTextView = true
textContainer.containerSize = NSSize(
width: contentSize.width,
height: CGFloat.greatestFiniteMagnitude
)
layoutManager.addTextContainer(textContainer)
let paragraphStyle = NSMutableParagraphStyle()
- paragraphStyle.lineSpacing = 8.5
+ let lineHeightMultiple: CGFloat = 1.5
+ paragraphStyle.lineHeightMultiple = lineHeightMultiple
let textView = NSTextView(frame: .zero, textContainer: textContainer)
textView.autoresizingMask = .width
textView.delegate = self.delegate
textView.drawsBackground = false
textView.font = self.font
textView.defaultParagraphStyle = paragraphStyle
textView.isEditable = self.isEditable
textView.isHorizontallyResizable = false
textView.isVerticallyResizable = true
textView.maxSize = NSSize(
width: CGFloat.greatestFiniteMagnitude,
height: CGFloat.greatestFiniteMagnitude
)
textView.minSize = NSSize(width: 0, height: contentSize.height)
textView.textColor = NSColor.labelColor
textView.allowsUndo = true
+ textView.usesFindPanel = true
+ textView.isAutomaticDashSubstitutionEnabled = false
+ textView.isRichText = false
return textView
}()
// MARK: - Init
init(text: String, isEditable: Bool, isFirstResponder: Bool, font: NSFont?) {
self.font = font
self.isFirstResponder = isFirstResponder
self.isEditable = isEditable
self.text = text
super.init(frame: .zero)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - Life cycle
override func viewWillDraw() {
super.viewWillDraw()
setupScrollViewConstraints()
setupTextView()
if isFirstResponder {
self.window?.makeFirstResponder(self.textView)
}
}
func setupScrollViewConstraints() {
scrollView.translatesAutoresizingMaskIntoConstraints = false
addSubview(scrollView)
NSLayoutConstraint.activate([
scrollView.topAnchor.constraint(equalTo: topAnchor),
scrollView.trailingAnchor.constraint(equalTo: trailingAnchor),
scrollView.bottomAnchor.constraint(equalTo: bottomAnchor),
scrollView.leadingAnchor.constraint(equalTo: leadingAnchor)
])
}
func setupTextView() {
scrollView.documentView = textView
}
}

File Metadata

Mime Type
text/x-diff
Expires
Mon, Jan 20, 2:31 AM (1 d, 13 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3136436

Event Timeline