Merge pull request #1706 from warrickct/merge-dialogs

Merge dialogs
pull/1709/head
Audric Ackermann 4 years ago committed by GitHub
commit 6c9aa589dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -418,5 +418,6 @@
"unknownCountry": "Unknown Country", "unknownCountry": "Unknown Country",
"device": "Device", "device": "Device",
"destination": "Destination", "destination": "Destination",
"learnMore": "Learn more" "learnMore": "Learn more",
"playAtCustomSpeed": "Play at $multipler$x speed"
} }

@ -16,7 +16,6 @@ import { SessionWrapperModal } from '../components/session/SessionWrapperModal';
import ip2country from 'ip2country'; import ip2country from 'ip2country';
import countryLookup from 'country-code-lookup'; import countryLookup from 'country-code-lookup';
import { useTheme } from 'styled-components'; import { useTheme } from 'styled-components';
import { useNetwork } from '../hooks/useNetwork';
import { Snode } from '../data/data'; import { Snode } from '../data/data';
import { onionPathModal } from '../state/ducks/modalDialog'; import { onionPathModal } from '../state/ducks/modalDialog';
import { import {
@ -25,6 +24,9 @@ import {
getOnionPathsCount, getOnionPathsCount,
} from '../state/selectors/onions'; } from '../state/selectors/onions';
// tslint:disable-next-line: no-submodule-imports
import useNetworkState from 'react-use/lib/useNetworkState';
export type StatusLightType = { export type StatusLightType = {
glowStartDelay: number; glowStartDelay: number;
glowDuration: number; glowDuration: number;
@ -132,7 +134,7 @@ export const ActionPanelOnionStatusLight = (props: {
const theme = useTheme(); const theme = useTheme();
const onionPathsCount = useSelector(getOnionPathsCount); const onionPathsCount = useSelector(getOnionPathsCount);
const firstPathLength = useSelector(getFirstOnionPathLength); const firstPathLength = useSelector(getFirstOnionPathLength);
const isOnline = useNetwork(); const isOnline = useNetworkState().online;
// Set icon color based on result // Set icon color based on result
const red = theme.colors.destructive; const red = theme.colors.destructive;

@ -1,4 +1,4 @@
import React from 'react'; import React, { createRef, useEffect } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { Avatar, AvatarSize } from '../Avatar'; import { Avatar, AvatarSize } from '../Avatar';
@ -13,9 +13,23 @@ import { Quote } from './Quote';
import H5AudioPlayer from 'react-h5-audio-player'; import H5AudioPlayer from 'react-h5-audio-player';
// import 'react-h5-audio-player/lib/styles.css'; // import 'react-h5-audio-player/lib/styles.css';
const AudioPlayerWithEncryptedFile = (props: { src: string; contentType: string }) => { const AudioPlayerWithEncryptedFile = (props: {
src: string;
contentType: string;
playbackSpeed: number;
}) => {
const theme = useTheme(); const theme = useTheme();
const { urlToLoad } = useEncryptedFileFetch(props.src, props.contentType); const { urlToLoad } = useEncryptedFileFetch(props.src, props.contentType);
const { playbackSpeed } = props;
const player = createRef<H5AudioPlayer>();
useEffect(() => {
// updates playback speed to value selected in context menu
if (player.current?.audio.current?.playbackRate) {
player.current.audio.current.playbackRate = playbackSpeed;
}
}, [playbackSpeed]);
return ( return (
<H5AudioPlayer <H5AudioPlayer
src={urlToLoad} src={urlToLoad}
@ -24,6 +38,7 @@ const AudioPlayerWithEncryptedFile = (props: { src: string; contentType: string
showJumpControls={false} showJumpControls={false}
showDownloadProgress={false} showDownloadProgress={false}
listenInterval={100} listenInterval={100}
ref={player}
customIcons={{ customIcons={{
play: ( play: (
<SessionIcon <SessionIcon
@ -86,6 +101,7 @@ interface State {
expiring: boolean; expiring: boolean;
expired: boolean; expired: boolean;
imageBroken: boolean; imageBroken: boolean;
playbackSpeed: number;
} }
const EXPIRATION_CHECK_MINIMUM = 2000; const EXPIRATION_CHECK_MINIMUM = 2000;
@ -106,11 +122,13 @@ class MessageInner extends React.PureComponent<MessageRegularProps, State> {
this.handleContextMenu = this.handleContextMenu.bind(this); this.handleContextMenu = this.handleContextMenu.bind(this);
this.onAddModerator = this.onAddModerator.bind(this); this.onAddModerator = this.onAddModerator.bind(this);
this.onRemoveFromModerator = this.onRemoveFromModerator.bind(this); this.onRemoveFromModerator = this.onRemoveFromModerator.bind(this);
this.updatePlaybackSpeed = this.updatePlaybackSpeed.bind(this);
this.state = { this.state = {
expiring: false, expiring: false,
expired: false, expired: false,
imageBroken: false, imageBroken: false,
playbackSpeed: 1,
}; };
this.ctxMenuID = `ctx-menu-message-${uuid()}`; this.ctxMenuID = `ctx-menu-message-${uuid()}`;
} }
@ -241,6 +259,7 @@ class MessageInner extends React.PureComponent<MessageRegularProps, State> {
}} }}
> >
<AudioPlayerWithEncryptedFile <AudioPlayerWithEncryptedFile
playbackSpeed={this.state.playbackSpeed}
src={firstAttachment.url} src={firstAttachment.url}
contentType={firstAttachment.contentType} contentType={firstAttachment.contentType}
/> />
@ -608,6 +627,11 @@ class MessageInner extends React.PureComponent<MessageRegularProps, State> {
</Item> </Item>
) : null} ) : null}
{isAudio(attachments) ? (
<Item onClick={this.updatePlaybackSpeed}>
{window.i18n('playAtCustomSpeed', this.state.playbackSpeed === 1 ? 2 : 1)}
</Item>
) : null}
<Item onClick={onCopyText}>{window.i18n('copyMessage')}</Item> <Item onClick={onCopyText}>{window.i18n('copyMessage')}</Item>
<Item onClick={this.onReplyPrivate}>{window.i18n('replyToMessage')}</Item> <Item onClick={this.onReplyPrivate}>{window.i18n('replyToMessage')}</Item>
<Item onClick={onShowDetail}>{window.i18n('moreInformation')}</Item> <Item onClick={onShowDetail}>{window.i18n('moreInformation')}</Item>
@ -848,6 +872,15 @@ class MessageInner extends React.PureComponent<MessageRegularProps, State> {
); );
} }
/**
* Doubles / halves the playback speed based on the current playback speed.
*/
private updatePlaybackSpeed() {
this.setState(prevState => ({
playbackSpeed: prevState.playbackSpeed === 1 ? 2 : 1,
}));
}
private handleContextMenu(e: any) { private handleContextMenu(e: any) {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();

@ -62,11 +62,11 @@ const rotate = keyframes`
* Creates a glow animation made for multiple element sequentially * Creates a glow animation made for multiple element sequentially
*/ */
const glow = (color: string, glowDuration: number, glowStartDelay: number) => { const glow = (color: string, glowDuration: number, glowStartDelay: number) => {
const dropShadowType = `drop-shadow(0px 0px 6px ${color}) `; const dropShadowType = `drop-shadow(0px 0px 4px ${color}) `;
//increase shadow intensity by 3 //increase shadow intensity by 3
const dropShadow = `${dropShadowType.repeat(2)};`; const dropShadow = `${dropShadowType.repeat(1)};`;
// TODO: Decrease dropshadow for last frame
// creating keyframe for sequential animations // creating keyframe for sequential animations
let kf = ''; let kf = '';
for (let i = 0; i <= glowDuration; i++) { for (let i = 0; i <= glowDuration; i++) {
@ -75,10 +75,12 @@ const glow = (color: string, glowDuration: number, glowStartDelay: number) => {
if (i === glowStartDelay) { if (i === glowStartDelay) {
kf += `${percent}% { kf += `${percent}% {
filter: ${dropShadow} filter: ${dropShadow}
transform: scale(1.5);
}`; }`;
} else { } else {
kf += `${percent}% { kf += `${percent}% {
filter: none; filter: none;
transform: scale(0.8);
}`; }`;
} }
} }
@ -92,7 +94,11 @@ const animation = (props: any) => {
`; `;
} else if (props.glowDuration !== undefined && props.glowStartDelay !== undefined) { } else if (props.glowDuration !== undefined && props.glowStartDelay !== undefined) {
return css` return css`
${glow(props.iconColor, props.glowDuration, props.glowStartDelay)} ${2}s ease-in infinite; ${glow(
props.iconColor,
props.glowDuration,
props.glowStartDelay
)} ${props.glowDuration}s ease-in infinite;
`; `;
} else { } else {
return; return;

Loading…
Cancel
Save