Merge pull request #2282 from omnivore-app/fix/macos-build

Fixes to build on Macos
This commit is contained in:
Jackson Harper 2023-06-01 09:03:24 +08:00 committed by GitHub
commit 493a6fd88d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 236 additions and 115 deletions

View file

@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>

View file

@ -1388,7 +1388,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 80;
CURRENT_PROJECT_VERSION = 90;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = QJF2XZ86HB;
@ -1400,7 +1400,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 1.23.0;
MARKETING_VERSION = 1.27.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = app.omnivore.app;
@ -1423,7 +1423,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 80;
CURRENT_PROJECT_VERSION = 90;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = QJF2XZ86HB;
@ -1435,7 +1435,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 1.23.0;
MARKETING_VERSION = 1.27.0;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = app.omnivore.app;
PRODUCT_NAME = "$(TARGET_NAME)";

View file

@ -8,11 +8,14 @@ import Views
NSFont.userFont(ofSize: 16)?.pointSize ?? 16
)
@AppStorage(UserDefaultKey.preferredWebLineSpacing.rawValue) var storedLineSpacing = 150
@AppStorage(UserDefaultKey.preferredWebMaxWidthPercentage.rawValue) var storedMaxWidthPercentage = 100
@AppStorage(UserDefaultKey.enableHighlightOnRelease.rawValue) var enableHighlightOnRelease = false
@AppStorage(UserDefaultKey.preferredWebMaxWidthPercentage.rawValue) var storedMaxWidthPercentage = 80
@Binding var preferredFont: String
@Binding var prefersHighContrastText: Bool
@Binding var justifyText: Bool
@Binding var currentThemeName: String
@Environment(\.openURL) var openURL
public var fontSizeButtons: some View {
Group {
@ -83,16 +86,40 @@ import Views
}
}
public var resetButton: some View {
Group {
Button(
action: {
storedLineSpacing = max(storedLineSpacing - 25, 100)
ThemeManager.currentThemeName = Theme.system.rawValue
storedFontSize = 16
storedLineSpacing = 150
storedMaxWidthPercentage = 80
preferredFont = WebFont.inter.rawValue
prefersHighContrastText = true
NSNotification.readerSettingsChanged()
},
label: { Text("Reset") }
)
}
}
public init(
preferredFont: Binding<String>,
prefersHighContrastText: Binding<Bool>
prefersHighContrastText: Binding<Bool>,
justifyText: Binding<Bool>,
currentThemeName: Binding<String>
) {
self._preferredFont = preferredFont
self._prefersHighContrastText = prefersHighContrastText
self._justifyText = justifyText
self._currentThemeName = currentThemeName
}
public var body: some Commands {
CommandMenu("Reader Display") {
var spacingButtons: some View {
Group {
fontSizeButtons
Divider()
@ -104,6 +131,24 @@ import Views
lineSpacingButtons
Divider()
}
}
public var body: some Commands {
CommandGroup(after: .appInfo) {
Button("Open Online", action: {
if let url = URL(string: "https://omnivore.app/") {
NSWorkspace.shared.open(url)
}
})
}
CommandGroup(after: .appTermination) {
Button("Logout", action: {
NSNotification.logout()
})
}
CommandMenu("Reader Display") {
spacingButtons
Picker(selection: $preferredFont, label: Text(LocalText.genericFontFamily)) {
ForEach(WebFont.allCases, id: \.self) { font in
@ -111,15 +156,25 @@ import Views
}
}
Picker(selection: $currentThemeName, label: Text("Theme")) {
ForEach(Theme.allCases, id: \.self) { theme in
Text(theme.rawValue).tag(theme.rawValue).tag(theme.rawValue)
}
}
Toggle(
isOn: $prefersHighContrastText,
label: { Text(LocalText.genericHighContrastText) }
)
Toggle(
isOn: $enableHighlightOnRelease,
label: { Text(LocalText.genericHighContrastText) }
isOn: $justifyText,
label: { Text(LocalText.enableJustifyText) }
)
Divider()
resetButton
}
}
}

View file

@ -28,9 +28,7 @@ struct MacFeedCardNavigationLink: View {
.onAppear {
Task { await viewModel.itemAppeared(item: item, dataService: dataService) }
}
FeedCard(item: item, viewer: dataService.currentViewer) {
viewModel.selectedLinkItem = item.objectID
}
LibraryItemCard(item: item, viewer: dataService.currentViewer)
}
}
}

