From 467a37e8cc370dea2912a7be44ea39a8d2fc002f Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Fri, 28 Oct 2022 09:32:00 +0800 Subject: [PATCH] WIP: New themes and reader preferences for iOS --- .../AppStoreScreenshots.swift | 7 +- .../App/Views/WebReader/WebReader.swift | 1 + .../Views/WebReader/WebReaderContainer.swift | 4 +- .../Views/WebReader/WebReaderContent.swift | 4 +- .../WebReader/WebReaderCoordinator.swift | 2 +- .../AudioSession/SpeechSynthesizer.swift | 2 +- .../Sources/Utils/UserDefaultKeys.swift | 1 + .../Views/Article/OmnivoreWebView.swift | 11 ++ .../Views/FontSizeAdjustmentPopoverView.swift | 161 +++++++++++------- apple/OmnivoreKit/Sources/Views/Theme.swift | 54 ++++++ .../Sources/Views/Web/BasicWebAppView.swift | 4 +- .../templates/article/ArticleContainer.tsx | 22 ++- .../article/ReaderSettingsControl.tsx | 4 +- .../article/SkeletonArticleContainer.tsx | 2 - .../web/components/tokens/stitches.config.ts | 37 +++- packages/web/lib/themeUpdater.tsx | 10 +- packages/web/pages/_document.tsx | 3 +- 17 files changed, 236 insertions(+), 93 deletions(-) create mode 100644 apple/OmnivoreKit/Sources/Views/Theme.swift diff --git a/apple/AppStoreScreenshots/AppStoreScreenshots.swift b/apple/AppStoreScreenshots/AppStoreScreenshots.swift index 974b76e81..09b6afc82 100644 --- a/apple/AppStoreScreenshots/AppStoreScreenshots.swift +++ b/apple/AppStoreScreenshots/AppStoreScreenshots.swift @@ -83,8 +83,11 @@ final class AppStoreScreenshots: XCTestCase { func testScreenshotSubscriptions() throws { let app = XCUIApplication() setupSnapshot(app) - app.navigationBars["Home"]/*@START_MENU_TOKEN@*/ .buttons["_profile"]/*[[".otherElements[\"_profile\"].buttons[\"_profile\"]",".buttons[\"_profile\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/ .tap() - app.collectionViews.buttons["Subscriptions"].tap() +// app.navigationBars.firstMatch.buttons["person.circle"].tap() +// app.collectionViews.buttons["Subscriptions"].tap() +// +// XCUIApplication().navigationBars["_TtGC7SwiftUI19UIHosting"]/*@START_MENU_TOKEN@*/.buttons["ToggleSidebar"]/*[[".buttons[\"Show Sidebar\"]",".buttons[\"ToggleSidebar\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap() +// snapshot("Newsletters") diff --git a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReader.swift b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReader.swift index 0e5a7551c..708b03e37 100644 --- a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReader.swift +++ b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReader.swift @@ -89,6 +89,7 @@ struct WebReader: PlatformViewRepresentable { if readerSettingsChangedTransactionID != context.coordinator.previousReaderSettingsChangedUUID { context.coordinator.previousReaderSettingsChangedUUID = readerSettingsChangedTransactionID + (webView as? OmnivoreWebView)?.updateTheme() (webView as? OmnivoreWebView)?.updateFontFamily() (webView as? OmnivoreWebView)?.updateFontSize() (webView as? OmnivoreWebView)?.updateTextContrast() diff --git a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContainer.swift b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContainer.swift index a81f5de1f..4ff5f2f62 100644 --- a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContainer.swift +++ b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContainer.swift @@ -240,7 +240,8 @@ struct WebReaderContainerView: View { } .frame(height: readerViewNavBarHeight * navBarVisibilityRatio) .opacity(navBarVisibilityRatio) - .background(Color.systemBackground) + .background(Color.black) + .background(Theme.fromName(themeName: ThemeManager.currentThemeName)?.bgColor ?? .clear) .alert("Are you sure?", isPresented: $showDeleteConfirmation) { Button("Remove Link", role: .destructive) { Snackbar.show(message: "Link removed") @@ -301,6 +302,7 @@ struct WebReaderContainerView: View { annotation: $annotation, showBottomBar: $showBottomBar ) + .background(Theme.fromName(themeName: ThemeManager.currentThemeName)?.bgColor ?? .clear) .onTapGesture { withAnimation { navBarVisibilityRatio = 1 diff --git a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContent.swift b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContent.swift index 6aaa82bcf..79c1e5d07 100644 --- a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContent.swift +++ b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContent.swift @@ -16,7 +16,7 @@ struct WebReaderContent { init( item: LinkedItem, articleContent: ArticleContent, - isDark: Bool, + isDark _: Bool, fontSize: Int, lineHeight: Int, maxWidthPercentage: Int, @@ -27,7 +27,7 @@ struct WebReaderContent { self.lineHeight = lineHeight self.maxWidthPercentage = maxWidthPercentage self.item = item - self.themeKey = isDark ? "Gray" : "LightGray" + self.themeKey = ThemeManager.currentThemeName // isDark ? "Gray" : "Charcoal" self.fontFamily = fontFamily self.articleContent = articleContent self.prefersHighContrastText = prefersHighContrastText diff --git a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderCoordinator.swift b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderCoordinator.swift index 99e9952d3..35fb77f63 100644 --- a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderCoordinator.swift +++ b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderCoordinator.swift @@ -74,7 +74,7 @@ extension WebReaderCoordinator: WKNavigationDelegate { func webView(_ webView: WKWebView, didFinish _: WKNavigation!) { #if os(iOS) webView.isOpaque = true - webView.backgroundColor = .systemBackground + webView.backgroundColor = .clear #endif } diff --git a/apple/OmnivoreKit/Sources/Services/AudioSession/SpeechSynthesizer.swift b/apple/OmnivoreKit/Sources/Services/AudioSession/SpeechSynthesizer.swift index c54355f6a..370d1f8e9 100644 --- a/apple/OmnivoreKit/Sources/Services/AudioSession/SpeechSynthesizer.swift +++ b/apple/OmnivoreKit/Sources/Services/AudioSession/SpeechSynthesizer.swift @@ -120,7 +120,7 @@ struct SpeechSynthesizer { func createPlayerItems(from: Int) -> [SpeechItem] { var result: [SpeechItem] = [] - for idx in from ..< document.utterances.count { + for idx in from ..< min(7, document.utterances.count) { let utterance = document.utterances[idx] let voiceStr = utterance.voice ?? document.defaultVoice let segmentStr = String(format: "%04d", arguments: [idx]) diff --git a/apple/OmnivoreKit/Sources/Utils/UserDefaultKeys.swift b/apple/OmnivoreKit/Sources/Utils/UserDefaultKeys.swift index a12253a37..f61b0742c 100644 --- a/apple/OmnivoreKit/Sources/Utils/UserDefaultKeys.swift +++ b/apple/OmnivoreKit/Sources/Utils/UserDefaultKeys.swift @@ -19,4 +19,5 @@ public enum UserDefaultKey: String { case textToSpeechPreloadEnabled case recentSearchTerms case audioPlayerExpanded + case themeName } diff --git a/apple/OmnivoreKit/Sources/Views/Article/OmnivoreWebView.swift b/apple/OmnivoreKit/Sources/Views/Article/OmnivoreWebView.swift index 006e57924..2b97441d4 100644 --- a/apple/OmnivoreKit/Sources/Views/Article/OmnivoreWebView.swift +++ b/apple/OmnivoreKit/Sources/Views/Article/OmnivoreWebView.swift @@ -44,6 +44,12 @@ public final class OmnivoreWebView: WKWebView { fatalError("init(coder:) has not been implemented") } + public func updateTheme() { + if let themeName = UserDefaults.standard.value(forKey: UserDefaultKey.themeName.rawValue) as? String { + dispatchEvent(.updateTheme(themeName: "Gray" /* themeName */ )) + } + } + public func updateFontFamily() { if let fontFamily = UserDefaults.standard.value(forKey: UserDefaultKey.preferredWebFont.rawValue) as? String { dispatchEvent(.updateFontFamily(family: fontFamily)) @@ -293,6 +299,7 @@ public enum WebViewDispatchEvent { case updateFontSize(size: Int) case updateColorMode(isDark: Bool) case updateFontFamily(family: String) + case updateTheme(themeName: String) case saveAnnotation(annotation: String) case annotate case highlight @@ -320,6 +327,8 @@ public enum WebViewDispatchEvent { return "updateColorMode" case .updateFontFamily: return "updateFontFamily" + case .updateTheme: + return "updateTheme" case .saveAnnotation: return "saveAnnotation" case .annotate: @@ -347,6 +356,8 @@ public enum WebViewDispatchEvent { return "event.lineHeight = '\(height)';" case let .updateMaxWidthPercentage(maxWidthPercentage: maxWidthPercentage): return "event.maxWidthPercentage = '\(maxWidthPercentage)';" + case let .updateTheme(themeName: themeName): + return "event.themeName = '\(themeName)';" case let .updateFontSize(size: size): return "event.fontSize = '\(size)';" case let .updateColorMode(isDark: isDark): diff --git a/apple/OmnivoreKit/Sources/Views/FontSizeAdjustmentPopoverView.swift b/apple/OmnivoreKit/Sources/Views/FontSizeAdjustmentPopoverView.swift index e6877fe23..9d9d12f93 100644 --- a/apple/OmnivoreKit/Sources/Views/FontSizeAdjustmentPopoverView.swift +++ b/apple/OmnivoreKit/Sources/Views/FontSizeAdjustmentPopoverView.swift @@ -69,81 +69,112 @@ public enum WebFont: String, CaseIterable { .navigationTitle("Reader Font") } + var themePicker: some View { + ScrollView(.horizontal, showsIndicators: false) { + HStack(spacing: 16) { + ForEach(Theme.allCases, id: \.self) { theme in + VStack { + ZStack { + Circle() + .foregroundColor(theme.bgColor) + .frame(minWidth: 32, minHeight: 32) + .padding(8) + } + + Text(theme.rawValue).font(.appCaption) + } + .padding(8) + .background(Color(red: 248 / 255.0, green: 248 / 255.0, blue: 248 / 255.0)) + .onTapGesture { + ThemeManager.currentThemeName = theme.rawValue + updateReaderPreferences() + } + .cornerRadius(8) + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(ThemeManager.currentThemeName == theme.rawValue ? Color.appCtaYellow : .clear, lineWidth: 2) + ) + .padding(2) + } + } + } + } + public var body: some View { NavigationView { - ScrollView(showsIndicators: false) { - VStack(alignment: .center) { - VStack { - LabelledStepper( - labelText: "Font Size:", - onIncrement: { - storedFontSize = min(storedFontSize + 2, 28) - updateReaderPreferences() - }, - onDecrement: { - storedFontSize = max(storedFontSize - 2, 10) - updateReaderPreferences() - } - ) + VStack(alignment: .center) { + themePicker + .padding(.bottom, 16) - LabelledStepper( - labelText: "Margin:", - onIncrement: { - storedMaxWidthPercentage = max(storedMaxWidthPercentage - 10, 40) - updateReaderPreferences() - }, - onDecrement: { - storedMaxWidthPercentage = min(storedMaxWidthPercentage + 10, 100) - updateReaderPreferences() - } - ) - - LabelledStepper( - labelText: "Line Spacing:", - onIncrement: { - storedLineSpacing = min(storedLineSpacing + 25, 300) - updateReaderPreferences() - }, - onDecrement: { - storedLineSpacing = max(storedLineSpacing - 25, 100) - updateReaderPreferences() - } - ) - - Toggle("High Contrast Text:", isOn: $prefersHighContrastText) - .frame(height: 40) - .padding(.trailing, 6) - .onChange(of: prefersHighContrastText) { _ in - updateReaderPreferences() - } - - HStack { - NavigationLink(destination: fontList) { - Text("Change Reader Font") - } - Image(systemName: "chevron.right") - Spacer() - } - .frame(height: 40) - - Spacer() + LabelledStepper( + labelText: "Font Size", + onIncrement: { + storedFontSize = min(storedFontSize + 2, 28) + updateReaderPreferences() + }, + onDecrement: { + storedFontSize = max(storedFontSize - 2, 10) + updateReaderPreferences() } + ) + + LabelledStepper( + labelText: "Margin", + onIncrement: { + storedMaxWidthPercentage = max(storedMaxWidthPercentage - 10, 40) + updateReaderPreferences() + }, + onDecrement: { + storedMaxWidthPercentage = min(storedMaxWidthPercentage + 10, 100) + updateReaderPreferences() + } + ) + + LabelledStepper( + labelText: "Line Spacing", + onIncrement: { + storedLineSpacing = min(storedLineSpacing + 25, 300) + updateReaderPreferences() + }, + onDecrement: { + storedLineSpacing = max(storedLineSpacing - 25, 100) + updateReaderPreferences() + } + ) + + HStack { + NavigationLink(destination: fontList) { + Text("Font") + } + Spacer() + Button(action: {}, label: { Text("Crimson Text").frame(width: 91) }) + .buttonStyle(RoundedRectButtonStyle()) } + .frame(height: 40) + + Toggle("High Contrast Text:", isOn: $prefersHighContrastText) + .frame(height: 40) + .padding(.trailing, 6) + .onChange(of: prefersHighContrastText) { _ in + updateReaderPreferences() + } + + Spacer() } .padding() .navigationTitle("Reader Preferences") .navigationBarTitleDisplayMode(.inline) - .toolbar { - ToolbarItem(placement: .barTrailing) { - Button( - action: dismissAction, - label: { Text("Done").foregroundColor(.appGrayTextContrast).padding() } - ) - } - } +// .toolbar { +// ToolbarItem(placement: .barTrailing) { +// Button( +// action: dismissAction, +// label: { Text("Done").foregroundColor(.appGrayTextContrast).padding() } +// ) +// } +// } } - .navigationViewStyle(.stack) - .accentColor(.appGrayTextContrast) + // .navigationViewStyle(.stack) + // .accentColor(.appGrayTextContrast) } } diff --git a/apple/OmnivoreKit/Sources/Views/Theme.swift b/apple/OmnivoreKit/Sources/Views/Theme.swift new file mode 100644 index 000000000..ece0f55fd --- /dev/null +++ b/apple/OmnivoreKit/Sources/Views/Theme.swift @@ -0,0 +1,54 @@ +// +// File.swift +// +// +// Created by Jackson Harper on 10/27/22. +// + +import Foundation +import SwiftUI +import Utils + +public enum Theme: String, CaseIterable { + case system = "System" + case sepia = "Sepia" + case charcoal = "Charcoal" + case mint = "Mint" + + case solarized = "Solarized" + + case light = "Light" + case dark = "Dark" + + public var bgColor: Color { + switch self { + case .system: + return Color.systemBackground + case .charcoal: + return Color(red: 48 / 255.0, green: 48 / 255.0, blue: 48 / 255.0) + case .sepia: + return Color(red: 249 / 255.0, green: 241 / 255.0, blue: 220 / 255.0) + case .mint: + return Color(red: 202 / 255.0, green: 230 / 255.0, blue: 208 / 255.0) + case .solarized: + return Color(red: 13 / 255.0, green: 39 / 255.0, blue: 50 / 255.0) + case .light: + return Color.white + case .dark: + return Color.black + } + } + + public static func fromName(themeName: String) -> Theme? { + for theme in Theme.allCases { + if theme.rawValue == themeName { + return theme + } + } + return nil + } +} + +public enum ThemeManager { + @AppStorage(UserDefaultKey.themeName.rawValue) public static var currentThemeName = "System" +} diff --git a/apple/OmnivoreKit/Sources/Views/Web/BasicWebAppView.swift b/apple/OmnivoreKit/Sources/Views/Web/BasicWebAppView.swift index d74d9691f..2618c0570 100644 --- a/apple/OmnivoreKit/Sources/Views/Web/BasicWebAppView.swift +++ b/apple/OmnivoreKit/Sources/Views/Web/BasicWebAppView.swift @@ -19,7 +19,7 @@ import WebKit webView.isOpaque = false webView.backgroundColor = UIColor.clear if let url = request.url { - let themeID = Color.isDarkMode ? "Gray" : "LightGray" + let themeID = Color.isDarkMode ? "Gray" /* "Sepia" */ : "Charcoal" webView.injectCookie(cookieString: "theme=\(themeID); Max-Age=31536000;", url: url) } return webView @@ -51,7 +51,7 @@ import WebKit if let url = request.url { // Dark mode is still rendering a white background on mac for some reason. // Forcing light mode for now until we figure out a fix - let themeID = "LightGray" // NSApp.effectiveAppearance.name == NSAppearance.Name.darkAqua ? "Gray" : "LightGray" + let themeID = "Charcoal" // NSApp.effectiveAppearance.name == NSAppearance.Name.darkAqua ? "Gray" : "LightGray" webView.injectCookie(cookieString: "theme=\(themeID); Max-Age=31536000;", url: url) } return webView diff --git a/packages/web/components/templates/article/ArticleContainer.tsx b/packages/web/components/templates/article/ArticleContainer.tsx index fe1dc0697..e05b848ed 100644 --- a/packages/web/components/templates/article/ArticleContainer.tsx +++ b/packages/web/components/templates/article/ArticleContainer.tsx @@ -11,7 +11,7 @@ import { ReportIssuesModal } from './ReportIssuesModal' import { reportIssueMutation } from '../../../lib/networking/mutations/reportIssueMutation' import { ArticleHeaderToolbar } from './ArticleHeaderToolbar' import { userPersonalizationMutation } from '../../../lib/networking/mutations/userPersonalizationMutation' -import { updateThemeLocally } from '../../../lib/themeUpdater' +import { updateTheme, updateThemeLocally } from '../../../lib/themeUpdater' import { ArticleMutations } from '../../../lib/articleActions' import { LabelChip } from '../../elements/LabelChip' import { Label } from '../../../lib/networking/fragments/labelFragment' @@ -121,6 +121,17 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element { } } + interface UpdateThemeEvent extends Event { + themeName?: string + } + + const handleThemeChange = async (event: UpdateThemeEvent) => { + const newTheme = event.themeName + if (newTheme) { + updateTheme(newTheme) + } + } + interface UpdateColorModeEvent extends Event { isDark?: string } @@ -145,6 +156,7 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element { 'updateMaxWidthPercentage', updateMaxWidthPercentage ) + document.addEventListener('updateTheme', handleThemeChange) document.addEventListener('updateFontSize', handleFontSizeChange) document.addEventListener('updateColorMode', updateColorMode) document.addEventListener( @@ -160,6 +172,7 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element { 'updateMaxWidthPercentage', updateMaxWidthPercentage ) + document.removeEventListener('updateTheme', handleThemeChange) document.removeEventListener('updateFontSize', handleFontSizeChange) document.removeEventListener('updateColorMode', updateColorMode) document.removeEventListener( @@ -179,7 +192,6 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element { 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(), } @@ -192,8 +204,8 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element { padding: '16px', maxWidth: `${styles.maxWidthPercentage ?? 100}%`, background: props.isAppleAppEmbed - ? 'unset' - : theme.colors.grayBg.toString(), + ? theme.colors.readerBg.toString() + : theme.colors.readerBg.toString(), '--text-font-family': styles.fontFamily, '--text-font-size': `${styles.fontSize}px`, '--line-height': `${styles.lineHeight}%`, @@ -202,7 +214,6 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element { '--figure-margin': '1.6rem auto', '--hr-margin': '1em', '--font-color': styles.readerFontColor, - '--font-color-transparent': styles.readerFontColorTransparent, '--table-header-color': styles.readerTableHeaderColor, '--headers-color': styles.readerHeadersColor, '@sm': { @@ -227,6 +238,7 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element { fontFamily: styles.fontFamily, width: '100%', wordWrap: 'break-word', + color: '$readerFont', }} > {props.article.title} diff --git a/packages/web/components/templates/article/ReaderSettingsControl.tsx b/packages/web/components/templates/article/ReaderSettingsControl.tsx index 63ad1000f..7ac275079 100644 --- a/packages/web/components/templates/article/ReaderSettingsControl.tsx +++ b/packages/web/components/templates/article/ReaderSettingsControl.tsx @@ -126,7 +126,7 @@ export function ReaderSettingsControl(props: ReaderSettingsProps): JSX.Element { }} > Margin: @@ -193,7 +193,7 @@ export function ReaderSettingsControl(props: ReaderSettingsProps): JSX.Element { }} > Line Spacing: diff --git a/packages/web/components/templates/article/SkeletonArticleContainer.tsx b/packages/web/components/templates/article/SkeletonArticleContainer.tsx index 115a91b87..d7ef809e7 100644 --- a/packages/web/components/templates/article/SkeletonArticleContainer.tsx +++ b/packages/web/components/templates/article/SkeletonArticleContainer.tsx @@ -17,7 +17,6 @@ export function SkeletonArticleContainer(props: SkeletonArticleContainerProps): lineHeight: props.lineHeight ?? 150, fontFamily: props.fontFamily ?? 'inter', readerFontColor: theme.colors.readerFont.toString(), - readerFontColorTransparent: theme.colors.readerFontTransparent.toString(), readerTableHeaderColor: theme.colors.readerTableHeader.toString(), readerHeadersColor: theme.colors.readerHeader.toString(), } @@ -40,7 +39,6 @@ export function SkeletonArticleContainer(props: SkeletonArticleContainerProps): '--figure-margin': '1.6rem auto', '--hr-margin': '1em', '--font-color': styles.readerFontColor, - '--font-color-transparent': styles.readerFontColorTransparent, '--table-header-color': styles.readerTableHeaderColor, '--headers-color': styles.readerHeadersColor, '@sm': { diff --git a/packages/web/components/tokens/stitches.config.ts b/packages/web/components/tokens/stitches.config.ts index 9bc77b0a2..5ec714070 100644 --- a/packages/web/components/tokens/stitches.config.ts +++ b/packages/web/components/tokens/stitches.config.ts @@ -6,6 +6,8 @@ export enum ThemeId { Light = 'LightGray', Dark = 'Gray', Darker = 'Dark', + Sepia = 'Sepia', + Charcoal = 'Charcoal' } export const { styled, css, theme, getCssText, globalCss, keyframes, config } = @@ -144,11 +146,10 @@ export const { styled, css, theme, getCssText, globalCss, keyframes, config } = omnivoreCtaYellow: 'rgb(255, 210, 52)', // Reader Colors - readerBg: '#E5E5E5', - readerFont: '#3D3D3D', - readerFontHighContrast: 'black', - readerFontTransparent: 'rgba(61,61,61,0.65)', - readerHeader: '3D3D3D', + readerBg: '#F9F1DC', // #E5E5E5', + readerFont: '#554A34', + readerFontHighContrast: '#342100', // black', + readerHeader: '554A34', readerTableHeader: '#FFFFFF', // Avatar Fallback color @@ -211,7 +212,6 @@ const darkThemeSpec = { readerBg: '#303030', readerFont: '#b9b9b9', readerFontHighContrast: 'white', - readerFontTransparent: 'rgba(185,185,185,0.65)', readerHeader: '#b9b9b9', readerTableHeader: '#FFFFFF', tooltipIcons: '#5F5E58', @@ -236,12 +236,35 @@ const darkThemeSpec = { }, } -// Avatar Fallback color +const sepiaThemeSpec = { + colors: { + // Reader Colors + readerBg: '#F9F1DC', + readerFont: '#554A34', + readerFontHighContrast: 'black', + readerHeader: '554A34', + readerTableHeader: '#FFFFFF', + } +} + +const charcoalThemeSpec = { + colors: { + // Reader Colors + readerBg: '#303030', + readerFont: '#b9b9b9', + readerFontHighContrast: 'white', + readerHeader: '#b9b9b9', + readerTableHeader: '#FFFFFF', + } +} + // Dark and Darker theme now match each other. // Use the darkThemeSpec object to make updates. export const darkTheme = createTheme(ThemeId.Dark, darkThemeSpec) export const darkerTheme = createTheme(ThemeId.Darker, darkThemeSpec) +export const sepiaTheme = createTheme(ThemeId.Sepia, {...darkThemeSpec, ...sepiaThemeSpec}) +export const charcoalTheme = createTheme(ThemeId.Charcoal, {...darkThemeSpec, ...charcoalThemeSpec}) // Lighter theme now matches the default theme. // This only exists for users that might still have a lighter theme set diff --git a/packages/web/lib/themeUpdater.tsx b/packages/web/lib/themeUpdater.tsx index 5efc2bd09..762468449 100644 --- a/packages/web/lib/themeUpdater.tsx +++ b/packages/web/lib/themeUpdater.tsx @@ -3,6 +3,8 @@ import { lighterTheme, darkTheme, darkerTheme, + sepiaTheme, + charcoalTheme, } from '../components/tokens/stitches.config' import { userPersonalizationMutation } from './networking/mutations/userPersonalizationMutation' @@ -26,7 +28,9 @@ export function updateThemeLocally(themeId: string): void { lighterTheme, ThemeId.Light, darkTheme, - darkerTheme + darkerTheme, + sepiaTheme, + charcoalTheme ) document.body.classList.add(themeId) } @@ -41,6 +45,10 @@ export function currentThemeName(): string { return 'Darker' case ThemeId.Lighter: return 'Lighter' + case ThemeId.Sepia: + return 'Sepia' + case ThemeId.Charcoal: + return 'Charcoal' default: return '' } diff --git a/packages/web/pages/_document.tsx b/packages/web/pages/_document.tsx index c36dfa4f9..927d240dc 100644 --- a/packages/web/pages/_document.tsx +++ b/packages/web/pages/_document.tsx @@ -1,6 +1,5 @@ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ /* eslint-disable functional/no-class */ -import { useEffect } from 'react' import NextDocument, { Html, Head, Main, NextScript } from 'next/document' import { getCssText, globalStyles } from '../components/tokens/stitches.config' @@ -35,7 +34,7 @@ export default class Document extends NextDocument { var themeId = window.localStorage.getItem('theme') if (themeId) { - document.body.classList.remove('theme-default', 'White', 'Gray', 'LightGray', 'Dark') + document.body.classList.remove('theme-default', 'White', 'Gray', 'LightGray', 'Dark', 'Sepia', 'Charcoal') document.body.classList.add(themeId) } `