diff --git a/packages/web/components/elements/LogoBox.tsx b/packages/web/components/elements/LogoBox.tsx
index a0afa173d..94d45e895 100644
--- a/packages/web/components/elements/LogoBox.tsx
+++ b/packages/web/components/elements/LogoBox.tsx
@@ -32,7 +32,7 @@ export function LogoBox(): JSX.Element {
},
}}
>
-
+
>
)
diff --git a/packages/web/components/patterns/DropdownMenu.tsx b/packages/web/components/patterns/DropdownMenu.tsx
index efa46dfcc..7f6ffe6eb 100644
--- a/packages/web/components/patterns/DropdownMenu.tsx
+++ b/packages/web/components/patterns/DropdownMenu.tsx
@@ -11,10 +11,8 @@ import { currentThemeName } from '../../lib/themeUpdater'
import { Check } from 'phosphor-react'
export type HeaderDropdownAction =
- | 'apply-darker-theme'
| 'apply-dark-theme'
| 'apply-light-theme'
- | 'apply-lighter-theme'
| 'navigate-to-install'
| 'navigate-to-emails'
| 'navigate-to-labels'
@@ -49,7 +47,7 @@ export function DropdownMenu(props: DropdownMenuProps): JSX.Element {
css={{ background: '#FFFFFF' }}
data-state={isDark ? 'unselected' : 'selected'}
onClick={() => {
- props.actionHandler('apply-lighter-theme')
+ props.actionHandler('apply-light-theme')
setCurrentTheme(currentThemeName())
}}
>
diff --git a/packages/web/components/templates/PrimaryDropdown.tsx b/packages/web/components/templates/PrimaryDropdown.tsx
index 3cfa6e774..b4cda53c8 100644
--- a/packages/web/components/templates/PrimaryDropdown.tsx
+++ b/packages/web/components/templates/PrimaryDropdown.tsx
@@ -234,7 +234,7 @@ function ThemeSection(props: PrimaryDropdownProps): JSX.Element {
}}
>
{
updateTheme(ThemeId.Light)
}}
@@ -243,9 +243,9 @@ function ThemeSection(props: PrimaryDropdownProps): JSX.Element {
{
- updateTheme(ThemeId.Darker)
+ updateTheme(ThemeId.Dark)
}}
>
Dark
diff --git a/packages/web/components/templates/PrimaryLayout.tsx b/packages/web/components/templates/PrimaryLayout.tsx
index 790dd7b2c..f0764cb84 100644
--- a/packages/web/components/templates/PrimaryLayout.tsx
+++ b/packages/web/components/templates/PrimaryLayout.tsx
@@ -10,6 +10,7 @@ import { KeyboardShortcutListModal } from './KeyboardShortcutListModal'
import { logoutMutation } from '../../lib/networking/mutations/logoutMutation'
import { setupAnalytics } from '../../lib/analytics'
import { primaryCommands } from '../../lib/keyboardShortcuts/navigationShortcuts'
+import { applyStoredTheme } from '../../lib/themeUpdater'
type PrimaryLayoutProps = {
children: ReactNode
@@ -21,6 +22,8 @@ type PrimaryLayoutProps = {
}
export function PrimaryLayout(props: PrimaryLayoutProps): JSX.Element {
+ applyStoredTheme(false)
+
const { viewerData } = useGetViewerQuery()
const router = useRouter()
const [showLogoutConfirmation, setShowLogoutConfirmation] = useState(false)
diff --git a/packages/web/components/templates/article/ArticleContainer.tsx b/packages/web/components/templates/article/ArticleContainer.tsx
index 35263c034..22412dc11 100644
--- a/packages/web/components/templates/article/ArticleContainer.tsx
+++ b/packages/web/components/templates/article/ArticleContainer.tsx
@@ -9,17 +9,15 @@ import {
import { theme, ThemeId } from './../../tokens/stitches.config'
import { HighlightsLayer } from '../../templates/article/HighlightsLayer'
import { Button } from '../../elements/Button'
-import { useEffect, useState, useRef, useMemo } from 'react'
+import { useEffect, useState, useRef, useMemo, useCallback } from 'react'
import { ReportIssuesModal } from './ReportIssuesModal'
import { reportIssueMutation } from '../../../lib/networking/mutations/reportIssueMutation'
-import { userPersonalizationMutation } from '../../../lib/networking/mutations/userPersonalizationMutation'
import { updateTheme, updateThemeLocally } from '../../../lib/themeUpdater'
import { ArticleMutations } from '../../../lib/articleActions'
import { LabelChip } from '../../elements/LabelChip'
import { Label } from '../../../lib/networking/fragments/labelFragment'
import { Recommendation } from '../../../lib/networking/queries/useGetLibraryItemsQuery'
import { Avatar } from '../../elements/Avatar'
-import { usePersistedState } from '../../../lib/hooks/usePersistedState'
type ArticleContainerProps = {
article: ArticleAttributes
@@ -125,12 +123,14 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element {
window.location.hash ? window.location.hash.split('#')[1] : null
)
- const updateFontSize = async (newFontSize: number) => {
- if (fontSize !== newFontSize) {
- setFontSize(newFontSize)
- await userPersonalizationMutation({ fontSize: newFontSize })
- }
- }
+ const updateFontSize = useCallback(
+ (newFontSize: number) => {
+ if (fontSize !== newFontSize) {
+ setFontSize(newFontSize)
+ }
+ },
+ [setFontSize]
+ )
useEffect(() => {
updateFontSize(props.fontSize ?? 20)
@@ -279,7 +279,7 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element {
@@ -325,6 +328,7 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element {
fontFamily: styles.fontFamily,
width: '100%',
wordWrap: 'break-word',
+ color: styles.readerFontColor,
}}
>
{props.article.title}
diff --git a/packages/web/components/templates/article/ReaderSettingsControl.tsx b/packages/web/components/templates/article/ReaderSettingsControl.tsx
index 8670503ff..0484c47e9 100644
--- a/packages/web/components/templates/article/ReaderSettingsControl.tsx
+++ b/packages/web/components/templates/article/ReaderSettingsControl.tsx
@@ -520,10 +520,7 @@ function LayoutControls(props: LayoutControlsProps): JSX.Element {
function ThemeSelector(props: ReaderSettingsProps): JSX.Element {
const [currentTheme, setCurrentTheme] = useState(currentThemeName())
-
- const isDark = useMemo(() => {
- return currentTheme === 'Dark' || currentTheme === 'Darker'
- }, [currentTheme])
+ console.log('currentTheme: ', currentTheme)
return (
{
updateTheme(ThemeId.Light)
setCurrentTheme(currentThemeName())
}}
>
- {!isDark && }
+ {currentTheme == ThemeId.Light && (
+
+ )}
+
+
diff --git a/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx b/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx
index 480c6fcdd..60bc3863b 100644
--- a/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx
+++ b/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx
@@ -34,7 +34,6 @@ import {
} from '../../../lib/networking/fragments/articleFragment'
import { Action, createAction, useKBar, useRegisterActions } from 'kbar'
import { EditLibraryItemModal } from './EditItemModals'
-import { useGetUserPreferences } from '../../../lib/networking/queries/useGetUserPreferences'
import debounce from 'lodash/debounce'
import {
SearchItem,
@@ -65,8 +64,6 @@ const debouncedFetchSearchResults = debounce((query, cb) => {
}, 300)
export function HomeFeedContainer(): JSX.Element {
- useGetUserPreferences()
-
const { viewerData } = useGetViewerQuery()
const router = useRouter()
const { queryValue } = useKBar((state) => ({ queryValue: state.searchQuery }))
diff --git a/packages/web/components/templates/reader/ReaderHeader.tsx b/packages/web/components/templates/reader/ReaderHeader.tsx
index e3345535f..c4884c1d3 100644
--- a/packages/web/components/templates/reader/ReaderHeader.tsx
+++ b/packages/web/components/templates/reader/ReaderHeader.tsx
@@ -35,9 +35,12 @@ export function ReaderHeader(props: ReaderHeaderProps): JSX.Element {
'@xlgDown': {
height: MOBILE_HEADER_HEIGHT,
pt: '0px',
- bg: '$thBackground3',
+ bg: '$readerMargin',
borderBottom: '1px solid $thBorderColor',
},
+ '@mdDown': {
+ bg: '$readerBg',
+ },
}}
>
{
- const { preferencesData } = useGetUserPreferences()
+ applyStoredTheme(false)
+
const [, updateState] = useState({})
const [fontSize, setFontSize] = usePersistedState({
key: 'fontSize',
- initialValue: preferencesData?.fontSize ?? 20,
+ initialValue: 20,
})
const [lineHeight, setLineHeight] = usePersistedState({
key: 'lineHeight',
@@ -76,12 +72,12 @@ export const useReaderSettings = (): ReaderSettings => {
useState(false)
const [showDeleteConfirmation, setShowDeleteConfirmation] = useState(false)
- const updateFontSize = async (newFontSize: number) => {
- setFontSize(newFontSize)
- ;(async () => {
- await userPersonalizationMutation({ fontSize: newFontSize })
- })()
- }
+ const updateFontSize = useCallback(
+ (newFontSize: number) => {
+ setFontSize(newFontSize)
+ },
+ [setFontSize]
+ )
// const [hideMargins, setHideMargins] = usePersistedState({
// key: `--display-hide-margins`,
@@ -207,7 +203,6 @@ export const useReaderSettings = (): ReaderSettings => {
)
return {
- preferencesData,
fontSize,
lineHeight,
marginWidth,
diff --git a/packages/web/lib/networking/mutations/userPersonalizationMutation.ts b/packages/web/lib/networking/mutations/userPersonalizationMutation.ts
deleted file mode 100644
index 5a07ade0b..000000000
--- a/packages/web/lib/networking/mutations/userPersonalizationMutation.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-import { gql } from 'graphql-request'
-import {
- UserPreferences,
- SortOrder,
- updateUserPreferencesCache,
-} from '../queries/useGetUserPreferences'
-import { gqlFetcher } from '../networkHelpers'
-
-type UserPersonalizationInput = {
- theme?: string
- fontSize?: number
- fontFamily?: string
- margin?: number
- libraryLayoutType?: string
- librarySortOrder?: SortOrder
-}
-
-type SetUserPersonalizationResult = {
- setUserPersonalization: InnerSetUserPersonalization
-}
-
-type InnerSetUserPersonalization = {
- updatedUserPersonalization?: UserPreferences
-}
-
-export async function userPersonalizationMutation(
- input: UserPersonalizationInput
-): Promise {
- const mutation = gql`
- mutation SetUserPersonalization($input: SetUserPersonalizationInput!) {
- setUserPersonalization(input: $input) {
- ... on SetUserPersonalizationSuccess {
- updatedUserPersonalization {
- id
- theme
- fontSize
- fontFamily
- margin
- libraryLayoutType
- librarySortOrder
- }
- }
- ... on SetUserPersonalizationError {
- errorCodes
- }
- }
- }
- `
-
- try {
- const data = await gqlFetcher(mutation, { input })
- const result = data as SetUserPersonalizationResult | undefined
- if (result?.setUserPersonalization?.updatedUserPersonalization) {
- updateUserPreferencesCache(result.setUserPersonalization.updatedUserPersonalization)
- return result.setUserPersonalization?.updatedUserPersonalization
- }
- return undefined
- } catch {
- return undefined
- }
-}
diff --git a/packages/web/lib/networking/queries/useGetUserPreferences.tsx b/packages/web/lib/networking/queries/useGetUserPreferences.tsx
deleted file mode 100644
index 9b74a795b..000000000
--- a/packages/web/lib/networking/queries/useGetUserPreferences.tsx
+++ /dev/null
@@ -1,88 +0,0 @@
-import { gql } from 'graphql-request'
-import useSWR, { mutate } from 'swr'
-import { gqlFetcher } from '../networkHelpers'
-import { applyStoredTheme, updateThemeLocally } from '../../themeUpdater'
-import { ThemeId } from '../../../components/tokens/stitches.config'
-
-type UserPreferencesResponse = {
- preferencesData?: UserPreferences
- preferencesDataError?: unknown
- isLoading: boolean
- isValidating: boolean
-}
-
-type QueryResponse = {
- getUserPersonalization: InnerQueryReponse
-}
-
-type InnerQueryReponse = {
- userPersonalization: UserPreferences
-}
-
-export type UserPreferences = {
- id: string
- theme: string
- fontSize: number
- fontFamily: string
- margin: number
- lineHeight?: number
- libraryLayoutType: string
- librarySortOrder?: SortOrder
-}
-
-export type SortOrder = 'ASCENDING' | 'DESCENDING'
-
-const QUERY = gql`
- query GetUserPersonalization {
- getUserPersonalization {
- ... on GetUserPersonalizationSuccess {
- userPersonalization {
- id
- theme
- margin
- fontSize
- fontFamily
- libraryLayoutType
- librarySortOrder
- }
- }
- ... on GetUserPersonalizationError {
- errorCodes
- }
- }
- }
-`
-
-export function updateUserPreferencesCache(
- userPersonalization: UserPreferences
-): void {
- mutate(
- QUERY,
- {
- getUserPersonalization: { userPersonalization },
- },
- false
- )
-}
-
-export function useGetUserPreferences(): UserPreferencesResponse {
- const currentTheme = applyStoredTheme(false)
- const { data, error, isValidating } = useSWR(QUERY, gqlFetcher, {
- dedupingInterval: 200000,
- })
-
- const preferencesData = (data as QueryResponse | undefined)
- ?.getUserPersonalization.userPersonalization
-
- const serverThemeKey = preferencesData?.theme as ThemeId | undefined
- if (!isValidating && serverThemeKey && currentTheme !== serverThemeKey) {
- updateThemeLocally(serverThemeKey)
- }
-
- return {
- preferencesData,
- isValidating,
- preferencesDataError: error, // TODO: figure out error possibilities
- isLoading: !error && !data,
- }
-}
diff --git a/packages/web/lib/themeUpdater.tsx b/packages/web/lib/themeUpdater.tsx
index 24668b03b..1b4694449 100644
--- a/packages/web/lib/themeUpdater.tsx
+++ b/packages/web/lib/themeUpdater.tsx
@@ -1,39 +1,54 @@
import {
ThemeId,
- lighterTheme,
darkTheme,
- darkerTheme,
+ sepiaTheme,
+ apolloTheme,
} from '../components/tokens/stitches.config'
-import { userPersonalizationMutation } from './networking/mutations/userPersonalizationMutation'
const themeKey = 'theme'
+// Map legacy theme names to their new equivelents
+const LEGACY_THEMES: { [string: string]: string } = {
+ White: ThemeId.Light,
+ LightGray: ThemeId.Light,
+ Gray: ThemeId.Dark,
+ Darker: ThemeId.Dark,
+}
+
export function updateTheme(themeId: string): void {
if (typeof window === 'undefined') {
return
}
updateThemeLocally(themeId)
- userPersonalizationMutation({ theme: themeId })
+}
+
+function getTheme(themeId: string) {
+ switch (currentTheme()) {
+ case ThemeId.Dark:
+ return darkTheme
+ case ThemeId.Sepia:
+ return sepiaTheme
+ case ThemeId.Apollo:
+ return apolloTheme
+ }
+ return ThemeId.Light
}
export function updateThemeLocally(themeId: string): void {
if (typeof window !== 'undefined') {
+ console.trace('storing theme: ', themeId)
window.localStorage.setItem(themeKey, themeId)
}
document.body.classList.remove(
- lighterTheme,
+ ...Object.keys(LEGACY_THEMES),
+ sepiaTheme,
darkTheme,
- darkerTheme,
- ThemeId.Light,
- ThemeId.Dark,
- ThemeId.Darker,
- ThemeId.Lighter,
- ThemeId.Sepia,
- ThemeId.Charcoal
+ apolloTheme,
+ ...Object.keys(ThemeId)
)
- document.body.classList.add(themeId)
+ document.body.classList.add(getTheme(themeId))
}
export function currentThemeName(): string {
@@ -42,17 +57,12 @@ export function currentThemeName(): string {
return 'Light'
case ThemeId.Dark:
return 'Dark'
- case ThemeId.Darker:
- return 'Darker'
- case ThemeId.Lighter:
- return 'Lighter'
case ThemeId.Sepia:
return 'Sepia'
- case ThemeId.Charcoal:
- return 'Charcoal'
- default:
- return ''
+ case ThemeId.Apollo:
+ return 'Apollo'
}
+ return 'Light'
}
export function currentTheme(): ThemeId | undefined {
@@ -60,7 +70,16 @@ export function currentTheme(): ThemeId | undefined {
return undefined
}
- return window.localStorage.getItem(themeKey) as ThemeId | undefined
+ const str = window.localStorage.getItem(themeKey)
+ if (str && Object.values(ThemeId).includes(str as ThemeId)) {
+ return str as ThemeId
+ }
+
+ if (str && Object.keys(LEGACY_THEMES).includes(str)) {
+ return LEGACY_THEMES[str] as ThemeId
+ }
+
+ return ThemeId.Light
}
export function applyStoredTheme(syncWithServer = true): ThemeId | undefined {
@@ -72,7 +91,8 @@ export function applyStoredTheme(syncWithServer = true): ThemeId | undefined {
| ThemeId
| undefined
if (theme && Object.values(ThemeId).includes(theme)) {
- syncWithServer ? updateTheme(theme) : updateThemeLocally(theme)
+ console.log('applying stored theme: ', theme)
+ updateThemeLocally(theme)
}
return theme
}
@@ -81,35 +101,3 @@ export function isDarkTheme(): boolean {
const currentTheme = currentThemeName()
return currentTheme === 'Dark' || currentTheme === 'Darker'
}
-
-export function darkenTheme(): void {
- switch (currentTheme()) {
- case ThemeId.Dark:
- updateTheme(ThemeId.Darker)
- break
- case ThemeId.Light:
- updateTheme(ThemeId.Dark)
- break
- case ThemeId.Lighter:
- updateTheme(ThemeId.Light)
- break
- default:
- break
- }
-}
-
-export function lightenTheme(): void {
- switch (currentTheme()) {
- case ThemeId.Dark:
- updateTheme(ThemeId.Light)
- break
- case ThemeId.Darker:
- updateTheme(ThemeId.Dark)
- break
- case ThemeId.Light:
- updateTheme(ThemeId.Lighter)
- break
- default:
- break
- }
-}
diff --git a/packages/web/pages/[username]/[slug]/index.tsx b/packages/web/pages/[username]/[slug]/index.tsx
index af9c9b364..0b61ef31c 100644
--- a/packages/web/pages/[username]/[slug]/index.tsx
+++ b/packages/web/pages/[username]/[slug]/index.tsx
@@ -47,7 +47,6 @@ const PdfArticleContainerNoSSR = dynamic(
export default function Home(): JSX.Element {
const router = useRouter()
const { cache, mutate } = useSWRConfig()
- const scrollRef = useRef(null)
const { slug } = router.query
const [showEditModal, setShowEditModal] = useState(false)
@@ -355,12 +354,12 @@ export default function Home(): JSX.Element {
{article && viewerData?.me ? (
diff --git a/packages/web/pages/_app.tsx b/packages/web/pages/_app.tsx
index ad224caca..ea31fe24a 100644
--- a/packages/web/pages/_app.tsx
+++ b/packages/web/pages/_app.tsx
@@ -24,7 +24,8 @@ import {
KBarResultsComponents,
searchStyle,
} from '../components/elements/KBar'
-import { darkenTheme, lightenTheme } from '../lib/themeUpdater'
+import { updateTheme } from '../lib/themeUpdater'
+import { ThemeId } from '../components/tokens/stitches.config'
TopBarProgress.config({
barColors: {
@@ -52,7 +53,7 @@ const generateActions = (router: NextRouter) => {
shortcut: ['v', 'l'],
keywords: 'light theme',
priority: Priority.LOW,
- perform: () => lightenTheme(),
+ perform: () => updateTheme(ThemeId.Light),
},
{
id: 'darkTheme',
@@ -61,7 +62,7 @@ const generateActions = (router: NextRouter) => {
shortcut: ['v', 'd'],
keywords: 'dark theme',
priority: Priority.LOW,
- perform: () => darkenTheme(),
+ perform: () => updateTheme(ThemeId.Dark),
},
]
diff --git a/packages/web/pages/_document.tsx b/packages/web/pages/_document.tsx
index e5c96fe8b..f63ebc224 100644
--- a/packages/web/pages/_document.tsx
+++ b/packages/web/pages/_document.tsx
@@ -5,40 +5,6 @@ import { getCssText, globalStyles } from '../components/tokens/stitches.config'
export default class Document extends NextDocument {
render() {
- const setUserPreferences = `
- function getCookie(cname) {
- let name = cname + "=";
- let ca = document.cookie.split(';');
- for(let i = 0; i < ca.length; i++) {
- let c = ca[i];
- while (c.charAt(0) == ' ') {
- c = c.substring(1);
- }
- if (c.indexOf(name) == 0) {
- return c.substring(name.length, c.length);
- }
- }
- return "";
- }
-
- function storeCookieInLocalStorage(key) {
- let value = getCookie(key);
- if (value != "") {
- window.localStorage.setItem(key, value)
- }
- }
-
- storeCookieInLocalStorage("authToken")
- storeCookieInLocalStorage("theme")
-
- var themeId = window.localStorage.getItem('theme')
-
- if (themeId) {
- document.body.classList.remove('theme-default', 'White', 'Gray', 'LightGray', 'Dark', 'Sepia', 'Charcoal')
- document.body.classList.add(themeId)
- }
- `
-
globalStyles()
return (
@@ -112,7 +78,6 @@ export default class Document extends NextDocument {
-