View file

@ -9,8 +9,11 @@ import Views
struct HomeFeedView: View {
@EnvironmentObject var dataService: DataService
@EnvironmentObject var audioController: AudioController
@EnvironmentObject var authenticator: Authenticator
@State private var itemToRemove: LinkedItem?
@State private var confirmationShown = false
@State private var presentProfileSheet = false
@ObservedObject var viewModel: HomeFeedViewModel
@ -35,63 +38,64 @@ import Views
}
}
List {
Section {
ForEach(viewModel.items) { item in
MacFeedCardNavigationLink(
item: item,
viewModel: viewModel
Spacer(minLength: 10)
ForEach(viewModel.items) { item in
MacFeedCardNavigationLink(
item: item,
viewModel: viewModel
)
.contextMenu {
Button(
action: { viewModel.itemUnderTitleEdit = item },
label: { Label("Edit Info", systemImage: "info.circle") }
)
.contextMenu {
Button(
action: { viewModel.itemUnderTitleEdit = item },
label: { Label("Edit Info", systemImage: "info.circle") }
)
Button(
action: { viewModel.itemUnderLabelEdit = item },
label: { Label(item.labels?.count == 0 ? "Add Labels" : "Edit Labels", systemImage: "tag") }
)
Button(action: {
withAnimation(.linear(duration: 0.4)) {
viewModel.setLinkArchived(
dataService: dataService,
objectID: item.objectID,
archived: !item.isArchived
)
}
}, label: {
Label(
item.isArchived ? "Unarchive" : "Archive",
systemImage: item.isArchived ? "tray.and.arrow.down.fill" : "archivebox"
Button(
action: { viewModel.itemUnderLabelEdit = item },
label: { Label(item.labels?.count == 0 ? "Add Labels" : "Edit Labels", systemImage: "tag") }
)
Button(action: {
withAnimation(.linear(duration: 0.4)) {
viewModel.setLinkArchived(
dataService: dataService,
objectID: item.objectID,
archived: !item.isArchived
)
})
Button(
action: {
itemToRemove = item
confirmationShown = true
},
label: { Label("Delete", systemImage: "trash") }
}
}, label: {
Label(
item.isArchived ? "Unarchive" : "Archive",
systemImage: item.isArchived ? "tray.and.arrow.down.fill" : "archivebox"
)
if FeatureFlag.enableSnooze {
Button {
viewModel.itemToSnoozeID = item.id
viewModel.snoozePresented = true
} label: {
Label { Text(LocalText.genericSnooze) } icon: { Image.moon }
}
})
Button(
action: {
itemToRemove = item
confirmationShown = true
},
label: { Label("Delete", systemImage: "trash") }
)
if FeatureFlag.enableSnooze {
Button {
viewModel.itemToSnoozeID = item.id
viewModel.snoozePresented = true
} label: {
Label { Text(LocalText.genericSnooze) } icon: { Image.moon }
}
}
}
Divider().padding(5)
}
if viewModel.isLoading {
LoadingSection()
}
}
.listStyle(PlainListStyle())
// .listStyle(PlainListStyle())
.navigationTitle("Home")
.searchable(
text: $viewModel.searchTerm,
placement: .toolbar
placement: .sidebar
) {
if viewModel.searchTerm.isEmpty {
Text(LocalText.inboxGeneric).searchCompletion("in:inbox ")
@ -143,6 +147,15 @@ import Views
.sheet(item: $viewModel.itemUnderTitleEdit) { item in
LinkedItemMetadataEditView(item: item)
}
.sheet(isPresented: $presentProfileSheet) {
ProfileView()
}
.onReceive(NSNotification.displayProfilePublisher) { _ in
presentProfileSheet = true
}
.onReceive(NSNotification.logoutPublisher) { _ in
authenticator.logout(dataService: dataService)
}
.task {
if viewModel.items.isEmpty {
loadItems(isRefresh: true)

View file

@ -1,4 +1,6 @@
import SwiftUI
import Utils
import Views
struct HomeView: View {
@StateObject private var viewModel = HomeFeedViewModel()
@ -22,6 +24,20 @@ struct HomeView: View {
}
#elseif os(macOS)
HomeFeedView(viewModel: viewModel)
.frame(minWidth: 320)
.toolbar {
ToolbarItem {
Button(
action: {
NSApp.keyWindow?.firstResponder?.tryToPerform(
#selector(NSSplitViewController.toggleSidebar(_:)), with: nil
)
},
label: { Label(LocalText.navigationSelectSidebarToggle, systemImage: "sidebar.left") }
)
}
}
#endif
}
}

View file

@ -72,9 +72,11 @@ struct ApplyLabelsView: View {
Image(systemName: "checkmark")
}
}
.contentShape(Rectangle())
}
)
.padding(.vertical, 5)
.frame(maxWidth: .infinity, alignment: .leading)
#if os(macOS)
.buttonStyle(PlainButtonStyle())
#endif

View file

@ -24,14 +24,7 @@ public struct PrimaryContentView: View {
#if os(macOS)
private var splitView: some View {
NavigationView {
// The first column is the sidebar.
PrimaryContentSidebar(categories: categories)
.navigationTitle("Categories")
// Second column is the Primary Nav Stack
PrimaryContentCategory.feed.destinationView
// Third column is the detail view
Text(LocalText.navigationSelectLink)
}
.accentColor(.appGrayTextContrast)

View file

@ -82,6 +82,7 @@ struct ProfileView: View {
innerBody
}
.listStyle(InsetListStyle())
.frame(minWidth: 400, minHeight: 400)
#endif
}

View file

@ -116,13 +116,15 @@ struct WebReader: PlatformViewRepresentable {
(webView as? OmnivoreWebView)?.updateTitle(title: item.title ?? "")
(webView as? OmnivoreWebView)?.updateJustifyText()
webView.backgroundColor = UIColor(ThemeManager.currentBgColor)
webView.tintColor = UIColor(ThemeManager.currentHighlightColor)
webView.underPageBackgroundColor = UIColor(ThemeManager.currentBgColor)
webView.scrollView.backgroundColor = UIColor(ThemeManager.currentBgColor)
webView.scrollView.indicatorStyle = ThemeManager.currentTheme.isDark ?
UIScrollView.IndicatorStyle.white :
UIScrollView.IndicatorStyle.black
#if os(iOS)
webView.backgroundColor = UIColor(ThemeManager.currentBgColor)
webView.tintColor = UIColor(ThemeManager.currentHighlightColor)
webView.underPageBackgroundColor = UIColor(ThemeManager.currentBgColor)
webView.scrollView.backgroundColor = UIColor(ThemeManager.currentBgColor)
webView.scrollView.indicatorStyle = ThemeManager.currentTheme.isDark ?
UIScrollView.IndicatorStyle.white :
UIScrollView.IndicatorStyle.black
#endif
}
if showNavBarActionID != context.coordinator.previousShowNavBarActionID {
@ -189,7 +191,7 @@ struct WebReader: PlatformViewRepresentable {
}
}()
let fontFamily = fontFamilyValue.flatMap { WebFont(rawValue: $0) } ?? .system
let fontFamily = fontFamilyValue.flatMap { WebFont(rawValue: $0) } ?? .atkinsonHyperlegible
let htmlString = WebReaderContent(
item: item,

View file

@ -288,30 +288,30 @@ struct WebReaderContainerView: View {
#if os(iOS)
audioNavbarItem
#endif
Button(
action: {
if UIDevice.current.userInterfaceIdiom == .phone {
showPreferencesFormsheet.toggle()
} else {
showPreferencesPopover.toggle()
Button(
action: {
if UIDevice.current.userInterfaceIdiom == .phone {
showPreferencesFormsheet.toggle()
} else {
showPreferencesPopover.toggle()
}
},
label: {
Image(systemName: "textformat.size")
.font(.appNavbarIcon)
}
},
label: {
Image(systemName: "textformat.size")
.font(.appNavbarIcon)
)
.padding(.horizontal, 5)
.scaleEffect(navBarVisibilityRatio)
.popover(isPresented: $showPreferencesPopover) {
webPreferencesPopoverView
.frame(maxWidth: 400, maxHeight: 475)
}
)
.padding(.horizontal, 5)
.scaleEffect(navBarVisibilityRatio)
.popover(isPresented: $showPreferencesPopover) {
webPreferencesPopoverView
.frame(maxWidth: 400, maxHeight: 475)
}
.formSheet(isPresented: $showPreferencesFormsheet, modalSize: CGSize(width: 400, height: 475)) {
webPreferencesPopoverView
}
.formSheet(isPresented: $showPreferencesFormsheet, modalSize: CGSize(width: 400, height: 475)) {
webPreferencesPopoverView
}
#endif
#if os(macOS)
Spacer()
@ -596,7 +596,9 @@ struct WebReaderContainerView: View {
#if os(iOS)
UIPasteboard.general.string = deepLink.absoluteString
#else
Pasteboard.general.string = deepLink.absoluteString
let pasteBoard = NSPasteboard.general
pasteBoard.clearContents()
pasteBoard.writeObjects([deepLink.absoluteString as NSString])
#endif
showInSnackbar("Deeplink Copied")
} else {

View file

@ -9,6 +9,8 @@ public extension NSNotification {
static let OperationFailure = Notification.Name("OperationFailure")
static let ReaderSettingsChanged = Notification.Name("ReaderSettingsChanged")
static let SpeakingReaderItem = Notification.Name("SpeakingReaderItem")
static let DisplayProfile = Notification.Name("DisplayProfile")
static let Logout = Notification.Name("Logout")
static var pushFeedItemPublisher: NotificationCenter.Publisher {
NotificationCenter.default.publisher(for: PushJSONArticle)
@ -34,6 +36,14 @@ public extension NSNotification {
NotificationCenter.default.publisher(for: SpeakingReaderItem)
}
static var displayProfilePublisher: NotificationCenter.Publisher {
NotificationCenter.default.publisher(for: DisplayProfile)
}
static var logoutPublisher: NotificationCenter.Publisher {
NotificationCenter.default.publisher(for: Logout)
}
internal var operationMessage: String? {
if let message = userInfo?["message"] as? String {
return message
@ -68,4 +78,12 @@ public extension NSNotification {
static func readerSettingsChanged() {
NotificationCenter.default.post(name: NSNotification.ReaderSettingsChanged, object: nil)
}
static func logout() {
NotificationCenter.default.post(name: NSNotification.Logout, object: nil)
}
static func displayProfile() {
NotificationCenter.default.post(name: NSNotification.DisplayProfile, object: nil)
}
}

View file

@ -50,19 +50,22 @@ public struct HighlightAnnotationSheet: View {
}
.padding()
.navigationTitle("Note")
.navigationBarTitleDisplayMode(.inline)
.navigationBarItems(leading: Button(action: onCancel, label: {
Text("Cancel")
}))
.navigationBarItems(trailing: Button(action: onSave, label: {
Text("Save").bold()
}))
#if os(iOS)
.navigationBarTitleDisplayMode(.inline)
.navigationBarItems(leading: Button(action: onCancel, label: {
Text("Cancel")
}))
.navigationBarItems(trailing: Button(action: onSave, label: {
Text("Save").bold()
}))
#endif
.listStyle(PlainListStyle())
.alert(errorAlertMessage ?? LocalText.readerError, isPresented: $showErrorAlertMessage) {
Button(LocalText.genericOk, role: .cancel, action: {
errorAlertMessage = nil
showErrorAlertMessage = false
})
}
.alert(errorAlertMessage ?? LocalText.readerError, isPresented: $showErrorAlertMessage) {
Button(LocalText.genericOk, role: .cancel, action: {
errorAlertMessage = nil
showErrorAlertMessage = false
})
}
}
}

View file

@ -187,7 +187,7 @@ public final class OmnivoreWebView: WKWebView {
override public func viewDidChangeEffectiveAppearance() {
super.viewDidChangeEffectiveAppearance()
if ThemeManager.currentTheme == .system {
try dispatchEvent(.updateTheme(themeName: ThemeManager.currentTheme.themeKey))
try? dispatchEvent(.updateTheme(themeName: ThemeManager.currentTheme.themeKey))
}
}
#endif

View file

@ -4,11 +4,13 @@ import Utils
public extension View {
func draggableItem(item: LinkedItem) -> some View {
if #available(iOS 16.0, *), let url = item.deepLink {
return AnyView(self.draggable(url) {
Label(item.unwrappedTitle, systemImage: "link")
})
}
#if os(iOS)
if #available(iOS 16.0, *), let url = item.deepLink {
return AnyView(self.draggable(url) {
Label(item.unwrappedTitle, systemImage: "link")
})
}
#endif
return AnyView(self)
}
}

View file

@ -164,6 +164,7 @@ public enum LocalText {
public static let genericLoading = localText(key: "genericLoading")
public static let genericFontFamily = localText(key: "genericFontFamily")
public static let genericHighContrastText = localText(key: "genericHighContrastText")
public static let enableJustifyText = localText(key: "enableJustifyText")
public static let enableHighlightOnReleaseText = localText(key: "enableHighlightOnReleaseText")
public static let genericFont = localText(key: "genericFont")
public static let genericHighlight = localText(key: "genericHighlight")

View file

@ -115,7 +115,7 @@
"menuDebugApiEnv" = "API Environment:";
// Navigation
"navigationSelectLink" = "Select a link from the feed";
"navigationSelectLink" = "Select a link from your library";
"navigationSelectSidebarToggle" = "Toggle sidebar";
// Welcome View
@ -163,7 +163,8 @@
"genericLoading" = "Loading...";
"genericFontFamily" = "Font Family";
"genericHighContrastText" = "High Contrast Text";
"enableHighlightOnReleaseText" = "Auto Highlight Mode:";
"enableHighlightOnReleaseText" = "Auto Highlight Mode";
"enableJustifyText" = "Justify Text";
"genericFont" = "Font";
"genericHighlight" = "Highlight";
"labelsGeneric" = "Labels";

View file

@ -17,6 +17,9 @@ struct MainApp: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
@AppStorage(UserDefaultKey.preferredWebFont.rawValue) var preferredFont = WebFont.inter.rawValue
@AppStorage(UserDefaultKey.prefersHighContrastWebFont.rawValue) var prefersHighContrastText = true
@AppStorage(UserDefaultKey.justifyText.rawValue) var justifyText = false
@AppStorage(UserDefaultKey.themeName.rawValue) var currentThemeName = "System"
#elseif os(iOS)
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
#endif
@ -39,7 +42,9 @@ struct MainApp: App {
.commands {
MacMenuCommands(
preferredFont: $preferredFont,
prefersHighContrastText: $prefersHighContrastText
prefersHighContrastText: $prefersHighContrastText,
justifyText: $justifyText,
currentThemeName: $currentThemeName
)
}
.onChange(of: preferredFont) { _ in
@ -48,6 +53,13 @@ struct MainApp: App {
.onChange(of: prefersHighContrastText) { _ in
NSNotification.readerSettingsChanged()
}
.onChange(of: justifyText) { _ in
NSNotification.readerSettingsChanged()
}
.onChange(of: currentThemeName) { _ in
NSNotification.readerSettingsChanged()
}
#endif
}
}