mirror of
https://github.com/responsively-org/responsively-app
synced 2024-09-20 22:31:59 +00:00
Preview layout modes, default devices refined and minor UI polish
This commit is contained in:
parent
fc9e502a6a
commit
2510ac47d9
8 changed files with 93 additions and 12 deletions
|
@ -42,7 +42,7 @@
|
|||
},
|
||||
"lint-staged": {
|
||||
"*.{js,jsx,ts,tsx}": [
|
||||
"cross-env NODE_ENV=development eslint --cache"
|
||||
"cross-env NODE_ENV=development eslint --cache --fix"
|
||||
],
|
||||
"*.json,.{eslintrc,prettierrc}": [
|
||||
"prettier --ignore-path .eslintignore --parser json --write"
|
||||
|
|
|
@ -5,3 +5,11 @@ export const DOCK_POSITION = {
|
|||
RIGHT: 'RIGHT',
|
||||
UNDOCKED: 'UNDOCKED',
|
||||
} as const;
|
||||
|
||||
export const PREVIEW_LAYOUTS = {
|
||||
COLUMN: 'COLUMN',
|
||||
FLEX: 'FLEX',
|
||||
} as const;
|
||||
|
||||
export type PreviewLayout =
|
||||
typeof PREVIEW_LAYOUTS[keyof typeof PREVIEW_LAYOUTS];
|
||||
|
|
|
@ -606,7 +606,8 @@ const devices: Device[] = [
|
|||
height: 1280,
|
||||
dpi: 1,
|
||||
capabilities: ['touch'],
|
||||
userAgent: '',
|
||||
userAgent:
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 13_0_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36',
|
||||
type: 'notebook',
|
||||
isTouchCapable: true,
|
||||
isMobileCapable: false,
|
||||
|
@ -617,7 +618,8 @@ const devices: Device[] = [
|
|||
height: 1440,
|
||||
dpi: 2,
|
||||
capabilities: [],
|
||||
userAgent: '',
|
||||
userAgent:
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 13_0_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36',
|
||||
type: 'notebook',
|
||||
isTouchCapable: false,
|
||||
isMobileCapable: false,
|
||||
|
@ -628,7 +630,20 @@ const devices: Device[] = [
|
|||
height: 1280,
|
||||
dpi: 1,
|
||||
capabilities: [],
|
||||
userAgent: '',
|
||||
userAgent:
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 13_0_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36',
|
||||
type: 'notebook',
|
||||
isTouchCapable: false,
|
||||
isMobileCapable: false,
|
||||
},
|
||||
{
|
||||
name: 'Macbook Pro',
|
||||
width: 1440,
|
||||
height: 900,
|
||||
dpi: 2,
|
||||
capabilities: [],
|
||||
userAgent:
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 13_0_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36',
|
||||
type: 'notebook',
|
||||
isTouchCapable: false,
|
||||
isMobileCapable: false,
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import { useSelector } from 'react-redux';
|
||||
import cx from 'classnames';
|
||||
import { selectDevices } from 'renderer/store/features/device-manager';
|
||||
import { DOCK_POSITION } from 'common/constants';
|
||||
import { DOCK_POSITION, PREVIEW_LAYOUTS } from 'common/constants';
|
||||
import {
|
||||
selectDockPosition,
|
||||
selectIsDevtoolsOpen,
|
||||
} from 'renderer/store/features/devtools';
|
||||
import { selectLayout } from 'renderer/store/features/renderer';
|
||||
import Device from './Device';
|
||||
import DevtoolsResizer from './DevtoolsResizer';
|
||||
|
||||
|
@ -13,6 +14,7 @@ const Previewer = () => {
|
|||
const devices = useSelector(selectDevices);
|
||||
const dockPosition = useSelector(selectDockPosition);
|
||||
const isDevtoolsOpen = useSelector(selectIsDevtoolsOpen);
|
||||
const layout = useSelector(selectLayout);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
@ -21,7 +23,11 @@ const Previewer = () => {
|
|||
'flex-row': dockPosition === DOCK_POSITION.RIGHT,
|
||||
})}
|
||||
>
|
||||
<div className="flex gap-4 overflow-auto p-4">
|
||||
<div
|
||||
className={cx('flex h-full gap-4 overflow-auto p-4', {
|
||||
'flex-wrap': layout === PREVIEW_LAYOUTS.FLEX,
|
||||
})}
|
||||
>
|
||||
{devices.map((device, idx) => {
|
||||
return (
|
||||
<Device key={device.name} device={device} isPrimary={idx === 0} />
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
import { Icon } from '@iconify/react';
|
||||
import { PREVIEW_LAYOUTS } from 'common/constants';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import Toggle from 'renderer/components/Toggle';
|
||||
import { selectLayout, setLayout } from 'renderer/store/features/renderer';
|
||||
|
||||
const PreviewLayout = () => {
|
||||
const layout = useSelector(selectLayout);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
return (
|
||||
<div className="flex flex-row items-center justify-start px-4">
|
||||
<span className="w-1/2">Preview Layout</span>
|
||||
<div className="flex w-fit items-center gap-3 border-l px-5 dark:border-slate-400">
|
||||
<Icon icon="radix-icons:layout" />
|
||||
<Toggle
|
||||
isOn={layout === PREVIEW_LAYOUTS.FLEX}
|
||||
onChange={(e) => {
|
||||
if (e.target.checked) {
|
||||
dispatch(setLayout(PREVIEW_LAYOUTS.FLEX));
|
||||
} else {
|
||||
dispatch(setLayout(PREVIEW_LAYOUTS.COLUMN));
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Icon icon="lucide:layout-dashboard" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PreviewLayout;
|
|
@ -7,6 +7,7 @@ import UITheme from './UITheme';
|
|||
import Zoom from './Zoom';
|
||||
import AllowInSecureSSL from './AllowInSecureSSL';
|
||||
import ClearHistory from './ClearHistory';
|
||||
import PreviewLayout from './PreviewLayout';
|
||||
|
||||
const MenuFlyout = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
@ -14,6 +15,7 @@ const MenuFlyout = () => {
|
|||
return (
|
||||
<div className="absolute top-[26px] right-[4px] z-50 flex w-80 flex-col gap-2 rounded bg-white p-2 text-sm shadow-lg ring-1 ring-slate-500 !ring-opacity-40 focus:outline-none dark:bg-slate-900 dark:ring-white dark:!ring-opacity-40">
|
||||
<Zoom />
|
||||
<PreviewLayout />
|
||||
<UITheme />
|
||||
<Devtools />
|
||||
<AllowInSecureSSL />
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { createSlice } from '@reduxjs/toolkit';
|
||||
import type { PayloadAction } from '@reduxjs/toolkit';
|
||||
import { PreviewLayout } from 'common/constants';
|
||||
import type { RootState } from '../..';
|
||||
|
||||
export interface RendererState {
|
||||
|
@ -7,17 +8,19 @@ export interface RendererState {
|
|||
zoomFactor: number;
|
||||
rotate: boolean;
|
||||
isInspecting: boolean | undefined;
|
||||
layout: PreviewLayout;
|
||||
}
|
||||
|
||||
const zoomSteps = [
|
||||
0.25, 0.33, 0.5, 0.67, 0.75, 0.8, 0.9, 1, 1.1, 1.25, 1.5, 1.75, 2,
|
||||
0.25, 0.33, 0.5, 0.55, 0.67, 0.75, 0.8, 0.9, 1, 1.1, 1.25, 1.5, 1.75, 2,
|
||||
];
|
||||
|
||||
const initialState: RendererState = {
|
||||
address: window.electron.store.get('homepage'),
|
||||
zoomFactor: zoomSteps[4],
|
||||
zoomFactor: zoomSteps[3],
|
||||
rotate: false,
|
||||
isInspecting: undefined,
|
||||
layout: window.electron.store.get('ui.previewLayout'),
|
||||
};
|
||||
|
||||
export const rendererSlice = createSlice({
|
||||
|
@ -47,17 +50,28 @@ export const rendererSlice = createSlice({
|
|||
setIsInspecting: (state, action: PayloadAction<boolean>) => {
|
||||
state.isInspecting = action.payload;
|
||||
},
|
||||
setLayout: (state, action: PayloadAction<PreviewLayout>) => {
|
||||
state.layout = action.payload;
|
||||
window.electron.store.set('ui.previewLayout', action.payload);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Action creators are generated for each case reducer function
|
||||
export const { setAddress, zoomIn, zoomOut, setRotate, setIsInspecting } =
|
||||
rendererSlice.actions;
|
||||
export const {
|
||||
setAddress,
|
||||
zoomIn,
|
||||
zoomOut,
|
||||
setRotate,
|
||||
setIsInspecting,
|
||||
setLayout,
|
||||
} = rendererSlice.actions;
|
||||
|
||||
export const selectZoomFactor = (state: RootState) => state.renderer.zoomFactor;
|
||||
export const selectAddress = (state: RootState) => state.renderer.address;
|
||||
export const selectRotate = (state: RootState) => state.renderer.rotate;
|
||||
export const selectIsInspecting = (state: RootState) =>
|
||||
state.renderer.isInspecting;
|
||||
export const selectLayout = (state: RootState) => state.renderer.layout;
|
||||
|
||||
export default rendererSlice.reducer;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { DOCK_POSITION } from '../common/constants';
|
||||
import { DOCK_POSITION, PREVIEW_LAYOUTS } from '../common/constants';
|
||||
|
||||
const Store = require('electron-store');
|
||||
|
||||
|
@ -10,6 +10,10 @@ const schema = {
|
|||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
previewlayout: {
|
||||
enum: Object.values(PREVIEW_LAYOUTS),
|
||||
default: PREVIEW_LAYOUTS.FLEX,
|
||||
},
|
||||
},
|
||||
},
|
||||
devtools: {
|
||||
|
@ -30,7 +34,7 @@ const schema = {
|
|||
items: {
|
||||
type: 'string',
|
||||
},
|
||||
default: ['iPhone SE', 'iPhone XR', 'iPhone 12 Pro'],
|
||||
default: ['iPhone 12 Pro', 'iPad', 'Macbook Pro'],
|
||||
},
|
||||
customDevices: {
|
||||
type: 'array',
|
||||
|
|
Loading…
Reference in a new issue