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,116 +40,32 @@ 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);
* ActionsPanel is the far left banner (not the left pane). const isSelected = focusedSection === props.type;
* The panel with buttons to switch between the message/contact/settings/theme views
*/
export class ActionsPanel extends React.Component<Props> {
private syncInterval: NodeJS.Timeout | null = null;
constructor(props: Props) {
super(props);
// we consider people had the time to upgrade, so remove this id from the db const handleClick = () => {
// 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.
public componentDidMount() {
void window.setClockParams();
if (
window.lokiFeatureFlags.useOnionRequests ||
window.lokiFeatureFlags.useFileOnionRequests
) {
// Initialize paths for onion requests
void OnionPaths.getInstance().buildNewOnionPaths();
}
// init the messageQueue. In the constructor, we had all not send messages
// this call does nothing except calling the constructor, which will continue sending message in the pipeline
void getMessageQueue().processAllPending();
const theme = window.Events.getThemeSetting();
window.setTheme(theme);
const newThemeObject = theme === 'dark' ? darkTheme : lightTheme;
this.props.applyTheme(newThemeObject);
void this.showResetSessionIDDialogIfNeeded();
// remove existing prekeys, sign prekeys and sessions
void clearSessionsAndPreKeys();
// Do this only if we created a new Session ID, or if we already received the initial configuration message
const syncConfiguration = async () => {
const didWeHandleAConfigurationMessageAlready =
(await getItemById(hasSyncedInitialConfigurationItem))?.value || false;
if (didWeHandleAConfigurationMessageAlready) {
await syncConfigurationIfNeeded();
}
};
// trigger a sync message if needed for our other devices
void syncConfiguration();
this.syncInterval = global.setInterval(() => {
void syncConfigurationIfNeeded();
}, DAYS * 2);
}
public componentWillUnmount() {
if (this.syncInterval) {
clearInterval(this.syncInterval);
this.syncInterval = null;
}
}
public Section = ({
isSelected,
onSelect,
type,
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 */ /* tslint:disable:no-void-expression */
if (type === SectionType.Profile) { if (type === SectionType.Profile) {
window.showEditProfileDialog(); window.showEditProfileDialog();
} else if (type === SectionType.Moon) { } else if (type === SectionType.Moon) {
const theme = window.Events.getThemeSetting(); const themeFromSettings = window.Events.getThemeSetting();
const updatedTheme = theme === 'dark' ? 'light' : 'dark'; const updatedTheme = themeFromSettings === 'dark' ? 'light' : 'dark';
window.setTheme(updatedTheme); window.setTheme(updatedTheme);
const newThemeObject = const newThemeObject = updatedTheme === 'dark' ? darkTheme : lightTheme;
updatedTheme === 'dark' ? darkTheme : lightTheme; dispatch(applyTheme(newThemeObject));
this.props.applyTheme(newThemeObject);
} else { } else {
onSelect(type); dispatch(clearSearch());
} dispatch(showLeftPaneSection(type));
/* tslint:enable:no-void-expression */
} }
: undefined; };
if (type === SectionType.Profile) { if (type === SectionType.Profile) {
const conversation = ConversationController.getInstance().get(ourNumber); const conversation = ConversationController.getInstance().get(ourNumber);
@ -163,9 +91,6 @@ export class ActionsPanel extends React.Component<Props> {
case SectionType.Contact: case SectionType.Contact:
iconType = SessionIconType.Users; iconType = SessionIconType.Users;
break; break;
case SectionType.Channel:
iconType = SessionIconType.Globe;
break;
case SectionType.Settings: case SectionType.Settings:
iconType = SessionIconType.Gear; iconType = SessionIconType.Gear;
break; break;
@ -181,77 +106,96 @@ export class ActionsPanel extends React.Component<Props> {
<SessionIconButton <SessionIconButton
iconSize={SessionIconSize.Medium} iconSize={SessionIconSize.Medium}
iconType={iconType} iconType={iconType}
notificationCount={notificationCount} notificationCount={unreadMessageCount}
onClick={handleClick} onClick={handleClick}
isSelected={isSelected} isSelected={isSelected}
theme={this.props.theme} theme={theme}
/> />
); );
}; };
public render(): JSX.Element { const showResetSessionIDDialogIfNeeded = async () => {
const { const userED25519KeyPairHex = await UserUtils.getUserED25519KeyPair();
selectedSection, if (userED25519KeyPairHex) {
unreadMessageCount, return;
ourPrimaryConversation, }
} = this.props;
window.showResetSessionIdDialog();
};
/**
* ActionsPanel is the far left banner (not the left pane).
* The panel with buttons to switch between the message/contact/settings/theme views
*/
export const ActionsPanel = () => {
const dispatch = useDispatch();
const ourPrimaryConversation = useSelector(getOurPrimaryConversation);
// this maxi useEffect is called only once: when the component is mounted.
useEffect(() => {
void window.setClockParams();
if (
window.lokiFeatureFlags.useOnionRequests ||
window.lokiFeatureFlags.useFileOnionRequests
) {
// Initialize paths for onion requests
void OnionPaths.getInstance().buildNewOnionPaths();
}
// init the messageQueue. In the constructor, we had all not send messages
// this call does nothing except calling the constructor, which will continue sending message in the pipeline
void getMessageQueue().processAllPending();
const theme = window.Events.getThemeSetting();
window.setTheme(theme);
const newThemeObject = theme === 'dark' ? darkTheme : lightTheme;
dispatch(applyTheme(newThemeObject));
void showResetSessionIDDialogIfNeeded();
// remove existing prekeys, sign prekeys and sessions
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
const syncConfiguration = async () => {
const didWeHandleAConfigurationMessageAlready =
(await getItemById(hasSyncedInitialConfigurationItem))?.value || false;
if (didWeHandleAConfigurationMessageAlready) {
await syncConfigurationIfNeeded();
}
};
// trigger a sync message if needed for our other devices
void syncConfiguration();
}, []);
if (!ourPrimaryConversation) { if (!ourPrimaryConversation) {
window.log.warn('ActionsPanel: ourPrimaryConversation is not set'); window.log.warn('ActionsPanel: ourPrimaryConversation is not set');
return <></>; return <></>;
} }
const isProfilePageSelected = selectedSection === SectionType.Profile; useInterval(() => {
const isMessagePageSelected = selectedSection === SectionType.Message; void syncConfigurationIfNeeded();
const isContactPageSelected = selectedSection === SectionType.Contact; }, DAYS * 2);
const isSettingsPageSelected = selectedSection === SectionType.Settings;
const isMoonPageSelected = selectedSection === SectionType.Moon;
return ( return (
<div className="module-left-pane__sections-container"> <div className="module-left-pane__sections-container">
<this.Section <Section
type={SectionType.Profile} type={SectionType.Profile}
avatarPath={ourPrimaryConversation.avatarPath} 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}
/> />
<Section type={SectionType.Message} />
<Section type={SectionType.Contact} />
<Section type={SectionType.Settings} />
<SessionToastContainer /> <SessionToastContainer />
<this.Section <Section type={SectionType.Moon} />
type={SectionType.Moon}
isSelected={isMoonPageSelected}
onSelect={this.handleSectionSelect}
/>
</div> </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