Skip to content

Commit

Permalink
feat: Simplify and speed up Home initialization
Browse files Browse the repository at this point in the history
We get rid of the  complicated state management to determine whether or not the
Home is initialized, to rely on a dedicated hook in charge of fetching all the required
data.
Note the Home is relying on this mechanism to later fetch data directly from the store.
In the future, we might have the same logic, but relying on the dataproxy directly
  • Loading branch information
paultranvan committed Jan 14, 2025
1 parent 7c1b67e commit c9f8817
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 63 deletions.
8 changes: 5 additions & 3 deletions src/components/FooterLogo/FooterLogo.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react'
import { useClient, useQuery } from 'cozy-client'
import { buildContextQuery } from 'queries'
import { makeContextQuery } from 'queries'
import Divider from 'cozy-ui/transpiled/react/Divider'
import { useCozyTheme } from 'cozy-ui/transpiled/react/providers/CozyTheme'

Expand All @@ -9,8 +9,10 @@ export const FooterLogo = () => {
const { type } = useCozyTheme()
const rootURL = client.getStackClient().uri

const contextQuery = buildContextQuery()
const { data } = useQuery(contextQuery.definition, contextQuery.options)
const { data } = useQuery(
makeContextQuery.definition,
makeContextQuery.options
)

const logos = data?.logos?.home?.light || []
const secondaries = logos.filter(logos => logos.type === 'secondary')
Expand Down
71 changes: 22 additions & 49 deletions src/containers/App.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/* global __SIMULATE_FLAGSHIP__ */
import React, { useEffect, useState } from 'react'
import React, { useState } from 'react'
import { Navigate, Route } from 'react-router-dom'

import flag, { enable as enableFlags } from 'cozy-flags'
import flag from 'cozy-flags'
import minilog from 'cozy-minilog'
import { useQuery } from 'cozy-client'
import { useWebviewIntent } from 'cozy-intent'
Expand All @@ -25,12 +25,10 @@ import IntentRedirect from 'components/IntentRedirect'
import MoveModal from 'components/MoveModal'
import StoreRedirection from 'components/StoreRedirection'
import BackupNotification from 'components/BackupNotification/BackupNotification'
import appEntryPoint from 'components/appEntryPoint'
import useBreakpoints from 'cozy-ui/transpiled/react/providers/Breakpoints'
import { BackgroundContainer } from 'components/BackgroundContainer'
import { FLAG_FAB_BUTTON_ENABLED } from 'components/AddButton/helpers'
import { MainView } from 'components/MainView'
import { toFlagNames } from './toFlagNames'
import { Konnector } from 'components/Konnector'
import DefaultRedirectionSnackbar from 'components/DefaultRedirectionSnackbar/DefaultRedirectionSnackbar'
import ReloadFocus from './ReloadFocus'
Expand All @@ -39,27 +37,22 @@ import { formatShortcuts } from 'components/Shortcuts/utils'
import {
mkHomeMagicFolderConn,
mkHomeCustomShorcutsConn,
mkHomeCustomShorcutsDirConn,
contextQuery
mkHomeCustomShorcutsDirConn
} from 'queries'
import { useFetchInitialData } from 'hooks/useFetchInitialData'
import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n'
import SectionDialog from 'components/Sections/SectionDialog'
import { SentryRoutes } from 'lib/sentry'
import '../flags'

window.flag = window.flag || flag
window.minilog = minilog

const App = ({ accounts, konnectors, triggers }) => {
const App = () => {
const { isMobile } = useBreakpoints()
const [contentWrapper, setContentWrapper] = useState(undefined)
const [isFetching, setIsFetching] = useState(
[accounts, konnectors, triggers].some(collection =>
['pending', 'loading'].includes(collection.fetchStatus)
)
)
const [hasError, setHasError] = useState(false)
const [isReady, setIsReady] = useState(false)
const [appsReady, setAppsReady] = useState(false)

const [didInit, setDidInit] = useState(false)
const webviewIntent = useWebviewIntent()
const theme = useCozyTheme()

Expand Down Expand Up @@ -93,48 +86,28 @@ const App = ({ accounts, konnectors, triggers }) => {
const shortcutsDirectories = canHaveShortcuts
? formatShortcuts(folders, customHomeShortcuts)
: null
const context = useQuery(contextQuery.definition, contextQuery.options)

const { isFetching, hasError } = useFetchInitialData()

const showAssistantForMobile = isFlagshipApp()
? flag('cozy.searchbar.enabled-for-flagship')
: flag('cozy.searchbar.enabled') && isMobile

useEffect(() => {
setIsFetching(
[accounts, konnectors, triggers, context].some(collection =>
['pending', 'loading'].includes(collection.fetchStatus)
)
)
setHasError(
[accounts, konnectors, triggers, context].find(
collection => collection.fetchStatus === 'failed'
)
)
}, [accounts, konnectors, triggers, context])

if (context?.attributes?.features) {
const flags = toFlagNames(context.attributes.features)
enableFlags(flags)
}

useEffect(() => {
setIsReady(
appsReady &&
!hasError &&
!isFetching &&
shortcutsDirectories !== undefined
)
}, [appsReady, hasError, isFetching, shortcutsDirectories])

useEffect(() => {
if (isReady && webviewIntent) {
if (
!didInit &&
!hasError &&
!isFetching &&
shortcutsDirectories !== undefined
) {
if (webviewIntent) {
webviewIntent.call('setTheme', theme.variant)
webviewIntent.call('hideSplashScreen')
}
if (isReady && !webviewIntent && __SIMULATE_FLAGSHIP__) {
if (!webviewIntent && __SIMULATE_FLAGSHIP__) {
document.getElementById('splashscreen').style.display = 'none'
}
}, [isReady, theme, webviewIntent])
setDidInit(true)
}

return (
<>
Expand All @@ -145,7 +118,7 @@ const App = ({ accounts, konnectors, triggers }) => {
<Corner />
<div
className="u-flex u-flex-column u-flex-content-start u-flex-content-stretch u-w-100 u-m-auto u-pos-relative"
ref={isReady ? div => setContentWrapper(div) : null}
ref={didInit ? div => setContentWrapper(div) : null}
>
<MoveModal />
<HeroHeader />
Expand Down Expand Up @@ -205,4 +178,4 @@ const App = ({ accounts, konnectors, triggers }) => {
)
}

export default appEntryPoint(App)
export default App
61 changes: 61 additions & 0 deletions src/hooks/useFetchInitialData.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { useEffect, useRef } from 'react'
import { useQuery } from 'cozy-client'
import {
makeAccountsQuery,
makeAppsQuery,
makeKonnectorsQuery,
makeTriggersQuery
} from 'queries'
import log from 'cozy-logger'

export const useFetchInitialData = () => {
const accountsQuery = useQuery(
makeAccountsQuery.definition,
makeAccountsQuery.options
)
const konnectorsQuery = useQuery(
makeKonnectorsQuery.definition,
makeKonnectorsQuery.options
)
const appsQuery = useQuery(makeAppsQuery.definition, makeAppsQuery.options)
const triggersQuery = useQuery(
makeTriggersQuery.definition,
makeTriggersQuery.options
)

// eslint-disable-next-line react-hooks/exhaustive-deps
const allQueries = [accountsQuery, konnectorsQuery, appsQuery, triggersQuery]

const startTime = useRef(null)
const loggedTime = useRef(false)

useEffect(() => {
if (startTime.current === null) {
startTime.current = performance.now()
}

const allFetched = allQueries.every(query => query.fetchStatus === 'loaded')

if (allFetched && !loggedTime.current) {
const endTime = performance.now()
log('info', `Required data fetched in ${endTime - startTime.current} ms`)
loggedTime.current = true
}
}, [allQueries])

const isFetching = allQueries.some(
query => query.fetchStatus === 'loading' || query.fetchStatus === 'pending'
)
const hasError = allQueries.some(query => query.fetchStatus === 'failed')

return {
isFetching,
hasError,
data: {
accounts: accountsQuery.data,
konnectors: konnectorsQuery.data,
apps: appsQuery.data,
triggers: triggersQuery.data
}
}
}
29 changes: 18 additions & 11 deletions src/queries.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,22 @@ export const konnectorsConn = {
fetchPolicy: defaultFetchPolicy
}

export const makeAppsQuery = {
definition: () => Q('io.cozy.apps'),
options: {
as: 'io.cozy.apps',
fetchPolicy: defaultFetchPolicy
}
}

export const makeKonnectorsQuery = {
definition: () => Q('io.cozy.konnectors'),
options: {
as: 'io.cozy.konnectors',
fetchPolicy: defaultFetchPolicy
}
}

export const makeTriggersQuery = {
definition: () => {
return Q('io.cozy.triggers')
Expand Down Expand Up @@ -133,14 +149,14 @@ export const mkHomeCustomShorcutsConn = foldersId => {
}
}

export const buildContextQuery = () => ({
export const makeContextQuery = {
definition: () => Q('io.cozy.settings').getById('io.cozy.settings.context'),
options: {
as: 'io.cozy.settings/io.cozy.settings.context',
fetchPolicy: defaultFetchPolicy,
singleDocData: true
}
})
}

export const buildExistingTimeseriesGeojsonQuery = () => ({
definition: Q('io.cozy.timeseries.geojson')
Expand All @@ -153,12 +169,3 @@ export const buildExistingTimeseriesGeojsonQuery = () => ({
fetchPolicy: CozyClient.fetchPolicies.olderThan(60 * 60 * 24 * 365 * 1000)
}
})

export const contextQuery = {
definition: Q('io.cozy.settings').getById('io.cozy.settings.context'),
options: {
as: 'io.cozy.settings/io.cozy.settings.context',
fetchPolicy: defaultFetchPolicy,
singleDocData: true
}
}

0 comments on commit c9f8817

Please sign in to comment.