@@ -5,11 +5,13 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
55Please see LICENSE files in the repository root for full details.
66*/
77
8- import { useCallback , useEffect , useState } from "react" ;
8+ import { useCallback , useState } from "react" ;
9+ import { CryptoEvent } from "matrix-js-sdk/src/crypto-api" ;
910import { logger } from "matrix-js-sdk/src/logger" ;
1011
1112import { useMatrixClientContext } from "../../../../contexts/MatrixClientContext" ;
1213import DeviceListener , { BACKUP_DISABLED_ACCOUNT_DATA_KEY } from "../../../../DeviceListener" ;
14+ import { useEventEmitterAsyncState } from "../../../../hooks/useEventEmitter" ;
1315
1416interface KeyStoragePanelState {
1517 /**
@@ -37,31 +39,37 @@ interface KeyStoragePanelState {
3739
3840/** Returns a ViewModel for use in {@link KeyStoragePanel} and {@link DeleteKeyStoragePanel}. */
3941export function useKeyStoragePanelViewModel ( ) : KeyStoragePanelState {
40- const [ isEnabled , setIsEnabled ] = useState < boolean | undefined > ( undefined ) ;
4142 const [ loading , setLoading ] = useState ( true ) ;
4243 // Whilst the change is being made, the toggle will reflect the pending value rather than the actual state
4344 const [ pendingValue , setPendingValue ] = useState < boolean | undefined > ( undefined ) ;
4445
4546 const matrixClient = useMatrixClientContext ( ) ;
4647
47- const checkStatus = useCallback ( async ( ) => {
48- const crypto = matrixClient . getCrypto ( ) ;
49- if ( ! crypto ) {
50- logger . error ( "Can't check key backup status: no crypto module available" ) ;
51- return ;
52- }
53- // The toggle is enabled only if this device will upload megolm keys to the backup.
54- // This is consistent with EX.
55- const activeBackupVersion = await crypto . getActiveSessionBackupVersion ( ) ;
56- setIsEnabled ( activeBackupVersion !== null ) ;
57- } , [ matrixClient ] ) ;
58-
59- useEffect ( ( ) => {
60- ( async ( ) => {
61- await checkStatus ( ) ;
48+ const isEnabled = useEventEmitterAsyncState (
49+ matrixClient ,
50+ CryptoEvent . KeyBackupStatus ,
51+ async ( enabled ?: boolean ) => {
52+ // If we're called as a result of an event, rather than during
53+ // initialisation, we can get the backup status from the event
54+ // instead of having to query the backup version.
55+ if ( enabled !== undefined ) {
56+ return enabled ;
57+ }
58+
59+ const crypto = matrixClient . getCrypto ( ) ;
60+ if ( ! crypto ) {
61+ logger . error ( "Can't check key backup status: no crypto module available" ) ;
62+ return ;
63+ }
64+ // The toggle is enabled only if this device will upload megolm keys to the backup.
65+ // This is consistent with EX.
66+ const activeBackupVersion = await crypto . getActiveSessionBackupVersion ( ) ;
6267 setLoading ( false ) ;
63- } ) ( ) ;
64- } , [ checkStatus ] ) ;
68+ return activeBackupVersion !== null ;
69+ } ,
70+ [ matrixClient ] ,
71+ undefined ,
72+ ) ;
6573
6674 const setEnabled = useCallback (
6775 async ( enable : boolean ) => {
@@ -121,14 +129,12 @@ export function useKeyStoragePanelViewModel(): KeyStoragePanelState {
121129 // so this will stop EX turning it back on spontaneously.
122130 await matrixClient . setAccountData ( BACKUP_DISABLED_ACCOUNT_DATA_KEY , { disabled : true } ) ;
123131 }
124-
125- await checkStatus ( ) ;
126132 } finally {
127133 setPendingValue ( undefined ) ;
128134 DeviceListener . sharedInstance ( ) . start ( matrixClient ) ;
129135 }
130136 } ,
131- [ setPendingValue , checkStatus , matrixClient ] ,
137+ [ setPendingValue , matrixClient ] ,
132138 ) ;
133139
134140 return { isEnabled : pendingValue ?? isEnabled , setEnabled, loading, busy : pendingValue !== undefined } ;
0 commit comments