Skip to content

Commit

Permalink
Finish high contrast mode
Browse files Browse the repository at this point in the history
  • Loading branch information
narickmann committed Sep 21, 2023
1 parent 5fd8642 commit d7ae6b0
Show file tree
Hide file tree
Showing 17 changed files with 122 additions and 43 deletions.
5 changes: 3 additions & 2 deletions src/layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,10 @@ type OverlayBoxProps = React.PropsWithChildren<{

const OverlayBox: React.FC<OverlayBoxProps> = ({ close, children, maxWidth }) => {
const isLight = useColorScheme().scheme === "light";
const { isHighContrast } = useColorScheme();
const ref = useRef<HTMLDivElement>(null);
useOnOutsideClick(ref, close);
const bg = isLight ? COLORS.neutral05 : COLORS.neutral15;
const bg = (isLight || isHighContrast) ? COLORS.neutral05 : COLORS.neutral15;

return (
<div role="dialog" aria-modal="true" css={{
Expand Down Expand Up @@ -80,7 +81,7 @@ const OverlayBox: React.FC<OverlayBoxProps> = ({ close, children, maxWidth }) =>
flex: "0 1 auto",
minHeight: 0,
maxWidth,
boxShadow: "0 4px 16px var(--shadow-color))",
boxShadow: isHighContrast ? "none" : "0 4px 16px var(--shadow-color))",
[screenWidthAtMost(850)]: {
padding: 24,
paddingLeft: 32,
Expand Down
18 changes: 13 additions & 5 deletions src/shortcuts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,14 @@ type SingleKeyProps = React.PropsWithChildren<{

const SingleKey: React.FC<SingleKeyProps> = ({ large, children }) => {
const isLight = useColorScheme().scheme === "light";
const { scheme, isHighContrast } = useColorScheme();

const bg = match(scheme, {
"light": () => COLORS.neutral05,
"dark": () => COLORS.neutral15,
"light-high-contrast": () => COLORS.neutral05,
"dark-high-contrast": () => COLORS.neutral15,
});

return (
<div css={{
Expand All @@ -186,11 +194,11 @@ const SingleKey: React.FC<SingleKeyProps> = ({ large, children }) => {
height: large ? 36 : 30,
minWidth: large ? 36 : 30,
fontSize: 16,
boxShadow: "0 0 8px var(--shadow-color)",
backgroundColor: large
? (isLight ? COLORS.neutral05 : COLORS.neutral15)
: COLORS.neutral10,
color: (isLight || !large) ? COLORS.neutral80 : COLORS.neutral90,
boxShadow: isHighContrast ? "none" : "0 0 8px var(--shadow-color)",
backgroundColor: large ? bg : COLORS.neutral10,
color: isHighContrast
? COLORS.neutral80
: ((isLight || !large) ? COLORS.neutral80 : COLORS.neutral90),
cursor: "default",
}}>
{children}
Expand Down
10 changes: 8 additions & 2 deletions src/steps/audio-setup/mic-preview.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useEffect, useId, useRef } from "react";
import { useTranslation } from "react-i18next";
import Oscilloscope from "oscilloscope";
import { Spinner } from "@opencast/appkit";
import { Spinner, useColorScheme } from "@opencast/appkit";

import { useDispatch, useStudioState } from "../../studio-state";
import { startAudioCapture, stopAudioCapture } from "../../capturer";
Expand All @@ -15,6 +15,7 @@ import { Select } from "../../ui/Select";
// audio-visualization and a device-selector.
export const MicrophonePreview: React.FC = () => {
const { t } = useTranslation();
const { isHighContrast } = useColorScheme();
const dispatch = useDispatch();
const state = useStudioState();
const { audioStream, audioAllowed, audioUnexpectedEnd } = state;
Expand Down Expand Up @@ -91,7 +92,7 @@ export const MicrophonePreview: React.FC = () => {
maxWidth: 850,
backgroundColor: COLORS.neutral05,
borderRadius: 16,
boxShadow: "0 4px 16px var(--shadow-color)",
boxShadow: isHighContrast ? "none" : "0 4px 16px var(--shadow-color)",
width: "100%",
margin: "0 auto",
padding: 24,
Expand All @@ -112,6 +113,7 @@ type AudioVisualziationProps = {

const AudioVisualziation: React.FC<AudioVisualziationProps> = ({ stream }) => {
const canvasRef = useRef<HTMLCanvasElement>(null);
const { isHighContrast } = useColorScheme();

useEffect(() => {
const canvas = canvasRef.current;
Expand Down Expand Up @@ -144,6 +146,10 @@ const AudioVisualziation: React.FC<AudioVisualziationProps> = ({ stream }) => {
flex: "1 0 70px",
backgroundColor: "rgba(0,0,0,0.8)",
borderRadius: "7px",
...isHighContrast && {
backgroundColor: "rgba(0,0,0,1)",
border: `1px solid ${COLORS.neutral50}`,
},
}}
/>
);
Expand Down
5 changes: 4 additions & 1 deletion src/steps/audio-setup/source-select.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useTranslation } from "react-i18next";
import { FiMic, FiMicOff } from "react-icons/fi";
import { screenWidthAtMost } from "@opencast/appkit";
import { screenWidthAtMost, useColorScheme } from "@opencast/appkit";

import { SourceOptionButton } from "../../ui/SourceOptionButton";
import { SHORTCUTS, useShortcut, useShowAvailableShortcuts } from "../../shortcuts";
Expand All @@ -15,6 +15,7 @@ type Props = {
/** The two large option buttons for "no audio" and "Microphone". */
export const SourceSelection: React.FC<Props> = ({ selectNoAudio, selectMicrophone }) => {
const { t } = useTranslation();
const { isHighContrast } = useColorScheme();
const showShortcuts = useShowAvailableShortcuts();
useShortcut(SHORTCUTS.audioSetup.withAudio, selectMicrophone);
useShortcut(SHORTCUTS.audioSetup.withoutAudio, selectNoAudio);
Expand All @@ -38,12 +39,14 @@ export const SourceSelection: React.FC<Props> = ({ selectNoAudio, selectMicropho
label={t("sources-audio-microphone")}
onClick={selectMicrophone}
shortcut={showShortcuts ? SHORTCUTS.audioSetup.withAudio : undefined}
isHighContrast={isHighContrast}
/>
<SourceOptionButton
icon={<FiMicOff />}
label={t("sources-audio-without-audio")}
onClick={selectNoAudio}
shortcut={showShortcuts ? SHORTCUTS.audioSetup.withoutAudio : undefined}
isHighContrast={isHighContrast}
/>
</div>
);
Expand Down
6 changes: 6 additions & 0 deletions src/steps/elements.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const StepButton: React.FC<StepButtonProps> = ({
const { t } = useTranslation();
const showShortcut = useShowAvailableShortcuts();
const isDark = useColorScheme().scheme === "dark";
const { isHighContrast } = useColorScheme();
const shortcut = match(kind, {
prev: () => SHORTCUTS.general.prev,
next: () => SHORTCUTS.general.next,
Expand Down Expand Up @@ -76,6 +77,11 @@ const StepButton: React.FC<StepButtonProps> = ({
color: danger ? COLORS.danger5 : COLORS.neutral90,
boxShadow: "0 0 8px var(--shadow-color)",
...danger && { backgroundColor: COLORS.danger1 },
...isHighContrast && {
outline: `2px solid ${danger ? COLORS.danger5 : COLORS.accent4}`,
borderColor: "transparent",
boxShadow: "none",
},
},
}}
>
Expand Down
14 changes: 10 additions & 4 deletions src/steps/finish/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useTranslation } from "react-i18next";
import { LuRotateCw } from "react-icons/lu";
import { screenWidthAtMost } from "@opencast/appkit";
import { screenWidthAtMost, useColorScheme } from "@opencast/appkit";

import { useDispatch, useStudioState } from "../../studio-state";
import { StepProps } from "..";
Expand Down Expand Up @@ -101,12 +101,13 @@ type BoxProps = React.PropsWithChildren<{
}>;

const Box: React.FC<BoxProps> = ({ title, children }) => {
const { isHighContrast } = useColorScheme();
return (
<div css={{
maxWidth: 420,
width: "100%",
backgroundColor: COLORS.neutral05,
boxShadow: "0 4px 16px var(--shadow-color)",
boxShadow: isHighContrast ? "none" : "0 4px 16px var(--shadow-color)",
border: `1px solid ${COLORS.neutral15}`,
padding: "24px 32px",
borderRadius: 6,
Expand Down Expand Up @@ -147,7 +148,7 @@ const getReturnTarget = (settings: Settings) => {
return settings.return.target;
};

export const sharedButtonStyle = {
export const sharedButtonStyle = (isHighContrast: boolean) => ({
display: "flex",
alignItems: "center",
padding: "8px 12px",
Expand All @@ -161,14 +162,19 @@ export const sharedButtonStyle = {
backgroundColor: COLORS.accent7,
":hover": {
backgroundColor: COLORS.accent8,
...isHighContrast && {
backgroundColor: COLORS.neutral15,
outline: `2px solid ${COLORS.accent8}`,
color: COLORS.neutral20,
},
},
},
"&[disabled]": {
backgroundColor: COLORS.neutral15,
color: COLORS.neutral70,
},
...focusStyle({ offset: 1 }),
} as const;
}) as const;

/**
* Get file size in human readable format. We use base-1000 XB instead of
Expand Down
4 changes: 3 additions & 1 deletion src/steps/finish/save-locally.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useDispatch, useStudioState } from "../../studio-state";
import { recordingFileName } from "../../util";
import { SHORTCUTS, ShortcutKeys, useShortcut, useShowAvailableShortcuts } from "../../shortcuts";
import { prettyFileSize, sharedButtonStyle } from ".";
import { useColorScheme } from "@opencast/appkit";



Expand All @@ -27,6 +28,7 @@ export const SaveLocally: React.FC = () => {
const { deviceType, mimeType, url, downloaded, media: blob } = recording;
const flavor = deviceType === "desktop" ? t("sources-display") : t("sources-user");
const downloadName = recordingFileName({ mime: mimeType, flavor, title, presenter });
const { isHighContrast } = useColorScheme();

if (!url) {
return null;
Expand Down Expand Up @@ -87,7 +89,7 @@ export const SaveLocally: React.FC = () => {
role="button"
onClick={() => dispatch({ type: "MARK_DOWNLOADED", index: i })}
css={{
...sharedButtonStyle,
...sharedButtonStyle(isHighContrast),
justifyContent: "center",
maxWidth: 260,
margin: "auto",
Expand Down
5 changes: 3 additions & 2 deletions src/steps/finish/upload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { LuCheckCircle2 } from "react-icons/lu";
import { COLORS, focusStyle } from "../../util";
import { FieldError, FieldValues, Path, SubmitHandler, Validate, useForm } from "react-hook-form";
import { FiUpload } from "react-icons/fi";
import { ProtoButton, Spinner, match, notNullish, unreachable } from "@opencast/appkit";
import { ProtoButton, Spinner, match, notNullish, unreachable, useColorScheme } from "@opencast/appkit";
import { ErrorBox } from "../../ui/ErrorBox";
import { prettyFileSize, sharedButtonStyle } from ".";

Expand Down Expand Up @@ -240,6 +240,7 @@ const UploadForm: React.FC<UploadFormProps> = ({ handleUpload }) => {

const totalBytes = recordings.reduce((acc, rec) => acc + rec.media.size, 0);
const uploadSize = prettyFileSize(totalBytes, i18n);
const { isHighContrast } = useColorScheme();


return (
Expand Down Expand Up @@ -315,7 +316,7 @@ const UploadForm: React.FC<UploadFormProps> = ({ handleUpload }) => {
<ProtoButton
type="submit"
css={{
...sharedButtonStyle,
...sharedButtonStyle(isHighContrast),
margin: "0 auto",
marginTop: 24,
}}
Expand Down
12 changes: 9 additions & 3 deletions src/steps/recording/controls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export const RecordingControls: React.FC<Props> = ({
}) => {
const { t } = useTranslation();
const isLight = useColorScheme().scheme === "light";
const { isHighContrast } = useColorScheme();
const fgColor = isLight ? COLORS.neutral05 : COLORS.neutral90;

const { userUnexpectedEnd, displayUnexpectedEnd, audioUnexpectedEnd } = useStudioState();
Expand Down Expand Up @@ -68,6 +69,11 @@ export const RecordingControls: React.FC<Props> = ({
boxShadow: "0 4px 16px rgba(0, 0, 0, 0.2)",
borderRadius: 12,
color: fgColor,
...isHighContrast && {
backgroundColor: COLORS.neutral05,
border: `2px solid ${COLORS.neutral25}`,
boxShadow: "none",
},
}}>
<WithTooltip tooltip={
match(recordingState, {
Expand All @@ -92,12 +98,12 @@ export const RecordingControls: React.FC<Props> = ({
fontSize: 28,
padding: 0,

boxShadow: "0 4px 4px rgba(0, 0, 0, 0.12)",
boxShadow: isHighContrast ? "none" : "0 4px 4px rgba(0, 0, 0, 0.12)",
cursor: "pointer",
color: isLight ? "white" : "#D6D6D6",
color: isHighContrast ? "white" : (isLight ? "white" : "#D6D6D6"),
borderRadius: "50%",
backgroundColor: isLight ? "#E42D43" : "#b8012d",
border: `1px solid ${fgColor}`,
border: `${isHighContrast ? "2px" : "1px"} solid ${fgColor}`,
":hover, :focus-visible": {
backgroundColor: isLight ? "#c40a31" : "#8f0121",
},
Expand Down
4 changes: 3 additions & 1 deletion src/steps/recording/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { COLORS, dimensionsOf } from "../../util";
import { RecordingControls } from "./controls";
import Recorder, { OnStopCallback } from "./recorder";
import { useSettings } from "../../settings";
import { useColorScheme } from "@opencast/appkit";


export type RecordingState = "inactive" | "paused" | "recording";
Expand Down Expand Up @@ -172,6 +173,7 @@ type StreamPreviewProps = {
const StreamPreview: React.FC<StreamPreviewProps> = ({ stream, paused }) => {
const resizeVideoBox = useVideoBoxResize();
const videoRef = useRef<HTMLVideoElement>(null);
const { isHighContrast } = useColorScheme();

useEffect(() => {
const v = videoRef.current;
Expand Down Expand Up @@ -210,7 +212,7 @@ const StreamPreview: React.FC<StreamPreviewProps> = ({ stream, paused }) => {
<div
css={{
position: "relative",
boxShadow: "0 2px 12px rgba(0, 0, 0, 0.35)",
boxShadow: isHighContrast ? "none" : "0 2px 12px rgba(0, 0, 0, 0.35)",
overflow: "hidden",
height: "100%",
}}
Expand Down
Loading

0 comments on commit d7ae6b0

Please sign in to comment.