mirror of
https://github.com/responsively-org/responsively-app
synced 2024-11-10 14:54:12 +00:00
Merge branch 'main' into jibranabsarulislam/zoom100-on-individual-and-persist
This commit is contained in:
commit
3e8e7365f4
17 changed files with 1306 additions and 90 deletions
|
@ -568,6 +568,24 @@
|
|||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "monalisamsteccentric",
|
||||
"name": "Monalisa Sahoo",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/65477771?v=4",
|
||||
"profile": "https://github.com/monalisamsteccentric",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "codewithmitesh",
|
||||
"name": "Mitesh Tank",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/85953650?v=4",
|
||||
"profile": "https://github.com/codewithmitesh",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 5,
|
||||
|
|
|
@ -226,6 +226,8 @@ Thanks go to these wonderful people ([emoji key](https://allcontributors.org/doc
|
|||
<tr>
|
||||
<td align="center" valign="top" width="20%"><a href="https://github.com/ReshadSadik"><img src="https://avatars.githubusercontent.com/u/66641469?v=4?s=100" width="100px;" alt="Reshad Sadik"/><br /><sub><b>Reshad Sadik</b></sub></a><br /><a href="https://github.com/responsively-org/responsively-app/commits?author=ReshadSadik" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="20%"><a href="https://github.com/PeterKwesiAnsah"><img src="https://avatars.githubusercontent.com/u/31078314?v=4?s=100" width="100px;" alt="Kwesi Ansah"/><br /><sub><b>Kwesi Ansah</b></sub></a><br /><a href="https://github.com/responsively-org/responsively-app/commits?author=PeterKwesiAnsah" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="20%"><a href="https://github.com/monalisamsteccentric"><img src="https://avatars.githubusercontent.com/u/65477771?v=4?s=100" width="100px;" alt="Monalisa Sahoo"/><br /><sub><b>Monalisa Sahoo</b></sub></a><br /><a href="https://github.com/responsively-org/responsively-app/commits?author=monalisamsteccentric" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="20%"><a href="https://github.com/codewithmitesh"><img src="https://avatars.githubusercontent.com/u/85953650?v=4?s=100" width="100px;" alt="Mitesh Tank"/><br /><sub><b>Mitesh Tank</b></sub></a><br /><a href="https://github.com/responsively-org/responsively-app/commits?author=codewithmitesh" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "Responsively-App",
|
||||
"productName": "ResponsivelyApp",
|
||||
"version": "1.0.0",
|
||||
"version": "1.4.0",
|
||||
"description": "A developer-friendly browser for developing responsive web apps",
|
||||
"keywords": [
|
||||
"developer-tools",
|
||||
|
@ -27,7 +27,7 @@
|
|||
"build": "concurrently \"yarn run build:main\" \"yarn run build:renderer\"",
|
||||
"build:main": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.main.prod.ts",
|
||||
"build:renderer": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.prod.ts",
|
||||
"postinstall": "yarn rimraf --glob node_modules/browser-sync/dist/**/*.map && yarn replace '\"network-throttle\".*' '' node_modules/browser-sync-ui/lib/UI.js && ts-node .erb/scripts/check-native-dep.js && replace-in-file '/// <reference types=\"howler\" />' \"import { Howl } from 'howler';\" node_modules/use-sound/dist/types.d.ts && electron-builder install-app-deps && cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.dev.dll.ts",
|
||||
"postinstall": "yarn rimraf --glob node_modules/browser-sync/dist/**/*.map && ts-node .erb/scripts/check-native-dep.js && ts-node postinstall.ts && electron-builder install-app-deps && cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.dev.dll.ts",
|
||||
"lint": "cross-env NODE_ENV=development eslint . --ext .js,.jsx,.ts,.tsx",
|
||||
"package": "ts-node ./.erb/scripts/clean.js dist && yarn run build && electron-builder build --publish never",
|
||||
"prepare": "cd .. && husky install desktop-app/.husky && chmod a+x desktop-app/.husky/pre-commit",
|
||||
|
@ -212,7 +212,7 @@
|
|||
"webpack": "^5.76.0",
|
||||
"webpack-bundle-analyzer": "^4.5.0",
|
||||
"webpack-cli": "^4.10.0",
|
||||
"webpack-dev-server": "^4.10.0",
|
||||
"webpack-dev-server": "^4.15.1",
|
||||
"webpack-merge": "^5.8.0"
|
||||
},
|
||||
"build": {
|
||||
|
|
31
desktop-app/postinstall.ts
Normal file
31
desktop-app/postinstall.ts
Normal file
|
@ -0,0 +1,31 @@
|
|||
import { replaceInFile } from 'replace-in-file';
|
||||
|
||||
async function performReplacements() {
|
||||
const replaceOptions = {
|
||||
files: 'node_modules/browser-sync-ui/lib/UI.js',
|
||||
from: /"network-throttle".*/,
|
||||
to: '',
|
||||
};
|
||||
|
||||
const howlerOptions = {
|
||||
files: 'node_modules/use-sound/dist/types.d.ts',
|
||||
from: '/// <reference types="howler" />',
|
||||
to: 'import { Howl } from "howler";',
|
||||
};
|
||||
|
||||
try {
|
||||
await replaceInFile(replaceOptions);
|
||||
console.log('Replacement in UI.js completed successfully.');
|
||||
|
||||
await replaceInFile(howlerOptions);
|
||||
console.log('Replacement in types.d.ts completed successfully.');
|
||||
} catch (error) {
|
||||
console.error('Error occurred during replacements:', error);
|
||||
}
|
||||
}
|
||||
|
||||
async function performPostInstall() {
|
||||
await performReplacements();
|
||||
}
|
||||
|
||||
performPostInstall();
|
17
desktop-app/release/app/package-lock.json
generated
17
desktop-app/release/app/package-lock.json
generated
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "ResponsivelyApp",
|
||||
"version": "1.3.0",
|
||||
"version": "1.4.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "ResponsivelyApp",
|
||||
"version": "1.3.0",
|
||||
"version": "1.4.0",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
@ -1470,10 +1470,9 @@
|
|||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"node_modules/socket.io-parser": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz",
|
||||
"integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==",
|
||||
"license": "MIT",
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
|
||||
"integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
|
||||
"dependencies": {
|
||||
"@socket.io/component-emitter": "~3.1.0",
|
||||
"debug": "~4.3.1"
|
||||
|
@ -2854,9 +2853,9 @@
|
|||
}
|
||||
},
|
||||
"socket.io-parser": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz",
|
||||
"integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==",
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
|
||||
"integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
|
||||
"requires": {
|
||||
"@socket.io/component-emitter": "~3.1.0",
|
||||
"debug": "~4.3.1"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "ResponsivelyApp",
|
||||
"version": "1.3.0",
|
||||
"version": "1.4.0",
|
||||
"description": "A developer-friendly browser for developing responsive web apps",
|
||||
"license": "MIT",
|
||||
"author": {
|
||||
|
|
1031
desktop-app/release/app/yarn.lock
Normal file
1031
desktop-app/release/app/yarn.lock
Normal file
File diff suppressed because it is too large
Load diff
|
@ -27,6 +27,8 @@ export const IPC_MAIN_CHANNELS = {
|
|||
AUTH_RESPONSE: 'auth-response',
|
||||
OPEN_EXTERNAL: 'open-external',
|
||||
OPEN_URL: 'open-url',
|
||||
START_WATCHING_FILE: 'start-watching-file',
|
||||
STOP_WATCHER: 'stop-watcher',
|
||||
} as const;
|
||||
|
||||
export type Channels = typeof IPC_MAIN_CHANNELS[keyof typeof IPC_MAIN_CHANNELS];
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||
import BrowserSync, { BrowserSyncInstance } from 'browser-sync';
|
||||
import fs from 'fs-extra';
|
||||
|
||||
export const BROWSER_SYNC_PORT = 12719;
|
||||
export const BROWSER_SYNC_HOST = `localhost:${BROWSER_SYNC_PORT}`;
|
||||
|
@ -7,6 +9,8 @@ export const BROWSER_SYNC_URL = `https://${BROWSER_SYNC_HOST}/browser-sync/brows
|
|||
const browserSyncEmbed: BrowserSyncInstance = BrowserSync.create('embed');
|
||||
|
||||
let created = false;
|
||||
let filesWatcher: ReturnType<BrowserSyncInstance['watch']> | null = null;
|
||||
let cssWatcher: ReturnType<BrowserSyncInstance['watch']> | null = null;
|
||||
|
||||
export async function initInstance(): Promise<BrowserSyncInstance> {
|
||||
if (created) {
|
||||
|
@ -32,3 +36,35 @@ export async function initInstance(): Promise<BrowserSyncInstance> {
|
|||
);
|
||||
});
|
||||
}
|
||||
|
||||
export function watchFiles(filePath: string) {
|
||||
if (filePath && fs.existsSync(filePath)) {
|
||||
const fileDir = filePath.substring(0, filePath.lastIndexOf('/'));
|
||||
|
||||
filesWatcher = browserSyncEmbed
|
||||
// @ts-expect-error
|
||||
.watch([filePath, `${fileDir}/**/**.js`])
|
||||
.on('change', browserSyncEmbed.reload);
|
||||
|
||||
cssWatcher = browserSyncEmbed.watch(
|
||||
`${fileDir}/**/**.css`,
|
||||
// @ts-expect-error
|
||||
(event: string, file: string) => {
|
||||
if (event === 'change') {
|
||||
browserSyncEmbed.reload(file);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function stopWatchFiles() {
|
||||
if (filesWatcher) {
|
||||
// @ts-expect-error
|
||||
await filesWatcher.close();
|
||||
}
|
||||
if (cssWatcher) {
|
||||
// @ts-expect-error
|
||||
await cssWatcher.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,14 +9,19 @@
|
|||
* `./src/main.js` using webpack. This gives us some performance wins.
|
||||
*/
|
||||
import path from 'path';
|
||||
import { app, BrowserWindow, shell, screen } from 'electron';
|
||||
import { app, BrowserWindow, shell, screen, ipcMain } from 'electron';
|
||||
import { autoUpdater } from 'electron-updater';
|
||||
import log from 'electron-log';
|
||||
import cli from './cli';
|
||||
import { PROTOCOL } from '../common/constants';
|
||||
import MenuBuilder from './menu';
|
||||
import { isValidCliArgURL, resolveHtmlPath } from './util';
|
||||
import { BROWSER_SYNC_HOST, initInstance } from './browser-sync';
|
||||
import { resolveHtmlPath } from './util';
|
||||
import {
|
||||
BROWSER_SYNC_HOST,
|
||||
initInstance,
|
||||
stopWatchFiles,
|
||||
watchFiles,
|
||||
} from './browser-sync';
|
||||
import store from '../store';
|
||||
import { initWebviewContextMenu } from './webview-context-menu/register';
|
||||
import { initScreenshotHandlers } from './screenshot';
|
||||
|
@ -197,6 +202,19 @@ const createWindow = async () => {
|
|||
return { action: 'deny' };
|
||||
});
|
||||
|
||||
ipcMain.on('start-watching-file', async (event, fileInfo) => {
|
||||
let filePath = fileInfo.path.replace('file://', '');
|
||||
if (process.platform === 'win32') {
|
||||
filePath = filePath.replace(/^\//, '');
|
||||
}
|
||||
app.addRecentDocument(filePath);
|
||||
await stopWatchFiles();
|
||||
watchFiles(filePath);
|
||||
});
|
||||
|
||||
ipcMain.on('stop-watcher', async () => {
|
||||
await stopWatchFiles();
|
||||
});
|
||||
// Remove this if your app does not use auto updates
|
||||
// eslint-disable-next-line
|
||||
new AppUpdater();
|
||||
|
|
|
@ -6,6 +6,8 @@ interface CustomProps {
|
|||
className?: string;
|
||||
isActive?: boolean;
|
||||
isLoading?: boolean;
|
||||
isPrimary?: boolean;
|
||||
isTextButton?: boolean;
|
||||
disableHoverEffects?: boolean;
|
||||
isActionButton?: boolean;
|
||||
subtle?: boolean;
|
||||
|
@ -15,6 +17,8 @@ const Button = ({
|
|||
className = '',
|
||||
isActive = false,
|
||||
isLoading = false,
|
||||
isPrimary = false,
|
||||
isTextButton = false,
|
||||
isActionButton = false,
|
||||
subtle = false,
|
||||
disableHoverEffects = false,
|
||||
|
@ -38,10 +42,15 @@ const Button = ({
|
|||
prevLoadingState.current = isLoading;
|
||||
}, [isLoading]);
|
||||
|
||||
const hoverBg = subtle ? 'hover:bg-slate-200' : 'hover:bg-slate-400';
|
||||
const hoverBgDark = subtle
|
||||
? 'dark:hover:bg-slate-700'
|
||||
: 'dark:hover:bg-slate-600';
|
||||
let hoverBg = 'hover:bg-slate-400';
|
||||
let hoverBgDark = 'dark:hover:bg-slate-600';
|
||||
if (subtle) {
|
||||
hoverBg = 'hover:bg-slate-200';
|
||||
hoverBgDark = 'dark:hover:bg-slate-700';
|
||||
} else if (isPrimary) {
|
||||
hoverBg = 'hover:bg-slate-800';
|
||||
hoverBgDark = 'dark:hover:bg-slate-100';
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
|
@ -51,11 +60,13 @@ const Button = ({
|
|||
disableHoverEffects === false ? `${hoverBg} ${hoverBgDark}` : ''
|
||||
} focus:outline-none`,
|
||||
{
|
||||
'bg-slate-400/60': isActive,
|
||||
'dark:bg-slate-600/60': isActive,
|
||||
'bg-slate-400/60': isActive && !isPrimary,
|
||||
'dark:bg-slate-600/60': isActive && !isPrimary,
|
||||
'bg-slate-600 text-white': isPrimary,
|
||||
'dark:bg-slate-300 dark:text-gray-900': isPrimary,
|
||||
'bg-slate-200': isActionButton,
|
||||
'dark:bg-slate-700': isActionButton,
|
||||
'px-2': isActionButton,
|
||||
'px-2': isActionButton || isTextButton,
|
||||
}
|
||||
)}
|
||||
type="button"
|
||||
|
|
|
@ -123,48 +123,52 @@ const Toolbar = ({
|
|||
};
|
||||
|
||||
return (
|
||||
<div className="my-1 flex items-center gap-1">
|
||||
<Button
|
||||
onClick={quickScreenshot}
|
||||
isLoading={screenshotLoading}
|
||||
title="Quick Screenshot"
|
||||
>
|
||||
<div className="relative h-4 w-4">
|
||||
<div className="flex items-center justify-between gap-1">
|
||||
<div className="my-1 flex items-center gap-1">
|
||||
<Button
|
||||
onClick={quickScreenshot}
|
||||
isLoading={screenshotLoading}
|
||||
title="Quick Screenshot"
|
||||
>
|
||||
<div className="relative h-4 w-4">
|
||||
<Icon
|
||||
icon="ic:outline-photo-camera"
|
||||
className="absolute top-0 left-0"
|
||||
/>
|
||||
<Icon
|
||||
icon="clarity:lightning-solid"
|
||||
className="absolute top-[-1px] right-[-2px]"
|
||||
height={8}
|
||||
/>
|
||||
</div>
|
||||
</Button>
|
||||
<Button
|
||||
onClick={fullScreenshot}
|
||||
isLoading={fullScreenshotLoading}
|
||||
title="Full Page Screenshot"
|
||||
>
|
||||
<Icon icon="ic:outline-photo-camera" />
|
||||
</Button>
|
||||
<Button
|
||||
onClick={toggleEventMirroring}
|
||||
isActive={eventMirroringOff}
|
||||
title="Disable Event Mirroring"
|
||||
>
|
||||
<Icon icon="fluent:plug-disconnected-24-regular" />
|
||||
</Button>
|
||||
<Button onClick={openDevTools} title="Open Devtools">
|
||||
<Icon icon="ic:round-code" />
|
||||
</Button>
|
||||
<Button onClick={rotate} isActive={rotated} title="Rotate This Device">
|
||||
<Icon
|
||||
icon="ic:outline-photo-camera"
|
||||
className="absolute top-0 left-0"
|
||||
icon={
|
||||
rotated
|
||||
? 'mdi:phone-rotate-portrait'
|
||||
: 'mdi:phone-rotate-landscape'
|
||||
}
|
||||
/>
|
||||
<Icon
|
||||
icon="clarity:lightning-solid"
|
||||
className="absolute top-[-1px] right-[-2px]"
|
||||
height={8}
|
||||
/>
|
||||
</div>
|
||||
</Button>
|
||||
<Button
|
||||
onClick={fullScreenshot}
|
||||
isLoading={fullScreenshotLoading}
|
||||
title="Full Page Screenshot"
|
||||
>
|
||||
<Icon icon="ic:outline-photo-camera" />
|
||||
</Button>
|
||||
<Button
|
||||
onClick={toggleEventMirroring}
|
||||
isActive={eventMirroringOff}
|
||||
title="Disable Event Mirroring"
|
||||
>
|
||||
<Icon icon="fluent:plug-disconnected-24-regular" />
|
||||
</Button>
|
||||
<Button onClick={openDevTools} title="Open Devtools">
|
||||
<Icon icon="ic:round-code" />
|
||||
</Button>
|
||||
<Button onClick={rotate} isActive={rotated} title="Rotate This Device">
|
||||
<Icon
|
||||
icon={
|
||||
rotated ? 'mdi:phone-rotate-portrait' : 'mdi:phone-rotate-landscape'
|
||||
}
|
||||
/>
|
||||
</Button>
|
||||
</Button>
|
||||
</div>
|
||||
<Button
|
||||
onClick={() => onIndividualLayoutHandler(device)}
|
||||
title={`${isIndividualLayout ? 'Disable' : 'Enable'} Individual Layout`}
|
||||
|
|
|
@ -42,11 +42,11 @@ const IndividualLayoutToolbar = ({
|
|||
<Tabs
|
||||
onSelect={onTabClick}
|
||||
selectedIndex={activeTab}
|
||||
className={cx('react-tabs flex')}
|
||||
className={cx('react-tabs flex flex-1')}
|
||||
>
|
||||
<TabList
|
||||
className={cx(
|
||||
'custom-scrollbar flex gap-1 overflow-x-auto border-b border-slate-400/60 dark:border-white'
|
||||
'custom-scrollbar flex flex-1 justify-center gap-1 overflow-x-auto border-b border-slate-400/60 dark:border-white'
|
||||
)}
|
||||
>
|
||||
{devices.map((device, idx) => (
|
||||
|
|
|
@ -101,7 +101,7 @@ const ReleaseNotes = () => {
|
|||
</ReactMarkdown>
|
||||
</div>
|
||||
<div className="mt-10 flex justify-between gap-12">
|
||||
<div className="flex">
|
||||
<div className="flex gap-1">
|
||||
<Button
|
||||
onClick={() => {
|
||||
window.electron.ipcRenderer.sendMessage(
|
||||
|
@ -112,13 +112,13 @@ const ReleaseNotes = () => {
|
|||
);
|
||||
closeAndMarkAsRead();
|
||||
}}
|
||||
isActionButton
|
||||
isActive
|
||||
tabIndex={0}
|
||||
isActionButton
|
||||
isTextButton
|
||||
>
|
||||
Release Notes
|
||||
</Button>
|
||||
<Button onClick={closeAndMarkAsRead} isActionButton>
|
||||
<Button onClick={closeAndMarkAsRead} isActionButton isTextButton>
|
||||
Close
|
||||
</Button>
|
||||
</div>
|
||||
|
@ -132,8 +132,8 @@ const ReleaseNotes = () => {
|
|||
}
|
||||
);
|
||||
}}
|
||||
isActionButton
|
||||
isActive
|
||||
isPrimary
|
||||
isTextButton
|
||||
>
|
||||
Support Responsively App
|
||||
</Button>
|
||||
|
|
|
@ -8,6 +8,7 @@ import {
|
|||
setRotate,
|
||||
} from 'renderer/store/features/renderer';
|
||||
import { Icon } from '@iconify/react';
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { ScreenshotAllArgs } from 'main/screenshot';
|
||||
import { selectActiveSuite } from 'renderer/store/features/device-manager';
|
||||
import WebPage from 'main/screenshot/webpage';
|
||||
|
@ -30,6 +31,10 @@ const ToolBar = () => {
|
|||
const activeSuite = useSelector(selectActiveSuite);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
function handleInspectShortcut() {
|
||||
dispatch(setIsInspecting(!isInspecting));
|
||||
}
|
||||
|
||||
const screenshotCaptureHandler = async () => {
|
||||
dispatch(setIsCapturingScreenshot(true));
|
||||
const webViews: NodeListOf<Electron.WebviewTag> =
|
||||
|
@ -75,10 +80,32 @@ const ToolBar = () => {
|
|||
// Do nothing. Prevent Dialog from closing.
|
||||
};
|
||||
|
||||
function useKey(key: string, cb: () => void) {
|
||||
const callbackRef = useRef(cb);
|
||||
|
||||
useEffect(() => {
|
||||
callbackRef.current = cb;
|
||||
}, [cb]);
|
||||
|
||||
useEffect(() => {
|
||||
function handle(event: { code: string }) {
|
||||
if (event.code === key) {
|
||||
callbackRef.current();
|
||||
}
|
||||
}
|
||||
// current(event)
|
||||
document.addEventListener('keypress', handle);
|
||||
return () => document.removeEventListener('keypress', handle);
|
||||
}, [key]);
|
||||
}
|
||||
// setting shortcut I for inspect element
|
||||
useKey('KeyI', handleInspectShortcut);
|
||||
return (
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<NavigationControls />
|
||||
|
||||
<AddressBar />
|
||||
|
||||
<Button
|
||||
onClick={() => dispatch(setRotate(!rotateDevices))}
|
||||
isActive={rotateDevices}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { createSlice } from '@reduxjs/toolkit';
|
||||
import type { PayloadAction } from '@reduxjs/toolkit';
|
||||
import { PREVIEW_LAYOUTS, PreviewLayout } from 'common/constants';
|
||||
import { IPC_MAIN_CHANNELS, PREVIEW_LAYOUTS, PreviewLayout } from 'common/constants';
|
||||
import type { RootState } from '../..';
|
||||
|
||||
export interface RendererState {
|
||||
|
@ -37,12 +37,27 @@ const initialState: RendererState = {
|
|||
isCapturingScreenshot: false,
|
||||
};
|
||||
|
||||
export const updateFileWatcher = (newURL: string) => {
|
||||
if (
|
||||
newURL.startsWith('file://') &&
|
||||
(newURL.endsWith('.html') || newURL.endsWith('.htm'))
|
||||
)
|
||||
window.electron.ipcRenderer.sendMessage(
|
||||
IPC_MAIN_CHANNELS.START_WATCHING_FILE,
|
||||
{
|
||||
path: newURL,
|
||||
}
|
||||
);
|
||||
else window.electron.ipcRenderer.sendMessage(IPC_MAIN_CHANNELS.STOP_WATCHER);
|
||||
};
|
||||
|
||||
export const rendererSlice = createSlice({
|
||||
name: 'renderer',
|
||||
initialState,
|
||||
reducers: {
|
||||
setAddress: (state, action: PayloadAction<string>) => {
|
||||
if (action.payload !== state.address) {
|
||||
updateFileWatcher(action.payload);
|
||||
state.address = action.payload;
|
||||
}
|
||||
},
|
||||
|
|
|
@ -2526,10 +2526,10 @@
|
|||
tapable "^2.2.0"
|
||||
webpack "^5"
|
||||
|
||||
"@types/ws@^8.5.1":
|
||||
version "8.5.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d"
|
||||
integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==
|
||||
"@types/ws@^8.5.5":
|
||||
version "8.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.5.tgz#af587964aa06682702ee6dcbc7be41a80e4b28eb"
|
||||
integrity sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
|
@ -4364,6 +4364,11 @@ clone@^1.0.0, clone@^1.0.2:
|
|||
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
|
||||
integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==
|
||||
|
||||
clsx@^1.1.0:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12"
|
||||
integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
|
||||
|
||||
co@^4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
|
||||
|
@ -8983,6 +8988,14 @@ language-tags@^1.0.5:
|
|||
dependencies:
|
||||
language-subtag-registry "~0.3.2"
|
||||
|
||||
launch-editor@^2.6.0:
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.6.0.tgz#4c0c1a6ac126c572bd9ff9a30da1d2cae66defd7"
|
||||
integrity sha512-JpDCcQnyAAzZZaZ7vEiSqL690w7dAEyLao+KC96zBplnYbJS7TYNjvM3M7y3dGz+v7aIsJk3hllWuc0kWAjyRQ==
|
||||
dependencies:
|
||||
picocolors "^1.0.0"
|
||||
shell-quote "^1.7.3"
|
||||
|
||||
lazy-cache@^1.0.3:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e"
|
||||
|
@ -11163,7 +11176,7 @@ prompts@^2.0.1:
|
|||
kleur "^3.0.3"
|
||||
sisteransi "^1.0.5"
|
||||
|
||||
prop-types@^15.0.0, prop-types@^15.8.1:
|
||||
prop-types@^15.0.0, prop-types@^15.5.0, prop-types@^15.8.1:
|
||||
version "15.8.1"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
|
||||
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
||||
|
@ -11364,6 +11377,14 @@ react-shallow-renderer@^16.15.0:
|
|||
object-assign "^4.1.1"
|
||||
react-is "^16.12.0 || ^17.0.0 || ^18.0.0"
|
||||
|
||||
react-tabs@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/react-tabs/-/react-tabs-6.0.1.tgz#3fdb6fd7408f38adfa7b1815b607cd5228e76c8b"
|
||||
integrity sha512-XE5D/iCcwUsr06wf6fWrjA/HbUaj3G2+6NMVJygZuKALHkWYp+D3ZPcG2VctuaOHHzMU48eSOuxwBALBnuXldA==
|
||||
dependencies:
|
||||
clsx "^1.1.0"
|
||||
prop-types "^15.5.0"
|
||||
|
||||
react-test-renderer@^18.2.0:
|
||||
version "18.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-18.2.0.tgz#1dd912bd908ff26da5b9fca4fd1c489b9523d37e"
|
||||
|
@ -12367,9 +12388,9 @@ socket.io-client@^4.4.1:
|
|||
socket.io-parser "~4.2.1"
|
||||
|
||||
socket.io-parser@~4.2.1:
|
||||
version "4.2.2"
|
||||
resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.2.2.tgz#1dd384019e25b7a3d374877f492ab34f2ad0d206"
|
||||
integrity sha512-DJtziuKypFkMMHCm2uIshOYC7QaylbtzQwiMYDuCKy3OPkjLzu4B2vAhTlqipRHHzrI0NJeBAizTK7X+6m1jVw==
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.2.3.tgz#926bcc6658e2ae0883dc9dee69acbdc76e4e3667"
|
||||
integrity sha512-JMafRntWVO2DCJimKsRTh/wnqVvO4hrfwOqtO7f+uzwsQMuxO6VwImtYxaQ+ieoyshWOTJyV0fA21lccEXRPpQ==
|
||||
dependencies:
|
||||
"@socket.io/component-emitter" "~3.1.0"
|
||||
debug "~4.3.1"
|
||||
|
@ -13821,10 +13842,10 @@ webpack-dev-middleware@^5.3.1:
|
|||
range-parser "^1.2.1"
|
||||
schema-utils "^4.0.0"
|
||||
|
||||
webpack-dev-server@^4.10.0:
|
||||
version "4.11.1"
|
||||
resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz#ae07f0d71ca0438cf88446f09029b92ce81380b5"
|
||||
integrity sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==
|
||||
webpack-dev-server@^4.15.1:
|
||||
version "4.15.1"
|
||||
resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz#8944b29c12760b3a45bdaa70799b17cb91b03df7"
|
||||
integrity sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==
|
||||
dependencies:
|
||||
"@types/bonjour" "^3.5.9"
|
||||
"@types/connect-history-api-fallback" "^1.3.5"
|
||||
|
@ -13832,7 +13853,7 @@ webpack-dev-server@^4.10.0:
|
|||
"@types/serve-index" "^1.9.1"
|
||||
"@types/serve-static" "^1.13.10"
|
||||
"@types/sockjs" "^0.3.33"
|
||||
"@types/ws" "^8.5.1"
|
||||
"@types/ws" "^8.5.5"
|
||||
ansi-html-community "^0.0.8"
|
||||
bonjour-service "^1.0.11"
|
||||
chokidar "^3.5.3"
|
||||
|
@ -13845,6 +13866,7 @@ webpack-dev-server@^4.10.0:
|
|||
html-entities "^2.3.2"
|
||||
http-proxy-middleware "^2.0.3"
|
||||
ipaddr.js "^2.0.1"
|
||||
launch-editor "^2.6.0"
|
||||
open "^8.0.9"
|
||||
p-retry "^4.5.0"
|
||||
rimraf "^3.0.2"
|
||||
|
@ -13854,7 +13876,7 @@ webpack-dev-server@^4.10.0:
|
|||
sockjs "^0.3.24"
|
||||
spdy "^4.0.2"
|
||||
webpack-dev-middleware "^5.3.1"
|
||||
ws "^8.4.2"
|
||||
ws "^8.13.0"
|
||||
|
||||
webpack-merge@^5.7.3, webpack-merge@^5.8.0:
|
||||
version "5.8.0"
|
||||
|
@ -14068,10 +14090,10 @@ ws@^7.3.1:
|
|||
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591"
|
||||
integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==
|
||||
|
||||
ws@^8.2.3, ws@^8.4.2:
|
||||
version "8.10.0"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.10.0.tgz#00a28c09dfb76eae4eb45c3b565f771d6951aa51"
|
||||
integrity sha512-+s49uSmZpvtAsd2h37vIPy1RBusaLawVe8of+GyEPsaJTCMpj/2v8NpeK1SHXjBlQ95lQTmQofOJnFiLoaN3yw==
|
||||
ws@^8.13.0, ws@^8.2.3:
|
||||
version "8.13.0"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0"
|
||||
integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==
|
||||
|
||||
ws@~8.2.3:
|
||||
version "8.2.3"
|
||||
|
|
Loading…
Reference in a new issue