Merge pull request #493 from vector-im/SimonBrandner/feat/volume-design
This commit is contained in:
commit
3de8f9077d
14 changed files with 132 additions and 29 deletions
|
|
@ -20,7 +20,7 @@ import classNames from "classnames";
|
|||
import styles from "./VideoTile.module.css";
|
||||
import { ReactComponent as MicMutedIcon } from "../icons/MicMuted.svg";
|
||||
import { ReactComponent as VideoMutedIcon } from "../icons/VideoMuted.svg";
|
||||
import { OptionsButton } from "../button/Button";
|
||||
import { AudioButton } from "../button/Button";
|
||||
|
||||
export const VideoTile = forwardRef(
|
||||
(
|
||||
|
|
@ -38,6 +38,7 @@ export const VideoTile = forwardRef(
|
|||
mediaRef,
|
||||
onOptionsPress,
|
||||
showOptions,
|
||||
localVolume,
|
||||
...rest
|
||||
},
|
||||
ref
|
||||
|
|
@ -53,6 +54,15 @@ export const VideoTile = forwardRef(
|
|||
ref={ref}
|
||||
{...rest}
|
||||
>
|
||||
{showOptions && (
|
||||
<div className={classNames(styles.toolbar)}>
|
||||
<AudioButton
|
||||
className={styles.button}
|
||||
volume={localVolume}
|
||||
onPress={onOptionsPress}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{(videoMuted || noVideo) && (
|
||||
<>
|
||||
<div className={styles.videoMutedOverlay} />
|
||||
|
|
@ -72,11 +82,7 @@ export const VideoTile = forwardRef(
|
|||
</div>
|
||||
)
|
||||
)}
|
||||
{showOptions && (
|
||||
<div className={classNames(styles.infoBubble, styles.optionsButton)}>
|
||||
<OptionsButton onPress={onOptionsPress} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
<video ref={mediaRef} playsInline disablePictureInPicture />
|
||||
</animated.div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -48,8 +48,8 @@
|
|||
position: absolute;
|
||||
height: 24px;
|
||||
padding: 0 8px;
|
||||
color: white;
|
||||
background-color: rgba(23, 25, 28, 0.85);
|
||||
color: var(--primary-content);
|
||||
background-color: var(--background-85);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
|
@ -60,14 +60,40 @@
|
|||
z-index: 1;
|
||||
}
|
||||
|
||||
.optionsButton {
|
||||
right: 16px;
|
||||
top: 16px;
|
||||
.toolbar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
width: 100%;
|
||||
height: 42px;
|
||||
|
||||
color: var(--primary-content);
|
||||
background-color: var(--background-85);
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
|
||||
overflow: hidden;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.optionsButton button svg {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
.videoTile:not(.isLocal):not(:hover) .toolbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.videoTile:not(.isLocal):hover .presenterLabel {
|
||||
top: calc(42px + 20px); /* toolbar + margin */
|
||||
}
|
||||
|
||||
.button {
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.button svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.memberName {
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ export function VideoTileContainer({
|
|||
avatar={getAvatar && getAvatar(member, width, height)}
|
||||
onOptionsPress={onOptionsPress}
|
||||
showOptions={!item.callFeed.isLocal()}
|
||||
localVolume={localVolume}
|
||||
{...rest}
|
||||
/>
|
||||
{videoTileSettingsModalState.isOpen && (
|
||||
|
|
|
|||
|
|
@ -1,5 +1,16 @@
|
|||
.videoTileSettingsModal {
|
||||
width: 700px;
|
||||
height: 316px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
margin: 27px 34px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.localVolumePercentage {
|
||||
|
|
|
|||
|
|
@ -17,10 +17,10 @@ limitations under the License.
|
|||
import React, { ChangeEvent, useState } from "react";
|
||||
import { CallFeed } from "matrix-js-sdk/src/webrtc/callFeed";
|
||||
|
||||
import selectInputStyles from "../input/SelectInput.module.css";
|
||||
import { FieldRow } from "../input/Input";
|
||||
import { Modal } from "../Modal";
|
||||
import styles from "./VideoTileSettingsModal.module.css";
|
||||
import { VolumeIcon } from "../button/VolumeIcon";
|
||||
|
||||
interface LocalVolumeProps {
|
||||
feed: CallFeed;
|
||||
|
|
@ -39,11 +39,8 @@ const LocalVolume: React.FC<LocalVolumeProps> = ({
|
|||
|
||||
return (
|
||||
<>
|
||||
<h4 className={selectInputStyles.label}> Local Volume </h4>
|
||||
<FieldRow>
|
||||
<span className={styles.localVolumePercentage}>
|
||||
{`${Math.round(localVolume * 100)}%`}
|
||||
</span>
|
||||
<VolumeIcon volume={localVolume} />
|
||||
<input
|
||||
className={styles.localVolumeSlider}
|
||||
type="range"
|
||||
|
|
@ -65,7 +62,13 @@ interface Props {
|
|||
|
||||
export const VideoTileSettingsModal = ({ feed, ...rest }: Props) => {
|
||||
return (
|
||||
<Modal title="Feed settings" isDismissable mobileFullScreen {...rest}>
|
||||
<Modal
|
||||
className={styles.videoTileSettingsModal}
|
||||
title="Local volume"
|
||||
isDismissable
|
||||
mobileFullScreen
|
||||
{...rest}
|
||||
>
|
||||
<div className={styles.content}>
|
||||
<LocalVolume feed={feed} />
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue