diff --git a/res/css/components/views/beacon/_LiveTimeRemaining.scss b/res/css/components/views/beacon/_LiveTimeRemaining.scss new file mode 100644 index 0000000000..de13f7aab2 --- /dev/null +++ b/res/css/components/views/beacon/_LiveTimeRemaining.scss @@ -0,0 +1,20 @@ +/* +Copyright 2022 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_LiveTimeRemaining { + color: $secondary-content; + font-size: $font-12px; +} diff --git a/res/css/components/views/beacon/_RoomLiveShareWarning.scss b/res/css/components/views/beacon/_RoomLiveShareWarning.scss index 7404f88aea..1449193e7b 100644 --- a/res/css/components/views/beacon/_RoomLiveShareWarning.scss +++ b/res/css/components/views/beacon/_RoomLiveShareWarning.scss @@ -39,12 +39,6 @@ limitations under the License. font-size: $font-15px; } -.mx_RoomLiveShareWarning_expiry { - color: $secondary-content; - font-size: $font-12px; - margin-right: $spacing-16; -} - .mx_RoomLiveShareWarning_spinner { margin-right: $spacing-16; } diff --git a/src/components/views/beacon/LiveTimeRemaining.tsx b/src/components/views/beacon/LiveTimeRemaining.tsx new file mode 100644 index 0000000000..1f25706a13 --- /dev/null +++ b/src/components/views/beacon/LiveTimeRemaining.tsx @@ -0,0 +1,75 @@ +/* +Copyright 2022 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import React, { useCallback, useEffect, useState } from 'react'; +import { BeaconEvent, Beacon } from 'matrix-js-sdk/src/matrix'; + +import { formatDuration } from '../../../DateUtils'; +import { useEventEmitterState } from '../../../hooks/useEventEmitter'; +import { useInterval } from '../../../hooks/useTimeout'; +import { _t } from '../../../languageHandler'; +import { getBeaconMsUntilExpiry } from '../../../utils/beacon'; + +const MINUTE_MS = 60000; +const HOUR_MS = MINUTE_MS * 60; +const getUpdateInterval = (ms: number) => { + // every 10 mins when more than an hour + if (ms > HOUR_MS) { + return MINUTE_MS * 10; + } + // every minute when more than a minute + if (ms > MINUTE_MS) { + return MINUTE_MS; + } + // otherwise every second + return 1000; +}; +const useMsRemaining = (beacon: Beacon): number => { + const beaconInfo = useEventEmitterState( + beacon, + BeaconEvent.Update, + () => beacon.beaconInfo, + ); + + const [msRemaining, setMsRemaining] = useState(() => getBeaconMsUntilExpiry(beaconInfo)); + + useEffect(() => { + setMsRemaining(getBeaconMsUntilExpiry(beaconInfo)); + }, [beaconInfo]); + + const updateMsRemaining = useCallback(() => { + const ms = getBeaconMsUntilExpiry(beaconInfo); + setMsRemaining(ms); + }, [beaconInfo]); + + useInterval(updateMsRemaining, getUpdateInterval(msRemaining)); + + return msRemaining; +}; + +const LiveTimeRemaining: React.FC<{ beacon: Beacon }> = ({ beacon }) => { + const msRemaining = useMsRemaining(beacon); + + const timeRemaining = formatDuration(msRemaining); + const liveTimeRemaining = _t(`%(timeRemaining)s left`, { timeRemaining }); + + return { liveTimeRemaining }; +}; + +export default LiveTimeRemaining; diff --git a/src/components/views/beacon/RoomLiveShareWarning.tsx b/src/components/views/beacon/RoomLiveShareWarning.tsx index 0c1b67dc10..89fb1cfb46 100644 --- a/src/components/views/beacon/RoomLiveShareWarning.tsx +++ b/src/components/views/beacon/RoomLiveShareWarning.tsx @@ -14,63 +14,23 @@ See the License for the specific language governing permissions and limitations under the License. */ -import React, { useCallback, useEffect, useState } from 'react'; +import React, { useEffect, useState } from 'react'; import classNames from 'classnames'; import { Room, Beacon, - BeaconEvent, BeaconIdentifier, } from 'matrix-js-sdk/src/matrix'; -import { formatDuration } from '../../../DateUtils'; import { _t } from '../../../languageHandler'; import { useEventEmitterState } from '../../../hooks/useEventEmitter'; -import { useInterval } from '../../../hooks/useTimeout'; import { OwnBeaconStore, OwnBeaconStoreEvent } from '../../../stores/OwnBeaconStore'; -import { getBeaconMsUntilExpiry, sortBeaconsByLatestExpiry } from '../../../utils/beacon'; +import { sortBeaconsByLatestExpiry } from '../../../utils/beacon'; import AccessibleButton from '../elements/AccessibleButton'; import Spinner from '../elements/Spinner'; import StyledLiveBeaconIcon from './StyledLiveBeaconIcon'; import { Icon as CloseIcon } from '../../../../res/img/image-view/close.svg'; - -const MINUTE_MS = 60000; -const HOUR_MS = MINUTE_MS * 60; - -const getUpdateInterval = (ms: number) => { - // every 10 mins when more than an hour - if (ms > HOUR_MS) { - return MINUTE_MS * 10; - } - // every minute when more than a minute - if (ms > MINUTE_MS) { - return MINUTE_MS; - } - // otherwise every second - return 1000; -}; -const useMsRemaining = (beacon: Beacon): number => { - const beaconInfo = useEventEmitterState( - beacon, - BeaconEvent.Update, - () => beacon.beaconInfo, - ); - - const [msRemaining, setMsRemaining] = useState(() => getBeaconMsUntilExpiry(beaconInfo)); - - useEffect(() => { - setMsRemaining(getBeaconMsUntilExpiry(beaconInfo)); - }, [beaconInfo]); - - const updateMsRemaining = useCallback(() => { - const ms = getBeaconMsUntilExpiry(beaconInfo); - setMsRemaining(ms); - }, [beaconInfo]); - - useInterval(updateMsRemaining, getUpdateInterval(msRemaining)); - - return msRemaining; -}; +import LiveTimeRemaining from './LiveTimeRemaining'; /** * It's technically possible to have multiple live beacons in one room @@ -134,18 +94,6 @@ const useLiveBeacons = (liveBeaconIds: BeaconIdentifier[], roomId: string): Live }; }; -const LiveTimeRemaining: React.FC<{ beacon: Beacon }> = ({ beacon }) => { - const msRemaining = useMsRemaining(beacon); - - const timeRemaining = formatDuration(msRemaining); - const liveTimeRemaining = _t(`%(timeRemaining)s left`, { timeRemaining }); - - return { liveTimeRemaining }; -}; - const getLabel = (hasWireError: boolean, hasStopSharingError: boolean): string => { if (hasWireError) { return _t('An error occured whilst sharing your live location, please try again'); diff --git a/test/components/views/beacon/__snapshots__/RoomLiveShareWarning-test.tsx.snap b/test/components/views/beacon/__snapshots__/RoomLiveShareWarning-test.tsx.snap index 65fcd27137..18efb2c8ab 100644 --- a/test/components/views/beacon/__snapshots__/RoomLiveShareWarning-test.tsx.snap +++ b/test/components/views/beacon/__snapshots__/RoomLiveShareWarning-test.tsx.snap @@ -1,8 +1,8 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[` when user has live beacons and geolocation is available renders correctly with one live beacon in room 1`] = `"
You are sharing your live location1h left
"`; +exports[` when user has live beacons and geolocation is available renders correctly with one live beacon in room 1`] = `"
You are sharing your live location1h left
"`; -exports[` when user has live beacons and geolocation is available renders correctly with two live beacons in room 1`] = `"
You are sharing your live location12h left
"`; +exports[` when user has live beacons and geolocation is available renders correctly with two live beacons in room 1`] = `"
You are sharing your live location12h left
"`; exports[` when user has live beacons and geolocation is available stopping beacons displays error when stop sharing fails 1`] = `"
An error occurred while stopping your live location, please try again
"`;