From cafd3473bce4a5f85ae0297fb4e6a6b8f3c6e85c Mon Sep 17 00:00:00 2001 From: Ldoppea Date: Thu, 18 Apr 2024 18:30:07 +0200 Subject: [PATCH 01/10] refactor: Use `useSettings` hook in DefaultRedirectionSnackbar In cozy/cozy-client#1460 we implemented a new `useSettings` hook This hook can be used in `DefaultRedirectionSnackbar` in order to simplify code and homogenize the way we access cozy-apps settings --- .../DefaultRedirectionSnackbar.jsx | 45 ++- .../DefaultRedirectionSnackbar.spec.jsx | 90 ++++- .../DefaultRedirectionSnackbar/helpers.js | 104 +----- .../helpers.spec.js | 333 ++++++------------ ...useIncrementDefaultRedirectionViewCount.js | 62 ++-- ...crementDefaultRedirectionViewCount.spec.js | 271 ++++++++------ 6 files changed, 427 insertions(+), 478 deletions(-) diff --git a/src/components/DefaultRedirectionSnackbar/DefaultRedirectionSnackbar.jsx b/src/components/DefaultRedirectionSnackbar/DefaultRedirectionSnackbar.jsx index 721ca0e56d..245ed38ddb 100644 --- a/src/components/DefaultRedirectionSnackbar/DefaultRedirectionSnackbar.jsx +++ b/src/components/DefaultRedirectionSnackbar/DefaultRedirectionSnackbar.jsx @@ -1,6 +1,6 @@ import React, { useState } from 'react' -import { useClient, useQuery } from 'cozy-client' +import { useSettings } from 'cozy-client' import { useWebviewIntent } from 'cozy-intent' import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n' import { makeStyles } from 'cozy-ui/transpiled/react/styles' @@ -10,13 +10,12 @@ import Button from 'cozy-ui/transpiled/react/Buttons' import Icon from 'cozy-ui/transpiled/react/Icon' import LightbulbIcon from 'cozy-ui/transpiled/react/Icons/Lightbulb' -import { instanceSettingsConn, homeSettingsConn } from 'queries' import { - shouldShowDefaultRedirectionSnackbar, - disableDefaultRedirectionSnackbar, - setDefaultRedirectionToHome + HOME_DEFAULT_REDIRECTION, + useShouldShowDefaultRedirectionSnackbar } from './helpers' import useIncrementDefaultRedirectionViewCount from './useIncrementDefaultRedirectionViewCount' +import { isFlagshipApp } from 'cozy-device-helper' const useStyles = makeStyles(theme => ({ snackbar: { @@ -29,39 +28,39 @@ const useStyles = makeStyles(theme => ({ const DefaultAppSnackbar = () => { const { t } = useI18n() - const client = useClient() const classes = useStyles() const [isOpen, setIsOpen] = useState(true) const webviewIntent = useWebviewIntent() - const instanceSettingsResult = useQuery( - instanceSettingsConn.query, - instanceSettingsConn - ) + const { save: saveHome } = useSettings('home', [ + 'default_redirection_snackbar_disabled' + ]) - const homeSettingsResult = useQuery(homeSettingsConn.query, homeSettingsConn) + const { save: saveGlobal } = useSettings('instance', ['default_redirection']) - useIncrementDefaultRedirectionViewCount( - instanceSettingsResult, - homeSettingsResult - ) + useIncrementDefaultRedirectionViewCount() - const showDefaultAppSnackbar = shouldShowDefaultRedirectionSnackbar( - instanceSettingsResult, - homeSettingsResult, - isOpen - ) + const showDefaultAppSnackbar = useShouldShowDefaultRedirectionSnackbar(isOpen) const onRefuse = () => { setIsOpen(false) - disableDefaultRedirectionSnackbar(client, homeSettingsResult) + saveHome({ + default_redirection_snackbar_disabled: true + }) } const onAccept = () => { setIsOpen(false) - disableDefaultRedirectionSnackbar(client, homeSettingsResult) - setDefaultRedirectionToHome(client, instanceSettingsResult, webviewIntent) + saveHome({ + default_redirection_snackbar_disabled: true + }) + saveGlobal({ + default_redirection: HOME_DEFAULT_REDIRECTION + }) + if (isFlagshipApp()) { + webviewIntent.call('setDefaultRedirection', HOME_DEFAULT_REDIRECTION) + } } return ( diff --git a/src/components/DefaultRedirectionSnackbar/DefaultRedirectionSnackbar.spec.jsx b/src/components/DefaultRedirectionSnackbar/DefaultRedirectionSnackbar.spec.jsx index 614eccbf6f..71efbcc055 100644 --- a/src/components/DefaultRedirectionSnackbar/DefaultRedirectionSnackbar.spec.jsx +++ b/src/components/DefaultRedirectionSnackbar/DefaultRedirectionSnackbar.spec.jsx @@ -1,20 +1,19 @@ import React from 'react' import { render, fireEvent } from '@testing-library/react' +import { useSettings } from 'cozy-client' + import CozyTheme from 'cozy-ui/transpiled/react/providers/CozyTheme' import AppLike from 'test/AppLike' import DefaultRedirectionSnackbar from './DefaultRedirectionSnackbar' -import { - shouldShowDefaultRedirectionSnackbar, - disableDefaultRedirectionSnackbar, - setDefaultRedirectionToHome -} from './helpers' +import { useShouldShowDefaultRedirectionSnackbar } from './helpers' jest.mock('cozy-client', () => ({ ...jest.requireActual('cozy-client'), useQuery: jest.fn(), - useClient: jest.fn() + useClient: jest.fn(), + useSettings: jest.fn() })) jest.mock('./helpers') jest.mock('./useIncrementDefaultRedirectionViewCount') @@ -36,7 +35,26 @@ describe('DefaultRedirectionSnackbar', () => { }) it('should display default redirection snackbar', () => { - shouldShowDefaultRedirectionSnackbar.mockReturnValue(true) + useShouldShowDefaultRedirectionSnackbar.mockReturnValue(true) + const mockSaveInstance = jest.fn() + const mockSaveHome = jest.fn() + useSettings.mockImplementation((...args) => { + if (args[0] === 'instance') { + return { + values: { + default_redirection: 'drive/#/folder' + }, + save: mockSaveInstance + } + } else if (args[0] === 'home') { + return { + values: { + default_redirection_view_count: 4 + }, + save: mockSaveHome + } + } + }) const { root } = setup() @@ -45,24 +63,70 @@ describe('DefaultRedirectionSnackbar', () => { }) it('should disable default redirection snackbar and set default redirection to home when accepting', () => { - shouldShowDefaultRedirectionSnackbar.mockReturnValue(true) + useShouldShowDefaultRedirectionSnackbar.mockReturnValue(true) + + const mockSaveInstance = jest.fn() + const mockSaveHome = jest.fn() + useSettings.mockImplementation((...args) => { + if (args[0] === 'instance') { + return { + values: { + default_redirection: 'drive/#/folder' + }, + save: mockSaveInstance + } + } else if (args[0] === 'home') { + return { + values: { + default_redirection_view_count: 4 + }, + save: mockSaveHome + } + } + }) const { root } = setup() fireEvent.click(root.queryByText('OK')) - expect(disableDefaultRedirectionSnackbar).toHaveBeenCalled() - expect(setDefaultRedirectionToHome).toHaveBeenCalled() + expect(mockSaveInstance).toHaveBeenCalledWith({ + default_redirection: 'home/' + }) + expect(mockSaveHome).toHaveBeenCalledWith({ + default_redirection_snackbar_disabled: true + }) }) it('should disable default redirection snackbar when refusing', () => { - shouldShowDefaultRedirectionSnackbar.mockReturnValue(true) + useShouldShowDefaultRedirectionSnackbar.mockReturnValue(true) + + const mockSaveInstance = jest.fn() + const mockSaveHome = jest.fn() + useSettings.mockImplementation((...args) => { + if (args[0] === 'instance') { + return { + values: { + default_redirection: 'drive/#/folder' + }, + save: mockSaveInstance + } + } else if (args[0] === 'home') { + return { + values: { + default_redirection_view_count: 4 + }, + save: mockSaveHome + } + } + }) const { root } = setup() fireEvent.click(root.queryByText('No, thank you')) - expect(disableDefaultRedirectionSnackbar).toHaveBeenCalled() - expect(setDefaultRedirectionToHome).not.toHaveBeenCalled() + expect(mockSaveHome).toHaveBeenCalledWith({ + default_redirection_snackbar_disabled: true + }) + expect(mockSaveInstance).not.toHaveBeenCalled() }) }) diff --git a/src/components/DefaultRedirectionSnackbar/helpers.js b/src/components/DefaultRedirectionSnackbar/helpers.js index 561bb6e355..6d2fd86e9b 100644 --- a/src/components/DefaultRedirectionSnackbar/helpers.js +++ b/src/components/DefaultRedirectionSnackbar/helpers.js @@ -1,102 +1,36 @@ -import { deconstructRedirectLink, hasQueryBeenLoaded } from 'cozy-client' -import { isFlagshipApp } from 'cozy-device-helper' +import { + deconstructRedirectLink, + hasQueryBeenLoaded, + useSettings +} from 'cozy-client' export const VIEW_COUNT_THRESHOLD = 3 export const HOME_DEFAULT_REDIRECTION = 'home/' -export const incrementDefaultRedirectionViewCount = async ( - client, - homeSettings -) => { - const { default_redirection_view_count } = homeSettings - const newHomeSettings = { - _type: 'io.cozy.home.settings', - ...homeSettings, - default_redirection_view_count: default_redirection_view_count - ? default_redirection_view_count + 1 - : 1 - } - - return await client.save(newHomeSettings) -} - -export const disableDefaultRedirectionSnackbar = async ( - client, - homeSettingsResult -) => { - const homeSettings = - (homeSettingsResult.data && homeSettingsResult.data[0]) || {} - - const newHomeSettings = { - _type: 'io.cozy.home.settings', - ...homeSettings, - default_redirection_snackbar_disabled: true - } - - return await client.save(newHomeSettings) -} - -export const setDefaultRedirectionToHome = async ( - client, - instanceSettingsResult, - webviewIntent -) => { - const instanceSettings = { - _id: instanceSettingsResult.data._id, - _type: instanceSettingsResult.data._type, - _rev: instanceSettingsResult.data.meta.rev, - data: { - ...instanceSettingsResult.data, - attributes: { - ...instanceSettingsResult.data.attributes, - default_redirection: HOME_DEFAULT_REDIRECTION - } - } - } +export const useShouldShowDefaultRedirectionSnackbar = isOpen => { + const { values: valueHome, query: queryHome } = useSettings('home', [ + 'default_redirection_view_count', + 'default_redirection_snackbar_disabled' + ]) - const res = await client.save(instanceSettings) - - if (isFlagshipApp()) { - webviewIntent.call('setDefaultRedirection', HOME_DEFAULT_REDIRECTION) - } - - return res -} - -export const shouldShowDefaultRedirectionSnackbar = ( - instanceSettingsResult, - homeSettingsResult, - isOpen -) => { - if ( - !hasQueryBeenLoaded(instanceSettingsResult) || - !hasQueryBeenLoaded(homeSettingsResult) + const { values: valueInstance, query: queryInstance } = useSettings( + 'instance', + ['default_redirection'] ) - return false - - const { - data: { - attributes: { default_redirection } - } - } = instanceSettingsResult - - const homeSettings = - (homeSettingsResult.data && homeSettingsResult.data[0]) || {} - const { - default_redirection_snackbar_disabled, - default_redirection_view_count - } = homeSettings + if (!hasQueryBeenLoaded(queryHome) || !hasQueryBeenLoaded(queryInstance)) { + return false + } - const { slug } = deconstructRedirectLink(default_redirection) + const { slug } = deconstructRedirectLink(valueInstance.default_redirection) const isDefaultRedirectionAppHomeApp = slug === 'home' const isShowThresholdReached = - default_redirection_view_count >= VIEW_COUNT_THRESHOLD + valueHome.default_redirection_view_count >= VIEW_COUNT_THRESHOLD - const isDisabled = default_redirection_snackbar_disabled + const isDisabled = valueHome.default_redirection_snackbar_disabled return ( !isDefaultRedirectionAppHomeApp && diff --git a/src/components/DefaultRedirectionSnackbar/helpers.spec.js b/src/components/DefaultRedirectionSnackbar/helpers.spec.js index f320bf3d04..169b90e59e 100644 --- a/src/components/DefaultRedirectionSnackbar/helpers.spec.js +++ b/src/components/DefaultRedirectionSnackbar/helpers.spec.js @@ -1,292 +1,173 @@ -import { deconstructRedirectLink, hasQueryBeenLoaded } from 'cozy-client' +import { renderHook } from '@testing-library/react-hooks' import { - HOME_DEFAULT_REDIRECTION, - incrementDefaultRedirectionViewCount, - disableDefaultRedirectionSnackbar, - setDefaultRedirectionToHome, - shouldShowDefaultRedirectionSnackbar -} from './helpers' + deconstructRedirectLink, + hasQueryBeenLoaded, + useSettings +} from 'cozy-client' -jest.mock('cozy-client') - -const client = { - save: v => v -} - -const FOO_INSTANCE = { - foo: 'foo' -} - -const FOO_BAR_INSTANCE = { - data: { - foo: 'foo', - attributes: { - bar: 'bar' - } - } -} - -describe('incrementDefaultRedirectionViewCount', () => { - it('should set default_redirection_view_count to 1 if previously undefined', async () => { - const homeSettings = {} - - const { default_redirection_view_count } = - await incrementDefaultRedirectionViewCount(client, homeSettings) - - expect(default_redirection_view_count).toBe(1) - }) - - it('should set default_redirection_view_count to 2 if previously 1', async () => { - const homeSettings = { - default_redirection_view_count: 1 - } - - const { default_redirection_view_count } = - await incrementDefaultRedirectionViewCount(client, homeSettings) - - expect(default_redirection_view_count).toBe(2) - }) - - it('should not erase previous data', async () => { - const { foo } = await incrementDefaultRedirectionViewCount( - client, - FOO_INSTANCE - ) - - expect(foo).toBe(FOO_INSTANCE.foo) - }) -}) - -describe('disableDefaultRedirectionSnackbar', () => { - it('should set default_redirection_snackbar_disabled to true', async () => { - const homeSettingsResult = { - data: [{}] - } - - const { default_redirection_snackbar_disabled } = - await disableDefaultRedirectionSnackbar(client, homeSettingsResult) - - expect(default_redirection_snackbar_disabled).toBe(true) - }) - - it('should not erase previous data', async () => { - const { foo } = await incrementDefaultRedirectionViewCount( - client, - FOO_INSTANCE - ) - - expect(foo).toBe(FOO_INSTANCE.foo) - }) -}) - -describe('setDefaultRedirectionToHome', () => { - it('should set default_redirection to home', async () => { - const instance = { - data: { - _id: '_id', - _type: '_type', - meta: { rev: 'rev' }, - attributes: {} - } - } - - const { data } = await setDefaultRedirectionToHome(client, instance) +import { useShouldShowDefaultRedirectionSnackbar } from './helpers' - expect(data.attributes.default_redirection).toBe(HOME_DEFAULT_REDIRECTION) - }) - - it('should not erase previous data', async () => { - const { data } = await incrementDefaultRedirectionViewCount( - client, - FOO_BAR_INSTANCE - ) - - expect(data.foo).toBe(FOO_BAR_INSTANCE.data.foo) - expect(data.attributes.bar).toBe(FOO_BAR_INSTANCE.data.attributes.bar) - }) -}) +jest.mock('cozy-client') describe('shouldShowDefaultRedirectionSnackbar', () => { it('should return true when everything is good', () => { - const instance = { - data: { - _id: '_id', - _type: '_type', - meta: { rev: 'rev' }, - attributes: { - default_redirection: 'drive/#/folder' + useSettings.mockImplementation((...args) => { + if (args[0] === 'instance') { + return { + values: { + default_redirection: 'drive/#/folder' + } } - } - } - const homeSettings = { - data: [ - { - default_redirection_view_count: 4 + } else if (args[0] === 'home') { + return { + values: { + default_redirection_view_count: 4 + } } - ] - } + } + }) + hasQueryBeenLoaded.mockReturnValue(true) deconstructRedirectLink.mockReturnValue({ slug: 'drive' }) - const showDefaultRedirectionSnackbar = shouldShowDefaultRedirectionSnackbar( - instance, - homeSettings, - true + const { result } = renderHook(() => + useShouldShowDefaultRedirectionSnackbar(true) ) - expect(showDefaultRedirectionSnackbar).toBe(true) + expect(result.current).toBe(true) }) it('should return false when query has not been loaded', () => { - const instance = { - data: { - _id: '_id', - _type: '_type', - meta: { rev: 'rev' }, - attributes: { - default_redirection: 'drive/#/folder' + useSettings.mockImplementation((...args) => { + if (args[0] === 'instance') { + return { + values: { + default_redirection: 'drive/#/folder' + } } - } - } - const homeSettings = { - data: [ - { - default_redirection_view_count: 4 + } else if (args[0] === 'home') { + return { + values: { + default_redirection_view_count: 4 + } } - ] - } + } + }) + hasQueryBeenLoaded.mockReturnValue(false) deconstructRedirectLink.mockReturnValue({ slug: 'drive' }) - const showDefaultRedirectionSnackbar = shouldShowDefaultRedirectionSnackbar( - instance, - homeSettings, - true + const { result } = renderHook(() => + useShouldShowDefaultRedirectionSnackbar(true) ) - expect(showDefaultRedirectionSnackbar).toBe(false) + expect(result.current).toBe(false) }) it('should return false when default redirection app is home app', () => { - const instance = { - data: { - _id: '_id', - _type: '_type', - meta: { rev: 'rev' }, - attributes: { - default_redirection: 'home/' + useSettings.mockImplementation((...args) => { + if (args[0] === 'instance') { + return { + values: { + default_redirection: 'home/' + } } - } - } - const homeSettings = { - data: [ - { - default_redirection_view_count: 4 + } else if (args[0] === 'home') { + return { + values: { + default_redirection_view_count: 4 + } } - ] - } + } + }) hasQueryBeenLoaded.mockReturnValue(true) deconstructRedirectLink.mockReturnValue({ slug: 'home' }) - const showDefaultRedirectionSnackbar = shouldShowDefaultRedirectionSnackbar( - instance, - homeSettings, - true + const { result } = renderHook(() => + useShouldShowDefaultRedirectionSnackbar(true) ) - expect(showDefaultRedirectionSnackbar).toBe(false) + expect(result.current).toBe(false) }) it('should return false when show threshold is not reached', () => { - const instance = { - data: { - _id: '_id', - _type: '_type', - meta: { rev: 'rev' }, - attributes: { - default_redirection: 'drive/#/folder' + useSettings.mockImplementation((...args) => { + if (args[0] === 'instance') { + return { + values: { + default_redirection: 'drive/#/folder' + } } - } - } - const homeSettings = { - data: [ - { - default_redirection_view_count: 2 + } else if (args[0] === 'home') { + return { + values: { + default_redirection_view_count: 2 + } } - ] - } + } + }) hasQueryBeenLoaded.mockReturnValue(true) deconstructRedirectLink.mockReturnValue({ slug: 'drive' }) - const showDefaultRedirectionSnackbar = shouldShowDefaultRedirectionSnackbar( - instance, - homeSettings, - true + const { result } = renderHook(() => + useShouldShowDefaultRedirectionSnackbar(true) ) - expect(showDefaultRedirectionSnackbar).toBe(false) + expect(result.current).toBe(false) }) it('should return false when default redirection snackbar is disabled', () => { - const instance = { - data: { - _id: '_id', - _type: '_type', - meta: { rev: 'rev' }, - attributes: { - default_redirection: 'drive/#/folder' + useSettings.mockImplementation((...args) => { + if (args[0] === 'instance') { + return { + values: { + default_redirection: 'drive/#/folder' + } } - } - } - const homeSettings = { - data: [ - { - default_redirection_snackbar_disabled: true, - default_redirection_view_count: 4 + } else if (args[0] === 'home') { + return { + values: { + default_redirection_snackbar_disabled: true, + default_redirection_view_count: 4 + } } - ] - } + } + }) hasQueryBeenLoaded.mockReturnValue(true) deconstructRedirectLink.mockReturnValue({ slug: 'drive' }) - const showDefaultRedirectionSnackbar = shouldShowDefaultRedirectionSnackbar( - instance, - homeSettings, - true + const { result } = renderHook(() => + useShouldShowDefaultRedirectionSnackbar(true) ) - expect(showDefaultRedirectionSnackbar).toBe(false) + expect(result.current).toBe(false) }) it('should return false when open is false', () => { - const instance = { - data: { - _id: '_id', - _type: '_type', - meta: { rev: 'rev' }, - attributes: { - default_redirection: 'drive/#/folder', - default_redirection_view_count: 4 + useSettings.mockImplementation((...args) => { + if (args[0] === 'instance') { + return { + values: { + default_redirection: 'drive/#/folder' + } } - } - } - const homeSettings = { - data: [ - { - default_redirection_view_count: 4 + } else if (args[0] === 'home') { + return { + values: { + default_redirection_snackbar_disabled: true, + default_redirection_view_count: 4 + } } - ] - } + } + }) hasQueryBeenLoaded.mockReturnValue(true) deconstructRedirectLink.mockReturnValue({ slug: 'drive' }) - const showDefaultRedirectionSnackbar = shouldShowDefaultRedirectionSnackbar( - instance, - homeSettings, - false + const { result } = renderHook(() => + useShouldShowDefaultRedirectionSnackbar(false) ) - expect(showDefaultRedirectionSnackbar).toBe(false) + expect(result.current).toBe(false) }) }) diff --git a/src/components/DefaultRedirectionSnackbar/useIncrementDefaultRedirectionViewCount.js b/src/components/DefaultRedirectionSnackbar/useIncrementDefaultRedirectionViewCount.js index 343c17a509..7868e18219 100644 --- a/src/components/DefaultRedirectionSnackbar/useIncrementDefaultRedirectionViewCount.js +++ b/src/components/DefaultRedirectionSnackbar/useIncrementDefaultRedirectionViewCount.js @@ -2,25 +2,34 @@ import { useState, useEffect } from 'react' import { useClient, + useSettings, deconstructRedirectLink, hasQueryBeenLoaded } from 'cozy-client' -import { - VIEW_COUNT_THRESHOLD, - incrementDefaultRedirectionViewCount -} from './helpers' +import { VIEW_COUNT_THRESHOLD } from './helpers' import useHomeAppOpened from './useHomeAppOpened' -const useIncrementDefaultRedirectionViewCount = ( - instanceSettingsResult, - homeSettingsResult -) => { +const useIncrementDefaultRedirectionViewCount = () => { const client = useClient() const [hasIncremented, setHasIncremented] = useState(false) const { homeJustOpenedOnFlagshipApp, homeJustQuitOnFlagshipApp } = useHomeAppOpened() + const { + values: valueHome, + save: saveHome, + query: queryHome + } = useSettings('home', [ + 'default_redirection_view_count', + 'default_redirection_snackbar_disabled' + ]) + + const { values: valueInstance, query: queryInstance } = useSettings( + 'instance', + ['default_redirection'] + ) + useEffect(() => { if (hasIncremented && homeJustQuitOnFlagshipApp) { setHasIncremented(false) @@ -28,35 +37,18 @@ const useIncrementDefaultRedirectionViewCount = ( }, [hasIncremented, homeJustQuitOnFlagshipApp]) useEffect(() => { - if ( - !hasQueryBeenLoaded(instanceSettingsResult) || - !hasQueryBeenLoaded(homeSettingsResult) - ) { + if (!hasQueryBeenLoaded(queryHome) || !hasQueryBeenLoaded(queryInstance)) { return } - const { - data: { - attributes: { default_redirection } - } - } = instanceSettingsResult - - const homeSettings = - (homeSettingsResult.data && homeSettingsResult.data[0]) || {} - - const { - default_redirection_snackbar_disabled, - default_redirection_view_count - } = homeSettings - - const { slug } = deconstructRedirectLink(default_redirection) + const { slug } = deconstructRedirectLink(valueInstance.default_redirection) const isDefaultRedirectionAppHomeApp = slug === 'home' const isShowThresholdReached = - default_redirection_view_count >= VIEW_COUNT_THRESHOLD + valueHome.default_redirection_view_count >= VIEW_COUNT_THRESHOLD - const isDisabled = default_redirection_snackbar_disabled + const isDisabled = valueHome.default_redirection_snackbar_disabled if ( !hasIncremented && @@ -65,15 +57,21 @@ const useIncrementDefaultRedirectionViewCount = ( !isShowThresholdReached && !isDisabled ) { - incrementDefaultRedirectionViewCount(client, homeSettings) + saveHome({ + default_redirection_view_count: + (valueHome.default_redirection_view_count ?? 0) + 1 + }) setHasIncremented(true) } }, [ client, hasIncremented, homeJustOpenedOnFlagshipApp, - instanceSettingsResult, - homeSettingsResult + valueInstance, + valueHome, + queryHome, + queryInstance, + saveHome ]) } diff --git a/src/components/DefaultRedirectionSnackbar/useIncrementDefaultRedirectionViewCount.spec.js b/src/components/DefaultRedirectionSnackbar/useIncrementDefaultRedirectionViewCount.spec.js index 9de5000a9c..758e91aa45 100644 --- a/src/components/DefaultRedirectionSnackbar/useIncrementDefaultRedirectionViewCount.spec.js +++ b/src/components/DefaultRedirectionSnackbar/useIncrementDefaultRedirectionViewCount.spec.js @@ -1,8 +1,11 @@ import { renderHook } from '@testing-library/react-hooks' -import { deconstructRedirectLink, hasQueryBeenLoaded } from 'cozy-client' +import { + deconstructRedirectLink, + hasQueryBeenLoaded, + useSettings +} from 'cozy-client' -import { incrementDefaultRedirectionViewCount } from './helpers' import useIncrementDefaultRedirectionViewCount from './useIncrementDefaultRedirectionViewCount' import useHomeAppOpened from './useHomeAppOpened' @@ -15,21 +18,86 @@ describe('useIncrementDefaultRedirectionViewCount', () => { jest.resetAllMocks() }) + it('should increment by 1', () => { + const mockSaveHome = jest.fn() + useSettings.mockImplementation((...args) => { + if (args[0] === 'instance') { + return { + values: { + default_redirection: 'drive/#/folder' + } + } + } else if (args[0] === 'home') { + return { + values: { + default_redirection_view_count: 1 + }, + save: mockSaveHome + } + } + }) + hasQueryBeenLoaded.mockReturnValue(true) + deconstructRedirectLink.mockReturnValue({ slug: 'drive' }) + useHomeAppOpened.mockReturnValue({ + homeJustOpenedOnFlagshipApp: true, + homeJustQuitOnFlagshipApp: false + }) + + renderHook(() => useIncrementDefaultRedirectionViewCount()) + + expect(mockSaveHome).toHaveBeenNthCalledWith(1, { + default_redirection_view_count: 2 + }) + }) + + it('should set view_count to 1 when incrementing if initial value is undefined', () => { + const mockSaveHome = jest.fn() + useSettings.mockImplementation((...args) => { + if (args[0] === 'instance') { + return { + values: { + default_redirection: 'drive/#/folder' + } + } + } else if (args[0] === 'home') { + return { + values: {}, + save: mockSaveHome + } + } + }) + hasQueryBeenLoaded.mockReturnValue(true) + deconstructRedirectLink.mockReturnValue({ slug: 'drive' }) + useHomeAppOpened.mockReturnValue({ + homeJustOpenedOnFlagshipApp: true, + homeJustQuitOnFlagshipApp: false + }) + + renderHook(() => useIncrementDefaultRedirectionViewCount()) + + expect(mockSaveHome).toHaveBeenNthCalledWith(1, { + default_redirection_view_count: 1 + }) + }) + it('should increment only 1 time when everything is good', () => { - const instance = { - data: { - attributes: { - default_redirection: 'drive/#/folder' + const mockSaveHome = jest.fn() + useSettings.mockImplementation((...args) => { + if (args[0] === 'instance') { + return { + values: { + default_redirection: 'drive/#/folder' + } + } + } else if (args[0] === 'home') { + return { + values: { + default_redirection_view_count: 2 + }, + save: mockSaveHome } } - } - const homeSettings = { - data: [ - { - default_redirection_view_count: 2 - } - ] - } + }) hasQueryBeenLoaded.mockReturnValue(true) deconstructRedirectLink.mockReturnValue({ slug: 'drive' }) useHomeAppOpened.mockReturnValue({ @@ -38,32 +106,34 @@ describe('useIncrementDefaultRedirectionViewCount', () => { }) const { rerender } = renderHook(() => - useIncrementDefaultRedirectionViewCount(instance, homeSettings) + useIncrementDefaultRedirectionViewCount() ) - expect(incrementDefaultRedirectionViewCount).toHaveBeenCalledTimes(1) + expect(mockSaveHome).toHaveBeenCalledTimes(1) rerender() - expect(incrementDefaultRedirectionViewCount).toHaveBeenCalledTimes(1) + expect(mockSaveHome).toHaveBeenCalledTimes(1) }) it('should not increment when query has not been loaded', () => { - const instance = { - data: { - attributes: { - default_redirection: 'drive/#/folder', - default_redirection_view_count: 2 + const mockSaveHome = jest.fn() + useSettings.mockImplementation((...args) => { + if (args[0] === 'instance') { + return { + values: { + default_redirection: 'drive/#/folder' + } + } + } else if (args[0] === 'home') { + return { + values: { + default_redirection_view_count: 2 + }, + save: mockSaveHome } } - } - const homeSettings = { - data: [ - { - default_redirection_view_count: 2 - } - ] - } + }) hasQueryBeenLoaded.mockReturnValue(false) deconstructRedirectLink.mockReturnValue({ slug: 'drive' }) useHomeAppOpened.mockReturnValue({ @@ -71,28 +141,29 @@ describe('useIncrementDefaultRedirectionViewCount', () => { homeJustQuitOnFlagshipApp: false }) - renderHook(() => - useIncrementDefaultRedirectionViewCount(instance, homeSettings) - ) + renderHook(() => useIncrementDefaultRedirectionViewCount()) - expect(incrementDefaultRedirectionViewCount).not.toHaveBeenCalled() + expect(mockSaveHome).not.toHaveBeenCalled() }) it('should not increment when default redirection app is home app', () => { - const instance = { - data: { - attributes: { - default_redirection: 'home/' + const mockSaveHome = jest.fn() + useSettings.mockImplementation((...args) => { + if (args[0] === 'instance') { + return { + values: { + default_redirection: 'home/' + } + } + } else if (args[0] === 'home') { + return { + values: { + default_redirection_view_count: 2 + }, + save: mockSaveHome } } - } - const homeSettings = { - data: [ - { - default_redirection_view_count: 2 - } - ] - } + }) hasQueryBeenLoaded.mockReturnValue(true) deconstructRedirectLink.mockReturnValue({ slug: 'home' }) useHomeAppOpened.mockReturnValue({ @@ -100,28 +171,29 @@ describe('useIncrementDefaultRedirectionViewCount', () => { homeJustQuitOnFlagshipApp: false }) - renderHook(() => - useIncrementDefaultRedirectionViewCount(instance, homeSettings) - ) + renderHook(() => useIncrementDefaultRedirectionViewCount()) - expect(incrementDefaultRedirectionViewCount).not.toHaveBeenCalled() + expect(mockSaveHome).not.toHaveBeenCalled() }) it('should not increment when show threshold is reached', () => { - const instance = { - data: { - attributes: { - default_redirection: 'drive/#/folder' + const mockSaveHome = jest.fn() + useSettings.mockImplementation((...args) => { + if (args[0] === 'instance') { + return { + values: { + default_redirection: 'drive/#/folder' + } + } + } else if (args[0] === 'home') { + return { + values: { + default_redirection_view_count: 4 + }, + save: mockSaveHome } } - } - const homeSettings = { - data: [ - { - default_redirection_view_count: 4 - } - ] - } + }) hasQueryBeenLoaded.mockReturnValue(true) deconstructRedirectLink.mockReturnValue({ slug: 'drive' }) useHomeAppOpened.mockReturnValue({ @@ -129,29 +201,30 @@ describe('useIncrementDefaultRedirectionViewCount', () => { homeJustQuitOnFlagshipApp: false }) - renderHook(() => - useIncrementDefaultRedirectionViewCount(instance, homeSettings) - ) + renderHook(() => useIncrementDefaultRedirectionViewCount()) - expect(incrementDefaultRedirectionViewCount).not.toHaveBeenCalled() + expect(mockSaveHome).not.toHaveBeenCalled() }) it('should not increment when default redirection snackbar is disabled', () => { - const instance = { - data: { - attributes: { - default_redirection: 'drive/#/folder' + const mockSaveHome = jest.fn() + useSettings.mockImplementation((...args) => { + if (args[0] === 'instance') { + return { + values: { + default_redirection: 'drive/#/folder' + } + } + } else if (args[0] === 'home') { + return { + values: { + default_redirection_snackbar_disabled: true, + default_redirection_view_count: 2 + }, + save: mockSaveHome } } - } - const homeSettings = { - data: [ - { - default_redirection_snackbar_disabled: true, - default_redirection_view_count: 2 - } - ] - } + }) hasQueryBeenLoaded.mockReturnValue(true) deconstructRedirectLink.mockReturnValue({ slug: 'drive' }) useHomeAppOpened.mockReturnValue({ @@ -159,28 +232,30 @@ describe('useIncrementDefaultRedirectionViewCount', () => { homeJustQuitOnFlagshipApp: false }) - renderHook(() => - useIncrementDefaultRedirectionViewCount(instance, homeSettings) - ) + renderHook(() => useIncrementDefaultRedirectionViewCount()) - expect(incrementDefaultRedirectionViewCount).not.toHaveBeenCalled() + expect(mockSaveHome).not.toHaveBeenCalled() }) it('should not increment when home not just opened on flagship app', () => { - const instance = { - data: { - attributes: { - default_redirection: 'drive/#/folder' + const mockSaveHome = jest.fn() + useSettings.mockImplementation((...args) => { + if (args[0] === 'instance') { + return { + values: { + default_redirection: 'drive/#/folder' + } + } + } else if (args[0] === 'home') { + return { + values: { + default_redirection_snackbar_disabled: true, + default_redirection_view_count: 2 + }, + save: mockSaveHome } } - } - const homeSettings = { - data: [ - { - default_redirection_view_count: 2 - } - ] - } + }) hasQueryBeenLoaded.mockReturnValue(true) deconstructRedirectLink.mockReturnValue({ slug: 'drive' }) useHomeAppOpened.mockReturnValue({ @@ -188,10 +263,8 @@ describe('useIncrementDefaultRedirectionViewCount', () => { homeJustQuitOnFlagshipApp: false }) - renderHook(() => - useIncrementDefaultRedirectionViewCount(instance, homeSettings) - ) + renderHook(() => useIncrementDefaultRedirectionViewCount()) - expect(incrementDefaultRedirectionViewCount).not.toHaveBee + expect(mockSaveHome).not.toHaveBeenCalled() }) }) From fa234a1ba411b658bdbc591083616e4be72dfc1f Mon Sep 17 00:00:00 2001 From: Ldoppea Date: Fri, 19 Apr 2024 12:16:30 +0200 Subject: [PATCH 02/10] refactor: Rename `helper` to `useShouldShowDefaultRedirectionSnackbar` --- .../DefaultRedirectionSnackbar/DefaultRedirectionSnackbar.jsx | 2 +- .../DefaultRedirectionSnackbar.spec.jsx | 4 ++-- .../useIncrementDefaultRedirectionViewCount.js | 2 +- .../useIncrementDefaultRedirectionViewCount.spec.js | 2 +- ...{helpers.js => useShouldShowDefaultRedirectionSnackbar.js} | 0 ...pec.js => useShouldShowDefaultRedirectionSnackbar.spec.js} | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) rename src/components/DefaultRedirectionSnackbar/{helpers.js => useShouldShowDefaultRedirectionSnackbar.js} (100%) rename src/components/DefaultRedirectionSnackbar/{helpers.spec.js => useShouldShowDefaultRedirectionSnackbar.spec.js} (97%) diff --git a/src/components/DefaultRedirectionSnackbar/DefaultRedirectionSnackbar.jsx b/src/components/DefaultRedirectionSnackbar/DefaultRedirectionSnackbar.jsx index 245ed38ddb..dff7237cbc 100644 --- a/src/components/DefaultRedirectionSnackbar/DefaultRedirectionSnackbar.jsx +++ b/src/components/DefaultRedirectionSnackbar/DefaultRedirectionSnackbar.jsx @@ -13,7 +13,7 @@ import LightbulbIcon from 'cozy-ui/transpiled/react/Icons/Lightbulb' import { HOME_DEFAULT_REDIRECTION, useShouldShowDefaultRedirectionSnackbar -} from './helpers' +} from './useShouldShowDefaultRedirectionSnackbar' import useIncrementDefaultRedirectionViewCount from './useIncrementDefaultRedirectionViewCount' import { isFlagshipApp } from 'cozy-device-helper' diff --git a/src/components/DefaultRedirectionSnackbar/DefaultRedirectionSnackbar.spec.jsx b/src/components/DefaultRedirectionSnackbar/DefaultRedirectionSnackbar.spec.jsx index 71efbcc055..ba1c0a50fc 100644 --- a/src/components/DefaultRedirectionSnackbar/DefaultRedirectionSnackbar.spec.jsx +++ b/src/components/DefaultRedirectionSnackbar/DefaultRedirectionSnackbar.spec.jsx @@ -7,7 +7,7 @@ import CozyTheme from 'cozy-ui/transpiled/react/providers/CozyTheme' import AppLike from 'test/AppLike' import DefaultRedirectionSnackbar from './DefaultRedirectionSnackbar' -import { useShouldShowDefaultRedirectionSnackbar } from './helpers' +import { useShouldShowDefaultRedirectionSnackbar } from './useShouldShowDefaultRedirectionSnackbar' jest.mock('cozy-client', () => ({ ...jest.requireActual('cozy-client'), @@ -15,7 +15,7 @@ jest.mock('cozy-client', () => ({ useClient: jest.fn(), useSettings: jest.fn() })) -jest.mock('./helpers') +jest.mock('./useShouldShowDefaultRedirectionSnackbar') jest.mock('./useIncrementDefaultRedirectionViewCount') const setup = () => { diff --git a/src/components/DefaultRedirectionSnackbar/useIncrementDefaultRedirectionViewCount.js b/src/components/DefaultRedirectionSnackbar/useIncrementDefaultRedirectionViewCount.js index 7868e18219..9df4934ec4 100644 --- a/src/components/DefaultRedirectionSnackbar/useIncrementDefaultRedirectionViewCount.js +++ b/src/components/DefaultRedirectionSnackbar/useIncrementDefaultRedirectionViewCount.js @@ -7,7 +7,7 @@ import { hasQueryBeenLoaded } from 'cozy-client' -import { VIEW_COUNT_THRESHOLD } from './helpers' +import { VIEW_COUNT_THRESHOLD } from './useShouldShowDefaultRedirectionSnackbar' import useHomeAppOpened from './useHomeAppOpened' const useIncrementDefaultRedirectionViewCount = () => { diff --git a/src/components/DefaultRedirectionSnackbar/useIncrementDefaultRedirectionViewCount.spec.js b/src/components/DefaultRedirectionSnackbar/useIncrementDefaultRedirectionViewCount.spec.js index 758e91aa45..d1b4e83a16 100644 --- a/src/components/DefaultRedirectionSnackbar/useIncrementDefaultRedirectionViewCount.spec.js +++ b/src/components/DefaultRedirectionSnackbar/useIncrementDefaultRedirectionViewCount.spec.js @@ -10,7 +10,7 @@ import useIncrementDefaultRedirectionViewCount from './useIncrementDefaultRedire import useHomeAppOpened from './useHomeAppOpened' jest.mock('cozy-client') -jest.mock('./helpers') +jest.mock('./useShouldShowDefaultRedirectionSnackbar') jest.mock('./useHomeAppOpened') describe('useIncrementDefaultRedirectionViewCount', () => { diff --git a/src/components/DefaultRedirectionSnackbar/helpers.js b/src/components/DefaultRedirectionSnackbar/useShouldShowDefaultRedirectionSnackbar.js similarity index 100% rename from src/components/DefaultRedirectionSnackbar/helpers.js rename to src/components/DefaultRedirectionSnackbar/useShouldShowDefaultRedirectionSnackbar.js diff --git a/src/components/DefaultRedirectionSnackbar/helpers.spec.js b/src/components/DefaultRedirectionSnackbar/useShouldShowDefaultRedirectionSnackbar.spec.js similarity index 97% rename from src/components/DefaultRedirectionSnackbar/helpers.spec.js rename to src/components/DefaultRedirectionSnackbar/useShouldShowDefaultRedirectionSnackbar.spec.js index 169b90e59e..f88e067296 100644 --- a/src/components/DefaultRedirectionSnackbar/helpers.spec.js +++ b/src/components/DefaultRedirectionSnackbar/useShouldShowDefaultRedirectionSnackbar.spec.js @@ -6,7 +6,7 @@ import { useSettings } from 'cozy-client' -import { useShouldShowDefaultRedirectionSnackbar } from './helpers' +import { useShouldShowDefaultRedirectionSnackbar } from './useShouldShowDefaultRedirectionSnackbar' jest.mock('cozy-client') From 7f5be5b0d600423dc6705a3450fb2d4f0f638cf1 Mon Sep 17 00:00:00 2001 From: Ldoppea Date: Tue, 24 Sep 2024 17:03:51 +0200 Subject: [PATCH 03/10] feat: Upgrade cozy-harvest-lib `cozy-harvest-lib` has been upgraded to `30.0.1` in order to retrieve a fix on accounts fetching that provide support for Offline mode Related PR: cozy/cozy-libs#2585 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 423a487c00..5be92d9327 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "cozy-device-helper": "2.7.0", "cozy-doctypes": "1.83.8", "cozy-flags": "4.0.0", - "cozy-harvest-lib": "^30.0.0", + "cozy-harvest-lib": "^30.0.1", "cozy-intent": "^2.19.2", "cozy-interapp": "^0.9.0", "cozy-keys-lib": "^6.1.1", diff --git a/yarn.lock b/yarn.lock index 57e440c909..14405a2ecf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6058,10 +6058,10 @@ cozy-flags@4.0.0: dependencies: microee "^0.0.6" -cozy-harvest-lib@^30.0.0: - version "30.0.0" - resolved "https://registry.yarnpkg.com/cozy-harvest-lib/-/cozy-harvest-lib-30.0.0.tgz#2966a120d7177acc8cd9c8127a4581d1ec131031" - integrity sha512-hnlY/7ZZrEeY7tyIjBro2yU78zhRCW3sPqmJKBMkjvamyd3iu6NZqweUv/zsqhtgUAbf0b317LpRuCPnaaglYA== +cozy-harvest-lib@^30.0.1: + version "30.0.1" + resolved "https://registry.yarnpkg.com/cozy-harvest-lib/-/cozy-harvest-lib-30.0.1.tgz#d548222f327bf9cea9da05b23f18398e1bd2ac9f" + integrity sha512-O2WscBZuJ6/L28dCq4ocCMYmmWk1gr2+m2qk/R359PAK8YV3MkYDbWv39+Fn2pTopTKXsdWzryWt+xhKGozHkQ== dependencies: "@cozy/minilog" "^1.0.0" classnames "^2.3.1" From 1c0d809b0270a5523bccc23d01d55c944c7de548 Mon Sep 17 00:00:00 2001 From: Ldoppea Date: Tue, 24 Sep 2024 17:07:47 +0200 Subject: [PATCH 04/10] feat: Upgrade cozy-client and cozy-intent `cozy-client` has been upgraded to `49.0.0` in order to retrieve the Offline mode support `cozy-intent` has been upgraded to `2.23.0` as it is the new minimal version for `cozy-client` since `49.0.0` Related PR: cozy/cozy-client#1507 --- package.json | 4 ++-- yarn.lock | 27 ++++++++++++++------------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 5be92d9327..6cb45c2c85 100644 --- a/package.json +++ b/package.json @@ -35,12 +35,12 @@ "homepage": "https://github.com/cozy/cozy-home#readme", "dependencies": { "@sentry/react": "7.119.0", - "cozy-client": "^48.25.0", + "cozy-client": "^49.0.0", "cozy-device-helper": "2.7.0", "cozy-doctypes": "1.83.8", "cozy-flags": "4.0.0", "cozy-harvest-lib": "^30.0.1", - "cozy-intent": "^2.19.2", + "cozy-intent": "^2.23.0", "cozy-interapp": "^0.9.0", "cozy-keys-lib": "^6.1.1", "cozy-logger": "1.10.4", diff --git a/yarn.lock b/yarn.lock index 14405a2ecf..628149cb68 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5990,16 +5990,16 @@ cozy-bi-auth@0.0.25: lodash "^4.17.20" node-jose "^1.1.4" -cozy-client@^48.25.0: - version "48.25.0" - resolved "https://registry.yarnpkg.com/cozy-client/-/cozy-client-48.25.0.tgz#8676cdeb1e4b3bc808421de304653e10982ff9f3" - integrity sha512-bAmSWPS7+5AwJxDnudBMvgaBGyU/D+qZANz23oz+ie7HNC7u/thCthrpEk80RCbuNyCuepZM0+FF7lPwfzgtzg== +cozy-client@^49.0.0: + version "49.0.0" + resolved "https://registry.yarnpkg.com/cozy-client/-/cozy-client-49.0.0.tgz#c38f3bdefd58cbf827a368fe126cc9e27deb996d" + integrity sha512-AY22bxwQV+46+4rSVc+zYci8pPHspolBJ1IcqvxJ+DknZrehJ5AKJ55F9DzN3aPXVNCQzmw+wpNFgVP4gShFAw== dependencies: "@cozy/minilog" "1.0.0" "@types/jest" "^26.0.20" "@types/lodash" "^4.14.170" btoa "^1.2.1" - cozy-stack-client "^48.16.0" + cozy-stack-client "^49.0.0" date-fns "2.29.3" json-stable-stringify "^1.0.1" lodash "^4.17.13" @@ -6079,11 +6079,12 @@ cozy-harvest-lib@^30.0.1: use-deep-compare-effect "^1.8.1" uuid "^3.3.2" -cozy-intent@^2.19.2: - version "2.19.2" - resolved "https://registry.yarnpkg.com/cozy-intent/-/cozy-intent-2.19.2.tgz#2f66f2c6613022264b737bb563cf90d9b0288e2a" - integrity sha512-frjTf6SQ4oiR3mCs7lDLJ7ldFBNBq6TF18Myoe2mq2riJ9QRHtIgPkcV44zjvk8KW4KElO+A7TW+wJXHAVfjaQ== +cozy-intent@^2.23.0: + version "2.23.0" + resolved "https://registry.yarnpkg.com/cozy-intent/-/cozy-intent-2.23.0.tgz#b6f3a407413df05c108e848b9dcb074b8780824b" + integrity sha512-DFn0ny4B4HpOE+3PYuZTTa074gRnFHqID+XaJ3gY2OrPL2xUQKEZmmFLp2bPVWThi5FvgvsU3EQeWPHZNQPbaQ== dependencies: + cozy-minilog "^3.3.1" post-me "0.4.5" cozy-interapp@^0.5.4: @@ -6246,10 +6247,10 @@ cozy-sharing@^16.0.0: react-tooltip "^3.11.1" snarkdown "^2.0.0" -cozy-stack-client@^48.16.0: - version "48.16.0" - resolved "https://registry.yarnpkg.com/cozy-stack-client/-/cozy-stack-client-48.16.0.tgz#e8820197a0eb640e2d9061e21fad430ca5e56065" - integrity sha512-JgXAsmXESCfbC+T2EiXzUoPiDNFf2ePzNFQK98ZbWorAj8G6DcggdcG83/eD4QCwmv/1jXTaUWI1euTQdYEDQg== +cozy-stack-client@^49.0.0: + version "49.0.0" + integrity sha512-mlh/hR9KsIve+et17P6WXlO33FjXftzXK8ovWAKr8zk+5FcD/wy/yxV/9Mr3Q+SSabdUbFbBIqu8kZncafUzdg== + resolved "https://registry.yarnpkg.com/cozy-stack-client/-/cozy-stack-client-49.0.0.tgz#1bda328d0d62b00bb8895be5b991d59ad6b41cfc" dependencies: detect-node "^2.0.4" mime "^2.4.0" From 8d428e72b2ec5b2355a1112f7f7baa74383981e5 Mon Sep 17 00:00:00 2001 From: Ldoppea Date: Tue, 24 Sep 2024 17:10:10 +0200 Subject: [PATCH 05/10] feat: Upgrade cozy-device-helper `cozy-device-helper` has been upgraded to `3.1.0` in order to retrieve the Offline mode support Related PR: cozy/cozy-libs#2562 --- package.json | 2 +- yarn.lock | 27 ++++++++++++++++++--------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 6cb45c2c85..d6c0edbc2b 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "dependencies": { "@sentry/react": "7.119.0", "cozy-client": "^49.0.0", - "cozy-device-helper": "2.7.0", + "cozy-device-helper": "3.1.0", "cozy-doctypes": "1.83.8", "cozy-flags": "4.0.0", "cozy-harvest-lib": "^30.0.1", diff --git a/yarn.lock b/yarn.lock index 628149cb68..706c26d6fd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6015,20 +6015,20 @@ cozy-client@^49.0.0: sift "^6.0.0" url-search-params-polyfill "^8.0.0" -cozy-device-helper@2.7.0, cozy-device-helper@^2.1.0, cozy-device-helper@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/cozy-device-helper/-/cozy-device-helper-2.7.0.tgz#573749997f18e5a1f11f720faec8c9bf2406beeb" - integrity sha512-jMzW7s4IDuMivbsP8fo1IWW1z5l0wJ0u440E0fQmdsi+Zm/L9GXFKthLuuceYqXlH6c/APUCfpozJqjFMMHU1A== - dependencies: - lodash "^4.17.19" - -cozy-device-helper@^3.1.0: +cozy-device-helper@3.1.0, cozy-device-helper@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/cozy-device-helper/-/cozy-device-helper-3.1.0.tgz#140079bf4a6844b21d6ac0a3a2d75741dba15faa" integrity sha512-KorbuWN+oZ+v7okbXQTbLuW6nt7IyVnIIsDXB3Ay6zdtl5nV13+fOGKeRsjaecgBDLSXWJ07j0ooT7l6orZpDg== dependencies: lodash "^4.17.19" +cozy-device-helper@^2.1.0, cozy-device-helper@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/cozy-device-helper/-/cozy-device-helper-2.7.0.tgz#573749997f18e5a1f11f720faec8c9bf2406beeb" + integrity sha512-jMzW7s4IDuMivbsP8fo1IWW1z5l0wJ0u440E0fQmdsi+Zm/L9GXFKthLuuceYqXlH6c/APUCfpozJqjFMMHU1A== + dependencies: + lodash "^4.17.19" + cozy-doctypes@1.83.8: version "1.83.8" resolved "https://registry.yarnpkg.com/cozy-doctypes/-/cozy-doctypes-1.83.8.tgz#99ec864059034bd032f6f01e322b57fea130a5d3" @@ -6247,10 +6247,19 @@ cozy-sharing@^16.0.0: react-tooltip "^3.11.1" snarkdown "^2.0.0" +cozy-stack-client@^48.16.0: + version "48.16.0" + resolved "https://registry.yarnpkg.com/cozy-stack-client/-/cozy-stack-client-48.16.0.tgz#e8820197a0eb640e2d9061e21fad430ca5e56065" + integrity sha512-JgXAsmXESCfbC+T2EiXzUoPiDNFf2ePzNFQK98ZbWorAj8G6DcggdcG83/eD4QCwmv/1jXTaUWI1euTQdYEDQg== + dependencies: + detect-node "^2.0.4" + mime "^2.4.0" + qs "^6.7.0" + cozy-stack-client@^49.0.0: version "49.0.0" - integrity sha512-mlh/hR9KsIve+et17P6WXlO33FjXftzXK8ovWAKr8zk+5FcD/wy/yxV/9Mr3Q+SSabdUbFbBIqu8kZncafUzdg== resolved "https://registry.yarnpkg.com/cozy-stack-client/-/cozy-stack-client-49.0.0.tgz#1bda328d0d62b00bb8895be5b991d59ad6b41cfc" + integrity sha512-mlh/hR9KsIve+et17P6WXlO33FjXftzXK8ovWAKr8zk+5FcD/wy/yxV/9Mr3Q+SSabdUbFbBIqu8kZncafUzdg== dependencies: detect-node "^2.0.4" mime "^2.4.0" From 189dc77860137c60189153d60d4d9b3891f8c120 Mon Sep 17 00:00:00 2001 From: Ldoppea Date: Wed, 19 Jun 2024 17:03:19 +0200 Subject: [PATCH 06/10] feat: Handle offline mode in Flagship app We want cozy-home to be compatible with the new Flagship app's Offline mode When hosted in a Flagship app's WebView we now want to use FlagshipLink instead of StackLink in cozy-client This link will allow to redirect all queries to the Flagship app that will handle data access when offline but also when online Related PR: cozy/cozy-client#1507 Related PR: cozy/cozy-flagship-app#1239 --- src/components/AppWrapper.jsx | 36 +++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/src/components/AppWrapper.jsx b/src/components/AppWrapper.jsx index dac323112b..146765e9ff 100644 --- a/src/components/AppWrapper.jsx +++ b/src/components/AppWrapper.jsx @@ -1,10 +1,15 @@ -import React, { createContext } from 'react' +import React, { createContext, useEffect, useState } from 'react' import { Provider as ReduxProvider } from 'react-redux' import memoize from 'lodash/memoize' import flag from 'cozy-flags' -import CozyClient, { CozyProvider, RealTimeQueries } from 'cozy-client' +import CozyClient, { + CozyProvider, + RealTimeQueries, + FlagshipLink +} from 'cozy-client' import CozyDevtools from 'cozy-client/dist/devtools' +import { useWebviewIntent } from 'cozy-intent' import I18n from 'cozy-ui/transpiled/react/providers/I18n' import CozyTheme from 'cozy-ui/transpiled/react/providers/CozyTheme' import { BreakpointsProvider } from 'cozy-ui/transpiled/react/providers/Breakpoints' @@ -14,7 +19,7 @@ import { useCozyTheme } from 'cozy-ui/transpiled/react/providers/CozyTheme' import configureStore from 'store/configureStore' import { RealtimePlugin } from 'cozy-realtime' -// import { isFlagshipApp } from 'cozy-device-helper' +import { isFlagshipApp, isFlagshipOfflineSupported } from 'cozy-device-helper' import { useWallpaperContext } from 'hooks/useWallpaperContext' @@ -31,12 +36,14 @@ export const AppContext = createContext() * * Is memoized to avoid several clients in case of hot-reload */ -export const setupAppContext = memoize(() => { +export const setupAppContext = memoize(intent => { const lang = document.documentElement.getAttribute('lang') || 'en' const context = window.context || 'cozy' const root = document.querySelector('[role=application]') const data = root.dataset + const shouldUseFlagshipLink = isFlagshipApp() && isFlagshipOfflineSupported() + // New improvements must be done with CozyClient const cozyClient = new CozyClient({ uri: `${window.location.protocol}//${data.cozyDomain}`, @@ -47,7 +54,10 @@ export const setupAppContext = memoize(() => { 'home.store.persist' ) ? true - : false + : false, + links: shouldUseFlagshipLink + ? new FlagshipLink({ webviewIntent: intent }) + : null }) cozyClient.registerPlugin(flag.plugin) @@ -100,7 +110,21 @@ const ThemeProvider = ({ children }) => { * for an app */ const AppWrapper = ({ children }) => { - const appContext = setupAppContext() + const webviewIntent = useWebviewIntent() + const [appContext, setAppContext] = useState(undefined) + + useEffect(() => { + if (isFlagshipApp() && !webviewIntent) return + + const newAppContext = setupAppContext(webviewIntent) + + setAppContext(newAppContext) + }, [webviewIntent]) + + if (!appContext) { + return null + } + const { store, cozyClient, context, lang, persistor } = appContext return ( From d4a25758fa960199a19094956990679342f2560e Mon Sep 17 00:00:00 2001 From: Ldoppea Date: Sun, 15 Sep 2024 15:21:56 +0200 Subject: [PATCH 07/10] fix: Do not rely on `.attributes` from queries result --- .../Announcements/AnnouncementsDialog.tsx | 2 +- .../AnnouncementsDialogContent.tsx | 25 +++++---- src/components/Announcements/types.ts | 54 +++++++++---------- src/components/ShortcutLink.jsx | 2 +- src/components/Shortcuts/utils.js | 6 +-- src/containers/App.jsx | 4 +- src/containers/IntentService.jsx | 4 +- src/hooks/useAnnouncements.tsx | 2 +- src/hooks/useInstanceSettings.ts | 7 ++- src/lib/konnectors.js | 2 +- 10 files changed, 51 insertions(+), 57 deletions(-) diff --git a/src/components/Announcements/AnnouncementsDialog.tsx b/src/components/Announcements/AnnouncementsDialog.tsx index a97d3acc3f..0f21a792f6 100644 --- a/src/components/Announcements/AnnouncementsDialog.tsx +++ b/src/components/Announcements/AnnouncementsDialog.tsx @@ -33,7 +33,7 @@ const AnnouncementsDialog: FC = ({ } const handleNext = (): void => { - const uuid = announcements[activeStep].attributes.uuid + const uuid = announcements[activeStep].uuid if (!values?.seen.includes(uuid)) { save({ seen: [...(values?.seen ?? []), uuid] diff --git a/src/components/Announcements/AnnouncementsDialogContent.tsx b/src/components/Announcements/AnnouncementsDialogContent.tsx index e20349bba4..3b0124ed02 100644 --- a/src/components/Announcements/AnnouncementsDialogContent.tsx +++ b/src/components/Announcements/AnnouncementsDialogContent.tsx @@ -23,17 +23,17 @@ const AnnouncementsDialogContent: FC = ({ }) => { const { t, f } = useI18n() const primaryImage = useAnnouncementsImage( - announcement.attributes.primary_image.data.attributes.formats.small?.url ?? - announcement.attributes.primary_image.data.attributes.url + announcement.primary_image.data.formats.small?.url ?? + announcement.primary_image.data.url ) const secondaryImage = useAnnouncementsImage( - announcement.attributes.secondary_image.data?.attributes.formats.thumbnail + announcement.secondary_image.data?.formats.thumbnail .url ) const handleMainAction = (): void => { - if (announcement.attributes.main_action?.link) { - window.open(announcement.attributes.main_action.link, '_blank') + if (announcement.main_action?.link) { + window.open(announcement.main_action.link, '_blank') } } @@ -43,7 +43,7 @@ const AnnouncementsDialogContent: FC = ({ { = ({ /> ) : null} - {announcement.attributes.title} + {announcement.title} = ({ variant="body2" > {f( - announcement.attributes.start_at, + announcement.start_at, t('AnnouncementsDialogContent.dateFormat') )}
- +
- {announcement.attributes.main_action ? ( + {announcement.main_action ? ( ) : null} @@ -93,8 +93,7 @@ const AnnouncementsDialogContent: FC = ({ { { return folders .map(folder => ({ id: folder._id, - name: folder.attributes.name, - items: shortcuts.filter( - shortcut => shortcut.attributes.dir_id === folder._id - ) + name: folder.name, + items: shortcuts.filter(shortcut => shortcut.dir_id === folder._id) })) .filter(folder => folder.items.length > 0) } diff --git a/src/containers/App.jsx b/src/containers/App.jsx index ab76a44ed0..78124421b0 100644 --- a/src/containers/App.jsx +++ b/src/containers/App.jsx @@ -106,8 +106,8 @@ const App = ({ accounts, konnectors, triggers }) => { ) }, [accounts, konnectors, triggers, context]) - if (context?.attributes?.features) { - const flags = toFlagNames(context.attributes.features) + if (context?.features) { + const flags = toFlagNames(context.features) enableFlags(flags) } useEffect(() => { diff --git a/src/containers/IntentService.jsx b/src/containers/IntentService.jsx index 4a8d2037a4..2898828141 100644 --- a/src/containers/IntentService.jsx +++ b/src/containers/IntentService.jsx @@ -41,8 +41,8 @@ const IntentService = ({ data, service }) => { service.hideCross() } if ( - intent.attributes.action === 'VIEW' && - intent.attributes.type === 'io.cozy.accounts' + intent.action === 'VIEW' && + intent.type === 'io.cozy.accounts' ) { navigate(`/${service.getData().slug}/accounts/${data.accountId}`) } else { diff --git a/src/hooks/useAnnouncements.tsx b/src/hooks/useAnnouncements.tsx index 8f0acdf09b..082319f65b 100644 --- a/src/hooks/useAnnouncements.tsx +++ b/src/hooks/useAnnouncements.tsx @@ -68,7 +68,7 @@ const useAnnouncements = ({ if (rawData !== null && values && !hasStartedFiltering) { setHasStartedFiltering(true) const uuidsSeen = values.seen ?? [] - const uuidsFromApi = rawData.map(({ attributes }) => attributes.uuid) + const uuidsFromApi = rawData.map(data => data.uuid) // we only keep the announcements seen that are still returned by the API // to limit the size of the seen array diff --git a/src/hooks/useInstanceSettings.ts b/src/hooks/useInstanceSettings.ts index 1686bdfa1e..5e7e4f4bc4 100644 --- a/src/hooks/useInstanceSettings.ts +++ b/src/hooks/useInstanceSettings.ts @@ -47,12 +47,11 @@ const getLocalAttributes = ( ): InstanceAttributes | undefined => (Array.isArray(instanceSettings.data) && instanceSettings.data.length > 0 && - (instanceSettings.data[0] as { attributes?: InstanceAttributes }) - .attributes) || + (instanceSettings.data[0] as InstanceAttributes)) || undefined type FetchAttributesResponse = { - data?: { attributes?: InstanceAttributes } + data?: InstanceAttributes } | void const fetchAttributes = async ( @@ -62,7 +61,7 @@ const fetchAttributes = async ( Q('io.cozy.settings').getById('io.cozy.settings.instance') )) as FetchAttributesResponse - return res?.data?.attributes + return res?.data } export const useInstanceSettings = (client: CozyClient): InstanceSettings => { diff --git a/src/lib/konnectors.js b/src/lib/konnectors.js index e26754c79e..becdb9d855 100644 --- a/src/lib/konnectors.js +++ b/src/lib/konnectors.js @@ -18,7 +18,7 @@ export const TWO_FA_ERRORS = [ ] function patchFolderPermission(cozy, konnector, folderId = null) { - const slug = konnector.attributes ? konnector.attributes.slug : konnector.slug + const slug = konnector.slug const saveFolder = folderId ? { type: 'io.cozy.files', values: [folderId] } : {} From 95cc6d3724e928aaaceb2d28253ce785790c9119 Mon Sep 17 00:00:00 2001 From: Ldoppea Date: Thu, 19 Sep 2024 14:59:56 +0200 Subject: [PATCH 08/10] fix: Use a query for `fetchAllKonnectors()` --- src/components/Sections/queries/konnectors.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/components/Sections/queries/konnectors.ts b/src/components/Sections/queries/konnectors.ts index 66506e78d3..ad58c32ffb 100644 --- a/src/components/Sections/queries/konnectors.ts +++ b/src/components/Sections/queries/konnectors.ts @@ -1,6 +1,6 @@ import memoize from 'lodash/memoize' -import CozyClient from 'cozy-client' +import CozyClient, { Q } from 'cozy-client' import { IOCozyKonnector } from 'cozy-client/types/types' import { KonnectorFromRegistry } from 'components/Sections/SectionsTypes' @@ -36,10 +36,8 @@ export const fetchAllKonnectors = async ( client: CozyClient, channel = 'stable' ): Promise<{ [key: string]: IOCozyKonnector[] }> => { - // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access - const { data } = (await client.stackClient.fetchJSON( - 'GET', - `/registry?versionsChannel=${channel}&filter[type]=konnector&limit=300` + const { data } = (await client.query( + Q('io.cozy.apps_registry').getById(`konnectors/${channel}`) )) as { data: KonnectorFromRegistry[] } return memoizedGroupByCategory(data) From e56ea587be1ce7626172b53c7c5a4bb3d9e5431f Mon Sep 17 00:00:00 2001 From: Ldoppea Date: Sun, 15 Sep 2024 15:26:47 +0200 Subject: [PATCH 09/10] feat: Declare offline compatibility in manifest.webapp --- manifest.webapp | 1 + 1 file changed, 1 insertion(+) diff --git a/manifest.webapp b/manifest.webapp index 592f4ab582..ff7cfb91cc 100644 --- a/manifest.webapp +++ b/manifest.webapp @@ -13,6 +13,7 @@ }, "version": "1.82.0", "licence": "AGPL-3.0", + "offline_support": true, "permissions": { "home": { "description": "Required to manage default redirection update", From 797a31202bbde1e5cba66ac18d8647f1f8cc21de Mon Sep 17 00:00:00 2001 From: Ldoppea Date: Mon, 23 Sep 2024 18:53:34 +0200 Subject: [PATCH 10/10] feat: Rename FlagshipLink to WebFlagshipLink Related PR: cozy/cozy-client#1536 --- src/components/AppWrapper.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/AppWrapper.jsx b/src/components/AppWrapper.jsx index 146765e9ff..cd61d4045a 100644 --- a/src/components/AppWrapper.jsx +++ b/src/components/AppWrapper.jsx @@ -6,7 +6,7 @@ import flag from 'cozy-flags' import CozyClient, { CozyProvider, RealTimeQueries, - FlagshipLink + WebFlagshipLink } from 'cozy-client' import CozyDevtools from 'cozy-client/dist/devtools' import { useWebviewIntent } from 'cozy-intent' @@ -42,7 +42,7 @@ export const setupAppContext = memoize(intent => { const root = document.querySelector('[role=application]') const data = root.dataset - const shouldUseFlagshipLink = isFlagshipApp() && isFlagshipOfflineSupported() + const shouldUseWebFlagshipLink = isFlagshipApp() && isFlagshipOfflineSupported() // New improvements must be done with CozyClient const cozyClient = new CozyClient({ @@ -55,8 +55,8 @@ export const setupAppContext = memoize(intent => { ) ? true : false, - links: shouldUseFlagshipLink - ? new FlagshipLink({ webviewIntent: intent }) + links: shouldUseWebFlagshipLink + ? new WebFlagshipLink({ webviewIntent: intent }) : null })