move ActionsPanel to hooks

pull/1540/head
Audric Ackermann 4 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 { getFocusedSection } from '../state/selectors/section';
import { useDispatch, useSelector } from 'react-redux';
import {
getLeftPaneLists,
getOurPrimaryConversation,
getUnreadMessageCount,
} from '../state/selectors/conversations';
import { getLeftPaneLists } from '../state/selectors/conversations';
import {
getQuery,
getSearchResults,
isSearching,
} from '../state/selectors/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 { applyTheme, ThemeStateType } from '../state/ducks/theme';
// from https://github.com/bvaughn/react-virtualized/blob/fb3484ed5dcc41bffae8eab029126c0fb8f7abc0/source/List/types.js#L5
export type RowRendererParamsType = {
@ -119,29 +112,11 @@ const LeftPaneSection = (props: { isExpired: boolean }) => {
export const LeftPane = (props: Props) => {
const theme = useSelector(getTheme);
const dispatch = useDispatch();
const focusedSection = useSelector(getFocusedSection);
const unreadMessageCount = useSelector(getUnreadMessageCount);
const ourPrimaryConversation = useSelector(getOurPrimaryConversation);
const ourNumber = useSelector(getOurNumber);
return (
<SessionTheme theme={theme}>
<div className="module-left-pane-session">
<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))
}
/>
<ActionsPanel />
<div className="module-left-pane">
<LeftPaneSection isExpired={props.isExpired} />
</div>

@ -1,4 +1,4 @@
import React from 'react';
import React, { useEffect } from 'react';
import { SessionIconButton, SessionIconSize, SessionIconType } from './icon';
import { Avatar } from '../Avatar';
import { darkTheme, lightTheme } from '../../state/ducks/SessionTheme';
@ -17,6 +17,18 @@ import {
import { OnionPaths } from '../../session/onions';
import { getMessageQueue } from '../../session/sending';
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
export enum SectionType {
@ -28,33 +40,100 @@ export enum SectionType {
Moon,
}
interface Props {
onSectionSelected: (section: SectionType) => void;
selectedSection: SectionType;
unreadMessageCount: number;
ourPrimaryConversation: ConversationType;
ourNumber: string;
applyTheme: any;
theme: DefaultTheme;
}
const Section = (props: { type: SectionType; avatarPath?: string }) => {
const ourNumber = useSelector(getOurNumber);
const unreadMessageCount = useSelector(getUnreadMessageCount);
const theme = useSelector(getTheme);
const dispatch = useDispatch();
const { type, avatarPath } = props;
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).
* 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);
export const ActionsPanel = () => {
const dispatch = useDispatch();
// 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');
}
const ourPrimaryConversation = useSelector(getOurPrimaryConversation);
// fetch the user saved theme from the db, and apply it on mount.
public componentDidMount() {
// this maxi useEffect is called only once: when the component is mounted.
useEffect(() => {
void window.setClockParams();
if (
window.lokiFeatureFlags.useOnionRequests ||
@ -72,12 +151,14 @@ export class ActionsPanel extends React.Component<Props> {
window.setTheme(theme);
const newThemeObject = theme === 'dark' ? darkTheme : lightTheme;
this.props.applyTheme(newThemeObject);
void this.showResetSessionIDDialogIfNeeded();
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
@ -92,166 +173,29 @@ export class ActionsPanel extends React.Component<Props> {
// trigger a sync message if needed for our other devices
void syncConfiguration();
}, []);
this.syncInterval = global.setInterval(() => {
void syncConfigurationIfNeeded();
}, DAYS * 2);
if (!ourPrimaryConversation) {
window.log.warn('ActionsPanel: ourPrimaryConversation is not set');
return <></>;
}
public componentWillUnmount() {
if (this.syncInterval) {
clearInterval(this.syncInterval);
this.syncInterval = null;
}
}
useInterval(() => {
void syncConfigurationIfNeeded();
}, DAYS * 2);
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 */
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}
return (
<div className="module-left-pane__sections-container">
<Section
type={SectionType.Profile}
avatarPath={ourPrimaryConversation.avatarPath}
/>
);
};
public render(): JSX.Element {
const {
selectedSection,
unreadMessageCount,
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();
}
}
<Section type={SectionType.Message} />
<Section type={SectionType.Contact} />
<Section type={SectionType.Settings} />
<SessionToastContainer />
<Section type={SectionType.Moon} />
</div>
);
};

Loading…
Cancel
Save