Add screensharing behind a feature flag
This commit is contained in:
parent
7c7f7ee5a0
commit
ceffc2380c
49 changed files with 2044 additions and 164 deletions
137
ts/components/CallingSelectPresentingSourcesModal.tsx
Normal file
137
ts/components/CallingSelectPresentingSourcesModal.tsx
Normal file
|
@ -0,0 +1,137 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { groupBy } from 'lodash';
|
||||
import { Button, ButtonVariant } from './Button';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Modal } from './Modal';
|
||||
import { PresentedSource, PresentableSource } from '../types/Calling';
|
||||
import { Theme } from '../util/theme';
|
||||
|
||||
export type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
presentingSourcesAvailable: Array<PresentableSource>;
|
||||
setPresenting: (_?: PresentedSource) => void;
|
||||
};
|
||||
|
||||
const Source = ({
|
||||
onSourceClick,
|
||||
source,
|
||||
sourceToPresent,
|
||||
}: {
|
||||
onSourceClick: (source: PresentedSource) => void;
|
||||
source: PresentableSource;
|
||||
sourceToPresent?: PresentedSource;
|
||||
}): JSX.Element => {
|
||||
return (
|
||||
<button
|
||||
className={classNames({
|
||||
'module-CallingSelectPresentingSourcesModal__source': true,
|
||||
'module-CallingSelectPresentingSourcesModal__source--selected':
|
||||
sourceToPresent?.id === source.id,
|
||||
})}
|
||||
key={source.id}
|
||||
onClick={() => {
|
||||
onSourceClick({
|
||||
id: source.id,
|
||||
name: source.name,
|
||||
});
|
||||
}}
|
||||
type="button"
|
||||
>
|
||||
<img
|
||||
alt={source.name}
|
||||
className="module-CallingSelectPresentingSourcesModal__name--screenshot"
|
||||
src={source.thumbnail}
|
||||
/>
|
||||
<div className="module-CallingSelectPresentingSourcesModal__name--container">
|
||||
{source.appIcon ? (
|
||||
<img
|
||||
alt={source.name}
|
||||
className="module-CallingSelectPresentingSourcesModal__name--icon"
|
||||
height={16}
|
||||
src={source.appIcon}
|
||||
width={16}
|
||||
/>
|
||||
) : null}
|
||||
<span className="module-CallingSelectPresentingSourcesModal__name--text">
|
||||
{source.name}
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
export const CallingSelectPresentingSourcesModal = ({
|
||||
i18n,
|
||||
presentingSourcesAvailable,
|
||||
setPresenting,
|
||||
}: PropsType): JSX.Element | null => {
|
||||
const [sourceToPresent, setSourceToPresent] = useState<
|
||||
PresentedSource | undefined
|
||||
>(undefined);
|
||||
|
||||
if (!presentingSourcesAvailable.length) {
|
||||
throw new Error('No sources available for presenting');
|
||||
}
|
||||
|
||||
const sources = groupBy(presentingSourcesAvailable, source =>
|
||||
source.id.startsWith('screen')
|
||||
);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
hasXButton
|
||||
i18n={i18n}
|
||||
moduleClassName="module-CallingSelectPresentingSourcesModal"
|
||||
onClose={() => {
|
||||
setPresenting(sourceToPresent);
|
||||
}}
|
||||
theme={Theme.Dark}
|
||||
title={i18n('calling__SelectPresentingSourcesModal--title')}
|
||||
>
|
||||
<div className="module-CallingSelectPresentingSourcesModal__title">
|
||||
{i18n('calling__SelectPresentingSourcesModal--entireScreen')}
|
||||
</div>
|
||||
<div className="module-CallingSelectPresentingSourcesModal__sources">
|
||||
{sources.true.map(source => (
|
||||
<Source
|
||||
key={source.id}
|
||||
onSourceClick={selectedSource => setSourceToPresent(selectedSource)}
|
||||
source={source}
|
||||
sourceToPresent={sourceToPresent}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<div className="module-CallingSelectPresentingSourcesModal__title">
|
||||
{i18n('calling__SelectPresentingSourcesModal--window')}
|
||||
</div>
|
||||
<div className="module-CallingSelectPresentingSourcesModal__sources">
|
||||
{sources.false.map(source => (
|
||||
<Source
|
||||
key={source.id}
|
||||
onSourceClick={selectedSource => setSourceToPresent(selectedSource)}
|
||||
source={source}
|
||||
sourceToPresent={sourceToPresent}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<Modal.Footer moduleClassName="module-CallingSelectPresentingSourcesModal">
|
||||
<Button
|
||||
onClick={() => setPresenting()}
|
||||
variant={ButtonVariant.Secondary}
|
||||
>
|
||||
{i18n('cancel')}
|
||||
</Button>
|
||||
<Button
|
||||
disabled={!sourceToPresent}
|
||||
onClick={() => setPresenting(sourceToPresent)}
|
||||
>
|
||||
{i18n('calling__SelectPresentingSourcesModal--confirm')}
|
||||
</Button>
|
||||
</Modal.Footer>
|
||||
</Modal>
|
||||
);
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue