From 5e1564543660fc5270776bebb1ff6b126bd7afb9 Mon Sep 17 00:00:00 2001 From: Arnei Date: Thu, 27 Jun 2024 16:54:54 +0200 Subject: [PATCH] Make use of ProtoButton from appkit Replaces our home-brewed buttons with the basic ProtoButtons from appkit. There is arguably more work to be done on buttons, but this should serve as a good foundation for such future work. --- src/cssStyles.tsx | 5 +++- src/main/CuttingActions.tsx | 42 ++++++++++---------------- src/main/Discard.tsx | 13 ++++----- src/main/Finish.tsx | 25 ++++++---------- src/main/FinishMenu.tsx | 13 ++++----- src/main/Header.tsx | 4 ++- src/main/MainMenu.tsx | 13 ++++----- src/main/Save.tsx | 13 ++++----- src/main/SubtitleEditor.tsx | 26 +++++++---------- src/main/SubtitleListEditor.tsx | 9 +++--- src/main/SubtitleSelect.tsx | 35 +++++++++------------- src/main/TheEnd.tsx | 13 ++++----- src/main/Thumbnail.tsx | 25 +++++++--------- src/main/TrackSelection.tsx | 21 ++++++------- src/main/VideoControls.tsx | 47 ++++++++++++++---------------- src/main/WorkflowConfiguration.tsx | 13 ++++----- 16 files changed, 135 insertions(+), 182 deletions(-) diff --git a/src/cssStyles.tsx b/src/cssStyles.tsx index a96b39391..397372b28 100644 --- a/src/cssStyles.tsx +++ b/src/cssStyles.tsx @@ -31,6 +31,10 @@ export const globalStyle = (theme: Theme) => css({ // Makes the body span to the bottom of the page minHeight: "100vh", }, + // Some elements not inheriting fonts is a really confusing browser default. + "input, button, textarea, select": { + font: "inherit", + }, }); @@ -43,7 +47,6 @@ export const BREAKPOINT_MEDIUM = 650; */ export const basicButtonStyle = (theme: Theme) => css({ borderRadius: "5px", - cursor: "pointer", "&:hover": { backgroundColor: `${theme.button_color}`, color: `${theme.inverted_text}`, diff --git a/src/main/CuttingActions.tsx b/src/main/CuttingActions.tsx index b2612d70b..81f2922cf 100644 --- a/src/main/CuttingActions.tsx +++ b/src/main/CuttingActions.tsx @@ -30,6 +30,7 @@ import { useTheme } from "../themes"; import { ThemedTooltip } from "./Tooltip"; import { Slider } from "@mui/material"; import { useHotkeys } from "react-hotkeys-hook"; +import { ProtoButton } from "@opencast/appkit"; /** * Defines the different actions a user can perform while in cutting mode @@ -52,7 +53,7 @@ const CuttingActions: React.FC = () => { actionWithPayload?: ActionCreatorWithPayload | undefined, // eslint-disable-next-line @typescript-eslint/no-explicit-any payload?: any, - ref?: React.RefObject + ref?: React.RefObject ) => { if (action) { dispatch(action()); @@ -194,8 +195,6 @@ const CuttingActions: React.FC = () => { */ const cuttingActionButtonStyle = css({ padding: "16px", - // boxShadow: `${theme.boxShadow}`, - // background: `${theme.element_bg}` }); interface cuttingActionsButtonInterface { @@ -206,7 +205,7 @@ interface cuttingActionsButtonInterface { actionWithPayload: ActionCreatorWithPayload | undefined, // eslint-disable-next-line @typescript-eslint/no-explicit-any payload: any, - ref?: React.RefObject, + ref?: React.RefObject, ) => void, action: ActionCreatorWithoutPayload, actionWithPayload: ActionCreatorWithPayload | undefined, @@ -230,24 +229,20 @@ const CuttingActionsButton: React.FC = ({ tooltip, ariaLabelText, }) => { - const ref = React.useRef(null); + const ref = React.useRef(null); const theme = useTheme(); return ( -
actionHandler(action, actionWithPayload, payload, ref)} - onKeyDown={(event: React.KeyboardEvent) => { - if (event.key === " " || event.key === "Enter") { - actionHandler(action, actionWithPayload, payload); - } - }} + css={[basicButtonStyle(theme), cuttingActionButtonStyle]} > {actionName} -
+
); }; @@ -258,7 +253,7 @@ interface markAsDeleteButtonInterface { actionWithPayload: ActionCreatorWithPayload | undefined, // eslint-disable-next-line @typescript-eslint/no-explicit-any payload: any, - ref?: React.RefObject + ref?: React.RefObject ) => void, action: ActionCreatorWithoutPayload, hotKeyName: string, @@ -274,26 +269,21 @@ const MarkAsDeletedButton: React.FC = ({ }) => { const { t } = useTranslation(); const isCurrentSegmentAlive = useAppSelector(selectIsCurrentSegmentAlive); - const ref = React.useRef(null); + const ref = React.useRef(null); const theme = useTheme(); return ( -
actionHandler(action, undefined, undefined, ref)} - onKeyDown={(event: React.KeyboardEvent) => { - if (event.key === " " || event.key === "Enter") { - actionHandler(action, undefined, undefined); - } - }} + css={[basicButtonStyle(theme), cuttingActionButtonStyle]} > {isCurrentSegmentAlive ? : }
{isCurrentSegmentAlive ? t("cuttingActions.delete-button") : t("cuttingActions.restore-button")}
-
+
); }; @@ -304,7 +294,7 @@ interface ZoomSliderInterface { actionWithPayload: ActionCreatorWithPayload | undefined, // eslint-disable-next-line @typescript-eslint/no-explicit-any payload: any, - ref?: React.RefObject, + ref?: React.RefObject, ) => void, tooltip: string, ariaLabelText: string, diff --git a/src/main/Discard.tsx b/src/main/Discard.tsx index 168f59796..e6c51e1c5 100644 --- a/src/main/Discard.tsx +++ b/src/main/Discard.tsx @@ -13,6 +13,7 @@ import { PageButton } from "./Finish"; import { useTranslation } from "react-i18next"; import { useTheme } from "../themes"; +import { ProtoButton } from "@opencast/appkit"; /** * Shown if the user wishes to abort. @@ -61,17 +62,13 @@ const DiscardButton: React.FC = () => { }; return ( -
) => { - if (event.key === " " || event.key === "Enter") { - discard(); - } - }}> + css={[basicButtonStyle(theme), navigationButtonStyle(theme)]} + > {t("discard.confirm-button")} -
+ ); }; diff --git a/src/main/Finish.tsx b/src/main/Finish.tsx index 2905ad76a..cf38e19ca 100644 --- a/src/main/Finish.tsx +++ b/src/main/Finish.tsx @@ -18,6 +18,7 @@ import { selectPageNumber, setPageNumber } from "../redux/finishSlice"; import { useTheme } from "../themes"; import { settings } from "../config"; import { useTranslation } from "react-i18next"; +import { ProtoButton } from "@opencast/appkit"; /** * Displays a menu for selecting what should be done with the current changes @@ -86,17 +87,13 @@ export const PageButton: React.FC<{ }); return ( -
) => { - if (event.key === " " || event.key === "Enter") { - onPageChange(); - } - }}> + css={[basicButtonStyle(theme), pageButtonStyle]} + > {label} -
+ ); }; @@ -116,14 +113,10 @@ export const CallbackButton: React.FC = () => { return ( <> {settings.callbackUrl !== undefined && -
) => { - if (event.key === " " || event.key === "Enter") { - openCallbackUrl(); - } - }}> + css={[basicButtonStyle(theme), navigationButtonStyle(theme)]} + > {settings.callbackSystem ? @@ -131,7 +124,7 @@ export const CallbackButton: React.FC = () => { t("various.callback-button-generic") } -
+ } ); diff --git a/src/main/FinishMenu.tsx b/src/main/FinishMenu.tsx index e350e91be..fa8961566 100644 --- a/src/main/FinishMenu.tsx +++ b/src/main/FinishMenu.tsx @@ -11,6 +11,7 @@ import { setState, setPageNumber, finish } from "../redux/finishSlice"; import { useTranslation } from "react-i18next"; import { useTheme } from "../themes"; +import { ProtoButton } from "@opencast/appkit"; /** * Displays a menu for selecting what should be done with the current changes @@ -81,19 +82,15 @@ const FinishMenuButton: React.FC<{ Icon: IconType, stateName: finish["value"]; } }); return ( -
) => { - if (event.key === " " || event.key === "Enter") { - finish(); - } - }}> + css={[basicButtonStyle(theme), tileButtonStyle(theme)]} + >
{buttonString}
-
+ ); }; diff --git a/src/main/Header.tsx b/src/main/Header.tsx index c87811a9b..4ffac00b9 100644 --- a/src/main/Header.tsx +++ b/src/main/Header.tsx @@ -247,7 +247,9 @@ const HeaderButton = React.forwardRef( }); return ( - diff --git a/src/main/MainMenu.tsx b/src/main/MainMenu.tsx index dcbd193b2..3f8daece7 100644 --- a/src/main/MainMenu.tsx +++ b/src/main/MainMenu.tsx @@ -22,6 +22,7 @@ import { resetPostRequestState } from "../redux/workflowPostSlice"; import { setIsDisplayEditView } from "../redux/subtitleSlice"; import { useTheme } from "../themes"; +import { ProtoButton } from "@opencast/appkit"; /** * A container for selecting the functionality shown in the main part of the app @@ -147,15 +148,11 @@ export const MainMenuButton: React.FC = ({ }); return ( -
  • ) => { - if (event.key === "Enter") { - onMenuItemClicked(); - } - }} + css={[basicButtonStyle(theme), customCSS ? customCSS : mainMenuButtonStyle]} > = ({ height: "auto", }} /> {bottomText &&
    {bottomText}
    } -
  • +
    ); }; diff --git a/src/main/Save.tsx b/src/main/Save.tsx index cc78e929b..09a7b9ef2 100644 --- a/src/main/Save.tsx +++ b/src/main/Save.tsx @@ -32,6 +32,7 @@ import { import { serializeSubtitle } from "../util/utilityFunctions"; import { useTheme } from "../themes"; import { ThemedTooltip } from "./Tooltip"; +import { ProtoButton } from "@opencast/appkit"; /** * Shown if the user wishes to save. @@ -193,18 +194,14 @@ export const SaveButton: React.FC = () => { return ( -
    ) => { - if (event.key === " " || event.key === "Enter") { - save(); - } - }}> + css={[basicButtonStyle(theme), navigationButtonStyle(theme)]} + > {t("save.confirm-button")}
    {ariaSaveUpdate()}
    -
    +
    ); }; diff --git a/src/main/SubtitleEditor.tsx b/src/main/SubtitleEditor.tsx index aa3be72d8..f3dff94c9 100644 --- a/src/main/SubtitleEditor.tsx +++ b/src/main/SubtitleEditor.tsx @@ -21,7 +21,7 @@ import { parseSubtitle, serializeSubtitle } from "../util/utilityFunctions"; import { ThemedTooltip } from "./Tooltip"; import { titleStyle, titleStyleBold } from "../cssStyles"; import { generateButtonTitle } from "./SubtitleSelect"; -import { ConfirmationModal, ConfirmationModalHandle, Modal, ModalHandle } from "@opencast/appkit"; +import { ConfirmationModal, ConfirmationModalHandle, Modal, ModalHandle, ProtoButton } from "@opencast/appkit"; /** * Displays an editor view for a selected subtitle file @@ -194,13 +194,13 @@ const DownloadButton: React.FC = () => { return ( -
    downloadSubtitles()} + css={[basicButtonStyle(theme), subtitleButtonStyle(theme)]} > {t("subtitles.downloadButton-title")} -
    +
    ); }; @@ -267,13 +267,13 @@ const UploadButton: React.FC<{ return ( <> -
    modalRef.current?.open()} + css={[basicButtonStyle(theme), subtitleButtonStyle(theme)]} > {t("subtitles.uploadButton-title")} -
    +
    {/* Hidden input field for upload */} { return ( -
    dispatch(setIsDisplayEditView(false))} - onKeyDown={(event: React.KeyboardEvent) => { - if (event.key === " " || event.key === "Enter") { - dispatch(setIsDisplayEditView(false)); - } - }}> + css={[basicButtonStyle(theme), subtitleButtonStyle(theme)]} + > {t("subtitles.backButton")} -
    +
    ); }; diff --git a/src/main/SubtitleListEditor.tsx b/src/main/SubtitleListEditor.tsx index 84caabb1c..942e68dea 100644 --- a/src/main/SubtitleListEditor.tsx +++ b/src/main/SubtitleListEditor.tsx @@ -32,7 +32,7 @@ import AutoSizer from "react-virtualized-auto-sizer"; import { useTheme } from "../themes"; import { ThemedTooltip } from "./Tooltip"; import { useHotkeys } from "react-hotkeys-hook"; -import { useColorScheme } from "@opencast/appkit"; +import { ProtoButton, useColorScheme } from "@opencast/appkit"; /** * Displays everything needed to edit subtitles @@ -482,15 +482,14 @@ const FunctionButton: React.FC<{ return ( -
    -
    +
    ); }; diff --git a/src/main/SubtitleSelect.tsx b/src/main/SubtitleSelect.tsx index c415a8670..115e9f6f7 100644 --- a/src/main/SubtitleSelect.tsx +++ b/src/main/SubtitleSelect.tsx @@ -22,6 +22,7 @@ import { ThemedTooltip } from "./Tooltip"; import { languageCodeToName } from "../util/utilityFunctions"; import { v4 as uuidv4 } from "uuid"; import { TFunction } from "i18next"; +import { ProtoButton } from "@opencast/appkit"; /** * Displays buttons that allow the user to select the subtitle they want to edit @@ -153,6 +154,11 @@ const SubtitleSelectButton: React.FC<{ const theme = useTheme(); const dispatch = useAppDispatch(); + const onClickHandler = () => { + dispatch(setIsDisplayEditView(true)); + dispatch(setSelectedSubtitleId(id)); + }; + const flagStyle = css({ fontSize: "2.5em", overflow: "hidden", @@ -175,22 +181,14 @@ const SubtitleSelectButton: React.FC<{ return ( -
    { - dispatch(setIsDisplayEditView(true)); - dispatch(setSelectedSubtitleId(id)); - }} - onKeyDown={(event: React.KeyboardEvent) => { - if (event.key === " " || event.key === "Enter") { - dispatch(setIsDisplayEditView(true)); - dispatch(setSelectedSubtitleId(id)); - } - }}> + onClick={onClickHandler} + css={[basicButtonStyle(theme), tileButtonStyle(theme)]} + > {icon &&
    {icon}
    }
    {title ?? t("subtitles.generic") + " " + id}
    -
    +
    ); }; @@ -270,16 +268,11 @@ const SubtitleAddButton: React.FC<{ return ( -
    setIsPlusDisplay(false)} - onKeyDown={(event: React.KeyboardEvent) => { - if (event.key === " " || event.key === "Enter") { - setIsPlusDisplay(false); - } - }} + css={[basicButtonStyle(theme), tileButtonStyle(theme), !isPlusDisplay && disableButtonAnimation]} >
    )} /> -
    +
    ); }; diff --git a/src/main/TheEnd.tsx b/src/main/TheEnd.tsx index a8ab3e204..e5568534c 100644 --- a/src/main/TheEnd.tsx +++ b/src/main/TheEnd.tsx @@ -12,6 +12,7 @@ import { useTranslation } from "react-i18next"; import { useTheme } from "../themes"; import { ThemedTooltip } from "./Tooltip"; import { CallbackButton } from "./Finish"; +import { ProtoButton } from "@opencast/appkit"; /** * This page is to be displayed when the user is "done" with the editor @@ -72,16 +73,12 @@ const StartOverButton: React.FC = () => { return ( -
    ) => { - if (event.key === " " || event.key === "Enter") { - reloadPage(); - } - }}> + css={[basicButtonStyle(theme), navigationButtonStyle(theme)]} + > {t("theEnd.startOver-button")} -
    +
    ); }; diff --git a/src/main/Thumbnail.tsx b/src/main/Thumbnail.tsx index 7d2d5c710..d4c5e2ce0 100644 --- a/src/main/Thumbnail.tsx +++ b/src/main/Thumbnail.tsx @@ -38,6 +38,7 @@ import { import { ThemedTooltip } from "./Tooltip"; import VideoPlayers, { VideoPlayerForwardRef } from "./VideoPlayers"; import VideoControls from "./VideoControls"; +import { ProtoButton } from "@opencast/appkit"; /** @@ -434,7 +435,7 @@ const ThumbnailButton: React.FC<{ active: boolean, }> = ({ handler, text, tooltipText, ariaLabel, Icon, active }) => { const theme = useTheme(); - const ref = React.useRef(null); + const ref = React.useRef(null); const clickHandler = () => { if (active) { handler(); } @@ -448,16 +449,16 @@ const ThumbnailButton: React.FC<{ return ( -
    {text} -
    +
    ); }; @@ -501,20 +502,16 @@ const AffectAllRow: React.FC<{ return (
    -
    { generateAll(); }} - onKeyDown={(event: React.KeyboardEvent) => { - if (event.key === " " || event.key === "Enter") { - generateAll(); - } - }} + css={[basicButtonStyle(theme), buttonStyle]} > {t("thumbnail.buttonGenerateAll")} -
    +
    ); diff --git a/src/main/TrackSelection.tsx b/src/main/TrackSelection.tsx index d26985f0c..76458caa6 100644 --- a/src/main/TrackSelection.tsx +++ b/src/main/TrackSelection.tsx @@ -19,8 +19,9 @@ import { } from "../cssStyles"; import { useTranslation } from "react-i18next"; -import { useTheme } from "../themes"; +import { Theme, useTheme } from "../themes"; import { ThemedTooltip } from "./Tooltip"; +import { ProtoButton } from "@opencast/appkit"; /** * Creates the track selection. @@ -189,7 +190,7 @@ const SelectButton: React.FC = ({ handler, text, Icon, to const theme = useTheme(); - const buttonStyle = [ + const buttonStyle = (theme: Theme) => [ active ? basicButtonStyle(theme) : deactivatedButtonStyle, { padding: "16px", @@ -197,7 +198,8 @@ const SelectButton: React.FC = ({ handler, text, Icon, to boxShadow: "", background: `${theme.element_bg}`, textWrap: "nowrap", - }]; + }, + ]; const clickHandler = () => { if (active) { handler(); } @@ -214,17 +216,16 @@ const SelectButton: React.FC = ({ handler, text, Icon, to return ( -
    + onKeyDown={keyHandler} + css={buttonStyle(theme)} + > {text} -
    +
    ); }; diff --git a/src/main/VideoControls.tsx b/src/main/VideoControls.tsx index c5c2c70ec..9051686d4 100644 --- a/src/main/VideoControls.tsx +++ b/src/main/VideoControls.tsx @@ -23,6 +23,7 @@ import { ThemedTooltip } from "./Tooltip"; import { Theme, useTheme } from "../themes"; import { useHotkeys } from "react-hotkeys-hook"; import { Slider } from "@mui/material"; +import { ProtoButton } from "@opencast/appkit"; /** * Contains controls for manipulating multiple video players at once @@ -231,19 +232,15 @@ const PlayButton: React.FC<{ return ( -
    -
    { switchIsPlaying(); }} - onKeyDown={(event: React.KeyboardEvent) => { - if (event.key === "Enter") { // "Space" is handled by global key - switchIsPlaying(); - } - }}> - {isPlaying ? : } -
    -
    + { switchIsPlaying(); }} + css={[basicButtonStyle(theme), playButtonStyle]} + > + {isPlaying ? : } +
    ); }; @@ -316,17 +313,14 @@ const NextButton: React.FC<{ return ( -
    { - if (event.key === "Enter") { - jumpToNext(); - } - }}> + css={[basicButtonStyle(theme)]} + > -
    +
    ); }; @@ -452,12 +446,15 @@ const VolumeSlider: React.FC<{ return (
    -
    + aria-pressed={isMuted} + aria-hidden={false} + onClick={switchIsMuted} + css={[basicButtonStyle(theme)]} + > {isMuted ? : } -
    +
    = ({ text }) => { }); return ( -
    ) => { - if (event.key === " " || event.key === "Enter") { - saveAndProcess(); - } - }}> + css={[basicButtonStyle(theme), saveButtonStyle]} + > {text} -
    + ); };