Dark theme for calling device selection
This commit is contained in:
		
					parent
					
						
							
								31c2fe56f4
							
						
					
				
			
			
				commit
				
					
						a9367f48f1
					
				
			
		
					 10 changed files with 70 additions and 36 deletions
				
			
		| 
						 | 
				
			
			@ -9714,13 +9714,7 @@ button.module-image__border-overlay:focus {
 | 
			
		|||
.module-calling-device-selection__close-button {
 | 
			
		||||
  @include button-reset;
 | 
			
		||||
 | 
			
		||||
  @include light-theme {
 | 
			
		||||
    @include color-svg('../images/x-shadow-16.svg', $color-gray-75);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @include dark-theme {
 | 
			
		||||
    @include color-svg('../images/x-shadow-16.svg', $color-white);
 | 
			
		||||
  }
 | 
			
		||||
  @include color-svg('../images/x-shadow-16.svg', $color-white);
 | 
			
		||||
 | 
			
		||||
  height: 16px;
 | 
			
		||||
  position: absolute;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,8 @@
 | 
			
		|||
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import classNames from 'classnames';
 | 
			
		||||
import { Tooltip, TooltipPlacement, TooltipTheme } from './Tooltip';
 | 
			
		||||
import { Tooltip, TooltipPlacement } from './Tooltip';
 | 
			
		||||
import { Theme } from '../util/theme';
 | 
			
		||||
import { LocalizerType } from '../types/Util';
 | 
			
		||||
 | 
			
		||||
export enum CallingButtonType {
 | 
			
		||||
| 
						 | 
				
			
			@ -63,7 +64,7 @@ export const CallingButton = ({
 | 
			
		|||
    <Tooltip
 | 
			
		||||
      content={tooltipContent}
 | 
			
		||||
      direction={tooltipDirection}
 | 
			
		||||
      theme={TooltipTheme.Dark}
 | 
			
		||||
      theme={Theme.Dark}
 | 
			
		||||
    >
 | 
			
		||||
      <button
 | 
			
		||||
        aria-label={tooltipContent}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,7 @@ import {
 | 
			
		|||
  ChangeIODevicePayloadType,
 | 
			
		||||
  MediaDeviceSettings,
 | 
			
		||||
} from '../types/Calling';
 | 
			
		||||
import { Theme } from '../util/theme';
 | 
			
		||||
 | 
			
		||||
export type Props = MediaDeviceSettings & {
 | 
			
		||||
  changeIODevice: (payload: ChangeIODevicePayloadType) => void;
 | 
			
		||||
| 
						 | 
				
			
			@ -134,7 +135,12 @@ export const CallingDeviceSelection = ({
 | 
			
		|||
    : undefined;
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <ConfirmationModal actions={[]} i18n={i18n} onClose={toggleSettings}>
 | 
			
		||||
    <ConfirmationModal
 | 
			
		||||
      actions={[]}
 | 
			
		||||
      i18n={i18n}
 | 
			
		||||
      theme={Theme.Dark}
 | 
			
		||||
      onClose={toggleSettings}
 | 
			
		||||
    >
 | 
			
		||||
      <div className="module-calling-device-selection">
 | 
			
		||||
        <button
 | 
			
		||||
          type="button"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,8 @@
 | 
			
		|||
import React from 'react';
 | 
			
		||||
import classNames from 'classnames';
 | 
			
		||||
import { LocalizerType } from '../types/Util';
 | 
			
		||||
import { Tooltip, TooltipTheme } from './Tooltip';
 | 
			
		||||
import { Tooltip } from './Tooltip';
 | 
			
		||||
import { Theme } from '../util/theme';
 | 
			
		||||
 | 
			
		||||
export type PropsType = {
 | 
			
		||||
  canPip?: boolean;
 | 
			
		||||
| 
						 | 
				
			
			@ -43,7 +44,7 @@ export const CallingHeader = ({
 | 
			
		|||
        <div className="module-calling-tools__button">
 | 
			
		||||
          <Tooltip
 | 
			
		||||
            content={i18n('calling__participants', [String(participantCount)])}
 | 
			
		||||
            theme={TooltipTheme.Dark}
 | 
			
		||||
            theme={Theme.Dark}
 | 
			
		||||
          >
 | 
			
		||||
            <button
 | 
			
		||||
              aria-label={i18n('calling__participants', [
 | 
			
		||||
| 
						 | 
				
			
			@ -69,7 +70,7 @@ export const CallingHeader = ({
 | 
			
		|||
      <div className="module-calling-tools__button">
 | 
			
		||||
        <Tooltip
 | 
			
		||||
          content={i18n('callingDeviceSelection__settings')}
 | 
			
		||||
          theme={TooltipTheme.Dark}
 | 
			
		||||
          theme={Theme.Dark}
 | 
			
		||||
        >
 | 
			
		||||
          <button
 | 
			
		||||
            aria-label={i18n('callingDeviceSelection__settings')}
 | 
			
		||||
| 
						 | 
				
			
			@ -81,7 +82,7 @@ export const CallingHeader = ({
 | 
			
		|||
      </div>
 | 
			
		||||
      {canPip && (
 | 
			
		||||
        <div className="module-calling-tools__button">
 | 
			
		||||
          <Tooltip content={i18n('calling__pip--on')} theme={TooltipTheme.Dark}>
 | 
			
		||||
          <Tooltip content={i18n('calling__pip--on')} theme={Theme.Dark}>
 | 
			
		||||
            <button
 | 
			
		||||
              aria-label={i18n('calling__pip--on')}
 | 
			
		||||
              className="module-calling-button__pip"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,22 +2,25 @@
 | 
			
		|||
// SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		||||
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
import classNames from 'classnames';
 | 
			
		||||
import { createPortal } from 'react-dom';
 | 
			
		||||
import {
 | 
			
		||||
  ConfirmationDialog,
 | 
			
		||||
  Props as ConfirmationDialogProps,
 | 
			
		||||
} from './ConfirmationDialog';
 | 
			
		||||
import { LocalizerType } from '../types/Util';
 | 
			
		||||
import { Theme, themeClassName } from '../util/theme';
 | 
			
		||||
 | 
			
		||||
export type OwnProps = {
 | 
			
		||||
  readonly i18n: LocalizerType;
 | 
			
		||||
  readonly onClose: () => unknown;
 | 
			
		||||
  readonly theme?: Theme;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export type Props = OwnProps & ConfirmationDialogProps;
 | 
			
		||||
 | 
			
		||||
export const ConfirmationModal = React.memo(
 | 
			
		||||
  ({ i18n, onClose, children, ...rest }: Props) => {
 | 
			
		||||
  ({ i18n, onClose, theme, children, ...rest }: Props) => {
 | 
			
		||||
    const [root, setRoot] = React.useState<HTMLElement | null>(null);
 | 
			
		||||
 | 
			
		||||
    React.useEffect(() => {
 | 
			
		||||
| 
						 | 
				
			
			@ -69,7 +72,10 @@ export const ConfirmationModal = React.memo(
 | 
			
		|||
      ? createPortal(
 | 
			
		||||
          <div
 | 
			
		||||
            role="presentation"
 | 
			
		||||
            className="module-confirmation-dialog__overlay"
 | 
			
		||||
            className={classNames(
 | 
			
		||||
              'module-confirmation-dialog__overlay',
 | 
			
		||||
              theme ? themeClassName(theme) : undefined
 | 
			
		||||
            )}
 | 
			
		||||
            onClick={handleCancel}
 | 
			
		||||
            onKeyUp={handleKeyCancel}
 | 
			
		||||
          >
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,8 @@
 | 
			
		|||
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { Avatar } from './Avatar';
 | 
			
		||||
import { Tooltip, TooltipTheme } from './Tooltip';
 | 
			
		||||
import { Tooltip } from './Tooltip';
 | 
			
		||||
import { Theme } from '../util/theme';
 | 
			
		||||
import { ContactName } from './conversation/ContactName';
 | 
			
		||||
import { LocalizerType } from '../types/Util';
 | 
			
		||||
import { ColorType } from '../types/Colors';
 | 
			
		||||
| 
						 | 
				
			
			@ -41,7 +42,7 @@ const CallButton = ({
 | 
			
		|||
  tooltipContent,
 | 
			
		||||
}: CallButtonProps): JSX.Element => {
 | 
			
		||||
  return (
 | 
			
		||||
    <Tooltip content={tooltipContent} theme={TooltipTheme.Dark}>
 | 
			
		||||
    <Tooltip content={tooltipContent} theme={Theme.Dark}>
 | 
			
		||||
      <button
 | 
			
		||||
        className={`module-incoming-call__button module-incoming-call__button--${classSuffix}`}
 | 
			
		||||
        onClick={onClick}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,7 +5,8 @@ import * as React from 'react';
 | 
			
		|||
import { storiesOf } from '@storybook/react';
 | 
			
		||||
import { select } from '@storybook/addon-knobs';
 | 
			
		||||
 | 
			
		||||
import { Tooltip, TooltipPlacement, TooltipTheme, PropsType } from './Tooltip';
 | 
			
		||||
import { Tooltip, TooltipPlacement, PropsType } from './Tooltip';
 | 
			
		||||
import { Theme } from '../util/theme';
 | 
			
		||||
 | 
			
		||||
const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
 | 
			
		||||
  content: overrideProps.content || 'Hello World',
 | 
			
		||||
| 
						 | 
				
			
			@ -84,7 +85,7 @@ story.add('Dark Theme', () => (
 | 
			
		|||
  <Tooltip
 | 
			
		||||
    {...createProps({
 | 
			
		||||
      sticky: true,
 | 
			
		||||
      theme: TooltipTheme.Dark,
 | 
			
		||||
      theme: Theme.Dark,
 | 
			
		||||
    })}
 | 
			
		||||
  >
 | 
			
		||||
    {Trigger}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@
 | 
			
		|||
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { Manager, Reference, Popper } from 'react-popper';
 | 
			
		||||
import { Theme, themeClassName } from '../util/theme';
 | 
			
		||||
 | 
			
		||||
export enum TooltipPlacement {
 | 
			
		||||
  Top = 'top',
 | 
			
		||||
| 
						 | 
				
			
			@ -11,17 +12,11 @@ export enum TooltipPlacement {
 | 
			
		|||
  Left = 'left',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export enum TooltipTheme {
 | 
			
		||||
  System = 'system',
 | 
			
		||||
  Light = 'light',
 | 
			
		||||
  Dark = 'dark',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type PropsType = {
 | 
			
		||||
  content: string | JSX.Element;
 | 
			
		||||
  direction?: TooltipPlacement;
 | 
			
		||||
  sticky?: boolean;
 | 
			
		||||
  theme?: TooltipTheme;
 | 
			
		||||
  theme?: Theme;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const Tooltip: React.FC<PropsType> = ({
 | 
			
		||||
| 
						 | 
				
			
			@ -29,19 +24,12 @@ export const Tooltip: React.FC<PropsType> = ({
 | 
			
		|||
  content,
 | 
			
		||||
  direction,
 | 
			
		||||
  sticky,
 | 
			
		||||
  theme = TooltipTheme.System,
 | 
			
		||||
  theme,
 | 
			
		||||
}) => {
 | 
			
		||||
  const isSticky = Boolean(sticky);
 | 
			
		||||
  const [showTooltip, setShowTooltip] = React.useState(isSticky);
 | 
			
		||||
 | 
			
		||||
  let tooltipTheme: string;
 | 
			
		||||
  if (theme === TooltipTheme.Light) {
 | 
			
		||||
    tooltipTheme = 'light-theme';
 | 
			
		||||
  } else if (theme === TooltipTheme.Dark) {
 | 
			
		||||
    tooltipTheme = 'dark-theme';
 | 
			
		||||
  } else {
 | 
			
		||||
    tooltipTheme = '';
 | 
			
		||||
  }
 | 
			
		||||
  const tooltipTheme = theme ? themeClassName(theme) : undefined;
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <Manager>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										16
									
								
								ts/test-both/util/theme_test.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								ts/test-both/util/theme_test.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
// Copyright 2019-2020 Signal Messenger, LLC
 | 
			
		||||
// SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		||||
 | 
			
		||||
import { assert } from 'chai';
 | 
			
		||||
 | 
			
		||||
import { Theme, themeClassName } from '../../util/theme';
 | 
			
		||||
 | 
			
		||||
describe('themeClassName', () => {
 | 
			
		||||
  it('returns "light-theme" when passed a light theme', () => {
 | 
			
		||||
    assert.strictEqual(themeClassName(Theme.Light), 'light-theme');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('returns "dark-theme" when passed a dark theme', () => {
 | 
			
		||||
    assert.strictEqual(themeClassName(Theme.Dark), 'dark-theme');
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										20
									
								
								ts/util/theme.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								ts/util/theme.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,20 @@
 | 
			
		|||
// Copyright 2020 Signal Messenger, LLC
 | 
			
		||||
// SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		||||
 | 
			
		||||
import { missingCaseError } from './missingCaseError';
 | 
			
		||||
 | 
			
		||||
export enum Theme {
 | 
			
		||||
  Light,
 | 
			
		||||
  Dark,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function themeClassName(theme: Theme): string {
 | 
			
		||||
  switch (theme) {
 | 
			
		||||
    case Theme.Light:
 | 
			
		||||
      return 'light-theme';
 | 
			
		||||
    case Theme.Dark:
 | 
			
		||||
      return 'dark-theme';
 | 
			
		||||
    default:
 | 
			
		||||
      throw missingCaseError(theme);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue