Hand raise feature (#2542)

* Initial support for Hand Raise feature

Signed-off-by: Milton Moura <miltonmoura@gmail.com>

* Refactored to use reaction and redaction events

Signed-off-by: Milton Moura <miltonmoura@gmail.com>

* Replacing button svg with raised hand emoji

Signed-off-by: Milton Moura <miltonmoura@gmail.com>

* SpotlightTile should not duplicate the raised hand

Signed-off-by: Milton Moura <miltonmoura@gmail.com>

* Update src/room/useRaisedHands.tsx

Element Call recently changed to AGPL-3.0

* Use relations to load existing reactions when joining the call

Signed-off-by: Milton Moura <miltonmoura@gmail.com>

* Links to sha commit of matrix-js-sdk that exposes the call membership event id and refactors some async code

Signed-off-by: Milton Moura <miltonmoura@gmail.com>

* Removing RaiseHand.svg

* Check for reaction & redaction capabilities in widget mode

Signed-off-by: Milton Moura <miltonmoura@gmail.com>

* Fix failing GridTile test

Signed-off-by: Milton Moura <miltonmoura@gmail.com>

* Center align hand raise.

* Add support for displaying the duration of a raised hand.

* Add a sound for when a hand is raised.

* Refactor raised hand indicator and add tests.

* lint

* Refactor into own files.

* Redact the right thing.

* Tidy up useEffect

* Lint tests

* Remove extra layer

* Add better sound. (woosh)

* Add a small mode for spotlight

* Fix timestamp calculation on relaod.

* Fix call border resizing video

* lint

* Fix and update tests

* Allow timer to be configurable.

* Add preferences tab for choosing to enable timer.

* Drop border from raised hand icon

* Handle cases when a new member event happens.

* Prevent infinite loop

* Major refactor to support various state problems.

* Tidy up and finish test rewrites

* Add some explanation comments.

* Even more comments.

* Use proper duration formatter

* Remove rerender

* Fix redactions not working because they pick up events in transit.

* More tidying

* Use deferred value

* linting

* Add tests for cases where we got a reaction from someone else.

* Be even less brittle.

* Transpose border to GridTile.

* lint

---------

Signed-off-by: Milton Moura <miltonmoura@gmail.com>
Co-authored-by: fkwp <fkwp@users.noreply.github.com>
Co-authored-by: Half-Shot <will@half-shot.uk>
Co-authored-by: Will Hunt <github@half-shot.uk>
This commit is contained in:
Milton Moura
2024-11-04 08:54:13 -01:00
committed by GitHub
parent f2ed07c258
commit 1897210a60
24 changed files with 1149 additions and 30 deletions

View File

@@ -0,0 +1,49 @@
/*
Copyright 2022-2024 New Vector Ltd.
SPDX-License-Identifier: AGPL-3.0-only
Please see LICENSE in the repository root for full details.
*/
import { ChangeEvent, FC, useCallback } from "react";
import { useTranslation } from "react-i18next";
import { Text } from "@vector-im/compound-web";
import { FieldRow, InputField } from "../input/Input";
import {
showHandRaisedTimer as showHandRaisedTimerSetting,
useSetting,
} from "./settings";
export const PreferencesSettingsTab: FC = () => {
const { t } = useTranslation();
const [showHandRaisedTimer, setShowHandRaisedTimer] = useSetting(
showHandRaisedTimerSetting,
);
const onChangeSetting = useCallback(
(e: ChangeEvent<HTMLInputElement>) => {
setShowHandRaisedTimer(e.target.checked);
},
[setShowHandRaisedTimer],
);
return (
<div>
<h4>{t("settings.preferences_tab_h4")}</h4>
<Text>{t("settings.preferences_tab_body")}</Text>
<FieldRow>
<InputField
id="showHandRaisedTimer"
label={t("settings.preferences_tab_show_hand_raised_timer_label")}
description={t(
"settings.preferences_tab_show_hand_raised_timer_description",
)}
type="checkbox"
checked={showHandRaisedTimer}
onChange={onChangeSetting}
/>
</FieldRow>
</div>
);
};

View File

@@ -30,11 +30,13 @@ import {
useOptInAnalytics,
} from "./settings";
import { isFirefox } from "../Platform";
import { PreferencesSettingsTab } from "./PreferencesSettingsTab";
type SettingsTab =
| "audio"
| "video"
| "profile"
| "preferences"
| "feedback"
| "more"
| "developer";
@@ -135,6 +137,12 @@ export const SettingsModal: FC<Props> = ({
content: generateDeviceSelection(devices.videoInput, t("common.camera")),
};
const preferencesTab: Tab<SettingsTab> = {
key: "preferences",
name: t("common.preferences"),
content: <PreferencesSettingsTab />,
};
const profileTab: Tab<SettingsTab> = {
key: "profile",
name: t("common.profile"),
@@ -234,7 +242,7 @@ export const SettingsModal: FC<Props> = ({
const tabs = [audioTab, videoTab];
if (widget === null) tabs.push(profileTab);
tabs.push(feedbackTab, moreTab);
tabs.push(preferencesTab, feedbackTab, moreTab);
if (developerSettingsTab) tabs.push(developerTab);
return (

View File

@@ -85,4 +85,9 @@ export const videoInput = new Setting<string | undefined>(
undefined,
);
export const showHandRaisedTimer = new Setting<boolean>(
"hand-raised-show-timer",
false,
);
export const alwaysShowSelf = new Setting<boolean>("always-show-self", true);