mirror of
https://github.com/oxen-io/session-desktop.git
synced 2023-12-14 02:12:57 +01:00
Merge remote-tracking branch 'upstream/clearnet' into fix-onion-path-light-orange
This commit is contained in:
commit
013df7fa2c
|
@ -418,5 +418,6 @@
|
|||
"unknownCountry": "Unknown Country",
|
||||
"device": "Device",
|
||||
"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 countryLookup from 'country-code-lookup';
|
||||
import { useTheme } from 'styled-components';
|
||||
import { useNetwork } from '../hooks/useNetwork';
|
||||
import { Snode } from '../data/data';
|
||||
import { onionPathModal } from '../state/ducks/modalDialog';
|
||||
import {
|
||||
|
@ -25,6 +24,9 @@ import {
|
|||
getOnionPathsCount,
|
||||
} from '../state/selectors/onions';
|
||||
|
||||
// tslint:disable-next-line: no-submodule-imports
|
||||
import useNetworkState from 'react-use/lib/useNetworkState';
|
||||
|
||||
export type StatusLightType = {
|
||||
glowStartDelay: number;
|
||||
glowDuration: number;
|
||||
|
@ -132,7 +134,7 @@ export const ActionPanelOnionStatusLight = (props: {
|
|||
const theme = useTheme();
|
||||
const onionPathsCount = useSelector(getOnionPathsCount);
|
||||
const firstPathLength = useSelector(getFirstOnionPathLength);
|
||||
const isOnline = useNetwork();
|
||||
const isOnline = useNetworkState().online;
|
||||
|
||||
// Set icon color based on result
|
||||
const red = theme.colors.destructive;
|
||||
|
|
54
ts/components/conversation/H5AudioPlayer.tsx
Normal file
54
ts/components/conversation/H5AudioPlayer.tsx
Normal file
|
@ -0,0 +1,54 @@
|
|||
// Audio Player
|
||||
import React, { createRef, useEffect } from 'react';
|
||||
import H5AudioPlayer from 'react-h5-audio-player';
|
||||
import { useTheme } from 'styled-components';
|
||||
import { useEncryptedFileFetch } from '../../hooks/useEncryptedFileFetch';
|
||||
import { SessionIcon, SessionIconSize, SessionIconType } from '../session/icon';
|
||||
|
||||
export const AudioPlayerWithEncryptedFile = (props: {
|
||||
src: string;
|
||||
contentType: string;
|
||||
playbackSpeed: number;
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
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 (
|
||||
<H5AudioPlayer
|
||||
src={urlToLoad}
|
||||
layout="horizontal-reverse"
|
||||
showSkipControls={false}
|
||||
showJumpControls={false}
|
||||
showDownloadProgress={false}
|
||||
listenInterval={100}
|
||||
ref={player}
|
||||
customIcons={{
|
||||
play: (
|
||||
<SessionIcon
|
||||
iconType={SessionIconType.Play}
|
||||
iconSize={SessionIconSize.Small}
|
||||
iconColor={theme.colors.textColorSubtle}
|
||||
theme={theme}
|
||||
/>
|
||||
),
|
||||
pause: (
|
||||
<SessionIcon
|
||||
iconType={SessionIconType.Pause}
|
||||
iconSize={SessionIconSize.Small}
|
||||
iconColor={theme.colors.textColorSubtle}
|
||||
theme={theme}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -9,42 +9,6 @@ import { Image } from './Image';
|
|||
import { ContactName } from './ContactName';
|
||||
import { Quote } from './Quote';
|
||||
|
||||
// Audio Player
|
||||
import H5AudioPlayer from 'react-h5-audio-player';
|
||||
|
||||
const AudioPlayerWithEncryptedFile = (props: { src: string; contentType: string }) => {
|
||||
const theme = useTheme();
|
||||
const { urlToLoad } = useEncryptedFileFetch(props.src, props.contentType);
|
||||
return (
|
||||
<H5AudioPlayer
|
||||
src={urlToLoad}
|
||||
layout="horizontal-reverse"
|
||||
showSkipControls={false}
|
||||
showJumpControls={false}
|
||||
showDownloadProgress={false}
|
||||
listenInterval={100}
|
||||
customIcons={{
|
||||
play: (
|
||||
<SessionIcon
|
||||
iconType={SessionIconType.Play}
|
||||
iconSize={SessionIconSize.Small}
|
||||
iconColor={theme.colors.textColorSubtle}
|
||||
theme={theme}
|
||||
/>
|
||||
),
|
||||
pause: (
|
||||
<SessionIcon
|
||||
iconType={SessionIconType.Pause}
|
||||
iconSize={SessionIconSize.Small}
|
||||
iconColor={theme.colors.textColorSubtle}
|
||||
theme={theme}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
import {
|
||||
canDisplayImage,
|
||||
getExtensionForDisplay,
|
||||
|
@ -61,16 +25,14 @@ import { AttachmentType } from '../../types/Attachment';
|
|||
|
||||
import { getIncrement } from '../../util/timer';
|
||||
import { isFileDangerous } from '../../util/isFileDangerous';
|
||||
import { SessionIcon, SessionIconSize, SessionIconType } from '../session/icon';
|
||||
import _ from 'lodash';
|
||||
import { animation, contextMenu, Item, Menu } from 'react-contexify';
|
||||
import uuid from 'uuid';
|
||||
import { InView } from 'react-intersection-observer';
|
||||
import { useTheme, withTheme } from 'styled-components';
|
||||
import { withTheme } from 'styled-components';
|
||||
import { MessageMetadata } from './message/MessageMetadata';
|
||||
import { PubKey } from '../../session/types';
|
||||
import { MessageRegularProps } from '../../models/messageType';
|
||||
import { useEncryptedFileFetch } from '../../hooks/useEncryptedFileFetch';
|
||||
import {
|
||||
addSenderAsModerator,
|
||||
removeSenderFromModerator,
|
||||
|
@ -78,6 +40,7 @@ import {
|
|||
import { updateUserDetailsModal } from '../../state/ducks/modalDialog';
|
||||
import { MessageInteraction } from '../../interactions';
|
||||
import autoBind from 'auto-bind';
|
||||
import { AudioPlayerWithEncryptedFile } from './H5AudioPlayer';
|
||||
|
||||
// Same as MIN_WIDTH in ImageGrid.tsx
|
||||
const MINIMUM_LINK_PREVIEW_IMAGE_WIDTH = 200;
|
||||
|
@ -86,6 +49,7 @@ interface State {
|
|||
expiring: boolean;
|
||||
expired: boolean;
|
||||
imageBroken: boolean;
|
||||
playbackSpeed: number;
|
||||
}
|
||||
|
||||
const EXPIRATION_CHECK_MINIMUM = 2000;
|
||||
|
@ -98,13 +62,13 @@ class MessageInner extends React.PureComponent<MessageRegularProps, State> {
|
|||
|
||||
public constructor(props: MessageRegularProps) {
|
||||
super(props);
|
||||
|
||||
autoBind(this);
|
||||
|
||||
this.state = {
|
||||
expiring: false,
|
||||
expired: false,
|
||||
imageBroken: false,
|
||||
playbackSpeed: 1,
|
||||
};
|
||||
this.ctxMenuID = `ctx-menu-message-${uuid()}`;
|
||||
}
|
||||
|
@ -235,6 +199,7 @@ class MessageInner extends React.PureComponent<MessageRegularProps, State> {
|
|||
}}
|
||||
>
|
||||
<AudioPlayerWithEncryptedFile
|
||||
playbackSpeed={this.state.playbackSpeed}
|
||||
src={firstAttachment.url}
|
||||
contentType={firstAttachment.contentType}
|
||||
/>
|
||||
|
@ -602,6 +567,11 @@ class MessageInner extends React.PureComponent<MessageRegularProps, State> {
|
|||
</Item>
|
||||
) : null}
|
||||
|
||||
{isAudio(attachments) ? (
|
||||
<Item onClick={this.updatePlaybackSpeed}>
|
||||
{window.i18n('playAtCustomSpeed', this.state.playbackSpeed === 1 ? 2 : 1)}
|
||||
</Item>
|
||||
) : null}
|
||||
<Item
|
||||
onClick={() => {
|
||||
MessageInteraction.copyBodyToClipboard(text);
|
||||
|
@ -848,6 +818,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) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
|
|
@ -62,11 +62,11 @@ const rotate = keyframes`
|
|||
* Creates a glow animation made for multiple element sequentially
|
||||
*/
|
||||
const glow = (color: string, glowDuration: number, glowStartDelay: number) => {
|
||||
const dropShadowType = `drop-shadow(0px 0px 6px ${color}) `;
|
||||
//increase shadow intensity by 3
|
||||
const dropShadow = `${dropShadowType.repeat(2)};`;
|
||||
const dropShadowType = `drop-shadow(0px 0px 4px ${color}) `;
|
||||
|
||||
//increase shadow intensity by 3
|
||||
const dropShadow = `${dropShadowType.repeat(1)};`;
|
||||
|
||||
// TODO: Decrease dropshadow for last frame
|
||||
// creating keyframe for sequential animations
|
||||
let kf = '';
|
||||
for (let i = 0; i <= glowDuration; i++) {
|
||||
|
@ -75,10 +75,12 @@ const glow = (color: string, glowDuration: number, glowStartDelay: number) => {
|
|||
if (i === glowStartDelay) {
|
||||
kf += `${percent}% {
|
||||
filter: ${dropShadow}
|
||||
transform: scale(1.5);
|
||||
}`;
|
||||
} else {
|
||||
kf += `${percent}% {
|
||||
filter: none;
|
||||
transform: scale(0.8);
|
||||
}`;
|
||||
}
|
||||
}
|
||||
|
@ -92,7 +94,11 @@ const animation = (props: any) => {
|
|||
`;
|
||||
} else if (props.glowDuration !== undefined && props.glowStartDelay !== undefined) {
|
||||
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 {
|
||||
return;
|
||||
|
|
Loading…
Reference in a new issue