-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ga topic status with localstorage #1604
base: main
Are you sure you want to change the base?
Changes from all commits
ced6c85
9dbea5f
cefb159
b684813
8bf750b
c816d9b
76de1cb
b0a2866
2d8a5a0
979b47f
1902036
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
--- | ||
'@commercetools-docs/gatsby-theme-learning': minor | ||
'@commercetools-docs/gatsby-theme-docs': minor | ||
'@commercetools-website/docs-smoke-test': minor | ||
'@commercetools-website/documentation': minor | ||
--- | ||
|
||
Added status indicator for course and course topics |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,9 @@ | ||
import React from 'react'; | ||
import { SWRConfig } from 'swr'; | ||
import PropTypes from 'prop-types'; | ||
import styled from '@emotion/styled'; | ||
import { designSystem } from '@commercetools-docs/ui-kit'; | ||
import useIsClientSide from '../../hooks/use-is-client-side'; | ||
|
||
/* NOTE: `overflow` shorthand is only supported is Chrome and FF */ | ||
const Root = styled.div` | ||
|
@@ -41,18 +43,55 @@ const Container = styled.div` | |
} | ||
`; | ||
|
||
const LayoutApplication = (props) => ( | ||
<> | ||
<Root | ||
role="application" | ||
id="application" | ||
isGlobalNotificationVisible={Boolean(props.globalNotification)} | ||
> | ||
<Container {...props} /> | ||
</Root> | ||
<div id="modal-portal" /> | ||
</> | ||
); | ||
const localStorageProvider = () => { | ||
// When initializing, we restore the data from `localStorage` into a map. | ||
const map = new Map(JSON.parse(localStorage.getItem('app-cache') || '[]')); | ||
|
||
const handleBeforUnload = (event) => { | ||
const appCache = JSON.stringify(Array.from(map.entries())); | ||
localStorage.setItem('app-cache', appCache); | ||
}; | ||
|
||
const handleBeforeAuth0LoginRedirect = (event) => { | ||
// I'm about to redirect to auth0, I want to disable the set cache logic | ||
window.removeEventListener(handleBeforUnload); | ||
// and ensure the cache is clean | ||
localStorage.removeItem('app-cache'); | ||
}; | ||
|
||
// Before unloading the app, we write back all the data into `localStorage`. | ||
window.addEventListener('beforeunload', handleBeforUnload); | ||
|
||
window.addEventListener( | ||
'beforeAuth0LoginRedirect', | ||
handleBeforeAuth0LoginRedirect | ||
); | ||
|
||
// We still use the map for write & read for performance. | ||
return map; | ||
}; | ||
|
||
const LayoutApplication = (props) => { | ||
const { isClientSide } = useIsClientSide(); | ||
return ( | ||
<> | ||
<Root | ||
role="application" | ||
id="application" | ||
isGlobalNotificationVisible={Boolean(props.globalNotification)} | ||
> | ||
{isClientSide ? ( | ||
<SWRConfig value={{ provider: localStorageProvider }}> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. First doubt. If we want to have the course/topic status available in the sidebar and (potentially in the future) in the actual content page, the only place common between these 2 layouts is the application layout. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. #1 I wonder if something like the SWRConfig would not be better placed in gatsby-browser's "wrapXXXElement" hooks. That implicitly makes them client side only and also makes sure they are in all layouts. #2 having one cache provider for any SWR even across microsites felt weird to me too in the beginning but I concluded that it's the whole point of it. The cache keys are the URLs you use to fetch from SWR and the content is the API response. And we want that information to be available at least in stale state for other pages / views / microsites. So it must be one fixed key like "app-cache" and also at top level for the domain. We could use a more specific localstorage key maybe that is more explanatory. |
||
<Container {...props} /> | ||
</SWRConfig> | ||
) : ( | ||
<Container {...props} /> | ||
)} | ||
</Root> | ||
<div id="modal-portal" /> | ||
</> | ||
); | ||
}; | ||
LayoutApplication.propTypes = { | ||
globalNotification: PropTypes.shape({ | ||
notificationType: PropTypes.oneOf(['info', 'warning']).isRequired, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import ConfigContext from './src/components/config-context'; | ||
|
||
export const wrapRootElement = ({ element }, pluginOptions) => { | ||
return ( | ||
<ConfigContext.Provider | ||
value={{ | ||
learnApiBaseUrl: pluginOptions.learnApiBaseUrl, | ||
auth0Domain: pluginOptions.auth0Domain, | ||
features: pluginOptions?.features || [], | ||
}} | ||
> | ||
{element} | ||
</ConfigContext.Provider> | ||
); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This handler is rather blind approach as it will simply dump swr state to the cache each time the page is refreshed. But we refresh the page also each time we login and logout.
This is the reason of the 2 custom events that basically disable writing the cache upon login and logout.