Merge pull request #3274 from omnivore-app/feat/ios-accesibility-issues

Fixes for users with the accessibility buttonShapes feature enabled on iOS
This commit is contained in:
Jackson Harper
2023-12-22 14:00:00 +08:00
committed by GitHub
11 changed files with 135 additions and 155 deletions

View File

@ -140,8 +140,11 @@ public struct ShareExtensionView: View {
Text("Add Labels").font(Font.system(size: 12, weight: .medium)).tint(Color.white)
} icon: {
Image.label.resizable(resizingMode: .stretch).frame(width: 17, height: 17).tint(Color.white)
}.padding(.leading, 10).padding(.trailing, 12)
}
.foregroundColor(Color.white)
.padding(.leading, 10).padding(.trailing, 12)
})
.buttonStyle(.plain)
.frame(height: 28)
.background(Color.blue)
.cornerRadius(24)
@ -243,7 +246,7 @@ public struct ShareExtensionView: View {
.aspectRatio(contentMode: .fit)
.frame(width: 15, height: 15)
}
}
}.buttonStyle(.plain)
}
var closeButton: some View {
@ -262,7 +265,7 @@ public struct ShareExtensionView: View {
.font(Font.title.weight(.bold))
.frame(width: 12, height: 12)
}
})
}).buttonStyle(.plain)
}
var titleBar: some View {
@ -337,12 +340,14 @@ public struct ShareExtensionView: View {
viewModel.handleReadNowAction(extensionContext: extensionContext)
}, label: {
Text("Read Now")
.foregroundColor(Color.white)
#if os(iOS)
.font(Font.system(size: 17, weight: .semibold))
.tint(Color.white)
.padding(20)
#endif
})
.buttonStyle(.plain)
#if os(iOS)
.frame(height: 50)
.background(Color.blue)

View File

@ -38,6 +38,6 @@ struct TabBarButton: View {
.frame(width: 28, height: 28)
.foregroundColor(selectedTab == key ? Color.blue : Color.themeTabButtonColor)
.frame(maxWidth: .infinity)
})
}).buttonStyle(.plain)
}
}

View File

@ -61,6 +61,6 @@ struct ToolBarButton: View {
.frame(width: 28, height: 28)
.foregroundColor(ThemeManager.currentTheme.toolbarColor)
.frame(maxWidth: .infinity)
})
}).buttonStyle(.plain)
}
}

View File

