Merge pull request #757 from omnivore-app/feature/high-text-contrast-reader-text

This commit is contained in:
Jackson Harper
2022-06-04 10:09:59 -07:00
committed by GitHub
9 changed files with 105 additions and 52 deletions

View File

@ -15,6 +15,7 @@ import WebKit
@Binding var updateFontFamilyActionID: UUID?
@Binding var updateFontActionID: UUID?
@Binding var updateTextContrastActionID: UUID?
@Binding var updateMarginActionID: UUID?
@Binding var updateLineHeightActionID: UUID?
@Binding var annotationSaveTransactionID: UUID?
@ -89,6 +90,11 @@ import WebKit
(webView as? WebView)?.updateFontSize()
}
if updateTextContrastActionID != context.coordinator.previousUpdateTextContrastActionID {
context.coordinator.previousUpdateTextContrastActionID = updateTextContrastActionID
(webView as? WebView)?.updateTextContrast()
}
if updateMarginActionID != context.coordinator.previousUpdateMarginActionID {
context.coordinator.previousUpdateMarginActionID = updateMarginActionID
(webView as? WebView)?.updateMargin()

View File

@ -17,6 +17,7 @@ import WebKit
@State private var progressViewOpacity = 0.0
@State var updateFontFamilyActionID: UUID?
@State var updateFontActionID: UUID?
@State var updateTextContrastActionID: UUID?
@State var updateMarginActionID: UUID?
@State var updateLineHeightActionID: UUID?
@State var annotationSaveTransactionID: UUID?
@ -149,6 +150,7 @@ import WebKit
},
updateFontFamilyActionID: $updateFontFamilyActionID,
updateFontActionID: $updateFontActionID,
updateTextContrastActionID: $updateTextContrastActionID,
updateMarginActionID: $updateMarginActionID,
updateLineHeightActionID: $updateLineHeightActionID,
annotationSaveTransactionID: $annotationSaveTransactionID,
@ -200,6 +202,7 @@ import WebKit
WebPreferencesPopoverView(
updateFontFamilyAction: { updateFontFamilyActionID = UUID() },
updateFontAction: { updateFontActionID = UUID() },
updateTextContrastAction: { updateTextContrastActionID = UUID() },
updateMarginAction: { updateMarginActionID = UUID() },
updateLineHeightAction: { updateLineHeightActionID = UUID() },
dismissAction: { showPreferencesPopover = false }

View File

@ -17,6 +17,7 @@ final class WebReaderCoordinator: NSObject {
var lastSavedAnnotationID: UUID?
var previousUpdateFontFamilyActionID: UUID?
var previousUpdateFontActionID: UUID?
var previousUpdateTextContrastActionID: UUID?
var previousUpdateMarginActionID: UUID?
var previousUpdateLineHeightActionID: UUID?
var previousShowNavBarActionID: UUID?

View File

@ -5,6 +5,7 @@ public enum UserDefaultKey: String {
case preferredWebFontSize
case preferredWebLineSpacing
case preferredWebMargin
case prefersHighContrastWebFont
case userHasDeniedPushPrimer
case firebasePushToken
case homeFeedlayoutPreference

View File

@ -51,6 +51,16 @@ public final class WebView: WKWebView {
}
}
public func updateTextContrast() {
let isHighContrast = UserDefaults.standard.value(
forKey: UserDefaultKey.prefersHighContrastWebFont.rawValue
) as? Bool
if let isHighContrast = isHighContrast {
dispatchEvent(.handleFontContrastChange(isHighContrast: isHighContrast))
}
}
public func shareOriginalItem() {
dispatchEvent(.share)
}
@ -228,6 +238,7 @@ public final class WebView: WKWebView {
#endif
public enum WebViewDispatchEvent {
case handleFontContrastChange(isHighContrast: Bool)
case updateLineHeight(height: Int)
case updateMargin(width: Int)
case updateFontSize(size: Int)
@ -247,6 +258,8 @@ public enum WebViewDispatchEvent {
private var eventName: String {
switch self {
case .handleFontContrastChange:
return "handleFontContrastChange"
case .updateLineHeight:
return "updateLineHeight"
case .updateMargin:
@ -276,6 +289,8 @@ public enum WebViewDispatchEvent {
private var scriptPropertyLine: String {
switch self {
case let .handleFontContrastChange(isHighContrast: isHighContrast):
return "event.fontContrast = '\(isHighContrast ? "high" : "normal")';"
case let .updateLineHeight(height: height):
return "event.lineHeight = '\(height)';"
case let .updateMargin(width: width):

View File

@ -12,6 +12,7 @@ public enum WebFont: String, CaseIterable {
public struct WebPreferencesPopoverView: View {
let updateFontFamilyAction: () -> Void
let updateFontAction: () -> Void
let updateTextContrastAction: () -> Void
let updateMarginAction: () -> Void
let updateLineHeightAction: () -> Void
let dismissAction: () -> Void
@ -26,16 +27,19 @@ public struct WebPreferencesPopoverView: View {
@AppStorage(UserDefaultKey.preferredWebLineSpacing.rawValue) var storedLineSpacing = 150
@AppStorage(UserDefaultKey.preferredWebMargin.rawValue) var storedMargin = 360
@AppStorage(UserDefaultKey.preferredWebFont.rawValue) var preferredFont = WebFont.inter.rawValue
@AppStorage(UserDefaultKey.prefersHighContrastWebFont.rawValue) var prefersHighContrastText = false
public init(
updateFontFamilyAction: @escaping () -> Void,
updateFontAction: @escaping () -> Void,
updateTextContrastAction: @escaping () -> Void,
updateMarginAction: @escaping () -> Void,
updateLineHeightAction: @escaping () -> Void,
dismissAction: @escaping () -> Void
) {
self.updateFontFamilyAction = updateFontFamilyAction
self.updateFontAction = updateFontAction
self.updateTextContrastAction = updateTextContrastAction
self.updateMarginAction = updateMarginAction
self.updateLineHeightAction = updateLineHeightAction
self.dismissAction = dismissAction
@ -60,69 +64,77 @@ public struct WebPreferencesPopoverView: View {
}
)
}
.padding()
}
.listStyle(.plain)
.navigationBarTitleDisplayMode(.inline)
}
public var body: some View {
NavigationView {
VStack(alignment: .center) {
Text("Reader Preferences")
.foregroundColor(.appGrayText)
.font(Font.system(size: 17, weight: .semibold))
ScrollView(showsIndicators: false) {
VStack(alignment: .center) {
VStack {
LabelledStepper(
labelText: "Font Size:",
onIncrement: {
storedFontSize = min(storedFontSize + 2, 28)
updateFontAction()
},
onDecrement: {
storedFontSize = max(storedFontSize - 2, 10)
updateFontAction()
}
)
LabelledStepper(
labelText: "Font Size:",
onIncrement: {
storedFontSize = min(storedFontSize + 2, 28)
updateFontAction()
},
onDecrement: {
storedFontSize = max(storedFontSize - 2, 10)
updateFontAction()
}
)
if UIDevice.isIPad {
LabelledStepper(
labelText: "Margin:",
onIncrement: {
storedMargin = min(storedMargin + 45, 560)
updateMarginAction()
},
onDecrement: {
storedMargin = max(storedMargin - 45, 200)
updateMarginAction()
if UIDevice.isIPad {
LabelledStepper(
labelText: "Margin:",
onIncrement: {
storedMargin = min(storedMargin + 45, 560)
updateMarginAction()
},
onDecrement: {
storedMargin = max(storedMargin - 45, 200)
updateMarginAction()
}
)
}
)
}
LabelledStepper(
labelText: "Line Spacing:",
onIncrement: {
storedLineSpacing = min(storedLineSpacing + 25, 300)
updateLineHeightAction()
},
onDecrement: {
storedLineSpacing = max(storedLineSpacing - 25, 100)
updateLineHeightAction()
LabelledStepper(
labelText: "Line Spacing:",
onIncrement: {
storedLineSpacing = min(storedLineSpacing + 25, 300)
updateLineHeightAction()
},
onDecrement: {
storedLineSpacing = max(storedLineSpacing - 25, 100)
updateLineHeightAction()
}
)
Toggle("High Contrast Text:", isOn: $prefersHighContrastText)
.frame(height: 40)
.padding(.trailing, 6)
.onChange(of: prefersHighContrastText) { _ in
updateTextContrastAction()
}
HStack {
NavigationLink(destination: fontList) {
Text("Change Reader Font")
}
Image(systemName: "chevron.right")
Spacer()
}
.frame(height: 40)
Spacer()
}
)
HStack {
NavigationLink(destination: fontList) {
Text("Change Reader Font")
}
Image(systemName: "chevron.right")
Spacer()
}
.frame(height: 40)
Spacer()
}
.padding()
.navigationBarHidden(true)
.navigationTitle("Reader Preferences")
.navigationBarTitleDisplayMode(.inline)
}
.accentColor(.appGrayTextContrast)
}

File diff suppressed because one or more lines are too long

View File

@ -32,6 +32,7 @@ type ArticleContainerProps = {
fontSize?: number
fontFamily?: string
lineHeight?: number
highContrastFont?: boolean
showHighlightsModal: boolean
setShowHighlightsModal: React.Dispatch<React.SetStateAction<boolean>>
}
@ -48,6 +49,7 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element {
const [fontFamilyOverride, setFontFamilyOverride] = useState<string | null>(
null
)
const [highContrastFont, setHighContrastFont] = useState(props.highContrastFont ?? false)
const highlightHref = useRef(
window.location.hash ? window.location.hash.split('#')[1] : null
)
@ -117,6 +119,15 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element {
setFontFamilyOverride(newFontFamily)
}
interface UpdateFontContrastEvent extends Event {
fontContrast?: 'high' | 'normal'
}
const handleFontContrastChange = async (event: UpdateFontContrastEvent) => {
const highContrast = event.fontContrast == 'high'
setHighContrastFont(highContrast)
}
interface UpdateFontSizeEvent extends Event {
fontSize?: number
}
@ -151,6 +162,7 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element {
document.addEventListener('updateMargin', updateMargin)
document.addEventListener('updateFontSize', handleFontSizeChange)
document.addEventListener('updateColorMode', updateColorMode)
document.addEventListener('handleFontContrastChange', handleFontContrastChange)
document.addEventListener('share', share)
return () => {
@ -159,6 +171,7 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element {
document.removeEventListener('updateMargin', updateMargin)
document.removeEventListener('updateFontSize', handleFontSizeChange)
document.removeEventListener('updateColorMode', updateColorMode)
document.removeEventListener('handleFontContrastChange', handleFontContrastChange)
document.removeEventListener('share', share)
}
})
@ -168,7 +181,7 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element {
margin: marginOverride ?? props.margin ?? 360,
lineHeight: lineHeightOverride ?? props.lineHeight ?? 150,
fontFamily: fontFamilyOverride ?? props.fontFamily ?? 'inter',
readerFontColor: theme.colors.readerFont.toString(),
readerFontColor: highContrastFont ? theme.colors.readerFontHighContrast.toString() : theme.colors.readerFont.toString(),
readerFontColorTransparent: theme.colors.readerFontTransparent.toString(),
readerTableHeaderColor: theme.colors.readerTableHeader.toString(),
readerHeadersColor: theme.colors.readerHeader.toString(),

View File

@ -139,6 +139,7 @@ export const { styled, css, theme, getCssText, globalCss, keyframes, config } =
// Reader Colors
readerBg: '#E5E5E5',
readerFont: '#3D3D3D',
readerFontHighContrast: 'black',
readerFontTransparent: 'rgba(61,61,61,0.65)',
readerHeader: '3D3D3D',
readerTableHeader: '#FFFFFF',
@ -194,6 +195,7 @@ const darkThemeSpec = {
// Reader Colors
readerBg: '#303030',
readerFont: '#b9b9b9',
readerFontHighContrast: 'black',
readerFontTransparent: 'rgba(185,185,185,0.65)',
readerHeader: '#b9b9b9',
readerTableHeader: '#FFFFFF',