Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import Notify from './components/notify/Notify.js'
import Connected from './components/connected/Connected.js'
import TourHelper from './components/tour/TourHelper.js'
import FilesExploreForm from './files/explore-form/files-explore-form.tsx'
import { useTours } from './contexts/tours-context'

export class App extends Component {
static propTypes = {
Expand Down Expand Up @@ -124,20 +125,27 @@ const dropCollect = (connect, monitor) => ({
canDrop: monitor.canDrop()
})

const AppWithTooltip = (props) => {
const { tooltip: showTooltip, disableTooltip } = useTours()
return (
<App {...props} showTooltip={showTooltip}
doDisableTooltip={disableTooltip}
/>
)
}

export const AppWithDropTarget = DropTarget(NativeTypes.FILE, dropTarget, dropCollect)(App)

export default connect(
'selectRoute',
'selectRouteInfo',
'selectIpfsReady',
'selectShowTooltip',
'doFilesNavigateTo',
'doUpdateUrl',
'doUpdateHash',
'doSetupLocalStorage',
'doTryInitIpfs',
'doFilesWrite',
'doDisableTooltip',
'selectFilesPathInfo',
withTranslation('app')(AppWithDropTarget)
withTranslation('app')(DropTarget(NativeTypes.FILE, dropTarget, dropCollect)(AppWithTooltip))
)
2 changes: 0 additions & 2 deletions src/bundles/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import redirectsBundle from './redirects.js'
import filesBundle from './files/index.js'
import configBundle from './config.js'
import configSaveBundle from './config-save.js'
import toursBundle from './tours.js'
import notifyBundle from './notify.js'
import connectedBundle from './connected.js'
import retryInitBundle from './retry-init.js'
Expand All @@ -32,7 +31,6 @@ export default composeBundles(
ipfsProvider,
routesBundle,
redirectsBundle,
toursBundle,
filesBundle(),
configBundle,
configSaveBundle,
Expand Down
49 changes: 0 additions & 49 deletions src/bundles/tours.js

This file was deleted.

12 changes: 5 additions & 7 deletions src/components/tour/TourHelper.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React from 'react'
import { connect } from 'redux-bundler-react'
import { withTranslation } from 'react-i18next'
import { useTours } from '../../contexts/tours-context'

export const TourHelper = ({ doEnableTours, className = '', size = 23, t }) => {
export const TourHelper = ({ className = '', size = 23, t }) => {
const { enableTours } = useTours()
const handleClick = () => {
doEnableTours()
enableTours()
}

return (
Expand All @@ -16,7 +17,4 @@ export const TourHelper = ({ doEnableTours, className = '', size = 23, t }) => {
)
}

export default connect(
'doEnableTours',
withTranslation('app')(TourHelper)
)
export default withTranslation('app')(TourHelper)
37 changes: 20 additions & 17 deletions src/components/tour/withTour.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,34 @@
import React from 'react'
import { connect } from 'redux-bundler-react'
import React, { useCallback } from 'react'
import { STATUS } from 'react-joyride'
import { useTours } from '../../contexts/tours-context'

/**
* @param {React.ComponentType<any>} WrappedComponent
* @returns {React.ComponentType<any>}
*/
const withTour = WrappedComponent => {
class WithTour extends React.Component {
/**
* @param {import('react-joyride').CallBackProps} data
*/
handleJoyrideCallback = (data) => {
const { doDisableTours } = this.props
const { action, status } = data
/**
* @param {Object} props
*/
const WithTour = (props) => {
const { disableTours } = useTours()
const handleJoyrideCallback = useCallback(
/**
* @param {import('react-joyride').CallBackProps} data
*/
(data) => {
const { action, status } = data

if (action === 'close' || status === STATUS.FINISHED) {
doDisableTours()
}
}
if (action === 'close' || status === STATUS.FINISHED) {
disableTours()
}
}, [disableTours]
)

render () {
return <WrappedComponent handleJoyrideCallback={this.handleJoyrideCallback} {...this.props} />
}
return <WrappedComponent handleJoyrideCallback={handleJoyrideCallback} {...props} />
}

return connect('doDisableTours', WithTour)
return WithTour
}

export default withTour
94 changes: 94 additions & 0 deletions src/contexts/tours-context.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import React, { createContext, useContext, useReducer, useCallback, useEffect } from 'react'
import { useBridgeContext } from '../helpers/context-bridge'
// Replace window-or-global with direct window check
const root = typeof window !== 'undefined' ? window : global

interface ToursState {
enabled: boolean
tooltip: boolean
}

interface ToursContextValue {
enabled: boolean
tooltip: boolean
enableTours: () => void
disableTours: () => void
disableTooltip: () => void
}

const ToursContext = createContext<ToursContextValue | undefined>(undefined)

type ToursAction = | { type: 'TOURS_ENABLE' }
| { type: 'TOURS_DISABLE' }
| { type: 'TOURS_TOOLTIP_DISABLE' }

const toursReducer = (state: ToursState, action: ToursAction): ToursState => {
switch (action.type) {
case 'TOURS_ENABLE':
return { ...state, enabled: true }
case 'TOURS_DISABLE':
return { ...state, enabled: false }
case 'TOURS_TOOLTIP_DISABLE':
return { ...state, tooltip: false }
default:
return state
}
}

const initialState: ToursState = { enabled: false, tooltip: true }

export const ToursProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [state, dispatch] = useReducer(toursReducer, initialState)

// Initialize from localStorage (equivalent to bundle's init function)
useEffect(() => {
const tourTooltip = root.localStorage.getItem('tourTooltip')
if (tourTooltip) {
dispatch({ type: 'TOURS_TOOLTIP_DISABLE' })
}
}, [])

const enableTours = useCallback(() => {
dispatch({ type: 'TOURS_ENABLE' })
}, [])

const disableTours = useCallback(() => {
dispatch({ type: 'TOURS_DISABLE' })
}, [])

const disableTooltip = useCallback(() => {
root.localStorage.setItem('tourTooltip', 'false')
dispatch({ type: 'TOURS_TOOLTIP_DISABLE' })
}, [])

const contextValue: ToursContextValue = {
enabled: state.enabled,
tooltip: state.tooltip,
enableTours,
disableTours,
disableTooltip
}

// Bridge to redux bundles that might still need tour state
useBridgeContext('tours', {
enabled: state.enabled,
tooltip: state.tooltip,
doEnableTours: enableTours,
doDisableTours: disableTours,
doDisableTooltip: disableTooltip
})

return (
<ToursContext.Provider value={contextValue}>
{children}
</ToursContext.Provider>
)
}

export const useTours = (): ToursContextValue => {
const context = useContext(ToursContext)
if (!context) {
throw new Error('useTours must be used within ToursProvider')
}
return context
}
16 changes: 6 additions & 10 deletions src/explore/ExploreContainer.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import React from 'react'
import { connect } from 'redux-bundler-react'
import { ExplorePage } from 'ipld-explorer-components/pages'
import withTour from '../components/tour/withTour.js'
import { useTours } from '../contexts/tours-context'

const ExploreContainer = ({ availableGatewayUrl, publicGateway }) => {
const { enabled, handleJoyrideCallback } = useTours()

const ExploreContainer = ({
toursEnabled,
handleJoyrideCallback,
availableGatewayUrl,
publicGateway
}) => {
return (
<div className="e2e-explorePage">
<ExplorePage
runTour={toursEnabled}
runTour={enabled}
joyrideCallback={handleJoyrideCallback}
gatewayUrl={availableGatewayUrl}
publicGateway={publicGateway}
Expand All @@ -22,8 +19,7 @@ const ExploreContainer = ({
}

export default connect(
'selectToursEnabled',
'selectAvailableGatewayUrl',
'selectPublicGateway',
withTour(ExploreContainer)
ExploreContainer
)
24 changes: 10 additions & 14 deletions src/explore/StartExploringContainer.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
import React from 'react'
import { connect } from 'redux-bundler-react'
import { StartExploringPage } from 'ipld-explorer-components/pages'
import withTour from '../components/tour/withTour.js'
import { useTours } from '../contexts/tours-context'

const StartExploringContainer = ({
toursEnabled,
handleJoyrideCallback
}) => (
<StartExploringPage
runTour={toursEnabled}
joyrideCallback={handleJoyrideCallback} />
)
const StartExploringContainer = () => {
const { enabled, handleJoyrideCallback } = useTours()
return (
<StartExploringPage
runTour={enabled}
joyrideCallback={handleJoyrideCallback} />
)
}

export default connect(
'selectToursEnabled',
withTour(StartExploringContainer)
)
export default StartExploringContainer
16 changes: 11 additions & 5 deletions src/files/FilesPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import { findDOMNode } from 'react-dom'
import { Helmet } from 'react-helmet'
import { connect } from 'redux-bundler-react'
import { withTranslation, Trans } from 'react-i18next'
import ReactJoyride from 'react-joyride'
import ReactJoyride, { STATUS } from 'react-joyride'
import { useTours } from '../contexts/tours-context'
// Lib
import { filesTour } from '../lib/tours.js'
// Components
import ContextMenu from './context-menu/ContextMenu.js'
import withTour from '../components/tour/withTour.js'
import InfoBoxes from './info-boxes/InfoBoxes.js'
import FilePreview from './file-preview/FilePreview.js'
import FilesList from './files-list/FilesList.js'
Expand All @@ -30,8 +30,15 @@ const FilesPage = ({
doFetchPinningServices, doFilesFetch, doPinsFetch, doFilesSizeGet, doFilesDownloadLink, doFilesDownloadCarLink, doFilesWrite, doAddCarFile, doFilesBulkCidImport, doFilesAddPath, doUpdateHash,
doFilesUpdateSorting, doFilesNavigateTo, doFilesMove, doSetCliOptions, doFetchRemotePins, remotePins, pendingPins, failedPins,
ipfsProvider, ipfsConnected, doFilesMakeDir, doFilesShareLink, doFilesCopyCidProvide, doFilesDelete, doSetPinning, onRemotePinClick, doPublishIpnsKey,
files, filesPathInfo, pinningServices, toursEnabled, handleJoyrideCallback, isCliTutorModeEnabled, cliOptions, t
files, filesPathInfo, pinningServices, isCliTutorModeEnabled, cliOptions, t
}) => {
const { enabled: toursEnabled, disableTours } = useTours()
const handleJoyrideCallback = useCallback((data) => {
const { action, status } = data
if (action === 'close' || status === STATUS.FINISHED) {
disableTours()
}
}, [disableTours])
const { doExploreUserProvidedPath } = useExplore()
const contextMenuRef = useRef()
const [modals, setModals] = useState({ show: null, files: null })
Expand Down Expand Up @@ -435,7 +442,6 @@ export default connect(
'doFilesNavigateTo',
'doFilesUpdateSorting',
'selectFilesSorting',
'selectToursEnabled',
'doFilesWrite',
'doFilesBulkCidImport',
'doFilesDownloadLink',
Expand All @@ -448,5 +454,5 @@ export default connect(
'selectCliOptions',
'doSetPinning',
'doPublishIpnsKey',
withTour(withTranslation('files')(FilesPage))
withTranslation('files')(FilesPage)
)
Loading