Merge pull request #39 from yougotwill/feat/ses-912/react18_and_framer_motion

Feat/ses 912/react18 and framer motion
pull/3056/head
Will G 1 year ago committed by GitHub
commit fd0a23c5c0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -16,7 +16,7 @@ module.exports = {
'airbnb-base',
'prettier',
'plugin:@typescript-eslint/recommended',
'plugin:react/recommended',
'plugin:react/jsx-runtime',
'plugin:react-hooks/recommended',
'plugin:import/recommended',
'plugin:import/typescript',

@ -9,9 +9,6 @@ const config = url.parse(window.location.toString(), true).query;
const { locale } = config;
const localeMessages = ipcRenderer.sendSync('locale-data');
window.React = require('react');
window.ReactDOM = require('react-dom');
window.theme = config.theme;
window.i18n = i18n.setupi18n(locale, localeMessages);

@ -14,9 +14,6 @@ const localeMessages = ipcRenderer.sendSync('locale-data');
window._ = require('lodash');
window.React = require('react');
window.ReactDOM = require('react-dom');
window.getVersion = () => config.version;
window.theme = config.theme;
window.i18n = i18n.setupi18n(locale, localeMessages);

@ -22,8 +22,8 @@
"lodash": "^4.17.20",
"ini": "^1.3.6",
"ejs": "^3.1.7",
"react": "17.0.2",
"@types/react": "17.0.2",
"react": "18.2.0",
"@types/react": "18.2.55",
"glob-parent": "^6.0.1",
"got": "^11.8.5",
"jpeg-js": "^0.4.4",
@ -92,6 +92,7 @@
"emoji-mart": "^5.5.2",
"filesize": "3.6.1",
"firstline": "1.2.1",
"framer-motion": "^11.0.3",
"fs-extra": "9.0.0",
"glob": "7.1.2",
"image-type": "^4.1.0",
@ -109,9 +110,9 @@
"pify": "3.0.0",
"protobufjs": "^7.2.4",
"rc-slider": "^10.2.1",
"react": "^17.0.2",
"react": "^18.2.0",
"react-contexify": "^6.0.0",
"react-dom": "^17.0.2",
"react-dom": "^18.2.0",
"react-draggable": "^4.4.4",
"react-h5-audio-player": "^3.2.0",
"react-intersection-observer": "^9.7.0",
@ -158,8 +159,8 @@
"@types/mocha": "5.0.0",
"@types/node-fetch": "^2.5.7",
"@types/pify": "3.0.2",
"@types/react": "^17.0.2",
"@types/react-dom": "^17.0.2",
"@types/react": "^18.2.55",
"@types/react-dom": "^18.2.19",
"@types/react-redux": "^7.1.24",
"@types/react-virtualized": "9.18.12",
"@types/redux-logger": "3.0.7",
@ -185,7 +186,7 @@
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-mocha": "^10.1.0",
"eslint-plugin-more": "^1.0.5",
"eslint-plugin-react": "^7.33.0",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"events": "^3.3.0",
"husky": "^8.0.0",

@ -9,9 +9,6 @@ const config = url.parse(window.location.toString(), true).query;
const { locale } = config;
const localeMessages = ipcRenderer.sendSync('locale-data');
window.React = require('react');
window.ReactDOM = require('react-dom');
// If the app is locked we can't access the database to check the theme.
window.theme = 'classic-dark';
window.primaryColor = 'green';

@ -243,9 +243,6 @@ setInterval(() => {
window.nodeSetImmediate(() => {});
}, 1000);
window.React = require('react');
window.ReactDOM = require('react-dom');
window.clipboard = clipboard;
window.getSeedNodeList = () =>

@ -1,7 +1,7 @@
import React, { useEffect } from 'react';
import { useEffect } from 'react';
import styled from 'styled-components';
import { switchThemeTo } from '../themes/switchTheme';
import { SessionTheme } from '../themes/SessionTheme';
import { switchThemeTo } from '../themes/switchTheme';
const StyledContent = styled.div`
background-color: var(--background-primary-color);

@ -1,4 +1,3 @@
import React from 'react';
import * as GoogleChrome from '../util/GoogleChrome';
import { AttachmentType } from '../types/Attachment';

@ -1,7 +1,7 @@
import React, { useEffect, useState } from 'react';
import { useEffect, useState } from 'react';
import styled from 'styled-components';
import { switchThemeTo } from '../themes/switchTheme';
import { SessionTheme } from '../themes/SessionTheme';
import { switchThemeTo } from '../themes/switchTheme';
import { fetch } from '../util/logging';
import { SessionButton, SessionButtonType } from './basic/SessionButton';
import { SessionIconButton } from './icon';

@ -1,4 +1,3 @@
import React from 'react';
import { CSSProperties } from 'styled-components';
export const MessageView = () => {

@ -1,8 +1,7 @@
import React from 'react';
import styled from 'styled-components';
import { Avatar, AvatarSize, CrownIcon } from './avatar/Avatar';
import { useNicknameOrProfileNameOrShortenedPubkey } from '../hooks/useParamSelector';
import { Avatar, AvatarSize, CrownIcon } from './avatar/Avatar';
import { SessionRadio } from './basic/SessionRadio';
const AvatarContainer = styled.div`

@ -1,4 +1,3 @@
import React from 'react';
import styled from 'styled-components';
import { Flex } from './basic/Flex';
import { SessionIconButton } from './icon';

@ -1,6 +1,6 @@
import { fromPairs, map } from 'lodash';
import moment from 'moment';
import React from 'react';
import { Provider } from 'react-redux';
import useMount from 'react-use/lib/useMount';
import useUpdate from 'react-use/lib/useUpdate';

@ -1,11 +1,10 @@
import React from 'react';
import { useSelector } from 'react-redux';
import { useAppIsFocused } from '../hooks/useAppFocused';
import { getFocusedSettingsSection } from '../state/selectors/section';
import { SmartSessionConversation } from '../state/smart/SessionConversation';
import { SessionSettingsView } from './settings/SessionSettings';
import { useHTMLDirection } from '../util/i18n';
import { SessionSettingsView } from './settings/SessionSettings';
const FilteredSettingsView = SessionSettingsView as any;

@ -1,7 +1,7 @@
import autoBind from 'auto-bind';
import classNames from 'classnames';
import { isString } from 'lodash';
import React, { useEffect } from 'react';
import { PureComponent, useEffect } from 'react';
import { toast } from 'react-toastify';
import styled from 'styled-components';
@ -45,7 +45,7 @@ function pushToastError(id: string, title: string, description?: string) {
});
}
class SessionPasswordPromptInner extends React.PureComponent<unknown, State> {
class SessionPasswordPromptInner extends PureComponent<unknown, State> {
private inputRef?: any;
constructor(props: any) {

@ -1,10 +1,9 @@
import React from 'react';
import { useSelector } from 'react-redux';
import styled from 'styled-components';
import { getShowScrollButton } from '../state/selectors/conversations';
import { SessionIconButton } from './icon';
import { Noop } from '../types/Util';
import { SessionIconButton } from './icon';
const SessionScrollButtonDiv = styled.div`
position: fixed;

@ -1,5 +1,5 @@
import { debounce } from 'lodash';
import React, { Dispatch, useState } from 'react';
import { Dispatch, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import styled from 'styled-components';
import { clearSearch, search, updateSearchTerm } from '../state/ducks/search';

@ -1,4 +1,3 @@
import React from 'react';
import { Slide, ToastContainer, ToastContainerProps } from 'react-toastify';
import styled from 'styled-components';

@ -1,5 +1,5 @@
import React, { useRef } from 'react';
import classNames from 'classnames';
import { useRef } from 'react';
import useKey from 'react-use/lib/useKey';
import { SessionIconButton } from './icon';

@ -1,9 +1,9 @@
import React, { useEffect, useRef, useState } from 'react';
import { ReactElement, ReactNode, useEffect, useRef, useState } from 'react';
import styled from 'styled-components';
type SplitViewProps = {
top: React.ReactElement;
bottom: React.ReactElement;
top: ReactElement;
bottom: ReactElement;
disableTop: boolean;
};
@ -44,12 +44,12 @@ const TopSplitViewPanel = ({
topHeight,
setTopHeight,
}: {
children: React.ReactNode;
children: ReactNode;
topHeight: number | undefined;
setTopHeight: (value: number) => void;
}) => {
const topRef = useRef<HTMLDivElement>(null);
React.useEffect(() => {
useEffect(() => {
if (topRef.current) {
if (!topHeight) {
setTopHeight(Math.max(MIN_HEIGHT_TOP, (topRef.current?.clientHeight || 0) / 2));

@ -1,6 +1,6 @@
import classNames from 'classnames';
import { isEqual } from 'lodash';
import React, { useState } from 'react';
import { memo, useState } from 'react';
import { useSelector } from 'react-redux';
import styled from 'styled-components';
@ -66,7 +66,7 @@ export const CrownIcon = () => {
);
};
const NoImage = React.memo(
const NoImage = memo(
(
props: Pick<Props, 'forcedName' | 'size' | 'pubkey' | 'onAvatarClick'> & {
isClosedGroup: boolean;
@ -185,4 +185,4 @@ const AvatarInner = (props: Props) => {
);
};
export const Avatar = React.memo(AvatarInner, isEqual);
export const Avatar = memo(AvatarInner, isEqual);

@ -1,7 +1,7 @@
import React, { useEffect, useState } from 'react';
import { useEffect, useState } from 'react';
import { allowOnlyOneAtATime } from '../../../session/utils/Promise';
import { COLORS } from '../../../themes/constants/colors';
import { getInitials } from '../../../util/getInitials';
import { allowOnlyOneAtATime } from '../../../session/utils/Promise';
import { MemberAvatarPlaceHolder } from '../../icon/MemberAvatarPlaceHolder';
type Props = {

@ -1,10 +1,9 @@
import React from 'react';
import { isEmpty } from 'lodash';
import { assertUnreachable } from '../../../types/sqlSharedTypes';
import { Avatar, AvatarSize } from '../Avatar';
import { useIsClosedGroup, useSortedGroupMembers } from '../../../hooks/useParamSelector';
import { UserUtils } from '../../../session/utils';
import { assertUnreachable } from '../../../types/sqlSharedTypes';
import { Avatar, AvatarSize } from '../Avatar';
function getClosedGroupAvatarsSize(size: AvatarSize): AvatarSize {
// Always use the size directly under the one requested

@ -1,4 +1,3 @@
import React from 'react';
import styled from 'styled-components';
import { RenderTextCallbackType } from '../../types/Util';
import { SizeClassType } from '../../util/emoji';

@ -1,8 +1,8 @@
import React from 'react';
import { ReactNode } from 'react';
import styled from 'styled-components';
type PillContainerProps = {
children: React.ReactNode;
children: ReactNode;
margin?: string;
padding?: string;
onClick?: () => void;

@ -1,5 +1,5 @@
import React, { ReactNode } from 'react';
import classNames from 'classnames';
import { ReactNode } from 'react';
import styled from 'styled-components';
export enum SessionButtonType {

@ -1,4 +1,4 @@
import React, { useState } from 'react';
import { useState } from 'react';
import { SessionIcon, SessionIconType } from '../icon';
import { SessionDropdownItem, SessionDropDownItemType } from './SessionDropdownItem';

@ -1,4 +1,3 @@
import React from 'react';
import classNames from 'classnames';
import { SessionIcon, SessionIconType } from '../icon';

@ -1,5 +1,5 @@
import React from 'react';
import DOMPurify from 'dompurify';
import { createElement } from 'react';
type ReceivedProps = {
html: string;
@ -14,7 +14,7 @@ export const SessionHtmlRenderer = ({ tag = 'div', key, html, className }: Recei
FORBID_ATTR: ['script'],
});
return React.createElement(tag, {
return createElement(tag, {
key,
className,

@ -1,5 +1,5 @@
import React, { ChangeEvent, KeyboardEvent, useRef } from 'react';
import classNames from 'classnames';
import { ChangeEvent, KeyboardEvent, useRef } from 'react';
import { useFocusMount } from '../../hooks/useFocusMount';
type Props = {

@ -1,9 +1,9 @@
import React, { useState } from 'react';
import { ChangeEvent, useState } from 'react';
import classNames from 'classnames';
import { SessionIconButton } from '../icon';
import { Noop } from '../../types/Util';
import { useHTMLDirection } from '../../util/i18n';
import { SessionIconButton } from '../icon';
type Props = {
label?: string;
@ -78,7 +78,7 @@ export const SessionInput = (props: Props) => {
const correctType = forceShow ? 'text' : type;
const updateInputValue = (e: React.ChangeEvent<HTMLInputElement>) => {
const updateInputValue = (e: ChangeEvent<HTMLInputElement>) => {
e.preventDefault();
const val = e.target.value;
setInputValue(val);

@ -1,4 +1,4 @@
import React, { ChangeEvent } from 'react';
import { ChangeEvent } from 'react';
import styled, { CSSProperties } from 'styled-components';
import { Flex } from './Flex';

@ -1,4 +1,4 @@
import React, { useState } from 'react';
import { useState } from 'react';
import useMount from 'react-use/lib/useMount';
import styled, { CSSProperties } from 'styled-components';

@ -1,5 +1,3 @@
import React from 'react';
type Props = {
loading: boolean;
};

@ -1,5 +1,5 @@
import { noop } from 'lodash';
import React from 'react';
import styled from 'styled-components';
import { Flex } from './Flex';

@ -1,4 +1,4 @@
import React from 'react';
import { MouseEvent } from 'react';
import { useDispatch } from 'react-redux';
import styled from 'styled-components';
import { updateConfirmModal } from '../../state/ducks/modalDialog';
@ -52,7 +52,7 @@ type Props = {
export const SessionToggle = (props: Props) => {
const dispatch = useDispatch();
const clickHandler = (event: React.MouseEvent<HTMLDivElement>) => {
const clickHandler = (event: MouseEvent<HTMLDivElement>) => {
const stateManager = (e: any) => {
e.stopPropagation();
props.onClick();

@ -1,4 +1,3 @@
import React from 'react';
import styled from 'styled-components';
type Props = {

@ -1,4 +1,4 @@
import React from 'react';
import { ReactNode } from 'react';
import styled, { CSSProperties } from 'styled-components';
type TextProps = {
@ -26,9 +26,7 @@ export const Text = (props: TextProps) => {
return <StyledDefaultText {...props}>{props.text}</StyledDefaultText>;
};
export const TextWithChildren = (
props: Omit<TextProps, 'text'> & { children: React.ReactNode }
) => {
export const TextWithChildren = (props: Omit<TextProps, 'text'> & { children: ReactNode }) => {
return <StyledDefaultText {...props}>{props.children}</StyledDefaultText>;
};

@ -1,4 +1,3 @@
import React from 'react';
import styled from 'styled-components';
import { UserUtils } from '../../session/utils';

@ -1,4 +1,3 @@
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import styled from 'styled-components';
import { resetLeftOverlayMode, setLeftOverlayMode } from '../../state/ducks/section';

@ -1,4 +1,4 @@
import React, { ReactNode } from 'react';
import { ReactNode } from 'react';
import styled, { CSSProperties } from 'styled-components';
import { Flex } from '../basic/Flex';

@ -1,4 +1,3 @@
import React from 'react';
import styled from 'styled-components';
import { SessionIcon, SessionIconType } from '../icon';
import { PanelButton, PanelButtonProps, PanelButtonText, StyledContent } from './PanelButton';

@ -1,4 +1,3 @@
import React from 'react';
import styled from 'styled-components';
import { SessionRadio } from '../basic/SessionRadio';
import { PanelButton, PanelButtonProps, PanelButtonText, StyledContent } from './PanelButton';

@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import { MouseEvent, useEffect, useState } from 'react';
import { contextMenu, Item, Menu } from 'react-contexify';
import { useDispatch, useSelector } from 'react-redux';
import styled from 'styled-components';
@ -40,7 +40,7 @@ const VideoInputMenu = ({
const showVideoInputMenu = (
currentConnectedCameras: Array<InputItem>,
e: React.MouseEvent<HTMLDivElement>
e: MouseEvent<HTMLDivElement>
) => {
if (currentConnectedCameras.length === 0) {
ToastUtils.pushNoCameraFound();
@ -113,7 +113,7 @@ const AudioInputMenu = ({
const showAudioInputMenu = (
currentConnectedAudioInputs: Array<any>,
e: React.MouseEvent<HTMLDivElement>
e: MouseEvent<HTMLDivElement>
) => {
if (currentConnectedAudioInputs.length === 0) {
ToastUtils.pushNoAudioInputFound();
@ -182,7 +182,7 @@ const AudioOutputMenu = ({
const showAudioOutputMenu = (
currentConnectedAudioOutputs: Array<any>,
e: React.MouseEvent<HTMLDivElement>
e: MouseEvent<HTMLDivElement>
) => {
if (currentConnectedAudioOutputs.length === 0) {
ToastUtils.pushNoAudioOutputFound();

@ -1,4 +1,4 @@
import React, { useEffect } from 'react';
import { useEffect, useRef } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import useKey from 'react-use/lib/useKey';
@ -52,8 +52,8 @@ export const CallInFullScreenContainer = () => {
localStreamVideoIsMuted,
} = useVideoCallEventsListener('CallInFullScreenContainer', true);
const videoRefRemote = React.useRef<HTMLVideoElement>(null);
const videoRefLocal = React.useRef<HTMLVideoElement>(null);
const videoRefRemote = useRef<HTMLVideoElement>(null);
const videoRefLocal = useRef<HTMLVideoElement>(null);
function toggleFullScreenOFF() {
dispatch(setFullScreenCall(false));

@ -1,16 +1,16 @@
import React, { useEffect, useRef, useState } from 'react';
import { useSelector } from 'react-redux';
import { useEffect, useRef, useState } from 'react';
import Draggable, { DraggableData, DraggableEvent } from 'react-draggable';
import { useSelector } from 'react-redux';
import styled from 'styled-components';
import { getHasOngoingCall, getHasOngoingCallWith } from '../../state/selectors/call';
import { openConversationWithMessages } from '../../state/ducks/conversations';
import { Avatar, AvatarSize } from '../avatar/Avatar';
import { useVideoCallEventsListener } from '../../hooks/useVideoEventListener';
import { VideoLoadingSpinner } from './InConversationCallContainer';
import { getSection } from '../../state/selectors/section';
import { openConversationWithMessages } from '../../state/ducks/conversations';
import { SectionType } from '../../state/ducks/section';
import { getHasOngoingCall, getHasOngoingCallWith } from '../../state/selectors/call';
import { getSection } from '../../state/selectors/section';
import { useSelectedConversationKey } from '../../state/selectors/selectedConversation';
import { Avatar, AvatarSize } from '../avatar/Avatar';
import { VideoLoadingSpinner } from './InConversationCallContainer';
export const DraggableCallWindow = styled.div`
position: absolute;

@ -1,9 +1,9 @@
import { useRef, useState } from 'react';
import { useSelector } from 'react-redux';
import React, { useRef, useState } from 'react';
import styled from 'styled-components';
import useInterval from 'react-use/lib/useInterval';
import moment from 'moment';
import useInterval from 'react-use/lib/useInterval';
import styled from 'styled-components';
import { CallManager, UserUtils } from '../../session/utils';
import {
getCallIsInFullScreen,
@ -13,13 +13,13 @@ import {
getHasOngoingCallWithFocusedConvo,
getHasOngoingCallWithPubkey,
} from '../../state/selectors/call';
import { StyledVideoElement } from './DraggableCallContainer';
import { Avatar, AvatarSize } from '../avatar/Avatar';
import { StyledVideoElement } from './DraggableCallContainer';
import { useVideoCallEventsListener } from '../../hooks/useVideoEventListener';
import { useModuloWithTripleDots } from '../../hooks/useModuloWithTripleDots';
import { CallWindowControls } from './CallButtons';
import { useVideoCallEventsListener } from '../../hooks/useVideoEventListener';
import { DEVICE_DISABLED_DEVICE_ID } from '../../session/utils/calling/CallManager';
import { CallWindowControls } from './CallButtons';
import { SessionSpinner } from '../basic/SessionSpinner';

@ -1,4 +1,4 @@
import React, { useEffect } from 'react';
import { useEffect } from 'react';
import { useSelector } from 'react-redux';
import styled from 'styled-components';
@ -7,9 +7,9 @@ import { ed25519Str } from '../../session/onions/onionPath';
import { CallManager } from '../../session/utils';
import { callTimeoutMs } from '../../session/utils/calling/CallManager';
import { getHasIncomingCall, getHasIncomingCallFrom } from '../../state/selectors/call';
import { SessionWrapperModal } from '../SessionWrapperModal';
import { Avatar, AvatarSize } from '../avatar/Avatar';
import { SessionButton, SessionButtonColor, SessionButtonType } from '../basic/SessionButton';
import { SessionWrapperModal } from '../SessionWrapperModal';
export const CallWindow = styled.div`
position: absolute;

@ -1,9 +1,8 @@
import React from 'react';
import styled from 'styled-components';
import { RenderTextCallbackType } from '../../types/Util';
import { PubKey } from '../../session/types';
import { getConversationController } from '../../session/conversations';
import { isUsAnySogsFromCache } from '../../session/apis/open_group_api/sogsv3/knownBlindedkeys';
import { getConversationController } from '../../session/conversations';
import { PubKey } from '../../session/types';
import { RenderTextCallbackType } from '../../types/Util';
interface MentionProps {
key: string;

@ -1,4 +1,3 @@
import React from 'react';
import { RenderTextCallbackType } from '../../types/Util';
type Props = {

@ -1,12 +1,11 @@
import React from 'react';
import classNames from 'classnames';
import { CSSProperties } from 'styled-components';
import { Emojify } from './Emojify';
import {
useNicknameOrProfileNameOrShortenedPubkey,
useIsPrivate,
useNicknameOrProfileNameOrShortenedPubkey,
} from '../../hooks/useParamSelector';
import { Emojify } from './Emojify';
type Props = {
pubkey: string;
@ -29,7 +28,7 @@ export const ContactName = (props: Props) => {
? {
fontWeight: 'bold',
}
: {}) as React.CSSProperties;
: {}) as CSSProperties;
const textProfile = profileName || name || convoName || window.i18n('anonymous');
return (

@ -1,5 +1,3 @@
import React from 'react';
import { SizeClassType } from '../../util/emoji';
import { RenderTextCallbackType } from '../../types/Util';

@ -1,4 +1,4 @@
import React, { useCallback, useState } from 'react';
import { useCallback, useState } from 'react';
import useInterval from 'react-use/lib/useInterval';
import styled, { CSSProperties } from 'styled-components';

@ -1,5 +1,5 @@
// Audio Player
import React, { useEffect, useRef, useState } from 'react';
import { useEffect, useRef, useState } from 'react';
import H5AudioPlayer, { RHAP_UI } from 'react-h5-audio-player';
import { useDispatch, useSelector } from 'react-redux';
import styled from 'styled-components';

@ -1,5 +1,5 @@
import classNames from 'classnames';
import React, { useCallback } from 'react';
import { useCallback } from 'react';
import styled from 'styled-components';
import { isNumber } from 'lodash';

@ -1,4 +1,4 @@
import React, { useContext } from 'react';
import { useContext } from 'react';
import styled from 'styled-components';
import {

@ -1,4 +1,3 @@
import React from 'react';
import { useSelector } from 'react-redux';
import styled from 'styled-components';
import { useIsIncomingRequest } from '../../hooks/useParamSelector';

@ -1,10 +1,10 @@
import _ from 'lodash';
import React from 'react';
import autoBind from 'auto-bind';
import { blobToArrayBuffer } from 'blob-util';
import loadImage from 'blueimp-load-image';
import classNames from 'classnames';
import { Component, RefObject, createRef } from 'react';
import styled from 'styled-components';
import {
CompositionBox,
@ -103,8 +103,8 @@ const ConvoLoadingSpinner = () => {
);
};
export class SessionConversation extends React.Component<Props, State> {
private readonly messageContainerRef: React.RefObject<HTMLDivElement>;
export class SessionConversation extends Component<Props, State> {
private readonly messageContainerRef: RefObject<HTMLDivElement>;
private dragCounter: number;
private publicMembersRefreshTimeout?: NodeJS.Timeout;
private readonly updateMemberList: () => any;
@ -115,7 +115,7 @@ export class SessionConversation extends React.Component<Props, State> {
this.state = {
isDraggingFile: false,
};
this.messageContainerRef = React.createRef();
this.messageContainerRef = createRef();
this.dragCounter = 0;
this.updateMemberList = _.debounce(this.updateMemberListBouncy.bind(this), 10000);

@ -1,9 +1,10 @@
import React, { forwardRef } from 'react';
import Picker from '@emoji-mart/react';
import classNames from 'classnames';
import styled from 'styled-components';
import { forwardRef } from 'react';
import { useSelector } from 'react-redux';
import Picker from '@emoji-mart/react';
import styled from 'styled-components';
import { getPrimaryColor } from '../../state/selectors/primaryColor';
import { getTheme, isDarkTheme } from '../../state/selectors/theme';
import {
COLORS,
@ -11,12 +12,10 @@ import {
PrimaryColorStateType,
THEMES,
ThemeStateType,
// eslint-disable-next-line import/extensions
} from '../../themes/constants/colors.js';
import { hexColorToRGB } from '../../util/hexColorToRGB';
import { getPrimaryColor } from '../../state/selectors/primaryColor';
import { i18nEmojiData } from '../../util/emoji';
} from '../../themes/constants/colors';
import { FixedBaseEmoji } from '../../types/Reaction';
import { i18nEmojiData } from '../../util/emoji';
import { hexColorToRGB } from '../../util/hexColorToRGB';
export const StyledEmojiPanel = styled.div<{
isModal: boolean;

@ -1,4 +1,3 @@
import React from 'react';
import styled from 'styled-components';
import { Flex } from '../basic/Flex';
import { SessionIcon } from '../icon';

@ -1,4 +1,4 @@
import React, { useContext, useLayoutEffect } from 'react';
import { useContext, useLayoutEffect } from 'react';
import { useSelector } from 'react-redux';
import styled from 'styled-components';
import { getQuotedMessageToAnimate } from '../../state/selectors/conversations';

@ -1,4 +1,4 @@
import React, { useLayoutEffect, useState } from 'react';
import { useLayoutEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import useKey from 'react-use/lib/useKey';
@ -26,9 +26,9 @@ import { Message } from './message/message-item/Message';
import { MessageRequestResponse } from './message/message-item/MessageRequestResponse';
import { CallNotification } from './message/message-item/notification-bubble/CallNotification';
import { DataExtractionNotification } from './message/message-item/DataExtractionNotification';
import { SessionLastSeenIndicator } from './SessionLastSeenIndicator';
import { TimerNotification } from './TimerNotification';
import { DataExtractionNotification } from './message/message-item/DataExtractionNotification';
import { InteractionNotification } from './message/message-item/InteractionNotification';
function isNotTextboxEvent(e: KeyboardEvent) {

@ -1,17 +1,16 @@
import React from 'react';
import { contextMenu } from 'react-contexify';
import { connect } from 'react-redux';
import autoBind from 'auto-bind';
import { Component, RefObject, createContext } from 'react';
import styled from 'styled-components';
import {
quotedMessageToAnimate,
ReduxConversationType,
SortedMessageModelProps,
quotedMessageToAnimate,
resetOldBottomMessageId,
resetOldTopMessageId,
SortedMessageModelProps,
} from '../../state/ducks/conversations';
import { SessionScrollButton } from '../SessionScrollButton';
@ -27,7 +26,7 @@ import { SessionMessagesList } from './SessionMessagesList';
import { TypingBubble } from './TypingBubble';
export type SessionMessageListProps = {
messageContainerRef: React.RefObject<HTMLDivElement>;
messageContainerRef: RefObject<HTMLDivElement>;
};
export const messageContainerDomID = 'messages-container';
@ -38,7 +37,7 @@ export type ScrollToLoadedReasons =
| 'load-more-top'
| 'load-more-bottom';
export const ScrollToLoadedMessageContext = React.createContext(
export const ScrollToLoadedMessageContext = createContext(
(_loadedMessageIdToScrollTo: string, _reason: ScrollToLoadedReasons) => {}
);
@ -77,7 +76,7 @@ const StyledTypingBubble = styled(TypingBubble)`
margin: var(--margins-xs) var(--margins-lg) 0;
`;
class SessionMessagesListContainerInner extends React.Component<Props> {
class SessionMessagesListContainerInner extends Component<Props> {
private timeoutResetQuotedScroll: NodeJS.Timeout | null = null;
public constructor(props: Props) {

@ -1,7 +1,6 @@
import React from 'react';
import styled from 'styled-components';
import { useDispatch, useSelector } from 'react-redux';
import useKey from 'react-use/lib/useKey';
import styled from 'styled-components';
import { SessionIcon, SessionIconButton } from '../icon';
import { quoteMessage } from '../../state/ducks/conversations';
@ -11,9 +10,9 @@ import { AUDIO_MP3 } from '../../types/MIME';
import { Flex } from '../basic/Flex';
import { Image } from './Image';
import { findAndFormatContact } from '../../models/message';
import { getAbsoluteAttachmentPath } from '../../types/MessageAttachment';
import { GoogleChrome } from '../../util';
import { findAndFormatContact } from '../../models/message';
const QuotedMessageComposition = styled(Flex)`
border-top: 1px solid var(--border-color);

@ -1,15 +1,16 @@
/* eslint-disable @typescript-eslint/no-misused-promises */
import React from 'react';
import classNames from 'classnames';
import moment from 'moment';
import autoBind from 'auto-bind';
import MicRecorder from 'mic-recorder-to-mp3';
import { Component } from 'react';
import styled from 'styled-components';
import { SessionIconButton } from '../icon';
import { Constants } from '../../session';
import { ToastUtils } from '../../session/utils';
import { MAX_ATTACHMENT_FILESIZE_BYTES } from '../../session/constants';
import { ToastUtils } from '../../session/utils';
import { SessionIconButton } from '../icon';
interface Props {
onExitVoiceNoteView: () => void;
@ -49,7 +50,7 @@ const StyledFlexWrapper = styled.div<StyledFlexWrapperProps>`
}
`;
export class SessionRecording extends React.Component<Props, State> {
export class SessionRecording extends Component<Props, State> {
private recorder?: any;
private audioBlobMp3?: Blob;
private audioElement?: HTMLAudioElement | null;

@ -1,15 +1,13 @@
import React from 'react';
// eslint-disable-next-line import/no-named-default
import { default as insecureNodeFetch } from 'node-fetch';
import { AbortSignal } from 'abort-controller';
import insecureNodeFetch from 'node-fetch';
import { StagedLinkPreviewData } from './composition/CompositionBox';
import { arrayBufferFromFile } from '../../types/Attachment';
import { getImageDimensions } from '../../types/attachments/VisualAttachment';
import { AttachmentUtil, LinkPreviewUtil } from '../../util';
import { fetchLinkPreviewImage } from '../../util/linkPreviewFetch';
import { StagedLinkPreview } from './StagedLinkPreview';
import { getImageDimensions } from '../../types/attachments/VisualAttachment';
import { LinkPreviews } from '../../util/linkPreviews';
import { StagedLinkPreview } from './StagedLinkPreview';
export interface StagedLinkPreviewProps extends StagedLinkPreviewData {
onClose: (url: string) => void;

@ -1,5 +1,3 @@
import React from 'react';
import { useDispatch } from 'react-redux';
import styled from 'styled-components';
import {

@ -1,5 +1,4 @@
import React from 'react';
import { Component } from 'react';
import { AttachmentType, getExtensionForDisplay } from '../../types/Attachment';
interface Props {
@ -7,7 +6,7 @@ interface Props {
onClose: (attachment: AttachmentType) => void;
}
export class StagedGenericAttachment extends React.Component<Props> {
export class StagedGenericAttachment extends Component<Props> {
public render() {
const { attachment, onClose } = this.props;
const { fileName, contentType } = attachment;

@ -1,14 +1,13 @@
import React from 'react';
import styled from 'styled-components';
import { Image } from './Image';
import { SessionSpinner } from '../basic/SessionSpinner';
import { StagedLinkPreviewImage } from './composition/CompositionBox';
import { isImage } from '../../types/MIME';
import { fromArrayBufferToBase64 } from '../../session/utils/String';
import { isImage } from '../../types/MIME';
import { Flex } from '../basic/Flex';
import { SessionSpinner } from '../basic/SessionSpinner';
import { SessionIconButton } from '../icon';
import { StagedLinkPreviewImage } from './composition/CompositionBox';
type Props = {
isLoaded: boolean;

@ -1,4 +1,4 @@
import React, { MouseEvent } from 'react';
import { MouseEvent } from 'react';
import styled from 'styled-components';
interface Props {

@ -1,4 +1,3 @@
import React from 'react';
import { useSelector } from 'react-redux';
import styled from 'styled-components';
import { useIsIncomingRequest } from '../../hooks/useParamSelector';

@ -1,5 +1,3 @@
import React from 'react';
import { useDispatch } from 'react-redux';
import styled from 'styled-components';
import { PropsForExpirationTimer } from '../../state/ducks/conversations';

@ -1,9 +1,8 @@
import React from 'react';
import moment from 'moment';
import useInterval from 'react-use/lib/useInterval';
import styled from 'styled-components';
import useUpdate from 'react-use/lib/useUpdate';
import styled from 'styled-components';
type Props = {
timestamp?: number;

@ -1,4 +1,3 @@
import React from 'react';
import styled from 'styled-components';
const StyledTypingContainer = styled.div`

@ -1,4 +1,3 @@
import React from 'react';
import styled from 'styled-components';
import { ConversationTypeEnum } from '../../models/conversationAttributes';

@ -1,5 +1,5 @@
import _, { debounce, isEmpty } from 'lodash';
import React from 'react';
import { connect } from 'react-redux';
import styled from 'styled-components';
@ -7,6 +7,7 @@ import { AbortController } from 'abort-controller';
import { Mention, MentionsInput, SuggestionDataItem } from 'react-mentions';
import autoBind from 'auto-bind';
import { Component, RefObject, createRef } from 'react';
import * as MIME from '../../../types/MIME';
import { SessionEmojiPanel, StyledEmojiPanel } from '../SessionEmojiPanel';
@ -268,10 +269,10 @@ const StyledSendMessageInput = styled.div<{ dir?: HTMLDirection }>`
}
`;
class CompositionBoxInner extends React.Component<Props, State> {
private readonly textarea: React.RefObject<any>;
private readonly fileInput: React.RefObject<HTMLInputElement>;
private readonly emojiPanel: React.RefObject<HTMLDivElement>;
class CompositionBoxInner extends Component<Props, State> {
private readonly textarea: RefObject<any>;
private readonly fileInput: RefObject<HTMLInputElement>;
private readonly emojiPanel: RefObject<HTMLDivElement>;
private readonly emojiPanelButton: any;
private linkPreviewAbortController?: AbortController;
private container: HTMLDivElement | null;
@ -281,13 +282,13 @@ class CompositionBoxInner extends React.Component<Props, State> {
super(props);
this.state = getDefaultState(props.selectedConversationKey);
this.textarea = React.createRef();
this.fileInput = React.createRef();
this.textarea = createRef();
this.fileInput = createRef();
this.container = null;
// Emojis
this.emojiPanel = React.createRef();
this.emojiPanelButton = React.createRef();
this.emojiPanel = createRef();
this.emojiPanelButton = createRef();
autoBind(this);
this.toggleEmojiPanel = debounce(this.toggleEmojiPanel.bind(this), 100);
}

@ -1,7 +1,7 @@
import React from 'react';
import { forwardRef } from 'react';
import styled from 'styled-components';
import { SessionIconButton } from '../../icon';
import { Noop } from '../../../types/Util';
import { SessionIconButton } from '../../icon';
const StyledChatButtonContainer = styled.div`
.session-icon-button {
@ -50,25 +50,23 @@ export const StartRecordingButton = (props: { onClick: Noop }) => {
};
// eslint-disable-next-line react/display-name
export const ToggleEmojiButton = React.forwardRef<HTMLDivElement, { onClick: Noop }>(
(props, ref) => {
return (
<StyledChatButtonContainer>
<SessionIconButton
iconType="emoji"
ref={ref}
backgroundColor={'var(--chat-buttons-background-color)'}
iconColor={'var(--chat-buttons-icon-color)'}
iconSize={'huge2'}
borderRadius="300px"
iconPadding="6px"
onClick={props.onClick}
dataTestId="emoji-button"
/>
</StyledChatButtonContainer>
);
}
);
export const ToggleEmojiButton = forwardRef<HTMLDivElement, { onClick: Noop }>((props, ref) => {
return (
<StyledChatButtonContainer>
<SessionIconButton
iconType="emoji"
ref={ref}
backgroundColor={'var(--chat-buttons-background-color)'}
iconColor={'var(--chat-buttons-icon-color)'}
iconSize={'huge2'}
borderRadius="300px"
iconPadding="6px"
onClick={props.onClick}
dataTestId="emoji-button"
/>
</StyledChatButtonContainer>
);
});
export const SendMessageButton = (props: { onClick: Noop }) => {
return (

@ -1,9 +1,7 @@
import React from 'react';
import { SearchIndex } from 'emoji-mart';
import { SuggestionDataItem } from 'react-mentions';
import styled from 'styled-components';
import { SearchIndex } from 'emoji-mart';
// eslint-disable-next-line import/extensions
import { searchSync } from '../../../util/emoji.js';
import { searchSync } from '../../../util/emoji';
const EmojiQuickResult = styled.span`
display: flex;

@ -1,7 +1,6 @@
import React from 'react';
import { SuggestionDataItem } from 'react-mentions';
import { MemberListItem } from '../../MemberListItem';
import { HTMLDirection } from '../../../util/i18n';
import { MemberListItem } from '../../MemberListItem';
const listRTLStyle = { position: 'absolute', bottom: '0px', right: '100%' };

@ -1,5 +1,3 @@
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { isMessageSelectionMode } from '../../../state/selectors/conversations';

@ -1,4 +1,3 @@
import React from 'react';
import { useSelector } from 'react-redux';
import { callRecipient } from '../../../interactions/conversationInteractions';
import { getHasIncomingCall, getHasOngoingCall } from '../../../state/selectors/call';

@ -1,4 +1,3 @@
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import {
deleteMessagesById,

@ -1,4 +1,3 @@
import React from 'react';
import styled, { CSSProperties } from 'styled-components';
import { Flex } from '../../basic/Flex';
import { SessionIconButton } from '../../icon';

@ -1,5 +1,5 @@
import { isEmpty } from 'lodash';
import React, { useEffect, useMemo, useState } from 'react';
import { useEffect, useMemo, useState } from 'react';
import { useDispatch } from 'react-redux';
import { useDisappearingMessageSettingText } from '../../../hooks/useParamSelector';
import { useIsRightPanelShowing } from '../../../hooks/useUI';

@ -1,9 +1,7 @@
import React from 'react';
import { DocumentListItem } from './DocumentListItem';
import { MediaGridItem } from './MediaGridItem';
import { missingCaseError } from '../../../util/missingCaseError';
import { MediaItemType } from '../../lightbox/LightboxGallery';
import { DocumentListItem } from './DocumentListItem';
import { MediaGridItem } from './MediaGridItem';
type Props = {
type: 'media' | 'documents';

@ -1,12 +1,12 @@
import classNames from 'classnames';
import React, { useCallback } from 'react';
import { useCallback } from 'react';
import moment from 'moment';
import formatFileSize from 'filesize';
import { useSelectedConversationKey } from '../../../state/selectors/selectedConversation';
import { saveAttachmentToDisk } from '../../../util/attachmentsUtil';
import { MediaItemType } from '../../lightbox/LightboxGallery';
import { useSelectedConversationKey } from '../../../state/selectors/selectedConversation';
type Props = {
// Required

@ -1,13 +1,14 @@
/**
* @prettier
*/
import React from 'react';
import { Component } from 'react';
interface Props {
label: string;
}
export class EmptyState extends React.Component<Props> {
export class EmptyState extends Component<Props> {
public render() {
const { label } = this.props;

@ -1,5 +1,5 @@
import classNames from 'classnames';
import React, { useCallback, useState } from 'react';
import { useCallback, useState } from 'react';
import { MediaItemType } from '../../lightbox/LightboxGallery';
import { AttachmentSection } from './AttachmentSection';

@ -1,12 +1,12 @@
import React, { useState } from 'react';
import classNames from 'classnames';
import { useState } from 'react';
import { isImageTypeSupported, isVideoTypeSupported } from '../../../util/GoogleChrome';
import { useDisableDrag } from '../../../hooks/useDisableDrag';
import { useEncryptedFileFetch } from '../../../hooks/useEncryptedFileFetch';
import { showLightBox } from '../../../state/ducks/conversations';
import { useDisableDrag } from '../../../hooks/useDisableDrag';
import { LightBoxOptions } from '../SessionConversation';
import { isImageTypeSupported, isVideoTypeSupported } from '../../../util/GoogleChrome';
import { MediaItemType } from '../../lightbox/LightboxGallery';
import { LightBoxOptions } from '../SessionConversation';
type Props = {
mediaItem: MediaItemType;

@ -1,4 +1,3 @@
import React from 'react';
import styled from 'styled-components';
import { Data } from '../../../../data/data';
import { getConversationController } from '../../../../session/conversations';

@ -1,6 +1,6 @@
import classNames from 'classnames';
import { clone } from 'lodash';
import React, { useCallback } from 'react';
import { useCallback } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import styled from 'styled-components';
import { Data } from '../../../../data/data';

@ -1,4 +1,3 @@
import React from 'react';
import styled from 'styled-components';
import { PubKey } from '../../../../session/types';
import {

@ -1,4 +1,4 @@
import React, { useCallback } from 'react';
import { useCallback } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import styled from 'styled-components';
import { OpenGroupData } from '../../../../data/opengroups';

@ -1,5 +1,5 @@
import LinkifyIt from 'linkify-it';
import React from 'react';
import { useDispatch } from 'react-redux';
import styled from 'styled-components';

@ -1,7 +1,14 @@
import classNames from 'classnames';
import { isEmpty } from 'lodash';
import moment from 'moment';
import React, { createContext, useCallback, useContext, useLayoutEffect, useState } from 'react';
import {
MouseEvent,
createContext,
useCallback,
useContext,
useLayoutEffect,
useState,
} from 'react';
import { InView } from 'react-intersection-observer';
import { useSelector } from 'react-redux';
import styled from 'styled-components';
@ -39,7 +46,7 @@ type Props = {
// TODO not too sure what is this doing? It is not preventDefault()
// or stopPropagation() so I think this is never cancelling a click event?
function onClickOnMessageInnerContainer(event: React.MouseEvent<HTMLDivElement>) {
function onClickOnMessageInnerContainer(event: MouseEvent<HTMLDivElement>) {
const selection = window.getSelection();
// Text is being selected
if (selection && selection.type === 'Range') {

@ -1,5 +1,5 @@
import classNames from 'classnames';
import React, { useCallback, useState } from 'react';
import { MouseEvent, useCallback, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import styled from 'styled-components';
import { replyToMessage } from '../../../../interactions/conversationInteractions';
@ -62,7 +62,7 @@ export const MessageContentWithStatuses = (props: Props) => {
const multiSelectMode = useSelector(isMessageSelectionMode);
const onClickOnMessageOuterContainer = useCallback(
(event: React.MouseEvent<HTMLDivElement>) => {
(event: MouseEvent<HTMLDivElement>) => {
if (multiSelectMode && props?.messageId) {
event.preventDefault();
event.stopPropagation();
@ -72,7 +72,7 @@ export const MessageContentWithStatuses = (props: Props) => {
[dispatch, props?.messageId, multiSelectMode]
);
const onDoubleClickReplyToMessage = (e: React.MouseEvent<HTMLDivElement>) => {
const onDoubleClickReplyToMessage = (e: MouseEvent<HTMLDivElement>) => {
const currentSelection = window.getSelection();
const currentSelectionString = currentSelection?.toString() || undefined;

@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/no-misused-promises */
import React, { Dispatch, useCallback, useEffect, useRef, useState } from 'react';
import { Dispatch, useCallback, useEffect, useRef, useState } from 'react';
import { isNumber } from 'lodash';
import { Item, ItemParams, Menu, useContextMenu } from 'react-contexify';

@ -1,29 +1,29 @@
import styled, { css, keyframes } from 'styled-components';
import { motion } from 'framer-motion';
import { MouseEvent, ReactNode } from 'react';
import styled from 'styled-components';
const opacityAnimation = keyframes`
0% {
opacity: 1;
}
25% {
opacity: 0.2;
}
50% {
opacity: 1;
}
75% {
opacity: 0.2;
}
100% {
opacity: 1;
}
`;
const StyledMessageHighlighter = styled(motion.div)``;
export const MessageHighlighter = styled.div<{
export function MessageHighlighter(props: {
children: ReactNode;
highlight: boolean;
}>`
${props =>
props.highlight &&
css`
animation: ${opacityAnimation} 1s linear;
`}
`;
role?: string;
className?: string;
onClick?: (event: MouseEvent<HTMLDivElement>) => void;
}) {
const { className, children, highlight, role, onClick } = props;
return (
<StyledMessageHighlighter
className={className}
role={role}
onClick={onClick}
animate={{
opacity: highlight ? [1, 0.2, 1, 0.2, 1] : undefined,
transition: { duration: 1, ease: 'linear', repeat: 0 },
}}
>
{children}
</StyledMessageHighlighter>
);
}

@ -1,5 +1,5 @@
import classNames from 'classnames';
import React from 'react';
import { useDispatch } from 'react-redux';
import { MessageRenderingProps } from '../../../../models/messageType';
import {

@ -1,5 +1,6 @@
import { isEmpty, toNumber } from 'lodash';
import React from 'react';
import { MouseEvent } from 'react';
import { useSelector } from 'react-redux';
import { Data } from '../../../../data/data';
import { MessageRenderingProps } from '../../../../models/messageType';
@ -34,7 +35,7 @@ export const MessageQuote = (props: Props) => {
quote.referencedMessageNotFound || !quote?.author || !quote.id || !quote.convoId
);
const onQuoteClick = async (event: React.MouseEvent<HTMLDivElement>) => {
const onQuoteClick = async (event: MouseEvent<HTMLDivElement>) => {
event.preventDefault();
event.stopPropagation();

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save