@ -38,6 +38,7 @@ struct LibraryFeatureCardNavigationLink: View {
LibraryFeatureCard(item: item, viewer: dataService.currentViewer)
}
)
.buttonStyle(.plain)
.confirmationDialog("", isPresented: $showFeatureActions) {
if FeaturedItemFilter(rawValue: viewModel.fetcher.featureFilter) == .pinned {
Button("Unpin", action: {

View File

@ -86,6 +86,7 @@ struct LibraryItemGridCardNavigationLink: View {
GridCard(item: LibraryItemData.make(from: item), isContextMenuOpen: $isContextMenuOpen, actionHandler: actionHandler)
}
)
.buttonStyle(.plain)
.aspectRatio(1.0, contentMode: .fill)
.background(
Color.secondarySystemGroupedBackground

View File

@ -7,6 +7,76 @@ import UserNotifications
import Utils
import Views
struct FiltersHeader: View {
@ObservedObject var viewModel: HomeFeedViewModel
var body: some View {
GeometryReader { reader in
ScrollView(.horizontal, showsIndicators: false) {
HStack {
if viewModel.searchTerm.count > 0 {
TextChipButton.makeSearchFilterButton(title: viewModel.searchTerm) {
viewModel.searchTerm = ""
}.frame(maxWidth: reader.size.width * 0.66)
} else {
if UIDevice.isIPhone {
Menu(
content: {
ForEach(viewModel.filters) { filter in
Button(filter.name, action: {
viewModel.appliedFilter = filter
})
}
},
label: {
TextChipButton.makeMenuButton(
title: viewModel.appliedFilter?.name ?? "-",
color: .systemGray6
)
}
).buttonStyle(.plain)
}
}
Menu(
content: {
ForEach(LinkedItemSort.allCases, id: \.self) { sort in
Button(sort.displayName, action: { viewModel.appliedSort = sort.rawValue })
}
},
label: {
TextChipButton.makeMenuButton(
title: LinkedItemSort(rawValue: viewModel.appliedSort)?.displayName ?? "Sort",
color: .systemGray6
)
}
).buttonStyle(.plain)
TextChipButton.makeAddLabelButton(color: .systemGray6, onTap: { viewModel.showLabelsSheet = true })
ForEach(viewModel.selectedLabels, id: \.self) { label in
TextChipButton.makeRemovableLabelButton(feedItemLabel: label, negated: false) {
viewModel.selectedLabels.removeAll { $0.id == label.id }
}
}
ForEach(viewModel.negatedLabels, id: \.self) { label in
TextChipButton.makeRemovableLabelButton(feedItemLabel: label, negated: true) {
viewModel.negatedLabels.removeAll { $0.id == label.id }
}
}
Spacer()
}
}
}
.padding(.top, 0)
.padding(.bottom, 10)
.padding(.leading, 15)
.listRowSpacing(0)
.listRowInsets(.init(top: 0, leading: 0, bottom: 0, trailing: 0))
.frame(maxWidth: .infinity, minHeight: 38)
.background(Color.systemBackground)
.dynamicTypeSize(.small ... .accessibility1)
}
}
struct AnimatingCellHeight: AnimatableModifier {
var height: CGFloat = 0
@ -189,7 +259,6 @@ struct AnimatingCellHeight: AnimatableModifier {
action: { isEditMode = isEditMode == .active ? .inactive : .active },
label: {
Image.selectMultiple
.foregroundColor(Color.appGrayTextContrast)
}
)
}
@ -211,14 +280,12 @@ struct AnimatingCellHeight: AnimatableModifier {
},
label: {
Image.addLink
.foregroundColor(Color.appGrayTextContrast)
}
)
Button(
action: { searchPresented = true },
label: {
Image.magnifyingGlass
.foregroundColor(Color.appGrayTextContrast)
}
)
}
@ -229,10 +296,12 @@ struct AnimatingCellHeight: AnimatableModifier {
viewModel.bulkAction(dataService: dataService, action: .archive, items: Array(selection))
isEditMode = .inactive
}, label: { Image(systemName: "archivebox") })
.padding(.trailing, 10)
Button(action: {
viewModel.bulkAction(dataService: dataService, action: .delete, items: Array(selection))
isEditMode = .inactive
}, label: { Image(systemName: "trash") })
.padding(.trailing, 10)
Spacer()
Text("\(selection.count) selected").font(.footnote)
Spacer()
@ -350,72 +419,12 @@ struct AnimatingCellHeight: AnimatableModifier {
@ObservedObject var networkMonitor = NetworkMonitor()
var filtersHeader: some View {
GeometryReader { reader in
ScrollView(.horizontal, showsIndicators: false) {
HStack {
if viewModel.searchTerm.count > 0 {
TextChipButton.makeSearchFilterButton(title: viewModel.searchTerm) {
viewModel.searchTerm = ""
}.frame(maxWidth: reader.size.width * 0.66)
} else {
if UIDevice.isIPhone {
Menu(
content: {
ForEach(viewModel.filters) { filter in
Button(filter.name, action: {
viewModel.appliedFilter = filter
})
}
},
label: {
TextChipButton.makeMenuButton(
title: viewModel.appliedFilter?.name ?? "-",
color: .systemGray6
)
}
)
}
}
Menu(
content: {
ForEach(LinkedItemSort.allCases, id: \.self) { sort in
Button(sort.displayName, action: { viewModel.appliedSort = sort.rawValue })
}
},
label: {
TextChipButton.makeMenuButton(
title: LinkedItemSort(rawValue: viewModel.appliedSort)?.displayName ?? "Sort",
color: .systemGray6
)
}
)
TextChipButton.makeAddLabelButton(color: .systemGray6, onTap: { viewModel.showLabelsSheet = true })
ForEach(viewModel.selectedLabels, id: \.self) { label in
TextChipButton.makeRemovableLabelButton(feedItemLabel: label, negated: false) {
viewModel.selectedLabels.removeAll { $0.id == label.id }
}
}
ForEach(viewModel.negatedLabels, id: \.self) { label in
TextChipButton.makeRemovableLabelButton(feedItemLabel: label, negated: true) {
viewModel.negatedLabels.removeAll { $0.id == label.id }
}
}
Spacer()
}
}
}
.padding(.top, 0)
.padding(.bottom, 10)
.padding(.leading, 15)
.listRowSpacing(0)
.listRowInsets(.init(top: 0, leading: 0, bottom: 0, trailing: 0))
.frame(maxWidth: .infinity, minHeight: 38)
.background(Color.systemBackground)
.overlay(Rectangle()
.padding(.leading, 15)
.frame(width: nil, height: 0.5, alignment: .bottom)
.foregroundColor(isListScrolled ? Color(hex: "#3D3D3D") : Color.systemBackground), alignment: .bottom)
.dynamicTypeSize(.small ... .accessibility1)
FiltersHeader(viewModel: viewModel)
.overlay(Rectangle()
.padding(.leading, 15)
.frame(width: nil, height: 0.5, alignment: .bottom)
.foregroundColor(isListScrolled ? Color(hex: "#3D3D3D") : Color.systemBackground), alignment: .bottom)
.dynamicTypeSize(.small ... .accessibility1)
}
func menuItems(for item: Models.LibraryItem) -> some View {
@ -464,7 +473,7 @@ struct AnimatingCellHeight: AnimatableModifier {
.background(Color(hex: "#007AFF")?.opacity(0.1))
.cornerRadius(5)
}.frame(maxWidth: .infinity, alignment: .leading)
})
}).buttonStyle(.plain)
Spacer()
}
.padding(.top, 10)
@ -820,59 +829,7 @@ struct AnimatingCellHeight: AnimatableModifier {
}
var filtersHeader: some View {
GeometryReader { reader in
ScrollView(.horizontal, showsIndicators: false) {
HStack {
if viewModel.searchTerm.count > 0 {
TextChipButton.makeSearchFilterButton(title: viewModel.searchTerm) {
viewModel.searchTerm = ""
}.frame(maxWidth: reader.size.width * 0.66)
} else {
Menu(
content: {
ForEach(viewModel.filters, id: \.self) { filter in
Button(filter.name, action: { viewModel.appliedFilter = filter })
}
},
label: {
TextChipButton.makeMenuButton(
title: viewModel.appliedFilter?.name ?? "-",
color: .systemGray6
)
}
)
}
Menu(
content: {
ForEach(LinkedItemSort.allCases, id: \.self) { sort in
Button(sort.displayName, action: { viewModel.appliedSort = sort.rawValue })
}
},
label: {
TextChipButton.makeMenuButton(
title: LinkedItemSort(rawValue: viewModel.appliedSort)?.displayName ?? "Sort",
color: .systemGray6
)
}
)
TextChipButton.makeAddLabelButton(color: .systemGray6, onTap: { viewModel.showLabelsSheet = true })
ForEach(viewModel.selectedLabels, id: \.self) { label in
TextChipButton.makeRemovableLabelButton(feedItemLabel: label, negated: false) {
viewModel.selectedLabels.removeAll { $0.id == label.id }
}
}
ForEach(viewModel.negatedLabels, id: \.self) { label in
TextChipButton.makeRemovableLabelButton(feedItemLabel: label, negated: true) {
viewModel.negatedLabels.removeAll { $0.id == label.id }
}
}
Spacer()
}
.padding(0)
}
.listRowSeparator(.hidden)
}
.dynamicTypeSize(.small ... .accessibility1)
FiltersHeader(viewModel: viewModel)
}
var body: some View {

View File

@ -94,8 +94,12 @@ struct FiltersView: View {
}
Section(header: Text("Saved Searches")) {
ForEach(viewModel.libraryFilters) { filter in
Text(filter.name)
if viewModel.libraryFilters.count > 0 {
ForEach(viewModel.libraryFilters) { filter in
Text(filter.name)
}
} else {
Text("No saved searches found")
}
}

View File

@ -76,12 +76,13 @@ struct NewsletterEmailsView: View {
OperationToast(operationMessage: $viewModel.operationMessage, showOperationToast: $viewModel.showOperationToast, operationStatus: $viewModel.operationStatus)
} label: {
EmptyView()
}
}.buttonStyle(.plain)
WindowLink(level: .alert, transition: .move(edge: .bottom), isPresented: $viewModel.showAddressCopied) {
MessageToast()
} label: {
EmptyView()
}
}.buttonStyle(.plain)
#if os(iOS)
Form {

View File

@ -161,7 +161,8 @@ struct SubscriptionsView: View {
OperationToast(operationMessage: $viewModel.operationMessage, showOperationToast: $viewModel.showOperationToast, operationStatus: $viewModel.operationStatus)
} label: {
EmptyView()
}
}.buttonStyle(.plain)
if viewModel.feeds.isEmpty, viewModel.newsletters.isEmpty, viewModel.isLoading {
ProgressView()
} else if viewModel.hasNetworkError {

View File

@ -129,29 +129,31 @@ struct WebReaderContainerView: View {
return AnyView(ProgressView()
.padding(.horizontal))
} else {
return AnyView(Button(
action: {
switch audioController.state {
case .playing:
if audioController.itemAudioProperties?.itemID == self.item.unwrappedID {
audioController.pause()
return
return AnyView(
Button(
action: {
switch audioController.state {
case .playing:
if audioController.itemAudioProperties?.itemID == self.item.unwrappedID {
audioController.pause()
return
}
fallthrough
case .paused:
if audioController.itemAudioProperties?.itemID == self.item.unwrappedID {
audioController.unpause()
return
}
fallthrough
default:
audioController.play(itemAudioProperties: item.audioProperties)
}
fallthrough
case .paused:
if audioController.itemAudioProperties?.itemID == self.item.unwrappedID {
audioController.unpause()
return
}
fallthrough
default:
audioController.play(itemAudioProperties: item.audioProperties)
},
label: {
textToSpeechButtonImage
}
},
label: {
textToSpeechButtonImage
}
))
).buttonStyle(.plain)
)
}
}
@ -258,6 +260,8 @@ struct WebReaderContainerView: View {
.padding(.vertical)
}
)
.buttonStyle(.plain)
Spacer()
#endif
@ -267,6 +271,7 @@ struct WebReaderContainerView: View {
Image.label
}
)
.buttonStyle(.plain)
.padding(.trailing, 4)
Button(
@ -275,6 +280,7 @@ struct WebReaderContainerView: View {
Image.notebook
}
)
.buttonStyle(.plain)
.padding(.trailing, 4)
#if os(iOS)
@ -292,6 +298,7 @@ struct WebReaderContainerView: View {
Image.readerSettings
}
)
.buttonStyle(.plain)
.padding(.horizontal, 5)
.popover(isPresented: $showPreferencesPopover) {
webPreferencesPopoverView
@ -318,6 +325,7 @@ struct WebReaderContainerView: View {
#endif
}
)
.buttonStyle(.plain)
#if os(macOS)
.frame(maxWidth: 100)
.padding(.trailing, 16)
@ -372,7 +380,8 @@ struct WebReaderContainerView: View {
OperationToast(operationMessage: $viewModel.operationMessage, showOperationToast: $viewModel.showOperationToast, operationStatus: $viewModel.operationStatus)
} label: {
EmptyView()
}
}.buttonStyle(.plain)
if let articleContent = viewModel.articleContent {
WebReader(
item: item,

View File

@ -149,6 +149,7 @@ struct WelcomeView: View {
.sheet(isPresented: $showAboutPage) {
if let url = URL(string: "https://omnivore.app/about") {
SafariView(url: url)
.ignoresSafeArea(.all, edges: .bottom)
}
}
.onTapGesture {