mirror of
https://github.com/writeas/writefreely-swiftui-multiplatform.git
synced 2024-11-15 01:11:02 +00:00
Improve offline experience (#255)
This commit is contained in:
parent
5efdde96cc
commit
3f424b399a
@ -17,6 +17,14 @@ final class WriteFreelyModel: ObservableObject {
|
|||||||
@Published var hasError: Bool = false
|
@Published var hasError: Bool = false
|
||||||
var currentError: Error? {
|
var currentError: Error? {
|
||||||
didSet {
|
didSet {
|
||||||
|
if let localizedErrorDescription = currentError?.localizedDescription,
|
||||||
|
localizedErrorDescription == "The operation couldn’t be completed. (WriteFreely.WFError error -2.)",
|
||||||
|
!hasNetworkConnection {
|
||||||
|
#if DEBUG
|
||||||
|
print("⚠️ currentError is WriteFreely.WFError -2 and there is no network connection.")
|
||||||
|
#endif
|
||||||
|
currentError = NetworkError.noConnectionError
|
||||||
|
}
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
print("⚠️ currentError -> didSet \(currentError?.localizedDescription ?? "nil")")
|
print("⚠️ currentError -> didSet \(currentError?.localizedDescription ?? "nil")")
|
||||||
print(" > hasError was: \(self.hasError)")
|
print(" > hasError was: \(self.hasError)")
|
||||||
@ -66,6 +74,10 @@ final class WriteFreelyModel: ObservableObject {
|
|||||||
self.preferences.appearance = self.defaults.integer(forKey: WFDefaults.colorSchemeIntegerKey)
|
self.preferences.appearance = self.defaults.integer(forKey: WFDefaults.colorSchemeIntegerKey)
|
||||||
self.preferences.font = self.defaults.integer(forKey: WFDefaults.defaultFontIntegerKey)
|
self.preferences.font = self.defaults.integer(forKey: WFDefaults.defaultFontIntegerKey)
|
||||||
self.account.restoreState()
|
self.account.restoreState()
|
||||||
|
|
||||||
|
// Set the appearance
|
||||||
|
self.preferences.updateAppearance(to: Appearance(rawValue: self.preferences.appearance) ?? .system)
|
||||||
|
|
||||||
if self.account.isLoggedIn {
|
if self.account.isLoggedIn {
|
||||||
guard let serverURL = URL(string: self.account.server) else {
|
guard let serverURL = URL(string: self.account.server) else {
|
||||||
self.currentError = AccountError.invalidServerURL
|
self.currentError = AccountError.invalidServerURL
|
||||||
|
@ -59,14 +59,7 @@ struct ContentView: View {
|
|||||||
.withErrorHandling()
|
.withErrorHandling()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if os(macOS)
|
NoSelectedPostView(isConnected: $model.hasNetworkConnection)
|
||||||
Text("Select a post, or create a new local draft.")
|
|
||||||
.foregroundColor(.secondary)
|
|
||||||
.frame(width: 500, height: 500)
|
|
||||||
#else
|
|
||||||
Text("Select a post, or create a new local draft.")
|
|
||||||
.foregroundColor(.secondary)
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
.environmentObject(model)
|
.environmentObject(model)
|
||||||
.onChange(of: model.hasError) { value in
|
.onChange(of: model.hasError) { value in
|
||||||
|
29
Shared/Navigation/NoSelectedPostView.swift
Normal file
29
Shared/Navigation/NoSelectedPostView.swift
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct NoSelectedPostView: View {
|
||||||
|
@Binding var isConnected: Bool
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack(spacing: 8) {
|
||||||
|
Text("Select a post, or create a new local draft.")
|
||||||
|
if !isConnected {
|
||||||
|
Label("You are not connected to the internet", systemImage: "wifi.exclamationmark")
|
||||||
|
.font(.caption)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.frame(width: 500, height: 500)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct NoSelectedPostViewIsDisconnected_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
NoSelectedPostView(isConnected: Binding.constant(true))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct NoSelectedPostViewIsConnected_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
NoSelectedPostView(isConnected: Binding.constant(false))
|
||||||
|
}
|
||||||
|
}
|
@ -97,6 +97,7 @@ struct PostListView: View {
|
|||||||
.padding(.vertical, 4)
|
.padding(.vertical, 4)
|
||||||
.padding(.horizontal, 8)
|
.padding(.horizontal, 8)
|
||||||
} else {
|
} else {
|
||||||
|
if model.hasNetworkConnection {
|
||||||
Button(action: {
|
Button(action: {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
model.fetchUserCollections()
|
model.fetchUserCollections()
|
||||||
@ -110,6 +111,12 @@ struct PostListView: View {
|
|||||||
.accessibilityLabel(Text("Refresh Posts"))
|
.accessibilityLabel(Text("Refresh Posts"))
|
||||||
.accessibilityHint(Text("Fetch changes from the server"))
|
.accessibilityHint(Text("Fetch changes from the server"))
|
||||||
.disabled(!model.account.isLoggedIn)
|
.disabled(!model.account.isLoggedIn)
|
||||||
|
} else {
|
||||||
|
Image(systemName: "wifi.exclamationmark")
|
||||||
|
.padding(.vertical, 4)
|
||||||
|
.padding(.horizontal, 8)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(.top, 8)
|
.padding(.top, 8)
|
||||||
|
@ -1,21 +1,25 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
enum Appearance: Int {
|
||||||
|
case system = 0
|
||||||
|
case light = 1
|
||||||
|
case dark = 2
|
||||||
|
}
|
||||||
|
|
||||||
class PreferencesModel: ObservableObject {
|
class PreferencesModel: ObservableObject {
|
||||||
private let defaults = UserDefaults.shared
|
private let defaults = UserDefaults.shared
|
||||||
|
|
||||||
/* We're stuck dropping into AppKit/UIKit to set light/dark schemes for now,
|
@Published var selectedColorScheme: ColorScheme?
|
||||||
* because setting the .preferredColorScheme modifier on views in SwiftUI is
|
@Published var appearance: Int = 0
|
||||||
* currently unreliable.
|
@Published var font: Int = 0 {
|
||||||
*
|
didSet {
|
||||||
* Feedback submitted to Apple:
|
defaults.set(font, forKey: WFDefaults.defaultFontIntegerKey)
|
||||||
*
|
}
|
||||||
* FB8382883: "On macOS 11β4, preferredColorScheme modifier does not respect .light ColorScheme"
|
}
|
||||||
* FB8383053: "On iOS 14β4/macOS 11β4, it is not possible to unset preferredColorScheme after setting
|
|
||||||
* it to either .light or .dark"
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if os(iOS)
|
|
||||||
@available(iOSApplicationExtension, unavailable)
|
@available(iOSApplicationExtension, unavailable)
|
||||||
|
func updateAppearance(to appearance: Appearance) {
|
||||||
|
#if os(iOS)
|
||||||
var window: UIWindow? {
|
var window: UIWindow? {
|
||||||
guard let scene = UIApplication.shared.connectedScenes.first,
|
guard let scene = UIApplication.shared.connectedScenes.first,
|
||||||
let windowSceneDelegate = scene.delegate as? UIWindowSceneDelegate,
|
let windowSceneDelegate = scene.delegate as? UIWindowSceneDelegate,
|
||||||
@ -26,42 +30,25 @@ class PreferencesModel: ObservableObject {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@available(iOSApplicationExtension, unavailable)
|
|
||||||
@Published var selectedColorScheme: ColorScheme?
|
|
||||||
|
|
||||||
@available(iOSApplicationExtension, unavailable)
|
|
||||||
@Published var appearance: Int = 0 {
|
|
||||||
didSet {
|
|
||||||
switch appearance {
|
switch appearance {
|
||||||
case 1:
|
case .light:
|
||||||
// selectedColorScheme = .light
|
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
NSApp.appearance = NSAppearance(named: .aqua)
|
NSApp.appearance = NSAppearance(named: .aqua)
|
||||||
#else
|
#else
|
||||||
window?.overrideUserInterfaceStyle = .light
|
window?.overrideUserInterfaceStyle = .light
|
||||||
#endif
|
#endif
|
||||||
case 2:
|
case .dark:
|
||||||
// selectedColorScheme = .dark
|
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
NSApp.appearance = NSAppearance(named: .darkAqua)
|
NSApp.appearance = NSAppearance(named: .darkAqua)
|
||||||
#else
|
#else
|
||||||
window?.overrideUserInterfaceStyle = .dark
|
window?.overrideUserInterfaceStyle = .dark
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
// selectedColorScheme = .none
|
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
NSApp.appearance = nil
|
NSApp.appearance = nil
|
||||||
#else
|
#else
|
||||||
window?.overrideUserInterfaceStyle = .unspecified
|
window?.overrideUserInterfaceStyle = .unspecified
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
defaults.set(appearance, forKey: WFDefaults.colorSchemeIntegerKey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Published var font: Int = 0 {
|
|
||||||
didSet {
|
|
||||||
defaults.set(font, forKey: WFDefaults.defaultFontIntegerKey)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,28 @@ import SwiftUI
|
|||||||
struct PreferencesView: View {
|
struct PreferencesView: View {
|
||||||
@ObservedObject var preferences: PreferencesModel
|
@ObservedObject var preferences: PreferencesModel
|
||||||
|
|
||||||
|
/* We're stuck dropping into AppKit/UIKit to set light/dark schemes for now,
|
||||||
|
* because setting the .preferredColorScheme modifier on views in SwiftUI is
|
||||||
|
* currently unreliable.
|
||||||
|
*
|
||||||
|
* Feedback submitted to Apple:
|
||||||
|
*
|
||||||
|
* FB8382883: "On macOS 11β4, preferredColorScheme modifier does not respect .light ColorScheme"
|
||||||
|
* FB8383053: "On iOS 14β4/macOS 11β4, it is not possible to unset preferredColorScheme after setting
|
||||||
|
* it to either .light or .dark"
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if os(iOS)
|
||||||
|
var window: UIWindow? {
|
||||||
|
guard let scene = UIApplication.shared.connectedScenes.first,
|
||||||
|
let windowSceneDelegate = scene.delegate as? UIWindowSceneDelegate,
|
||||||
|
let window = windowSceneDelegate.window else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return window
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack {
|
VStack {
|
||||||
VStack {
|
VStack {
|
||||||
@ -46,6 +68,10 @@ struct PreferencesView: View {
|
|||||||
}
|
}
|
||||||
.padding(.bottom)
|
.padding(.bottom)
|
||||||
}
|
}
|
||||||
|
.onChange(of: preferences.appearance) { value in
|
||||||
|
preferences.updateAppearance(to: Appearance(rawValue: value) ?? .system)
|
||||||
|
UserDefaults.shared.set(value, forKey: WFDefaults.colorSchemeIntegerKey)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,6 +136,8 @@
|
|||||||
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 */; };
|
17E5DF8A2543610700DCDC9B /* PostTextEditingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17E5DF892543610700DCDC9B /* PostTextEditingView.swift */; };
|
||||||
|
37095AE02AA4A0E700C9C5F8 /* NoSelectedPostView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37113EF82A98C10A00B36B98 /* NoSelectedPostView.swift */; };
|
||||||
|
37113EF92A98C10A00B36B98 /* NoSelectedPostView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37113EF82A98C10A00B36B98 /* NoSelectedPostView.swift */; };
|
||||||
375A67E828FC555C007A1AC0 /* MultilineTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 375A67E728FC555C007A1AC0 /* MultilineTextView.swift */; };
|
375A67E828FC555C007A1AC0 /* MultilineTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 375A67E728FC555C007A1AC0 /* MultilineTextView.swift */; };
|
||||||
3779389729EC0C880032D6C1 /* HelpCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3779389629EC0C880032D6C1 /* HelpCommands.swift */; };
|
3779389729EC0C880032D6C1 /* HelpCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3779389629EC0C880032D6C1 /* HelpCommands.swift */; };
|
||||||
37F749D129B4D3090087F0BF /* SearchablePostListFilteredView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37F749D029B4D3090087F0BF /* SearchablePostListFilteredView.swift */; };
|
37F749D129B4D3090087F0BF /* SearchablePostListFilteredView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37F749D029B4D3090087F0BF /* SearchablePostListFilteredView.swift */; };
|
||||||
@ -270,6 +272,7 @@
|
|||||||
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>"; };
|
17E5DF892543610700DCDC9B /* PostTextEditingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostTextEditingView.swift; sourceTree = "<group>"; };
|
||||||
|
37113EF82A98C10A00B36B98 /* NoSelectedPostView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoSelectedPostView.swift; sourceTree = "<group>"; };
|
||||||
375A67E728FC555C007A1AC0 /* MultilineTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultilineTextView.swift; sourceTree = "<group>"; };
|
375A67E728FC555C007A1AC0 /* MultilineTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultilineTextView.swift; sourceTree = "<group>"; };
|
||||||
3779389629EC0C880032D6C1 /* HelpCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HelpCommands.swift; sourceTree = "<group>"; };
|
3779389629EC0C880032D6C1 /* HelpCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HelpCommands.swift; sourceTree = "<group>"; };
|
||||||
37F749D029B4D3090087F0BF /* SearchablePostListFilteredView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchablePostListFilteredView.swift; sourceTree = "<group>"; };
|
37F749D029B4D3090087F0BF /* SearchablePostListFilteredView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchablePostListFilteredView.swift; sourceTree = "<group>"; };
|
||||||
@ -586,6 +589,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
17DF328224C87D3300BCE2E3 /* ContentView.swift */,
|
17DF328224C87D3300BCE2E3 /* ContentView.swift */,
|
||||||
|
37113EF82A98C10A00B36B98 /* NoSelectedPostView.swift */,
|
||||||
);
|
);
|
||||||
path = Navigation;
|
path = Navigation;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -922,6 +926,7 @@
|
|||||||
173E19D1254318F600440F0F /* RemoteChangePromptView.swift in Sources */,
|
173E19D1254318F600440F0F /* RemoteChangePromptView.swift in Sources */,
|
||||||
17B37C5625C8679800FE75E9 /* WriteFreelyModel+API.swift in Sources */,
|
17B37C5625C8679800FE75E9 /* WriteFreelyModel+API.swift in Sources */,
|
||||||
17C42E622507D8E600072984 /* PostStatus.swift in Sources */,
|
17C42E622507D8E600072984 /* PostStatus.swift in Sources */,
|
||||||
|
37095AE02AA4A0E700C9C5F8 /* NoSelectedPostView.swift in Sources */,
|
||||||
1756DBBA24FED45500207AB8 /* LocalStorageManager.swift in Sources */,
|
1756DBBA24FED45500207AB8 /* LocalStorageManager.swift in Sources */,
|
||||||
1727526A2809991A003D0A6A /* ErrorHandling.swift in Sources */,
|
1727526A2809991A003D0A6A /* ErrorHandling.swift in Sources */,
|
||||||
1756AE8124CB844500FD7257 /* View+Keyboard.swift in Sources */,
|
1756AE8124CB844500FD7257 /* View+Keyboard.swift in Sources */,
|
||||||
@ -975,6 +980,7 @@
|
|||||||
17120DAA24E1B2F5002B9F6C /* AccountLogoutView.swift in Sources */,
|
17120DAA24E1B2F5002B9F6C /* AccountLogoutView.swift in Sources */,
|
||||||
17DF32D624C8CA3400BCE2E3 /* PostStatusBadgeView.swift in Sources */,
|
17DF32D624C8CA3400BCE2E3 /* PostStatusBadgeView.swift in Sources */,
|
||||||
172C492E2593981900E20ADF /* MacUpdatesView.swift in Sources */,
|
172C492E2593981900E20ADF /* MacUpdatesView.swift in Sources */,
|
||||||
|
37113EF92A98C10A00B36B98 /* NoSelectedPostView.swift in Sources */,
|
||||||
1727526728099802003D0A6A /* ErrorConstants.swift in Sources */,
|
1727526728099802003D0A6A /* ErrorConstants.swift in Sources */,
|
||||||
17479F152583D8E40072B7FB /* PostEditorSharingPicker.swift in Sources */,
|
17479F152583D8E40072B7FB /* PostEditorSharingPicker.swift in Sources */,
|
||||||
17480CA6251272EE00EB7765 /* Bundle+AppVersion.swift in Sources */,
|
17480CA6251272EE00EB7765 /* Bundle+AppVersion.swift in Sources */,
|
||||||
@ -1060,7 +1066,7 @@
|
|||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||||
CODE_SIGN_ENTITLEMENTS = "ActionExtension-iOS/ActionExtension-iOS.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "ActionExtension-iOS/ActionExtension-iOS.entitlements";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 704;
|
CURRENT_PROJECT_VERSION = 706;
|
||||||
DEVELOPMENT_TEAM = TPPAB4YBA6;
|
DEVELOPMENT_TEAM = TPPAB4YBA6;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_FILE = "ActionExtension-iOS/Info.plist";
|
INFOPLIST_FILE = "ActionExtension-iOS/Info.plist";
|
||||||
@ -1072,7 +1078,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.16;
|
MARKETING_VERSION = 1.0.17;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.abunchtell.WriteFreely-MultiPlatform.ActionExtension-iOS";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.abunchtell.WriteFreely-MultiPlatform.ActionExtension-iOS";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
@ -1091,7 +1097,7 @@
|
|||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||||
CODE_SIGN_ENTITLEMENTS = "ActionExtension-iOS/ActionExtension-iOS.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "ActionExtension-iOS/ActionExtension-iOS.entitlements";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 704;
|
CURRENT_PROJECT_VERSION = 706;
|
||||||
DEVELOPMENT_TEAM = TPPAB4YBA6;
|
DEVELOPMENT_TEAM = TPPAB4YBA6;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_FILE = "ActionExtension-iOS/Info.plist";
|
INFOPLIST_FILE = "ActionExtension-iOS/Info.plist";
|
||||||
@ -1103,7 +1109,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.16;
|
MARKETING_VERSION = 1.0.17;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.abunchtell.WriteFreely-MultiPlatform.ActionExtension-iOS";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.abunchtell.WriteFreely-MultiPlatform.ActionExtension-iOS";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
@ -1234,7 +1240,7 @@
|
|||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CODE_SIGN_ENTITLEMENTS = "WriteFreely-MultiPlatform (iOS).entitlements";
|
CODE_SIGN_ENTITLEMENTS = "WriteFreely-MultiPlatform (iOS).entitlements";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 704;
|
CURRENT_PROJECT_VERSION = 706;
|
||||||
DEVELOPMENT_TEAM = TPPAB4YBA6;
|
DEVELOPMENT_TEAM = TPPAB4YBA6;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
INFOPLIST_FILE = iOS/Info.plist;
|
INFOPLIST_FILE = iOS/Info.plist;
|
||||||
@ -1243,7 +1249,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.16;
|
MARKETING_VERSION = 1.0.17;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.abunchtell.WriteFreely-MultiPlatform";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.abunchtell.WriteFreely-MultiPlatform";
|
||||||
PRODUCT_NAME = "WriteFreely-MultiPlatform";
|
PRODUCT_NAME = "WriteFreely-MultiPlatform";
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
@ -1260,7 +1266,7 @@
|
|||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CODE_SIGN_ENTITLEMENTS = "WriteFreely-MultiPlatform (iOS).entitlements";
|
CODE_SIGN_ENTITLEMENTS = "WriteFreely-MultiPlatform (iOS).entitlements";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 704;
|
CURRENT_PROJECT_VERSION = 706;
|
||||||
DEVELOPMENT_TEAM = TPPAB4YBA6;
|
DEVELOPMENT_TEAM = TPPAB4YBA6;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
INFOPLIST_FILE = iOS/Info.plist;
|
INFOPLIST_FILE = iOS/Info.plist;
|
||||||
@ -1269,7 +1275,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.16;
|
MARKETING_VERSION = 1.0.17;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.abunchtell.WriteFreely-MultiPlatform";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.abunchtell.WriteFreely-MultiPlatform";
|
||||||
PRODUCT_NAME = "WriteFreely-MultiPlatform";
|
PRODUCT_NAME = "WriteFreely-MultiPlatform";
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
|
@ -50,7 +50,10 @@ struct PostEditorView: View {
|
|||||||
PostEditorStatusToolbarView(post: post)
|
PostEditorStatusToolbarView(post: post)
|
||||||
}
|
}
|
||||||
ToolbarItem(placement: .primaryAction) {
|
ToolbarItem(placement: .primaryAction) {
|
||||||
if model.isProcessingRequest {
|
if !model.hasNetworkConnection {
|
||||||
|
Image(systemName: "wifi.exclamationmark")
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
} else if model.isProcessingRequest {
|
||||||
ProgressView()
|
ProgressView()
|
||||||
} else {
|
} else {
|
||||||
Menu(content: {
|
Menu(content: {
|
||||||
|
@ -115,6 +115,7 @@ final class CustomTextView: NSView {
|
|||||||
let scrollView = NSScrollView()
|
let scrollView = NSScrollView()
|
||||||
scrollView.drawsBackground = false
|
scrollView.drawsBackground = false
|
||||||
scrollView.borderType = .noBorder
|
scrollView.borderType = .noBorder
|
||||||
|
scrollView.autohidesScrollers = true
|
||||||
scrollView.hasVerticalScroller = true
|
scrollView.hasVerticalScroller = true
|
||||||
scrollView.hasHorizontalRuler = false
|
scrollView.hasHorizontalRuler = false
|
||||||
scrollView.autoresizingMask = [.width, .height]
|
scrollView.autoresizingMask = [.width, .height]
|
||||||
@ -167,6 +168,8 @@ final class CustomTextView: NSView {
|
|||||||
.font: font ?? NSFont.systemFont(ofSize: 17), // Fall back to system font if we can't unwrap font argument
|
.font: font ?? NSFont.systemFont(ofSize: 17), // Fall back to system font if we can't unwrap font argument
|
||||||
.foregroundColor: NSColor.labelColor
|
.foregroundColor: NSColor.labelColor
|
||||||
]
|
]
|
||||||
|
textView.textContainer?.lineFragmentPadding = 16
|
||||||
|
textView.textContainerInset = NSSize(width: 0, height: 16)
|
||||||
|
|
||||||
return textView
|
return textView
|
||||||
}()
|
}()
|
||||||
|
@ -9,11 +9,17 @@ struct PostEditorView: View {
|
|||||||
@State private var updatingFromServer: Bool = false
|
@State private var updatingFromServer: Bool = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
|
VStack {
|
||||||
|
if !model.hasNetworkConnection {
|
||||||
|
Label("You are not connected to the internet", systemImage: "wifi.exclamationmark")
|
||||||
|
.font(.caption)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
.padding(.top, 8)
|
||||||
|
}
|
||||||
PostTextEditingView(
|
PostTextEditingView(
|
||||||
post: post,
|
post: post,
|
||||||
updatingFromServer: $updatingFromServer
|
updatingFromServer: $updatingFromServer
|
||||||
)
|
)
|
||||||
.padding()
|
|
||||||
.background(Color(NSColor.controlBackgroundColor))
|
.background(Color(NSColor.controlBackgroundColor))
|
||||||
.onAppear(perform: {
|
.onAppear(perform: {
|
||||||
model.editor.setInitialValues(for: post)
|
model.editor.setInitialValues(for: post)
|
||||||
@ -69,6 +75,7 @@ struct PostEditorView: View {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PostEditorView_EmptyPostPreviews: PreviewProvider {
|
struct PostEditorView_EmptyPostPreviews: PreviewProvider {
|
||||||
|
@ -15,7 +15,8 @@ struct PostTextEditingView: View {
|
|||||||
if combinedText.count == 0 {
|
if combinedText.count == 0 {
|
||||||
Text("Write…")
|
Text("Write…")
|
||||||
.foregroundColor(Color(NSColor.placeholderTextColor))
|
.foregroundColor(Color(NSColor.placeholderTextColor))
|
||||||
.padding(.horizontal, 5)
|
.padding(.horizontal, 16)
|
||||||
|
.padding(.vertical, 16)
|
||||||
.font(.custom(appearance.rawValue, size: 17, relativeTo: .body))
|
.font(.custom(appearance.rawValue, size: 17, relativeTo: .body))
|
||||||
}
|
}
|
||||||
if post.appearance == "sans" {
|
if post.appearance == "sans" {
|
||||||
|
Loading…
Reference in New Issue
Block a user