-
-
Notifications
You must be signed in to change notification settings - Fork 833
Commit
And automatically refresh the timezone every minute.
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import { useEffect, useState } from "react"; | ||
Check failure on line 1 in src/hooks/useUserTimezone.ts GitHub Actions / ESLint
|
||
import { MatrixClientPeg } from "../MatrixClientPeg"; | ||
import { MatrixError } from "matrix-js-sdk/src/matrix"; | ||
|
||
/** | ||
* Fetch a user's delclared timezone through their profile, and return | ||
* a friendly string of the current time for that user. This will keep | ||
* in sync with the current time, and will be refreshed once a minute. | ||
* | ||
* @param userId The userID to fetch the timezone for. | ||
* @returns A timezone name and friendly string for the user's timezone, or | ||
* null if the user has no timezone or the timezone was not recognised | ||
* by the browser. | ||
*/ | ||
export const useUserTimezone = (userId: string): { timezone: string, friendly: string }|null => { | ||
const [timezone, setTimezone] = useState<string>(); | ||
const [updateInterval, setUpdateInterval] = useState<number>(); | ||
const [friendly, setFriendly] = useState<string>(); | ||
const [supported, setSupported] = useState<boolean>(); | ||
const cli = MatrixClientPeg.safeGet(); | ||
|
||
useEffect(() => { | ||
if (supported !== undefined) { | ||
return; | ||
} | ||
cli.doesServerSupportExtendedProfiles().then(setSupported).catch((ex) => { | ||
Check failure on line 26 in src/hooks/useUserTimezone.ts GitHub Actions / Typescript Syntax Check
Check failure on line 26 in src/hooks/useUserTimezone.ts GitHub Actions / Typescript Syntax Check
Check failure on line 26 in src/hooks/useUserTimezone.ts GitHub Actions / Jest (1)<UserInfo /> › closes on close button click
Check failure on line 26 in src/hooks/useUserTimezone.ts GitHub Actions / Jest (1)<UserInfo /> › without a room › does not render space header
Check failure on line 26 in src/hooks/useUserTimezone.ts GitHub Actions / Jest (1)<UserInfo /> › without a room › renders user info
Check failure on line 26 in src/hooks/useUserTimezone.ts GitHub Actions / Jest (1)<UserInfo /> › without a room › renders encryption info panel without pending verification
Check failure on line 26 in src/hooks/useUserTimezone.ts GitHub Actions / Jest (1)<UserInfo /> › without a room › renders encryption verification panel with pending verification
Check failure on line 26 in src/hooks/useUserTimezone.ts GitHub Actions / Jest (1)<UserInfo /> › without a room › should show error modal when the verification request is cancelled with a mismatch
Check failure on line 26 in src/hooks/useUserTimezone.ts GitHub Actions / Jest (1)<UserInfo /> › without a room › should not show error modal when the verification request is changed for some other reason
Check failure on line 26 in src/hooks/useUserTimezone.ts GitHub Actions / Jest (1)<UserInfo /> › without a room › renders close button correctly when encryption panel with a pending verification request
Check failure on line 26 in src/hooks/useUserTimezone.ts GitHub Actions / Jest (1)<UserInfo /> › with a room › renders user info
Check failure on line 26 in src/hooks/useUserTimezone.ts GitHub Actions / Jest (1)<UserInfo /> › with a room › does not render space header when room is not a space room
|
||
console.warn("Unable to determine if extended profiles are supported", ex); | ||
}); | ||
}, [supported]); | ||
|
||
useEffect(() => { | ||
return () => { | ||
if (updateInterval) { | ||
clearInterval(updateInterval); | ||
} | ||
} | ||
}, [updateInterval]); | ||
|
||
useEffect(() => { | ||
if (supported !== true) { | ||
return; | ||
} | ||
(async () => { | ||
try { | ||
const tz = await cli.getExtendedProfileProperty(userId, 'us.cloke.msc4175.tz'); | ||
if (typeof tz !== "string") { | ||
// Err, definitely not a tz. | ||
throw Error('Timezone value was not a string'); | ||
} | ||
// This will validate the timezone for us. | ||
Intl.DateTimeFormat(undefined, {timeZone: tz}); | ||
|
||
const updateTime = () => { | ||
const currentTime = new Date(); | ||
const friendly = currentTime.toLocaleString(undefined, { timeZone: tz, hour12: true, hour: "2-digit", minute: "2-digit", timeZoneName: "shortOffset"}); | ||
setTimezone(tz); | ||
setFriendly(friendly); | ||
setUpdateInterval(setTimeout(updateTime, (60 - currentTime.getSeconds()) * 1000)); | ||
} | ||
updateTime(); | ||
} catch (ex) { | ||
setTimezone(undefined); | ||
setFriendly(undefined); | ||
setUpdateInterval(undefined); | ||
if (ex instanceof MatrixError && ex.errcode === "M_NOT_FOUND") { | ||
// No timezone set, ignore. | ||
return; | ||
} | ||
console.error('Could not render current timezone for user', ex); | ||
} | ||
})(); | ||
}, [supported, userId]); | ||
|
||
if (!timezone || !friendly) { | ||
return null; | ||
} | ||
|
||
return { | ||
friendly, | ||
timezone | ||
}; | ||
} |