mirror of
https://github.com/responsively-org/responsively-app
synced 2024-11-10 14:54:12 +00:00
Formatting fixed
This commit is contained in:
parent
a3340d43d8
commit
e11664a60d
122 changed files with 8588 additions and 7241 deletions
|
@ -1,13 +1,14 @@
|
|||
{
|
||||
"overrides": [
|
||||
{
|
||||
"files": [".prettierrc", ".babelrc", ".eslintrc", ".stylelintrc"],
|
||||
"options": {
|
||||
"parser": "json"
|
||||
}
|
||||
}
|
||||
],
|
||||
"singleQuote": true,
|
||||
"bracketSpacing": false,
|
||||
"trailingComma": "es5"
|
||||
"overrides": [
|
||||
{
|
||||
"files": [".prettierrc", ".babelrc", ".eslintrc", ".stylelintrc"],
|
||||
"options": {
|
||||
"parser": "json"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tabWidth": 4,
|
||||
"singleQuote": true,
|
||||
"bracketSpacing": false,
|
||||
"trailingComma": "es5"
|
||||
}
|
||||
|
|
60
desktop-app/.vscode/settings.json
vendored
60
desktop-app/.vscode/settings.json
vendored
|
@ -1,36 +1,36 @@
|
|||
{
|
||||
"editor.formatOnSave": true,
|
||||
"files.associations": {
|
||||
".babelrc": "jsonc",
|
||||
".eslintrc": "jsonc",
|
||||
".prettierrc": "jsonc",
|
||||
"editor.formatOnSave": true,
|
||||
"files.associations": {
|
||||
".babelrc": "jsonc",
|
||||
".eslintrc": "jsonc",
|
||||
".prettierrc": "jsonc",
|
||||
|
||||
".stylelintrc": "json",
|
||||
".stylelintrc": "json",
|
||||
|
||||
".dockerignore": "ignore",
|
||||
".eslintignore": "ignore",
|
||||
".flowconfig": "ignore"
|
||||
},
|
||||
".dockerignore": "ignore",
|
||||
".eslintignore": "ignore",
|
||||
".flowconfig": "ignore"
|
||||
},
|
||||
|
||||
"javascript.validate.enable": false,
|
||||
"javascript.format.enable": false,
|
||||
"typescript.validate.enable": false,
|
||||
"typescript.format.enable": false,
|
||||
"javascript.validate.enable": false,
|
||||
"javascript.format.enable": false,
|
||||
"typescript.validate.enable": false,
|
||||
"typescript.format.enable": false,
|
||||
|
||||
"flow.useNPMPackagedFlow": true,
|
||||
"search.exclude": {
|
||||
".git": true,
|
||||
".eslintcache": true,
|
||||
"app/dist": true,
|
||||
"app/main.prod.js": true,
|
||||
"app/main.prod.js.map": true,
|
||||
"bower_components": true,
|
||||
"dll": true,
|
||||
"flow-typed": true,
|
||||
"release": true,
|
||||
"node_modules": true,
|
||||
"npm-debug.log.*": true,
|
||||
"test/**/__snapshots__": true,
|
||||
"yarn.lock": true
|
||||
}
|
||||
"flow.useNPMPackagedFlow": true,
|
||||
"search.exclude": {
|
||||
".git": true,
|
||||
".eslintcache": true,
|
||||
"app/dist": true,
|
||||
"app/main.prod.js": true,
|
||||
"app/main.prod.js.map": true,
|
||||
"bower_components": true,
|
||||
"dll": true,
|
||||
"flow-typed": true,
|
||||
"release": true,
|
||||
"node_modules": true,
|
||||
"npm-debug.log.*": true,
|
||||
"test/**/__snapshots__": true,
|
||||
"yarn.lock": true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,16 +7,16 @@ import LeftIconsPaneContainer from './containers/LeftIconsPaneContainer';
|
|||
import styles from './layout.css';
|
||||
|
||||
export default () => (
|
||||
<App>
|
||||
<div className={styles.appRoot}>
|
||||
<div className={styles.iconColumn}>
|
||||
<LeftIconsPaneContainer />
|
||||
</div>
|
||||
<div className={styles.contentColumn}>
|
||||
<Switch>
|
||||
<Route path={routes.HOME} component={Browser} />
|
||||
</Switch>
|
||||
</div>
|
||||
</div>
|
||||
</App>
|
||||
<App>
|
||||
<div className={styles.appRoot}>
|
||||
<div className={styles.iconColumn}>
|
||||
<LeftIconsPaneContainer />
|
||||
</div>
|
||||
<div className={styles.contentColumn}>
|
||||
<Switch>
|
||||
<Route path={routes.HOME} component={Browser} />
|
||||
</Switch>
|
||||
</div>
|
||||
</div>
|
||||
</App>
|
||||
);
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
import type {Dispatch, BrowserStateType} from '../reducers/types';
|
||||
import pubsub from 'pubsub.js';
|
||||
import {
|
||||
SCROLL_DOWN,
|
||||
SCROLL_UP,
|
||||
NAVIGATION_BACK,
|
||||
NAVIGATION_FORWARD,
|
||||
NAVIGATION_RELOAD,
|
||||
SCREENSHOT_ALL_DEVICES,
|
||||
FLIP_ORIENTATION_ALL_DEVICES,
|
||||
ENABLE_INSPECTOR_ALL_DEVICES,
|
||||
SCROLL_DOWN,
|
||||
SCROLL_UP,
|
||||
NAVIGATION_BACK,
|
||||
NAVIGATION_FORWARD,
|
||||
NAVIGATION_RELOAD,
|
||||
SCREENSHOT_ALL_DEVICES,
|
||||
FLIP_ORIENTATION_ALL_DEVICES,
|
||||
ENABLE_INSPECTOR_ALL_DEVICES,
|
||||
} from '../constants/pubsubEvents';
|
||||
|
||||
export const NEW_ADDRESS = 'NEW_ADDRESS';
|
||||
|
@ -24,320 +24,320 @@ export const NEW_ACTIVE_DEVICE = 'NEW_ACTIVE_DEVICE';
|
|||
export const NEW_FILTERS = 'NEW_FILTERS';
|
||||
|
||||
export function newAddress(address) {
|
||||
return {
|
||||
type: NEW_ADDRESS,
|
||||
address,
|
||||
};
|
||||
return {
|
||||
type: NEW_ADDRESS,
|
||||
address,
|
||||
};
|
||||
}
|
||||
|
||||
export function newHomepage(homepage) {
|
||||
return {
|
||||
type: NEW_HOMEPAGE,
|
||||
homepage,
|
||||
};
|
||||
return {
|
||||
type: NEW_HOMEPAGE,
|
||||
homepage,
|
||||
};
|
||||
}
|
||||
|
||||
export function newZoomLevel(zoomLevel) {
|
||||
return {
|
||||
type: NEW_ZOOM_LEVEL,
|
||||
zoomLevel,
|
||||
};
|
||||
return {
|
||||
type: NEW_ZOOM_LEVEL,
|
||||
zoomLevel,
|
||||
};
|
||||
}
|
||||
|
||||
export function newScrollPosition(scrollPosition) {
|
||||
return {
|
||||
type: NEW_SCROLL_POSITION,
|
||||
scrollPosition,
|
||||
};
|
||||
return {
|
||||
type: NEW_SCROLL_POSITION,
|
||||
scrollPosition,
|
||||
};
|
||||
}
|
||||
|
||||
export function newNavigatorStatus(navigatorStatus) {
|
||||
return {
|
||||
type: NEW_NAVIGATOR_STATUS,
|
||||
navigatorStatus,
|
||||
};
|
||||
return {
|
||||
type: NEW_NAVIGATOR_STATUS,
|
||||
navigatorStatus,
|
||||
};
|
||||
}
|
||||
|
||||
export function newDrawerContent(drawer) {
|
||||
return {
|
||||
type: NEW_DRAWER_CONTENT,
|
||||
drawer,
|
||||
};
|
||||
return {
|
||||
type: NEW_DRAWER_CONTENT,
|
||||
drawer,
|
||||
};
|
||||
}
|
||||
|
||||
export function newPreviewerConfig(previewer) {
|
||||
return {
|
||||
type: NEW_PREVIEWER_CONFIG,
|
||||
previewer,
|
||||
};
|
||||
return {
|
||||
type: NEW_PREVIEWER_CONFIG,
|
||||
previewer,
|
||||
};
|
||||
}
|
||||
|
||||
export function newActiveDevices(devices) {
|
||||
return {
|
||||
type: NEW_ACTIVE_DEVICES,
|
||||
devices,
|
||||
};
|
||||
return {
|
||||
type: NEW_ACTIVE_DEVICES,
|
||||
devices,
|
||||
};
|
||||
}
|
||||
|
||||
export function newActiveDevice(device) {
|
||||
return {
|
||||
type: NEW_ACTIVE_DEVICE,
|
||||
device,
|
||||
};
|
||||
return {
|
||||
type: NEW_ACTIVE_DEVICE,
|
||||
device,
|
||||
};
|
||||
}
|
||||
|
||||
export function newFilters(filters) {
|
||||
return {
|
||||
type: NEW_FILTERS,
|
||||
filters,
|
||||
};
|
||||
return {
|
||||
type: NEW_FILTERS,
|
||||
filters,
|
||||
};
|
||||
}
|
||||
|
||||
export function onAddressChange(newURL) {
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
const {
|
||||
browser: {address},
|
||||
} = getState();
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
const {
|
||||
browser: {address},
|
||||
} = getState();
|
||||
|
||||
console.log('newURL', newURL);
|
||||
console.log('newURL', newURL);
|
||||
|
||||
if (newURL === address) {
|
||||
return;
|
||||
}
|
||||
if (newURL === address) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(newAddress(newURL));
|
||||
};
|
||||
dispatch(newAddress(newURL));
|
||||
};
|
||||
}
|
||||
|
||||
export function onZoomChange(newLevel) {
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
const {
|
||||
browser: {zoomLevel},
|
||||
} = getState();
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
const {
|
||||
browser: {zoomLevel},
|
||||
} = getState();
|
||||
|
||||
if (newLevel === zoomLevel) {
|
||||
return;
|
||||
}
|
||||
if (newLevel === zoomLevel) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(newZoomLevel(newLevel));
|
||||
};
|
||||
dispatch(newZoomLevel(newLevel));
|
||||
};
|
||||
}
|
||||
|
||||
export function onScrollChange({x: newX, y: newY}) {
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
const {
|
||||
browser: {
|
||||
scrollPosition: {x, y},
|
||||
},
|
||||
} = getState();
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
const {
|
||||
browser: {
|
||||
scrollPosition: {x, y},
|
||||
},
|
||||
} = getState();
|
||||
|
||||
if (newX === x && newY === y) {
|
||||
return;
|
||||
}
|
||||
if (newX === x && newY === y) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(newScrollPosition({x: newX, y: newY}));
|
||||
};
|
||||
dispatch(newScrollPosition({x: newX, y: newY}));
|
||||
};
|
||||
}
|
||||
|
||||
export function updateNavigatorStatus({
|
||||
backEnabled: newBackEnabled,
|
||||
forwardEnabled: newForwardEnabled,
|
||||
backEnabled: newBackEnabled,
|
||||
forwardEnabled: newForwardEnabled,
|
||||
}) {
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
const {
|
||||
browser: {
|
||||
navigatorStatus: {backEnabled, forwardEnabled},
|
||||
},
|
||||
} = getState();
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
const {
|
||||
browser: {
|
||||
navigatorStatus: {backEnabled, forwardEnabled},
|
||||
},
|
||||
} = getState();
|
||||
|
||||
if (
|
||||
newBackEnabled === backEnabled &&
|
||||
newForwardEnabled === forwardEnabled
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
newBackEnabled === backEnabled &&
|
||||
newForwardEnabled === forwardEnabled
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(
|
||||
newNavigatorStatus({
|
||||
backEnabled: newBackEnabled,
|
||||
forwardEnabled: newForwardEnabled,
|
||||
})
|
||||
);
|
||||
};
|
||||
dispatch(
|
||||
newNavigatorStatus({
|
||||
backEnabled: newBackEnabled,
|
||||
forwardEnabled: newForwardEnabled,
|
||||
})
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export function openDrawerAndSetContent(_newDrawerContent) {
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
const {
|
||||
browser: {
|
||||
drawer: {drawerContent, open},
|
||||
},
|
||||
} = getState();
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
const {
|
||||
browser: {
|
||||
drawer: {drawerContent, open},
|
||||
},
|
||||
} = getState();
|
||||
|
||||
if (_newDrawerContent === drawerContent && open) {
|
||||
return;
|
||||
}
|
||||
if (_newDrawerContent === drawerContent && open) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(
|
||||
newDrawerContent({
|
||||
content: _newDrawerContent,
|
||||
open: true,
|
||||
})
|
||||
);
|
||||
};
|
||||
dispatch(
|
||||
newDrawerContent({
|
||||
content: _newDrawerContent,
|
||||
open: true,
|
||||
})
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export function changeDrawerOpenState(newOpenState) {
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
const {
|
||||
browser: {drawer},
|
||||
} = getState();
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
const {
|
||||
browser: {drawer},
|
||||
} = getState();
|
||||
|
||||
if (newOpenState === drawer.open) {
|
||||
return;
|
||||
}
|
||||
if (newOpenState === drawer.open) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(
|
||||
newDrawerContent({
|
||||
...drawer,
|
||||
open: newOpenState,
|
||||
})
|
||||
);
|
||||
};
|
||||
dispatch(
|
||||
newDrawerContent({
|
||||
...drawer,
|
||||
open: newOpenState,
|
||||
})
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export function setPreviewLayout(newLayout) {
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
const {
|
||||
browser: {previewer},
|
||||
} = getState();
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
const {
|
||||
browser: {previewer},
|
||||
} = getState();
|
||||
|
||||
if (previewer.layout === newLayout) {
|
||||
return;
|
||||
}
|
||||
if (previewer.layout === newLayout) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(
|
||||
newPreviewerConfig({
|
||||
...previewer,
|
||||
layout: newLayout,
|
||||
})
|
||||
);
|
||||
};
|
||||
dispatch(
|
||||
newPreviewerConfig({
|
||||
...previewer,
|
||||
layout: newLayout,
|
||||
})
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export function setActiveDevices(newDevices) {
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
const {
|
||||
browser: {devices},
|
||||
} = getState();
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
const {
|
||||
browser: {devices},
|
||||
} = getState();
|
||||
|
||||
if (false) {
|
||||
//TODO verify the devices list and return if the order of the devices didn;t change;
|
||||
return;
|
||||
}
|
||||
if (false) {
|
||||
//TODO verify the devices list and return if the order of the devices didn;t change;
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(newActiveDevices(newDevices));
|
||||
};
|
||||
dispatch(newActiveDevices(newDevices));
|
||||
};
|
||||
}
|
||||
|
||||
export function addNewDevice(newDevice) {
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
if (newDevice.added) {
|
||||
dispatch(newActiveDevice(newDevice));
|
||||
}
|
||||
};
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
if (newDevice.added) {
|
||||
dispatch(newActiveDevice(newDevice));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function toggleFilter(filterField, value) {
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
const {
|
||||
browser: {filters},
|
||||
} = getState();
|
||||
if (!filters[filterField]) {
|
||||
filters[filterField] = [];
|
||||
}
|
||||
const index = filters[filterField].indexOf(value);
|
||||
if (index === -1) {
|
||||
filters[filterField].push(value);
|
||||
} else {
|
||||
filters[filterField].splice(index, 1);
|
||||
}
|
||||
dispatch(newFilters(filters));
|
||||
};
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
const {
|
||||
browser: {filters},
|
||||
} = getState();
|
||||
if (!filters[filterField]) {
|
||||
filters[filterField] = [];
|
||||
}
|
||||
const index = filters[filterField].indexOf(value);
|
||||
if (index === -1) {
|
||||
filters[filterField].push(value);
|
||||
} else {
|
||||
filters[filterField].splice(index, 1);
|
||||
}
|
||||
dispatch(newFilters(filters));
|
||||
};
|
||||
}
|
||||
|
||||
export function goToHomepage() {
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
const {
|
||||
browser: {homepage, address},
|
||||
} = getState();
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
const {
|
||||
browser: {homepage, address},
|
||||
} = getState();
|
||||
|
||||
if (homepage === address) {
|
||||
return;
|
||||
}
|
||||
if (homepage === address) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(newAddress(homepage));
|
||||
};
|
||||
dispatch(newAddress(homepage));
|
||||
};
|
||||
}
|
||||
|
||||
export function setCurrentAddressAsHomepage() {
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
const {
|
||||
browser: {homepage, address},
|
||||
} = getState();
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
const {
|
||||
browser: {homepage, address},
|
||||
} = getState();
|
||||
|
||||
if (homepage === address) {
|
||||
return;
|
||||
}
|
||||
if (homepage === address) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(newHomepage(address));
|
||||
};
|
||||
dispatch(newHomepage(address));
|
||||
};
|
||||
}
|
||||
|
||||
export function triggerScrollDown() {
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
pubsub.publish(SCROLL_DOWN);
|
||||
};
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
pubsub.publish(SCROLL_DOWN);
|
||||
};
|
||||
}
|
||||
|
||||
export function screenshotAllDevices() {
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
pubsub.publish(SCREENSHOT_ALL_DEVICES, [{now: new Date()}]);
|
||||
};
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
pubsub.publish(SCREENSHOT_ALL_DEVICES, [{now: new Date()}]);
|
||||
};
|
||||
}
|
||||
|
||||
export function flipOrientationAllDevices() {
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
pubsub.publish(FLIP_ORIENTATION_ALL_DEVICES);
|
||||
};
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
pubsub.publish(FLIP_ORIENTATION_ALL_DEVICES);
|
||||
};
|
||||
}
|
||||
|
||||
export function enableInpector() {
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
pubsub.publish(ENABLE_INSPECTOR_ALL_DEVICES);
|
||||
};
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
pubsub.publish(ENABLE_INSPECTOR_ALL_DEVICES);
|
||||
};
|
||||
}
|
||||
|
||||
export function triggerScrollUp() {
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
pubsub.publish(SCROLL_UP);
|
||||
};
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
pubsub.publish(SCROLL_UP);
|
||||
};
|
||||
}
|
||||
|
||||
export function triggerNavigationBack() {
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
pubsub.publish(NAVIGATION_BACK);
|
||||
};
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
pubsub.publish(NAVIGATION_BACK);
|
||||
};
|
||||
}
|
||||
|
||||
export function triggerNavigationForward() {
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
pubsub.publish(NAVIGATION_FORWARD);
|
||||
};
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
pubsub.publish(NAVIGATION_FORWARD);
|
||||
};
|
||||
}
|
||||
|
||||
export function triggerNavigationReload() {
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
pubsub.publish(NAVIGATION_RELOAD);
|
||||
};
|
||||
return (dispatch: Dispatch, getState: RootStateType) => {
|
||||
pubsub.publish(NAVIGATION_RELOAD);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,70 +1,72 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Roboto&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<meta charset="utf-8" />
|
||||
<title>Responsively</title>
|
||||
<script type="text/javascript">
|
||||
// prettier-ignore
|
||||
window.heap=window.heap||[],heap.load=function(e,t){window.heap.appid=e,window.heap.config=t=t||{};var r=t.forceSSL||"https:"===document.location.protocol,a=document.createElement("script");a.type="text/javascript",a.async=!0,a.src=(r?"https:":"http:")+"//cdn.heapanalytics.com/js/heap-"+e+".js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(a,n);for(var o=function(e){return function(){heap.push([e].concat(Array.prototype.slice.call(arguments,0)))}},p=["addEventProperties","addUserProperties","clearEventProperties","identify","resetIdentity","removeEventProperty","setEventProperties","track","unsetEventProperty"],c=0;c<p.length;c++)heap[p[c]]=o(p[c])};
|
||||
heap.load('3453744655');
|
||||
</script>
|
||||
<script>
|
||||
(function() {
|
||||
if (!process.env.HOT) {
|
||||
const link = document.createElement('link');
|
||||
link.rel = 'stylesheet';
|
||||
link.href = './dist/style.css';
|
||||
// HACK: Writing the script path should be done with webpack
|
||||
document.getElementsByTagName('head')[0].appendChild(link);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script>
|
||||
{
|
||||
const scripts = [];
|
||||
<head>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Roboto&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<meta charset="utf-8" />
|
||||
<title>Responsively</title>
|
||||
<script type="text/javascript">
|
||||
// prettier-ignore
|
||||
window.heap=window.heap||[],heap.load=function(e,t){window.heap.appid=e,window.heap.config=t=t||{};var r=t.forceSSL||"https:"===document.location.protocol,a=document.createElement("script");a.type="text/javascript",a.async=!0,a.src=(r?"https:":"http:")+"//cdn.heapanalytics.com/js/heap-"+e+".js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(a,n);for(var o=function(e){return function(){heap.push([e].concat(Array.prototype.slice.call(arguments,0)))}},p=["addEventProperties","addUserProperties","clearEventProperties","identify","resetIdentity","removeEventProperty","setEventProperties","track","unsetEventProperty"],c=0;c<p.length;c++)heap[p[c]]=o(p[c])};
|
||||
heap.load('3453744655');
|
||||
</script>
|
||||
<script>
|
||||
(function() {
|
||||
if (!process.env.HOT) {
|
||||
const link = document.createElement('link');
|
||||
link.rel = 'stylesheet';
|
||||
link.href = './dist/style.css';
|
||||
// HACK: Writing the script path should be done with webpack
|
||||
document.getElementsByTagName('head')[0].appendChild(link);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script>
|
||||
{
|
||||
const scripts = [];
|
||||
|
||||
// Dynamically insert the DLL script in development env in the
|
||||
// renderer process
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
scripts.push('../dll/renderer.dev.dll.js');
|
||||
}
|
||||
// Dynamically insert the DLL script in development env in the
|
||||
// renderer process
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
scripts.push('../dll/renderer.dev.dll.js');
|
||||
}
|
||||
|
||||
// Dynamically insert the bundled app script in the renderer process
|
||||
const port = process.env.PORT || 1212;
|
||||
scripts.push(
|
||||
process.env.HOT
|
||||
? 'http://localhost:' + port + '/dist/renderer.dev.js'
|
||||
: './dist/renderer.prod.js'
|
||||
);
|
||||
// Dynamically insert the bundled app script in the renderer process
|
||||
const port = process.env.PORT || 1212;
|
||||
scripts.push(
|
||||
process.env.HOT
|
||||
? 'http://localhost:' + port + '/dist/renderer.dev.js'
|
||||
: './dist/renderer.prod.js'
|
||||
);
|
||||
|
||||
document.write(
|
||||
scripts
|
||||
.map(script => `<script defer src="${script}"><\/script>`)
|
||||
.join('')
|
||||
);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
// @see https://docs.headwayapp.co/widget for more configuration options.
|
||||
var HW_config = {
|
||||
selector: '#headway', // CSS selector where to inject the badge
|
||||
account: 'xdYpn7',
|
||||
};
|
||||
setTimeout(() => {
|
||||
var headwayScript = document.createElement('script');
|
||||
headwayScript.setAttribute(
|
||||
'src',
|
||||
'https://cdn.headwayapp.co/widget.js'
|
||||
);
|
||||
document.head.appendChild(headwayScript);
|
||||
}, 4000);
|
||||
</script>
|
||||
</body>
|
||||
document.write(
|
||||
scripts
|
||||
.map(
|
||||
script => `<script defer src="${script}"><\/script>`
|
||||
)
|
||||
.join('')
|
||||
);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
// @see https://docs.headwayapp.co/widget for more configuration options.
|
||||
var HW_config = {
|
||||
selector: '#headway', // CSS selector where to inject the badge
|
||||
account: 'xdYpn7',
|
||||
};
|
||||
setTimeout(() => {
|
||||
var headwayScript = document.createElement('script');
|
||||
headwayScript.setAttribute(
|
||||
'src',
|
||||
'https://cdn.headwayapp.co/widget.js'
|
||||
);
|
||||
document.head.appendChild(headwayScript);
|
||||
}, 4000);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -10,97 +10,107 @@ import styles from './style.css';
|
|||
import {Tooltip} from '@material-ui/core';
|
||||
|
||||
type Props = {
|
||||
address: string,
|
||||
onChange: () => void,
|
||||
address: string,
|
||||
onChange: () => void,
|
||||
};
|
||||
|
||||
type State = {
|
||||
address: string,
|
||||
address: string,
|
||||
};
|
||||
|
||||
class AddressBar extends React.Component<Props> {
|
||||
props: Props;
|
||||
state: State;
|
||||
props: Props;
|
||||
state: State;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
userTypedAddress: props.address,
|
||||
previousAddress: props.address,
|
||||
};
|
||||
this.inputRef = React.createRef();
|
||||
}
|
||||
|
||||
static getDerivedStateFromProps(props, state) {
|
||||
if (props.address != state.previousAddress) {
|
||||
return {userTypedAddress: props.address, previousAddress: props.address};
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
userTypedAddress: props.address,
|
||||
previousAddress: props.address,
|
||||
};
|
||||
this.inputRef = React.createRef();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className={styles.addressBarContainer}>
|
||||
<input
|
||||
ref={this.inputRef}
|
||||
type="text"
|
||||
id="adress"
|
||||
name="address"
|
||||
className={styles.addressInput}
|
||||
placeholder="https://your-website.com"
|
||||
value={this.state.userTypedAddress}
|
||||
onKeyDown={this._handleKeyDown}
|
||||
onChange={e => this.setState({userTypedAddress: e.target.value})}
|
||||
/>
|
||||
<div
|
||||
className={cx(styles.goButton, commonStyles.icons, {
|
||||
[commonStyles.enabled]: this.props.address !== this.props.homepage,
|
||||
[commonStyles.disabled]: this.props.address == this.props.homepage,
|
||||
})}
|
||||
>
|
||||
<Tooltip title="Set a Homepage">
|
||||
<div
|
||||
className={cx(commonStyles.flexAlignVerticalMiddle)}
|
||||
onClick={this.props.setHomepage}
|
||||
>
|
||||
<HomePlusIcon
|
||||
height={22}
|
||||
width={22}
|
||||
color={iconsColor}
|
||||
padding={5}
|
||||
/>
|
||||
static getDerivedStateFromProps(props, state) {
|
||||
if (props.address != state.previousAddress) {
|
||||
return {
|
||||
userTypedAddress: props.address,
|
||||
previousAddress: props.address,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className={styles.addressBarContainer}>
|
||||
<input
|
||||
ref={this.inputRef}
|
||||
type="text"
|
||||
id="adress"
|
||||
name="address"
|
||||
className={styles.addressInput}
|
||||
placeholder="https://your-website.com"
|
||||
value={this.state.userTypedAddress}
|
||||
onKeyDown={this._handleKeyDown}
|
||||
onChange={e =>
|
||||
this.setState({userTypedAddress: e.target.value})
|
||||
}
|
||||
/>
|
||||
<div
|
||||
className={cx(styles.goButton, commonStyles.icons, {
|
||||
[commonStyles.enabled]:
|
||||
this.props.address !== this.props.homepage,
|
||||
[commonStyles.disabled]:
|
||||
this.props.address == this.props.homepage,
|
||||
})}
|
||||
>
|
||||
<Tooltip title="Set a Homepage">
|
||||
<div
|
||||
className={cx(commonStyles.flexAlignVerticalMiddle)}
|
||||
onClick={this.props.setHomepage}
|
||||
>
|
||||
<HomePlusIcon
|
||||
height={22}
|
||||
width={22}
|
||||
color={iconsColor}
|
||||
padding={5}
|
||||
/>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
_handleKeyDown = e => {
|
||||
if (e.key === 'Enter') {
|
||||
this.inputRef.current.blur();
|
||||
this._onChange();
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
_onChange = () => {
|
||||
if (!this.state.userTypedAddress) {
|
||||
return;
|
||||
}
|
||||
this.props.onChange &&
|
||||
this.props.onChange(this._normalize(this.state.userTypedAddress));
|
||||
};
|
||||
_handleKeyDown = e => {
|
||||
if (e.key === 'Enter') {
|
||||
this.inputRef.current.blur();
|
||||
this._onChange();
|
||||
}
|
||||
};
|
||||
|
||||
_normalize = address => {
|
||||
if (!address.startsWith('http')) {
|
||||
let protocol = 'https://';
|
||||
if (address.startsWith('localhost') || address.startsWith('127.0.0.1')) {
|
||||
protocol = 'http://';
|
||||
}
|
||||
address = `${protocol}${address}`;
|
||||
}
|
||||
return address;
|
||||
};
|
||||
_onChange = () => {
|
||||
if (!this.state.userTypedAddress) {
|
||||
return;
|
||||
}
|
||||
this.props.onChange &&
|
||||
this.props.onChange(this._normalize(this.state.userTypedAddress));
|
||||
};
|
||||
|
||||
_normalize = address => {
|
||||
if (!address.startsWith('http')) {
|
||||
let protocol = 'https://';
|
||||
if (
|
||||
address.startsWith('localhost') ||
|
||||
address.startsWith('127.0.0.1')
|
||||
) {
|
||||
protocol = 'http://';
|
||||
}
|
||||
address = `${protocol}${address}`;
|
||||
}
|
||||
return address;
|
||||
};
|
||||
}
|
||||
|
||||
export default AddressBar;
|
||||
|
|
|
@ -12,14 +12,14 @@ import commonStyles from '../common.styles.css';
|
|||
import DevicesOverviewContainer from '../../containers/DevicesOverviewContainer';
|
||||
|
||||
export default function DeviceDrawer(props) {
|
||||
return (
|
||||
<div>
|
||||
<DevicesOverviewContainer />
|
||||
<PreviewerLayoutSelector
|
||||
value={props.browser.previewer.layout}
|
||||
onChange={val => props.setPreviewLayout(val.value)}
|
||||
/>
|
||||
<QuickFilterDevicesContainer />
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div>
|
||||
<DevicesOverviewContainer />
|
||||
<PreviewerLayoutSelector
|
||||
value={props.browser.previewer.layout}
|
||||
onChange={val => props.setPreviewLayout(val.value)}
|
||||
/>
|
||||
<QuickFilterDevicesContainer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -21,12 +21,12 @@ import FormGroup from '@material-ui/core/FormGroup';
|
|||
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
||||
//import Switch from '@material-ui/core/Switch';
|
||||
import {
|
||||
Typography,
|
||||
Grid,
|
||||
MenuItem,
|
||||
NativeSelect,
|
||||
RadioGroup,
|
||||
Radio,
|
||||
Typography,
|
||||
Grid,
|
||||
MenuItem,
|
||||
NativeSelect,
|
||||
RadioGroup,
|
||||
Radio,
|
||||
} from '@material-ui/core';
|
||||
import RadioButtonUncheckedIcon from '@material-ui/icons/RadioButtonUnchecked';
|
||||
import RadioButtonCheckedIcon from '@material-ui/icons/RadioButtonChecked';
|
||||
|
@ -37,402 +37,426 @@ import {lightIconsColor, themeColor} from '../../../constants/colors';
|
|||
import Switch from 'react-switch';
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
fab: {
|
||||
position: 'absolute',
|
||||
top: theme.spacing(10),
|
||||
right: theme.spacing(3),
|
||||
},
|
||||
extendedIcon: {
|
||||
marginRight: theme.spacing(1),
|
||||
},
|
||||
inputField: {
|
||||
marginRight: '1%',
|
||||
width: '49%',
|
||||
},
|
||||
formControl: {
|
||||
margin: theme.spacing(1),
|
||||
minWidth: 120,
|
||||
},
|
||||
select: {
|
||||
marginTop: theme.spacing(2),
|
||||
maxWidth: 150,
|
||||
},
|
||||
radioIcon: {
|
||||
color: lightIconsColor,
|
||||
},
|
||||
inputAdornment: {
|
||||
color: lightIconsColor,
|
||||
},
|
||||
userAgent: {
|
||||
fontSize: 12,
|
||||
},
|
||||
actionButton: {
|
||||
padding: '10px !important',
|
||||
borderRadius: '5px !important',
|
||||
},
|
||||
fab: {
|
||||
position: 'absolute',
|
||||
top: theme.spacing(10),
|
||||
right: theme.spacing(3),
|
||||
},
|
||||
extendedIcon: {
|
||||
marginRight: theme.spacing(1),
|
||||
},
|
||||
inputField: {
|
||||
marginRight: '1%',
|
||||
width: '49%',
|
||||
},
|
||||
formControl: {
|
||||
margin: theme.spacing(1),
|
||||
minWidth: 120,
|
||||
},
|
||||
select: {
|
||||
marginTop: theme.spacing(2),
|
||||
maxWidth: 150,
|
||||
},
|
||||
radioIcon: {
|
||||
color: lightIconsColor,
|
||||
},
|
||||
inputAdornment: {
|
||||
color: lightIconsColor,
|
||||
},
|
||||
userAgent: {
|
||||
fontSize: 12,
|
||||
},
|
||||
actionButton: {
|
||||
padding: '10px !important',
|
||||
borderRadius: '5px !important',
|
||||
},
|
||||
}));
|
||||
|
||||
export default function AddDevice(props) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [name, setName] = useState('');
|
||||
const [width, setWidth] = useState(0);
|
||||
const [height, setHeight] = useState(0);
|
||||
const [userAgentString, setUserAgentString] = useState('');
|
||||
const [previewState, setPreviewState] = useState(true);
|
||||
const [capabilities, setCapabilities] = useState({
|
||||
[CAPABILITIES.mobile]: false,
|
||||
[CAPABILITIES.touch]: true,
|
||||
});
|
||||
const [deviceType, setDeviceType] = useState(DEVICE_TYPE.phone);
|
||||
const [os, setOS] = useState(OS.android);
|
||||
const classes = useStyles();
|
||||
|
||||
const updateUserAgent = () => {
|
||||
console.log(os, deviceType);
|
||||
let userAgent =
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36';
|
||||
if (os === OS.android) {
|
||||
if (deviceType === DEVICE_TYPE.phone) {
|
||||
userAgent =
|
||||
'Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36';
|
||||
}
|
||||
if (deviceType === DEVICE_TYPE.tablet) {
|
||||
userAgent =
|
||||
'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Safari/537.36';
|
||||
}
|
||||
}
|
||||
if (os === OS.ios) {
|
||||
if (deviceType === DEVICE_TYPE.phone) {
|
||||
userAgent =
|
||||
'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1';
|
||||
}
|
||||
if (deviceType === DEVICE_TYPE.tablet) {
|
||||
userAgent =
|
||||
'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1';
|
||||
}
|
||||
}
|
||||
|
||||
if (os === OS.windowsPhone) {
|
||||
userAgent =
|
||||
'Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 520)';
|
||||
}
|
||||
|
||||
setUserAgentString(userAgent);
|
||||
};
|
||||
|
||||
React.useEffect(updateUserAgent, [os, deviceType]);
|
||||
|
||||
const CustomRadio = props => (
|
||||
<Radio
|
||||
{...props}
|
||||
color="primary"
|
||||
icon={<RadioButtonUncheckedIcon className={classes.radioIcon} />}
|
||||
checkedIcon={<RadioButtonCheckedIcon className={classes.radioIcon} />}
|
||||
/>
|
||||
);
|
||||
|
||||
const CustomCheckbox = props => (
|
||||
<Checkbox
|
||||
{...props}
|
||||
color="primary"
|
||||
icon={<CheckBoxOutlineBlankIcon className={classes.radioIcon} />}
|
||||
checkedIcon={<CheckBoxIcon className={classes.radioIcon} />}
|
||||
/>
|
||||
);
|
||||
|
||||
const CustomSwitch = withStyles({
|
||||
switchBase: {
|
||||
color: lightIconsColor,
|
||||
'&$checked': {
|
||||
color: lightIconsColor,
|
||||
},
|
||||
'&$checked + $track': {
|
||||
backgroundColor: lightIconsColor,
|
||||
},
|
||||
},
|
||||
checked: {},
|
||||
track: {},
|
||||
})(Switch);
|
||||
|
||||
const closeDialog = () => setOpen(false);
|
||||
|
||||
const saveDevice = () => {
|
||||
props.addNewDevice({
|
||||
name,
|
||||
width: parseInt(width, 10),
|
||||
height: parseInt(height, 10),
|
||||
added: previewState,
|
||||
useragent: userAgentString,
|
||||
id: `custom-${new Date().getTime()}`,
|
||||
type: deviceType,
|
||||
capabilities: Object.keys(capabilities).filter(val => capabilities[val]),
|
||||
os,
|
||||
const [open, setOpen] = useState(false);
|
||||
const [name, setName] = useState('');
|
||||
const [width, setWidth] = useState(0);
|
||||
const [height, setHeight] = useState(0);
|
||||
const [userAgentString, setUserAgentString] = useState('');
|
||||
const [previewState, setPreviewState] = useState(true);
|
||||
const [capabilities, setCapabilities] = useState({
|
||||
[CAPABILITIES.mobile]: false,
|
||||
[CAPABILITIES.touch]: true,
|
||||
});
|
||||
closeDialog();
|
||||
};
|
||||
console.log('capabilities', capabilities);
|
||||
return (
|
||||
<Fragment>
|
||||
<Fab
|
||||
variant="extended"
|
||||
aria-label="add"
|
||||
color="primary"
|
||||
className={classes.fab}
|
||||
onClick={() => setOpen(true)}
|
||||
>
|
||||
<AddIcon className={classes.extendedIcon} /> New Device
|
||||
</Fab>
|
||||
const [deviceType, setDeviceType] = useState(DEVICE_TYPE.phone);
|
||||
const [os, setOS] = useState(OS.android);
|
||||
const classes = useStyles();
|
||||
|
||||
<Dialog
|
||||
disableEnforceFocus
|
||||
open={open}
|
||||
onClose={closeDialog}
|
||||
aria-labelledby="form-dialog-title"
|
||||
fullWidth={true}
|
||||
>
|
||||
<DialogTitle id="form-dialog-title">New Device</DialogTitle>
|
||||
<DialogContent>
|
||||
<DialogContentText color="ternary">
|
||||
Please enter the details of the new device
|
||||
</DialogContentText>
|
||||
<TextField
|
||||
autoFocus
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
margin="normal"
|
||||
label="Name"
|
||||
type="text"
|
||||
placeholder="Device name"
|
||||
InputLabelProps={{
|
||||
shrink: true,
|
||||
}}
|
||||
value={name}
|
||||
onChange={e => setName(e.target.value)}
|
||||
className={'padded-input'}
|
||||
/>
|
||||
<TextField
|
||||
className={classes.inputField}
|
||||
variant="outlined"
|
||||
margin="normal"
|
||||
label="Width"
|
||||
type="number"
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<InputAdornment position="end" className="input-adornment">
|
||||
px
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
value={width}
|
||||
onChange={e => setWidth(e.target.value)}
|
||||
className={'padded-input'}
|
||||
/>
|
||||
<TextField
|
||||
className={classes.inputField}
|
||||
variant="outlined"
|
||||
margin="normal"
|
||||
label="Height"
|
||||
type="number"
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<InputAdornment position="end" className="input-adornment">
|
||||
px
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
value={height}
|
||||
onChange={e => setHeight(e.target.value)}
|
||||
className={'padded-input'}
|
||||
/>
|
||||
<FormControl
|
||||
component="fieldset"
|
||||
className={classes.formControl}
|
||||
fullWidth
|
||||
>
|
||||
<FormLabel component="legend">Device Type</FormLabel>
|
||||
<RadioGroup
|
||||
name="deviceType"
|
||||
value={deviceType}
|
||||
onChange={e => setDeviceType(e.target.value)}
|
||||
>
|
||||
<Grid container alignItems="center" spacing={1}>
|
||||
<Grid item>
|
||||
<FormControlLabel
|
||||
value={DEVICE_TYPE.phone}
|
||||
control={<CustomRadio />}
|
||||
label="Phone"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<FormControlLabel
|
||||
value={DEVICE_TYPE.tablet}
|
||||
control={<CustomRadio />}
|
||||
label="Tablet"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<FormControlLabel
|
||||
value={DEVICE_TYPE.desktop}
|
||||
control={<CustomRadio />}
|
||||
label="Laptop/Desktop"
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
component="fieldset"
|
||||
className={classes.formControl}
|
||||
fullWidth
|
||||
>
|
||||
<FormLabel component="legend">Operating System</FormLabel>
|
||||
<RadioGroup
|
||||
name="os"
|
||||
value={os}
|
||||
onChange={e => setOS(e.target.value)}
|
||||
>
|
||||
<Grid container alignItems="center" spacing={1}>
|
||||
<Grid item>
|
||||
<FormControlLabel
|
||||
value={OS.android}
|
||||
control={<CustomRadio />}
|
||||
label="Android"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<FormControlLabel
|
||||
value={OS.ios}
|
||||
control={<CustomRadio />}
|
||||
label="iOS"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<FormControlLabel
|
||||
value={OS.windowsPhone}
|
||||
control={<CustomRadio />}
|
||||
label="Windows Phone"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<FormControlLabel
|
||||
value={OS.pc}
|
||||
control={<CustomRadio />}
|
||||
label="Desktop"
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
<FormLabel>Device capabilities</FormLabel>
|
||||
<FormGroup>
|
||||
<Grid container alignItems="center" spacing={1}>
|
||||
<Grid item>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<CustomCheckbox
|
||||
checked={capabilities[CAPABILITIES.mobile]}
|
||||
onChange={e =>
|
||||
setCapabilities({
|
||||
...capabilities,
|
||||
[CAPABILITIES.mobile]: e.target.checked,
|
||||
})
|
||||
}
|
||||
value="Flippable"
|
||||
/>
|
||||
}
|
||||
label="Flippable"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<CustomCheckbox
|
||||
checked={capabilities[CAPABILITIES.touch]}
|
||||
onChange={e =>
|
||||
setCapabilities({
|
||||
...capabilities,
|
||||
[CAPABILITIES.touch]: e.target.checked,
|
||||
})
|
||||
}
|
||||
value="Touchscreen"
|
||||
/>
|
||||
}
|
||||
label="Touchscreen"
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</FormGroup>
|
||||
<TextField
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
margin="normal"
|
||||
label="User-Agent String"
|
||||
placeholder="User-Agent String"
|
||||
InputLabelProps={{
|
||||
shrink: true,
|
||||
}}
|
||||
InputProps={{
|
||||
classes: {
|
||||
input: classes.userAgent,
|
||||
},
|
||||
}}
|
||||
type="text"
|
||||
value={userAgentString}
|
||||
onChange={e => setUserAgentString(e.target.value)}
|
||||
className={cx('padded-input')}
|
||||
/>
|
||||
const updateUserAgent = () => {
|
||||
console.log(os, deviceType);
|
||||
let userAgent =
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36';
|
||||
if (os === OS.android) {
|
||||
if (deviceType === DEVICE_TYPE.phone) {
|
||||
userAgent =
|
||||
'Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36';
|
||||
}
|
||||
if (deviceType === DEVICE_TYPE.tablet) {
|
||||
userAgent =
|
||||
'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Safari/537.36';
|
||||
}
|
||||
}
|
||||
if (os === OS.ios) {
|
||||
if (deviceType === DEVICE_TYPE.phone) {
|
||||
userAgent =
|
||||
'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1';
|
||||
}
|
||||
if (deviceType === DEVICE_TYPE.tablet) {
|
||||
userAgent =
|
||||
'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1';
|
||||
}
|
||||
}
|
||||
|
||||
<Grid
|
||||
container
|
||||
alignItems="center"
|
||||
className="MuiFormControl-marginNormal"
|
||||
>
|
||||
<Grid item style={{flex: 1}} className="MuiFormLabel-root">
|
||||
Activate Preview
|
||||
</Grid>
|
||||
<Grid
|
||||
item
|
||||
className={cx('MuiFormLabel-root', {
|
||||
'Mui-focused': !previewState,
|
||||
})}
|
||||
>
|
||||
{/*Off*/}
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Switch
|
||||
onChange={checked => setPreviewState(checked)}
|
||||
checked={previewState}
|
||||
onColor={themeColor}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid
|
||||
item
|
||||
className={cx('MuiFormLabel-root', {
|
||||
'Mui-focused': previewState,
|
||||
})}
|
||||
>
|
||||
{/*On*/}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
onClick={closeDialog}
|
||||
if (os === OS.windowsPhone) {
|
||||
userAgent =
|
||||
'Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 520)';
|
||||
}
|
||||
|
||||
setUserAgentString(userAgent);
|
||||
};
|
||||
|
||||
React.useEffect(updateUserAgent, [os, deviceType]);
|
||||
|
||||
const CustomRadio = props => (
|
||||
<Radio
|
||||
{...props}
|
||||
color="primary"
|
||||
className={classes.actionButton}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={saveDevice}
|
||||
icon={<RadioButtonUncheckedIcon className={classes.radioIcon} />}
|
||||
checkedIcon={
|
||||
<RadioButtonCheckedIcon className={classes.radioIcon} />
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
const CustomCheckbox = props => (
|
||||
<Checkbox
|
||||
{...props}
|
||||
color="primary"
|
||||
className={classes.actionButton}
|
||||
>
|
||||
Add
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</Fragment>
|
||||
);
|
||||
icon={<CheckBoxOutlineBlankIcon className={classes.radioIcon} />}
|
||||
checkedIcon={<CheckBoxIcon className={classes.radioIcon} />}
|
||||
/>
|
||||
);
|
||||
|
||||
const CustomSwitch = withStyles({
|
||||
switchBase: {
|
||||
color: lightIconsColor,
|
||||
'&$checked': {
|
||||
color: lightIconsColor,
|
||||
},
|
||||
'&$checked + $track': {
|
||||
backgroundColor: lightIconsColor,
|
||||
},
|
||||
},
|
||||
checked: {},
|
||||
track: {},
|
||||
})(Switch);
|
||||
|
||||
const closeDialog = () => setOpen(false);
|
||||
|
||||
const saveDevice = () => {
|
||||
props.addNewDevice({
|
||||
name,
|
||||
width: parseInt(width, 10),
|
||||
height: parseInt(height, 10),
|
||||
added: previewState,
|
||||
useragent: userAgentString,
|
||||
id: `custom-${new Date().getTime()}`,
|
||||
type: deviceType,
|
||||
capabilities: Object.keys(capabilities).filter(
|
||||
val => capabilities[val]
|
||||
),
|
||||
os,
|
||||
});
|
||||
closeDialog();
|
||||
};
|
||||
console.log('capabilities', capabilities);
|
||||
return (
|
||||
<Fragment>
|
||||
<Fab
|
||||
variant="extended"
|
||||
aria-label="add"
|
||||
color="primary"
|
||||
className={classes.fab}
|
||||
onClick={() => setOpen(true)}
|
||||
>
|
||||
<AddIcon className={classes.extendedIcon} /> New Device
|
||||
</Fab>
|
||||
|
||||
<Dialog
|
||||
disableEnforceFocus
|
||||
open={open}
|
||||
onClose={closeDialog}
|
||||
aria-labelledby="form-dialog-title"
|
||||
fullWidth={true}
|
||||
>
|
||||
<DialogTitle id="form-dialog-title">New Device</DialogTitle>
|
||||
<DialogContent>
|
||||
<DialogContentText color="ternary">
|
||||
Please enter the details of the new device
|
||||
</DialogContentText>
|
||||
<TextField
|
||||
autoFocus
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
margin="normal"
|
||||
label="Name"
|
||||
type="text"
|
||||
placeholder="Device name"
|
||||
InputLabelProps={{
|
||||
shrink: true,
|
||||
}}
|
||||
value={name}
|
||||
onChange={e => setName(e.target.value)}
|
||||
className={'padded-input'}
|
||||
/>
|
||||
<TextField
|
||||
className={classes.inputField}
|
||||
variant="outlined"
|
||||
margin="normal"
|
||||
label="Width"
|
||||
type="number"
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<InputAdornment
|
||||
position="end"
|
||||
className="input-adornment"
|
||||
>
|
||||
px
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
value={width}
|
||||
onChange={e => setWidth(e.target.value)}
|
||||
className={'padded-input'}
|
||||
/>
|
||||
<TextField
|
||||
className={classes.inputField}
|
||||
variant="outlined"
|
||||
margin="normal"
|
||||
label="Height"
|
||||
type="number"
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<InputAdornment
|
||||
position="end"
|
||||
className="input-adornment"
|
||||
>
|
||||
px
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
value={height}
|
||||
onChange={e => setHeight(e.target.value)}
|
||||
className={'padded-input'}
|
||||
/>
|
||||
<FormControl
|
||||
component="fieldset"
|
||||
className={classes.formControl}
|
||||
fullWidth
|
||||
>
|
||||
<FormLabel component="legend">Device Type</FormLabel>
|
||||
<RadioGroup
|
||||
name="deviceType"
|
||||
value={deviceType}
|
||||
onChange={e => setDeviceType(e.target.value)}
|
||||
>
|
||||
<Grid container alignItems="center" spacing={1}>
|
||||
<Grid item>
|
||||
<FormControlLabel
|
||||
value={DEVICE_TYPE.phone}
|
||||
control={<CustomRadio />}
|
||||
label="Phone"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<FormControlLabel
|
||||
value={DEVICE_TYPE.tablet}
|
||||
control={<CustomRadio />}
|
||||
label="Tablet"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<FormControlLabel
|
||||
value={DEVICE_TYPE.desktop}
|
||||
control={<CustomRadio />}
|
||||
label="Laptop/Desktop"
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
component="fieldset"
|
||||
className={classes.formControl}
|
||||
fullWidth
|
||||
>
|
||||
<FormLabel component="legend">
|
||||
Operating System
|
||||
</FormLabel>
|
||||
<RadioGroup
|
||||
name="os"
|
||||
value={os}
|
||||
onChange={e => setOS(e.target.value)}
|
||||
>
|
||||
<Grid container alignItems="center" spacing={1}>
|
||||
<Grid item>
|
||||
<FormControlLabel
|
||||
value={OS.android}
|
||||
control={<CustomRadio />}
|
||||
label="Android"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<FormControlLabel
|
||||
value={OS.ios}
|
||||
control={<CustomRadio />}
|
||||
label="iOS"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<FormControlLabel
|
||||
value={OS.windowsPhone}
|
||||
control={<CustomRadio />}
|
||||
label="Windows Phone"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<FormControlLabel
|
||||
value={OS.pc}
|
||||
control={<CustomRadio />}
|
||||
label="Desktop"
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
<FormLabel>Device capabilities</FormLabel>
|
||||
<FormGroup>
|
||||
<Grid container alignItems="center" spacing={1}>
|
||||
<Grid item>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<CustomCheckbox
|
||||
checked={
|
||||
capabilities[
|
||||
CAPABILITIES.mobile
|
||||
]
|
||||
}
|
||||
onChange={e =>
|
||||
setCapabilities({
|
||||
...capabilities,
|
||||
[CAPABILITIES.mobile]:
|
||||
e.target.checked,
|
||||
})
|
||||
}
|
||||
value="Flippable"
|
||||
/>
|
||||
}
|
||||
label="Flippable"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<CustomCheckbox
|
||||
checked={
|
||||
capabilities[CAPABILITIES.touch]
|
||||
}
|
||||
onChange={e =>
|
||||
setCapabilities({
|
||||
...capabilities,
|
||||
[CAPABILITIES.touch]:
|
||||
e.target.checked,
|
||||
})
|
||||
}
|
||||
value="Touchscreen"
|
||||
/>
|
||||
}
|
||||
label="Touchscreen"
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</FormGroup>
|
||||
<TextField
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
margin="normal"
|
||||
label="User-Agent String"
|
||||
placeholder="User-Agent String"
|
||||
InputLabelProps={{
|
||||
shrink: true,
|
||||
}}
|
||||
InputProps={{
|
||||
classes: {
|
||||
input: classes.userAgent,
|
||||
},
|
||||
}}
|
||||
type="text"
|
||||
value={userAgentString}
|
||||
onChange={e => setUserAgentString(e.target.value)}
|
||||
className={cx('padded-input')}
|
||||
/>
|
||||
|
||||
<Grid
|
||||
container
|
||||
alignItems="center"
|
||||
className="MuiFormControl-marginNormal"
|
||||
>
|
||||
<Grid
|
||||
item
|
||||
style={{flex: 1}}
|
||||
className="MuiFormLabel-root"
|
||||
>
|
||||
Activate Preview
|
||||
</Grid>
|
||||
<Grid
|
||||
item
|
||||
className={cx('MuiFormLabel-root', {
|
||||
'Mui-focused': !previewState,
|
||||
})}
|
||||
>
|
||||
{/*Off*/}
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Switch
|
||||
onChange={checked => setPreviewState(checked)}
|
||||
checked={previewState}
|
||||
onColor={themeColor}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid
|
||||
item
|
||||
className={cx('MuiFormLabel-root', {
|
||||
'Mui-focused': previewState,
|
||||
})}
|
||||
>
|
||||
{/*On*/}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
onClick={closeDialog}
|
||||
color="primary"
|
||||
className={classes.actionButton}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={saveDevice}
|
||||
color="primary"
|
||||
className={classes.actionButton}
|
||||
>
|
||||
Add
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -10,40 +10,44 @@ import {DEVICE_TYPE} from '../../../constants/devices';
|
|||
import {getDeviceIcon, getOSIcon} from '../../../utils/iconUtils';
|
||||
|
||||
export default function DeviceItem({device, index}) {
|
||||
return (
|
||||
<Draggable draggableId={device.id} index={index}>
|
||||
{provided => (
|
||||
<div
|
||||
className={cx(styles.deviceHolder)}
|
||||
ref={provided.innerRef}
|
||||
{...provided.draggableProps}
|
||||
{...provided.dragHandleProps}
|
||||
>
|
||||
<div
|
||||
className={cx(
|
||||
commonStyles.flexAlignVerticalMiddle,
|
||||
commonStyles.fullWidth
|
||||
return (
|
||||
<Draggable draggableId={device.id} index={index}>
|
||||
{provided => (
|
||||
<div
|
||||
className={cx(styles.deviceHolder)}
|
||||
ref={provided.innerRef}
|
||||
{...provided.draggableProps}
|
||||
{...provided.dragHandleProps}
|
||||
>
|
||||
<div
|
||||
className={cx(
|
||||
commonStyles.flexAlignVerticalMiddle,
|
||||
commonStyles.fullWidth
|
||||
)}
|
||||
>
|
||||
<DragIndicator style={{color: 'grey'}} />
|
||||
<div
|
||||
className={cx(
|
||||
commonStyles.flexContainerSpaceBetween,
|
||||
commonStyles.fullWidth
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={commonStyles.flexAlignVerticalMiddle}
|
||||
>
|
||||
{getDeviceIcon(device.type)}
|
||||
<span className={styles.deviceName}>
|
||||
{device.name}
|
||||
</span>
|
||||
<span className={styles.deviceDimensions}>
|
||||
{device.width}x{device.height}
|
||||
</span>
|
||||
</div>
|
||||
<div>{getOSIcon(device.os, '#ffffff90')}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
>
|
||||
<DragIndicator style={{color: 'grey'}} />
|
||||
<div
|
||||
className={cx(
|
||||
commonStyles.flexContainerSpaceBetween,
|
||||
commonStyles.fullWidth
|
||||
)}
|
||||
>
|
||||
<div className={commonStyles.flexAlignVerticalMiddle}>
|
||||
{getDeviceIcon(device.type)}
|
||||
<span className={styles.deviceName}>{device.name}</span>
|
||||
<span className={styles.deviceDimensions}>
|
||||
{device.width}x{device.height}
|
||||
</span>
|
||||
</div>
|
||||
<div>{getOSIcon(device.os, '#ffffff90')}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</Draggable>
|
||||
);
|
||||
</Draggable>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -6,19 +6,23 @@ import cx from 'classnames';
|
|||
import styles from './styles.css';
|
||||
|
||||
export default function DeviceList({droppableId, devices}) {
|
||||
return (
|
||||
<Droppable droppableId={droppableId}>
|
||||
{provided => (
|
||||
<div
|
||||
ref={provided.innerRef}
|
||||
{...provided.droppableProps}
|
||||
className={cx(styles.listHolder)}
|
||||
>
|
||||
{devices.map((device, index) => (
|
||||
<DeviceItem device={device} index={index} key={device.id} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</Droppable>
|
||||
);
|
||||
return (
|
||||
<Droppable droppableId={droppableId}>
|
||||
{provided => (
|
||||
<div
|
||||
ref={provided.innerRef}
|
||||
{...provided.droppableProps}
|
||||
className={cx(styles.listHolder)}
|
||||
>
|
||||
{devices.map((device, index) => (
|
||||
<DeviceItem
|
||||
device={device}
|
||||
index={index}
|
||||
key={device.id}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</Droppable>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -21,110 +21,120 @@ import ErrorBoundary from '../ErrorBoundary';
|
|||
import styles from './styles.css';
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
appBar: {
|
||||
position: 'relative',
|
||||
},
|
||||
title: {
|
||||
marginLeft: theme.spacing(2),
|
||||
flex: 1,
|
||||
},
|
||||
appBar: {
|
||||
position: 'relative',
|
||||
},
|
||||
title: {
|
||||
marginLeft: theme.spacing(2),
|
||||
flex: 1,
|
||||
},
|
||||
}));
|
||||
|
||||
export default function DeviceManager(props) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const classes = useStyles();
|
||||
const [open, setOpen] = useState(false);
|
||||
const classes = useStyles();
|
||||
|
||||
const [devices, setDevices] = useState({
|
||||
active: [],
|
||||
inactive: [],
|
||||
});
|
||||
const [devices, setDevices] = useState({
|
||||
active: [],
|
||||
inactive: [],
|
||||
});
|
||||
|
||||
useEffect(
|
||||
() => {
|
||||
const activeDevices = props.browser.devices;
|
||||
const activeDevicesById = activeDevices.reduce((acc, val) => {
|
||||
acc[val.id] = val;
|
||||
return acc;
|
||||
}, {});
|
||||
const inactiveDevices = allDevices.filter(
|
||||
device => !activeDevicesById[device.id]
|
||||
);
|
||||
setDevices({active: activeDevices, inactive: inactiveDevices});
|
||||
},
|
||||
[props.browser.devices.map(JSON.stringify).join(',')]
|
||||
);
|
||||
useEffect(
|
||||
() => {
|
||||
const activeDevices = props.browser.devices;
|
||||
const activeDevicesById = activeDevices.reduce((acc, val) => {
|
||||
acc[val.id] = val;
|
||||
return acc;
|
||||
}, {});
|
||||
const inactiveDevices = allDevices.filter(
|
||||
device => !activeDevicesById[device.id]
|
||||
);
|
||||
setDevices({active: activeDevices, inactive: inactiveDevices});
|
||||
},
|
||||
[props.browser.devices.map(JSON.stringify).join(',')]
|
||||
);
|
||||
|
||||
const closeDialog = () => setOpen(false);
|
||||
const closeDialog = () => setOpen(false);
|
||||
|
||||
const onDragEnd = result => {
|
||||
const {source, destination} = result;
|
||||
const onDragEnd = result => {
|
||||
const {source, destination} = result;
|
||||
|
||||
const sourceList = devices[source.droppableId];
|
||||
const destinationList = devices[destination.droppableId];
|
||||
const sourceList = devices[source.droppableId];
|
||||
const destinationList = devices[destination.droppableId];
|
||||
|
||||
const itemDragged = sourceList[source.index];
|
||||
sourceList.splice(source.index, 1);
|
||||
const itemDragged = sourceList[source.index];
|
||||
sourceList.splice(source.index, 1);
|
||||
|
||||
destinationList.splice(destination.index, 0, itemDragged);
|
||||
destinationList.splice(destination.index, 0, itemDragged);
|
||||
|
||||
setDevices({...devices});
|
||||
props.setActiveDevices(devices.active);
|
||||
};
|
||||
return (
|
||||
<Fragment>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
aria-label="upload picture"
|
||||
component="span"
|
||||
onClick={() => setOpen(true)}
|
||||
className={styles.editButton}
|
||||
>
|
||||
Customize
|
||||
{/*<EditIcon style={{fontSize: 'inherit'}} />*/}
|
||||
</Button>
|
||||
<Dialog fullScreen open={open} onClose={closeDialog}>
|
||||
<AppBar className={classes.appBar} color="secondary">
|
||||
<Toolbar>
|
||||
{/*<IconButton edge="start" onClick={closeDialog} aria-label="close">
|
||||
setDevices({...devices});
|
||||
props.setActiveDevices(devices.active);
|
||||
};
|
||||
return (
|
||||
<Fragment>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
aria-label="upload picture"
|
||||
component="span"
|
||||
onClick={() => setOpen(true)}
|
||||
className={styles.editButton}
|
||||
>
|
||||
Customize
|
||||
{/*<EditIcon style={{fontSize: 'inherit'}} />*/}
|
||||
</Button>
|
||||
<Dialog fullScreen open={open} onClose={closeDialog}>
|
||||
<AppBar className={classes.appBar} color="secondary">
|
||||
<Toolbar>
|
||||
{/*<IconButton edge="start" onClick={closeDialog} aria-label="close">
|
||||
<CloseIcon />
|
||||
</IconButton>*/}
|
||||
<Typography variant="h6" className={classes.title}>
|
||||
Manage Devices
|
||||
</Typography>
|
||||
<Button color="inherit" onClick={closeDialog}>
|
||||
close
|
||||
</Button>
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
<div className={styles.container}>
|
||||
<p className={styles.toolTip}>
|
||||
<span>✨</span>Drag and drop the devices across to re-order them.
|
||||
</p>
|
||||
<DragDropContext onDragEnd={onDragEnd}>
|
||||
<Grid container spacing={3} className={styles.content}>
|
||||
<Grid item xs={3} className={styles.section}>
|
||||
<div className={styles.listTitle}>
|
||||
<LightBulbIcon height={30} color="#FFD517" />
|
||||
Active Devices
|
||||
<Typography variant="h6" className={classes.title}>
|
||||
Manage Devices
|
||||
</Typography>
|
||||
<Button color="inherit" onClick={closeDialog}>
|
||||
close
|
||||
</Button>
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
<div className={styles.container}>
|
||||
<p className={styles.toolTip}>
|
||||
<span>✨</span>Drag and drop the devices across to
|
||||
re-order them.
|
||||
</p>
|
||||
<DragDropContext onDragEnd={onDragEnd}>
|
||||
<Grid container spacing={3} className={styles.content}>
|
||||
<Grid item xs={3} className={styles.section}>
|
||||
<div className={styles.listTitle}>
|
||||
<LightBulbIcon
|
||||
height={30}
|
||||
color="#FFD517"
|
||||
/>
|
||||
Active Devices
|
||||
</div>
|
||||
<DeviceList
|
||||
droppableId={'active'}
|
||||
devices={devices.active}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={3} className={styles.section}>
|
||||
<div className={styles.listTitle}>
|
||||
<LightBulbIcon
|
||||
height={30}
|
||||
color="darkgrey"
|
||||
/>
|
||||
Inactive Devices
|
||||
</div>
|
||||
<DeviceList
|
||||
droppableId={'inactive'}
|
||||
devices={devices.inactive}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</DragDropContext>
|
||||
<AddDeviceContainer />
|
||||
</div>
|
||||
<DeviceList droppableId={'active'} devices={devices.active} />
|
||||
</Grid>
|
||||
<Grid item xs={3} className={styles.section}>
|
||||
<div className={styles.listTitle}>
|
||||
<LightBulbIcon height={30} color="darkgrey" />
|
||||
Inactive Devices
|
||||
</div>
|
||||
<DeviceList
|
||||
droppableId={'inactive'}
|
||||
devices={devices.inactive}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</DragDropContext>
|
||||
<AddDeviceContainer />
|
||||
</div>
|
||||
</Dialog>
|
||||
</Fragment>
|
||||
);
|
||||
</Dialog>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -6,23 +6,23 @@ import DevicesIcon from '../icons/Devices';
|
|||
import commonStyles from '../common.styles.css';
|
||||
|
||||
export default function DevicesOverview(props) {
|
||||
return (
|
||||
<div className={cx(commonStyles.sidebarContentSection)}>
|
||||
<div className={cx(commonStyles.sidebarContentSectionTitleBar)}>
|
||||
<DevicesIcon color="white" width={26} margin={2} /> Devices
|
||||
</div>
|
||||
<div className={cx(commonStyles.sidebarContentSectionContainer)}>
|
||||
<div
|
||||
className={cx(
|
||||
commonStyles.flexContainer,
|
||||
commonStyles.flexContainerSpaceBetween
|
||||
)}
|
||||
>
|
||||
{props.browser.devices.length} active device
|
||||
{props.browser.devices.length !== 1 && 's'}
|
||||
<DeviceManagerContainer />
|
||||
return (
|
||||
<div className={cx(commonStyles.sidebarContentSection)}>
|
||||
<div className={cx(commonStyles.sidebarContentSectionTitleBar)}>
|
||||
<DevicesIcon color="white" width={26} margin={2} /> Devices
|
||||
</div>
|
||||
<div className={cx(commonStyles.sidebarContentSectionContainer)}>
|
||||
<div
|
||||
className={cx(
|
||||
commonStyles.flexContainer,
|
||||
commonStyles.flexContainerSpaceBetween
|
||||
)}
|
||||
>
|
||||
{props.browser.devices.length} active device
|
||||
{props.browser.devices.length !== 1 && 's'}
|
||||
<DeviceManagerContainer />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
|
|
@ -6,70 +6,78 @@ import Renderer from '../Renderer';
|
|||
|
||||
import styles from './style.module.css';
|
||||
import {
|
||||
HORIZONTAL_LAYOUT,
|
||||
FLEXIGRID_LAYOUT,
|
||||
INDIVIDUAL_LAYOUT,
|
||||
HORIZONTAL_LAYOUT,
|
||||
FLEXIGRID_LAYOUT,
|
||||
INDIVIDUAL_LAYOUT,
|
||||
} from '../../constants/previewerLayouts';
|
||||
import {isDeviceEligible} from '../../utils/filterUtils';
|
||||
import {getDeviceIcon} from '../../utils/iconUtils';
|
||||
|
||||
export default function DevicesPreviewer(props) {
|
||||
const {
|
||||
browser: {
|
||||
devices,
|
||||
address,
|
||||
zoomLevel,
|
||||
previewer: {layout},
|
||||
},
|
||||
} = props;
|
||||
const [activeTab, changeTab] = useState(0);
|
||||
const {
|
||||
browser: {
|
||||
devices,
|
||||
address,
|
||||
zoomLevel,
|
||||
previewer: {layout},
|
||||
},
|
||||
} = props;
|
||||
const [activeTab, changeTab] = useState(0);
|
||||
|
||||
return (
|
||||
<div className={cx(styles.container)}>
|
||||
{layout === INDIVIDUAL_LAYOUT && (
|
||||
<Tabs onSelect={changeTab}>
|
||||
<TabList>
|
||||
{devices
|
||||
.map(device => {
|
||||
if (!isDeviceEligible(device, props.browser.filters)) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<Tab tabId={device.id}>
|
||||
{getDeviceIcon(device.type)}
|
||||
{device.name}
|
||||
</Tab>
|
||||
);
|
||||
})
|
||||
.filter(Boolean)}
|
||||
</TabList>
|
||||
</Tabs>
|
||||
)}
|
||||
<div
|
||||
className={cx(styles.devicesContainer, {
|
||||
[styles.flexigrid]: layout === FLEXIGRID_LAYOUT,
|
||||
[styles.horizontal]: layout === HORIZONTAL_LAYOUT,
|
||||
})}
|
||||
>
|
||||
{devices.map((device, index) => (
|
||||
<div
|
||||
key={device.id}
|
||||
className={cx({
|
||||
[styles.tab]: layout === INDIVIDUAL_LAYOUT,
|
||||
[styles.activeTab]:
|
||||
layout === INDIVIDUAL_LAYOUT && activeTab === index,
|
||||
})}
|
||||
>
|
||||
<Renderer
|
||||
hidden={!isDeviceEligible(device, props.browser.filters)}
|
||||
device={device}
|
||||
src={address}
|
||||
zoomLevel={zoomLevel}
|
||||
transmitNavigatorStatus={index === 0}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div className={cx(styles.container)}>
|
||||
{layout === INDIVIDUAL_LAYOUT && (
|
||||
<Tabs onSelect={changeTab}>
|
||||
<TabList>
|
||||
{devices
|
||||
.map(device => {
|
||||
if (
|
||||
!isDeviceEligible(
|
||||
device,
|
||||
props.browser.filters
|
||||
)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<Tab tabId={device.id}>
|
||||
{getDeviceIcon(device.type)}
|
||||
{device.name}
|
||||
</Tab>
|
||||
);
|
||||
})
|
||||
.filter(Boolean)}
|
||||
</TabList>
|
||||
</Tabs>
|
||||
)}
|
||||
<div
|
||||
className={cx(styles.devicesContainer, {
|
||||
[styles.flexigrid]: layout === FLEXIGRID_LAYOUT,
|
||||
[styles.horizontal]: layout === HORIZONTAL_LAYOUT,
|
||||
})}
|
||||
>
|
||||
{devices.map((device, index) => (
|
||||
<div
|
||||
key={device.id}
|
||||
className={cx({
|
||||
[styles.tab]: layout === INDIVIDUAL_LAYOUT,
|
||||
[styles.activeTab]:
|
||||
layout === INDIVIDUAL_LAYOUT &&
|
||||
activeTab === index,
|
||||
})}
|
||||
>
|
||||
<Renderer
|
||||
hidden={
|
||||
!isDeviceEligible(device, props.browser.filters)
|
||||
}
|
||||
device={device}
|
||||
src={address}
|
||||
zoomLevel={zoomLevel}
|
||||
transmitNavigatorStatus={index === 0}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -7,42 +7,42 @@ import DevicesPreviewer from './';
|
|||
|
||||
const testSrc = 'https://testUrl.com';
|
||||
const testDevice1 = {
|
||||
id: 1,
|
||||
name: 'testDevice1',
|
||||
width: 100,
|
||||
height: 100,
|
||||
id: 1,
|
||||
name: 'testDevice1',
|
||||
width: 100,
|
||||
height: 100,
|
||||
};
|
||||
const testDevice2 = {
|
||||
id: 2,
|
||||
name: 'testDevice2',
|
||||
width: 200,
|
||||
height: 200,
|
||||
id: 2,
|
||||
name: 'testDevice2',
|
||||
width: 200,
|
||||
height: 200,
|
||||
};
|
||||
const testDevices = [testDevice1, testDevice2];
|
||||
|
||||
describe('<DevicesPreviewer />', () => {
|
||||
it('Renders the Renderer for all passed array of devices', () => {
|
||||
const wrapper = shallow(
|
||||
<DevicesPreviewer devices={testDevices} url={testSrc} />
|
||||
);
|
||||
expect(wrapper.find('Renderer')).to.have.lengthOf(testDevices.length);
|
||||
});
|
||||
|
||||
it('Renders the Renderer for all devices passed with the given url', () => {
|
||||
const wrapper = shallow(
|
||||
<DevicesPreviewer devices={testDevices} url={testSrc} />
|
||||
);
|
||||
wrapper.find('Renderer').forEach(renderer => {
|
||||
expect(renderer.prop('src')).to.equal(testSrc);
|
||||
it('Renders the Renderer for all passed array of devices', () => {
|
||||
const wrapper = shallow(
|
||||
<DevicesPreviewer devices={testDevices} url={testSrc} />
|
||||
);
|
||||
expect(wrapper.find('Renderer')).to.have.lengthOf(testDevices.length);
|
||||
});
|
||||
});
|
||||
|
||||
it('Renders the Renderer for all devices in the given order', () => {
|
||||
const wrapper = shallow(
|
||||
<DevicesPreviewer devices={testDevices} url={testSrc} />
|
||||
);
|
||||
wrapper.find('Renderer').forEach((renderer, idx) => {
|
||||
expect(renderer.prop('device')).to.equal(testDevices[idx]);
|
||||
it('Renders the Renderer for all devices passed with the given url', () => {
|
||||
const wrapper = shallow(
|
||||
<DevicesPreviewer devices={testDevices} url={testSrc} />
|
||||
);
|
||||
wrapper.find('Renderer').forEach(renderer => {
|
||||
expect(renderer.prop('src')).to.equal(testSrc);
|
||||
});
|
||||
});
|
||||
|
||||
it('Renders the Renderer for all devices in the given order', () => {
|
||||
const wrapper = shallow(
|
||||
<DevicesPreviewer devices={testDevices} url={testSrc} />
|
||||
);
|
||||
wrapper.find('Renderer').forEach((renderer, idx) => {
|
||||
expect(renderer.prop('device')).to.equal(testDevices[idx]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -16,58 +16,58 @@ import {iconsColor} from '../../constants/colors';
|
|||
import DoubleLeftArrowIcon from '../icons/DoubleLeftArrow';
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
root: {
|
||||
display: 'flex',
|
||||
justifyContent: 'flex-end',
|
||||
margin: '0 0 10px',
|
||||
'&:hover': {},
|
||||
},
|
||||
iconHover: {
|
||||
color: iconsColor,
|
||||
opacity: 0.8,
|
||||
borderRadius: '50%',
|
||||
'&:hover': {
|
||||
opacity: 1,
|
||||
color: '#8c8c8c42',
|
||||
root: {
|
||||
display: 'flex',
|
||||
justifyContent: 'flex-end',
|
||||
margin: '0 0 10px',
|
||||
'&:hover': {},
|
||||
},
|
||||
iconHover: {
|
||||
color: iconsColor,
|
||||
opacity: 0.8,
|
||||
borderRadius: '50%',
|
||||
'&:hover': {
|
||||
opacity: 1,
|
||||
color: '#8c8c8c42',
|
||||
},
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
export function Drawer(props) {
|
||||
const classes = useStyles();
|
||||
return (
|
||||
<div className={cx(styles.drawer, {[styles.open]: props.drawer.open})}>
|
||||
<div
|
||||
className={classes.root}
|
||||
onClick={() => props.changeDrawerOpenState(false)}
|
||||
>
|
||||
<div
|
||||
className={cx(
|
||||
commonStyles.flexContainer,
|
||||
commonStyles.icons,
|
||||
commonStyles.enabled
|
||||
)}
|
||||
onClick={() => props.changeDrawerOpenState(false)}
|
||||
>
|
||||
<DoubleLeftArrowIcon color="white" height={30} />
|
||||
const classes = useStyles();
|
||||
return (
|
||||
<div className={cx(styles.drawer, {[styles.open]: props.drawer.open})}>
|
||||
<div
|
||||
className={classes.root}
|
||||
onClick={() => props.changeDrawerOpenState(false)}
|
||||
>
|
||||
<div
|
||||
className={cx(
|
||||
commonStyles.flexContainer,
|
||||
commonStyles.icons,
|
||||
commonStyles.enabled
|
||||
)}
|
||||
onClick={() => props.changeDrawerOpenState(false)}
|
||||
>
|
||||
<DoubleLeftArrowIcon color="white" height={30} />
|
||||
</div>
|
||||
{/*<Icon type="chevronsLeft" title="Close Drawer" color="white" className={classes.iconHover} />*/}
|
||||
{/*<ChevronLeftIcon className={classes.iconHover} />*/}
|
||||
</div>
|
||||
<div className={styles.contentContainer}>
|
||||
{getDrawerContent(props.drawer.content)}
|
||||
</div>
|
||||
</div>
|
||||
{/*<Icon type="chevronsLeft" title="Close Drawer" color="white" className={classes.iconHover} />*/}
|
||||
{/*<ChevronLeftIcon className={classes.iconHover} />*/}
|
||||
</div>
|
||||
<div className={styles.contentContainer}>
|
||||
{getDrawerContent(props.drawer.content)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
const deviceDrawerComponent = <DeviceDrawerContainer />;
|
||||
|
||||
function getDrawerContent(type) {
|
||||
switch (type) {
|
||||
case DEVICE_MANAGER:
|
||||
return deviceDrawerComponent;
|
||||
}
|
||||
switch (type) {
|
||||
case DEVICE_MANAGER:
|
||||
return deviceDrawerComponent;
|
||||
}
|
||||
}
|
||||
|
||||
export default Drawer;
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
import React, {Fragment} from 'react';
|
||||
|
||||
export default class ErrorBoundary extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {hasError: false};
|
||||
}
|
||||
|
||||
static getDerivedStateFromError(error) {
|
||||
// Update state so the next render will show the fallback UI.
|
||||
return {hasError: true, error};
|
||||
}
|
||||
|
||||
componentDidCatch(error, errorInfo) {
|
||||
// You can also log the error to an error reporting service
|
||||
alert(JSON.stringify({error, erroInfo}));
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.hasError) {
|
||||
// You can render any custom fallback UI
|
||||
return (
|
||||
<Fragment>
|
||||
<h1>Something went wrong.</h1>
|
||||
<div>JSON.stringify(error)</div>
|
||||
</Fragment>
|
||||
);
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {hasError: false};
|
||||
}
|
||||
|
||||
return this.props.children;
|
||||
}
|
||||
static getDerivedStateFromError(error) {
|
||||
// Update state so the next render will show the fallback UI.
|
||||
return {hasError: true, error};
|
||||
}
|
||||
|
||||
componentDidCatch(error, errorInfo) {
|
||||
// You can also log the error to an error reporting service
|
||||
alert(JSON.stringify({error, erroInfo}));
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.hasError) {
|
||||
// You can render any custom fallback UI
|
||||
return (
|
||||
<Fragment>
|
||||
<h1>Something went wrong.</h1>
|
||||
<div>JSON.stringify(error)</div>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,34 +12,39 @@ import styles from './style.module.css';
|
|||
import NavigationControlsContainer from '../../containers/NavigationControlsContainer';
|
||||
|
||||
const Header = function() {
|
||||
return (
|
||||
<div className={styles.header}>
|
||||
<Grid container direction="row" justify="flex-start" alignItems="center">
|
||||
<Grid item>
|
||||
<NavigationControlsContainer />
|
||||
</Grid>
|
||||
<Grid item style={{flex: 1}}>
|
||||
<AddressBar />
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<ScrollControlsContainer />
|
||||
</Grid>
|
||||
</Grid>
|
||||
<HttpAuthDialog />
|
||||
<ToastContainer
|
||||
position="top-right"
|
||||
autoClose={3000}
|
||||
hideProgressBar
|
||||
newestOnTop={false}
|
||||
closeOnClick
|
||||
pauseOnFocusLoss={false}
|
||||
rtl={false}
|
||||
draggable
|
||||
pauseOnHover
|
||||
toastClassName={styles.darkToast}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div className={styles.header}>
|
||||
<Grid
|
||||
container
|
||||
direction="row"
|
||||
justify="flex-start"
|
||||
alignItems="center"
|
||||
>
|
||||
<Grid item>
|
||||
<NavigationControlsContainer />
|
||||
</Grid>
|
||||
<Grid item style={{flex: 1}}>
|
||||
<AddressBar />
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<ScrollControlsContainer />
|
||||
</Grid>
|
||||
</Grid>
|
||||
<HttpAuthDialog />
|
||||
<ToastContainer
|
||||
position="top-right"
|
||||
autoClose={3000}
|
||||
hideProgressBar
|
||||
newestOnTop={false}
|
||||
closeOnClick
|
||||
pauseOnFocusLoss={false}
|
||||
rtl={false}
|
||||
draggable
|
||||
pauseOnHover
|
||||
toastClassName={styles.darkToast}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Header;
|
||||
|
|
|
@ -4,11 +4,10 @@ import {expect} from 'chai';
|
|||
|
||||
import Header from './';
|
||||
|
||||
|
||||
describe('<Header />', () => {
|
||||
it('renders a h1 and BrowserZoom components', () => {
|
||||
const wrapper = shallow(<Header />);
|
||||
expect(wrapper.find('h1')).to.have.lengthOf(1);
|
||||
expect(wrapper.find('ZoomInput')).to.have.lengthOf(1);
|
||||
})
|
||||
});
|
||||
it('renders a h1 and BrowserZoom components', () => {
|
||||
const wrapper = shallow(<Header />);
|
||||
expect(wrapper.find('h1')).to.have.lengthOf(1);
|
||||
expect(wrapper.find('ZoomInput')).to.have.lengthOf(1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,14 +8,14 @@ import styles from './Home.css';
|
|||
type Props = {};
|
||||
|
||||
export default class Home extends Component<Props> {
|
||||
props: Props;
|
||||
props: Props;
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className={styles.container} data-tid="container">
|
||||
<AddressBar address="https://www.google.com" />
|
||||
<h2>Home</h2>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div className={styles.container} data-tid="container">
|
||||
<AddressBar address="https://www.google.com" />
|
||||
<h2>Home</h2>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,85 +9,89 @@ import DialogContentText from '@material-ui/core/DialogContentText';
|
|||
import DialogTitle from '@material-ui/core/DialogTitle';
|
||||
|
||||
export default function HttpAuthDialog() {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [url, setUrl] = useState('');
|
||||
const usernameRef = useRef(null);
|
||||
const passwordRef = useRef(null);
|
||||
const [open, setOpen] = useState(false);
|
||||
const [url, setUrl] = useState('');
|
||||
const usernameRef = useRef(null);
|
||||
const passwordRef = useRef(null);
|
||||
|
||||
ipcRenderer.on('http-auth-prompt', (event, args) => {
|
||||
console.log('HTTP msg', event, args);
|
||||
setUrl(args.url);
|
||||
setOpen(true);
|
||||
});
|
||||
|
||||
function handleClose(status) {
|
||||
if (!status) {
|
||||
ipcRenderer.send('http-auth-promt-response', {url});
|
||||
}
|
||||
ipcRenderer.send('http-auth-promt-response', {
|
||||
url,
|
||||
username: usernameRef.current.querySelector('input').value,
|
||||
password: passwordRef.current.querySelector('input').value,
|
||||
ipcRenderer.on('http-auth-prompt', (event, args) => {
|
||||
console.log('HTTP msg', event, args);
|
||||
setUrl(args.url);
|
||||
setOpen(true);
|
||||
});
|
||||
setOpen(false);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Dialog
|
||||
open={open}
|
||||
onClose={handleClose}
|
||||
disableBackdropClick={true}
|
||||
aria-labelledby="form-dialog-title"
|
||||
>
|
||||
<DialogTitle id="form-dialog-title">Sign-in</DialogTitle>
|
||||
<form
|
||||
id="my-form-id"
|
||||
onSubmit={e => {
|
||||
e.preventDefault();
|
||||
handleClose(true);
|
||||
}}
|
||||
>
|
||||
<DialogContent>
|
||||
<DialogContentText>
|
||||
{url ? <strong>{url}</strong> : 'The webpage'} requires HTTP Basic
|
||||
authentication to connect, please enter the details to continue.
|
||||
</DialogContentText>
|
||||
function handleClose(status) {
|
||||
if (!status) {
|
||||
ipcRenderer.send('http-auth-promt-response', {url});
|
||||
}
|
||||
ipcRenderer.send('http-auth-promt-response', {
|
||||
url,
|
||||
username: usernameRef.current.querySelector('input').value,
|
||||
password: passwordRef.current.querySelector('input').value,
|
||||
});
|
||||
setOpen(false);
|
||||
}
|
||||
|
||||
<TextField
|
||||
ref={usernameRef}
|
||||
autoFocus
|
||||
margin="dense"
|
||||
id="username"
|
||||
label="Username"
|
||||
type="text"
|
||||
fullWidth
|
||||
/>
|
||||
<TextField
|
||||
ref={passwordRef}
|
||||
margin="dense"
|
||||
id="password"
|
||||
label="Password"
|
||||
type="password"
|
||||
fullWidth
|
||||
/>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={() => handleClose(false)} color="secondary">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={() => handleClose(true)}
|
||||
color="primary"
|
||||
type="submit"
|
||||
primary={true}
|
||||
return (
|
||||
<div>
|
||||
<Dialog
|
||||
open={open}
|
||||
onClose={handleClose}
|
||||
disableBackdropClick={true}
|
||||
aria-labelledby="form-dialog-title"
|
||||
>
|
||||
Sign In
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</form>
|
||||
</Dialog>
|
||||
</div>
|
||||
);
|
||||
<DialogTitle id="form-dialog-title">Sign-in</DialogTitle>
|
||||
<form
|
||||
id="my-form-id"
|
||||
onSubmit={e => {
|
||||
e.preventDefault();
|
||||
handleClose(true);
|
||||
}}
|
||||
>
|
||||
<DialogContent>
|
||||
<DialogContentText>
|
||||
{url ? <strong>{url}</strong> : 'The webpage'}{' '}
|
||||
requires HTTP Basic authentication to connect,
|
||||
please enter the details to continue.
|
||||
</DialogContentText>
|
||||
|
||||
<TextField
|
||||
ref={usernameRef}
|
||||
autoFocus
|
||||
margin="dense"
|
||||
id="username"
|
||||
label="Username"
|
||||
type="text"
|
||||
fullWidth
|
||||
/>
|
||||
<TextField
|
||||
ref={passwordRef}
|
||||
margin="dense"
|
||||
id="password"
|
||||
label="Password"
|
||||
type="password"
|
||||
fullWidth
|
||||
/>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
onClick={() => handleClose(false)}
|
||||
color="secondary"
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={() => handleClose(true)}
|
||||
color="primary"
|
||||
type="submit"
|
||||
primary={true}
|
||||
>
|
||||
Sign In
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</form>
|
||||
</Dialog>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -11,56 +11,63 @@ import styles from './styles.css';
|
|||
import commonStyles from '../common.styles.css';
|
||||
import {iconsColor} from '../../constants/colors';
|
||||
import {
|
||||
DEVICE_MANAGER,
|
||||
SCREENSHOT_MANAGER,
|
||||
DEVICE_MANAGER,
|
||||
SCREENSHOT_MANAGER,
|
||||
} from '../../constants/DrawerContents';
|
||||
|
||||
const LeftIconsPane = props => {
|
||||
const headwayRef = useRef();
|
||||
const iconProps = {
|
||||
color: iconsColor,
|
||||
style: {fontSize: 30},
|
||||
height: 30,
|
||||
width: 30,
|
||||
};
|
||||
return (
|
||||
<div className={styles.iconsContainer}>
|
||||
<div className={cx(styles.icon, styles.logo)}>
|
||||
<Logo width={40} height={40} />
|
||||
</div>
|
||||
<Grid
|
||||
container
|
||||
spacing={1}
|
||||
direction="column"
|
||||
alignItems="center"
|
||||
className={cx(styles.utilitySection)}
|
||||
>
|
||||
<Grid item className={cx(commonStyles.icons, commonStyles.enabled)}>
|
||||
<div onClick={() => props.openDrawerAndSetContent(DEVICE_MANAGER)}>
|
||||
<DevicesIcon {...iconProps} />
|
||||
</div>
|
||||
</Grid>
|
||||
{/*<Grid item className={cx(commonStyles.icons, commonStyles.enabled)}>
|
||||
const headwayRef = useRef();
|
||||
const iconProps = {
|
||||
color: iconsColor,
|
||||
style: {fontSize: 30},
|
||||
height: 30,
|
||||
width: 30,
|
||||
};
|
||||
return (
|
||||
<div className={styles.iconsContainer}>
|
||||
<div className={cx(styles.icon, styles.logo)}>
|
||||
<Logo width={40} height={40} />
|
||||
</div>
|
||||
<Grid
|
||||
container
|
||||
spacing={1}
|
||||
direction="column"
|
||||
alignItems="center"
|
||||
className={cx(styles.utilitySection)}
|
||||
>
|
||||
<Grid
|
||||
item
|
||||
className={cx(commonStyles.icons, commonStyles.enabled)}
|
||||
>
|
||||
<div
|
||||
onClick={() =>
|
||||
props.openDrawerAndSetContent(DEVICE_MANAGER)
|
||||
}
|
||||
>
|
||||
<DevicesIcon {...iconProps} />
|
||||
</div>
|
||||
</Grid>
|
||||
{/*<Grid item className={cx(commonStyles.icons, commonStyles.enabled)}>
|
||||
<div
|
||||
onClick={() => props.openDrawerAndSetContent(SCREENSHOT_MANAGER)}
|
||||
>
|
||||
<PhotoLibraryIcon {...iconProps} />
|
||||
</div>
|
||||
</Grid>*/}
|
||||
</Grid>
|
||||
<div style={{position: 'relative'}}>
|
||||
<div
|
||||
id="headway"
|
||||
ref={headwayRef}
|
||||
className={cx(
|
||||
styles.updates,
|
||||
commonStyles.icons,
|
||||
commonStyles.enabled
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
</Grid>
|
||||
<div style={{position: 'relative'}}>
|
||||
<div
|
||||
id="headway"
|
||||
ref={headwayRef}
|
||||
className={cx(
|
||||
styles.updates,
|
||||
commonStyles.icons,
|
||||
commonStyles.enabled
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LeftIconsPane;
|
||||
|
|
|
@ -14,79 +14,93 @@ import {iconsColor} from '../../constants/colors';
|
|||
import {Tooltip} from '@material-ui/core';
|
||||
|
||||
class NavigationControls extends Component {
|
||||
render() {
|
||||
const iconProps = {
|
||||
color: iconsColor,
|
||||
height: 25,
|
||||
width: 25,
|
||||
};
|
||||
const {backEnabled, forwardEnabled} = this.props;
|
||||
return (
|
||||
<div className={styles.navigationControls}>
|
||||
<Grid container spacing={1} alignItems="center">
|
||||
<Grid
|
||||
item
|
||||
className={cx(commonStyles.icons, {
|
||||
[commonStyles.disabled]: !backEnabled,
|
||||
[commonStyles.enabled]: backEnabled,
|
||||
})}
|
||||
>
|
||||
<div
|
||||
className={cx(commonStyles.iconDisabler, {
|
||||
[commonStyles.disabled]: !backEnabled,
|
||||
})}
|
||||
/>
|
||||
<Tooltip title="Back">
|
||||
<div onClick={this.props.triggerNavigationBack}>
|
||||
<Icon type="arrowLeft" size="30px" {...iconProps} />
|
||||
{/*<ArrowLeftIcon {...iconProps} />*/}
|
||||
</div>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
<Grid
|
||||
item
|
||||
className={cx(commonStyles.icons, {
|
||||
[commonStyles.disabled]: !forwardEnabled,
|
||||
[commonStyles.enabled]: forwardEnabled,
|
||||
})}
|
||||
>
|
||||
<div
|
||||
className={cx(commonStyles.iconDisabler, {
|
||||
[commonStyles.disabled]: !forwardEnabled,
|
||||
})}
|
||||
/>
|
||||
<Tooltip title="Forward">
|
||||
<div onClick={this.props.triggerNavigationForward}>
|
||||
<Icon type="arrowRight" size="30px" {...iconProps} />
|
||||
{/*<ArrowRightIcon {...iconProps} />*/}
|
||||
</div>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
<Grid item className={cx(commonStyles.icons, commonStyles.enabled)}>
|
||||
<Tooltip title="Reload">
|
||||
<div
|
||||
onClick={this.props.triggerNavigationReload}
|
||||
style={{transform: 'rotate(90deg)'}}
|
||||
>
|
||||
<Icon type="rotate" {...iconProps} />
|
||||
{/*<ReloadIcon {...iconProps} height={15} width={15} padding={5} />*/}
|
||||
</div>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
<Grid item className={cx(commonStyles.icons, commonStyles.enabled)}>
|
||||
<Tooltip title="Go to Homepage">
|
||||
<div
|
||||
className={commonStyles.flexAlignVerticalMiddle}
|
||||
onClick={this.props.goToHomepage}
|
||||
>
|
||||
<HomeIcon {...iconProps} padding={5} />
|
||||
</div>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
render() {
|
||||
const iconProps = {
|
||||
color: iconsColor,
|
||||
height: 25,
|
||||
width: 25,
|
||||
};
|
||||
const {backEnabled, forwardEnabled} = this.props;
|
||||
return (
|
||||
<div className={styles.navigationControls}>
|
||||
<Grid container spacing={1} alignItems="center">
|
||||
<Grid
|
||||
item
|
||||
className={cx(commonStyles.icons, {
|
||||
[commonStyles.disabled]: !backEnabled,
|
||||
[commonStyles.enabled]: backEnabled,
|
||||
})}
|
||||
>
|
||||
<div
|
||||
className={cx(commonStyles.iconDisabler, {
|
||||
[commonStyles.disabled]: !backEnabled,
|
||||
})}
|
||||
/>
|
||||
<Tooltip title="Back">
|
||||
<div onClick={this.props.triggerNavigationBack}>
|
||||
<Icon
|
||||
type="arrowLeft"
|
||||
size="30px"
|
||||
{...iconProps}
|
||||
/>
|
||||
{/*<ArrowLeftIcon {...iconProps} />*/}
|
||||
</div>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
<Grid
|
||||
item
|
||||
className={cx(commonStyles.icons, {
|
||||
[commonStyles.disabled]: !forwardEnabled,
|
||||
[commonStyles.enabled]: forwardEnabled,
|
||||
})}
|
||||
>
|
||||
<div
|
||||
className={cx(commonStyles.iconDisabler, {
|
||||
[commonStyles.disabled]: !forwardEnabled,
|
||||
})}
|
||||
/>
|
||||
<Tooltip title="Forward">
|
||||
<div onClick={this.props.triggerNavigationForward}>
|
||||
<Icon
|
||||
type="arrowRight"
|
||||
size="30px"
|
||||
{...iconProps}
|
||||
/>
|
||||
{/*<ArrowRightIcon {...iconProps} />*/}
|
||||
</div>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
<Grid
|
||||
item
|
||||
className={cx(commonStyles.icons, commonStyles.enabled)}
|
||||
>
|
||||
<Tooltip title="Reload">
|
||||
<div
|
||||
onClick={this.props.triggerNavigationReload}
|
||||
style={{transform: 'rotate(90deg)'}}
|
||||
>
|
||||
<Icon type="rotate" {...iconProps} />
|
||||
{/*<ReloadIcon {...iconProps} height={15} width={15} padding={5} />*/}
|
||||
</div>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
<Grid
|
||||
item
|
||||
className={cx(commonStyles.icons, commonStyles.enabled)}
|
||||
>
|
||||
<Tooltip title="Go to Homepage">
|
||||
<div
|
||||
className={commonStyles.flexAlignVerticalMiddle}
|
||||
onClick={this.props.goToHomepage}
|
||||
>
|
||||
<HomeIcon {...iconProps} padding={5} />
|
||||
</div>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default NavigationControls;
|
||||
|
|
|
@ -8,20 +8,20 @@ import BrowserZoom from './';
|
|||
import Slider from '@material-ui/core/Slider';
|
||||
|
||||
describe('<BrowserZoom />', () => {
|
||||
it('Renders label and the slider component ', () => {
|
||||
const wrapper = shallow(<BrowserZoom />);
|
||||
expect(wrapper.find(Slider)).to.have.lengthOf(1);
|
||||
});
|
||||
it('Renders label and the slider component ', () => {
|
||||
const wrapper = shallow(<BrowserZoom />);
|
||||
expect(wrapper.find(Slider)).to.have.lengthOf(1);
|
||||
});
|
||||
|
||||
it('Calls the callback on slider change', () => {
|
||||
const onChange = sinon.spy();
|
||||
const wrapper = mount(<BrowserZoom onChange={onChange} />);
|
||||
wrapper.find('.MuiSlider-thumb').simulate('mousedown');
|
||||
wrapper.find('.MuiSlider-thumb').simulate('mouseup');
|
||||
expect(onChange).to.have.property('callCount', 1);
|
||||
});
|
||||
it('Calls the callback on slider change', () => {
|
||||
const onChange = sinon.spy();
|
||||
const wrapper = mount(<BrowserZoom onChange={onChange} />);
|
||||
wrapper.find('.MuiSlider-thumb').simulate('mousedown');
|
||||
wrapper.find('.MuiSlider-thumb').simulate('mouseup');
|
||||
expect(onChange).to.have.property('callCount', 1);
|
||||
});
|
||||
|
||||
/*it('Calls the callback with a number value', () => {
|
||||
/*it('Calls the callback with a number value', () => {
|
||||
const onChange = sinon.spy();
|
||||
const wrapper = mount(<BrowserZoom onChange={onChange} />);
|
||||
wrapper.find('.MuiSlider-thumb').simulate('mousedown');
|
||||
|
|
|
@ -3,19 +3,19 @@ import Spinner from '../Spinner';
|
|||
import Tick from '../icons/TickAnimation';
|
||||
|
||||
export default function NotificationMessage(props) {
|
||||
return (
|
||||
<div style={{display: 'flex'}}>
|
||||
{props.spinner && (
|
||||
<div style={{marginRight: 5}}>
|
||||
<Spinner />
|
||||
return (
|
||||
<div style={{display: 'flex'}}>
|
||||
{props.spinner && (
|
||||
<div style={{marginRight: 5}}>
|
||||
<Spinner />
|
||||
</div>
|
||||
)}
|
||||
{props.tick && (
|
||||
<div style={{marginRight: 5}}>
|
||||
<Tick />
|
||||
</div>
|
||||
)}
|
||||
{props.message}
|
||||
</div>
|
||||
)}
|
||||
{props.tick && (
|
||||
<div style={{marginRight: 5}}>
|
||||
<Tick />
|
||||
</div>
|
||||
)}
|
||||
{props.message}
|
||||
</div>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
|
|
@ -3,61 +3,61 @@ import cx from 'classnames';
|
|||
import Select from 'react-select';
|
||||
import LayoutIcon from '../icons/Layout';
|
||||
import {
|
||||
HORIZONTAL_LAYOUT,
|
||||
FLEXIGRID_LAYOUT,
|
||||
INDIVIDUAL_LAYOUT,
|
||||
HORIZONTAL_LAYOUT,
|
||||
FLEXIGRID_LAYOUT,
|
||||
INDIVIDUAL_LAYOUT,
|
||||
} from '../../constants/previewerLayouts';
|
||||
|
||||
import commonStyles from '../common.styles.css';
|
||||
|
||||
const options = [
|
||||
{value: HORIZONTAL_LAYOUT, label: 'Horizontal'},
|
||||
{value: FLEXIGRID_LAYOUT, label: 'FlexiGrid'},
|
||||
{value: INDIVIDUAL_LAYOUT, label: 'Individual'},
|
||||
{value: HORIZONTAL_LAYOUT, label: 'Horizontal'},
|
||||
{value: FLEXIGRID_LAYOUT, label: 'FlexiGrid'},
|
||||
{value: INDIVIDUAL_LAYOUT, label: 'Individual'},
|
||||
];
|
||||
|
||||
const styles = {
|
||||
control: styles => ({...styles, backgroundColor: '#ffffff10'}),
|
||||
option: (styles, {data, isDisabled, isFocused, isSelected}) => {
|
||||
const color = 'white';
|
||||
return {
|
||||
...styles,
|
||||
backgroundColor: isDisabled
|
||||
? null
|
||||
: isSelected
|
||||
? '#ffffff40'
|
||||
: isFocused
|
||||
? '#ffffff20'
|
||||
: null,
|
||||
color: 'white',
|
||||
control: styles => ({...styles, backgroundColor: '#ffffff10'}),
|
||||
option: (styles, {data, isDisabled, isFocused, isSelected}) => {
|
||||
const color = 'white';
|
||||
return {
|
||||
...styles,
|
||||
backgroundColor: isDisabled
|
||||
? null
|
||||
: isSelected
|
||||
? '#ffffff40'
|
||||
: isFocused
|
||||
? '#ffffff20'
|
||||
: null,
|
||||
color: 'white',
|
||||
|
||||
':active': {
|
||||
...styles[':active'],
|
||||
backgroundColor: !isDisabled && '#ffffff40',
|
||||
},
|
||||
};
|
||||
},
|
||||
input: styles => ({...styles}),
|
||||
placeholder: styles => ({...styles}),
|
||||
singleValue: (styles, {data}) => ({...styles, color: 'white'}),
|
||||
menu: styles => ({...styles, background: '#4b4b4b', zIndex: 100}),
|
||||
':active': {
|
||||
...styles[':active'],
|
||||
backgroundColor: !isDisabled && '#ffffff40',
|
||||
},
|
||||
};
|
||||
},
|
||||
input: styles => ({...styles}),
|
||||
placeholder: styles => ({...styles}),
|
||||
singleValue: (styles, {data}) => ({...styles, color: 'white'}),
|
||||
menu: styles => ({...styles, background: '#4b4b4b', zIndex: 100}),
|
||||
};
|
||||
|
||||
export default function PreviewerLayoutSelector(props) {
|
||||
return (
|
||||
<div className={cx(commonStyles.sidebarContentSection)}>
|
||||
<div className={cx(commonStyles.sidebarContentSectionTitleBar)}>
|
||||
<LayoutIcon height={18} margin={6} color="white" />
|
||||
Layout
|
||||
</div>
|
||||
<div className={cx(commonStyles.sidebarContentSectionContainer)}>
|
||||
<Select
|
||||
options={options}
|
||||
value={options.find(option => option.value === props.value)}
|
||||
onChange={props.onChange}
|
||||
styles={styles}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div className={cx(commonStyles.sidebarContentSection)}>
|
||||
<div className={cx(commonStyles.sidebarContentSectionTitleBar)}>
|
||||
<LayoutIcon height={18} margin={6} color="white" />
|
||||
Layout
|
||||
</div>
|
||||
<div className={cx(commonStyles.sidebarContentSectionContainer)}>
|
||||
<Select
|
||||
options={options}
|
||||
value={options.find(option => option.value === props.value)}
|
||||
onChange={props.onChange}
|
||||
styles={styles}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -15,125 +15,189 @@ import {OS, DEVICE_TYPE} from '../../constants/devices';
|
|||
import {FILTER_FIELDS} from '../../reducers/browser';
|
||||
|
||||
export default function QuickFilterDevices(props) {
|
||||
return (
|
||||
<div className={cx(commonStyles.sidebarContentSection)}>
|
||||
<div className={cx(commonStyles.sidebarContentSectionTitleBar)}>
|
||||
<Icon type="filter" color="white" size="30px" /> Quick Filters
|
||||
</div>
|
||||
<div className={cx(commonStyles.sidebarContentSectionContainer)}>
|
||||
<div className={cx(styles.filterSection)}>
|
||||
<div className={cx(styles.sectionTitle)}>Operating System</div>
|
||||
<div className={cx(styles.optionIconsContainer)}>
|
||||
<div
|
||||
className={cx(styles.optionIcon, commonStyles.icons, {
|
||||
[commonStyles.disabled]: false,
|
||||
[commonStyles.enabled]: true,
|
||||
[commonStyles.selected]:
|
||||
props.browser.filters[FILTER_FIELDS.OS].indexOf(OS.ios) !==
|
||||
-1,
|
||||
})}
|
||||
onClick={() => props.toggleFilter(FILTER_FIELDS.OS, OS.ios)}
|
||||
>
|
||||
<AppleIcon color={iconsColor} height={40} />
|
||||
return (
|
||||
<div className={cx(commonStyles.sidebarContentSection)}>
|
||||
<div className={cx(commonStyles.sidebarContentSectionTitleBar)}>
|
||||
<Icon type="filter" color="white" size="30px" /> Quick Filters
|
||||
</div>
|
||||
<div
|
||||
className={cx(styles.optionIcon, commonStyles.icons, {
|
||||
[commonStyles.disabled]: false,
|
||||
[commonStyles.enabled]: true,
|
||||
[commonStyles.selected]:
|
||||
props.browser.filters[FILTER_FIELDS.OS].indexOf(
|
||||
OS.android
|
||||
) !== -1,
|
||||
})}
|
||||
onClick={() => props.toggleFilter(FILTER_FIELDS.OS, OS.android)}
|
||||
>
|
||||
<AndroidIcon color={iconsColor} style={{fontSize: 40}} />
|
||||
<div className={cx(commonStyles.sidebarContentSectionContainer)}>
|
||||
<div className={cx(styles.filterSection)}>
|
||||
<div className={cx(styles.sectionTitle)}>
|
||||
Operating System
|
||||
</div>
|
||||
<div className={cx(styles.optionIconsContainer)}>
|
||||
<div
|
||||
className={cx(
|
||||
styles.optionIcon,
|
||||
commonStyles.icons,
|
||||
{
|
||||
[commonStyles.disabled]: false,
|
||||
[commonStyles.enabled]: true,
|
||||
[commonStyles.selected]:
|
||||
props.browser.filters[
|
||||
FILTER_FIELDS.OS
|
||||
].indexOf(OS.ios) !== -1,
|
||||
}
|
||||
)}
|
||||
onClick={() =>
|
||||
props.toggleFilter(FILTER_FIELDS.OS, OS.ios)
|
||||
}
|
||||
>
|
||||
<AppleIcon color={iconsColor} height={40} />
|
||||
</div>
|
||||
<div
|
||||
className={cx(
|
||||
styles.optionIcon,
|
||||
commonStyles.icons,
|
||||
{
|
||||
[commonStyles.disabled]: false,
|
||||
[commonStyles.enabled]: true,
|
||||
[commonStyles.selected]:
|
||||
props.browser.filters[
|
||||
FILTER_FIELDS.OS
|
||||
].indexOf(OS.android) !== -1,
|
||||
}
|
||||
)}
|
||||
onClick={() =>
|
||||
props.toggleFilter(FILTER_FIELDS.OS, OS.android)
|
||||
}
|
||||
>
|
||||
<AndroidIcon
|
||||
color={iconsColor}
|
||||
style={{fontSize: 40}}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={cx(
|
||||
styles.optionIcon,
|
||||
commonStyles.icons,
|
||||
{
|
||||
[commonStyles.disabled]: false,
|
||||
[commonStyles.enabled]: true,
|
||||
[commonStyles.selected]:
|
||||
props.browser.filters[
|
||||
FILTER_FIELDS.OS
|
||||
].indexOf(OS.windowsPhone) !== -1,
|
||||
}
|
||||
)}
|
||||
onClick={() =>
|
||||
props.toggleFilter(
|
||||
FILTER_FIELDS.OS,
|
||||
OS.windowsPhone
|
||||
)
|
||||
}
|
||||
>
|
||||
<WindowsIcon
|
||||
color={iconsColor}
|
||||
height={34}
|
||||
padding={3}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={cx(
|
||||
styles.optionIcon,
|
||||
commonStyles.icons,
|
||||
{
|
||||
[commonStyles.disabled]: false,
|
||||
[commonStyles.enabled]: true,
|
||||
[commonStyles.selected]:
|
||||
props.browser.filters[
|
||||
FILTER_FIELDS.OS
|
||||
].indexOf(OS.pc) !== -1,
|
||||
}
|
||||
)}
|
||||
onClick={() =>
|
||||
props.toggleFilter(FILTER_FIELDS.OS, OS.pc)
|
||||
}
|
||||
>
|
||||
<DesktopIcon
|
||||
color={iconsColor}
|
||||
style={{fontSize: 40}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={cx(styles.filterSection)}>
|
||||
<div className={cx(styles.sectionTitle)}>Device</div>
|
||||
<div className={cx(styles.optionIconsContainer)}>
|
||||
<div
|
||||
className={cx(
|
||||
styles.optionIcon,
|
||||
commonStyles.icons,
|
||||
{
|
||||
[commonStyles.disabled]: false,
|
||||
[commonStyles.enabled]: true,
|
||||
[commonStyles.selected]:
|
||||
props.browser.filters[
|
||||
FILTER_FIELDS.DEVICE_TYPE
|
||||
].indexOf(DEVICE_TYPE.phone) !== -1,
|
||||
}
|
||||
)}
|
||||
onClick={() =>
|
||||
props.toggleFilter(
|
||||
FILTER_FIELDS.DEVICE_TYPE,
|
||||
DEVICE_TYPE.phone
|
||||
)
|
||||
}
|
||||
>
|
||||
<MobileIcon
|
||||
color={iconsColor}
|
||||
style={{fontSize: 35}}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={cx(
|
||||
styles.optionIcon,
|
||||
commonStyles.icons,
|
||||
{
|
||||
[commonStyles.disabled]: false,
|
||||
[commonStyles.enabled]: true,
|
||||
[commonStyles.selected]:
|
||||
props.browser.filters[
|
||||
FILTER_FIELDS.DEVICE_TYPE
|
||||
].indexOf(DEVICE_TYPE.tablet) !== -1,
|
||||
}
|
||||
)}
|
||||
onClick={() =>
|
||||
props.toggleFilter(
|
||||
FILTER_FIELDS.DEVICE_TYPE,
|
||||
DEVICE_TYPE.tablet
|
||||
)
|
||||
}
|
||||
>
|
||||
<TabletIcon
|
||||
color={iconsColor}
|
||||
style={{fontSize: 35}}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={cx(
|
||||
styles.optionIcon,
|
||||
commonStyles.icons,
|
||||
{
|
||||
[commonStyles.disabled]: false,
|
||||
[commonStyles.enabled]: true,
|
||||
[commonStyles.selected]:
|
||||
props.browser.filters[
|
||||
FILTER_FIELDS.DEVICE_TYPE
|
||||
].indexOf(DEVICE_TYPE.desktop) !== -1,
|
||||
}
|
||||
)}
|
||||
onClick={() =>
|
||||
props.toggleFilter(
|
||||
FILTER_FIELDS.DEVICE_TYPE,
|
||||
DEVICE_TYPE.desktop
|
||||
)
|
||||
}
|
||||
>
|
||||
<DesktopIcon
|
||||
color={iconsColor}
|
||||
style={{fontSize: 40}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={cx(styles.optionIcon, commonStyles.icons, {
|
||||
[commonStyles.disabled]: false,
|
||||
[commonStyles.enabled]: true,
|
||||
[commonStyles.selected]:
|
||||
props.browser.filters[FILTER_FIELDS.OS].indexOf(
|
||||
OS.windowsPhone
|
||||
) !== -1,
|
||||
})}
|
||||
onClick={() =>
|
||||
props.toggleFilter(FILTER_FIELDS.OS, OS.windowsPhone)
|
||||
}
|
||||
>
|
||||
<WindowsIcon color={iconsColor} height={34} padding={3} />
|
||||
</div>
|
||||
<div
|
||||
className={cx(styles.optionIcon, commonStyles.icons, {
|
||||
[commonStyles.disabled]: false,
|
||||
[commonStyles.enabled]: true,
|
||||
[commonStyles.selected]:
|
||||
props.browser.filters[FILTER_FIELDS.OS].indexOf(OS.pc) !== -1,
|
||||
})}
|
||||
onClick={() => props.toggleFilter(FILTER_FIELDS.OS, OS.pc)}
|
||||
>
|
||||
<DesktopIcon color={iconsColor} style={{fontSize: 40}} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={cx(styles.filterSection)}>
|
||||
<div className={cx(styles.sectionTitle)}>Device</div>
|
||||
<div className={cx(styles.optionIconsContainer)}>
|
||||
<div
|
||||
className={cx(styles.optionIcon, commonStyles.icons, {
|
||||
[commonStyles.disabled]: false,
|
||||
[commonStyles.enabled]: true,
|
||||
[commonStyles.selected]:
|
||||
props.browser.filters[FILTER_FIELDS.DEVICE_TYPE].indexOf(
|
||||
DEVICE_TYPE.phone
|
||||
) !== -1,
|
||||
})}
|
||||
onClick={() =>
|
||||
props.toggleFilter(FILTER_FIELDS.DEVICE_TYPE, DEVICE_TYPE.phone)
|
||||
}
|
||||
>
|
||||
<MobileIcon color={iconsColor} style={{fontSize: 35}} />
|
||||
</div>
|
||||
<div
|
||||
className={cx(styles.optionIcon, commonStyles.icons, {
|
||||
[commonStyles.disabled]: false,
|
||||
[commonStyles.enabled]: true,
|
||||
[commonStyles.selected]:
|
||||
props.browser.filters[FILTER_FIELDS.DEVICE_TYPE].indexOf(
|
||||
DEVICE_TYPE.tablet
|
||||
) !== -1,
|
||||
})}
|
||||
onClick={() =>
|
||||
props.toggleFilter(
|
||||
FILTER_FIELDS.DEVICE_TYPE,
|
||||
DEVICE_TYPE.tablet
|
||||
)
|
||||
}
|
||||
>
|
||||
<TabletIcon color={iconsColor} style={{fontSize: 35}} />
|
||||
</div>
|
||||
<div
|
||||
className={cx(styles.optionIcon, commonStyles.icons, {
|
||||
[commonStyles.disabled]: false,
|
||||
[commonStyles.enabled]: true,
|
||||
[commonStyles.selected]:
|
||||
props.browser.filters[FILTER_FIELDS.DEVICE_TYPE].indexOf(
|
||||
DEVICE_TYPE.desktop
|
||||
) !== -1,
|
||||
})}
|
||||
onClick={() =>
|
||||
props.toggleFilter(
|
||||
FILTER_FIELDS.DEVICE_TYPE,
|
||||
DEVICE_TYPE.desktop
|
||||
)
|
||||
}
|
||||
>
|
||||
<DesktopIcon color={iconsColor} style={{fontSize: 40}} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
|
|
@ -9,27 +9,29 @@ import styles from './style.module.css';
|
|||
import {getDeviceIcon} from '../../utils/iconUtils';
|
||||
|
||||
function Renderer(props) {
|
||||
const [loading, setLoading] = useState(true);
|
||||
return (
|
||||
<div className={cx(styles.container, {[styles.hidden]: props.hidden})}>
|
||||
<div className={styles.titleContainer}>
|
||||
{getDeviceIcon(props.device.type)}
|
||||
<span className={cx(styles.deviceTitle)}>{props.device.name}</span>
|
||||
{loading && (
|
||||
<div>
|
||||
<Spinner size={16} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className={cx(styles.deviceWrapper)}>
|
||||
<WebViewContainer
|
||||
device={props.device}
|
||||
transmitNavigatorStatus={props.transmitNavigatorStatus}
|
||||
onLoadingStateChange={setLoading}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
const [loading, setLoading] = useState(true);
|
||||
return (
|
||||
<div className={cx(styles.container, {[styles.hidden]: props.hidden})}>
|
||||
<div className={styles.titleContainer}>
|
||||
{getDeviceIcon(props.device.type)}
|
||||
<span className={cx(styles.deviceTitle)}>
|
||||
{props.device.name}
|
||||
</span>
|
||||
{loading && (
|
||||
<div>
|
||||
<Spinner size={16} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className={cx(styles.deviceWrapper)}>
|
||||
<WebViewContainer
|
||||
device={props.device}
|
||||
transmitNavigatorStatus={props.transmitNavigatorStatus}
|
||||
onLoadingStateChange={setLoading}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Renderer;
|
||||
|
|
|
@ -7,35 +7,47 @@ import Renderer from './';
|
|||
|
||||
const testSrc = 'https://testUrl.com';
|
||||
const testDevice1 = {
|
||||
name: 'testDevice1',
|
||||
width: 100,
|
||||
height: 100,
|
||||
name: 'testDevice1',
|
||||
width: 100,
|
||||
height: 100,
|
||||
};
|
||||
|
||||
describe('<Renderer />', () => {
|
||||
it('Renders the header and the iframe', () => {
|
||||
const wrapper = shallow(<Renderer src={testSrc} device={testDevice1} />);
|
||||
expect(wrapper.find('iframe')).to.have.lengthOf(1);
|
||||
expect(wrapper.find('h2')).to.have.lengthOf(1);
|
||||
});
|
||||
it('Renders the header and the iframe', () => {
|
||||
const wrapper = shallow(
|
||||
<Renderer src={testSrc} device={testDevice1} />
|
||||
);
|
||||
expect(wrapper.find('iframe')).to.have.lengthOf(1);
|
||||
expect(wrapper.find('h2')).to.have.lengthOf(1);
|
||||
});
|
||||
|
||||
it('Renders the header with the device name', () => {
|
||||
const wrapper = shallow(<Renderer src={testSrc} device={testDevice1} />);
|
||||
expect(wrapper.find('h2').text()).to.equal(testDevice1.name);
|
||||
});
|
||||
it('Renders the header with the device name', () => {
|
||||
const wrapper = shallow(
|
||||
<Renderer src={testSrc} device={testDevice1} />
|
||||
);
|
||||
expect(wrapper.find('h2').text()).to.equal(testDevice1.name);
|
||||
});
|
||||
|
||||
it('Renders the iframe with the given device dimensions', () => {
|
||||
const wrapper = shallow(<Renderer src={testSrc} device={testDevice1} />);
|
||||
expect(wrapper.find('iframe').prop('width')).to.equal(testDevice1.width);
|
||||
expect(wrapper.find('iframe').prop('height')).to.equal(testDevice1.height);
|
||||
});
|
||||
it('Renders the iframe with the given device dimensions', () => {
|
||||
const wrapper = shallow(
|
||||
<Renderer src={testSrc} device={testDevice1} />
|
||||
);
|
||||
expect(wrapper.find('iframe').prop('width')).to.equal(
|
||||
testDevice1.width
|
||||
);
|
||||
expect(wrapper.find('iframe').prop('height')).to.equal(
|
||||
testDevice1.height
|
||||
);
|
||||
});
|
||||
|
||||
it('Renders the iframe with the given url', () => {
|
||||
const wrapper = shallow(<Renderer src={testSrc} device={testDevice1} />);
|
||||
expect(wrapper.find('iframe').prop('src')).to.equal(testSrc);
|
||||
});
|
||||
it('Renders the iframe with the given url', () => {
|
||||
const wrapper = shallow(
|
||||
<Renderer src={testSrc} device={testDevice1} />
|
||||
);
|
||||
expect(wrapper.find('iframe').prop('src')).to.equal(testSrc);
|
||||
});
|
||||
|
||||
/*it('Calls the callback with a number value', () => {
|
||||
/*it('Calls the callback with a number value', () => {
|
||||
const onChange = sinon.spy();
|
||||
const wrapper = mount(<BrowserZoom onChange={onChange} />);
|
||||
wrapper.find('.MuiSlider-thumb').simulate('mousedown');
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
|
||||
export default function Screenshotmanager(props) {
|
||||
return '';
|
||||
return '';
|
||||
}
|
||||
|
|
|
@ -15,55 +15,74 @@ import ZoomContainer from '../../containers/ZoomContainer';
|
|||
import Tooltip from '@material-ui/core/Tooltip';
|
||||
|
||||
class ScrollControls extends Component {
|
||||
render() {
|
||||
const iconProps = {
|
||||
color: iconsColor,
|
||||
height: 25,
|
||||
width: 25,
|
||||
};
|
||||
return (
|
||||
<div className={styles.scrollControls}>
|
||||
<Grid container spacing={1} alignItems="center">
|
||||
<Grid item className={cx(commonStyles.icons, commonStyles.enabled)}>
|
||||
<Tooltip title="Scroll Down">
|
||||
<div onClick={this.props.triggerScrollDown}>
|
||||
<ScrollDownIcon {...iconProps} />
|
||||
</div>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
<Grid item className={cx(commonStyles.icons, commonStyles.enabled)}>
|
||||
<Tooltip title="Scroll Up">
|
||||
<div onClick={this.props.triggerScrollUp}>
|
||||
<ScrollUpIcon {...iconProps} height={30} width={30} />
|
||||
</div>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
<Grid item className={cx(commonStyles.icons, commonStyles.enabled)}>
|
||||
<Tooltip title="Take Screenshot">
|
||||
<div onClick={this.props.screenshotAllDevices}>
|
||||
<ScreenshotIcon {...iconProps} />
|
||||
</div>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
<Grid item className={cx(commonStyles.icons, commonStyles.enabled)}>
|
||||
<Tooltip title="Tilt Devices">
|
||||
<div onClick={this.props.flipOrientationAllDevices}>
|
||||
<DeviceRotateIcon {...iconProps} />
|
||||
</div>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
<Grid item className={cx(commonStyles.icons, commonStyles.enabled)}>
|
||||
<Tooltip title="Inspect Element">
|
||||
<div onClick={this.props.enableInpector}>
|
||||
<InspectElementIcon {...iconProps} />
|
||||
</div>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
<ZoomContainer />
|
||||
</Grid>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
render() {
|
||||
const iconProps = {
|
||||
color: iconsColor,
|
||||
height: 25,
|
||||
width: 25,
|
||||
};
|
||||
return (
|
||||
<div className={styles.scrollControls}>
|
||||
<Grid container spacing={1} alignItems="center">
|
||||
<Grid
|
||||
item
|
||||
className={cx(commonStyles.icons, commonStyles.enabled)}
|
||||
>
|
||||
<Tooltip title="Scroll Down">
|
||||
<div onClick={this.props.triggerScrollDown}>
|
||||
<ScrollDownIcon {...iconProps} />
|
||||
</div>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
<Grid
|
||||
item
|
||||
className={cx(commonStyles.icons, commonStyles.enabled)}
|
||||
>
|
||||
<Tooltip title="Scroll Up">
|
||||
<div onClick={this.props.triggerScrollUp}>
|
||||
<ScrollUpIcon
|
||||
{...iconProps}
|
||||
height={30}
|
||||
width={30}
|
||||
/>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
<Grid
|
||||
item
|
||||
className={cx(commonStyles.icons, commonStyles.enabled)}
|
||||
>
|
||||
<Tooltip title="Take Screenshot">
|
||||
<div onClick={this.props.screenshotAllDevices}>
|
||||
<ScreenshotIcon {...iconProps} />
|
||||
</div>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
<Grid
|
||||
item
|
||||
className={cx(commonStyles.icons, commonStyles.enabled)}
|
||||
>
|
||||
<Tooltip title="Tilt Devices">
|
||||
<div onClick={this.props.flipOrientationAllDevices}>
|
||||
<DeviceRotateIcon {...iconProps} />
|
||||
</div>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
<Grid
|
||||
item
|
||||
className={cx(commonStyles.icons, commonStyles.enabled)}
|
||||
>
|
||||
<Tooltip title="Inspect Element">
|
||||
<div onClick={this.props.enableInpector}>
|
||||
<InspectElementIcon {...iconProps} />
|
||||
</div>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
<ZoomContainer />
|
||||
</Grid>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ScrollControls;
|
||||
|
|
|
@ -8,20 +8,20 @@ import BrowserZoom from './';
|
|||
import Slider from '@material-ui/core/Slider';
|
||||
|
||||
describe('<BrowserZoom />', () => {
|
||||
it('Renders label and the slider component ', () => {
|
||||
const wrapper = shallow(<BrowserZoom />);
|
||||
expect(wrapper.find(Slider)).to.have.lengthOf(1);
|
||||
});
|
||||
it('Renders label and the slider component ', () => {
|
||||
const wrapper = shallow(<BrowserZoom />);
|
||||
expect(wrapper.find(Slider)).to.have.lengthOf(1);
|
||||
});
|
||||
|
||||
it('Calls the callback on slider change', () => {
|
||||
const onChange = sinon.spy();
|
||||
const wrapper = mount(<BrowserZoom onChange={onChange} />);
|
||||
wrapper.find('.MuiSlider-thumb').simulate('mousedown');
|
||||
wrapper.find('.MuiSlider-thumb').simulate('mouseup');
|
||||
expect(onChange).to.have.property('callCount', 1);
|
||||
});
|
||||
it('Calls the callback on slider change', () => {
|
||||
const onChange = sinon.spy();
|
||||
const wrapper = mount(<BrowserZoom onChange={onChange} />);
|
||||
wrapper.find('.MuiSlider-thumb').simulate('mousedown');
|
||||
wrapper.find('.MuiSlider-thumb').simulate('mouseup');
|
||||
expect(onChange).to.have.property('callCount', 1);
|
||||
});
|
||||
|
||||
/*it('Calls the callback with a number value', () => {
|
||||
/*it('Calls the callback with a number value', () => {
|
||||
const onChange = sinon.spy();
|
||||
const wrapper = mount(<BrowserZoom onChange={onChange} />);
|
||||
wrapper.find('.MuiSlider-thumb').simulate('mousedown');
|
||||
|
|
|
@ -3,43 +3,43 @@ import CircularProgress from '@material-ui/core/CircularProgress';
|
|||
import {makeStyles} from '@material-ui/core/styles';
|
||||
|
||||
export default function(props) {
|
||||
const classes = makeStyles({
|
||||
root: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
position: 'relative',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
top: {
|
||||
color: '#ffffff00', //'#eef3fd',
|
||||
},
|
||||
bottom: {
|
||||
color: '#7587ec', //'#6798e5',
|
||||
animationDuration: '550ms',
|
||||
position: 'absolute',
|
||||
},
|
||||
})();
|
||||
const classes = makeStyles({
|
||||
root: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
position: 'relative',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
top: {
|
||||
color: '#ffffff00', //'#eef3fd',
|
||||
},
|
||||
bottom: {
|
||||
color: '#7587ec', //'#6798e5',
|
||||
animationDuration: '550ms',
|
||||
position: 'absolute',
|
||||
},
|
||||
})();
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<CircularProgress
|
||||
variant="determinate"
|
||||
value={100}
|
||||
className={classes.top}
|
||||
size={20}
|
||||
thickness={4}
|
||||
{...props}
|
||||
/>
|
||||
<CircularProgress
|
||||
variant="indeterminate"
|
||||
disableShrink
|
||||
className={classes.bottom}
|
||||
size={20}
|
||||
thickness={4}
|
||||
{...props}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<CircularProgress
|
||||
variant="determinate"
|
||||
value={100}
|
||||
className={classes.top}
|
||||
size={20}
|
||||
thickness={4}
|
||||
{...props}
|
||||
/>
|
||||
<CircularProgress
|
||||
variant="indeterminate"
|
||||
disableShrink
|
||||
className={classes.bottom}
|
||||
size={20}
|
||||
thickness={4}
|
||||
{...props}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,15 +8,15 @@ import DeviceRotateIcon from '../icons/DeviceRotate';
|
|||
import cx from 'classnames';
|
||||
import {iconsColor} from '../../constants/colors';
|
||||
import {
|
||||
SCROLL_DOWN,
|
||||
SCROLL_UP,
|
||||
NAVIGATION_BACK,
|
||||
NAVIGATION_FORWARD,
|
||||
NAVIGATION_RELOAD,
|
||||
SCREENSHOT_ALL_DEVICES,
|
||||
FLIP_ORIENTATION_ALL_DEVICES,
|
||||
ENABLE_INSPECTOR_ALL_DEVICES,
|
||||
DISABLE_INSPECTOR_ALL_DEVICES,
|
||||
SCROLL_DOWN,
|
||||
SCROLL_UP,
|
||||
NAVIGATION_BACK,
|
||||
NAVIGATION_FORWARD,
|
||||
NAVIGATION_RELOAD,
|
||||
SCREENSHOT_ALL_DEVICES,
|
||||
FLIP_ORIENTATION_ALL_DEVICES,
|
||||
ENABLE_INSPECTOR_ALL_DEVICES,
|
||||
DISABLE_INSPECTOR_ALL_DEVICES,
|
||||
} from '../../constants/pubsubEvents';
|
||||
import {CAPABILITIES} from '../../constants/devices';
|
||||
|
||||
|
@ -29,287 +29,304 @@ import {Tooltip} from '@material-ui/core';
|
|||
const BrowserWindow = remote.BrowserWindow;
|
||||
|
||||
const MESSAGE_TYPES = {
|
||||
scroll: 'scroll',
|
||||
click: 'click',
|
||||
openDevToolsInspector: 'openDevToolsInspector',
|
||||
disableInspector: 'disableInspector',
|
||||
openConsole: 'openConsole',
|
||||
tiltDevice: 'tiltDevice',
|
||||
takeScreenshot: 'takeScreenshot',
|
||||
toggleEventMirroring: 'toggleEventMirroring',
|
||||
scroll: 'scroll',
|
||||
click: 'click',
|
||||
openDevToolsInspector: 'openDevToolsInspector',
|
||||
disableInspector: 'disableInspector',
|
||||
openConsole: 'openConsole',
|
||||
tiltDevice: 'tiltDevice',
|
||||
takeScreenshot: 'takeScreenshot',
|
||||
toggleEventMirroring: 'toggleEventMirroring',
|
||||
};
|
||||
|
||||
class WebView extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.webviewRef = createRef();
|
||||
this.state = {
|
||||
screenshotInProgress: false,
|
||||
isTilted: false,
|
||||
isUnplugged: false,
|
||||
errorCode: null,
|
||||
errorDesc: null,
|
||||
};
|
||||
this.subscriptions = [];
|
||||
}
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.webviewRef = createRef();
|
||||
this.state = {
|
||||
screenshotInProgress: false,
|
||||
isTilted: false,
|
||||
isUnplugged: false,
|
||||
errorCode: null,
|
||||
errorDesc: null,
|
||||
};
|
||||
this.subscriptions = [];
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
//this.initDeviceEmulationParams();
|
||||
this.webviewRef.current.addEventListener(
|
||||
'ipc-message',
|
||||
this.messageHandler
|
||||
);
|
||||
this.subscriptions.push(
|
||||
pubsub.subscribe('scroll', this.processScrollEvent)
|
||||
);
|
||||
this.subscriptions.push(pubsub.subscribe('click', this.processClickEvent));
|
||||
this.subscriptions.push(
|
||||
pubsub.subscribe(SCROLL_DOWN, this.processScrollDownEvent)
|
||||
);
|
||||
this.subscriptions.push(
|
||||
pubsub.subscribe(SCROLL_UP, this.processScrollUpEvent)
|
||||
);
|
||||
this.subscriptions.push(
|
||||
pubsub.subscribe(NAVIGATION_BACK, this.processNavigationBackEvent)
|
||||
);
|
||||
this.subscriptions.push(
|
||||
pubsub.subscribe(NAVIGATION_FORWARD, this.processNavigationForwardEvent)
|
||||
);
|
||||
this.subscriptions.push(
|
||||
pubsub.subscribe(NAVIGATION_RELOAD, this.processNavigationReloadEvent)
|
||||
);
|
||||
this.subscriptions.push(
|
||||
pubsub.subscribe(SCREENSHOT_ALL_DEVICES, this.processScreenshotEvent)
|
||||
);
|
||||
this.subscriptions.push(
|
||||
pubsub.subscribe(
|
||||
FLIP_ORIENTATION_ALL_DEVICES,
|
||||
this.processFlipOrientationEvent
|
||||
)
|
||||
);
|
||||
this.subscriptions.push(
|
||||
pubsub.subscribe(
|
||||
ENABLE_INSPECTOR_ALL_DEVICES,
|
||||
this.processEnableInspectorEvent
|
||||
)
|
||||
);
|
||||
this.subscriptions.push(
|
||||
pubsub.subscribe(
|
||||
DISABLE_INSPECTOR_ALL_DEVICES,
|
||||
this.processDisableInspectorEvent
|
||||
)
|
||||
);
|
||||
|
||||
this.webviewRef.current.addEventListener('dom-ready', () => {
|
||||
this.initEventTriggers(this.webviewRef.current);
|
||||
});
|
||||
|
||||
this.webviewRef.current.addEventListener('did-start-loading', () => {
|
||||
this.setState({errorCode: null, errorDesc: null});
|
||||
this.props.onLoadingStateChange(true);
|
||||
});
|
||||
this.webviewRef.current.addEventListener('did-stop-loading', () => {
|
||||
this.props.onLoadingStateChange(false);
|
||||
});
|
||||
this.webviewRef.current.addEventListener(
|
||||
'did-fail-load',
|
||||
({errorCode, errorDescription}) => {
|
||||
if (errorCode === -3) {
|
||||
//Aborted error, can be ignored
|
||||
return;
|
||||
}
|
||||
this.setState({errorCode: errorCode, errorDesc: errorDescription});
|
||||
}
|
||||
);
|
||||
|
||||
this.webviewRef.current.addEventListener(
|
||||
'login',
|
||||
(event, request, authInfo, callback) => {
|
||||
console.log(
|
||||
'event, request, authInfo, callback',
|
||||
event,
|
||||
request,
|
||||
authInfo,
|
||||
callback
|
||||
componentDidMount() {
|
||||
//this.initDeviceEmulationParams();
|
||||
this.webviewRef.current.addEventListener(
|
||||
'ipc-message',
|
||||
this.messageHandler
|
||||
);
|
||||
this.subscriptions.push(
|
||||
pubsub.subscribe('scroll', this.processScrollEvent)
|
||||
);
|
||||
this.subscriptions.push(
|
||||
pubsub.subscribe('click', this.processClickEvent)
|
||||
);
|
||||
this.subscriptions.push(
|
||||
pubsub.subscribe(SCROLL_DOWN, this.processScrollDownEvent)
|
||||
);
|
||||
this.subscriptions.push(
|
||||
pubsub.subscribe(SCROLL_UP, this.processScrollUpEvent)
|
||||
);
|
||||
this.subscriptions.push(
|
||||
pubsub.subscribe(NAVIGATION_BACK, this.processNavigationBackEvent)
|
||||
);
|
||||
this.subscriptions.push(
|
||||
pubsub.subscribe(
|
||||
NAVIGATION_FORWARD,
|
||||
this.processNavigationForwardEvent
|
||||
)
|
||||
);
|
||||
this.subscriptions.push(
|
||||
pubsub.subscribe(
|
||||
NAVIGATION_RELOAD,
|
||||
this.processNavigationReloadEvent
|
||||
)
|
||||
);
|
||||
this.subscriptions.push(
|
||||
pubsub.subscribe(
|
||||
SCREENSHOT_ALL_DEVICES,
|
||||
this.processScreenshotEvent
|
||||
)
|
||||
);
|
||||
this.subscriptions.push(
|
||||
pubsub.subscribe(
|
||||
FLIP_ORIENTATION_ALL_DEVICES,
|
||||
this.processFlipOrientationEvent
|
||||
)
|
||||
);
|
||||
this.subscriptions.push(
|
||||
pubsub.subscribe(
|
||||
ENABLE_INSPECTOR_ALL_DEVICES,
|
||||
this.processEnableInspectorEvent
|
||||
)
|
||||
);
|
||||
this.subscriptions.push(
|
||||
pubsub.subscribe(
|
||||
DISABLE_INSPECTOR_ALL_DEVICES,
|
||||
this.processDisableInspectorEvent
|
||||
)
|
||||
);
|
||||
event.preventDefault();
|
||||
callback('username', 'secret');
|
||||
}
|
||||
);
|
||||
|
||||
this.webviewRef.current.addEventListener('will-navigate', ({url}) => {
|
||||
console.log('Navigating to ', url);
|
||||
this.props.onAddressChange(url);
|
||||
});
|
||||
|
||||
this.webviewRef.current.addEventListener('did-navigate', ({url}) => {
|
||||
if (this.props.transmitNavigatorStatus) {
|
||||
this.props.updateNavigatorStatus({
|
||||
backEnabled: this.webviewRef.current.canGoBack(),
|
||||
forwardEnabled: this.webviewRef.current.canGoForward(),
|
||||
this.webviewRef.current.addEventListener('dom-ready', () => {
|
||||
this.initEventTriggers(this.webviewRef.current);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.webviewRef.current.addEventListener('devtools-opened', () => {
|
||||
/*this.webviewRef.current
|
||||
this.webviewRef.current.addEventListener('did-start-loading', () => {
|
||||
this.setState({errorCode: null, errorDesc: null});
|
||||
this.props.onLoadingStateChange(true);
|
||||
});
|
||||
this.webviewRef.current.addEventListener('did-stop-loading', () => {
|
||||
this.props.onLoadingStateChange(false);
|
||||
});
|
||||
this.webviewRef.current.addEventListener(
|
||||
'did-fail-load',
|
||||
({errorCode, errorDescription}) => {
|
||||
if (errorCode === -3) {
|
||||
//Aborted error, can be ignored
|
||||
return;
|
||||
}
|
||||
this.setState({
|
||||
errorCode: errorCode,
|
||||
errorDesc: errorDescription,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
this.webviewRef.current.addEventListener(
|
||||
'login',
|
||||
(event, request, authInfo, callback) => {
|
||||
console.log(
|
||||
'event, request, authInfo, callback',
|
||||
event,
|
||||
request,
|
||||
authInfo,
|
||||
callback
|
||||
);
|
||||
event.preventDefault();
|
||||
callback('username', 'secret');
|
||||
}
|
||||
);
|
||||
|
||||
this.webviewRef.current.addEventListener('will-navigate', ({url}) => {
|
||||
console.log('Navigating to ', url);
|
||||
this.props.onAddressChange(url);
|
||||
});
|
||||
|
||||
this.webviewRef.current.addEventListener('did-navigate', ({url}) => {
|
||||
if (this.props.transmitNavigatorStatus) {
|
||||
this.props.updateNavigatorStatus({
|
||||
backEnabled: this.webviewRef.current.canGoBack(),
|
||||
forwardEnabled: this.webviewRef.current.canGoForward(),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.webviewRef.current.addEventListener('devtools-opened', () => {
|
||||
/*this.webviewRef.current
|
||||
.getWebContents()
|
||||
.devToolsWebContents.executeJavaScript(
|
||||
'DevToolsAPI.enterInspectElementMode()'
|
||||
);*/
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.subscriptions.forEach(pubsub.unsubscribe);
|
||||
}
|
||||
|
||||
initDeviceEmulationParams = () => {
|
||||
try {
|
||||
return;
|
||||
this.webviewRef.current.getWebContents().enableDeviceEmulation({
|
||||
screenPosition: this.isMobile ? 'mobile' : 'desktop',
|
||||
screenSize: {
|
||||
width: this.props.device.width,
|
||||
height: this.props.device.height,
|
||||
},
|
||||
deviceScaleFactor: this.props.device.dpr,
|
||||
});
|
||||
} catch (err) {
|
||||
console.log('err', err);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
processNavigationBackEvent = () => {
|
||||
this.webviewRef.current.goBack();
|
||||
};
|
||||
|
||||
processNavigationForwardEvent = () => {
|
||||
this.webviewRef.current.goForward();
|
||||
};
|
||||
|
||||
processNavigationReloadEvent = () => {
|
||||
this.webviewRef.current.reload();
|
||||
};
|
||||
|
||||
processScrollEvent = message => {
|
||||
if (
|
||||
this.state.isUnplugged ||
|
||||
message.sourceDeviceId === this.props.device.id
|
||||
) {
|
||||
return;
|
||||
componentWillUnmount() {
|
||||
this.subscriptions.forEach(pubsub.unsubscribe);
|
||||
}
|
||||
this.webviewRef.current.send('scrollMessage', message.position);
|
||||
};
|
||||
|
||||
processClickEvent = message => {
|
||||
if (
|
||||
this.state.isUnplugged ||
|
||||
message.sourceDeviceId === this.props.device.id
|
||||
) {
|
||||
return;
|
||||
}
|
||||
this.webviewRef.current.send('clickMessage', message);
|
||||
};
|
||||
initDeviceEmulationParams = () => {
|
||||
try {
|
||||
return;
|
||||
this.webviewRef.current.getWebContents().enableDeviceEmulation({
|
||||
screenPosition: this.isMobile ? 'mobile' : 'desktop',
|
||||
screenSize: {
|
||||
width: this.props.device.width,
|
||||
height: this.props.device.height,
|
||||
},
|
||||
deviceScaleFactor: this.props.device.dpr,
|
||||
});
|
||||
} catch (err) {
|
||||
console.log('err', err);
|
||||
}
|
||||
};
|
||||
|
||||
processScrollDownEvent = message => {
|
||||
if (this.state.isUnplugged) {
|
||||
return;
|
||||
}
|
||||
console.log('processScrollDownEvent', this.webviewRef);
|
||||
this.webviewRef.current.send('scrollDownMessage');
|
||||
};
|
||||
processNavigationBackEvent = () => {
|
||||
this.webviewRef.current.goBack();
|
||||
};
|
||||
|
||||
processScrollUpEvent = message => {
|
||||
if (this.state.isUnplugged) {
|
||||
return;
|
||||
}
|
||||
this.webviewRef.current.send('scrollUpMessage');
|
||||
};
|
||||
processNavigationForwardEvent = () => {
|
||||
this.webviewRef.current.goForward();
|
||||
};
|
||||
|
||||
processScreenshotEvent = async ({now}) => {
|
||||
this.setState({screenshotInProgress: true});
|
||||
await captureFullPage(
|
||||
this.props.browser.address,
|
||||
this.props.device,
|
||||
this.webviewRef.current,
|
||||
now != null,
|
||||
now
|
||||
);
|
||||
this.setState({screenshotInProgress: false});
|
||||
};
|
||||
processNavigationReloadEvent = () => {
|
||||
this.webviewRef.current.reload();
|
||||
};
|
||||
|
||||
processFlipOrientationEvent = () => {
|
||||
if (!this.isMobile) {
|
||||
return;
|
||||
}
|
||||
this._flipOrientation();
|
||||
};
|
||||
processScrollEvent = message => {
|
||||
if (
|
||||
this.state.isUnplugged ||
|
||||
message.sourceDeviceId === this.props.device.id
|
||||
) {
|
||||
return;
|
||||
}
|
||||
this.webviewRef.current.send('scrollMessage', message.position);
|
||||
};
|
||||
|
||||
processOpenDevToolsInspectorEvent = message => {
|
||||
const {
|
||||
x: webViewX,
|
||||
y: webViewY,
|
||||
} = this.webviewRef.current.getBoundingClientRect();
|
||||
const {x: deviceX, y: deviceY} = message;
|
||||
const zoomFactor = this.props.browser.zoomLevel;
|
||||
this.webviewRef.current
|
||||
.getWebContents()
|
||||
.inspectElement(
|
||||
Math.round(webViewX + deviceX * zoomFactor),
|
||||
Math.round(webViewY + deviceY * zoomFactor)
|
||||
);
|
||||
};
|
||||
processClickEvent = message => {
|
||||
if (
|
||||
this.state.isUnplugged ||
|
||||
message.sourceDeviceId === this.props.device.id
|
||||
) {
|
||||
return;
|
||||
}
|
||||
this.webviewRef.current.send('clickMessage', message);
|
||||
};
|
||||
|
||||
processEnableInspectorEvent = () => {
|
||||
this.webviewRef.current.send('enableInspectorMessage');
|
||||
};
|
||||
processScrollDownEvent = message => {
|
||||
if (this.state.isUnplugged) {
|
||||
return;
|
||||
}
|
||||
console.log('processScrollDownEvent', this.webviewRef);
|
||||
this.webviewRef.current.send('scrollDownMessage');
|
||||
};
|
||||
|
||||
processDisableInspectorEvent = message => {
|
||||
if (message.sourceDeviceId === this.props.device.id) {
|
||||
return;
|
||||
}
|
||||
this.webviewRef.current.send('disableInspectorMessage');
|
||||
};
|
||||
processScrollUpEvent = message => {
|
||||
if (this.state.isUnplugged) {
|
||||
return;
|
||||
}
|
||||
this.webviewRef.current.send('scrollUpMessage');
|
||||
};
|
||||
|
||||
messageHandler = ({channel: type, args: [message]}) => {
|
||||
if (type !== MESSAGE_TYPES.toggleEventMirroring && this.state.isUnplugged) {
|
||||
return;
|
||||
}
|
||||
switch (type) {
|
||||
case MESSAGE_TYPES.scroll:
|
||||
pubsub.publish('scroll', [message]);
|
||||
return;
|
||||
case MESSAGE_TYPES.click:
|
||||
pubsub.publish('click', [message]);
|
||||
return;
|
||||
case MESSAGE_TYPES.openDevToolsInspector:
|
||||
this.processOpenDevToolsInspectorEvent(message);
|
||||
return;
|
||||
case MESSAGE_TYPES.disableInspector:
|
||||
this.transmitDisableInspectorToAllDevices(message);
|
||||
return;
|
||||
case MESSAGE_TYPES.openConsole:
|
||||
this._toggleDevTools();
|
||||
return;
|
||||
case MESSAGE_TYPES.tiltDevice:
|
||||
processScreenshotEvent = async ({now}) => {
|
||||
this.setState({screenshotInProgress: true});
|
||||
await captureFullPage(
|
||||
this.props.browser.address,
|
||||
this.props.device,
|
||||
this.webviewRef.current,
|
||||
now != null,
|
||||
now
|
||||
);
|
||||
this.setState({screenshotInProgress: false});
|
||||
};
|
||||
|
||||
processFlipOrientationEvent = () => {
|
||||
if (!this.isMobile) {
|
||||
return;
|
||||
}
|
||||
this._flipOrientation();
|
||||
return;
|
||||
case MESSAGE_TYPES.takeScreenshot:
|
||||
this.processScreenshotEvent({});
|
||||
return;
|
||||
case MESSAGE_TYPES.toggleEventMirroring:
|
||||
this._unPlug();
|
||||
return;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
transmitDisableInspectorToAllDevices = message => {
|
||||
pubsub.publish(DISABLE_INSPECTOR_ALL_DEVICES, [message]);
|
||||
};
|
||||
processOpenDevToolsInspectorEvent = message => {
|
||||
const {
|
||||
x: webViewX,
|
||||
y: webViewY,
|
||||
} = this.webviewRef.current.getBoundingClientRect();
|
||||
const {x: deviceX, y: deviceY} = message;
|
||||
const zoomFactor = this.props.browser.zoomLevel;
|
||||
this.webviewRef.current
|
||||
.getWebContents()
|
||||
.inspectElement(
|
||||
Math.round(webViewX + deviceX * zoomFactor),
|
||||
Math.round(webViewY + deviceY * zoomFactor)
|
||||
);
|
||||
};
|
||||
|
||||
initEventTriggers = webview => {
|
||||
webview.getWebContents().executeJavaScript(`
|
||||
processEnableInspectorEvent = () => {
|
||||
this.webviewRef.current.send('enableInspectorMessage');
|
||||
};
|
||||
|
||||
processDisableInspectorEvent = message => {
|
||||
if (message.sourceDeviceId === this.props.device.id) {
|
||||
return;
|
||||
}
|
||||
this.webviewRef.current.send('disableInspectorMessage');
|
||||
};
|
||||
|
||||
messageHandler = ({channel: type, args: [message]}) => {
|
||||
if (
|
||||
type !== MESSAGE_TYPES.toggleEventMirroring &&
|
||||
this.state.isUnplugged
|
||||
) {
|
||||
return;
|
||||
}
|
||||
switch (type) {
|
||||
case MESSAGE_TYPES.scroll:
|
||||
pubsub.publish('scroll', [message]);
|
||||
return;
|
||||
case MESSAGE_TYPES.click:
|
||||
pubsub.publish('click', [message]);
|
||||
return;
|
||||
case MESSAGE_TYPES.openDevToolsInspector:
|
||||
this.processOpenDevToolsInspectorEvent(message);
|
||||
return;
|
||||
case MESSAGE_TYPES.disableInspector:
|
||||
this.transmitDisableInspectorToAllDevices(message);
|
||||
return;
|
||||
case MESSAGE_TYPES.openConsole:
|
||||
this._toggleDevTools();
|
||||
return;
|
||||
case MESSAGE_TYPES.tiltDevice:
|
||||
this._flipOrientation();
|
||||
return;
|
||||
case MESSAGE_TYPES.takeScreenshot:
|
||||
this.processScreenshotEvent({});
|
||||
return;
|
||||
case MESSAGE_TYPES.toggleEventMirroring:
|
||||
this._unPlug();
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
transmitDisableInspectorToAllDevices = message => {
|
||||
pubsub.publish(DISABLE_INSPECTOR_ALL_DEVICES, [message]);
|
||||
};
|
||||
|
||||
initEventTriggers = webview => {
|
||||
webview.getWebContents().executeJavaScript(`
|
||||
responsivelyApp.deviceId = ${this.props.device.id};
|
||||
document.body.addEventListener('mouseleave', () => {
|
||||
window.responsivelyApp.mouseOn = false;
|
||||
|
@ -369,10 +386,10 @@ class WebView extends Component {
|
|||
true
|
||||
);
|
||||
`);
|
||||
};
|
||||
};
|
||||
|
||||
_toggleDevTools = () => {
|
||||
/*const devtools = new BrowserWindow({
|
||||
_toggleDevTools = () => {
|
||||
/*const devtools = new BrowserWindow({
|
||||
fullscreen: false,
|
||||
acceptFirstMouse: true,
|
||||
show: true,
|
||||
|
@ -383,127 +400,140 @@ class WebView extends Component {
|
|||
.getWebContents()
|
||||
.setDevToolsWebContents(devtools.webContents);
|
||||
this.webviewRef.current.getWebContents().openDevTools({mode: 'detach'});*/
|
||||
this.webviewRef.current.getWebContents().toggleDevTools();
|
||||
};
|
||||
|
||||
_flipOrientation = () => {
|
||||
this.setState({isTilted: !this.state.isTilted});
|
||||
};
|
||||
|
||||
_unPlug = () => {
|
||||
this.setState({isUnplugged: !this.state.isUnplugged}, () => {
|
||||
this.webviewRef.current.send(
|
||||
'eventsMirroringState',
|
||||
!this.state.isUnplugged
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
get isMobile() {
|
||||
return this.props.device.capabilities.indexOf(CAPABILITIES.mobile) > -1;
|
||||
}
|
||||
|
||||
render() {
|
||||
const {device, browser} = this.props;
|
||||
const deviceStyles = {
|
||||
width:
|
||||
this.isMobile && this.state.isTilted ? device.height : device.width,
|
||||
height:
|
||||
this.isMobile && this.state.isTilted ? device.width : device.height,
|
||||
transform: `scale(${browser.zoomLevel})`,
|
||||
this.webviewRef.current.getWebContents().toggleDevTools();
|
||||
};
|
||||
return (
|
||||
<div
|
||||
className={cx(styles.webViewContainer)}
|
||||
style={{height: deviceStyles.height * browser.zoomLevel + 40}} //Hack, ref below TODO
|
||||
>
|
||||
<div className={cx(styles.webViewToolbar)}>
|
||||
<Tooltip title="Open DevTools">
|
||||
|
||||
_flipOrientation = () => {
|
||||
this.setState({isTilted: !this.state.isTilted});
|
||||
};
|
||||
|
||||
_unPlug = () => {
|
||||
this.setState({isUnplugged: !this.state.isUnplugged}, () => {
|
||||
this.webviewRef.current.send(
|
||||
'eventsMirroringState',
|
||||
!this.state.isUnplugged
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
get isMobile() {
|
||||
return this.props.device.capabilities.indexOf(CAPABILITIES.mobile) > -1;
|
||||
}
|
||||
|
||||
render() {
|
||||
const {device, browser} = this.props;
|
||||
const deviceStyles = {
|
||||
width:
|
||||
this.isMobile && this.state.isTilted
|
||||
? device.height
|
||||
: device.width,
|
||||
height:
|
||||
this.isMobile && this.state.isTilted
|
||||
? device.width
|
||||
: device.height,
|
||||
transform: `scale(${browser.zoomLevel})`,
|
||||
};
|
||||
return (
|
||||
<div
|
||||
className={cx(
|
||||
styles.webViewToolbarIcons,
|
||||
commonStyles.icons,
|
||||
commonStyles.enabled
|
||||
)}
|
||||
onClick={this._toggleDevTools}
|
||||
className={cx(styles.webViewContainer)}
|
||||
style={{height: deviceStyles.height * browser.zoomLevel + 40}} //Hack, ref below TODO
|
||||
>
|
||||
<BugIcon width={20} color={iconsColor} />
|
||||
<div className={cx(styles.webViewToolbar)}>
|
||||
<Tooltip title="Open DevTools">
|
||||
<div
|
||||
className={cx(
|
||||
styles.webViewToolbarIcons,
|
||||
commonStyles.icons,
|
||||
commonStyles.enabled
|
||||
)}
|
||||
onClick={this._toggleDevTools}
|
||||
>
|
||||
<BugIcon width={20} color={iconsColor} />
|
||||
</div>
|
||||
</Tooltip>
|
||||
<Tooltip title="Take Screenshot">
|
||||
<div
|
||||
className={cx(
|
||||
styles.webViewToolbarIcons,
|
||||
commonStyles.icons,
|
||||
commonStyles.enabled
|
||||
)}
|
||||
onClick={() => this.processScreenshotEvent({})}
|
||||
>
|
||||
<ScreenshotIcon height={18} color={iconsColor} />
|
||||
</div>
|
||||
</Tooltip>
|
||||
<Tooltip title="Tilt Device">
|
||||
<div
|
||||
className={cx(
|
||||
styles.webViewToolbarIcons,
|
||||
commonStyles.icons,
|
||||
{
|
||||
[commonStyles.enabled]: this.isMobile,
|
||||
[commonStyles.disabled]: !this.isMobile,
|
||||
[commonStyles.selected]: this.state
|
||||
.isTilted,
|
||||
}
|
||||
)}
|
||||
onClick={this._flipOrientation}
|
||||
>
|
||||
<DeviceRotateIcon height={17} color={iconsColor} />
|
||||
</div>
|
||||
</Tooltip>
|
||||
<Tooltip title="Disable event mirroring">
|
||||
<div
|
||||
className={cx(
|
||||
styles.webViewToolbarIcons,
|
||||
commonStyles.icons,
|
||||
commonStyles.enabled,
|
||||
{
|
||||
[commonStyles.selected]: this.state
|
||||
.isUnplugged,
|
||||
}
|
||||
)}
|
||||
onClick={this._unPlug}
|
||||
>
|
||||
<UnplugIcon height={30} color={iconsColor} />
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div
|
||||
className={cx(styles.deviceContainer)}
|
||||
style={{
|
||||
width: deviceStyles.width * browser.zoomLevel,
|
||||
height: deviceStyles.height * browser.zoomLevel, //TODO why is this height not getting set?
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className={cx(styles.deviceOverlay, {
|
||||
[styles.overlayEnabled]: this.state
|
||||
.screenshotInProgress,
|
||||
})}
|
||||
style={deviceStyles}
|
||||
/>
|
||||
<div
|
||||
className={cx(styles.deviceOverlay, {
|
||||
[styles.overlayEnabled]: this.state.errorCode,
|
||||
})}
|
||||
style={deviceStyles}
|
||||
>
|
||||
<p>ERROR: {this.state.errorCode}</p>
|
||||
<p className={cx(styles.errorDesc)}>
|
||||
{this.state.errorDesc}
|
||||
</p>
|
||||
</div>
|
||||
<webview
|
||||
ref={this.webviewRef}
|
||||
preload="./preload.js"
|
||||
className={cx(styles.device)}
|
||||
src={browser.address || 'about:blank'}
|
||||
useragent={device.useragent}
|
||||
style={deviceStyles}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Tooltip>
|
||||
<Tooltip title="Take Screenshot">
|
||||
<div
|
||||
className={cx(
|
||||
styles.webViewToolbarIcons,
|
||||
commonStyles.icons,
|
||||
commonStyles.enabled
|
||||
)}
|
||||
onClick={() => this.processScreenshotEvent({})}
|
||||
>
|
||||
<ScreenshotIcon height={18} color={iconsColor} />
|
||||
</div>
|
||||
</Tooltip>
|
||||
<Tooltip title="Tilt Device">
|
||||
<div
|
||||
className={cx(styles.webViewToolbarIcons, commonStyles.icons, {
|
||||
[commonStyles.enabled]: this.isMobile,
|
||||
[commonStyles.disabled]: !this.isMobile,
|
||||
[commonStyles.selected]: this.state.isTilted,
|
||||
})}
|
||||
onClick={this._flipOrientation}
|
||||
>
|
||||
<DeviceRotateIcon height={17} color={iconsColor} />
|
||||
</div>
|
||||
</Tooltip>
|
||||
<Tooltip title="Disable event mirroring">
|
||||
<div
|
||||
className={cx(
|
||||
styles.webViewToolbarIcons,
|
||||
commonStyles.icons,
|
||||
commonStyles.enabled,
|
||||
{
|
||||
[commonStyles.selected]: this.state.isUnplugged,
|
||||
}
|
||||
)}
|
||||
onClick={this._unPlug}
|
||||
>
|
||||
<UnplugIcon height={30} color={iconsColor} />
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div
|
||||
className={cx(styles.deviceContainer)}
|
||||
style={{
|
||||
width: deviceStyles.width * browser.zoomLevel,
|
||||
height: deviceStyles.height * browser.zoomLevel, //TODO why is this height not getting set?
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className={cx(styles.deviceOverlay, {
|
||||
[styles.overlayEnabled]: this.state.screenshotInProgress,
|
||||
})}
|
||||
style={deviceStyles}
|
||||
/>
|
||||
<div
|
||||
className={cx(styles.deviceOverlay, {
|
||||
[styles.overlayEnabled]: this.state.errorCode,
|
||||
})}
|
||||
style={deviceStyles}
|
||||
>
|
||||
<p>ERROR: {this.state.errorCode}</p>
|
||||
<p className={cx(styles.errorDesc)}>{this.state.errorDesc}</p>
|
||||
</div>
|
||||
<webview
|
||||
ref={this.webviewRef}
|
||||
preload="./preload.js"
|
||||
className={cx(styles.device)}
|
||||
src={browser.address || 'about:blank'}
|
||||
useragent={device.useragent}
|
||||
style={deviceStyles}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default WebView;
|
||||
|
|
|
@ -7,35 +7,47 @@ import Renderer from './';
|
|||
|
||||
const testSrc = 'https://testUrl.com';
|
||||
const testDevice1 = {
|
||||
name: 'testDevice1',
|
||||
width: 100,
|
||||
height: 100,
|
||||
name: 'testDevice1',
|
||||
width: 100,
|
||||
height: 100,
|
||||
};
|
||||
|
||||
describe('<Renderer />', () => {
|
||||
it('Renders the header and the iframe', () => {
|
||||
const wrapper = shallow(<Renderer src={testSrc} device={testDevice1} />);
|
||||
expect(wrapper.find('iframe')).to.have.lengthOf(1);
|
||||
expect(wrapper.find('h2')).to.have.lengthOf(1);
|
||||
});
|
||||
it('Renders the header and the iframe', () => {
|
||||
const wrapper = shallow(
|
||||
<Renderer src={testSrc} device={testDevice1} />
|
||||
);
|
||||
expect(wrapper.find('iframe')).to.have.lengthOf(1);
|
||||
expect(wrapper.find('h2')).to.have.lengthOf(1);
|
||||
});
|
||||
|
||||
it('Renders the header with the device name', () => {
|
||||
const wrapper = shallow(<Renderer src={testSrc} device={testDevice1} />);
|
||||
expect(wrapper.find('h2').text()).to.equal(testDevice1.name);
|
||||
});
|
||||
it('Renders the header with the device name', () => {
|
||||
const wrapper = shallow(
|
||||
<Renderer src={testSrc} device={testDevice1} />
|
||||
);
|
||||
expect(wrapper.find('h2').text()).to.equal(testDevice1.name);
|
||||
});
|
||||
|
||||
it('Renders the iframe with the given device dimensions', () => {
|
||||
const wrapper = shallow(<Renderer src={testSrc} device={testDevice1} />);
|
||||
expect(wrapper.find('iframe').prop('width')).to.equal(testDevice1.width);
|
||||
expect(wrapper.find('iframe').prop('height')).to.equal(testDevice1.height);
|
||||
});
|
||||
it('Renders the iframe with the given device dimensions', () => {
|
||||
const wrapper = shallow(
|
||||
<Renderer src={testSrc} device={testDevice1} />
|
||||
);
|
||||
expect(wrapper.find('iframe').prop('width')).to.equal(
|
||||
testDevice1.width
|
||||
);
|
||||
expect(wrapper.find('iframe').prop('height')).to.equal(
|
||||
testDevice1.height
|
||||
);
|
||||
});
|
||||
|
||||
it('Renders the iframe with the given url', () => {
|
||||
const wrapper = shallow(<Renderer src={testSrc} device={testDevice1} />);
|
||||
expect(wrapper.find('iframe').prop('src')).to.equal(testSrc);
|
||||
});
|
||||
it('Renders the iframe with the given url', () => {
|
||||
const wrapper = shallow(
|
||||
<Renderer src={testSrc} device={testDevice1} />
|
||||
);
|
||||
expect(wrapper.find('iframe').prop('src')).to.equal(testSrc);
|
||||
});
|
||||
|
||||
/*it('Calls the callback with a number value', () => {
|
||||
/*it('Calls the callback with a number value', () => {
|
||||
const onChange = sinon.spy();
|
||||
const wrapper = mount(<BrowserZoom onChange={onChange} />);
|
||||
wrapper.find('.MuiSlider-thumb').simulate('mousedown');
|
||||
|
|
|
@ -14,23 +14,23 @@ import PromiseWorker from 'promise-worker';
|
|||
const mergeImg = Promise.promisifyAll(_mergeImg);
|
||||
|
||||
export const captureFullPage = async (
|
||||
address,
|
||||
device,
|
||||
webView,
|
||||
createSeparateDir,
|
||||
now
|
||||
address,
|
||||
device,
|
||||
webView,
|
||||
createSeparateDir,
|
||||
now
|
||||
) => {
|
||||
const worker = new Worker('./imageWorker.js');
|
||||
const promiseWorker = new PromiseWorker(worker);
|
||||
const toastId = toast.info(
|
||||
<NotificationMessage
|
||||
spinner={true}
|
||||
message={`Capturing ${device.name} screenshot...`}
|
||||
/>,
|
||||
{autoClose: false}
|
||||
);
|
||||
//Hiding scrollbars in the screenshot
|
||||
await webView.insertCSS(`
|
||||
const worker = new Worker('./imageWorker.js');
|
||||
const promiseWorker = new PromiseWorker(worker);
|
||||
const toastId = toast.info(
|
||||
<NotificationMessage
|
||||
spinner={true}
|
||||
message={`Capturing ${device.name} screenshot...`}
|
||||
/>,
|
||||
{autoClose: false}
|
||||
);
|
||||
//Hiding scrollbars in the screenshot
|
||||
await webView.insertCSS(`
|
||||
.responsivelyApp__ScreenshotInProgress::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
@ -40,18 +40,18 @@ export const captureFullPage = async (
|
|||
}
|
||||
`);
|
||||
|
||||
//Get the windows's scroll details
|
||||
let scrollX = 0;
|
||||
let scrollY = 0;
|
||||
let pageX = 0;
|
||||
let pageY = 0;
|
||||
const {
|
||||
previousScrollPosition,
|
||||
scrollHeight,
|
||||
viewPortHeight,
|
||||
scrollWidth,
|
||||
viewPortWidth,
|
||||
} = await webView.executeJavaScript(`
|
||||
//Get the windows's scroll details
|
||||
let scrollX = 0;
|
||||
let scrollY = 0;
|
||||
let pageX = 0;
|
||||
let pageY = 0;
|
||||
const {
|
||||
previousScrollPosition,
|
||||
scrollHeight,
|
||||
viewPortHeight,
|
||||
scrollWidth,
|
||||
viewPortWidth,
|
||||
} = await webView.executeJavaScript(`
|
||||
document.body.classList.add('responsivelyApp__ScreenshotInProgress');
|
||||
responsivelyApp.screenshotVar = {
|
||||
previousScrollPosition : {
|
||||
|
@ -66,137 +66,137 @@ export const captureFullPage = async (
|
|||
responsivelyApp.screenshotVar;
|
||||
`);
|
||||
|
||||
let images = [];
|
||||
let images = [];
|
||||
|
||||
for (
|
||||
let pageY = 0;
|
||||
scrollY < scrollHeight;
|
||||
pageY++, scrollY = viewPortHeight * pageY
|
||||
) {
|
||||
scrollX = 0;
|
||||
const columnImages = [];
|
||||
for (
|
||||
let pageX = 0;
|
||||
scrollX < scrollWidth;
|
||||
pageX++, scrollX = viewPortWidth * pageX
|
||||
let pageY = 0;
|
||||
scrollY < scrollHeight;
|
||||
pageY++, scrollY = viewPortHeight * pageY
|
||||
) {
|
||||
await webView.executeJavaScript(`
|
||||
scrollX = 0;
|
||||
const columnImages = [];
|
||||
for (
|
||||
let pageX = 0;
|
||||
scrollX < scrollWidth;
|
||||
pageX++, scrollX = viewPortWidth * pageX
|
||||
) {
|
||||
await webView.executeJavaScript(`
|
||||
window.scrollTo(${scrollX}, ${scrollY})
|
||||
responsivelyApp.hideFixedPositionElementsForScreenshot();
|
||||
`);
|
||||
await _delay(200);
|
||||
const options = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: viewPortWidth,
|
||||
height: viewPortHeight,
|
||||
};
|
||||
if (scrollX + viewPortWidth > scrollWidth) {
|
||||
options.width = scrollWidth - scrollX;
|
||||
options.x = viewPortWidth - options.width;
|
||||
}
|
||||
if (scrollY + viewPortHeight > scrollHeight) {
|
||||
options.height = scrollHeight - scrollY;
|
||||
options.y = viewPortHeight - options.height;
|
||||
}
|
||||
const image = await _takeSnapshot(webView, options);
|
||||
columnImages.push(image);
|
||||
await _delay(200);
|
||||
const options = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: viewPortWidth,
|
||||
height: viewPortHeight,
|
||||
};
|
||||
if (scrollX + viewPortWidth > scrollWidth) {
|
||||
options.width = scrollWidth - scrollX;
|
||||
options.x = viewPortWidth - options.width;
|
||||
}
|
||||
if (scrollY + viewPortHeight > scrollHeight) {
|
||||
options.height = scrollHeight - scrollY;
|
||||
options.y = viewPortHeight - options.height;
|
||||
}
|
||||
const image = await _takeSnapshot(webView, options);
|
||||
columnImages.push(image);
|
||||
}
|
||||
const pngs = columnImages.map(img => img.toPNG());
|
||||
images.push(
|
||||
await promiseWorker.postMessage(
|
||||
{
|
||||
images: pngs,
|
||||
direction: 'horizontal',
|
||||
},
|
||||
[...pngs]
|
||||
)
|
||||
);
|
||||
}
|
||||
const pngs = columnImages.map(img => img.toPNG());
|
||||
images.push(
|
||||
await promiseWorker.postMessage(
|
||||
{
|
||||
images: pngs,
|
||||
direction: 'horizontal',
|
||||
},
|
||||
[...pngs]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
webView.executeJavaScript(`
|
||||
webView.executeJavaScript(`
|
||||
window.scrollTo(${JSON.stringify(previousScrollPosition)});
|
||||
document.body.classList.remove('responsivelyApp__ScreenshotInProgress');
|
||||
responsivelyApp.unHideElementsHiddenForScreenshot();
|
||||
`);
|
||||
|
||||
toast.update(toastId, {
|
||||
render: (
|
||||
<NotificationMessage
|
||||
spinner={true}
|
||||
message={`Processing ${device.name} screenshot...`}
|
||||
/>
|
||||
),
|
||||
type: toast.TYPE.INFO,
|
||||
});
|
||||
const resultFilename = _getScreenshotFileName(
|
||||
address,
|
||||
device,
|
||||
now,
|
||||
createSeparateDir
|
||||
);
|
||||
const mergedImage = await promiseWorker.postMessage({
|
||||
images,
|
||||
direction: 'vertical',
|
||||
resultFilename,
|
||||
});
|
||||
toast.update(toastId, {
|
||||
render: (
|
||||
<NotificationMessage
|
||||
tick={true}
|
||||
message={`${device.name} screenshot taken!`}
|
||||
/>
|
||||
),
|
||||
type: toast.TYPE.INFO,
|
||||
autoClose: 2000,
|
||||
});
|
||||
await _delay(250);
|
||||
shell.showItemInFolder(path.join(resultFilename.dir, resultFilename.file));
|
||||
toast.update(toastId, {
|
||||
render: (
|
||||
<NotificationMessage
|
||||
spinner={true}
|
||||
message={`Processing ${device.name} screenshot...`}
|
||||
/>
|
||||
),
|
||||
type: toast.TYPE.INFO,
|
||||
});
|
||||
const resultFilename = _getScreenshotFileName(
|
||||
address,
|
||||
device,
|
||||
now,
|
||||
createSeparateDir
|
||||
);
|
||||
const mergedImage = await promiseWorker.postMessage({
|
||||
images,
|
||||
direction: 'vertical',
|
||||
resultFilename,
|
||||
});
|
||||
toast.update(toastId, {
|
||||
render: (
|
||||
<NotificationMessage
|
||||
tick={true}
|
||||
message={`${device.name} screenshot taken!`}
|
||||
/>
|
||||
),
|
||||
type: toast.TYPE.INFO,
|
||||
autoClose: 2000,
|
||||
});
|
||||
await _delay(250);
|
||||
shell.showItemInFolder(path.join(resultFilename.dir, resultFilename.file));
|
||||
};
|
||||
|
||||
const _delay = ms =>
|
||||
new Promise((resolve, reject) => {
|
||||
setTimeout(() => resolve(), ms);
|
||||
});
|
||||
new Promise((resolve, reject) => {
|
||||
setTimeout(() => resolve(), ms);
|
||||
});
|
||||
|
||||
const _takeSnapshot = (webView, options) => {
|
||||
return webView.getWebContents().capturePage(options);
|
||||
return webView.getWebContents().capturePage(options);
|
||||
};
|
||||
|
||||
function _getScreenshotFileName(
|
||||
address,
|
||||
device,
|
||||
now = new Date(),
|
||||
createSeparateDir
|
||||
address,
|
||||
device,
|
||||
now = new Date(),
|
||||
createSeparateDir
|
||||
) {
|
||||
const dateString = `${now
|
||||
.toLocaleDateString()
|
||||
.split('/')
|
||||
.reverse()
|
||||
.join('-')} at ${now
|
||||
.toLocaleTimeString([], {hour12: true})
|
||||
.replace(/\:/g, '.')
|
||||
.toUpperCase()}`;
|
||||
const directoryPath = createSeparateDir ? `${dateString}/` : '';
|
||||
return {
|
||||
dir: path.join(
|
||||
os.homedir(),
|
||||
`Desktop/Responsively-Screenshots`,
|
||||
directoryPath
|
||||
),
|
||||
file: `${_getWebsiteName(address)} - ${device.name.replace(
|
||||
/\//g,
|
||||
'-'
|
||||
)} - ${dateString}.png`,
|
||||
};
|
||||
const dateString = `${now
|
||||
.toLocaleDateString()
|
||||
.split('/')
|
||||
.reverse()
|
||||
.join('-')} at ${now
|
||||
.toLocaleTimeString([], {hour12: true})
|
||||
.replace(/\:/g, '.')
|
||||
.toUpperCase()}`;
|
||||
const directoryPath = createSeparateDir ? `${dateString}/` : '';
|
||||
return {
|
||||
dir: path.join(
|
||||
os.homedir(),
|
||||
`Desktop/Responsively-Screenshots`,
|
||||
directoryPath
|
||||
),
|
||||
file: `${_getWebsiteName(address)} - ${device.name.replace(
|
||||
/\//g,
|
||||
'-'
|
||||
)} - ${dateString}.png`,
|
||||
};
|
||||
}
|
||||
|
||||
const _getWebsiteName = address => {
|
||||
let domain = new URL(address).hostname;
|
||||
domain = domain.replace('www.', '');
|
||||
const dotIndex = domain.indexOf('.');
|
||||
if (dotIndex > -1) {
|
||||
domain = domain.substr(0, domain.indexOf('.'));
|
||||
}
|
||||
return domain.charAt(0).toUpperCase() + domain.slice(1);
|
||||
let domain = new URL(address).hostname;
|
||||
domain = domain.replace('www.', '');
|
||||
const dotIndex = domain.indexOf('.');
|
||||
if (dotIndex > -1) {
|
||||
domain = domain.substr(0, domain.indexOf('.'));
|
||||
}
|
||||
return domain.charAt(0).toUpperCase() + domain.slice(1);
|
||||
};
|
||||
|
|
|
@ -18,72 +18,72 @@ import {iconsColor} from '../../constants/colors';
|
|||
import {Tooltip} from '@material-ui/core';
|
||||
|
||||
const marks = [
|
||||
{
|
||||
value: 25,
|
||||
label: '25%',
|
||||
},
|
||||
{
|
||||
value: 50,
|
||||
label: '50%',
|
||||
},
|
||||
{
|
||||
value: 100,
|
||||
label: '100%',
|
||||
},
|
||||
{
|
||||
value: 200,
|
||||
label: '200%',
|
||||
},
|
||||
{
|
||||
value: 25,
|
||||
label: '25%',
|
||||
},
|
||||
{
|
||||
value: 50,
|
||||
label: '50%',
|
||||
},
|
||||
{
|
||||
value: 100,
|
||||
label: '100%',
|
||||
},
|
||||
{
|
||||
value: 200,
|
||||
label: '200%',
|
||||
},
|
||||
];
|
||||
|
||||
export default function BrowserZoom(props) {
|
||||
const [showExpanded, setShowExpanded] = useState(false);
|
||||
const zoomRef = useRef();
|
||||
const handleClickOutside = event => {
|
||||
if (!showExpanded) {
|
||||
return;
|
||||
}
|
||||
if (zoomRef.current && !zoomRef.current.contains(event.target)) {
|
||||
setShowExpanded(false);
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
// Bind the event listener
|
||||
document.addEventListener('mousedown', handleClickOutside);
|
||||
return () => {
|
||||
// Unbind the event listener on clean up
|
||||
document.removeEventListener('mousedown', handleClickOutside);
|
||||
const [showExpanded, setShowExpanded] = useState(false);
|
||||
const zoomRef = useRef();
|
||||
const handleClickOutside = event => {
|
||||
if (!showExpanded) {
|
||||
return;
|
||||
}
|
||||
if (zoomRef.current && !zoomRef.current.contains(event.target)) {
|
||||
setShowExpanded(false);
|
||||
}
|
||||
};
|
||||
});
|
||||
useEffect(() => {
|
||||
// Bind the event listener
|
||||
document.addEventListener('mousedown', handleClickOutside);
|
||||
return () => {
|
||||
// Unbind the event listener on clean up
|
||||
document.removeEventListener('mousedown', handleClickOutside);
|
||||
};
|
||||
});
|
||||
|
||||
const _zoomChange = (_, [action]) => {
|
||||
switch (action) {
|
||||
case 'zoomIn':
|
||||
return props.onZoomChange(props.browser.zoomLevel + 0.1);
|
||||
case 'zoomOut':
|
||||
return props.onZoomChange(props.browser.zoomLevel - 0.1);
|
||||
}
|
||||
};
|
||||
const _zoomChange = (_, [action]) => {
|
||||
switch (action) {
|
||||
case 'zoomIn':
|
||||
return props.onZoomChange(props.browser.zoomLevel + 0.1);
|
||||
case 'zoomOut':
|
||||
return props.onZoomChange(props.browser.zoomLevel - 0.1);
|
||||
}
|
||||
};
|
||||
|
||||
const value = Math.round(props.browser.zoomLevel * 100);
|
||||
const value = Math.round(props.browser.zoomLevel * 100);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={zoomRef}
|
||||
className={cx(
|
||||
commonStyles.icons,
|
||||
commonStyles.enabled,
|
||||
styles.zoomSlider,
|
||||
'MuiGrid-item',
|
||||
'MuiGrid-root'
|
||||
)}
|
||||
>
|
||||
<Tooltip title="Zoom In/Out">
|
||||
<div onClick={() => setShowExpanded(!showExpanded)}>
|
||||
<ZoomIcon width={25} color={iconsColor} />
|
||||
</div>
|
||||
</Tooltip>
|
||||
{/*<Grid container spacing={1}>
|
||||
return (
|
||||
<div
|
||||
ref={zoomRef}
|
||||
className={cx(
|
||||
commonStyles.icons,
|
||||
commonStyles.enabled,
|
||||
styles.zoomSlider,
|
||||
'MuiGrid-item',
|
||||
'MuiGrid-root'
|
||||
)}
|
||||
>
|
||||
<Tooltip title="Zoom In/Out">
|
||||
<div onClick={() => setShowExpanded(!showExpanded)}>
|
||||
<ZoomIcon width={25} color={iconsColor} />
|
||||
</div>
|
||||
</Tooltip>
|
||||
{/*<Grid container spacing={1}>
|
||||
<Grid item>
|
||||
<ZoomOutIcon />
|
||||
</Grid>
|
||||
|
@ -100,23 +100,35 @@ export default function BrowserZoom(props) {
|
|||
<ZoomInIcon />
|
||||
</Grid>
|
||||
</Grid>*/}
|
||||
<div
|
||||
className={cx(styles.zoomControls, {
|
||||
[commonStyles.hidden]: !showExpanded,
|
||||
})}
|
||||
>
|
||||
<ToggleButtonGroup value={[]} onChange={_zoomChange}>
|
||||
<ToggleButton value="zoomOut" disabled={value === 20} disableRipple>
|
||||
–
|
||||
</ToggleButton>
|
||||
<ToggleButton value="value" disabled className={styles.zoomValue}>
|
||||
{value}%
|
||||
</ToggleButton>
|
||||
<ToggleButton value="zoomIn" disabled={value === 200} disableRipple>
|
||||
+
|
||||
</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
<div
|
||||
className={cx(styles.zoomControls, {
|
||||
[commonStyles.hidden]: !showExpanded,
|
||||
})}
|
||||
>
|
||||
<ToggleButtonGroup value={[]} onChange={_zoomChange}>
|
||||
<ToggleButton
|
||||
value="zoomOut"
|
||||
disabled={value === 20}
|
||||
disableRipple
|
||||
>
|
||||
–
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
value="value"
|
||||
disabled
|
||||
className={styles.zoomValue}
|
||||
>
|
||||
{value}%
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
value="zoomIn"
|
||||
disabled={value === 200}
|
||||
disableRipple
|
||||
>
|
||||
+
|
||||
</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,20 +8,20 @@ import BrowserZoom from './';
|
|||
import Slider from '@material-ui/core/Slider';
|
||||
|
||||
describe('<BrowserZoom />', () => {
|
||||
it('Renders label and the slider component ', () => {
|
||||
const wrapper = shallow(<BrowserZoom />);
|
||||
expect(wrapper.find(Slider)).to.have.lengthOf(1);
|
||||
});
|
||||
it('Renders label and the slider component ', () => {
|
||||
const wrapper = shallow(<BrowserZoom />);
|
||||
expect(wrapper.find(Slider)).to.have.lengthOf(1);
|
||||
});
|
||||
|
||||
it('Calls the callback on slider change', () => {
|
||||
const onChange = sinon.spy();
|
||||
const wrapper = mount(<BrowserZoom onChange={onChange} />);
|
||||
wrapper.find('.MuiSlider-thumb').simulate('mousedown');
|
||||
wrapper.find('.MuiSlider-thumb').simulate('mouseup');
|
||||
expect(onChange).to.have.property('callCount', 1);
|
||||
});
|
||||
it('Calls the callback on slider change', () => {
|
||||
const onChange = sinon.spy();
|
||||
const wrapper = mount(<BrowserZoom onChange={onChange} />);
|
||||
wrapper.find('.MuiSlider-thumb').simulate('mousedown');
|
||||
wrapper.find('.MuiSlider-thumb').simulate('mouseup');
|
||||
expect(onChange).to.have.property('callCount', 1);
|
||||
});
|
||||
|
||||
/*it('Calls the callback with a number value', () => {
|
||||
/*it('Calls the callback with a number value', () => {
|
||||
const onChange = sinon.spy();
|
||||
const wrapper = mount(<BrowserZoom onChange={onChange} />);
|
||||
wrapper.find('.MuiSlider-thumb').simulate('mousedown');
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
import React, {Fragment} from 'react';
|
||||
|
||||
export default ({width, height, color, padding, margin}) => (
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
data-name="Layer 1"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="M14.94,5.19A4.38,4.38,0,0,0,16,2,4.44,4.44,0,0,0,13,3.52,4.17,4.17,0,0,0,12,6.61,3.69,3.69,0,0,0,14.94,5.19Zm2.52,7.44a4.51,4.51,0,0,1,2.16-3.81,4.66,4.66,0,0,0-3.66-2c-1.56-.16-3,.91-3.83.91s-2-.89-3.3-.87A4.92,4.92,0,0,0,4.69,9.39C2.93,12.45,4.24,17,6,19.47,6.8,20.68,7.8,22.05,9.12,22s1.75-.82,3.28-.82,2,.82,3.3.79,2.22-1.24,3.06-2.45a11,11,0,0,0,1.38-2.85A4.41,4.41,0,0,1,17.46,12.63Z" />
|
||||
</svg>
|
||||
</Fragment>
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
data-name="Layer 1"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="M14.94,5.19A4.38,4.38,0,0,0,16,2,4.44,4.44,0,0,0,13,3.52,4.17,4.17,0,0,0,12,6.61,3.69,3.69,0,0,0,14.94,5.19Zm2.52,7.44a4.51,4.51,0,0,1,2.16-3.81,4.66,4.66,0,0,0-3.66-2c-1.56-.16-3,.91-3.83.91s-2-.89-3.3-.87A4.92,4.92,0,0,0,4.69,9.39C2.93,12.45,4.24,17,6,19.47,6.8,20.68,7.8,22.05,9.12,22s1.75-.82,3.28-.82,2,.82,3.3.79,2.22-1.24,3.06-2.45a11,11,0,0,0,1.38-2.85A4.41,4.41,0,0,1,17.46,12.63Z" />
|
||||
</svg>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
import React, {Fragment} from 'react';
|
||||
|
||||
export default ({width, height, color, padding, margin}) => (
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
data-name="Layer 1"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="M17,11H9.41l3.3-3.29a1,1,0,1,0-1.42-1.42l-5,5a1,1,0,0,0-.21.33,1,1,0,0,0,0,.76,1,1,0,0,0,.21.33l5,5a1,1,0,0,0,1.42,0,1,1,0,0,0,0-1.42L9.41,13H17a1,1,0,0,0,0-2Z" />
|
||||
</svg>
|
||||
</Fragment>
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
data-name="Layer 1"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="M17,11H9.41l3.3-3.29a1,1,0,1,0-1.42-1.42l-5,5a1,1,0,0,0-.21.33,1,1,0,0,0,0,.76,1,1,0,0,0,.21.33l5,5a1,1,0,0,0,1.42,0,1,1,0,0,0,0-1.42L9.41,13H17a1,1,0,0,0,0-2Z" />
|
||||
</svg>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
import React, {Fragment} from 'react';
|
||||
|
||||
export default ({width, height, color, padding, margin}) => (
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
data-name="Layer 1"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="M17.92,11.62a1,1,0,0,0-.21-.33l-5-5a1,1,0,0,0-1.42,1.42L14.59,11H7a1,1,0,0,0,0,2h7.59l-3.3,3.29a1,1,0,0,0,0,1.42,1,1,0,0,0,1.42,0l5-5a1,1,0,0,0,.21-.33A1,1,0,0,0,17.92,11.62Z" />
|
||||
</svg>
|
||||
</Fragment>
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
data-name="Layer 1"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="M17.92,11.62a1,1,0,0,0-.21-.33l-5-5a1,1,0,0,0-1.42,1.42L14.59,11H7a1,1,0,0,0,0,2h7.59l-3.3,3.29a1,1,0,0,0,0,1.42,1,1,0,0,0,1.42,0l5-5a1,1,0,0,0,.21-.33A1,1,0,0,0,17.92,11.62Z" />
|
||||
</svg>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import React, {Fragment} from 'react';
|
||||
|
||||
export default ({width, height, color, padding, margin}) => (
|
||||
<Fragment>
|
||||
{/*<svg
|
||||
<Fragment>
|
||||
{/*<svg
|
||||
width={width}
|
||||
height={height}
|
||||
fill={color}
|
||||
|
@ -11,25 +11,25 @@ export default ({width, height, color, padding, margin}) => (
|
|||
>
|
||||
<path d="M9.71,6.29a1,1,0,0,0-1.42,0l-5,5a1,1,0,0,0,0,1.42l5,5a1,1,0,0,0,1.42,0,1,1,0,0,0,0-1.42L5.41,12l4.3-4.29A1,1,0,0,0,9.71,6.29Zm11,5-5-5a1,1,0,0,0-1.42,1.42L18.59,12l-4.3,4.29a1,1,0,0,0,0,1.42,1,1,0,0,0,1.42,0l5-5A1,1,0,0,0,20.71,11.29Z" />
|
||||
</svg>*/}
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
viewBox="0 0 100 100"
|
||||
x="0px"
|
||||
y="0px"
|
||||
>
|
||||
<g data-name="Group">
|
||||
<polygon
|
||||
data-name="Path"
|
||||
points="39.5 23.6 13.1 50 39.5 76.4 42.4 73.6 18.8 50 42.4 26.4 39.5 23.6"
|
||||
/>
|
||||
<polygon
|
||||
data-name="Path"
|
||||
points="60.5 76.4 86.9 50 60.5 23.6 57.6 26.4 81.2 50 57.6 73.6 60.5 76.4"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</Fragment>
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
viewBox="0 0 100 100"
|
||||
x="0px"
|
||||
y="0px"
|
||||
>
|
||||
<g data-name="Group">
|
||||
<polygon
|
||||
data-name="Path"
|
||||
points="39.5 23.6 13.1 50 39.5 76.4 42.4 73.6 18.8 50 42.4 26.4 39.5 23.6"
|
||||
/>
|
||||
<polygon
|
||||
data-name="Path"
|
||||
points="60.5 76.4 86.9 50 60.5 23.6 57.6 26.4 81.2 50 57.6 73.6 60.5 76.4"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
import React, {Fragment} from 'react';
|
||||
|
||||
export default ({width, height, color, padding, margin}) => (
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="M13.41,12l4.3-4.29a1,1,0,1,0-1.42-1.42L12,10.59,7.71,6.29A1,1,0,0,0,6.29,7.71L10.59,12l-4.3,4.29a1,1,0,0,0,0,1.42,1,1,0,0,0,1.42,0L12,13.41l4.29,4.3a1,1,0,0,0,1.42,0,1,1,0,0,0,0-1.42Z" />
|
||||
</svg>
|
||||
</Fragment>
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="M13.41,12l4.3-4.29a1,1,0,1,0-1.42-1.42L12,10.59,7.71,6.29A1,1,0,0,0,6.29,7.71L10.59,12l-4.3,4.29a1,1,0,0,0,0,1.42,1,1,0,0,0,1.42,0L12,13.41l4.29,4.3a1,1,0,0,0,1.42,0,1,1,0,0,0,0-1.42Z" />
|
||||
</svg>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import React, {Fragment} from 'react';
|
||||
|
||||
export default ({width, height, color, padding, margin}) => (
|
||||
<Fragment>
|
||||
{/*<svg
|
||||
<Fragment>
|
||||
{/*<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
|
@ -55,39 +55,39 @@ export default ({width, height, color, padding, margin}) => (
|
|||
<g />
|
||||
<g />
|
||||
</svg>*/}
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
data-name="Layer 1"
|
||||
viewBox="0 0 100 100"
|
||||
x="0px"
|
||||
y="0px"
|
||||
>
|
||||
<g data-name="Group">
|
||||
<path
|
||||
data-name="Compound Path"
|
||||
d="M8.8,62.2a7.2,7.2,0,0,0,2.1,5.2L32.7,89.1a7.3,7.3,0,0,0,10.3,0L89.1,43a7.3,7.3,0,0,0,0-10.3L67.3,10.9a7.3,7.3,0,0,0-10.3,0L10.9,57A7.2,7.2,0,0,0,8.8,62.2ZM48,78.4,21.6,52,54.9,18.7,81.3,45.1ZM64.5,13.7,86.3,35.5a3.3,3.3,0,0,1,0,4.7l-2.2,2.2L57.7,15.9l2.2-2.2A3.4,3.4,0,0,1,64.5,13.7ZM13.7,59.9l5.1-5.1L45.2,81.2l-5.1,5.1a3.4,3.4,0,0,1-4.7,0L13.7,64.5a3.3,3.3,0,0,1,0-4.7Z"
|
||||
/>
|
||||
<rect
|
||||
data-name="Path"
|
||||
x="26.4"
|
||||
y="69.2"
|
||||
width="4"
|
||||
height="4.88"
|
||||
transform="translate(-42.4 41.1) rotate(-45)"
|
||||
/>
|
||||
<path
|
||||
data-name="Path"
|
||||
d="M92.8,68.1A14.2,14.2,0,0,1,78.6,82.3H65.8l7.4-8.7-3-2.6L58.9,84.3,70.2,97.5l3-2.6-7.4-8.6H78.6A18.2,18.2,0,0,0,96.8,68.1Z"
|
||||
/>
|
||||
<path
|
||||
data-name="Path"
|
||||
d="M21.4,17.7H34.2l-7.4,8.7,3,2.6L41.1,15.7,29.8,2.5l-3,2.6,7.4,8.6H21.4A18.2,18.2,0,0,0,3.2,31.9h4A14.2,14.2,0,0,1,21.4,17.7Z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
data-name="Layer 1"
|
||||
viewBox="0 0 100 100"
|
||||
x="0px"
|
||||
y="0px"
|
||||
>
|
||||
<g data-name="Group">
|
||||
<path
|
||||
data-name="Compound Path"
|
||||
d="M8.8,62.2a7.2,7.2,0,0,0,2.1,5.2L32.7,89.1a7.3,7.3,0,0,0,10.3,0L89.1,43a7.3,7.3,0,0,0,0-10.3L67.3,10.9a7.3,7.3,0,0,0-10.3,0L10.9,57A7.2,7.2,0,0,0,8.8,62.2ZM48,78.4,21.6,52,54.9,18.7,81.3,45.1ZM64.5,13.7,86.3,35.5a3.3,3.3,0,0,1,0,4.7l-2.2,2.2L57.7,15.9l2.2-2.2A3.4,3.4,0,0,1,64.5,13.7ZM13.7,59.9l5.1-5.1L45.2,81.2l-5.1,5.1a3.4,3.4,0,0,1-4.7,0L13.7,64.5a3.3,3.3,0,0,1,0-4.7Z"
|
||||
/>
|
||||
<rect
|
||||
data-name="Path"
|
||||
x="26.4"
|
||||
y="69.2"
|
||||
width="4"
|
||||
height="4.88"
|
||||
transform="translate(-42.4 41.1) rotate(-45)"
|
||||
/>
|
||||
<path
|
||||
data-name="Path"
|
||||
d="M92.8,68.1A14.2,14.2,0,0,1,78.6,82.3H65.8l7.4-8.7-3-2.6L58.9,84.3,70.2,97.5l3-2.6-7.4-8.6H78.6A18.2,18.2,0,0,0,96.8,68.1Z"
|
||||
/>
|
||||
<path
|
||||
data-name="Path"
|
||||
d="M21.4,17.7H34.2l-7.4,8.7,3,2.6L41.1,15.7,29.8,2.5l-3,2.6,7.4,8.6H21.4A18.2,18.2,0,0,0,3.2,31.9h4A14.2,14.2,0,0,1,21.4,17.7Z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
import React, {Fragment} from 'react';
|
||||
|
||||
export default ({width, height, color, padding, margin}) => (
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 100 100"
|
||||
enableBackground="new 0 0 100 100"
|
||||
>
|
||||
<path d="M17.914,60.871v9.576h3.573v-9.576H17.914z M66.886,25.279v9.703h3.573V17.425c0-2.659-2.181-4.82-4.842-4.82h-3.075v7.853 C64.975,20.729,66.886,22.765,66.886,25.279z" />
|
||||
<path d="M65.617,12.605H22.775c-2.68,0-4.861,2.161-4.861,4.82v63.183c0,2.68,2.181,4.842,4.841,4.842h32.91v-8.436H26.348 c-1.495,0-2.844-0.664-3.739-1.723v-0.023c-0.706-0.85-1.122-1.91-1.122-3.074V25.279c0-2.68,2.182-4.841,4.861-4.841h35.674 c0.166,0,0.355,0,0.52,0.02c2.433,0.271,4.344,2.307,4.344,4.821v9.703h3.573V17.425C70.459,14.766,68.278,12.605,65.617,12.605z M44.425,78.676c1.495,0,2.722,1.207,2.722,2.701c0,1.516-1.227,2.721-2.722,2.721c-1.516,0-2.721-1.205-2.721-2.721 C41.704,79.883,42.909,78.676,44.425,78.676z" />
|
||||
<path d="M82.239,37.995h-20.88c-1.769,0-3.181,1.413-3.181,3.18v41.513c0,1.203,0.646,2.223,1.622,2.762 c0.456,0.27,0.996,0.416,1.559,0.416h20.88c1.765,0,3.2-1.414,3.2-3.178V41.174C85.439,39.407,84.004,37.995,82.239,37.995z M60.527,46.326c0-1.351,0.832-2.493,2.015-2.95c0.354-0.146,0.749-0.229,1.165-0.229h16.185c1.766,0,3.2,1.415,3.2,3.179v30.813 c0,1.766-1.435,3.18-3.2,3.18H63.707c-1.746,0-3.18-1.414-3.18-3.18V46.326z M71.664,84.971c-0.976,0-1.767-0.789-1.767-1.787 c0-0.166,0.021-0.311,0.083-0.455c0.022-0.189,0.105-0.355,0.208-0.5c0,0,0-0.02,0.021-0.041c0.312-0.457,0.852-0.77,1.454-0.77 c0.997,0,1.786,0.791,1.786,1.766C73.45,84.182,72.661,84.971,71.664,84.971z" />
|
||||
</svg>
|
||||
</Fragment>
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 100 100"
|
||||
enableBackground="new 0 0 100 100"
|
||||
>
|
||||
<path d="M17.914,60.871v9.576h3.573v-9.576H17.914z M66.886,25.279v9.703h3.573V17.425c0-2.659-2.181-4.82-4.842-4.82h-3.075v7.853 C64.975,20.729,66.886,22.765,66.886,25.279z" />
|
||||
<path d="M65.617,12.605H22.775c-2.68,0-4.861,2.161-4.861,4.82v63.183c0,2.68,2.181,4.842,4.841,4.842h32.91v-8.436H26.348 c-1.495,0-2.844-0.664-3.739-1.723v-0.023c-0.706-0.85-1.122-1.91-1.122-3.074V25.279c0-2.68,2.182-4.841,4.861-4.841h35.674 c0.166,0,0.355,0,0.52,0.02c2.433,0.271,4.344,2.307,4.344,4.821v9.703h3.573V17.425C70.459,14.766,68.278,12.605,65.617,12.605z M44.425,78.676c1.495,0,2.722,1.207,2.722,2.701c0,1.516-1.227,2.721-2.722,2.721c-1.516,0-2.721-1.205-2.721-2.721 C41.704,79.883,42.909,78.676,44.425,78.676z" />
|
||||
<path d="M82.239,37.995h-20.88c-1.769,0-3.181,1.413-3.181,3.18v41.513c0,1.203,0.646,2.223,1.622,2.762 c0.456,0.27,0.996,0.416,1.559,0.416h20.88c1.765,0,3.2-1.414,3.2-3.178V41.174C85.439,39.407,84.004,37.995,82.239,37.995z M60.527,46.326c0-1.351,0.832-2.493,2.015-2.95c0.354-0.146,0.749-0.229,1.165-0.229h16.185c1.766,0,3.2,1.415,3.2,3.179v30.813 c0,1.766-1.435,3.18-3.2,3.18H63.707c-1.746,0-3.18-1.414-3.18-3.18V46.326z M71.664,84.971c-0.976,0-1.767-0.789-1.767-1.787 c0-0.166,0.021-0.311,0.083-0.455c0.022-0.189,0.105-0.355,0.208-0.5c0,0,0-0.02,0.021-0.041c0.312-0.457,0.852-0.77,1.454-0.77 c0.997,0,1.786,0.791,1.786,1.766C73.45,84.182,72.661,84.971,71.664,84.971z" />
|
||||
</svg>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
|
@ -1,44 +1,44 @@
|
|||
import React, {Fragment} from 'react';
|
||||
|
||||
export default ({width, height, color, padding, margin}) => (
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
viewBox="0 0 1240 1240"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<g
|
||||
id="chevronsLeft"
|
||||
stroke="none"
|
||||
strokeWidth="1"
|
||||
fill="none"
|
||||
fillRule="evenodd"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<g
|
||||
id="Group"
|
||||
transform="translate(619.500000, 620.000000) rotate(90.000000) translate(-619.500000, -620.000000) translate(409.000000, 406.000000)"
|
||||
stroke="white"
|
||||
strokeWidth="50"
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
viewBox="0 0 1240 1240"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<polyline
|
||||
id="Path"
|
||||
transform="translate(210.500000, 321.000000) scale(1, -1) translate(-210.500000, -321.000000) "
|
||||
points="0 428 210.5 214 421 428"
|
||||
/>
|
||||
<polyline
|
||||
id="Path"
|
||||
transform="translate(210.500000, 107.000000) scale(1, -1) translate(-210.500000, -107.000000) "
|
||||
points="0 214 210.5 0 421 214"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</Fragment>
|
||||
<g
|
||||
id="chevronsLeft"
|
||||
stroke="none"
|
||||
strokeWidth="1"
|
||||
fill="none"
|
||||
fillRule="evenodd"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<g
|
||||
id="Group"
|
||||
transform="translate(619.500000, 620.000000) rotate(90.000000) translate(-619.500000, -620.000000) translate(409.000000, 406.000000)"
|
||||
stroke="white"
|
||||
strokeWidth="50"
|
||||
>
|
||||
<polyline
|
||||
id="Path"
|
||||
transform="translate(210.500000, 321.000000) scale(1, -1) translate(-210.500000, -321.000000) "
|
||||
points="0 428 210.5 214 421 428"
|
||||
/>
|
||||
<polyline
|
||||
id="Path"
|
||||
transform="translate(210.500000, 107.000000) scale(1, -1) translate(-210.500000, -107.000000) "
|
||||
points="0 214 210.5 0 421 214"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
import React, {Fragment} from 'react';
|
||||
|
||||
export default ({width, height, color, padding, margin}) => (
|
||||
<Fragment>
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
fill={color}
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 129 129"
|
||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
enableBackground="new 0 0 129 129"
|
||||
>
|
||||
<g>
|
||||
<path d="m40.4,121.3c-0.8,0.8-1.8,1.2-2.9,1.2s-2.1-0.4-2.9-1.2c-1.6-1.6-1.6-4.2 0-5.8l51-51-51-51c-1.6-1.6-1.6-4.2 0-5.8 1.6-1.6 4.2-1.6 5.8,0l53.9,53.9c1.6,1.6 1.6,4.2 0,5.8l-53.9,53.9z" />
|
||||
</g>
|
||||
</svg>
|
||||
</Fragment>
|
||||
<Fragment>
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
fill={color}
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 129 129"
|
||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
enableBackground="new 0 0 129 129"
|
||||
>
|
||||
<g>
|
||||
<path d="m40.4,121.3c-0.8,0.8-1.8,1.2-2.9,1.2s-2.1-0.4-2.9-1.2c-1.6-1.6-1.6-4.2 0-5.8l51-51-51-51c-1.6-1.6-1.6-4.2 0-5.8 1.6-1.6 4.2-1.6 5.8,0l53.9,53.9c1.6,1.6 1.6,4.2 0,5.8l-53.9,53.9z" />
|
||||
</g>
|
||||
</svg>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
import React, {Fragment} from 'react';
|
||||
|
||||
export default ({width, height, color, padding, margin}) => (
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
version="1.1"
|
||||
id="Capa_1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 63.699 63.699"
|
||||
xmlSpace="preserve"
|
||||
>
|
||||
<g>
|
||||
<path
|
||||
d="M63.663,29.424c-0.143-1.093-0.701-2.065-1.575-2.737l-11.715-9.021V8.608c0-2.275-1.851-4.126-4.125-4.126
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
version="1.1"
|
||||
id="Capa_1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 63.699 63.699"
|
||||
xmlSpace="preserve"
|
||||
>
|
||||
<g>
|
||||
<path
|
||||
d="M63.663,29.424c-0.143-1.093-0.701-2.065-1.575-2.737l-11.715-9.021V8.608c0-2.275-1.851-4.126-4.125-4.126
|
||||
c-2.273,0-4.125,1.851-4.125,4.126v2.705l-7.758-5.975c-0.718-0.551-1.612-0.856-2.517-0.856c-0.906,0-1.801,0.304-2.519,0.857
|
||||
L1.606,26.687c-1.802,1.389-2.139,3.983-0.751,5.785c0.788,1.022,1.979,1.608,3.271,1.608c0.664,0,1.302-0.153,1.88-0.451V55.09
|
||||
c0,2.275,1.851,4.127,4.126,4.127h18.534V39.732h6.351v19.482h18.271c2.274,0,4.125-1.85,4.125-4.127V33.472
|
||||
|
@ -26,23 +26,23 @@ export default ({width, height, color, padding, margin}) => (
|
|||
c-0.059,0-0.167-0.017-0.248-0.121c-0.065-0.084-0.07-0.171-0.062-0.229c0.007-0.058,0.034-0.141,0.118-0.205L31.661,8.363
|
||||
c0.138-0.105,0.239-0.106,0.379,0l13.899,10.703V8.608c0-0.172,0.14-0.311,0.311-0.311s0.312,0.139,0.312,0.311v10.935
|
||||
l13.205,10.166c0.084,0.064,0.108,0.147,0.116,0.205C59.891,29.975,59.885,30.062,59.819,30.144z"
|
||||
/>
|
||||
</g>
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
</svg>
|
||||
</Fragment>
|
||||
/>
|
||||
</g>
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
</svg>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
|
@ -1,51 +1,51 @@
|
|||
import React, {Fragment} from 'react';
|
||||
|
||||
export default ({width, height, color, padding, margin}) => (
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
stroke={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 66 66"
|
||||
>
|
||||
<defs>
|
||||
<clipPath id="_clipPath_1jbp17xur21ul8z5IuRkxmo4gJ5cDGqz">
|
||||
<rect width="66" height="66" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g clipPath="url(#_clipPath_1jbp17xur21ul8z5IuRkxmo4gJ5cDGqz)">
|
||||
<g>
|
||||
<path d=" M 47.973 42.767 C 47.865 41.943 47.445 41.211 46.786 40.704 L 37.958 33.907 L 37.958 27.081 C 37.958 25.367 36.564 23.972 34.85 23.972 C 33.137 23.972 31.742 25.367 31.742 27.081 L 31.742 29.119 L 25.896 24.617 C 25.355 24.202 24.681 23.972 23.999 23.972 C 23.316 23.972 22.642 24.201 22.101 24.618 L 1.21 40.704 C -0.147 41.751 -0.401 43.706 0.645 45.064 C 1.238 45.834 2.136 46.275 3.109 46.275 C 3.61 46.275 4.091 46.16 4.526 45.935 L 4.526 62.107 C 4.526 63.821 5.921 65.217 7.635 65.217 L 21.601 65.217 L 21.601 50.534 L 26.387 50.534 L 26.387 65.215 L 40.155 65.215 C 41.869 65.215 43.263 63.821 43.263 62.105 L 43.263 45.817 C 43.752 46.118 44.309 46.275 44.889 46.275 C 45.86 46.275 46.759 45.834 47.353 45.065 C 47.861 44.407 48.082 43.591 47.973 42.767 Z M 45.076 43.309 C 45.016 43.388 44.934 43.401 44.89 43.401 C 44.838 43.401 44.791 43.385 44.749 43.352 L 40.39 39.997 L 40.39 62.107 C 40.39 62.237 40.285 62.342 40.156 62.342 L 29.262 62.342 L 29.263 47.66 L 18.727 47.66 L 18.727 62.342 L 7.635 62.342 C 7.506 62.342 7.402 62.236 7.402 62.107 L 7.402 40.156 L 3.252 43.351 C 3.21 43.384 3.162 43.4 3.11 43.4 C 3.066 43.4 2.984 43.388 2.923 43.309 C 2.874 43.246 2.871 43.18 2.877 43.137 C 2.882 43.093 2.902 43.03 2.965 42.982 L 23.858 26.896 C 23.962 26.817 24.038 26.817 24.144 26.896 L 34.617 34.962 L 34.617 27.081 C 34.617 26.951 34.723 26.847 34.852 26.847 C 34.98 26.847 35.087 26.951 35.087 27.081 L 35.087 35.321 L 45.037 42.982 C 45.1 43.03 45.119 43.092 45.125 43.136 C 45.131 43.182 45.126 43.248 45.076 43.309 Z " />
|
||||
</g>
|
||||
<g>
|
||||
<line
|
||||
x1="51"
|
||||
y1="2"
|
||||
x2="51"
|
||||
y2="28"
|
||||
vectorEffect="non-scaling-stroke"
|
||||
strokeWidth="1"
|
||||
strokeLinejoin="miter"
|
||||
strokeLinecap="round"
|
||||
strokeMiterlimit="3"
|
||||
/>
|
||||
<line
|
||||
x1="64"
|
||||
y1="15"
|
||||
x2="38"
|
||||
y2="15"
|
||||
vectorEffect="non-scaling-stroke"
|
||||
strokeWidth="1"
|
||||
strokeLinejoin="miter"
|
||||
strokeLinecap="round"
|
||||
strokeMiterlimit="3"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</Fragment>
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
stroke={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 66 66"
|
||||
>
|
||||
<defs>
|
||||
<clipPath id="_clipPath_1jbp17xur21ul8z5IuRkxmo4gJ5cDGqz">
|
||||
<rect width="66" height="66" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g clipPath="url(#_clipPath_1jbp17xur21ul8z5IuRkxmo4gJ5cDGqz)">
|
||||
<g>
|
||||
<path d=" M 47.973 42.767 C 47.865 41.943 47.445 41.211 46.786 40.704 L 37.958 33.907 L 37.958 27.081 C 37.958 25.367 36.564 23.972 34.85 23.972 C 33.137 23.972 31.742 25.367 31.742 27.081 L 31.742 29.119 L 25.896 24.617 C 25.355 24.202 24.681 23.972 23.999 23.972 C 23.316 23.972 22.642 24.201 22.101 24.618 L 1.21 40.704 C -0.147 41.751 -0.401 43.706 0.645 45.064 C 1.238 45.834 2.136 46.275 3.109 46.275 C 3.61 46.275 4.091 46.16 4.526 45.935 L 4.526 62.107 C 4.526 63.821 5.921 65.217 7.635 65.217 L 21.601 65.217 L 21.601 50.534 L 26.387 50.534 L 26.387 65.215 L 40.155 65.215 C 41.869 65.215 43.263 63.821 43.263 62.105 L 43.263 45.817 C 43.752 46.118 44.309 46.275 44.889 46.275 C 45.86 46.275 46.759 45.834 47.353 45.065 C 47.861 44.407 48.082 43.591 47.973 42.767 Z M 45.076 43.309 C 45.016 43.388 44.934 43.401 44.89 43.401 C 44.838 43.401 44.791 43.385 44.749 43.352 L 40.39 39.997 L 40.39 62.107 C 40.39 62.237 40.285 62.342 40.156 62.342 L 29.262 62.342 L 29.263 47.66 L 18.727 47.66 L 18.727 62.342 L 7.635 62.342 C 7.506 62.342 7.402 62.236 7.402 62.107 L 7.402 40.156 L 3.252 43.351 C 3.21 43.384 3.162 43.4 3.11 43.4 C 3.066 43.4 2.984 43.388 2.923 43.309 C 2.874 43.246 2.871 43.18 2.877 43.137 C 2.882 43.093 2.902 43.03 2.965 42.982 L 23.858 26.896 C 23.962 26.817 24.038 26.817 24.144 26.896 L 34.617 34.962 L 34.617 27.081 C 34.617 26.951 34.723 26.847 34.852 26.847 C 34.98 26.847 35.087 26.951 35.087 27.081 L 35.087 35.321 L 45.037 42.982 C 45.1 43.03 45.119 43.092 45.125 43.136 C 45.131 43.182 45.126 43.248 45.076 43.309 Z " />
|
||||
</g>
|
||||
<g>
|
||||
<line
|
||||
x1="51"
|
||||
y1="2"
|
||||
x2="51"
|
||||
y2="28"
|
||||
vectorEffect="non-scaling-stroke"
|
||||
strokeWidth="1"
|
||||
strokeLinejoin="miter"
|
||||
strokeLinecap="round"
|
||||
strokeMiterlimit="3"
|
||||
/>
|
||||
<line
|
||||
x1="64"
|
||||
y1="15"
|
||||
x2="38"
|
||||
y2="15"
|
||||
vectorEffect="non-scaling-stroke"
|
||||
strokeWidth="1"
|
||||
strokeLinejoin="miter"
|
||||
strokeLinecap="round"
|
||||
strokeMiterlimit="3"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
|
@ -1,48 +1,48 @@
|
|||
import React, {Fragment} from 'react';
|
||||
|
||||
export default ({width, height, color, padding, margin}) => (
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="563.5 323.5 162.599 156.526"
|
||||
>
|
||||
<path
|
||||
d=" M 595 340 L 665 340 C 673.279 340 680 346.721 680 355 L 680 425 C 680 433.279 673.279 440 665 440 L 595 440 C 586.721 440 580 433.279 580 425 L 580 355 C 580 346.721 586.721 340 595 340 Z "
|
||||
vectorEffect="non-scaling-stroke"
|
||||
strokeWidth="1"
|
||||
stroke={color}
|
||||
strokeLinejoin="miter"
|
||||
strokeLinecap="square"
|
||||
strokeMiterlimit="3"
|
||||
fill="none"
|
||||
/>
|
||||
<g>
|
||||
<path
|
||||
d=" M 653.959 477.588 L 615.403 363.46 L 726.099 418.249 L 677.594 434.636 L 674.982 436.313 L 653.959 477.588 Z "
|
||||
fill={'black'}
|
||||
/>
|
||||
<path
|
||||
d=" M 720.556 460.652 L 698.492 480.026 L 638.218 412.176 L 660.996 392.561 L 720.556 460.652 Z "
|
||||
fill={'black'}
|
||||
/>
|
||||
<rect
|
||||
x="676.273"
|
||||
y="411.114"
|
||||
width="15.059"
|
||||
height="60.236"
|
||||
transform="matrix(0.75,-0.662,0.662,0.75,-120.833,563.023)"
|
||||
fill={color}
|
||||
/>
|
||||
<path
|
||||
d=" M 628.319 378.169 L 655.309 458.059 L 669.719 430.144 L 672.331 428.467 L 706.57 416.9 L 628.319 378.169 Z "
|
||||
fill={color}
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</Fragment>
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="563.5 323.5 162.599 156.526"
|
||||
>
|
||||
<path
|
||||
d=" M 595 340 L 665 340 C 673.279 340 680 346.721 680 355 L 680 425 C 680 433.279 673.279 440 665 440 L 595 440 C 586.721 440 580 433.279 580 425 L 580 355 C 580 346.721 586.721 340 595 340 Z "
|
||||
vectorEffect="non-scaling-stroke"
|
||||
strokeWidth="1"
|
||||
stroke={color}
|
||||
strokeLinejoin="miter"
|
||||
strokeLinecap="square"
|
||||
strokeMiterlimit="3"
|
||||
fill="none"
|
||||
/>
|
||||
<g>
|
||||
<path
|
||||
d=" M 653.959 477.588 L 615.403 363.46 L 726.099 418.249 L 677.594 434.636 L 674.982 436.313 L 653.959 477.588 Z "
|
||||
fill={'black'}
|
||||
/>
|
||||
<path
|
||||
d=" M 720.556 460.652 L 698.492 480.026 L 638.218 412.176 L 660.996 392.561 L 720.556 460.652 Z "
|
||||
fill={'black'}
|
||||
/>
|
||||
<rect
|
||||
x="676.273"
|
||||
y="411.114"
|
||||
width="15.059"
|
||||
height="60.236"
|
||||
transform="matrix(0.75,-0.662,0.662,0.75,-120.833,563.023)"
|
||||
fill={color}
|
||||
/>
|
||||
<path
|
||||
d=" M 628.319 378.169 L 655.309 458.059 L 669.719 430.144 L 672.331 428.467 L 706.57 416.9 L 628.319 378.169 Z "
|
||||
fill={color}
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
import React, {Fragment} from 'react';
|
||||
|
||||
export default ({width, height, color, padding, margin}) => (
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 32 32"
|
||||
enableBackground="new 0 0 32 32"
|
||||
>
|
||||
<path d="M32 14c0 1.104-0.896 2-2 2H20c-1.104 0-2-0.896-2-2V2c0-1.104 0.896-2 2-2h10c1.104 0 2 0.896 2 2v3c0 0.552-0.447 1-1 1s-1-0.448-1-1V2H20v12h10V9c0-0.552 0.447-1 1-1s1 0.448 1 1V14z" />
|
||||
<path d="M27 32c-0.553 0-1-0.448-1-1s0.447-1 1-1h3v-8H20v8h3c0.553 0 1 0.448 1 1s-0.447 1-1 1h-3c-1.104 0-2-0.896-2-2v-8c0-1.104 0.896-2 2-2h10c1.104 0 2 0.896 2 2v8c0 1.104-0.896 2-2 2H27z" />
|
||||
<path d="M0 2c0-1.104 0.896-2 2-2h10c1.104 0 2 0.896 2 2v28c0 1.104-0.896 2-2 2H2c-1.104 0-2-0.896-2-2v-3c0-0.552 0.447-1 1-1s1 0.448 1 1v3h10V2H2v21c0 0.552-0.447 1-1 1s-1-0.448-1-1V2z" />
|
||||
</svg>
|
||||
</Fragment>
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 32 32"
|
||||
enableBackground="new 0 0 32 32"
|
||||
>
|
||||
<path d="M32 14c0 1.104-0.896 2-2 2H20c-1.104 0-2-0.896-2-2V2c0-1.104 0.896-2 2-2h10c1.104 0 2 0.896 2 2v3c0 0.552-0.447 1-1 1s-1-0.448-1-1V2H20v12h10V9c0-0.552 0.447-1 1-1s1 0.448 1 1V14z" />
|
||||
<path d="M27 32c-0.553 0-1-0.448-1-1s0.447-1 1-1h3v-8H20v8h3c0.553 0 1 0.448 1 1s-0.447 1-1 1h-3c-1.104 0-2-0.896-2-2v-8c0-1.104 0.896-2 2-2h10c1.104 0 2 0.896 2 2v8c0 1.104-0.896 2-2 2H27z" />
|
||||
<path d="M0 2c0-1.104 0.896-2 2-2h10c1.104 0 2 0.896 2 2v28c0 1.104-0.896 2-2 2H2c-1.104 0-2-0.896-2-2v-3c0-0.552 0.447-1 1-1s1 0.448 1 1v3h10V2H2v21c0 0.552-0.447 1-1 1s-1-0.448-1-1V2z" />
|
||||
</svg>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
|
@ -1,104 +1,104 @@
|
|||
import React, {Fragment} from 'react';
|
||||
|
||||
export default ({width, height, color, padding, margin}) => (
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{enableBackground: 'new 0 0 480.8 480.8', padding}}
|
||||
version="1.1"
|
||||
id="Capa_1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 480.8 480.8"
|
||||
xmlSpace="preserve"
|
||||
>
|
||||
<path
|
||||
style={{fill: color}}
|
||||
d="M317.112,314.4c-22.4,22.4-19.6,67.6-19.6,67.6h-113.6c0,0,2.4-45.2-19.6-67.6
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{enableBackground: 'new 0 0 480.8 480.8', padding}}
|
||||
version="1.1"
|
||||
id="Capa_1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 480.8 480.8"
|
||||
xmlSpace="preserve"
|
||||
>
|
||||
<path
|
||||
style={{fill: color}}
|
||||
d="M317.112,314.4c-22.4,22.4-19.6,67.6-19.6,67.6h-113.6c0,0,2.4-45.2-19.6-67.6
|
||||
c-24.4-21.6-40-52.8-40-87.6c0-64,52-116,116-116s116,52,116,116C356.312,261.6,341.112,292.8,317.112,314.4L317.112,314.4z"
|
||||
/>
|
||||
<g>
|
||||
<path
|
||||
style={{fill: '#E5E5E5'}}
|
||||
d="M300.712,417.6c0,6-4.8,10.8-10.8,10.8h-98.8c-6,0-10.8-4.8-10.8-10.8l0,0c0-6,4.8-10.8,10.8-10.8
|
||||
/>
|
||||
<g>
|
||||
<path
|
||||
style={{fill: '#E5E5E5'}}
|
||||
d="M300.712,417.6c0,6-4.8,10.8-10.8,10.8h-98.8c-6,0-10.8-4.8-10.8-10.8l0,0c0-6,4.8-10.8,10.8-10.8
|
||||
h98.4C295.512,406.8,300.712,411.6,300.712,417.6L300.712,417.6z"
|
||||
/>
|
||||
<path
|
||||
style={{fill: '#E5E5E5'}}
|
||||
d="M285.912,462.4c0,6-4.8,10.8-10.8,10.8h-69.2c-6,0-10.8-4.8-10.8-10.8l0,0c0-6,4.8-10.8,10.8-10.8
|
||||
/>
|
||||
<path
|
||||
style={{fill: '#E5E5E5'}}
|
||||
d="M285.912,462.4c0,6-4.8,10.8-10.8,10.8h-69.2c-6,0-10.8-4.8-10.8-10.8l0,0c0-6,4.8-10.8,10.8-10.8
|
||||
h69.2C281.112,451.6,285.912,456.4,285.912,462.4L285.912,462.4z"
|
||||
/>
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
style={{fill: '#210B20'}}
|
||||
d="M323.112,318.4c26-23.6,40.8-56.8,40.8-91.6c0-68-55.6-123.6-123.6-123.6s-123.6,55.6-123.6,123.6
|
||||
/>
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
style={{fill: '#210B20'}}
|
||||
d="M323.112,318.4c26-23.6,40.8-56.8,40.8-91.6c0-68-55.6-123.6-123.6-123.6s-123.6,55.6-123.6,123.6
|
||||
c0,35.6,15.6,69.6,42,92.8c19.6,19.6,17.6,61.2,17.6,61.6c0,2,0.8,4,2,5.6c1.6,1.6,3.6,2.4,5.6,2.4h113.2c2,0,4-0.8,5.6-2.4
|
||||
s2-3.6,2-5.6c0-0.4-2-42,17.6-61.6C322.712,319.2,323.112,318.8,323.112,318.4z M311.912,308.4c-0.8,0.4-1.2,1.2-1.6,2
|
||||
c-17.6,18.8-20.4,49.6-20.8,64h-98c-0.4-14.8-3.6-46.8-22.4-65.6c-23.6-20.8-37.2-50.4-37.2-81.6c0-60,48.8-108.4,108.4-108.4
|
||||
c60,0,108.4,48.8,108.4,108.4C348.712,258,335.512,288,311.912,308.4z"
|
||||
/>
|
||||
<path
|
||||
style={{fill: '#210B20'}}
|
||||
d="M240.312,135.2c-4,0-7.6,3.2-7.6,7.6c0,4,3.2,7.6,7.6,7.6c44.8,0,81.2,36.4,81.2,81.2
|
||||
/>
|
||||
<path
|
||||
style={{fill: '#210B20'}}
|
||||
d="M240.312,135.2c-4,0-7.6,3.2-7.6,7.6c0,4,3.2,7.6,7.6,7.6c44.8,0,81.2,36.4,81.2,81.2
|
||||
c0,4,3.2,7.6,7.6,7.6c4,0,7.6-3.2,7.6-7.6C336.712,178.4,293.512,135.2,240.312,135.2z"
|
||||
/>
|
||||
<path
|
||||
style={{fill: '#210B20'}}
|
||||
d="M308.312,417.6c0-10.4-8.4-18.4-18.4-18.4h-98.8c-10.4,0-18.4,8.4-18.4,18.4
|
||||
/>
|
||||
<path
|
||||
style={{fill: '#210B20'}}
|
||||
d="M308.312,417.6c0-10.4-8.4-18.4-18.4-18.4h-98.8c-10.4,0-18.4,8.4-18.4,18.4
|
||||
c0,10.4,8.4,18.4,18.4,18.4h98.4C299.912,436,308.312,428,308.312,417.6z M289.512,420.8h-98.4c-2,0-3.2-1.6-3.2-3.2
|
||||
c0-2,1.6-3.2,3.2-3.2h98.4c2,0,3.2,1.6,3.2,3.2C293.112,419.6,291.512,420.8,289.512,420.8z"
|
||||
/>
|
||||
<path
|
||||
style={{fill: '#210B20'}}
|
||||
d="M275.112,444h-69.2c-10.4,0-18.4,8.4-18.4,18.4c0,10.4,8.4,18.4,18.4,18.4h69.2
|
||||
/>
|
||||
<path
|
||||
style={{fill: '#210B20'}}
|
||||
d="M275.112,444h-69.2c-10.4,0-18.4,8.4-18.4,18.4c0,10.4,8.4,18.4,18.4,18.4h69.2
|
||||
c10.4,0,18.4-8.4,18.4-18.4C293.512,452.4,285.112,444,275.112,444z M275.112,465.6h-69.2c-2,0-3.2-1.6-3.2-3.2
|
||||
c0-2,1.6-3.2,3.2-3.2h69.2c2,0,3.2,1.6,3.2,3.2C278.312,464.4,277.112,465.6,275.112,465.6z"
|
||||
/>
|
||||
<path
|
||||
style={{fill: '#210B20'}}
|
||||
d="M247.912,58.8V7.6c0-4-3.2-7.6-7.6-7.6c-4,0-7.6,3.2-7.6,7.6v51.6c0,4,3.2,7.6,7.6,7.6
|
||||
/>
|
||||
<path
|
||||
style={{fill: '#210B20'}}
|
||||
d="M247.912,58.8V7.6c0-4-3.2-7.6-7.6-7.6c-4,0-7.6,3.2-7.6,7.6v51.6c0,4,3.2,7.6,7.6,7.6
|
||||
C244.712,66.4,247.912,63.2,247.912,58.8z"
|
||||
/>
|
||||
<path
|
||||
style={{fill: '#210B20'}}
|
||||
d="M366.312,38c-3.6-2.4-8-1.2-10.4,2l-28.4,42.8c-2.4,3.6-1.2,8,2,10.4c1.2,0.8,2.8,1.2,4,1.2
|
||||
/>
|
||||
<path
|
||||
style={{fill: '#210B20'}}
|
||||
d="M366.312,38c-3.6-2.4-8-1.2-10.4,2l-28.4,42.8c-2.4,3.6-1.2,8,2,10.4c1.2,0.8,2.8,1.2,4,1.2
|
||||
c2.4,0,4.8-1.2,6.4-3.2l28.4-42.8C370.712,45.2,369.512,40.4,366.312,38z"
|
||||
/>
|
||||
<path
|
||||
style={{fill: '#210B20'}}
|
||||
d="M149.912,92.8c1.2,0,2.8-0.4,4-1.2c3.6-2.4,4.4-6.8,2.4-10.4l-27.6-43.2c-2.4-3.6-6.8-4.4-10.4-2.4
|
||||
/>
|
||||
<path
|
||||
style={{fill: '#210B20'}}
|
||||
d="M149.912,92.8c1.2,0,2.8-0.4,4-1.2c3.6-2.4,4.4-6.8,2.4-10.4l-27.6-43.2c-2.4-3.6-6.8-4.4-10.4-2.4
|
||||
c-3.6,2.4-4.4,6.8-2.4,10.4l27.6,43.2C145.112,91.6,147.512,92.8,149.912,92.8z"
|
||||
/>
|
||||
<path
|
||||
style={{fill: '#210B20'}}
|
||||
d="M43.912,128.8l45.2,24.4c1.2,0.8,2.4,0.8,3.6,0.8c2.8,0,5.2-1.6,6.8-4c2-3.6,0.8-8.4-3.2-10.4
|
||||
/>
|
||||
<path
|
||||
style={{fill: '#210B20'}}
|
||||
d="M43.912,128.8l45.2,24.4c1.2,0.8,2.4,0.8,3.6,0.8c2.8,0,5.2-1.6,6.8-4c2-3.6,0.8-8.4-3.2-10.4
|
||||
l-45.2-24.4c-3.6-2-8.4-0.8-10.4,3.2C39.112,122.4,40.312,126.8,43.912,128.8z"
|
||||
/>
|
||||
<path
|
||||
style={{fill: '#210B20'}}
|
||||
d="M387.912,154.4c1.2,0,2.4-0.4,3.6-0.8l45.2-24.4c3.6-2,5.2-6.4,3.2-10.4c-2-3.6-6.4-5.2-10.4-3.2
|
||||
/>
|
||||
<path
|
||||
style={{fill: '#210B20'}}
|
||||
d="M387.912,154.4c1.2,0,2.4-0.4,3.6-0.8l45.2-24.4c3.6-2,5.2-6.4,3.2-10.4c-2-3.6-6.4-5.2-10.4-3.2
|
||||
l-45.2,24.4c-3.6,2-5.2,6.4-3.2,10.4C382.312,152.8,385.112,154.4,387.912,154.4z"
|
||||
/>
|
||||
</g>
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
</svg>
|
||||
</Fragment>
|
||||
/>
|
||||
</g>
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
<g />
|
||||
</svg>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
|
@ -3,5 +3,5 @@ import React from 'react';
|
|||
import logoImage from '../../../resources/logo.svg';
|
||||
|
||||
export default ({width, height, color, padding, margin}) => (
|
||||
<img src={logoImage} height={height} width={width} alt="" />
|
||||
<img src={logoImage} height={height} width={width} alt="" />
|
||||
);
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
import React, {Fragment} from 'react';
|
||||
|
||||
export default ({width, height, color, padding, margin}) => (
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="M19,2H5A3,3,0,0,0,2,5V19a3,3,0,0,0,3,3H19a2.81,2.81,0,0,0,.49-.05l.3-.07.07,0h0l.05,0,.37-.14.13-.07c.1-.06.21-.11.31-.18a3.79,3.79,0,0,0,.38-.32l.07-.09a2.69,2.69,0,0,0,.27-.32l.09-.13a2.31,2.31,0,0,0,.18-.35,1,1,0,0,0,.07-.15c.05-.12.08-.25.12-.38l0-.15A2.6,2.6,0,0,0,22,19V5A3,3,0,0,0,19,2ZM5,20a1,1,0,0,1-1-1V14.69l3.29-3.3h0a1,1,0,0,1,1.42,0L17.31,20Zm15-1a1,1,0,0,1-.07.36,1,1,0,0,1-.08.14.94.94,0,0,1-.09.12l-5.35-5.35.88-.88a1,1,0,0,1,1.42,0h0L20,16.69Zm0-5.14L18.12,12a3.08,3.08,0,0,0-4.24,0l-.88.88L10.12,10a3.08,3.08,0,0,0-4.24,0L4,11.86V5A1,1,0,0,1,5,4H19a1,1,0,0,1,1,1ZM13.5,6A1.5,1.5,0,1,0,15,7.5,1.5,1.5,0,0,0,13.5,6Z" />
|
||||
</svg>
|
||||
</Fragment>
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="M19,2H5A3,3,0,0,0,2,5V19a3,3,0,0,0,3,3H19a2.81,2.81,0,0,0,.49-.05l.3-.07.07,0h0l.05,0,.37-.14.13-.07c.1-.06.21-.11.31-.18a3.79,3.79,0,0,0,.38-.32l.07-.09a2.69,2.69,0,0,0,.27-.32l.09-.13a2.31,2.31,0,0,0,.18-.35,1,1,0,0,0,.07-.15c.05-.12.08-.25.12-.38l0-.15A2.6,2.6,0,0,0,22,19V5A3,3,0,0,0,19,2ZM5,20a1,1,0,0,1-1-1V14.69l3.29-3.3h0a1,1,0,0,1,1.42,0L17.31,20Zm15-1a1,1,0,0,1-.07.36,1,1,0,0,1-.08.14.94.94,0,0,1-.09.12l-5.35-5.35.88-.88a1,1,0,0,1,1.42,0h0L20,16.69Zm0-5.14L18.12,12a3.08,3.08,0,0,0-4.24,0l-.88.88L10.12,10a3.08,3.08,0,0,0-4.24,0L4,11.86V5A1,1,0,0,1,5,4H19a1,1,0,0,1,1,1ZM13.5,6A1.5,1.5,0,1,0,15,7.5,1.5,1.5,0,0,0,13.5,6Z" />
|
||||
</svg>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
import React, {Fragment} from 'react';
|
||||
|
||||
export default ({width, height, color, padding, margin}) => (
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="M21,11a1,1,0,0,0-1,1,8.05,8.05,0,1,1-2.22-5.5h-2.4a1,1,0,0,0,0,2h4.53a1,1,0,0,0,1-1V3a1,1,0,0,0-2,0V4.77A10,10,0,1,0,22,12,1,1,0,0,0,21,11Z" />
|
||||
</svg>
|
||||
</Fragment>
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="M21,11a1,1,0,0,0-1,1,8.05,8.05,0,1,1-2.22-5.5h-2.4a1,1,0,0,0,0,2h4.53a1,1,0,0,0,1-1V3a1,1,0,0,0-2,0V4.77A10,10,0,1,0,22,12,1,1,0,0,0,21,11Z" />
|
||||
</svg>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import React, {Fragment} from 'react';
|
||||
|
||||
export default ({width, height, color, padding, margin}) => (
|
||||
<Fragment>
|
||||
{/*<svg
|
||||
<Fragment>
|
||||
{/*<svg
|
||||
width={width}
|
||||
height={height}
|
||||
fill={color}
|
||||
|
@ -12,29 +12,29 @@ export default ({width, height, color, padding, margin}) => (
|
|||
>
|
||||
<path d="M20,10.5a1,1,0,0,0-1,1v7a1,1,0,0,1-1,1H4a1,1,0,0,1-1-1v-8a1,1,0,0,1,1-1H6a1,1,0,0,0,1-.68l.54-1.64a1,1,0,0,1,.95-.68H14a1,1,0,0,0,0-2H8.44A3,3,0,0,0,5.6,6.55l-.32,1H4a3,3,0,0,0-3,3v8a3,3,0,0,0,3,3H18a3,3,0,0,0,3-3v-7A1,1,0,0,0,20,10.5Zm-9-1a4,4,0,1,0,4,4A4,4,0,0,0,11,9.5Zm0,6a2,2,0,1,1,2-2A2,2,0,0,1,11,15.5Zm11-11H21v-1a1,1,0,0,0-2,0v1H18a1,1,0,0,0,0,2h1v1a1,1,0,0,0,2,0v-1h1a1,1,0,0,0,0-2Z" />
|
||||
</svg>*/}
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 100 100"
|
||||
>
|
||||
<g transform="translate(0,-952.36218)">
|
||||
<path
|
||||
d="m 83,958.36218 c -1.1046,0 -2,0.89543 -2,2 l 0,7 -7,0 c -1.10457,0 -2,0.8954 -2,2 0,1.1046 0.89543,2 2,2 l 7,0 0,7 c 0,1.10457 0.8954,2 2,2 1.1046,0 2,-0.89543 2,-2 l 0,-7 7,0 c 1.10457,0 2,-0.8954 2,-2 0,-1.1046 -0.89543,-2 -2,-2 l -7,0 0,-7 c 0,-1.10457 -0.8954,-2 -2,-2 z m -48,22 c -0.78068,0.007 -1.3909,0.40265 -1.71875,0.96875 l -6.4375,11.03125 -12.84375,0 c -4.3973999,0 -8,3.6026 -8,8.00002 l 0,38 c 0,4.3974 3.6026001,8 8,8 l 62,0 c 4.3974,0 8,-3.6026 8,-8 l 0,-38 c 0,-4.39742 -3.6026,-8.00002 -8,-8.00002 l -12.84375,0 -6.4375,-11.03125 C 56.3641,980.74168 55.68774,980.36046 55,980.36218 l -20,0 z m 1.125,4 17.75,0 6.40625,11 c 0.34687,0.60075 1.02507,0.99534 1.71875,1 l 14,0 c 2.25056,0 4,1.74944 4,4.00002 l 0,38 c 0,2.2505 -1.74944,4 -4,4 l -62,0 c -2.25056,0 -4,-1.7495 -4,-4 l 0,-38 c 0,-2.25058 1.74944,-4.00002 4,-4.00002 l 14,0 c 0.69368,-0.005 1.37188,-0.39925 1.71875,-1 l 6.40625,-11 z M 45,1002.3622 c -8.81287,0 -16,7.1871 -16,16 0,8.8128 7.18713,16 16,16 8.81286,0 16,-7.1872 16,-16 0,-8.8129 -7.18714,-16 -16,-16 z m 0,4 c 6.6511,0 12,5.3489 12,12 0,6.6511 -5.3489,12 -12,12 -6.65111,0 -12,-5.3489 -12,-12 0,-6.6511 5.34889,-12 12,-12 z"
|
||||
fill={color}
|
||||
fillOpacity="1"
|
||||
stroke="none"
|
||||
marker="none"
|
||||
visibility="visible"
|
||||
display="inline"
|
||||
overflow="visible"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</Fragment>
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 100 100"
|
||||
>
|
||||
<g transform="translate(0,-952.36218)">
|
||||
<path
|
||||
d="m 83,958.36218 c -1.1046,0 -2,0.89543 -2,2 l 0,7 -7,0 c -1.10457,0 -2,0.8954 -2,2 0,1.1046 0.89543,2 2,2 l 7,0 0,7 c 0,1.10457 0.8954,2 2,2 1.1046,0 2,-0.89543 2,-2 l 0,-7 7,0 c 1.10457,0 2,-0.8954 2,-2 0,-1.1046 -0.89543,-2 -2,-2 l -7,0 0,-7 c 0,-1.10457 -0.8954,-2 -2,-2 z m -48,22 c -0.78068,0.007 -1.3909,0.40265 -1.71875,0.96875 l -6.4375,11.03125 -12.84375,0 c -4.3973999,0 -8,3.6026 -8,8.00002 l 0,38 c 0,4.3974 3.6026001,8 8,8 l 62,0 c 4.3974,0 8,-3.6026 8,-8 l 0,-38 c 0,-4.39742 -3.6026,-8.00002 -8,-8.00002 l -12.84375,0 -6.4375,-11.03125 C 56.3641,980.74168 55.68774,980.36046 55,980.36218 l -20,0 z m 1.125,4 17.75,0 6.40625,11 c 0.34687,0.60075 1.02507,0.99534 1.71875,1 l 14,0 c 2.25056,0 4,1.74944 4,4.00002 l 0,38 c 0,2.2505 -1.74944,4 -4,4 l -62,0 c -2.25056,0 -4,-1.7495 -4,-4 l 0,-38 c 0,-2.25058 1.74944,-4.00002 4,-4.00002 l 14,0 c 0.69368,-0.005 1.37188,-0.39925 1.71875,-1 l 6.40625,-11 z M 45,1002.3622 c -8.81287,0 -16,7.1871 -16,16 0,8.8128 7.18713,16 16,16 8.81286,0 16,-7.1872 16,-16 0,-8.8129 -7.18714,-16 -16,-16 z m 0,4 c 6.6511,0 12,5.3489 12,12 0,6.6511 -5.3489,12 -12,12 -6.65111,0 -12,-5.3489 -12,-12 0,-6.6511 5.34889,-12 12,-12 z"
|
||||
fill={color}
|
||||
fillOpacity="1"
|
||||
stroke="none"
|
||||
marker="none"
|
||||
visibility="visible"
|
||||
display="inline"
|
||||
overflow="visible"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
import React, {Fragment} from 'react';
|
||||
|
||||
export default ({width, height, color, padding, margin}) => (
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 100 100"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
>
|
||||
<g stroke="none" strokeWidth="1" fillRule="evenodd">
|
||||
<g>
|
||||
<path d="M32,23.004355 L32,23.004355 L32,48.995645 C32,58.9442689 40.056121,67 50,67 C59.942622,67 68,58.9403509 68,48.995645 L68,23.004355 C68,13.0557311 59.943879,5 50,5 C40.057378,5 32,13.0596491 32,23.004355 L32,23.004355 Z M28,23.004355 C28,10.8516853 37.847064,1 50,1 C62.1502645,1 72,10.8438387 72,23.004355 L72,48.995645 C72,61.1483147 62.152936,71 50,71 C37.8497355,71 28,61.1561613 28,48.995645 L28,23.004355 L28,23.004355 Z" />
|
||||
<path d="M48,17.0085302 C48,15.8992496 48.8877296,15 50,15 C51.1045695,15 52,15.9019504 52,17.0085302 L52,24.9914698 C52,26.1007504 51.1122704,27 50,27 C48.8954305,27 48,26.0980496 48,24.9914698 L48,17.0085302 Z" />
|
||||
<path d="M50,95.1715729 L58.5857864,86.5857864 C59.366835,85.8047379 60.633165,85.8047379 61.4142136,86.5857864 C62.1952621,87.366835 62.1952621,88.633165 61.4142136,89.4142136 L51.4142136,99.4142136 C51.0236893,99.8047379 50.5118446,100 50,100 C49.4881554,100 48.9763107,99.8047379 48.5857864,99.4142136 L38.5857864,89.4142136 C37.8047379,88.633165 37.8047379,87.366835 38.5857864,86.5857864 C39.366835,85.8047379 40.633165,85.8047379 41.4142136,86.5857864 L50,95.1715729 Z" />
|
||||
<path d="M50,82.1715729 L58.5857864,73.5857864 C59.366835,72.8047379 60.633165,72.8047379 61.4142136,73.5857864 C62.1952621,74.366835 62.1952621,75.633165 61.4142136,76.4142136 L51.4142136,86.4142136 C51.0236893,86.8047379 50.5118446,87 50,87 C49.4881554,87 48.9763107,86.8047379 48.5857864,86.4142136 L38.5857864,76.4142136 C37.8047379,75.633165 37.8047379,74.366835 38.5857864,73.5857864 C39.366835,72.8047379 40.633165,72.8047379 41.4142136,73.5857864 L50,82.1715729 Z" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</Fragment>
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 100 100"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
>
|
||||
<g stroke="none" strokeWidth="1" fillRule="evenodd">
|
||||
<g>
|
||||
<path d="M32,23.004355 L32,23.004355 L32,48.995645 C32,58.9442689 40.056121,67 50,67 C59.942622,67 68,58.9403509 68,48.995645 L68,23.004355 C68,13.0557311 59.943879,5 50,5 C40.057378,5 32,13.0596491 32,23.004355 L32,23.004355 Z M28,23.004355 C28,10.8516853 37.847064,1 50,1 C62.1502645,1 72,10.8438387 72,23.004355 L72,48.995645 C72,61.1483147 62.152936,71 50,71 C37.8497355,71 28,61.1561613 28,48.995645 L28,23.004355 L28,23.004355 Z" />
|
||||
<path d="M48,17.0085302 C48,15.8992496 48.8877296,15 50,15 C51.1045695,15 52,15.9019504 52,17.0085302 L52,24.9914698 C52,26.1007504 51.1122704,27 50,27 C48.8954305,27 48,26.0980496 48,24.9914698 L48,17.0085302 Z" />
|
||||
<path d="M50,95.1715729 L58.5857864,86.5857864 C59.366835,85.8047379 60.633165,85.8047379 61.4142136,86.5857864 C62.1952621,87.366835 62.1952621,88.633165 61.4142136,89.4142136 L51.4142136,99.4142136 C51.0236893,99.8047379 50.5118446,100 50,100 C49.4881554,100 48.9763107,99.8047379 48.5857864,99.4142136 L38.5857864,89.4142136 C37.8047379,88.633165 37.8047379,87.366835 38.5857864,86.5857864 C39.366835,85.8047379 40.633165,85.8047379 41.4142136,86.5857864 L50,95.1715729 Z" />
|
||||
<path d="M50,82.1715729 L58.5857864,73.5857864 C59.366835,72.8047379 60.633165,72.8047379 61.4142136,73.5857864 C62.1952621,74.366835 62.1952621,75.633165 61.4142136,76.4142136 L51.4142136,86.4142136 C51.0236893,86.8047379 50.5118446,87 50,87 C49.4881554,87 48.9763107,86.8047379 48.5857864,86.4142136 L38.5857864,76.4142136 C37.8047379,75.633165 37.8047379,74.366835 38.5857864,73.5857864 C39.366835,72.8047379 40.633165,72.8047379 41.4142136,73.5857864 L50,82.1715729 Z" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
import React, {Fragment} from 'react';
|
||||
|
||||
export default ({width, height, color, padding, margin}) => (
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 100 100"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
>
|
||||
<g stroke="none" strokeWidth="1" fillRule="evenodd">
|
||||
<g>
|
||||
<path d="M42,21c0.5,0,1-0.2,1.4-0.6l6.6-6.6l6.6,6.6C57,20.8,57.5,21,58,21s1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8l-8-8 c-0.8-0.8-2-0.8-2.8,0l-8,8c-0.8,0.8-0.8,2,0,2.8C41,20.8,41.5,21,42,21z" />
|
||||
<path d="M40.6,31.4C41,31.8,41.5,32,42,32s1-0.2,1.4-0.6l6.6-6.6l6.6,6.6C57,31.8,57.5,32,58,32s1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8 l-8-8c-0.8-0.8-2-0.8-2.8,0l-8,8C39.8,29.4,39.8,30.6,40.6,31.4z" />
|
||||
<path d="M50,37c-9.9,0-18,8.1-18,18v18c0,9.9,8.1,18,18,18s18-8.1,18-18V55C68,45.1,59.9,37,50,37z M64,73c0,7.7-6.3,14-14,14 s-14-6.3-14-14V55c0-7.7,6.3-14,14-14s14,6.3,14,14V73z" />
|
||||
<path d="M50,48c-1.1,0-2,0.9-2,2v6c0,1.1,0.9,2,2,2s2-0.9,2-2v-6C52,48.9,51.1,48,50,48z" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</Fragment>
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 100 100"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
>
|
||||
<g stroke="none" strokeWidth="1" fillRule="evenodd">
|
||||
<g>
|
||||
<path d="M42,21c0.5,0,1-0.2,1.4-0.6l6.6-6.6l6.6,6.6C57,20.8,57.5,21,58,21s1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8l-8-8 c-0.8-0.8-2-0.8-2.8,0l-8,8c-0.8,0.8-0.8,2,0,2.8C41,20.8,41.5,21,42,21z" />
|
||||
<path d="M40.6,31.4C41,31.8,41.5,32,42,32s1-0.2,1.4-0.6l6.6-6.6l6.6,6.6C57,31.8,57.5,32,58,32s1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8 l-8-8c-0.8-0.8-2-0.8-2.8,0l-8,8C39.8,29.4,39.8,30.6,40.6,31.4z" />
|
||||
<path d="M50,37c-9.9,0-18,8.1-18,18v18c0,9.9,8.1,18,18,18s18-8.1,18-18V55C68,45.1,59.9,37,50,37z M64,73c0,7.7-6.3,14-14,14 s-14-6.3-14-14V55c0-7.7,6.3-14,14-14s14,6.3,14,14V73z" />
|
||||
<path d="M50,48c-1.1,0-2,0.9-2,2v6c0,1.1,0.9,2,2,2s2-0.9,2-2v-6C52,48.9,51.1,48,50,48z" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
|
@ -2,33 +2,37 @@ import React, {Fragment} from 'react';
|
|||
import styles from './styles.css';
|
||||
|
||||
export default ({width, height, color = '#ffffff80', padding}) => (
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
className={styles.iconCheck}
|
||||
viewBox="0 0 225 225"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
xmlSpace="preserve"
|
||||
>
|
||||
<g transform="matrix(1,0,0,1,-178.667,-170.667)">
|
||||
<g className={styles.check} transform="matrix(1,0,0,1,176,113)">
|
||||
<path
|
||||
d="M65,166L101,202L165,138"
|
||||
style={{fill: 'none', stroke: color, strokeWidth: 16.67}}
|
||||
/>
|
||||
</g>
|
||||
<circle
|
||||
className={styles.circle}
|
||||
cx="291"
|
||||
cy="283"
|
||||
r="104"
|
||||
style={{stroke: color}}
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</Fragment>
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
className={styles.iconCheck}
|
||||
viewBox="0 0 225 225"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
xmlSpace="preserve"
|
||||
>
|
||||
<g transform="matrix(1,0,0,1,-178.667,-170.667)">
|
||||
<g className={styles.check} transform="matrix(1,0,0,1,176,113)">
|
||||
<path
|
||||
d="M65,166L101,202L165,138"
|
||||
style={{
|
||||
fill: 'none',
|
||||
stroke: color,
|
||||
strokeWidth: 16.67,
|
||||
}}
|
||||
/>
|
||||
</g>
|
||||
<circle
|
||||
className={styles.circle}
|
||||
cx="291"
|
||||
cy="283"
|
||||
r="104"
|
||||
style={{stroke: color}}
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
import React, {Fragment} from 'react';
|
||||
|
||||
export default ({width, height, color, padding, margin}) => (
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 100 100"
|
||||
enableBackground="new 0 0 100 100"
|
||||
xmlSpace="preserve"
|
||||
>
|
||||
<g>
|
||||
<g>
|
||||
<path d="M79.859,20.143c-0.778-0.777-2.037-0.777-2.815,0l-9.222,9.223c-1.901-1.334-4.156-2.061-6.527-2.061 c-3.046,0-5.909,1.186-8.061,3.34l-5.621,5.619c-0.374,0.373-0.583,0.879-0.583,1.406s0.209,1.035,0.583,1.408l13.308,13.309 c0.39,0.389,0.898,0.582,1.408,0.582c0.509,0,1.019-0.193,1.407-0.582l5.621-5.619c3.962-3.965,4.38-10.141,1.275-14.584 l9.227-9.227C80.637,22.18,80.637,20.92,79.859,20.143z M66.543,43.953l-4.214,4.211L51.835,37.67l4.215-4.211 c1.4-1.402,3.264-2.174,5.245-2.174c1.982,0,3.846,0.773,5.248,2.174C69.434,36.354,69.434,41.059,66.543,43.953z" />
|
||||
<path d="M51.213,52.229l-4.352,4.352l-3.441-3.44l4.351-4.351c0.778-0.777,0.778-2.037,0-2.814c-0.777-0.777-2.036-0.777-2.814,0 l-4.351,4.351l-2.12-2.12c-0.777-0.777-2.037-0.777-2.814,0l-5.619,5.619c-3.964,3.965-4.383,10.141-1.276,14.585l-8.635,8.634 c-0.777,0.777-0.777,2.037,0,2.814c0.389,0.389,0.898,0.584,1.407,0.584c0.51,0,1.019-0.195,1.408-0.584l8.632-8.631 c1.9,1.334,4.154,2.061,6.525,2.061c3.045,0,5.907-1.186,8.062-3.34l5.619-5.619c0.777-0.777,0.777-2.037,0-2.814l-2.118-2.119 l4.352-4.352c0.777-0.777,0.777-2.037,0-2.814S51.99,51.451,51.213,52.229z M43.36,67.133c-1.402,1.4-3.266,2.174-5.247,2.174 s-3.845-0.773-5.247-2.174c-2.893-2.893-2.893-7.6,0-10.494l4.211-4.211l10.494,10.494L43.36,67.133z" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</Fragment>
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 100 100"
|
||||
enableBackground="new 0 0 100 100"
|
||||
xmlSpace="preserve"
|
||||
>
|
||||
<g>
|
||||
<g>
|
||||
<path d="M79.859,20.143c-0.778-0.777-2.037-0.777-2.815,0l-9.222,9.223c-1.901-1.334-4.156-2.061-6.527-2.061 c-3.046,0-5.909,1.186-8.061,3.34l-5.621,5.619c-0.374,0.373-0.583,0.879-0.583,1.406s0.209,1.035,0.583,1.408l13.308,13.309 c0.39,0.389,0.898,0.582,1.408,0.582c0.509,0,1.019-0.193,1.407-0.582l5.621-5.619c3.962-3.965,4.38-10.141,1.275-14.584 l9.227-9.227C80.637,22.18,80.637,20.92,79.859,20.143z M66.543,43.953l-4.214,4.211L51.835,37.67l4.215-4.211 c1.4-1.402,3.264-2.174,5.245-2.174c1.982,0,3.846,0.773,5.248,2.174C69.434,36.354,69.434,41.059,66.543,43.953z" />
|
||||
<path d="M51.213,52.229l-4.352,4.352l-3.441-3.44l4.351-4.351c0.778-0.777,0.778-2.037,0-2.814c-0.777-0.777-2.036-0.777-2.814,0 l-4.351,4.351l-2.12-2.12c-0.777-0.777-2.037-0.777-2.814,0l-5.619,5.619c-3.964,3.965-4.383,10.141-1.276,14.585l-8.635,8.634 c-0.777,0.777-0.777,2.037,0,2.814c0.389,0.389,0.898,0.584,1.407,0.584c0.51,0,1.019-0.195,1.408-0.584l8.632-8.631 c1.9,1.334,4.154,2.061,6.525,2.061c3.045,0,5.907-1.186,8.062-3.34l5.619-5.619c0.777-0.777,0.777-2.037,0-2.814l-2.118-2.119 l4.352-4.352c0.777-0.777,0.777-2.037,0-2.814S51.99,51.451,51.213,52.229z M43.36,67.133c-1.402,1.4-3.266,2.174-5.247,2.174 s-3.845-0.773-5.247-2.174c-2.893-2.893-2.893-7.6,0-10.494l4.211-4.211l10.494,10.494L43.36,67.133z" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
import React, {Fragment} from 'react';
|
||||
|
||||
export default ({width, height, color, padding, margin}) => (
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 88 88"
|
||||
>
|
||||
<path d="m0 12.402 35.687-4.8602.0156 34.423-35.67.20313zm35.67 33.529.0277 34.453-35.67-4.9041-.002-29.78zm4.3261-39.025 47.318-6.906v41.527l-47.318.37565zm47.329 39.349-.0111 41.34-47.318-6.6784-.0663-34.739z" />
|
||||
</svg>
|
||||
</Fragment>
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 88 88"
|
||||
>
|
||||
<path d="m0 12.402 35.687-4.8602.0156 34.423-35.67.20313zm35.67 33.529.0277 34.453-35.67-4.9041-.002-29.78zm4.3261-39.025 47.318-6.906v41.527l-47.318.37565zm47.329 39.349-.0111 41.34-47.318-6.6784-.0663-34.739z" />
|
||||
</svg>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
import React, {Fragment} from 'react';
|
||||
|
||||
export default ({width, height, color, padding, margin}) => (
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 100 100"
|
||||
enableBackground="new 0 0 100 100"
|
||||
>
|
||||
<g>
|
||||
<path d="M91.414,88.586L70.815,67.987C76.522,61.614,80,53.207,80,44C80,24.149,63.851,8,44,8S8,24.149,8,44 s16.149,36,36,36c9.207,0,17.614-3.478,23.987-9.185l20.599,20.599C88.977,91.805,89.488,92,90,92s1.023-0.195,1.414-0.586 C92.195,90.633,92.195,89.367,91.414,88.586z M44,76c-17.645,0-32-14.355-32-32s14.355-32,32-32s32,14.355,32,32S61.645,76,44,76z" />
|
||||
<path d="M62,42H46V26c0-1.104-0.896-2-2-2s-2,0.896-2,2v16H26c-1.104,0-2,0.896-2,2s0.896,2,2,2h16v16 c0,1.104,0.896,2,2,2s2-0.896,2-2V46h16c1.104,0,2-0.896,2-2S63.104,42,62,42z" />
|
||||
</g>
|
||||
</svg>
|
||||
</Fragment>
|
||||
<Fragment>
|
||||
<svg
|
||||
height={height}
|
||||
width={width}
|
||||
fill={color}
|
||||
style={{padding, margin}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 100 100"
|
||||
enableBackground="new 0 0 100 100"
|
||||
>
|
||||
<g>
|
||||
<path d="M91.414,88.586L70.815,67.987C76.522,61.614,80,53.207,80,44C80,24.149,63.851,8,44,8S8,24.149,8,44 s16.149,36,36,36c9.207,0,17.614-3.478,23.987-9.185l20.599,20.599C88.977,91.805,89.488,92,90,92s1.023-0.195,1.414-0.586 C92.195,90.633,92.195,89.367,91.414,88.586z M44,76c-17.645,0-32-14.355-32-32s14.355-32,32-32s32,14.355,32,32S61.645,76,44,76z" />
|
||||
<path d="M62,42H46V26c0-1.104-0.896-2-2-2s-2,0.896-2,2v16H26c-1.104,0-2,0.896-2,2s0.896,2,2,2h16v16 c0,1.104,0.896,2,2,2s2-0.896,2-2V46h16c1.104,0,2-0.896,2-2S63.104,42,62,42z" />
|
||||
</g>
|
||||
</svg>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -2,21 +2,21 @@
|
|||
import chromeEmulatedDevices from './chromeEmulatedDevices';
|
||||
|
||||
export const OS: {[key: string]: OS} = {
|
||||
ios: 'iOS',
|
||||
android: 'Android',
|
||||
windowsPhone: 'Windows Phone',
|
||||
pc: 'PC',
|
||||
ios: 'iOS',
|
||||
android: 'Android',
|
||||
windowsPhone: 'Windows Phone',
|
||||
pc: 'PC',
|
||||
};
|
||||
|
||||
export const DEVICE_TYPE: {[key: string]: DeviceType} = {
|
||||
phone: 'phone',
|
||||
tablet: 'tablet',
|
||||
desktop: 'notebook',
|
||||
phone: 'phone',
|
||||
tablet: 'tablet',
|
||||
desktop: 'notebook',
|
||||
};
|
||||
|
||||
export const CAPABILITIES: {[key: string]: Capability} = {
|
||||
mobile: 'mobile',
|
||||
touch: 'touch',
|
||||
mobile: 'mobile',
|
||||
touch: 'touch',
|
||||
};
|
||||
|
||||
type OSType = OS.ios | OS.android | OS.windowsPhone | OS.pc;
|
||||
|
@ -26,49 +26,49 @@ type DeviceType = DEVICE_TYPE.phone | DEVICE_TYPE.tablet | DEVICE_TYPE.desktop;
|
|||
type Capability = CAPABILITIES.mobile | CAPABILITIES.touch;
|
||||
|
||||
export type Device = {
|
||||
id: number,
|
||||
added: boolean,
|
||||
width: number,
|
||||
height: number,
|
||||
name: string,
|
||||
useragent: string,
|
||||
capabilities: Array<Capability>,
|
||||
os: OSType,
|
||||
type: DeviceType,
|
||||
id: number,
|
||||
added: boolean,
|
||||
width: number,
|
||||
height: number,
|
||||
name: string,
|
||||
useragent: string,
|
||||
capabilities: Array<Capability>,
|
||||
os: OSType,
|
||||
type: DeviceType,
|
||||
};
|
||||
|
||||
function getOS(device) {
|
||||
if (device.capabilities.indexOf('mobile') > -1) {
|
||||
const useragent = device['user-agent'];
|
||||
if (useragent.indexOf('like Mac OS X') > -1) {
|
||||
return OS.ios;
|
||||
if (device.capabilities.indexOf('mobile') > -1) {
|
||||
const useragent = device['user-agent'];
|
||||
if (useragent.indexOf('like Mac OS X') > -1) {
|
||||
return OS.ios;
|
||||
}
|
||||
if (useragent.indexOf('Lumia') > -1) {
|
||||
return OS.windowsPhone;
|
||||
}
|
||||
return OS.android;
|
||||
}
|
||||
if (useragent.indexOf('Lumia') > -1) {
|
||||
return OS.windowsPhone;
|
||||
}
|
||||
return OS.android;
|
||||
}
|
||||
return OS.pc;
|
||||
return OS.pc;
|
||||
}
|
||||
|
||||
let idGen = 1;
|
||||
export default chromeEmulatedDevices.extensions
|
||||
.sort((a, b) => a.order - b.order)
|
||||
.map(({order, device}) => {
|
||||
const dimension =
|
||||
device.type === DEVICE_TYPE.desktop
|
||||
? device.screen.horizontal
|
||||
: device.screen.vertical;
|
||||
.sort((a, b) => a.order - b.order)
|
||||
.map(({order, device}) => {
|
||||
const dimension =
|
||||
device.type === DEVICE_TYPE.desktop
|
||||
? device.screen.horizontal
|
||||
: device.screen.vertical;
|
||||
|
||||
return {
|
||||
id: idGen++,
|
||||
name: device.title,
|
||||
width: dimension.width,
|
||||
height: dimension.height,
|
||||
useragent: device['user-agent'],
|
||||
capabilities: device.capabilities,
|
||||
added: device['show-by-default'],
|
||||
os: getOS(device),
|
||||
type: device.type,
|
||||
};
|
||||
});
|
||||
return {
|
||||
id: idGen++,
|
||||
name: device.title,
|
||||
width: dimension.width,
|
||||
height: dimension.height,
|
||||
useragent: device['user-agent'],
|
||||
capabilities: device.capabilities,
|
||||
added: device['show-by-default'],
|
||||
os: getOS(device),
|
||||
type: device.type,
|
||||
};
|
||||
});
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
export const DEACTIVATION_REASON = {
|
||||
REVALIDATION: 'REVALIDATION',
|
||||
REVALIDATION: 'REVALIDATION',
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export default {
|
||||
HOME: '/',
|
||||
COUNTER: '/counter',
|
||||
HOME: '/',
|
||||
COUNTER: '/counter',
|
||||
};
|
||||
|
|
|
@ -7,16 +7,16 @@ import AddDevice from '../../components/DeviceManager/AddDevice';
|
|||
import * as BrowserActions from '../../actions/browser';
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
browser: state.browser,
|
||||
};
|
||||
return {
|
||||
browser: state.browser,
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(AddDevice);
|
||||
|
|
|
@ -7,27 +7,27 @@ import AddressInput from '../../components/Addressinput';
|
|||
import * as BrowserActions from '../../actions/browser';
|
||||
|
||||
const AddressBar = function(props) {
|
||||
return (
|
||||
<AddressInput
|
||||
address={props.browser.address}
|
||||
onChange={props.onAddressChange}
|
||||
homepage={props.browser.homepage}
|
||||
setHomepage={props.setCurrentAddressAsHomepage}
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<AddressInput
|
||||
address={props.browser.address}
|
||||
onChange={props.onAddressChange}
|
||||
homepage={props.browser.homepage}
|
||||
setHomepage={props.setCurrentAddressAsHomepage}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
browser: state.browser,
|
||||
};
|
||||
return {
|
||||
browser: state.browser,
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(AddressBar);
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
import * as React from 'react';
|
||||
|
||||
type Props = {
|
||||
children: React.Node
|
||||
children: React.Node,
|
||||
};
|
||||
|
||||
export default class App extends React.Component<Props> {
|
||||
props: Props;
|
||||
props: Props;
|
||||
|
||||
render() {
|
||||
const { children } = this.props;
|
||||
return <React.Fragment>{children}</React.Fragment>;
|
||||
}
|
||||
render() {
|
||||
const {children} = this.props;
|
||||
return <React.Fragment>{children}</React.Fragment>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,32 +11,38 @@ import Grid from '@material-ui/core/Grid';
|
|||
type Props = {};
|
||||
|
||||
class Browser extends React.Component<Props> {
|
||||
props: Props;
|
||||
props: Props;
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Fragment>
|
||||
<Header />
|
||||
<div style={{display: 'flex', flexDirection: 'row', height: '100%'}}>
|
||||
<DrawerContainer />
|
||||
<DevicePreviewerContainer />
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<Fragment>
|
||||
<Header />
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
height: '100%',
|
||||
}}
|
||||
>
|
||||
<DrawerContainer />
|
||||
<DevicePreviewerContainer />
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
browser: state.browser,
|
||||
};
|
||||
return {
|
||||
browser: state.browser,
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Browser);
|
||||
|
|
|
@ -7,16 +7,16 @@ import DeviceDrawer from '../../components/DeviceDrawer';
|
|||
import * as BrowserActions from '../../actions/browser';
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
browser: state.browser,
|
||||
};
|
||||
return {
|
||||
browser: state.browser,
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(DeviceDrawer);
|
||||
|
|
|
@ -7,16 +7,16 @@ import DeviceManager from '../../components/DeviceManager';
|
|||
import * as BrowserActions from '../../actions/browser';
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
browser: state.browser,
|
||||
};
|
||||
return {
|
||||
browser: state.browser,
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(DeviceManager);
|
||||
|
|
|
@ -6,16 +6,16 @@ import DevicesPreviewer from '../../components/DevicesPreviewer';
|
|||
import * as BrowserActions from '../../actions/browser';
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
browser: state.browser,
|
||||
};
|
||||
return {
|
||||
browser: state.browser,
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(DevicesPreviewer);
|
||||
|
|
|
@ -7,16 +7,16 @@ import DevicesOverview from '../../components/DevicesOverview';
|
|||
import * as BrowserActions from '../../actions/browser';
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
browser: state.browser,
|
||||
};
|
||||
return {
|
||||
browser: state.browser,
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(DevicesOverview);
|
||||
|
|
|
@ -7,16 +7,16 @@ import Drawer from '../../components/Drawer';
|
|||
import * as BrowserActions from '../../actions/browser';
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
drawer: state.browser.drawer,
|
||||
};
|
||||
return {
|
||||
drawer: state.browser.drawer,
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Drawer);
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
// @flow
|
||||
import React, { Component } from 'react';
|
||||
import React, {Component} from 'react';
|
||||
import Home from '../components/Home';
|
||||
|
||||
type Props = {};
|
||||
|
||||
export default class HomePage extends Component<Props> {
|
||||
props: Props;
|
||||
props: Props;
|
||||
|
||||
render() {
|
||||
return <Home />;
|
||||
}
|
||||
render() {
|
||||
return <Home />;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,16 +7,16 @@ import LeftIconsPane from '../../components/LeftIconsPane';
|
|||
import * as BrowserActions from '../../actions/browser';
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
drawer: state.browser.drawer,
|
||||
};
|
||||
return {
|
||||
drawer: state.browser.drawer,
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(LeftIconsPane);
|
||||
|
|
|
@ -7,17 +7,17 @@ import * as BrowserActions from '../../actions/browser';
|
|||
import NavigationControls from '../../components/NavigationControls';
|
||||
|
||||
function mapStateToProps(state) {
|
||||
const {
|
||||
navigatorStatus: {backEnabled, forwardEnabled},
|
||||
} = state.browser;
|
||||
return {backEnabled, forwardEnabled};
|
||||
const {
|
||||
navigatorStatus: {backEnabled, forwardEnabled},
|
||||
} = state.browser;
|
||||
return {backEnabled, forwardEnabled};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(NavigationControls);
|
||||
|
|
|
@ -7,16 +7,16 @@ import QuickFilterDevices from '../../components/QuickFilterDevices';
|
|||
import * as BrowserActions from '../../actions/browser';
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
browser: state.browser,
|
||||
};
|
||||
return {
|
||||
browser: state.browser,
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(QuickFilterDevices);
|
||||
|
|
|
@ -12,53 +12,53 @@ import {themeColor} from '../constants/colors';
|
|||
import ErrorBoundary from '../components/ErrorBoundary';
|
||||
|
||||
type Props = {
|
||||
store: Store,
|
||||
history: {},
|
||||
store: Store,
|
||||
history: {},
|
||||
};
|
||||
|
||||
const theme = createMuiTheme({
|
||||
palette: {
|
||||
type: 'dark',
|
||||
primary: {
|
||||
main: themeColor,
|
||||
palette: {
|
||||
type: 'dark',
|
||||
primary: {
|
||||
main: themeColor,
|
||||
},
|
||||
secondary: {
|
||||
main: '#424242',
|
||||
},
|
||||
ternary: {
|
||||
main: '#C4C5CE',
|
||||
},
|
||||
divider: grey[500],
|
||||
background: {
|
||||
main: '#252526',
|
||||
},
|
||||
},
|
||||
secondary: {
|
||||
main: '#424242',
|
||||
},
|
||||
ternary: {
|
||||
main: '#C4C5CE',
|
||||
},
|
||||
divider: grey[500],
|
||||
background: {
|
||||
main: '#252526',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const getApp = history => {
|
||||
if (true || process.env.NODE_ENV !== 'development') {
|
||||
if (true || process.env.NODE_ENV !== 'development') {
|
||||
return (
|
||||
<ErrorBoundary>
|
||||
<ConnectedRouter history={history}>
|
||||
<Routes />
|
||||
</ConnectedRouter>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<ErrorBoundary>
|
||||
<ConnectedRouter history={history}>
|
||||
<Routes />
|
||||
<Routes />
|
||||
</ConnectedRouter>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<ConnectedRouter history={history}>
|
||||
<Routes />
|
||||
</ConnectedRouter>
|
||||
);
|
||||
};
|
||||
|
||||
export default class Root extends Component<Props> {
|
||||
render() {
|
||||
const {store, history} = this.props;
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<ThemeProvider theme={theme}>{getApp(history)}</ThemeProvider>
|
||||
</Provider>
|
||||
);
|
||||
}
|
||||
render() {
|
||||
const {store, history} = this.props;
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<ThemeProvider theme={theme}>{getApp(history)}</ThemeProvider>
|
||||
</Provider>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,16 +7,16 @@ import ScrollControls from '../../components/ScrollControls';
|
|||
import * as BrowserActions from '../../actions/browser';
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
browser: state.browser,
|
||||
};
|
||||
return {
|
||||
browser: state.browser,
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(ScrollControls);
|
||||
|
|
|
@ -6,16 +6,16 @@ import WebView from '../../components/WebView';
|
|||
import * as BrowserActions from '../../actions/browser';
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
browser: state.browser,
|
||||
};
|
||||
return {
|
||||
browser: state.browser,
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(WebView);
|
||||
|
|
|
@ -7,16 +7,16 @@ import ZoomInput from '../../components/ZoomInput';
|
|||
import * as BrowserActions from '../../actions/browser';
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
browser: state.browser,
|
||||
};
|
||||
return {
|
||||
browser: state.browser,
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
return bindActionCreators(BrowserActions, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(ZoomInput);
|
||||
|
|
|
@ -10,52 +10,55 @@ const fs = require('fs-extra');
|
|||
const tempDir = path.join(os.tmpdir(), UUID());
|
||||
|
||||
registerPromiseWorker(({images, direction, resultFilename}) => {
|
||||
if (direction === 'horizontal') {
|
||||
return stitchHorizontally(images);
|
||||
}
|
||||
return stitchVertically(images, resultFilename);
|
||||
if (direction === 'horizontal') {
|
||||
return stitchHorizontally(images);
|
||||
}
|
||||
return stitchVertically(images, resultFilename);
|
||||
});
|
||||
|
||||
async function stitchHorizontally(images) {
|
||||
const result = await mergeImg(images.map(img => ({src: Buffer.from(img)})), {
|
||||
direction: false,
|
||||
});
|
||||
const tempPath = await writeToTempFile(result);
|
||||
return tempPath;
|
||||
const result = await mergeImg(
|
||||
images.map(img => ({src: Buffer.from(img)})),
|
||||
{
|
||||
direction: false,
|
||||
}
|
||||
);
|
||||
const tempPath = await writeToTempFile(result);
|
||||
return tempPath;
|
||||
}
|
||||
|
||||
async function writeToTempFile(image) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
await fs.ensureDir(tempDir);
|
||||
const tempPath = path.join(tempDir, `${UUID()}.png`);
|
||||
await image.write(tempPath, err => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
return resolve(tempPath);
|
||||
return new Promise(async (resolve, reject) => {
|
||||
await fs.ensureDir(tempDir);
|
||||
const tempPath = path.join(tempDir, `${UUID()}.png`);
|
||||
await image.write(tempPath, err => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
return resolve(tempPath);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function stitchVertically(images, {dir, file}) {
|
||||
const result = (await mergeImg(
|
||||
await Promise.all(
|
||||
images.map(async img => {
|
||||
const JimpImg = await Jimp.read(img);
|
||||
return {
|
||||
src: await JimpImg.getBufferAsync('image/png'),
|
||||
};
|
||||
})
|
||||
),
|
||||
{
|
||||
direction: true,
|
||||
}
|
||||
))
|
||||
.rgba(false)
|
||||
.background(0xffffffff);
|
||||
await fs.ensureDir(dir);
|
||||
await Promise.all([
|
||||
result.write(path.join(dir, file)),
|
||||
...images.map(image => fs.remove(image)),
|
||||
]);
|
||||
const result = (await mergeImg(
|
||||
await Promise.all(
|
||||
images.map(async img => {
|
||||
const JimpImg = await Jimp.read(img);
|
||||
return {
|
||||
src: await JimpImg.getBufferAsync('image/png'),
|
||||
};
|
||||
})
|
||||
),
|
||||
{
|
||||
direction: true,
|
||||
}
|
||||
))
|
||||
.rgba(false)
|
||||
.background(0xffffffff);
|
||||
await fs.ensureDir(dir);
|
||||
await Promise.all([
|
||||
result.write(path.join(dir, file)),
|
||||
...images.map(image => fs.remove(image)),
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -9,29 +9,29 @@ import './app.global.css';
|
|||
import * as Sentry from '@sentry/electron';
|
||||
|
||||
if (remote.getGlobal('process').env.NODE_ENV !== 'development') {
|
||||
Sentry.init({
|
||||
dsn: 'https://f2cdbc6a88aa4a068a738d4e4cfd3e12@sentry.io/1553155',
|
||||
environment: remote.getGlobal('process').env.NODE_ENV,
|
||||
});
|
||||
Sentry.init({
|
||||
dsn: 'https://f2cdbc6a88aa4a068a738d4e4cfd3e12@sentry.io/1553155',
|
||||
environment: remote.getGlobal('process').env.NODE_ENV,
|
||||
});
|
||||
}
|
||||
const store = configureStore();
|
||||
|
||||
render(
|
||||
<AppContainer>
|
||||
<Root store={store} history={history} />
|
||||
</AppContainer>,
|
||||
document.getElementById('root')
|
||||
<AppContainer>
|
||||
<Root store={store} history={history} />
|
||||
</AppContainer>,
|
||||
document.getElementById('root')
|
||||
);
|
||||
|
||||
if (module.hot) {
|
||||
module.hot.accept('./containers/Root', () => {
|
||||
// eslint-disable-next-line global-require
|
||||
const NextRoot = require('./containers/Root').default;
|
||||
render(
|
||||
<AppContainer>
|
||||
<NextRoot store={store} history={history} />
|
||||
</AppContainer>,
|
||||
document.getElementById('root')
|
||||
);
|
||||
});
|
||||
module.hot.accept('./containers/Root', () => {
|
||||
// eslint-disable-next-line global-require
|
||||
const NextRoot = require('./containers/Root').default;
|
||||
render(
|
||||
<AppContainer>
|
||||
<NextRoot store={store} history={history} />
|
||||
</AppContainer>,
|
||||
document.getElementById('root')
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -19,20 +19,20 @@ import MenuBuilder from './menu';
|
|||
import {ACTIVE_DEVICES} from './constants/settingKeys';
|
||||
import * as Sentry from '@sentry/electron';
|
||||
|
||||
const path = require('path')
|
||||
const path = require('path');
|
||||
|
||||
if (process.env.NODE_ENV !== 'development') {
|
||||
Sentry.init({
|
||||
dsn: 'https://f2cdbc6a88aa4a068a738d4e4cfd3e12@sentry.io/1553155',
|
||||
});
|
||||
Sentry.init({
|
||||
dsn: 'https://f2cdbc6a88aa4a068a738d4e4cfd3e12@sentry.io/1553155',
|
||||
});
|
||||
}
|
||||
|
||||
export default class AppUpdater {
|
||||
constructor() {
|
||||
log.transports.file.level = 'info';
|
||||
autoUpdater.logger = log;
|
||||
autoUpdater.checkForUpdatesAndNotify();
|
||||
}
|
||||
constructor() {
|
||||
log.transports.file.level = 'info';
|
||||
autoUpdater.logger = log;
|
||||
autoUpdater.checkForUpdatesAndNotify();
|
||||
}
|
||||
}
|
||||
|
||||
let mainWindow = null;
|
||||
|
@ -40,25 +40,27 @@ let mainWindow = null;
|
|||
let httpAuthCallbacks = {};
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
const sourceMapSupport = require('source-map-support');
|
||||
sourceMapSupport.install();
|
||||
const sourceMapSupport = require('source-map-support');
|
||||
sourceMapSupport.install();
|
||||
}
|
||||
|
||||
if (
|
||||
process.env.NODE_ENV === 'development' ||
|
||||
process.env.DEBUG_PROD === 'true'
|
||||
process.env.NODE_ENV === 'development' ||
|
||||
process.env.DEBUG_PROD === 'true'
|
||||
) {
|
||||
require('electron-debug')();
|
||||
require('electron-debug')();
|
||||
}
|
||||
|
||||
const installExtensions = async () => {
|
||||
const installer = require('electron-devtools-installer');
|
||||
const forceDownload = !!process.env.UPGRADE_EXTENSIONS;
|
||||
const extensions = ['REACT_DEVELOPER_TOOLS', 'REDUX_DEVTOOLS'];
|
||||
const installer = require('electron-devtools-installer');
|
||||
const forceDownload = !!process.env.UPGRADE_EXTENSIONS;
|
||||
const extensions = ['REACT_DEVELOPER_TOOLS', 'REDUX_DEVTOOLS'];
|
||||
|
||||
return Promise.all(
|
||||
extensions.map(name => installer.default(installer[name], forceDownload))
|
||||
).catch(console.log);
|
||||
return Promise.all(
|
||||
extensions.map(name =>
|
||||
installer.default(installer[name], forceDownload)
|
||||
)
|
||||
).catch(console.log);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -66,54 +68,54 @@ const installExtensions = async () => {
|
|||
*/
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
// Respect the OSX convention of having the application in memory even
|
||||
// after all windows have been closed
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit();
|
||||
}
|
||||
// Respect the OSX convention of having the application in memory even
|
||||
// after all windows have been closed
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
|
||||
app.on('login', (event, webContents, request, authInfo, callback) => {
|
||||
event.preventDefault();
|
||||
const {url} = request;
|
||||
console.log('Sending HTTP Auth Prompt', {url});
|
||||
if (httpAuthCallbacks[url]) {
|
||||
return httpAuthCallbacks[url].push(callback);
|
||||
}
|
||||
httpAuthCallbacks[url] = [callback];
|
||||
mainWindow.webContents.send('http-auth-prompt', {url});
|
||||
event.preventDefault();
|
||||
const {url} = request;
|
||||
console.log('Sending HTTP Auth Prompt', {url});
|
||||
if (httpAuthCallbacks[url]) {
|
||||
return httpAuthCallbacks[url].push(callback);
|
||||
}
|
||||
httpAuthCallbacks[url] = [callback];
|
||||
mainWindow.webContents.send('http-auth-prompt', {url});
|
||||
});
|
||||
|
||||
const createWindow = async () => {
|
||||
if (
|
||||
process.env.NODE_ENV === 'development' ||
|
||||
process.env.DEBUG_PROD === 'true'
|
||||
) {
|
||||
await installExtensions();
|
||||
}
|
||||
if (
|
||||
process.env.NODE_ENV === 'development' ||
|
||||
process.env.DEBUG_PROD === 'true'
|
||||
) {
|
||||
await installExtensions();
|
||||
}
|
||||
|
||||
const {width, height} = electron.screen.getPrimaryDisplay().workAreaSize;
|
||||
const {width, height} = electron.screen.getPrimaryDisplay().workAreaSize;
|
||||
|
||||
let iconPath=path.resolve(__dirname, '../resources/icons/64x64.png')
|
||||
mainWindow = new BrowserWindow({
|
||||
show: false,
|
||||
width,
|
||||
height,
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
nodeIntegrationInWorker: true,
|
||||
webviewTag: true,
|
||||
},
|
||||
titleBarStyle: 'hidden',
|
||||
icon: iconPath
|
||||
});
|
||||
let iconPath = path.resolve(__dirname, '../resources/icons/64x64.png');
|
||||
mainWindow = new BrowserWindow({
|
||||
show: false,
|
||||
width,
|
||||
height,
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
nodeIntegrationInWorker: true,
|
||||
webviewTag: true,
|
||||
},
|
||||
titleBarStyle: 'hidden',
|
||||
icon: iconPath,
|
||||
});
|
||||
|
||||
mainWindow.loadURL(`file://${__dirname}/app.html`);
|
||||
mainWindow.loadURL(`file://${__dirname}/app.html`);
|
||||
|
||||
mainWindow.webContents.on('did-finish-load', function() {
|
||||
if (process.platform === 'darwin') {
|
||||
// Trick to make the transparent title bar draggable
|
||||
mainWindow.webContents.executeJavaScript(`
|
||||
mainWindow.webContents.on('did-finish-load', function() {
|
||||
if (process.platform === 'darwin') {
|
||||
// Trick to make the transparent title bar draggable
|
||||
mainWindow.webContents.executeJavaScript(`
|
||||
var div = document.createElement("div");
|
||||
div.style.position = "absolute";
|
||||
div.style.top = 0;
|
||||
|
@ -123,42 +125,42 @@ const createWindow = async () => {
|
|||
div.style['-webkit-user-select'] = 'none';
|
||||
document.body.appendChild(div);
|
||||
`);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
mainWindow.once('ready-to-show', () => {
|
||||
mainWindow.show();
|
||||
});
|
||||
mainWindow.once('ready-to-show', () => {
|
||||
mainWindow.show();
|
||||
});
|
||||
|
||||
ipcMain.on('http-auth-promt-response', (event, ...args) => {
|
||||
if (!args[0].url) {
|
||||
return;
|
||||
}
|
||||
const {url, username, password} = args[0];
|
||||
if (!httpAuthCallbacks[url]) {
|
||||
return;
|
||||
}
|
||||
httpAuthCallbacks[url].forEach(cb => cb(username, password));
|
||||
httpAuthCallbacks[url] = null;
|
||||
});
|
||||
ipcMain.on('http-auth-promt-response', (event, ...args) => {
|
||||
if (!args[0].url) {
|
||||
return;
|
||||
}
|
||||
const {url, username, password} = args[0];
|
||||
if (!httpAuthCallbacks[url]) {
|
||||
return;
|
||||
}
|
||||
httpAuthCallbacks[url].forEach(cb => cb(username, password));
|
||||
httpAuthCallbacks[url] = null;
|
||||
});
|
||||
|
||||
mainWindow.on('closed', () => {
|
||||
mainWindow = null;
|
||||
});
|
||||
mainWindow.on('closed', () => {
|
||||
mainWindow = null;
|
||||
});
|
||||
|
||||
const menuBuilder = new MenuBuilder(mainWindow);
|
||||
menuBuilder.buildMenu();
|
||||
const menuBuilder = new MenuBuilder(mainWindow);
|
||||
menuBuilder.buildMenu();
|
||||
|
||||
// Remove this if your app does not use auto updates
|
||||
// eslint-disable-next-line
|
||||
new AppUpdater();
|
||||
// Remove this if your app does not use auto updates
|
||||
// eslint-disable-next-line
|
||||
new AppUpdater();
|
||||
};
|
||||
|
||||
app.on('activate', (event, hasVisibleWindows) => {
|
||||
if (hasVisibleWindows) {
|
||||
return;
|
||||
}
|
||||
createWindow();
|
||||
if (hasVisibleWindows) {
|
||||
return;
|
||||
}
|
||||
createWindow();
|
||||
});
|
||||
|
||||
app.on('ready', createWindow);
|
||||
|
|
|
@ -2,276 +2,304 @@
|
|||
import {app, Menu, shell, BrowserWindow} from 'electron';
|
||||
|
||||
export default class MenuBuilder {
|
||||
mainWindow: BrowserWindow;
|
||||
mainWindow: BrowserWindow;
|
||||
|
||||
constructor(mainWindow: BrowserWindow) {
|
||||
this.mainWindow = mainWindow;
|
||||
}
|
||||
|
||||
buildMenu() {
|
||||
if (
|
||||
process.env.NODE_ENV === 'development' ||
|
||||
process.env.DEBUG_PROD === 'true'
|
||||
) {
|
||||
this.setupDevelopmentEnvironment();
|
||||
constructor(mainWindow: BrowserWindow) {
|
||||
this.mainWindow = mainWindow;
|
||||
}
|
||||
|
||||
const template =
|
||||
process.platform === 'darwin'
|
||||
? this.buildDarwinTemplate()
|
||||
: this.buildDefaultTemplate();
|
||||
buildMenu() {
|
||||
if (
|
||||
process.env.NODE_ENV === 'development' ||
|
||||
process.env.DEBUG_PROD === 'true'
|
||||
) {
|
||||
this.setupDevelopmentEnvironment();
|
||||
}
|
||||
|
||||
const menu = Menu.buildFromTemplate(template);
|
||||
Menu.setApplicationMenu(menu);
|
||||
const template =
|
||||
process.platform === 'darwin'
|
||||
? this.buildDarwinTemplate()
|
||||
: this.buildDefaultTemplate();
|
||||
|
||||
return menu;
|
||||
}
|
||||
const menu = Menu.buildFromTemplate(template);
|
||||
Menu.setApplicationMenu(menu);
|
||||
|
||||
setupDevelopmentEnvironment() {
|
||||
this.mainWindow.openDevTools();
|
||||
this.mainWindow.webContents.on('context-menu', (e, props) => {
|
||||
const {x, y} = props;
|
||||
return menu;
|
||||
}
|
||||
|
||||
Menu.buildFromTemplate([
|
||||
{
|
||||
label: 'Inspect element',
|
||||
click: () => {
|
||||
this.mainWindow.inspectElement(x, y);
|
||||
},
|
||||
},
|
||||
]).popup(this.mainWindow);
|
||||
});
|
||||
}
|
||||
setupDevelopmentEnvironment() {
|
||||
this.mainWindow.openDevTools();
|
||||
this.mainWindow.webContents.on('context-menu', (e, props) => {
|
||||
const {x, y} = props;
|
||||
|
||||
buildDarwinTemplate() {
|
||||
const subMenuAbout = {
|
||||
label: 'Electron',
|
||||
submenu: [
|
||||
{
|
||||
label: 'About ResponsivelyApp',
|
||||
selector: 'orderFrontStandardAboutPanel:',
|
||||
},
|
||||
{type: 'separator'},
|
||||
{label: 'Services', submenu: []},
|
||||
{type: 'separator'},
|
||||
{
|
||||
label: 'Hide ResponsivelyApp',
|
||||
accelerator: 'Command+H',
|
||||
selector: 'hide:',
|
||||
},
|
||||
{
|
||||
label: 'Hide Others',
|
||||
accelerator: 'Command+Shift+H',
|
||||
selector: 'hideOtherApplications:',
|
||||
},
|
||||
{label: 'Show All', selector: 'unhideAllApplications:'},
|
||||
{type: 'separator'},
|
||||
{
|
||||
label: 'Quit',
|
||||
accelerator: 'Command+Q',
|
||||
click: () => {
|
||||
app.quit();
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
const subMenuEdit = {
|
||||
label: 'Edit',
|
||||
submenu: [
|
||||
{label: 'Undo', accelerator: 'Command+Z', selector: 'undo:'},
|
||||
{label: 'Redo', accelerator: 'Shift+Command+Z', selector: 'redo:'},
|
||||
{type: 'separator'},
|
||||
{label: 'Cut', accelerator: 'Command+X', selector: 'cut:'},
|
||||
{label: 'Copy', accelerator: 'Command+C', selector: 'copy:'},
|
||||
{label: 'Paste', accelerator: 'Command+V', selector: 'paste:'},
|
||||
{
|
||||
label: 'Select All',
|
||||
accelerator: 'Command+A',
|
||||
selector: 'selectAll:',
|
||||
},
|
||||
],
|
||||
};
|
||||
const subMenuViewDev = {
|
||||
label: 'View',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Reload',
|
||||
accelerator: 'Command+R',
|
||||
click: () => {
|
||||
this.mainWindow.webContents.reload();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Toggle Full Screen',
|
||||
accelerator: 'Ctrl+Command+F',
|
||||
click: () => {
|
||||
this.mainWindow.setFullScreen(!this.mainWindow.isFullScreen());
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Toggle Developer Tools',
|
||||
accelerator: 'Alt+Command+I',
|
||||
click: () => {
|
||||
this.mainWindow.toggleDevTools();
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
const subMenuViewProd = {
|
||||
label: 'View',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Toggle Full Screen',
|
||||
accelerator: 'Ctrl+Command+F',
|
||||
click: () => {
|
||||
this.mainWindow.setFullScreen(!this.mainWindow.isFullScreen());
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
const subMenuWindow = {
|
||||
label: 'Window',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Minimize',
|
||||
accelerator: 'Command+M',
|
||||
selector: 'performMiniaturize:',
|
||||
},
|
||||
{label: 'Close', accelerator: 'Command+W', selector: 'performClose:'},
|
||||
{type: 'separator'},
|
||||
{label: 'Bring All to Front', selector: 'arrangeInFront:'},
|
||||
],
|
||||
};
|
||||
const subMenuHelp = {
|
||||
label: 'Help',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Learn More',
|
||||
click() {
|
||||
shell.openExternal('http://electron.atom.io');
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Documentation',
|
||||
click() {
|
||||
shell.openExternal(
|
||||
'https://github.com/atom/electron/tree/master/docs#readme'
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Community Discussions',
|
||||
click() {
|
||||
shell.openExternal('https://discuss.atom.io/c/electron');
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Search Issues',
|
||||
click() {
|
||||
shell.openExternal('https://github.com/atom/electron/issues');
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const subMenuView =
|
||||
process.env.NODE_ENV === 'development' ? subMenuViewDev : subMenuViewProd;
|
||||
|
||||
return [subMenuAbout, subMenuEdit, subMenuView, subMenuWindow, subMenuHelp];
|
||||
}
|
||||
|
||||
buildDefaultTemplate() {
|
||||
const templateDefault = [
|
||||
{
|
||||
label: '&File',
|
||||
submenu: [
|
||||
{
|
||||
label: '&Open',
|
||||
accelerator: 'Ctrl+O',
|
||||
},
|
||||
{
|
||||
label: '&Close',
|
||||
accelerator: 'Ctrl+W',
|
||||
click: () => {
|
||||
this.mainWindow.close();
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: '&View',
|
||||
submenu:
|
||||
process.env.NODE_ENV === 'development'
|
||||
? [
|
||||
Menu.buildFromTemplate([
|
||||
{
|
||||
label: '&Reload',
|
||||
accelerator: 'Ctrl+R',
|
||||
click: () => {
|
||||
this.mainWindow.webContents.reload();
|
||||
},
|
||||
label: 'Inspect element',
|
||||
click: () => {
|
||||
this.mainWindow.inspectElement(x, y);
|
||||
},
|
||||
},
|
||||
]).popup(this.mainWindow);
|
||||
});
|
||||
}
|
||||
|
||||
buildDarwinTemplate() {
|
||||
const subMenuAbout = {
|
||||
label: 'Electron',
|
||||
submenu: [
|
||||
{
|
||||
label: 'About ResponsivelyApp',
|
||||
selector: 'orderFrontStandardAboutPanel:',
|
||||
},
|
||||
{type: 'separator'},
|
||||
{label: 'Services', submenu: []},
|
||||
{type: 'separator'},
|
||||
{
|
||||
label: 'Hide ResponsivelyApp',
|
||||
accelerator: 'Command+H',
|
||||
selector: 'hide:',
|
||||
},
|
||||
{
|
||||
label: 'Toggle &Full Screen',
|
||||
accelerator: 'F11',
|
||||
click: () => {
|
||||
this.mainWindow.setFullScreen(
|
||||
!this.mainWindow.isFullScreen()
|
||||
);
|
||||
},
|
||||
label: 'Hide Others',
|
||||
accelerator: 'Command+Shift+H',
|
||||
selector: 'hideOtherApplications:',
|
||||
},
|
||||
{label: 'Show All', selector: 'unhideAllApplications:'},
|
||||
{type: 'separator'},
|
||||
{
|
||||
label: 'Quit',
|
||||
accelerator: 'Command+Q',
|
||||
click: () => {
|
||||
app.quit();
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
const subMenuEdit = {
|
||||
label: 'Edit',
|
||||
submenu: [
|
||||
{label: 'Undo', accelerator: 'Command+Z', selector: 'undo:'},
|
||||
{
|
||||
label: 'Redo',
|
||||
accelerator: 'Shift+Command+Z',
|
||||
selector: 'redo:',
|
||||
},
|
||||
{type: 'separator'},
|
||||
{label: 'Cut', accelerator: 'Command+X', selector: 'cut:'},
|
||||
{label: 'Copy', accelerator: 'Command+C', selector: 'copy:'},
|
||||
{label: 'Paste', accelerator: 'Command+V', selector: 'paste:'},
|
||||
{
|
||||
label: 'Select All',
|
||||
accelerator: 'Command+A',
|
||||
selector: 'selectAll:',
|
||||
},
|
||||
],
|
||||
};
|
||||
const subMenuViewDev = {
|
||||
label: 'View',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Reload',
|
||||
accelerator: 'Command+R',
|
||||
click: () => {
|
||||
this.mainWindow.webContents.reload();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Toggle &Developer Tools',
|
||||
accelerator: 'Alt+Ctrl+I',
|
||||
click: () => {
|
||||
this.mainWindow.toggleDevTools();
|
||||
},
|
||||
label: 'Toggle Full Screen',
|
||||
accelerator: 'Ctrl+Command+F',
|
||||
click: () => {
|
||||
this.mainWindow.setFullScreen(
|
||||
!this.mainWindow.isFullScreen()
|
||||
);
|
||||
},
|
||||
},
|
||||
]
|
||||
: [
|
||||
{
|
||||
label: 'Toggle &Full Screen',
|
||||
accelerator: 'F11',
|
||||
click: () => {
|
||||
this.mainWindow.setFullScreen(
|
||||
!this.mainWindow.isFullScreen()
|
||||
);
|
||||
},
|
||||
label: 'Toggle Developer Tools',
|
||||
accelerator: 'Alt+Command+I',
|
||||
click: () => {
|
||||
this.mainWindow.toggleDevTools();
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Help',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Learn More',
|
||||
click() {
|
||||
shell.openExternal('http://electron.atom.io');
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Documentation',
|
||||
click() {
|
||||
shell.openExternal(
|
||||
'https://github.com/atom/electron/tree/master/docs#readme'
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Community Discussions',
|
||||
click() {
|
||||
shell.openExternal('https://discuss.atom.io/c/electron');
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Search Issues',
|
||||
click() {
|
||||
shell.openExternal('https://github.com/atom/electron/issues');
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
],
|
||||
};
|
||||
const subMenuViewProd = {
|
||||
label: 'View',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Toggle Full Screen',
|
||||
accelerator: 'Ctrl+Command+F',
|
||||
click: () => {
|
||||
this.mainWindow.setFullScreen(
|
||||
!this.mainWindow.isFullScreen()
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
const subMenuWindow = {
|
||||
label: 'Window',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Minimize',
|
||||
accelerator: 'Command+M',
|
||||
selector: 'performMiniaturize:',
|
||||
},
|
||||
{
|
||||
label: 'Close',
|
||||
accelerator: 'Command+W',
|
||||
selector: 'performClose:',
|
||||
},
|
||||
{type: 'separator'},
|
||||
{label: 'Bring All to Front', selector: 'arrangeInFront:'},
|
||||
],
|
||||
};
|
||||
const subMenuHelp = {
|
||||
label: 'Help',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Learn More',
|
||||
click() {
|
||||
shell.openExternal('http://electron.atom.io');
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Documentation',
|
||||
click() {
|
||||
shell.openExternal(
|
||||
'https://github.com/atom/electron/tree/master/docs#readme'
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Community Discussions',
|
||||
click() {
|
||||
shell.openExternal(
|
||||
'https://discuss.atom.io/c/electron'
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Search Issues',
|
||||
click() {
|
||||
shell.openExternal(
|
||||
'https://github.com/atom/electron/issues'
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
return templateDefault;
|
||||
}
|
||||
const subMenuView =
|
||||
process.env.NODE_ENV === 'development'
|
||||
? subMenuViewDev
|
||||
: subMenuViewProd;
|
||||
|
||||
return [
|
||||
subMenuAbout,
|
||||
subMenuEdit,
|
||||
subMenuView,
|
||||
subMenuWindow,
|
||||
subMenuHelp,
|
||||
];
|
||||
}
|
||||
|
||||
buildDefaultTemplate() {
|
||||
const templateDefault = [
|
||||
{
|
||||
label: '&File',
|
||||
submenu: [
|
||||
{
|
||||
label: '&Open',
|
||||
accelerator: 'Ctrl+O',
|
||||
},
|
||||
{
|
||||
label: '&Close',
|
||||
accelerator: 'Ctrl+W',
|
||||
click: () => {
|
||||
this.mainWindow.close();
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: '&View',
|
||||
submenu:
|
||||
process.env.NODE_ENV === 'development'
|
||||
? [
|
||||
{
|
||||
label: '&Reload',
|
||||
accelerator: 'Ctrl+R',
|
||||
click: () => {
|
||||
this.mainWindow.webContents.reload();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Toggle &Full Screen',
|
||||
accelerator: 'F11',
|
||||
click: () => {
|
||||
this.mainWindow.setFullScreen(
|
||||
!this.mainWindow.isFullScreen()
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Toggle &Developer Tools',
|
||||
accelerator: 'Alt+Ctrl+I',
|
||||
click: () => {
|
||||
this.mainWindow.toggleDevTools();
|
||||
},
|
||||
},
|
||||
]
|
||||
: [
|
||||
{
|
||||
label: 'Toggle &Full Screen',
|
||||
accelerator: 'F11',
|
||||
click: () => {
|
||||
this.mainWindow.setFullScreen(
|
||||
!this.mainWindow.isFullScreen()
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Help',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Learn More',
|
||||
click() {
|
||||
shell.openExternal('http://electron.atom.io');
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Documentation',
|
||||
click() {
|
||||
shell.openExternal(
|
||||
'https://github.com/atom/electron/tree/master/docs#readme'
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Community Discussions',
|
||||
click() {
|
||||
shell.openExternal(
|
||||
'https://discuss.atom.io/c/electron'
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Search Issues',
|
||||
click() {
|
||||
shell.openExternal(
|
||||
'https://github.com/atom/electron/issues'
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
return templateDefault;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,169 +8,169 @@ var menu = new Menu();
|
|||
var rightClickPosition = null;
|
||||
|
||||
menu.append(
|
||||
new MenuItem({
|
||||
label: 'Take Screenshot',
|
||||
click: function(menuItem, browserWindow, event) {
|
||||
window.responsivelyApp.sendMessageToHost('takeScreenshot');
|
||||
},
|
||||
})
|
||||
new MenuItem({
|
||||
label: 'Take Screenshot',
|
||||
click: function(menuItem, browserWindow, event) {
|
||||
window.responsivelyApp.sendMessageToHost('takeScreenshot');
|
||||
},
|
||||
})
|
||||
);
|
||||
menu.append(
|
||||
new MenuItem({
|
||||
label: 'Tilt Device',
|
||||
click: function(menuItem, browserWindow, event) {
|
||||
window.responsivelyApp.sendMessageToHost('tiltDevice');
|
||||
},
|
||||
})
|
||||
new MenuItem({
|
||||
label: 'Tilt Device',
|
||||
click: function(menuItem, browserWindow, event) {
|
||||
window.responsivelyApp.sendMessageToHost('tiltDevice');
|
||||
},
|
||||
})
|
||||
);
|
||||
menu.append(
|
||||
new MenuItem({
|
||||
id: 'mirror-events',
|
||||
label: 'Mirror Events',
|
||||
type: 'checkbox',
|
||||
checked: true,
|
||||
click: function(menuItem, browserWindow, event) {
|
||||
window.responsivelyApp.sendMessageToHost('toggleEventMirroring');
|
||||
},
|
||||
})
|
||||
new MenuItem({
|
||||
id: 'mirror-events',
|
||||
label: 'Mirror Events',
|
||||
type: 'checkbox',
|
||||
checked: true,
|
||||
click: function(menuItem, browserWindow, event) {
|
||||
window.responsivelyApp.sendMessageToHost('toggleEventMirroring');
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
menu.append(new MenuItem({type: 'separator'}));
|
||||
|
||||
menu.append(
|
||||
new MenuItem({
|
||||
label: 'Inspect',
|
||||
click: function(menuItem, browserWindow, event) {
|
||||
window.responsivelyApp.sendMessageToHost(
|
||||
'openDevToolsInspector',
|
||||
rightClickPosition
|
||||
);
|
||||
},
|
||||
})
|
||||
new MenuItem({
|
||||
label: 'Inspect',
|
||||
click: function(menuItem, browserWindow, event) {
|
||||
window.responsivelyApp.sendMessageToHost(
|
||||
'openDevToolsInspector',
|
||||
rightClickPosition
|
||||
);
|
||||
},
|
||||
})
|
||||
);
|
||||
menu.append(
|
||||
new MenuItem({
|
||||
label: 'Open Console',
|
||||
click: function(menuItem, browserWindow, event) {
|
||||
window.responsivelyApp.sendMessageToHost('openConsole');
|
||||
},
|
||||
})
|
||||
new MenuItem({
|
||||
label: 'Open Console',
|
||||
click: function(menuItem, browserWindow, event) {
|
||||
window.responsivelyApp.sendMessageToHost('openConsole');
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
window.addEventListener(
|
||||
'contextmenu',
|
||||
function(e) {
|
||||
e.preventDefault();
|
||||
rightClickPosition = {x: e.x, y: e.y};
|
||||
menu.popup(remote.getCurrentWindow());
|
||||
},
|
||||
false
|
||||
'contextmenu',
|
||||
function(e) {
|
||||
e.preventDefault();
|
||||
rightClickPosition = {x: e.x, y: e.y};
|
||||
menu.popup(remote.getCurrentWindow());
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
global.responsivelyApp = {
|
||||
DomInspector: DomInspector,
|
||||
sendMessageToHost: (type, message) => {
|
||||
if (!message) {
|
||||
message = {};
|
||||
}
|
||||
message.sourceDeviceId = window.responsivelyApp.deviceId;
|
||||
ipcRenderer.sendToHost(type, message);
|
||||
},
|
||||
cssPath: el => {
|
||||
if (!(el instanceof Element)) return;
|
||||
var path = [];
|
||||
while (el.nodeType === Node.ELEMENT_NODE) {
|
||||
var selector = el.nodeName.toLowerCase();
|
||||
var sib = el,
|
||||
nth = 1;
|
||||
while (
|
||||
sib.nodeType === Node.ELEMENT_NODE &&
|
||||
(sib = sib.previousElementSibling) &&
|
||||
nth++
|
||||
);
|
||||
selector += ':nth-child(' + nth + ')';
|
||||
path.unshift(selector);
|
||||
el = el.parentNode;
|
||||
}
|
||||
return path.join(' > ');
|
||||
},
|
||||
eventFire: (el, etype) => {
|
||||
if (el.fireEvent) {
|
||||
el.fireEvent('on' + etype);
|
||||
} else {
|
||||
var evObj = document.createEvent('Events');
|
||||
evObj.initEvent(etype, true, false);
|
||||
evObj.responsivelyAppProcessed = true;
|
||||
el.dispatchEvent(evObj);
|
||||
}
|
||||
},
|
||||
hideFixedPositionElementsForScreenshot: () => {
|
||||
const elems = document.body.getElementsByTagName('*');
|
||||
for (const elem of elems) {
|
||||
const computedStyle = window.getComputedStyle(elem, null);
|
||||
if (computedStyle.getPropertyValue('position') == 'fixed') {
|
||||
elem.classList.add('responsivelyApp__HiddenForScreenshot');
|
||||
}
|
||||
}
|
||||
},
|
||||
unHideElementsHiddenForScreenshot: () => {
|
||||
const elems = document.body.querySelectorAll(
|
||||
'.responsivelyApp__HiddenForScreenshot'
|
||||
);
|
||||
for (const elem of elems) {
|
||||
elem.classList.remove('responsivelyApp__HiddenForScreenshot');
|
||||
}
|
||||
},
|
||||
DomInspector: DomInspector,
|
||||
sendMessageToHost: (type, message) => {
|
||||
if (!message) {
|
||||
message = {};
|
||||
}
|
||||
message.sourceDeviceId = window.responsivelyApp.deviceId;
|
||||
ipcRenderer.sendToHost(type, message);
|
||||
},
|
||||
cssPath: el => {
|
||||
if (!(el instanceof Element)) return;
|
||||
var path = [];
|
||||
while (el.nodeType === Node.ELEMENT_NODE) {
|
||||
var selector = el.nodeName.toLowerCase();
|
||||
var sib = el,
|
||||
nth = 1;
|
||||
while (
|
||||
sib.nodeType === Node.ELEMENT_NODE &&
|
||||
(sib = sib.previousElementSibling) &&
|
||||
nth++
|
||||
);
|
||||
selector += ':nth-child(' + nth + ')';
|
||||
path.unshift(selector);
|
||||
el = el.parentNode;
|
||||
}
|
||||
return path.join(' > ');
|
||||
},
|
||||
eventFire: (el, etype) => {
|
||||
if (el.fireEvent) {
|
||||
el.fireEvent('on' + etype);
|
||||
} else {
|
||||
var evObj = document.createEvent('Events');
|
||||
evObj.initEvent(etype, true, false);
|
||||
evObj.responsivelyAppProcessed = true;
|
||||
el.dispatchEvent(evObj);
|
||||
}
|
||||
},
|
||||
hideFixedPositionElementsForScreenshot: () => {
|
||||
const elems = document.body.getElementsByTagName('*');
|
||||
for (const elem of elems) {
|
||||
const computedStyle = window.getComputedStyle(elem, null);
|
||||
if (computedStyle.getPropertyValue('position') == 'fixed') {
|
||||
elem.classList.add('responsivelyApp__HiddenForScreenshot');
|
||||
}
|
||||
}
|
||||
},
|
||||
unHideElementsHiddenForScreenshot: () => {
|
||||
const elems = document.body.querySelectorAll(
|
||||
'.responsivelyApp__HiddenForScreenshot'
|
||||
);
|
||||
for (const elem of elems) {
|
||||
elem.classList.remove('responsivelyApp__HiddenForScreenshot');
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
ipcRenderer.on('scrollMessage', (event, args) => {
|
||||
window.scrollTo({
|
||||
top: args.y,
|
||||
left: args.x,
|
||||
});
|
||||
window.scrollTo({
|
||||
top: args.y,
|
||||
left: args.x,
|
||||
});
|
||||
});
|
||||
|
||||
ipcRenderer.on('clickMessage', (event, args) => {
|
||||
const elem = document.querySelector(args.cssPath);
|
||||
if (!elem) {
|
||||
return;
|
||||
}
|
||||
window.responsivelyApp.lastClickElement = elem;
|
||||
if (elem.click) {
|
||||
elem.click();
|
||||
return;
|
||||
}
|
||||
window.responsivelyApp.eventFire(elem, 'click');
|
||||
const elem = document.querySelector(args.cssPath);
|
||||
if (!elem) {
|
||||
return;
|
||||
}
|
||||
window.responsivelyApp.lastClickElement = elem;
|
||||
if (elem.click) {
|
||||
elem.click();
|
||||
return;
|
||||
}
|
||||
window.responsivelyApp.eventFire(elem, 'click');
|
||||
});
|
||||
|
||||
ipcRenderer.on('scrollDownMessage', (event, args) => {
|
||||
window.scrollTo({
|
||||
top: window.scrollY + 250,
|
||||
left: window.scrollX + 250,
|
||||
behavior: 'smooth',
|
||||
});
|
||||
window.scrollTo({
|
||||
top: window.scrollY + 250,
|
||||
left: window.scrollX + 250,
|
||||
behavior: 'smooth',
|
||||
});
|
||||
});
|
||||
|
||||
ipcRenderer.on('scrollUpMessage', (event, args) => {
|
||||
window.scrollTo({
|
||||
top: window.scrollY - 250,
|
||||
left: window.scrollX - 250,
|
||||
behavior: 'smooth',
|
||||
});
|
||||
window.scrollTo({
|
||||
top: window.scrollY - 250,
|
||||
left: window.scrollX - 250,
|
||||
behavior: 'smooth',
|
||||
});
|
||||
});
|
||||
|
||||
ipcRenderer.on('enableInspectorMessage', (event, args) => {
|
||||
responsivelyApp.domInspector = new responsivelyApp.DomInspector();
|
||||
window.responsivelyApp.domInspector.enable();
|
||||
window.responsivelyApp.domInspectorEnabled = true;
|
||||
responsivelyApp.domInspector = new responsivelyApp.DomInspector();
|
||||
window.responsivelyApp.domInspector.enable();
|
||||
window.responsivelyApp.domInspectorEnabled = true;
|
||||
});
|
||||
|
||||
ipcRenderer.on('disableInspectorMessage', (event, args) => {
|
||||
window.responsivelyApp.domInspector.destroy();
|
||||
window.responsivelyApp.domInspector = null;
|
||||
window.responsivelyApp.domInspectorEnabled = false;
|
||||
window.responsivelyApp.domInspector.destroy();
|
||||
window.responsivelyApp.domInspector = null;
|
||||
window.responsivelyApp.domInspectorEnabled = false;
|
||||
});
|
||||
|
||||
ipcRenderer.on('eventsMirroringState', (event, args) => {
|
||||
menu.getMenuItemById('mirror-events').checked = args;
|
||||
menu.getMenuItemById('mirror-events').checked = args;
|
||||
});
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
// @flow
|
||||
import {
|
||||
NEW_ADDRESS,
|
||||
NEW_ZOOM_LEVEL,
|
||||
NEW_SCROLL_POSITION,
|
||||
NEW_NAVIGATOR_STATUS,
|
||||
NEW_DRAWER_CONTENT,
|
||||
NEW_PREVIEWER_CONFIG,
|
||||
NEW_ACTIVE_DEVICES,
|
||||
NEW_ACTIVE_DEVICE,
|
||||
NEW_FILTERS,
|
||||
NEW_HOMEPAGE,
|
||||
NEW_ADDRESS,
|
||||
NEW_ZOOM_LEVEL,
|
||||
NEW_SCROLL_POSITION,
|
||||
NEW_NAVIGATOR_STATUS,
|
||||
NEW_DRAWER_CONTENT,
|
||||
NEW_PREVIEWER_CONFIG,
|
||||
NEW_ACTIVE_DEVICES,
|
||||
NEW_ACTIVE_DEVICE,
|
||||
NEW_FILTERS,
|
||||
NEW_HOMEPAGE,
|
||||
} from '../actions/browser';
|
||||
import type {Action} from './types';
|
||||
import devices from '../constants/devices';
|
||||
import settings from 'electron-settings';
|
||||
import type {Device} from '../constants/devices';
|
||||
import {
|
||||
FLEXIGRID_LAYOUT,
|
||||
INDIVIDUAL_LAYOUT,
|
||||
FLEXIGRID_LAYOUT,
|
||||
INDIVIDUAL_LAYOUT,
|
||||
} from '../constants/previewerLayouts';
|
||||
import {DEVICE_MANAGER} from '../constants/DrawerContents';
|
||||
import {ACTIVE_DEVICES} from '../constants/settingKeys';
|
||||
|
@ -25,27 +25,27 @@ import {isIfStatement} from 'typescript';
|
|||
import {getHomepage, saveHomepage} from '../utils/navigatorUtils';
|
||||
|
||||
export const FILTER_FIELDS = {
|
||||
OS: 'OS',
|
||||
DEVICE_TYPE: 'DEVICE_TYPE',
|
||||
OS: 'OS',
|
||||
DEVICE_TYPE: 'DEVICE_TYPE',
|
||||
};
|
||||
|
||||
type ScrollPositionType = {
|
||||
x: number,
|
||||
y: number,
|
||||
x: number,
|
||||
y: number,
|
||||
};
|
||||
|
||||
type NavigatorStatusType = {
|
||||
backEnabled: boolean,
|
||||
forwardEnabled: boolean,
|
||||
backEnabled: boolean,
|
||||
forwardEnabled: boolean,
|
||||
};
|
||||
|
||||
type DrawerType = {
|
||||
open: boolean,
|
||||
content: string,
|
||||
open: boolean,
|
||||
content: string,
|
||||
};
|
||||
|
||||
type PreviewerType = {
|
||||
layout: string,
|
||||
layout: string,
|
||||
};
|
||||
|
||||
type FilterFieldType = FILTER_FIELDS.OS | FILTER_FIELDS.DEVICE_TYPE;
|
||||
|
@ -53,93 +53,93 @@ type FilterFieldType = FILTER_FIELDS.OS | FILTER_FIELDS.DEVICE_TYPE;
|
|||
type FilterType = {[key: FilterFieldType]: Array<string>};
|
||||
|
||||
export type BrowserStateType = {
|
||||
devices: Array<Device>,
|
||||
homepage: string,
|
||||
address: string,
|
||||
zoomLevel: number,
|
||||
scrollPosition: ScrollPositionType,
|
||||
navigatorStatus: NavigatorStatusType,
|
||||
drawer: DrawerType,
|
||||
previewer: PreviewerType,
|
||||
filters: FilterType,
|
||||
devices: Array<Device>,
|
||||
homepage: string,
|
||||
address: string,
|
||||
zoomLevel: number,
|
||||
scrollPosition: ScrollPositionType,
|
||||
navigatorStatus: NavigatorStatusType,
|
||||
drawer: DrawerType,
|
||||
previewer: PreviewerType,
|
||||
filters: FilterType,
|
||||
};
|
||||
|
||||
let _activeDevices = null;
|
||||
|
||||
function _saveActiveDevices(devices) {
|
||||
settings.set(ACTIVE_DEVICES, devices);
|
||||
_activeDevices = devices;
|
||||
settings.set(ACTIVE_DEVICES, devices);
|
||||
_activeDevices = devices;
|
||||
}
|
||||
|
||||
function _getActiveDevices() {
|
||||
if (_activeDevices) {
|
||||
return _activeDevices;
|
||||
}
|
||||
let activeDevices = settings.get(ACTIVE_DEVICES);
|
||||
if (!activeDevices) {
|
||||
activeDevices = devices.filter(device => device.added);
|
||||
_saveActiveDevices(activeDevices);
|
||||
}
|
||||
return activeDevices;
|
||||
if (_activeDevices) {
|
||||
return _activeDevices;
|
||||
}
|
||||
let activeDevices = settings.get(ACTIVE_DEVICES);
|
||||
if (!activeDevices) {
|
||||
activeDevices = devices.filter(device => device.added);
|
||||
_saveActiveDevices(activeDevices);
|
||||
}
|
||||
return activeDevices;
|
||||
}
|
||||
|
||||
export default function counter(
|
||||
state: BrowserStateType = {
|
||||
devices: _getActiveDevices(),
|
||||
homepage: getHomepage(),
|
||||
address: getHomepage(),
|
||||
zoomLevel: 0.6,
|
||||
previousZoomLevel: null,
|
||||
scrollPosition: {x: 0, y: 0},
|
||||
navigatorStatus: {backEnabled: false, forwardEnabled: false},
|
||||
drawer: {open: true, content: DEVICE_MANAGER},
|
||||
previewer: {layout: FLEXIGRID_LAYOUT},
|
||||
filters: {[FILTER_FIELDS.OS]: [], [FILTER_FIELDS.DEVICE_TYPE]: []},
|
||||
},
|
||||
action: Action
|
||||
state: BrowserStateType = {
|
||||
devices: _getActiveDevices(),
|
||||
homepage: getHomepage(),
|
||||
address: getHomepage(),
|
||||
zoomLevel: 0.6,
|
||||
previousZoomLevel: null,
|
||||
scrollPosition: {x: 0, y: 0},
|
||||
navigatorStatus: {backEnabled: false, forwardEnabled: false},
|
||||
drawer: {open: true, content: DEVICE_MANAGER},
|
||||
previewer: {layout: FLEXIGRID_LAYOUT},
|
||||
filters: {[FILTER_FIELDS.OS]: [], [FILTER_FIELDS.DEVICE_TYPE]: []},
|
||||
},
|
||||
action: Action
|
||||
) {
|
||||
switch (action.type) {
|
||||
case NEW_ADDRESS:
|
||||
return {...state, address: action.address};
|
||||
case NEW_HOMEPAGE:
|
||||
const {homepage} = action;
|
||||
saveHomepage(homepage);
|
||||
return {...state, homepage};
|
||||
case NEW_ZOOM_LEVEL:
|
||||
return {...state, zoomLevel: action.zoomLevel};
|
||||
case NEW_SCROLL_POSITION:
|
||||
return {...state, scrollPosition: action.scrollPosition};
|
||||
case NEW_NAVIGATOR_STATUS:
|
||||
return {...state, navigatorStatus: action.navigatorStatus};
|
||||
case NEW_DRAWER_CONTENT:
|
||||
return {...state, drawer: action.drawer};
|
||||
case NEW_PREVIEWER_CONFIG:
|
||||
const updateObject = {previewer: action.previewer};
|
||||
if (
|
||||
state.previewer.layout !== INDIVIDUAL_LAYOUT &&
|
||||
action.previewer.layout === INDIVIDUAL_LAYOUT
|
||||
) {
|
||||
updateObject.zoomLevel = 1;
|
||||
updateObject.previousZoomLevel = state.zoomLevel;
|
||||
}
|
||||
if (
|
||||
state.previewer.layout === INDIVIDUAL_LAYOUT &&
|
||||
action.previewer.layout !== INDIVIDUAL_LAYOUT
|
||||
) {
|
||||
updateObject.zoomLevel = state.previousZoomLevel;
|
||||
updateObject.previousZoomLevel = null;
|
||||
}
|
||||
return {...state, ...updateObject};
|
||||
case NEW_ACTIVE_DEVICES:
|
||||
_saveActiveDevices(action.devices);
|
||||
return {...state, devices: action.devices};
|
||||
case NEW_ACTIVE_DEVICE:
|
||||
const devices = [...state.devices, action.device];
|
||||
_saveActiveDevices(devices);
|
||||
return {...state, devices};
|
||||
case NEW_FILTERS:
|
||||
return {...state, filters: action.filters};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
switch (action.type) {
|
||||
case NEW_ADDRESS:
|
||||
return {...state, address: action.address};
|
||||
case NEW_HOMEPAGE:
|
||||
const {homepage} = action;
|
||||
saveHomepage(homepage);
|
||||
return {...state, homepage};
|
||||
case NEW_ZOOM_LEVEL:
|
||||
return {...state, zoomLevel: action.zoomLevel};
|
||||
case NEW_SCROLL_POSITION:
|
||||
return {...state, scrollPosition: action.scrollPosition};
|
||||
case NEW_NAVIGATOR_STATUS:
|
||||
return {...state, navigatorStatus: action.navigatorStatus};
|
||||
case NEW_DRAWER_CONTENT:
|
||||
return {...state, drawer: action.drawer};
|
||||
case NEW_PREVIEWER_CONFIG:
|
||||
const updateObject = {previewer: action.previewer};
|
||||
if (
|
||||
state.previewer.layout !== INDIVIDUAL_LAYOUT &&
|
||||
action.previewer.layout === INDIVIDUAL_LAYOUT
|
||||
) {
|
||||
updateObject.zoomLevel = 1;
|
||||
updateObject.previousZoomLevel = state.zoomLevel;
|
||||
}
|
||||
if (
|
||||
state.previewer.layout === INDIVIDUAL_LAYOUT &&
|
||||
action.previewer.layout !== INDIVIDUAL_LAYOUT
|
||||
) {
|
||||
updateObject.zoomLevel = state.previousZoomLevel;
|
||||
updateObject.previousZoomLevel = null;
|
||||
}
|
||||
return {...state, ...updateObject};
|
||||
case NEW_ACTIVE_DEVICES:
|
||||
_saveActiveDevices(action.devices);
|
||||
return {...state, devices: action.devices};
|
||||
case NEW_ACTIVE_DEVICE:
|
||||
const devices = [...state.devices, action.device];
|
||||
_saveActiveDevices(devices);
|
||||
return {...state, devices};
|
||||
case NEW_FILTERS:
|
||||
return {...state, filters: action.filters};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ import {connectRouter} from 'connected-react-router';
|
|||
import browser from './browser';
|
||||
|
||||
export default function createRootReducer(history: History) {
|
||||
return combineReducers({
|
||||
router: connectRouter(history),
|
||||
browser,
|
||||
});
|
||||
return combineReducers({
|
||||
router: connectRouter(history),
|
||||
browser,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -4,15 +4,15 @@ import type {BrowserStateType as _BrowserStateType} from './browser';
|
|||
export type BrowserStateType = _BrowserStateType;
|
||||
|
||||
export type counterStateType = {
|
||||
+counter: number,
|
||||
+counter: number,
|
||||
};
|
||||
|
||||
export type RootStateType = {
|
||||
browser: BrowserStateType,
|
||||
browser: BrowserStateType,
|
||||
};
|
||||
|
||||
export type Action = {
|
||||
+type: string,
|
||||
+type: string,
|
||||
};
|
||||
|
||||
export type GetState = () => RootStateType;
|
||||
|
|
|
@ -10,58 +10,58 @@ const history = createHashHistory();
|
|||
const rootReducer = createRootReducer(history);
|
||||
|
||||
const configureStore = initialState => {
|
||||
// Redux Configuration
|
||||
const middleware = [];
|
||||
const enhancers = [];
|
||||
// Redux Configuration
|
||||
const middleware = [];
|
||||
const enhancers = [];
|
||||
|
||||
// Thunk Middleware
|
||||
middleware.push(thunk);
|
||||
// Thunk Middleware
|
||||
middleware.push(thunk);
|
||||
|
||||
// Logging Middleware
|
||||
const logger = createLogger({
|
||||
level: 'info',
|
||||
collapsed: true,
|
||||
});
|
||||
// Logging Middleware
|
||||
const logger = createLogger({
|
||||
level: 'info',
|
||||
collapsed: true,
|
||||
});
|
||||
|
||||
// Skip redux logs in console during the tests
|
||||
if (process.env.NODE_ENV !== 'test') {
|
||||
middleware.push(logger);
|
||||
}
|
||||
// Skip redux logs in console during the tests
|
||||
if (process.env.NODE_ENV !== 'test') {
|
||||
middleware.push(logger);
|
||||
}
|
||||
|
||||
// Router Middleware
|
||||
const router = routerMiddleware(history);
|
||||
middleware.push(router);
|
||||
// Router Middleware
|
||||
const router = routerMiddleware(history);
|
||||
middleware.push(router);
|
||||
|
||||
// Redux DevTools Configuration
|
||||
const actionCreators = {
|
||||
...routerActions,
|
||||
};
|
||||
// If Redux DevTools Extension is installed use it, otherwise use Redux compose
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
|
||||
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
|
||||
// Options: http://extension.remotedev.io/docs/API/Arguments.html
|
||||
actionCreators,
|
||||
})
|
||||
: compose;
|
||||
/* eslint-enable no-underscore-dangle */
|
||||
// Redux DevTools Configuration
|
||||
const actionCreators = {
|
||||
...routerActions,
|
||||
};
|
||||
// If Redux DevTools Extension is installed use it, otherwise use Redux compose
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
|
||||
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
|
||||
// Options: http://extension.remotedev.io/docs/API/Arguments.html
|
||||
actionCreators,
|
||||
})
|
||||
: compose;
|
||||
/* eslint-enable no-underscore-dangle */
|
||||
|
||||
// Apply Middleware & Compose Enhancers
|
||||
enhancers.push(applyMiddleware(...middleware));
|
||||
const enhancer = composeEnhancers(...enhancers);
|
||||
// Apply Middleware & Compose Enhancers
|
||||
enhancers.push(applyMiddleware(...middleware));
|
||||
const enhancer = composeEnhancers(...enhancers);
|
||||
|
||||
// Create Store
|
||||
const store = createStore(rootReducer, initialState, enhancer);
|
||||
// Create Store
|
||||
const store = createStore(rootReducer, initialState, enhancer);
|
||||
|
||||
if (module.hot) {
|
||||
module.hot.accept(
|
||||
'../reducers',
|
||||
// eslint-disable-next-line global-require
|
||||
() => store.replaceReducer(require('../reducers').default)
|
||||
);
|
||||
}
|
||||
if (module.hot) {
|
||||
module.hot.accept(
|
||||
'../reducers',
|
||||
// eslint-disable-next-line global-require
|
||||
() => store.replaceReducer(require('../reducers').default)
|
||||
);
|
||||
}
|
||||
|
||||
return store;
|
||||
return store;
|
||||
};
|
||||
|
||||
export default {configureStore, history};
|
||||
|
|
|
@ -3,10 +3,10 @@ import configureStoreDev from './configureStore.dev';
|
|||
import configureStoreProd from './configureStore.prod';
|
||||
|
||||
const selectedConfigureStore =
|
||||
process.env.NODE_ENV === 'production'
|
||||
? configureStoreProd
|
||||
: configureStoreDev;
|
||||
process.env.NODE_ENV === 'production'
|
||||
? configureStoreProd
|
||||
: configureStoreDev;
|
||||
|
||||
export const { configureStore } = selectedConfigureStore;
|
||||
export const {configureStore} = selectedConfigureStore;
|
||||
|
||||
export const { history } = selectedConfigureStore;
|
||||
export const {history} = selectedConfigureStore;
|
||||
|
|
|
@ -11,7 +11,7 @@ const router = routerMiddleware(history);
|
|||
const enhancer = applyMiddleware(thunk, router);
|
||||
|
||||
function configureStore(initialState) {
|
||||
return createStore(rootReducer, initialState, enhancer);
|
||||
return createStore(rootReducer, initialState, enhancer);
|
||||
}
|
||||
|
||||
export default {configureStore, history};
|
||||
|
|
|
@ -1,22 +1,25 @@
|
|||
import {FILTER_FIELDS} from '../reducers/browser';
|
||||
|
||||
export const isDeviceEligible = (device, filterCriteria) => {
|
||||
if (Object.keys(filterCriteria[FILTER_FIELDS.OS]).length > 0) {
|
||||
console.log(
|
||||
'OS',
|
||||
device.os,
|
||||
filterCriteria[FILTER_FIELDS.OS].indexOf(device.os)
|
||||
);
|
||||
if (filterCriteria[FILTER_FIELDS.OS].indexOf(device.os) === -1) {
|
||||
return false;
|
||||
if (Object.keys(filterCriteria[FILTER_FIELDS.OS]).length > 0) {
|
||||
console.log(
|
||||
'OS',
|
||||
device.os,
|
||||
filterCriteria[FILTER_FIELDS.OS].indexOf(device.os)
|
||||
);
|
||||
if (filterCriteria[FILTER_FIELDS.OS].indexOf(device.os) === -1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.keys(filterCriteria[FILTER_FIELDS.DEVICE_TYPE]).length > 0) {
|
||||
if (filterCriteria[FILTER_FIELDS.DEVICE_TYPE].indexOf(device.type) === -1) {
|
||||
return false;
|
||||
if (Object.keys(filterCriteria[FILTER_FIELDS.DEVICE_TYPE]).length > 0) {
|
||||
if (
|
||||
filterCriteria[FILTER_FIELDS.DEVICE_TYPE].indexOf(device.type) ===
|
||||
-1
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const emailRE = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||
|
||||
export function validateEmail(email) {
|
||||
return emailRE.test(String(email).toLowerCase());
|
||||
return emailRE.test(String(email).toLowerCase());
|
||||
}
|
||||
|
|
|
@ -9,39 +9,39 @@ import WindowsIcon from '../components/icons/Windows';
|
|||
import AndroidIcon from '@material-ui/icons/Android';
|
||||
|
||||
export const getDeviceIcon = deviceType => {
|
||||
const iconProps = {
|
||||
color: iconsColor,
|
||||
style: {fontSize: 'inherit', paddingRight: 2},
|
||||
};
|
||||
switch (deviceType) {
|
||||
case DEVICE_TYPE.phone:
|
||||
return <MobileIcon {...iconProps} />;
|
||||
case DEVICE_TYPE.tablet:
|
||||
return <TabletIcon {...iconProps} />;
|
||||
case DEVICE_TYPE.desktop:
|
||||
return <DesktopIcon {...iconProps} />;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
const iconProps = {
|
||||
color: iconsColor,
|
||||
style: {fontSize: 'inherit', paddingRight: 2},
|
||||
};
|
||||
switch (deviceType) {
|
||||
case DEVICE_TYPE.phone:
|
||||
return <MobileIcon {...iconProps} />;
|
||||
case DEVICE_TYPE.tablet:
|
||||
return <TabletIcon {...iconProps} />;
|
||||
case DEVICE_TYPE.desktop:
|
||||
return <DesktopIcon {...iconProps} />;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export const getOSIcon = (os, _color) => {
|
||||
const color = _color || iconsColor;
|
||||
const iconProps = {
|
||||
color,
|
||||
style: {fontSize: 'inherit', paddingRight: 2, color},
|
||||
height: '1em',
|
||||
};
|
||||
switch (os) {
|
||||
case OS.ios:
|
||||
return <AppleIcon {...iconProps} />;
|
||||
case OS.android:
|
||||
return <AndroidIcon {...iconProps} />;
|
||||
case OS.windowsPhone:
|
||||
return <WindowsIcon {...iconProps} height="0.8em" />;
|
||||
case OS.pc:
|
||||
return <DesktopIcon {...iconProps} />;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
const color = _color || iconsColor;
|
||||
const iconProps = {
|
||||
color,
|
||||
style: {fontSize: 'inherit', paddingRight: 2, color},
|
||||
height: '1em',
|
||||
};
|
||||
switch (os) {
|
||||
case OS.ios:
|
||||
return <AppleIcon {...iconProps} />;
|
||||
case OS.android:
|
||||
return <AndroidIcon {...iconProps} />;
|
||||
case OS.windowsPhone:
|
||||
return <WindowsIcon {...iconProps} height="0.8em" />;
|
||||
case OS.pc:
|
||||
return <DesktopIcon {...iconProps} />;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -4,9 +4,9 @@ import path from 'path';
|
|||
const HOME_PAGE = 'HOME_PAGE';
|
||||
|
||||
export function saveHomepage(url) {
|
||||
settings.set(HOME_PAGE, url);
|
||||
settings.set(HOME_PAGE, url);
|
||||
}
|
||||
|
||||
export function getHomepage() {
|
||||
return settings.get(HOME_PAGE) || 'https://www.google.com';
|
||||
return settings.get(HOME_PAGE) || 'https://www.google.com';
|
||||
}
|
||||
|
|
|
@ -3,68 +3,73 @@
|
|||
const developmentEnvironments = ['development', 'test'];
|
||||
|
||||
const developmentPlugins = [
|
||||
require('@babel/plugin-transform-classes'),
|
||||
require('react-hot-loader/babel'),
|
||||
require('@babel/plugin-transform-classes'),
|
||||
require('react-hot-loader/babel'),
|
||||
];
|
||||
|
||||
const productionPlugins = [
|
||||
require('babel-plugin-dev-expression'),
|
||||
require('babel-plugin-dev-expression'),
|
||||
|
||||
// babel-preset-react-optimize
|
||||
require('@babel/plugin-transform-react-constant-elements'),
|
||||
require('@babel/plugin-transform-react-inline-elements'),
|
||||
require('babel-plugin-transform-react-remove-prop-types'),
|
||||
// babel-preset-react-optimize
|
||||
require('@babel/plugin-transform-react-constant-elements'),
|
||||
require('@babel/plugin-transform-react-inline-elements'),
|
||||
require('babel-plugin-transform-react-remove-prop-types'),
|
||||
];
|
||||
|
||||
module.exports = api => {
|
||||
// see docs about api at https://babeljs.io/docs/en/config-files#apicache
|
||||
// see docs about api at https://babeljs.io/docs/en/config-files#apicache
|
||||
|
||||
const development = api.env(developmentEnvironments);
|
||||
const development = api.env(developmentEnvironments);
|
||||
|
||||
return {
|
||||
presets: [
|
||||
[
|
||||
require('@babel/preset-env'),
|
||||
{
|
||||
targets: {electron: require('electron/package.json').version},
|
||||
useBuiltIns: 'usage',
|
||||
},
|
||||
],
|
||||
require('@babel/preset-flow'),
|
||||
[require('@babel/preset-react'), {development}],
|
||||
],
|
||||
plugins: [
|
||||
// Stage 0
|
||||
require('@babel/plugin-proposal-function-bind'),
|
||||
return {
|
||||
presets: [
|
||||
[
|
||||
require('@babel/preset-env'),
|
||||
{
|
||||
targets: {
|
||||
electron: require('electron/package.json').version,
|
||||
},
|
||||
useBuiltIns: 'usage',
|
||||
},
|
||||
],
|
||||
require('@babel/preset-flow'),
|
||||
[require('@babel/preset-react'), {development}],
|
||||
],
|
||||
plugins: [
|
||||
// Stage 0
|
||||
require('@babel/plugin-proposal-function-bind'),
|
||||
|
||||
// Stage 1
|
||||
require('@babel/plugin-proposal-export-default-from'),
|
||||
require('@babel/plugin-proposal-logical-assignment-operators'),
|
||||
[require('@babel/plugin-proposal-optional-chaining'), {loose: false}],
|
||||
[
|
||||
require('@babel/plugin-proposal-pipeline-operator'),
|
||||
{proposal: 'minimal'},
|
||||
],
|
||||
[
|
||||
require('@babel/plugin-proposal-nullish-coalescing-operator'),
|
||||
{loose: false},
|
||||
],
|
||||
require('@babel/plugin-proposal-do-expressions'),
|
||||
// Stage 1
|
||||
require('@babel/plugin-proposal-export-default-from'),
|
||||
require('@babel/plugin-proposal-logical-assignment-operators'),
|
||||
[
|
||||
require('@babel/plugin-proposal-optional-chaining'),
|
||||
{loose: false},
|
||||
],
|
||||
[
|
||||
require('@babel/plugin-proposal-pipeline-operator'),
|
||||
{proposal: 'minimal'},
|
||||
],
|
||||
[
|
||||
require('@babel/plugin-proposal-nullish-coalescing-operator'),
|
||||
{loose: false},
|
||||
],
|
||||
require('@babel/plugin-proposal-do-expressions'),
|
||||
|
||||
// Stage 2
|
||||
[require('@babel/plugin-proposal-decorators'), {legacy: true}],
|
||||
require('@babel/plugin-proposal-function-sent'),
|
||||
require('@babel/plugin-proposal-export-namespace-from'),
|
||||
require('@babel/plugin-proposal-numeric-separator'),
|
||||
require('@babel/plugin-proposal-throw-expressions'),
|
||||
// Stage 2
|
||||
[require('@babel/plugin-proposal-decorators'), {legacy: true}],
|
||||
require('@babel/plugin-proposal-function-sent'),
|
||||
require('@babel/plugin-proposal-export-namespace-from'),
|
||||
require('@babel/plugin-proposal-numeric-separator'),
|
||||
require('@babel/plugin-proposal-throw-expressions'),
|
||||
|
||||
// Stage 3
|
||||
require('@babel/plugin-syntax-dynamic-import'),
|
||||
require('@babel/plugin-syntax-import-meta'),
|
||||
[require('@babel/plugin-proposal-class-properties'), {loose: true}],
|
||||
require('@babel/plugin-proposal-json-strings'),
|
||||
// Stage 3
|
||||
require('@babel/plugin-syntax-dynamic-import'),
|
||||
require('@babel/plugin-syntax-import-meta'),
|
||||
[require('@babel/plugin-proposal-class-properties'), {loose: true}],
|
||||
require('@babel/plugin-proposal-json-strings'),
|
||||
|
||||
...(development ? developmentPlugins : productionPlugins),
|
||||
],
|
||||
};
|
||||
...(development ? developmentPlugins : productionPlugins),
|
||||
],
|
||||
};
|
||||
};
|
||||
|
|
|
@ -4,44 +4,44 @@
|
|||
|
||||
import path from 'path';
|
||||
import webpack from 'webpack';
|
||||
import { dependencies } from '../package.json';
|
||||
import {dependencies} from '../package.json';
|
||||
|
||||
export default {
|
||||
externals: [...Object.keys(dependencies || {})],
|
||||
externals: [...Object.keys(dependencies || {})],
|
||||
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.jsx?$/,
|
||||
exclude: /node_modules/,
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
cacheDirectory: true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.jsx?$/,
|
||||
exclude: /node_modules/,
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
cacheDirectory: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
output: {
|
||||
path: path.join(__dirname, '..', 'app'),
|
||||
// https://github.com/webpack/webpack/issues/1114
|
||||
libraryTarget: 'commonjs2'
|
||||
},
|
||||
output: {
|
||||
path: path.join(__dirname, '..', 'app'),
|
||||
// https://github.com/webpack/webpack/issues/1114
|
||||
libraryTarget: 'commonjs2',
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine the array of extensions that should be used to resolve modules.
|
||||
*/
|
||||
resolve: {
|
||||
extensions: ['.js', '.jsx', '.json']
|
||||
},
|
||||
/**
|
||||
* Determine the array of extensions that should be used to resolve modules.
|
||||
*/
|
||||
resolve: {
|
||||
extensions: ['.js', '.jsx', '.json'],
|
||||
},
|
||||
|
||||
plugins: [
|
||||
new webpack.EnvironmentPlugin({
|
||||
NODE_ENV: 'production'
|
||||
}),
|
||||
plugins: [
|
||||
new webpack.EnvironmentPlugin({
|
||||
NODE_ENV: 'production',
|
||||
}),
|
||||
|
||||
new webpack.NamedModulesPlugin()
|
||||
]
|
||||
new webpack.NamedModulesPlugin(),
|
||||
],
|
||||
};
|
||||
|
|
|
@ -6,68 +6,68 @@ import path from 'path';
|
|||
import webpack from 'webpack';
|
||||
import merge from 'webpack-merge';
|
||||
import TerserPlugin from 'terser-webpack-plugin';
|
||||
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
|
||||
import {BundleAnalyzerPlugin} from 'webpack-bundle-analyzer';
|
||||
import baseConfig from './webpack.config.base';
|
||||
import CheckNodeEnv from '../internals/scripts/CheckNodeEnv';
|
||||
|
||||
CheckNodeEnv('production');
|
||||
|
||||
export default merge.smart(baseConfig, {
|
||||
devtool: 'source-map',
|
||||
devtool: 'source-map',
|
||||
|
||||
mode: 'production',
|
||||
mode: 'production',
|
||||
|
||||
target: 'electron-main',
|
||||
target: 'electron-main',
|
||||
|
||||
entry: './app/main.dev',
|
||||
entry: './app/main.dev',
|
||||
|
||||
output: {
|
||||
path: path.join(__dirname, '..'),
|
||||
filename: './app/main.prod.js'
|
||||
},
|
||||
output: {
|
||||
path: path.join(__dirname, '..'),
|
||||
filename: './app/main.prod.js',
|
||||
},
|
||||
|
||||
optimization: {
|
||||
minimizer: process.env.E2E_BUILD
|
||||
? []
|
||||
: [
|
||||
new TerserPlugin({
|
||||
parallel: true,
|
||||
sourceMap: true,
|
||||
cache: true
|
||||
})
|
||||
]
|
||||
},
|
||||
optimization: {
|
||||
minimizer: process.env.E2E_BUILD
|
||||
? []
|
||||
: [
|
||||
new TerserPlugin({
|
||||
parallel: true,
|
||||
sourceMap: true,
|
||||
cache: true,
|
||||
}),
|
||||
],
|
||||
},
|
||||
|
||||
plugins: [
|
||||
new BundleAnalyzerPlugin({
|
||||
analyzerMode:
|
||||
process.env.OPEN_ANALYZER === 'true' ? 'server' : 'disabled',
|
||||
openAnalyzer: process.env.OPEN_ANALYZER === 'true'
|
||||
}),
|
||||
plugins: [
|
||||
new BundleAnalyzerPlugin({
|
||||
analyzerMode:
|
||||
process.env.OPEN_ANALYZER === 'true' ? 'server' : 'disabled',
|
||||
openAnalyzer: process.env.OPEN_ANALYZER === 'true',
|
||||
}),
|
||||
|
||||
/**
|
||||
* Create global constants which can be configured at compile time.
|
||||
*
|
||||
* Useful for allowing different behaviour between development builds and
|
||||
* release builds
|
||||
*
|
||||
* NODE_ENV should be production so that modules do not perform certain
|
||||
* development checks
|
||||
*/
|
||||
new webpack.EnvironmentPlugin({
|
||||
NODE_ENV: 'production',
|
||||
DEBUG_PROD: false,
|
||||
START_MINIMIZED: false,
|
||||
}),
|
||||
],
|
||||
|
||||
/**
|
||||
* Create global constants which can be configured at compile time.
|
||||
*
|
||||
* Useful for allowing different behaviour between development builds and
|
||||
* release builds
|
||||
*
|
||||
* NODE_ENV should be production so that modules do not perform certain
|
||||
* development checks
|
||||
* Disables webpack processing of __dirname and __filename.
|
||||
* If you run the bundle in node.js it falls back to these values of node.js.
|
||||
* https://github.com/webpack/webpack/issues/2010
|
||||
*/
|
||||
new webpack.EnvironmentPlugin({
|
||||
NODE_ENV: 'production',
|
||||
DEBUG_PROD: false,
|
||||
START_MINIMIZED: false
|
||||
})
|
||||
],
|
||||
|
||||
/**
|
||||
* Disables webpack processing of __dirname and __filename.
|
||||
* If you run the bundle in node.js it falls back to these values of node.js.
|
||||
* https://github.com/webpack/webpack/issues/2010
|
||||
*/
|
||||
node: {
|
||||
__dirname: false,
|
||||
__filename: false
|
||||
}
|
||||
node: {
|
||||
__dirname: false,
|
||||
__filename: false,
|
||||
},
|
||||
});
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue