mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
Merge commit '5d0a5112d68f54a217ca9d5a87b0d99878301f28' into OMN-SB
This commit is contained in:
commit
82190e52af
14 changed files with 169 additions and 390 deletions
|
|
@ -1156,7 +1156,7 @@
|
|||
"@executable_path/../Frameworks",
|
||||
"@loader_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.3;
|
||||
MACOSX_DEPLOYMENT_TARGET = 12.0;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "app.omnivore.UnitTests-MacApp";
|
||||
|
|
@ -1182,7 +1182,7 @@
|
|||
"@executable_path/../Frameworks",
|
||||
"@loader_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.3;
|
||||
MACOSX_DEPLOYMENT_TARGET = 12.0;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "app.omnivore.UnitTests-MacApp";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
|
@ -1200,7 +1200,7 @@
|
|||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = QJF2XZ86HB;
|
||||
INFOPLIST_FILE = InfoPlists/iOSUITests.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.5;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
|
@ -1225,7 +1225,7 @@
|
|||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = QJF2XZ86HB;
|
||||
INFOPLIST_FILE = InfoPlists/iOSUITests.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.5;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
|
@ -1260,7 +1260,7 @@
|
|||
"@executable_path/../Frameworks",
|
||||
"@executable_path/../../../../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 12.0;
|
||||
MARKETING_VERSION = 1.4.0;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
|
|
@ -1291,7 +1291,7 @@
|
|||
"@executable_path/../Frameworks",
|
||||
"@executable_path/../../../../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 12.0;
|
||||
MARKETING_VERSION = 1.4.0;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "app.omnivore.app.ShareExtension-Mac";
|
||||
|
|
@ -1316,7 +1316,7 @@
|
|||
"@executable_path/../Frameworks",
|
||||
"@loader_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.3;
|
||||
MACOSX_DEPLOYMENT_TARGET = 12.0;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "app.omnivore.UITests-Mac";
|
||||
|
|
@ -1341,7 +1341,7 @@
|
|||
"@executable_path/../Frameworks",
|
||||
"@loader_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.3;
|
||||
MACOSX_DEPLOYMENT_TARGET = 12.0;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "app.omnivore.UITests-Mac";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
|
@ -1373,7 +1373,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 12.0;
|
||||
MARKETING_VERSION = 1.4.0;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
|
|
@ -1407,7 +1407,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 12.0;
|
||||
MARKETING_VERSION = 1.4.0;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = app.omnivore.app;
|
||||
|
|
@ -1458,7 +1458,7 @@
|
|||
DEVELOPMENT_TEAM = QJF2XZ86HB;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
INFOPLIST_FILE = InfoPlists/Omnivore.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.1;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
|
@ -1572,7 +1572,7 @@
|
|||
"@executable_path/../Frameworks",
|
||||
"@executable_path/../../../../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 12.0;
|
||||
MARKETING_VERSION = 1.4.0;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
|
|
@ -1610,7 +1610,7 @@
|
|||
"@executable_path/../Frameworks",
|
||||
"@executable_path/../../../../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 12.0;
|
||||
MARKETING_VERSION = 1.4.0;
|
||||
MTL_FAST_MATH = YES;
|
||||
OTHER_LDFLAGS = (
|
||||
|
|
@ -1674,8 +1674,8 @@
|
|||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.1;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 12.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
|
|
@ -1690,7 +1690,7 @@
|
|||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = QJF2XZ86HB;
|
||||
INFOPLIST_FILE = InfoPlists/ShareExtension.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.1;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
|
@ -1745,7 +1745,7 @@
|
|||
DEVELOPMENT_TEAM = QJF2XZ86HB;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
INFOPLIST_FILE = InfoPlists/Omnivore.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.1;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
|
@ -1772,7 +1772,7 @@
|
|||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = QJF2XZ86HB;
|
||||
INFOPLIST_FILE = InfoPlists/ShareExtension.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.1;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
|
@ -1843,8 +1843,8 @@
|
|||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.1;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 12.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ let package = Package(
|
|||
name: "OmnivoreKit",
|
||||
defaultLocalization: "en",
|
||||
platforms: [
|
||||
.iOS(.v14),
|
||||
.macOS(.v11)
|
||||
.iOS(.v15),
|
||||
.macOS(.v12)
|
||||
],
|
||||
products: [
|
||||
.library(name: "App", targets: ["App"]),
|
||||
|
|
@ -17,7 +17,7 @@ let package = Package(
|
|||
.library(name: "Utils", targets: ["Utils"])
|
||||
],
|
||||
dependencies: [
|
||||
.package(name: "AppAuth", url: "https://github.com/openid/AppAuth-iOS.git", .upToNextMajor(from: "1.4.0")),
|
||||
.package(url: "https://github.com/openid/AppAuth-iOS.git", .upToNextMajor(from: "1.4.0")),
|
||||
.package(url: "https://github.com/Square/Valet", from: "4.1.2"),
|
||||
.package(url: "https://github.com/maticzav/swift-graphql", from: "2.3.1"),
|
||||
.package(url: "https://github.com/siteline/SwiftUI-Introspect.git", from: "0.1.4")
|
||||
|
|
@ -37,7 +37,7 @@ let package = Package(
|
|||
.target(
|
||||
name: "Services",
|
||||
dependencies: [
|
||||
"AppAuth",
|
||||
.product(name: "AppAuth", package: "AppAuth-iOS"),
|
||||
"Valet",
|
||||
.product(name: "SwiftGraphQL", package: "swift-graphql"),
|
||||
"Models",
|
||||
|
|
|
|||
|
|
@ -14,62 +14,38 @@ import Views
|
|||
|
||||
var body: some View {
|
||||
Group {
|
||||
if #available(iOS 15.0, *) {
|
||||
HomeFeedView(
|
||||
prefersListLayout: $prefersListLayout,
|
||||
viewModel: viewModel
|
||||
)
|
||||
.refreshable {
|
||||
viewModel.loadItems(dataService: dataService, isRefresh: true)
|
||||
HomeFeedView(
|
||||
prefersListLayout: $prefersListLayout,
|
||||
viewModel: viewModel
|
||||
)
|
||||
.refreshable {
|
||||
viewModel.loadItems(dataService: dataService, isRefresh: true)
|
||||
}
|
||||
.searchable(
|
||||
text: $viewModel.searchTerm,
|
||||
placement: .navigationBarDrawer
|
||||
) {
|
||||
if viewModel.searchTerm.isEmpty {
|
||||
Text("Inbox").searchCompletion("in:inbox ")
|
||||
Text("All").searchCompletion("in:all ")
|
||||
Text("Archived").searchCompletion("in:archive ")
|
||||
Text("Files").searchCompletion("type:file ")
|
||||
}
|
||||
.searchable(
|
||||
text: $viewModel.searchTerm,
|
||||
placement: .navigationBarDrawer
|
||||
) {
|
||||
if viewModel.searchTerm.isEmpty {
|
||||
Text("Inbox").searchCompletion("in:inbox ")
|
||||
Text("All").searchCompletion("in:all ")
|
||||
Text("Archived").searchCompletion("in:archive ")
|
||||
Text("Files").searchCompletion("type:file ")
|
||||
}
|
||||
}
|
||||
.onChange(of: viewModel.searchTerm) { _ in
|
||||
// Maybe we should debounce this, but
|
||||
// it feels like it works ok without
|
||||
viewModel.loadItems(dataService: dataService, isRefresh: true)
|
||||
}
|
||||
.onChange(of: viewModel.selectedLabels) { _ in
|
||||
viewModel.loadItems(dataService: dataService, isRefresh: true)
|
||||
}
|
||||
.onSubmit(of: .search) {
|
||||
viewModel.loadItems(dataService: dataService, isRefresh: true)
|
||||
}
|
||||
.sheet(item: $viewModel.itemUnderLabelEdit) { item in
|
||||
ApplyLabelsView(mode: .item(item)) { labels in
|
||||
viewModel.updateLabels(itemID: item.id, labels: labels)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
HomeFeedView(
|
||||
prefersListLayout: $prefersListLayout,
|
||||
viewModel: viewModel
|
||||
)
|
||||
.sheet(item: $viewModel.itemUnderLabelEdit) { item in
|
||||
ApplyLabelsView(mode: .item(item)) { labels in
|
||||
viewModel.updateLabels(itemID: item.id, labels: labels)
|
||||
}
|
||||
}
|
||||
.toolbar {
|
||||
ToolbarItem {
|
||||
if viewModel.isLoading {
|
||||
Button(action: {}, label: { ProgressView() })
|
||||
} else {
|
||||
Button(
|
||||
action: { viewModel.loadItems(dataService: dataService, isRefresh: true) },
|
||||
label: { Label("Refresh Feed", systemImage: "arrow.clockwise") }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: viewModel.searchTerm) { _ in
|
||||
// Maybe we should debounce this, but
|
||||
// it feels like it works ok without
|
||||
viewModel.loadItems(dataService: dataService, isRefresh: true)
|
||||
}
|
||||
.onChange(of: viewModel.selectedLabels) { _ in
|
||||
viewModel.loadItems(dataService: dataService, isRefresh: true)
|
||||
}
|
||||
.onSubmit(of: .search) {
|
||||
viewModel.loadItems(dataService: dataService, isRefresh: true)
|
||||
}
|
||||
.sheet(item: $viewModel.itemUnderLabelEdit) { item in
|
||||
ApplyLabelsView(mode: .item(item)) { labels in
|
||||
viewModel.updateLabels(itemID: item.id, labels: labels)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -141,24 +117,13 @@ import Views
|
|||
HomeFeedGridView(viewModel: viewModel)
|
||||
.toolbar {
|
||||
ToolbarItem {
|
||||
if #available(iOS 15.0, *) {
|
||||
Button("", action: {})
|
||||
.disabled(true)
|
||||
.overlay {
|
||||
if viewModel.isLoading {
|
||||
ProgressView()
|
||||
}
|
||||
Button("", action: {})
|
||||
.disabled(true)
|
||||
.overlay {
|
||||
if viewModel.isLoading {
|
||||
ProgressView()
|
||||
}
|
||||
} else {
|
||||
if viewModel.isLoading {
|
||||
Button(action: {}, label: { ProgressView() })
|
||||
} else {
|
||||
Button(
|
||||
action: { viewModel.loadItems(dataService: dataService, isRefresh: true) },
|
||||
label: { Label("Refresh Feed", systemImage: "arrow.clockwise") }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
ToolbarItem {
|
||||
if UIDevice.isIPad {
|
||||
|
|
@ -189,7 +154,7 @@ import Views
|
|||
List {
|
||||
Section {
|
||||
ForEach(viewModel.items) { item in
|
||||
let link = FeedCardNavigationLink(
|
||||
FeedCardNavigationLink(
|
||||
item: item,
|
||||
viewModel: viewModel
|
||||
)
|
||||
|
|
@ -224,61 +189,56 @@ import Views
|
|||
}
|
||||
}
|
||||
}
|
||||
if #available(iOS 15.0, *) {
|
||||
link
|
||||
.swipeActions(edge: .trailing, allowsFullSwipe: true) {
|
||||
if !item.isArchived {
|
||||
Button {
|
||||
withAnimation(.linear(duration: 0.4)) {
|
||||
viewModel.setLinkArchived(dataService: dataService, linkId: item.id, archived: true)
|
||||
}
|
||||
} label: {
|
||||
Label("Archive", systemImage: "archivebox")
|
||||
}.tint(.green)
|
||||
} else {
|
||||
Button {
|
||||
withAnimation(.linear(duration: 0.4)) {
|
||||
viewModel.setLinkArchived(dataService: dataService, linkId: item.id, archived: false)
|
||||
}
|
||||
} label: {
|
||||
Label("Unarchive", systemImage: "tray.and.arrow.down.fill")
|
||||
}.tint(.indigo)
|
||||
.swipeActions(edge: .trailing, allowsFullSwipe: true) {
|
||||
if !item.isArchived {
|
||||
Button {
|
||||
withAnimation(.linear(duration: 0.4)) {
|
||||
viewModel.setLinkArchived(dataService: dataService, linkId: item.id, archived: true)
|
||||
}
|
||||
} label: {
|
||||
Label("Archive", systemImage: "archivebox")
|
||||
}.tint(.green)
|
||||
} else {
|
||||
Button {
|
||||
withAnimation(.linear(duration: 0.4)) {
|
||||
viewModel.setLinkArchived(dataService: dataService, linkId: item.id, archived: false)
|
||||
}
|
||||
} label: {
|
||||
Label("Unarchive", systemImage: "tray.and.arrow.down.fill")
|
||||
}.tint(.indigo)
|
||||
}
|
||||
}
|
||||
.swipeActions(edge: .trailing, allowsFullSwipe: true) {
|
||||
Button(
|
||||
role: .destructive,
|
||||
action: {
|
||||
itemToRemove = item
|
||||
confirmationShown = true
|
||||
},
|
||||
label: {
|
||||
Image(systemName: "trash")
|
||||
}
|
||||
)
|
||||
}.alert("Are you sure?", isPresented: $confirmationShown) {
|
||||
Button("Remove Link", role: .destructive) {
|
||||
if let itemToRemove = itemToRemove {
|
||||
withAnimation {
|
||||
viewModel.removeLink(dataService: dataService, linkId: itemToRemove.id)
|
||||
}
|
||||
}
|
||||
.swipeActions(edge: .trailing, allowsFullSwipe: true) {
|
||||
Button(
|
||||
role: .destructive,
|
||||
action: {
|
||||
itemToRemove = item
|
||||
confirmationShown = true
|
||||
},
|
||||
label: {
|
||||
Image(systemName: "trash")
|
||||
}
|
||||
)
|
||||
}.alert("Are you sure?", isPresented: $confirmationShown) {
|
||||
Button("Remove Link", role: .destructive) {
|
||||
if let itemToRemove = itemToRemove {
|
||||
withAnimation {
|
||||
viewModel.removeLink(dataService: dataService, linkId: itemToRemove.id)
|
||||
}
|
||||
}
|
||||
self.itemToRemove = nil
|
||||
}
|
||||
Button("Cancel", role: .cancel) { self.itemToRemove = nil }
|
||||
}
|
||||
.swipeActions(edge: .leading, allowsFullSwipe: true) {
|
||||
if FeatureFlag.enableSnooze {
|
||||
Button {
|
||||
viewModel.itemToSnooze = item
|
||||
viewModel.snoozePresented = true
|
||||
} label: {
|
||||
Label { Text("Snooze") } icon: { Image.moon }
|
||||
}.tint(.appYellow48)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
link
|
||||
self.itemToRemove = nil
|
||||
}
|
||||
Button("Cancel", role: .cancel) { self.itemToRemove = nil }
|
||||
}
|
||||
.swipeActions(edge: .leading, allowsFullSwipe: true) {
|
||||
if FeatureFlag.enableSnooze {
|
||||
Button {
|
||||
viewModel.itemToSnooze = item
|
||||
viewModel.snoozePresented = true
|
||||
} label: {
|
||||
Label { Text("Snooze") } icon: { Image.moon }
|
||||
}.tint(.appYellow48)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -331,27 +291,22 @@ import Views
|
|||
ScrollView {
|
||||
LazyVGrid(columns: [GridItem(.adaptive(minimum: 325), spacing: 24)], spacing: 24) {
|
||||
ForEach(viewModel.items) { item in
|
||||
let link = GridCardNavigationLink(
|
||||
GridCardNavigationLink(
|
||||
item: item,
|
||||
actionHandler: { contextMenuActionHandler(item: item, action: $0) },
|
||||
isContextMenuOpen: $isContextMenuOpen,
|
||||
viewModel: viewModel
|
||||
)
|
||||
if #available(iOS 15.0, *) {
|
||||
link
|
||||
.alert("Are you sure?", isPresented: $confirmationShown) {
|
||||
Button("Remove Link", role: .destructive) {
|
||||
if let itemToRemove = itemToRemove {
|
||||
withAnimation {
|
||||
viewModel.removeLink(dataService: dataService, linkId: itemToRemove.id)
|
||||
}
|
||||
}
|
||||
self.itemToRemove = nil
|
||||
.alert("Are you sure?", isPresented: $confirmationShown) {
|
||||
Button("Remove Link", role: .destructive) {
|
||||
if let itemToRemove = itemToRemove {
|
||||
withAnimation {
|
||||
viewModel.removeLink(dataService: dataService, linkId: itemToRemove.id)
|
||||
}
|
||||
Button("Cancel", role: .cancel) { self.itemToRemove = nil }
|
||||
}
|
||||
} else {
|
||||
link
|
||||
self.itemToRemove = nil
|
||||
}
|
||||
Button("Cancel", role: .cancel) { self.itemToRemove = nil }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,15 +15,6 @@ import Views
|
|||
@ObservedObject var viewModel: HomeFeedViewModel
|
||||
|
||||
var body: some View {
|
||||
if #available(macOS 12.0, *) {
|
||||
innerBody
|
||||
} else {
|
||||
innerBodyMac11
|
||||
}
|
||||
}
|
||||
|
||||
@available(macOS 12.0, *)
|
||||
var innerBody: some View {
|
||||
List {
|
||||
Section {
|
||||
ForEach(viewModel.items) { item in
|
||||
|
|
@ -118,40 +109,6 @@ import Views
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
var innerBodyMac11: some View {
|
||||
List {
|
||||
Section {
|
||||
ForEach(viewModel.items) { item in
|
||||
FeedCardNavigationLink(
|
||||
item: item,
|
||||
viewModel: viewModel
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if viewModel.isLoading {
|
||||
LoadingSection()
|
||||
}
|
||||
}
|
||||
.listStyle(PlainListStyle())
|
||||
.navigationTitle("Home")
|
||||
.toolbar {
|
||||
ToolbarItem {
|
||||
Button(
|
||||
action: {
|
||||
viewModel.loadItems(dataService: dataService, isRefresh: true)
|
||||
},
|
||||
label: { Label("Refresh Feed", systemImage: "arrow.clockwise") }
|
||||
)
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
if viewModel.items.isEmpty {
|
||||
viewModel.loadItems(dataService: dataService, isRefresh: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -126,15 +126,11 @@ struct ApplyLabelsView: View {
|
|||
EmptyView()
|
||||
} else {
|
||||
#if os(iOS)
|
||||
if #available(iOS 15.0, *) {
|
||||
innerBody
|
||||
.searchable(
|
||||
text: $labelSearchFilter,
|
||||
placement: .navigationBarDrawer(displayMode: .always)
|
||||
)
|
||||
} else {
|
||||
innerBody
|
||||
}
|
||||
innerBody
|
||||
.searchable(
|
||||
text: $labelSearchFilter,
|
||||
placement: .navigationBarDrawer(displayMode: .always)
|
||||
)
|
||||
#else
|
||||
innerBody
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -16,25 +16,20 @@ struct LabelsView: View {
|
|||
var body: some View {
|
||||
Group {
|
||||
#if os(iOS)
|
||||
if #available(iOS 15.0, *) {
|
||||
Form {
|
||||
innerBody
|
||||
.alert("Are you sure you want to delete this label?", isPresented: $showDeleteConfirmation) {
|
||||
Button("Delete Label", role: .destructive) {
|
||||
if let labelID = labelToRemoveID {
|
||||
withAnimation {
|
||||
viewModel.deleteLabel(dataService: dataService, labelID: labelID)
|
||||
}
|
||||
Form {
|
||||
innerBody
|
||||
.alert("Are you sure you want to delete this label?", isPresented: $showDeleteConfirmation) {
|
||||
Button("Delete Label", role: .destructive) {
|
||||
if let labelID = labelToRemoveID {
|
||||
withAnimation {
|
||||
viewModel.deleteLabel(dataService: dataService, labelID: labelID)
|
||||
}
|
||||
self.labelToRemoveID = nil
|
||||
}
|
||||
Button("Cancel", role: .cancel) { self.labelToRemoveID = nil }
|
||||
self.labelToRemoveID = nil
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Form { innerBody }
|
||||
Button("Cancel", role: .cancel) { self.labelToRemoveID = nil }
|
||||
}
|
||||
}
|
||||
|
||||
#elseif os(macOS)
|
||||
List {
|
||||
innerBody
|
||||
|
|
|
|||
|
|
@ -157,39 +157,6 @@ struct LinkItemDetailView: View {
|
|||
#endif
|
||||
}
|
||||
|
||||
var navBariOS14: some View {
|
||||
HStack(alignment: .center) {
|
||||
Button(
|
||||
action: { self.presentationMode.wrappedValue.dismiss() },
|
||||
label: {
|
||||
Image(systemName: "chevron.backward")
|
||||
.font(.appTitleTwo)
|
||||
.foregroundColor(.appGrayTextContrast)
|
||||
.padding(.horizontal)
|
||||
}
|
||||
)
|
||||
.scaleEffect(navBarVisibilityRatio)
|
||||
Spacer()
|
||||
Button(
|
||||
action: { showFontSizePopover.toggle() },
|
||||
label: {
|
||||
Image(systemName: "textformat.size")
|
||||
.font(.appTitleTwo)
|
||||
}
|
||||
)
|
||||
.padding(.horizontal)
|
||||
.scaleEffect(navBarVisibilityRatio)
|
||||
}
|
||||
.frame(height: readerViewNavBarHeight * navBarVisibilityRatio)
|
||||
.opacity(navBarVisibilityRatio)
|
||||
.background(Color.systemBackground)
|
||||
.onTapGesture {
|
||||
showFontSizePopover = false
|
||||
}
|
||||
}
|
||||
|
||||
@available(macOS 12.0, *)
|
||||
@available(iOS 15.0, *)
|
||||
var navBar: some View {
|
||||
HStack(alignment: .center) {
|
||||
Button(
|
||||
|
|
@ -286,47 +253,25 @@ struct LinkItemDetailView: View {
|
|||
}
|
||||
)
|
||||
}
|
||||
if #available(iOS 15.0, *) {
|
||||
VStack(spacing: 0) {
|
||||
navBar
|
||||
Spacer()
|
||||
}
|
||||
.navigationBarHidden(true)
|
||||
} else {
|
||||
VStack(spacing: 0) {
|
||||
navBariOS14
|
||||
Spacer()
|
||||
}
|
||||
.navigationBarHidden(true)
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if #available(iOS 15.0, *) {
|
||||
VStack(spacing: 0) {
|
||||
navBar
|
||||
Spacer()
|
||||
}
|
||||
.onAppear {
|
||||
viewModel.loadWebAppWrapper(
|
||||
dataService: dataService,
|
||||
rawAuthCookie: authenticator.omnivoreAuthCookieString
|
||||
)
|
||||
}
|
||||
.navigationBarHidden(true)
|
||||
} else {
|
||||
VStack(spacing: 0) {
|
||||
navBariOS14
|
||||
Spacer()
|
||||
}
|
||||
.onAppear {
|
||||
viewModel.loadWebAppWrapper(
|
||||
dataService: dataService,
|
||||
rawAuthCookie: authenticator.omnivoreAuthCookieString
|
||||
)
|
||||
}
|
||||
.navigationBarHidden(true)
|
||||
}
|
||||
|
||||
} else {
|
||||
VStack(spacing: 0) {
|
||||
navBar
|
||||
Spacer()
|
||||
}
|
||||
.onAppear {
|
||||
viewModel.loadWebAppWrapper(
|
||||
dataService: dataService,
|
||||
rawAuthCookie: authenticator.omnivoreAuthCookieString
|
||||
)
|
||||
}
|
||||
.navigationBarHidden(true)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -51,10 +51,8 @@ public struct PrimaryContentView: View {
|
|||
.introspectSplitViewController {
|
||||
$0.preferredSplitBehavior = .tile
|
||||
$0.preferredPrimaryColumnWidth = 200
|
||||
if #available(iOS 14.5, *) {
|
||||
$0.presentsWithGesture = false
|
||||
$0.displayModeButtonVisibility = .always
|
||||
}
|
||||
$0.presentsWithGesture = false
|
||||
$0.displayModeButtonVisibility = .always
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -74,39 +74,6 @@ import WebKit
|
|||
}
|
||||
}
|
||||
|
||||
var navBariOS14: some View {
|
||||
HStack(alignment: .center) {
|
||||
Button(
|
||||
action: { self.presentationMode.wrappedValue.dismiss() },
|
||||
label: {
|
||||
Image(systemName: "chevron.backward")
|
||||
.font(.appTitleTwo)
|
||||
.foregroundColor(.appGrayTextContrast)
|
||||
.padding(.horizontal)
|
||||
}
|
||||
)
|
||||
.scaleEffect(navBarVisibilityRatio)
|
||||
Spacer()
|
||||
Button(
|
||||
action: { showFontSizePopover.toggle() },
|
||||
label: {
|
||||
Image(systemName: "textformat.size")
|
||||
.font(.appTitleTwo)
|
||||
}
|
||||
)
|
||||
.padding(.horizontal)
|
||||
.scaleEffect(navBarVisibilityRatio)
|
||||
}
|
||||
.frame(height: readerViewNavBarHeight * navBarVisibilityRatio)
|
||||
.opacity(navBarVisibilityRatio)
|
||||
.background(Color.systemBackground)
|
||||
.onTapGesture {
|
||||
showFontSizePopover = false
|
||||
}
|
||||
}
|
||||
|
||||
@available(macOS 12.0, *)
|
||||
@available(iOS 15.0, *)
|
||||
var navBar: some View {
|
||||
HStack(alignment: .center) {
|
||||
Button(
|
||||
|
|
@ -264,19 +231,11 @@ import WebKit
|
|||
}
|
||||
)
|
||||
}
|
||||
if #available(iOS 15.0, *) {
|
||||
VStack(spacing: 0) {
|
||||
navBar
|
||||
Spacer()
|
||||
}
|
||||
.navigationBarHidden(true)
|
||||
} else {
|
||||
VStack(spacing: 0) {
|
||||
navBariOS14
|
||||
Spacer()
|
||||
}
|
||||
.navigationBarHidden(true)
|
||||
VStack(spacing: 0) {
|
||||
navBar
|
||||
Spacer()
|
||||
}
|
||||
.navigationBarHidden(true)
|
||||
|
||||
}.onDisappear {
|
||||
// Clear the shared webview content when exiting
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ public enum PageScraper {
|
|||
}
|
||||
|
||||
var pageScrapePayload: PageScrapePayload?
|
||||
let propertyListKey = String(kUTTypePropertyList)
|
||||
let propertyListKey = UTType.propertyList.identifier
|
||||
|
||||
let group = DispatchGroup()
|
||||
|
||||
|
|
@ -76,7 +76,7 @@ public enum PageScraper {
|
|||
extensionContext: NSExtensionContext?,
|
||||
completion: @escaping (Result<PageScrapePayload, PageScrapeError>) -> Void
|
||||
) {
|
||||
let urlKey = String(kUTTypeURL)
|
||||
let urlKey = UTType.url.identifier
|
||||
|
||||
// First look for a URL type
|
||||
let urlFound = extensionContext?.inputItems.first { inputItem in
|
||||
|
|
@ -108,7 +108,7 @@ public enum PageScraper {
|
|||
return
|
||||
}
|
||||
|
||||
let textKey = String(kUTTypeText)
|
||||
let textKey = UTType.text.identifier
|
||||
// We didn't find a URL type, so check for a string that contains a URL
|
||||
let textUrlFound = extensionContext?.inputItems.first { inputItem in
|
||||
let itemProvider = (inputItem as? NSExtensionItem)?.attachments?.first(where: { attachment in
|
||||
|
|
@ -150,8 +150,8 @@ public enum PageScraper {
|
|||
extensionContext: NSExtensionContext?,
|
||||
completion: @escaping (Result<PageScrapePayload, PageScrapeError>) -> Void
|
||||
) {
|
||||
let urlKey = String(kUTTypeURL)
|
||||
let textKey = String(kUTTypeUTF16PlainText)
|
||||
let urlKey = UTType.url.identifier
|
||||
let textKey = UTType.utf16PlainText.identifier
|
||||
let inputItem = extensionContext?.inputItems.first as? NSExtensionItem
|
||||
let itemProvider = inputItem?.attachments?.first(where: { attachment in
|
||||
attachment.hasItemConformingToTypeIdentifier(urlKey)
|
||||
|
|
|
|||
|
|
@ -23,13 +23,7 @@ public extension Color {
|
|||
static var systemPlaceholder: Color { Color(.placeholderText) }
|
||||
static var secondarySystemGroupedBackground: Color { Color(.secondarySystemGroupedBackground) }
|
||||
static var systemGray6: Color { Color(.systemGray6) }
|
||||
static var systemLabel: Color {
|
||||
if #available(iOS 15.0, *) {
|
||||
return Color(uiColor: .label)
|
||||
} else {
|
||||
return Color.appGrayTextContrast
|
||||
}
|
||||
}
|
||||
static var systemLabel: Color { Color(uiColor: .label) }
|
||||
|
||||
#elseif os(macOS)
|
||||
static var systemBackground: Color { Color(.windowBackgroundColor) }
|
||||
|
|
|
|||
|
|
@ -68,21 +68,9 @@ public struct GridCard: View {
|
|||
VStack(alignment: .leading, spacing: 16) {
|
||||
// Progress Bar
|
||||
Group {
|
||||
// Remove os check when dropping macOS 11
|
||||
#if os(iOS)
|
||||
if #available(iOS 15.0, *) {
|
||||
ProgressView(value: min(abs(item.readingProgress) / 100, 1))
|
||||
.tint(.appYellow48)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
} else {
|
||||
Color.clear
|
||||
.contentShape(Rectangle())
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
}
|
||||
#else
|
||||
ProgressView(value: max(abs(item.readingProgress) / 100, 1))
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
#endif
|
||||
ProgressView(value: min(abs(item.readingProgress) / 100, 1))
|
||||
.tint(.appYellow48)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
}
|
||||
.onTapGesture { tapHandler() }
|
||||
|
||||
|
|
|
|||
|
|
@ -30,14 +30,13 @@ import SwiftUI
|
|||
let controller = UIHostingController(rootView: content())
|
||||
|
||||
if controller.traitCollection.userInterfaceIdiom == .phone {
|
||||
if #available(iOS 15, *) {
|
||||
if let sheet = controller.sheetPresentationController {
|
||||
sheet.preferredCornerRadius = 16
|
||||
sheet.prefersGrabberVisible = false
|
||||
sheet.detents = [.medium()]
|
||||
sheet.widthFollowsPreferredContentSizeWhenEdgeAttached = true
|
||||
}
|
||||
if let sheet = controller.sheetPresentationController {
|
||||
sheet.preferredCornerRadius = 16
|
||||
sheet.prefersGrabberVisible = false
|
||||
sheet.detents = [.medium()]
|
||||
sheet.widthFollowsPreferredContentSizeWhenEdgeAttached = true
|
||||
}
|
||||
|
||||
controller.modalPresentationStyle = .pageSheet
|
||||
} else {
|
||||
controller.view.sizeToFit()
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import SwiftUI
|
|||
self.denyAction = denyAction
|
||||
}
|
||||
|
||||
var content: some View {
|
||||
public var body: some View {
|
||||
VStack(alignment: .leading, spacing: 10) {
|
||||
HStack {
|
||||
Image
|
||||
|
|
@ -45,14 +45,7 @@ import SwiftUI
|
|||
.foregroundColor(Color.appTextDefault)
|
||||
.cornerRadius(8)
|
||||
.frame(maxWidth: min(UIScreen.main.bounds.width - 20, 320))
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
if #available(iOS 15.0, *) {
|
||||
content.interactiveDismissDisabled()
|
||||
} else {
|
||||
content
|
||||
}
|
||||
.interactiveDismissDisabled()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue