From c337288efa74acec63f4ba37f1abbd2f469f068b Mon Sep 17 00:00:00 2001 From: Labhansh Agrawal Date: Wed, 19 Feb 2020 21:11:29 +0530 Subject: [PATCH] Improve containers typings and add prop types --- lib/containers/header.ts | 89 ++++++++++--------- lib/containers/hyper.tsx | 60 ++++++------- lib/containers/notifications.ts | 153 ++++++++++++++++++-------------- lib/containers/terms.ts | 140 ++++++++++++++--------------- lib/hyper.d.ts | 57 ++++-------- 5 files changed, 249 insertions(+), 250 deletions(-) diff --git a/lib/containers/header.ts b/lib/containers/header.ts index 89bd35d4..575223b9 100644 --- a/lib/containers/header.ts +++ b/lib/containers/header.ts @@ -5,8 +5,7 @@ import Header from '../components/header'; import {closeTab, changeTab, maximize, openHamburgerMenu, unmaximize, minimize, close} from '../actions/header'; import {connect} from '../utils/plugins'; import {getRootGroups} from '../selectors'; -import {HyperState} from '../hyper'; -import {Dispatch} from 'redux'; +import {HyperState, HyperDispatch} from '../hyper'; const isMac = /Mac/.test(navigator.userAgent); @@ -29,51 +28,53 @@ const getTabs = createSelector( }) ); -export const HeaderContainer = connect( - (state: HyperState) => { - return { - // active is an index - isMac, - tabs: getTabs(state), - activeMarkers: state.ui.activityMarkers, - borderColor: state.ui.borderColor, - backgroundColor: state.ui.backgroundColor, - maximized: state.ui.maximized, - fullScreen: state.ui.fullScreen, - showHamburgerMenu: state.ui.showHamburgerMenu, - showWindowControls: state.ui.showWindowControls - }; - }, - (dispatch: Dispatch) => { - return { - onCloseTab: (i: string) => { - dispatch(closeTab(i)); - }, +const mapStateToProps = (state: HyperState) => { + return { + // active is an index + isMac, + tabs: getTabs(state), + activeMarkers: state.ui.activityMarkers, + borderColor: state.ui.borderColor, + backgroundColor: state.ui.backgroundColor, + maximized: state.ui.maximized, + fullScreen: state.ui.fullScreen, + showHamburgerMenu: state.ui.showHamburgerMenu, + showWindowControls: state.ui.showWindowControls + }; +}; - onChangeTab: (i: string) => { - dispatch(changeTab(i)); - }, +const mapDispatchToProps = (dispatch: HyperDispatch) => { + return { + onCloseTab: (i: string) => { + dispatch(closeTab(i)); + }, - maximize: () => { - dispatch(maximize()); - }, + onChangeTab: (i: string) => { + dispatch(changeTab(i)); + }, - unmaximize: () => { - dispatch(unmaximize()); - }, + maximize: () => { + dispatch(maximize()); + }, - openHamburgerMenu: (coordinates: {x: number; y: number}) => { - dispatch(openHamburgerMenu(coordinates)); - }, + unmaximize: () => { + dispatch(unmaximize()); + }, - minimize: () => { - dispatch(minimize()); - }, + openHamburgerMenu: (coordinates: {x: number; y: number}) => { + dispatch(openHamburgerMenu(coordinates)); + }, - close: () => { - dispatch(close()); - } - }; - }, - null -)(Header, 'Header'); + minimize: () => { + dispatch(minimize()); + }, + + close: () => { + dispatch(close()); + } + }; +}; + +export const HeaderContainer = connect(mapStateToProps, mapDispatchToProps, null)(Header, 'Header'); + +export type HeaderConnectedProps = ReturnType & ReturnType; diff --git a/lib/containers/hyper.tsx b/lib/containers/hyper.tsx index 25a6de8a..35f00f05 100644 --- a/lib/containers/hyper.tsx +++ b/lib/containers/hyper.tsx @@ -11,12 +11,11 @@ import stylis from 'stylis'; import {HeaderContainer} from './header'; import TermsContainer from './terms'; import NotificationsContainer from './notifications'; -import {HyperState} from '../hyper'; -import {Dispatch} from 'redux'; +import {HyperState, HyperProps, HyperDispatch} from '../hyper'; const isMac = /Mac/.test(navigator.userAgent); -class Hyper extends React.PureComponent { +class Hyper extends React.PureComponent { mousetrap!: MousetrapInstance; terms: any; constructor(props: any) { @@ -26,7 +25,7 @@ class Hyper extends React.PureComponent { }; } //TODO: Remove usage of legacy and soon deprecated lifecycle methods - UNSAFE_componentWillReceiveProps(next: any) { + UNSAFE_componentWillReceiveProps(next: HyperProps) { if (this.props.backgroundColor !== next.backgroundColor) { // this can be removed when `setBackgroundColor` in electron // starts working again @@ -90,9 +89,9 @@ class Hyper extends React.PureComponent { window.focusActiveTerm = this.handleFocusActive; }; - componentDidUpdate(prev: any) { + componentDidUpdate(prev: HyperProps) { if (prev.activeSession !== this.props.activeSession) { - this.handleFocusActive(this.props.activeSession); + this.handleFocusActive(this.props.activeSession!); } } @@ -147,29 +146,30 @@ class Hyper extends React.PureComponent { } } -const HyperContainer = connect( - (state: HyperState) => { - return { - isMac, - customCSS: state.ui.css, - uiFontFamily: state.ui.uiFontFamily, - borderColor: state.ui.borderColor, - activeSession: state.sessions.activeUid, - backgroundColor: state.ui.backgroundColor, - maximized: state.ui.maximized, - fullScreen: state.ui.fullScreen, - lastConfigUpdate: state.ui._lastUpdate - }; - }, - (dispatch: Dispatch) => { - return { - execCommand: (command: any, fn: any, e: any) => { - dispatch(uiActions.execCommand(command, fn, e)); - } - }; - }, - null, - {forwardRef: true} -)(Hyper, 'Hyper'); +const mapStateToProps = (state: HyperState) => { + return { + isMac, + customCSS: state.ui.css, + uiFontFamily: state.ui.uiFontFamily, + borderColor: state.ui.borderColor, + activeSession: state.sessions.activeUid, + backgroundColor: state.ui.backgroundColor, + maximized: state.ui.maximized, + fullScreen: state.ui.fullScreen, + lastConfigUpdate: state.ui._lastUpdate + }; +}; + +const mapDispatchToProps = (dispatch: HyperDispatch) => { + return { + execCommand: (command: any, fn: any, e: any) => { + dispatch(uiActions.execCommand(command, fn, e)); + } + }; +}; + +const HyperContainer = connect(mapStateToProps, mapDispatchToProps, null, {forwardRef: true})(Hyper, 'Hyper'); export default HyperContainer; + +export type HyperConnectedProps = ReturnType & ReturnType; diff --git a/lib/containers/notifications.ts b/lib/containers/notifications.ts index 7ff1ac10..28ccc217 100644 --- a/lib/containers/notifications.ts +++ b/lib/containers/notifications.ts @@ -2,75 +2,96 @@ import Notifications from '../components/notifications'; import {installUpdate} from '../actions/updater'; import {connect} from '../utils/plugins'; import {dismissNotification} from '../actions/notifications'; -import {HyperState} from '../hyper'; -import {Dispatch} from 'redux'; +import {HyperState, HyperDispatch} from '../hyper'; -const NotificationsContainer = connect( - (state: HyperState) => { - const {ui} = state; - const {notifications} = ui; - const state_ = {}; +const mapStateToProps = (state: HyperState) => { + const {ui} = state; + const {notifications} = ui; + let state_: Partial<{ + fontShowing: boolean; + fontSize: number; + fontText: string; + resizeShowing: boolean; + cols: number | null; + rows: number | null; + updateShowing: boolean; + updateVersion: string | null; + updateNote: string | null; + updateReleaseUrl: string | null; + updateCanInstall: boolean | null; + messageShowing: boolean; + messageText: string | null; + messageURL: string | null; + messageDismissable: boolean | null; + }> = {}; - if (notifications.font) { - const fontSize = ui.fontSizeOverride || ui.fontSize; + if (notifications.font) { + const fontSize = ui.fontSizeOverride || ui.fontSize; - Object.assign(state_, { - fontShowing: true, - fontSize, - fontText: `${fontSize}px` - }); - } - - if (notifications.resize) { - const cols = ui.cols; - const rows = ui.rows; - - Object.assign(state_, { - resizeShowing: true, - cols, - rows - }); - } - - if (notifications.updates) { - Object.assign(state_, { - updateShowing: true, - updateVersion: ui.updateVersion, - updateNote: ui.updateNotes!.split('\n')[0], - updateReleaseUrl: ui.updateReleaseUrl, - updateCanInstall: ui.updateCanInstall - }); - } else if (notifications.message) { - Object.assign(state_, { - messageShowing: true, - messageText: ui.messageText, - messageURL: ui.messageURL, - messageDismissable: ui.messageDismissable - }); - } - - return state_; - }, - (dispatch: Dispatch) => { - return { - onDismissFont: () => { - dispatch(dismissNotification('font')); - }, - onDismissResize: () => { - dispatch(dismissNotification('resize')); - }, - onDismissUpdate: () => { - dispatch(dismissNotification('updates')); - }, - onDismissMessage: () => { - dispatch(dismissNotification('message')); - }, - onUpdateInstall: () => { - dispatch(installUpdate()); - } + state_ = { + ...state_, + fontShowing: true, + fontSize, + fontText: `${fontSize}px` }; - }, - null -)(Notifications, 'Notifications'); + } + + if (notifications.resize) { + const cols = ui.cols; + const rows = ui.rows; + + state_ = { + ...state_, + resizeShowing: true, + cols, + rows + }; + } + + if (notifications.updates) { + state_ = { + ...state_, + updateShowing: true, + updateVersion: ui.updateVersion, + updateNote: ui.updateNotes!.split('\n')[0], + updateReleaseUrl: ui.updateReleaseUrl, + updateCanInstall: ui.updateCanInstall + }; + } else if (notifications.message) { + state_ = { + ...state_, + messageShowing: true, + messageText: ui.messageText, + messageURL: ui.messageURL, + messageDismissable: ui.messageDismissable + }; + } + + return state_; +}; + +const mapDispatchToProps = (dispatch: HyperDispatch) => { + return { + onDismissFont: () => { + dispatch(dismissNotification('font')); + }, + onDismissResize: () => { + dispatch(dismissNotification('resize')); + }, + onDismissUpdate: () => { + dispatch(dismissNotification('updates')); + }, + onDismissMessage: () => { + dispatch(dismissNotification('message')); + }, + onUpdateInstall: () => { + dispatch(installUpdate()); + } + }; +}; + +const NotificationsContainer = connect(mapStateToProps, mapDispatchToProps, null)(Notifications, 'Notifications'); export default NotificationsContainer; + +export type NotificationsConnectedProps = ReturnType & ReturnType; diff --git a/lib/containers/terms.ts b/lib/containers/terms.ts index a6dddfd8..c749a186 100644 --- a/lib/containers/terms.ts +++ b/lib/containers/terms.ts @@ -4,80 +4,80 @@ import {resizeSession, sendSessionData, setSessionXtermTitle, setActiveSession, import {openContextMenu} from '../actions/ui'; import {getRootGroups} from '../selectors'; -import {HyperState, TermsProps} from '../hyper'; -import {Dispatch} from 'redux'; +import {HyperState, HyperDispatch} from '../hyper'; -const TermsContainer = connect( - (state: HyperState): TermsProps => { - const {sessions} = state.sessions; - return { - sessions, - cols: state.ui.cols, - rows: state.ui.rows, - scrollback: state.ui.scrollback, - termGroups: getRootGroups(state), - activeRootGroup: state.termGroups.activeRootGroup, - activeSession: state.sessions.activeUid, - customCSS: state.ui.termCSS, - write: state.sessions.write, - fontSize: state.ui.fontSizeOverride ? state.ui.fontSizeOverride : state.ui.fontSize, - fontFamily: state.ui.fontFamily, - fontWeight: state.ui.fontWeight, - fontWeightBold: state.ui.fontWeightBold, - lineHeight: state.ui.lineHeight, - letterSpacing: state.ui.letterSpacing, - uiFontFamily: state.ui.uiFontFamily, - fontSmoothing: state.ui.fontSmoothingOverride, - padding: state.ui.padding, - cursorColor: state.ui.cursorColor, - cursorAccentColor: state.ui.cursorAccentColor, - cursorShape: state.ui.cursorShape, - cursorBlink: state.ui.cursorBlink, - borderColor: state.ui.borderColor, - selectionColor: state.ui.selectionColor, - colors: state.ui.colors, - foregroundColor: state.ui.foregroundColor, - backgroundColor: state.ui.backgroundColor, - bell: state.ui.bell, - bellSoundURL: state.ui.bellSoundURL, - bellSound: state.ui.bellSound, - copyOnSelect: state.ui.copyOnSelect, - modifierKeys: state.ui.modifierKeys, - quickEdit: state.ui.quickEdit, - webGLRenderer: state.ui.webGLRenderer, - macOptionSelectionMode: state.ui.macOptionSelectionMode, - disableLigatures: state.ui.disableLigatures - }; - }, - (dispatch: Dispatch) => { - return { - onData(uid: string, data: any) { - dispatch(sendSessionData(uid, data)); - }, +const mapStateToProps = (state: HyperState) => { + const {sessions} = state.sessions; + return { + sessions, + cols: state.ui.cols, + rows: state.ui.rows, + scrollback: state.ui.scrollback, + termGroups: getRootGroups(state), + activeRootGroup: state.termGroups.activeRootGroup, + activeSession: state.sessions.activeUid, + customCSS: state.ui.termCSS, + write: state.sessions.write, + fontSize: state.ui.fontSizeOverride ? state.ui.fontSizeOverride : state.ui.fontSize, + fontFamily: state.ui.fontFamily, + fontWeight: state.ui.fontWeight, + fontWeightBold: state.ui.fontWeightBold, + lineHeight: state.ui.lineHeight, + letterSpacing: state.ui.letterSpacing, + uiFontFamily: state.ui.uiFontFamily, + fontSmoothing: state.ui.fontSmoothingOverride, + padding: state.ui.padding, + cursorColor: state.ui.cursorColor, + cursorAccentColor: state.ui.cursorAccentColor, + cursorShape: state.ui.cursorShape, + cursorBlink: state.ui.cursorBlink, + borderColor: state.ui.borderColor, + selectionColor: state.ui.selectionColor, + colors: state.ui.colors, + foregroundColor: state.ui.foregroundColor, + backgroundColor: state.ui.backgroundColor, + bell: state.ui.bell, + bellSoundURL: state.ui.bellSoundURL, + bellSound: state.ui.bellSound, + copyOnSelect: state.ui.copyOnSelect, + modifierKeys: state.ui.modifierKeys, + quickEdit: state.ui.quickEdit, + webGLRenderer: state.ui.webGLRenderer, + macOptionSelectionMode: state.ui.macOptionSelectionMode, + disableLigatures: state.ui.disableLigatures + }; +}; - onTitle(uid: string, title: string) { - dispatch(setSessionXtermTitle(uid, title)); - }, +const mapDispatchToProps = (dispatch: HyperDispatch) => { + return { + onData(uid: string, data: any) { + dispatch(sendSessionData(uid, data)); + }, - onResize(uid: string, cols: number, rows: number) { - dispatch(resizeSession(uid, cols, rows)); - }, + onTitle(uid: string, title: string) { + dispatch(setSessionXtermTitle(uid, title)); + }, - onActive(uid: string) { - dispatch(setActiveSession(uid)); - }, - toggleSearch(uid: string) { - dispatch(onSearch(uid)); - }, + onResize(uid: string, cols: number, rows: number) { + dispatch(resizeSession(uid, cols, rows)); + }, - onContextMenu(uid: string, selection: any) { - dispatch(setActiveSession(uid)); - dispatch(openContextMenu(uid, selection)); - } - }; - }, - null, - {forwardRef: true} -)(Terms, 'Terms'); + onActive(uid: string) { + dispatch(setActiveSession(uid)); + }, + toggleSearch(uid: string) { + dispatch(onSearch(uid)); + }, + + onContextMenu(uid: string, selection: any) { + dispatch(setActiveSession(uid)); + dispatch(openContextMenu(uid, selection)); + } + }; +}; + +const TermsContainer = connect(mapStateToProps, mapDispatchToProps, null, {forwardRef: true})(Terms, 'Terms'); export default TermsContainer; + +export type TermsConnectedProps = ReturnType & ReturnType; diff --git a/lib/hyper.d.ts b/lib/hyper.d.ts index 544c9fff..30f0538e 100644 --- a/lib/hyper.d.ts +++ b/lib/hyper.d.ts @@ -185,44 +185,21 @@ import configureStore from './store/configure-store'; export type HyperThunkDispatch = ThunkDispatch; export type HyperDispatch = ReturnType['dispatch']; -export type TermsProps = { - activeRootGroup: string | null; - activeSession: string | null; +type extensionProps = Partial<{ + customChildren: any; + customChildrenBefore: any; customCSS: string; - fontSmoothing: string; - termGroups: Immutable[]; -} & immutableRecord< - Pick< - uiState, - | 'backgroundColor' - | 'bell' - | 'bellSound' - | 'bellSoundURL' - | 'borderColor' - | 'colors' - | 'cols' - | 'copyOnSelect' - | 'cursorAccentColor' - | 'cursorBlink' - | 'cursorColor' - | 'cursorShape' - | 'disableLigatures' - | 'fontFamily' - | 'fontSize' - | 'fontWeight' - | 'fontWeightBold' - | 'foregroundColor' - | 'letterSpacing' - | 'lineHeight' - | 'macOptionSelectionMode' - | 'modifierKeys' - | 'padding' - | 'quickEdit' - | 'rows' - | 'scrollback' - | 'selectionColor' - | 'uiFontFamily' - | 'webGLRenderer' - > -> & - immutableRecord>; + customInnerChildren: any; +}>; + +import {HeaderConnectedProps} from './containers/header'; +export type HeaderProps = HeaderConnectedProps & extensionProps; + +import {HyperConnectedProps} from './containers/hyper'; +export type HyperProps = HyperConnectedProps & extensionProps; + +import {NotificationsConnectedProps} from './containers/notifications'; +export type NotificationsProps = NotificationsConnectedProps & extensionProps; + +import {TermsConnectedProps} from './containers/terms'; +export type TermsProps = TermsConnectedProps & extensionProps & {ref_: any};