move ActionsPanel to hooks

pull/1540/head
Audric Ackermann 5 years ago
parent 08ce55f1a6
commit 041a32101b
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -11,21 +11,14 @@ import { SessionOffline } from './session/network/SessionOffline';
import { SessionExpiredWarning } from './session/network/SessionExpiredWarning'; import { SessionExpiredWarning } from './session/network/SessionExpiredWarning';
import { getFocusedSection } from '../state/selectors/section'; import { getFocusedSection } from '../state/selectors/section';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { import { getLeftPaneLists } from '../state/selectors/conversations';
getLeftPaneLists,
getOurPrimaryConversation,
getUnreadMessageCount,
} from '../state/selectors/conversations';
import { import {
getQuery, getQuery,
getSearchResults, getSearchResults,
isSearching, isSearching,
} from '../state/selectors/search'; } from '../state/selectors/search';
import { clearSearch, search, updateSearchTerm } from '../state/ducks/search'; import { clearSearch, search, updateSearchTerm } from '../state/ducks/search';
import { showLeftPaneSection } from '../state/ducks/section';
import { getOurNumber } from '../state/selectors/user';
import { getTheme } from '../state/selectors/theme'; import { getTheme } from '../state/selectors/theme';
import { applyTheme, ThemeStateType } from '../state/ducks/theme';
// from https://github.com/bvaughn/react-virtualized/blob/fb3484ed5dcc41bffae8eab029126c0fb8f7abc0/source/List/types.js#L5 // from https://github.com/bvaughn/react-virtualized/blob/fb3484ed5dcc41bffae8eab029126c0fb8f7abc0/source/List/types.js#L5
export type RowRendererParamsType = { export type RowRendererParamsType = {
@ -119,29 +112,11 @@ const LeftPaneSection = (props: { isExpired: boolean }) => {
export const LeftPane = (props: Props) => { export const LeftPane = (props: Props) => {
const theme = useSelector(getTheme); const theme = useSelector(getTheme);
const dispatch = useDispatch();
const focusedSection = useSelector(getFocusedSection);
const unreadMessageCount = useSelector(getUnreadMessageCount);
const ourPrimaryConversation = useSelector(getOurPrimaryConversation);
const ourNumber = useSelector(getOurNumber);
return ( return (
<SessionTheme theme={theme}> <SessionTheme theme={theme}>
<div className="module-left-pane-session"> <div className="module-left-pane-session">
<ActionsPanel <ActionsPanel />
selectedSection={focusedSection}
onSectionSelected={(section: SectionType) => {
dispatch(clearSearch());
dispatch(showLeftPaneSection(section));
}}
unreadMessageCount={unreadMessageCount}
ourPrimaryConversation={ourPrimaryConversation}
ourNumber={ourNumber}
theme={theme}
applyTheme={(newTheme: ThemeStateType) =>
dispatch(applyTheme(newTheme))
}
/>
<div className="module-left-pane"> <div className="module-left-pane">
<LeftPaneSection isExpired={props.isExpired} /> <LeftPaneSection isExpired={props.isExpired} />
</div> </div>

@ -1,4 +1,4 @@
import React from 'react'; import React, { useEffect } from 'react';
import { SessionIconButton, SessionIconSize, SessionIconType } from './icon'; import { SessionIconButton, SessionIconSize, SessionIconType } from './icon';
import { Avatar } from '../Avatar'; import { Avatar } from '../Avatar';
import { darkTheme, lightTheme } from '../../state/ducks/SessionTheme'; import { darkTheme, lightTheme } from '../../state/ducks/SessionTheme';
@ -17,6 +17,18 @@ import {
import { OnionPaths } from '../../session/onions'; import { OnionPaths } from '../../session/onions';
import { getMessageQueue } from '../../session/sending'; import { getMessageQueue } from '../../session/sending';
import { clearSessionsAndPreKeys } from '../../util/accountManager'; import { clearSessionsAndPreKeys } from '../../util/accountManager';
import { useDispatch, useSelector } from 'react-redux';
import { getOurNumber } from '../../state/selectors/user';
import {
getOurPrimaryConversation,
getUnreadMessageCount,
} from '../../state/selectors/conversations';
import { getTheme } from '../../state/selectors/theme';
import { applyTheme } from '../../state/ducks/theme';
import { getFocusedSection } from '../../state/selectors/section';
import { useInterval } from '../../hooks/useInterval';
import { clearSearch } from '../../state/ducks/search';
import { showLeftPaneSection } from '../../state/ducks/section';
// tslint:disable-next-line: no-import-side-effect no-submodule-imports // tslint:disable-next-line: no-import-side-effect no-submodule-imports
export enum SectionType { export enum SectionType {
@ -28,33 +40,100 @@ export enum SectionType {
Moon, Moon,
} }
interface Props { const Section = (props: { type: SectionType; avatarPath?: string }) => {
onSectionSelected: (section: SectionType) => void; const ourNumber = useSelector(getOurNumber);
selectedSection: SectionType; const unreadMessageCount = useSelector(getUnreadMessageCount);
unreadMessageCount: number; const theme = useSelector(getTheme);
ourPrimaryConversation: ConversationType; const dispatch = useDispatch();
ourNumber: string; const { type, avatarPath } = props;
applyTheme: any;
theme: DefaultTheme; const focusedSection = useSelector(getFocusedSection);
} const isSelected = focusedSection === props.type;
const handleClick = () => {
/* tslint:disable:no-void-expression */
if (type === SectionType.Profile) {
window.showEditProfileDialog();
} else if (type === SectionType.Moon) {
const themeFromSettings = window.Events.getThemeSetting();
const updatedTheme = themeFromSettings === 'dark' ? 'light' : 'dark';
window.setTheme(updatedTheme);
const newThemeObject = updatedTheme === 'dark' ? darkTheme : lightTheme;
dispatch(applyTheme(newThemeObject));
} else {
dispatch(clearSearch());
dispatch(showLeftPaneSection(type));
}
};
if (type === SectionType.Profile) {
const conversation = ConversationController.getInstance().get(ourNumber);
const profile = conversation?.getLokiProfile();
const userName = (profile && profile.displayName) || ourNumber;
return (
<Avatar
avatarPath={avatarPath}
size={28}
onAvatarClick={handleClick}
name={userName}
pubkey={ourNumber}
/>
);
}
let iconType: SessionIconType;
switch (type) {
case SectionType.Message:
iconType = SessionIconType.ChatBubble;
break;
case SectionType.Contact:
iconType = SessionIconType.Users;
break;
case SectionType.Settings:
iconType = SessionIconType.Gear;
break;
case SectionType.Moon:
iconType = SessionIconType.Moon;
break;
default:
iconType = SessionIconType.Moon;
}
return (
<SessionIconButton
iconSize={SessionIconSize.Medium}
iconType={iconType}
notificationCount={unreadMessageCount}
onClick={handleClick}
isSelected={isSelected}
theme={theme}
/>
);
};
const showResetSessionIDDialogIfNeeded = async () => {
const userED25519KeyPairHex = await UserUtils.getUserED25519KeyPair();
if (userED25519KeyPairHex) {
return;
}
window.showResetSessionIdDialog();
};
/** /**
* ActionsPanel is the far left banner (not the left pane). * ActionsPanel is the far left banner (not the left pane).
* The panel with buttons to switch between the message/contact/settings/theme views * The panel with buttons to switch between the message/contact/settings/theme views
*/ */
export class ActionsPanel extends React.Component<Props> { export const ActionsPanel = () => {
private syncInterval: NodeJS.Timeout | null = null; const dispatch = useDispatch();
constructor(props: Props) {
super(props);
// we consider people had the time to upgrade, so remove this id from the db const ourPrimaryConversation = useSelector(getOurPrimaryConversation);
// it was used to display a dialog when we added the light mode auto-enabled
void removeItemById('hasSeenLightModeDialog');
}
// fetch the user saved theme from the db, and apply it on mount. // this maxi useEffect is called only once: when the component is mounted.
public componentDidMount() { useEffect(() => {
void window.setClockParams(); void window.setClockParams();
if ( if (
window.lokiFeatureFlags.useOnionRequests || window.lokiFeatureFlags.useOnionRequests ||
@ -72,12 +151,14 @@ export class ActionsPanel extends React.Component<Props> {
window.setTheme(theme); window.setTheme(theme);
const newThemeObject = theme === 'dark' ? darkTheme : lightTheme; const newThemeObject = theme === 'dark' ? darkTheme : lightTheme;
this.props.applyTheme(newThemeObject); dispatch(applyTheme(newThemeObject));
void this.showResetSessionIDDialogIfNeeded();
void showResetSessionIDDialogIfNeeded();
// remove existing prekeys, sign prekeys and sessions // remove existing prekeys, sign prekeys and sessions
void clearSessionsAndPreKeys(); void clearSessionsAndPreKeys();
// we consider people had the time to upgrade, so remove this id from the db
// it was used to display a dialog when we added the light mode auto-enabled
void removeItemById('hasSeenLightModeDialog');
// Do this only if we created a new Session ID, or if we already received the initial configuration message // Do this only if we created a new Session ID, or if we already received the initial configuration message
@ -92,166 +173,29 @@ export class ActionsPanel extends React.Component<Props> {
// trigger a sync message if needed for our other devices // trigger a sync message if needed for our other devices
void syncConfiguration(); void syncConfiguration();
}, []);
this.syncInterval = global.setInterval(() => { if (!ourPrimaryConversation) {
void syncConfigurationIfNeeded(); window.log.warn('ActionsPanel: ourPrimaryConversation is not set');
}, DAYS * 2); return <></>;
} }
public componentWillUnmount() { useInterval(() => {
if (this.syncInterval) { void syncConfigurationIfNeeded();
clearInterval(this.syncInterval); }, DAYS * 2);
this.syncInterval = null;
}
}
public Section = ({ return (
isSelected, <div className="module-left-pane__sections-container">
onSelect, <Section
type, type={SectionType.Profile}
avatarPath, avatarPath={ourPrimaryConversation.avatarPath}
notificationCount,
}: {
isSelected: boolean;
onSelect?: (event: SectionType) => void;
type: SectionType;
avatarPath?: string;
notificationCount?: number;
}) => {
const { ourNumber } = this.props;
const handleClick = onSelect
? () => {
/* tslint:disable:no-void-expression */
if (type === SectionType.Profile) {
window.showEditProfileDialog();
} else if (type === SectionType.Moon) {
const theme = window.Events.getThemeSetting();
const updatedTheme = theme === 'dark' ? 'light' : 'dark';
window.setTheme(updatedTheme);
const newThemeObject =
updatedTheme === 'dark' ? darkTheme : lightTheme;
this.props.applyTheme(newThemeObject);
} else {
onSelect(type);
}
/* tslint:enable:no-void-expression */
}
: undefined;
if (type === SectionType.Profile) {
const conversation = ConversationController.getInstance().get(ourNumber);
const profile = conversation?.getLokiProfile();
const userName = (profile && profile.displayName) || ourNumber;
return (
<Avatar
avatarPath={avatarPath}
size={28}
onAvatarClick={handleClick}
name={userName}
pubkey={ourNumber}
/>
);
}
let iconType: SessionIconType;
switch (type) {
case SectionType.Message:
iconType = SessionIconType.ChatBubble;
break;
case SectionType.Contact:
iconType = SessionIconType.Users;
break;
case SectionType.Channel:
iconType = SessionIconType.Globe;
break;
case SectionType.Settings:
iconType = SessionIconType.Gear;
break;
case SectionType.Moon:
iconType = SessionIconType.Moon;
break;
default:
iconType = SessionIconType.Moon;
}
return (
<SessionIconButton
iconSize={SessionIconSize.Medium}
iconType={iconType}
notificationCount={notificationCount}
onClick={handleClick}
isSelected={isSelected}
theme={this.props.theme}
/> />
); <Section type={SectionType.Message} />
}; <Section type={SectionType.Contact} />
<Section type={SectionType.Settings} />
public render(): JSX.Element {
const { <SessionToastContainer />
selectedSection, <Section type={SectionType.Moon} />
unreadMessageCount, </div>
ourPrimaryConversation, );
} = this.props; };
if (!ourPrimaryConversation) {
window.log.warn('ActionsPanel: ourPrimaryConversation is not set');
return <></>;
}
const isProfilePageSelected = selectedSection === SectionType.Profile;
const isMessagePageSelected = selectedSection === SectionType.Message;
const isContactPageSelected = selectedSection === SectionType.Contact;
const isSettingsPageSelected = selectedSection === SectionType.Settings;
const isMoonPageSelected = selectedSection === SectionType.Moon;
return (
<div className="module-left-pane__sections-container">
<this.Section
type={SectionType.Profile}
avatarPath={ourPrimaryConversation.avatarPath}
isSelected={isProfilePageSelected}
onSelect={this.handleSectionSelect}
/>
<this.Section
type={SectionType.Message}
isSelected={isMessagePageSelected}
onSelect={this.handleSectionSelect}
notificationCount={unreadMessageCount}
/>
<this.Section
type={SectionType.Contact}
isSelected={isContactPageSelected}
onSelect={this.handleSectionSelect}
/>
<this.Section
type={SectionType.Settings}
isSelected={isSettingsPageSelected}
onSelect={this.handleSectionSelect}
/>
<SessionToastContainer />
<this.Section
type={SectionType.Moon}
isSelected={isMoonPageSelected}
onSelect={this.handleSectionSelect}
/>
</div>
);
}
private readonly handleSectionSelect = (section: SectionType): void => {
this.props.onSectionSelected(section);
};
private async showResetSessionIDDialogIfNeeded() {
const userED25519KeyPairHex = await UserUtils.getUserED25519KeyPair();
if (userED25519KeyPairHex) {
return;
}
window.showResetSessionIdDialog();
}
}

Loading…
Cancel
Save