feat(extension): add back buttons for opening new windows (#784)

This commit is contained in:
Nathan Bierema 2021-08-27 01:37:12 +00:00 committed by GitHub
parent f122f5227a
commit fdf3f2d94f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 175 additions and 24 deletions

View File

@ -0,0 +1,168 @@
import React, { Component } from 'react';
import { connect, ResolveThunks } from 'react-redux';
import { Button, Container, Divider, Toolbar } from 'devui';
import SliderMonitor from '@redux-devtools/app/lib/containers/monitors/Slider';
import {
liftedDispatch as liftedDispatchAction,
getReport,
} from '@redux-devtools/app/lib/actions';
import { getActiveInstance } from '@redux-devtools/app/lib/reducers/instances';
import DevTools from '@redux-devtools/app/lib/containers/DevTools';
import Dispatcher from '@redux-devtools/app/lib/containers/monitors/Dispatcher';
import TopButtons from '@redux-devtools/app/lib/components/TopButtons';
import ExportButton from '@redux-devtools/app/lib/components/buttons/ExportButton';
import ImportButton from '@redux-devtools/app/lib/components/buttons/ImportButton';
import PrintButton from '@redux-devtools/app/lib/components/buttons/PrintButton';
import MonitorSelector from '@redux-devtools/app/lib/components/MonitorSelector';
import SliderButton from '@redux-devtools/app/lib/components/buttons/SliderButton';
import DispatcherButton from '@redux-devtools/app/lib/components/buttons/DispatcherButton';
import { StoreState } from '@redux-devtools/app/lib/reducers';
import { GoRadioTower } from 'react-icons/go';
import {
MdBorderBottom,
MdBorderLeft,
MdBorderRight,
MdSave,
} from 'react-icons/md';
import { Position } from '../api/openWindow';
import { SingleMessage } from '../middlewares/api';
type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps = ResolveThunks<typeof actionCreators>;
interface OwnProps {
readonly position: string;
}
type Props = StateProps & DispatchProps & OwnProps;
declare global {
interface Window {
isElectron?: boolean;
}
}
function sendMessage(message: SingleMessage) {
chrome.runtime.sendMessage(message);
}
class Actions extends Component<Props> {
openWindow = (position: Position) => {
sendMessage({ type: 'OPEN', position });
};
openOptionsPage = () => {
if (navigator.userAgent.indexOf('Firefox') !== -1) {
sendMessage({ type: 'OPEN_OPTIONS' });
} else {
chrome.runtime.openOptionsPage();
}
};
render() {
const {
monitor,
dispatcherIsOpen,
sliderIsOpen,
options,
liftedState,
liftedDispatch,
position,
} = this.props;
const { features } = options;
return (
<Container>
<TopButtons
dispatch={liftedDispatch}
liftedState={liftedState}
options={options}
/>
<DevTools
monitor={monitor}
liftedState={liftedState}
monitorState={this.props.monitorState}
dispatch={liftedDispatch}
features={options.features}
/>
{sliderIsOpen && options.connectionId && options.features.jump && (
<SliderMonitor liftedState={liftedState} dispatch={liftedDispatch} />
)}
{dispatcherIsOpen &&
options.connectionId &&
options.features.dispatch && <Dispatcher options={options} />}
<Toolbar borderPosition="top">
{features.export && (
<Button title="Save a report" tooltipPosition="top-right">
<MdSave />
</Button>
)}
{features.export && <ExportButton />}
{features.import && <ImportButton />}
<PrintButton />
<Divider />
<MonitorSelector />
<Divider />
{features.jump && <SliderButton isOpen={this.props.sliderIsOpen} />}
{features.dispatch && (
<DispatcherButton dispatcherIsOpen={this.props.dispatcherIsOpen} />
)}
<Divider />
{!window.isElectron && position !== '#left' && (
<Button
onClick={() => {
this.openWindow('left');
}}
>
<MdBorderLeft />
</Button>
)}
{!window.isElectron && position !== '#right' && (
<Button
onClick={() => {
this.openWindow('right');
}}
>
<MdBorderRight />
</Button>
)}
{!window.isElectron && position !== '#bottom' && (
<Button
onClick={() => {
this.openWindow('bottom');
}}
>
<MdBorderBottom />
</Button>
)}
{!window.isElectron && (
<Button
onClick={() => {
this.openWindow('remote');
}}
>
<GoRadioTower />
</Button>
)}
</Toolbar>
</Container>
);
}
}
const mapStateToProps = (state: StoreState) => {
const instances = state.instances;
const id = getActiveInstance(instances);
return {
liftedState: instances.states[id],
monitorState: state.monitor.monitorState,
options: instances.options[id],
monitor: state.monitor.selected,
dispatcherIsOpen: state.monitor.dispatcherIsOpen,
sliderIsOpen: state.monitor.sliderIsOpen,
reports: state.reports.data,
};
};
const actionCreators = {
liftedDispatch: liftedDispatchAction,
getReport,
};
export default connect(mapStateToProps, actionCreators)(Actions);

View File

@ -3,12 +3,10 @@ import { connect, ResolveThunks } from 'react-redux';
import { Container, Notification } from 'devui'; import { Container, Notification } from 'devui';
import { getActiveInstance } from '@redux-devtools/app/lib/reducers/instances'; import { getActiveInstance } from '@redux-devtools/app/lib/reducers/instances';
import Settings from '@redux-devtools/app/lib/components/Settings'; import Settings from '@redux-devtools/app/lib/components/Settings';
import Actions from '@redux-devtools/app/lib/containers/Actions';
import Header from '@redux-devtools/app/lib/components/Header'; import Header from '@redux-devtools/app/lib/components/Header';
import { clearNotification } from '@redux-devtools/app/lib/actions'; import { clearNotification } from '@redux-devtools/app/lib/actions';
import { StoreState } from '@redux-devtools/app/lib/reducers'; import { StoreState } from '@redux-devtools/app/lib/reducers';
import { SingleMessage } from '../middlewares/api'; import Actions from './Actions';
import { Position } from '../api/openWindow';
type StateProps = ReturnType<typeof mapStateToProps>; type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps = ResolveThunks<typeof actionCreators>; type DispatchProps = ResolveThunks<typeof actionCreators>;
@ -17,22 +15,7 @@ interface OwnProps {
} }
type Props = StateProps & DispatchProps & OwnProps; type Props = StateProps & DispatchProps & OwnProps;
function sendMessage(message: SingleMessage) {
chrome.runtime.sendMessage(message);
}
class App extends Component<Props> { class App extends Component<Props> {
openWindow = (position: Position) => {
sendMessage({ type: 'OPEN', position });
};
openOptionsPage = () => {
if (navigator.userAgent.indexOf('Firefox') !== -1) {
sendMessage({ type: 'OPEN_OPTIONS' });
} else {
chrome.runtime.openOptionsPage();
}
};
render() { render() {
const { position, options, section, theme, notification } = this.props; const { position, options, section, theme, notification } = this.props;
if (!position && (!options || !options.features)) { if (!position && (!options || !options.features)) {
@ -56,7 +39,7 @@ class App extends Component<Props> {
body = <Settings />; body = <Settings />;
break; break;
default: default:
body = <Actions />; body = <Actions position={position} />;
} }
return ( return (

View File

@ -1,13 +1,13 @@
// Mock not supported chrome.* API for Firefox and Electron // Mock not supported chrome.* API for Firefox and Electron
(window as any).isElectron = window.isElectron =
window.navigator && window.navigator.userAgent.indexOf('Electron') !== -1; window.navigator && window.navigator.userAgent.indexOf('Electron') !== -1;
const isFirefox = navigator.userAgent.indexOf('Firefox') !== -1; const isFirefox = navigator.userAgent.indexOf('Firefox') !== -1;
// Background page only // Background page only
if ( if (
((window as any).isElectron && (window.isElectron &&
location.pathname === '/_generated_background_page.html') || location.pathname === '/_generated_background_page.html') ||
isFirefox isFirefox
) { ) {
@ -18,7 +18,7 @@ if (
addListener() {}, addListener() {},
}; };
if ((window as any).isElectron) { if (window.isElectron) {
(chrome.notifications as any) = { (chrome.notifications as any) = {
onClicked: { onClicked: {
addListener() {}, addListener() {},
@ -39,7 +39,7 @@ if (
} }
} }
if ((window as any).isElectron) { if (window.isElectron) {
if (!chrome.storage.local || !chrome.storage.local.remove) { if (!chrome.storage.local || !chrome.storage.local.remove) {
(chrome.storage as any).local = { (chrome.storage as any).local = {
set(obj: any, callback: any) { set(obj: any, callback: any) {
@ -87,6 +87,6 @@ if ((window as any).isElectron) {
}; };
} }
if (isFirefox || (window as any).isElectron) { if (isFirefox || window.isElectron) {
(chrome.storage as any).sync = chrome.storage.local; (chrome.storage as any).sync = chrome.storage.local;
} }