New top-level React root: <App />

This commit is contained in:
Josh Perez 2021-06-14 15:01:00 -04:00 committed by GitHub
parent 9a1f722545
commit 173771d34b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 457 additions and 266 deletions

View file

@ -1,6 +1,7 @@
// Copyright 2019-2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { actions as app } from './ducks/app';
import { actions as audioPlayer } from './ducks/audioPlayer';
import { actions as calling } from './ducks/calling';
import { actions as conversations } from './ducks/conversations';
@ -17,6 +18,7 @@ import { actions as updates } from './ducks/updates';
import { actions as user } from './ducks/user';
export const mapDispatchToProps = {
...app,
...audioPlayer,
...calling,
...conversations,

155
ts/state/ducks/app.ts Normal file
View file

@ -0,0 +1,155 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { ThunkAction } from 'redux-thunk';
import { StateType as RootStateType } from '../reducer';
// State
export enum AppViewType {
Blank = 'Blank',
Inbox = 'Inbox',
Installer = 'Installer',
Standalone = 'Standalone',
}
export type AppStateType = {
appView: AppViewType;
hasInitialLoadCompleted: boolean;
};
// Actions
const INITIAL_LOAD_COMPLETE = 'app/INITIAL_LOAD_COMPLETE';
const OPEN_INBOX = 'app/OPEN_INBOX';
const OPEN_INSTALLER = 'app/OPEN_INSTALLER';
const OPEN_STANDALONE = 'app/OPEN_STANDALONE';
type InitialLoadCompleteActionType = {
type: typeof INITIAL_LOAD_COMPLETE;
};
type OpenInboxActionType = {
type: typeof OPEN_INBOX;
};
type OpenInstallerActionType = {
type: typeof OPEN_INSTALLER;
};
type OpenStandaloneActionType = {
type: typeof OPEN_STANDALONE;
};
export type AppActionType =
| InitialLoadCompleteActionType
| OpenInboxActionType
| OpenInstallerActionType
| OpenStandaloneActionType;
export const actions = {
initialLoadComplete,
openInbox,
openInstaller,
openStandalone,
};
function initialLoadComplete(): InitialLoadCompleteActionType {
return {
type: INITIAL_LOAD_COMPLETE,
};
}
function openInbox(): ThunkAction<
void,
RootStateType,
unknown,
OpenInboxActionType
> {
return async dispatch => {
window.log.info('open inbox');
await window.ConversationController.loadPromise();
dispatch({
type: OPEN_INBOX,
});
};
}
function openInstaller(): ThunkAction<
void,
RootStateType,
unknown,
OpenInstallerActionType
> {
return dispatch => {
window.addSetupMenuItems();
dispatch({
type: OPEN_INSTALLER,
});
};
}
function openStandalone(): ThunkAction<
void,
RootStateType,
unknown,
OpenStandaloneActionType
> {
return dispatch => {
if (window.getEnvironment() === 'production') {
return;
}
window.addSetupMenuItems();
dispatch({
type: OPEN_STANDALONE,
});
};
}
// Reducer
export function getEmptyState(): AppStateType {
return {
appView: AppViewType.Blank,
hasInitialLoadCompleted: false,
};
}
export function reducer(
state: Readonly<AppStateType> = getEmptyState(),
action: Readonly<AppActionType>
): AppStateType {
if (action.type === OPEN_INBOX) {
return {
...state,
appView: AppViewType.Inbox,
};
}
if (action.type === INITIAL_LOAD_COMPLETE) {
return {
...state,
hasInitialLoadCompleted: true,
};
}
if (action.type === OPEN_INSTALLER) {
return {
...state,
appView: AppViewType.Installer,
};
}
if (action.type === OPEN_STANDALONE) {
return {
...state,
appView: AppViewType.Standalone,
};
}
return state;
}

View file

@ -3,6 +3,7 @@
import { combineReducers } from 'redux';
import { reducer as app } from './ducks/app';
import { reducer as audioPlayer } from './ducks/audioPlayer';
import { reducer as calling } from './ducks/calling';
import { reducer as conversations } from './ducks/conversations';
@ -19,6 +20,7 @@ import { reducer as updates } from './ducks/updates';
import { reducer as user } from './ducks/user';
export const reducer = combineReducers({
app,
audioPlayer,
calling,
conversations,

View file

@ -0,0 +1,15 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React, { ReactElement } from 'react';
import { Provider } from 'react-redux';
import { Store } from 'redux';
import { SmartApp } from '../smart/App';
export const createApp = (store: Store): ReactElement => (
<Provider store={store}>
<SmartApp />
</Provider>
);

21
ts/state/smart/App.ts Normal file
View file

@ -0,0 +1,21 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { connect } from 'react-redux';
import { App } from '../../components/App';
import { StateType } from '../reducer';
import { getIntl, getTheme } from '../selectors/user';
import { mapDispatchToProps } from '../actions';
const mapStateToProps = (state: StateType) => {
return {
...state.app,
i18n: getIntl(state),
theme: getTheme(state),
};
};
const smart = connect(mapStateToProps, mapDispatchToProps);
export const SmartApp = smart(App);

View file

@ -1,6 +1,7 @@
// Copyright 2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { actions as app } from './ducks/app';
import { actions as audioPlayer } from './ducks/audioPlayer';
import { actions as calling } from './ducks/calling';
import { actions as conversations } from './ducks/conversations';
@ -17,6 +18,7 @@ import { actions as updates } from './ducks/updates';
import { actions as user } from './ducks/user';
export type ReduxActions = {
app: typeof app;
audioPlayer: typeof audioPlayer;
calling: typeof calling;
conversations: typeof conversations;