Merge branch 'develop' into dev
This commit is contained in:
@@ -1,18 +1,13 @@
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
import { Box, Button, Grid, Typography } from '@mui/joy';
|
import { Box, Grid, Typography } from '@mui/joy';
|
||||||
import Option from '@mui/joy/Option';
|
|
||||||
import Select from '@mui/joy/Select';
|
|
||||||
// eslint-disable-next-line no-restricted-imports
|
// eslint-disable-next-line no-restricted-imports
|
||||||
import { useMediaQuery } from '@mui/material';
|
import { useMediaQuery } from '@mui/material';
|
||||||
|
|
||||||
import 'github-markdown-css';
|
import 'github-markdown-css';
|
||||||
import AboutText from './about.mdx';
|
import AboutText from './about.mdx';
|
||||||
import { AFFiNEFooter, AFFiNEImage } from './Common';
|
import { AFFiNEFooter, AFFiNEHeader, AFFiNEImage } from './Common';
|
||||||
import { options } from './i18n';
|
|
||||||
import KeepUpdate from './keeupdate.png';
|
import KeepUpdate from './keeupdate.png';
|
||||||
|
|
||||||
export const AboutUs = () => {
|
export const AboutUs = () => {
|
||||||
const matches = useMediaQuery('(max-width: 1024px)');
|
const matches = useMediaQuery('(max-width: 1024px)');
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -23,58 +18,7 @@ export const AboutUs = () => {
|
|||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Grid
|
<AFFiNEHeader />
|
||||||
container
|
|
||||||
spacing={2}
|
|
||||||
sx={{
|
|
||||||
maxWidth: '1280px',
|
|
||||||
margin: 'auto',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Grid xs={6}>
|
|
||||||
<Button
|
|
||||||
size="lg"
|
|
||||||
variant="plain"
|
|
||||||
onClick={() => navigate('/')}
|
|
||||||
sx={{
|
|
||||||
padding: matches ? '0' : '0 0.5em',
|
|
||||||
':hover': { backgroundColor: 'unset' },
|
|
||||||
fontSize: '24px',
|
|
||||||
'@media (max-width: 1024px)': {
|
|
||||||
fontSize: '16px',
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
AFFiNE
|
|
||||||
</Button>
|
|
||||||
</Grid>
|
|
||||||
<Grid xs={6} sx={{ display: 'flex', justifyContent: 'right' }}>
|
|
||||||
<Button
|
|
||||||
onClick={() => {
|
|
||||||
window.open('https://blog.affine.pro');
|
|
||||||
}}
|
|
||||||
variant="plain"
|
|
||||||
sx={{
|
|
||||||
padding: matches ? '0' : '0 0.5em',
|
|
||||||
':hover': { backgroundColor: 'unset' },
|
|
||||||
fontSize: '24px',
|
|
||||||
'@media (max-width: 1024px)': {
|
|
||||||
fontSize: '16px',
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
size="lg"
|
|
||||||
>
|
|
||||||
Blog
|
|
||||||
</Button>
|
|
||||||
<Select defaultValue="en" onChange={changeLanguage}>
|
|
||||||
{options.map(option => (
|
|
||||||
<Option key={option.value} value={option.value}>
|
|
||||||
{option.text}
|
|
||||||
</Option>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
<Grid xs={12} sx={{ display: 'flex', marginTop: '4vh!important' }}>
|
<Grid xs={12} sx={{ display: 'flex', marginTop: '4vh!important' }}>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
|
|||||||
@@ -6,16 +6,13 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
import { Box, Button, Grid, Typography } from '@mui/joy';
|
import { Box, Button, Grid, Typography } from '@mui/joy';
|
||||||
import Option from '@mui/joy/Option';
|
|
||||||
import Select from '@mui/joy/Select';
|
|
||||||
import { styled } from '@mui/joy/styles';
|
import { styled } from '@mui/joy/styles';
|
||||||
import { LogoIcon } from '@toeverything/components/icons';
|
import { LogoIcon } from '@toeverything/components/icons';
|
||||||
// eslint-disable-next-line no-restricted-imports
|
// eslint-disable-next-line no-restricted-imports
|
||||||
import { useMediaQuery } from '@mui/material';
|
import { useMediaQuery } from '@mui/material';
|
||||||
|
|
||||||
import CollaborationImage from './collaboration.png';
|
import CollaborationImage from './collaboration.png';
|
||||||
import { AFFiNEFooter, AFFiNEImage } from './Common';
|
import { AFFiNEFooter, AFFiNEHeader, AFFiNEImage } from './Common';
|
||||||
import { options } from './i18n';
|
|
||||||
import { GitHub } from './Icons';
|
import { GitHub } from './Icons';
|
||||||
import PageImage from './page.png';
|
import PageImage from './page.png';
|
||||||
import ShapeImage from './shape.png';
|
import ShapeImage from './shape.png';
|
||||||
@@ -220,71 +217,7 @@ export function App() {
|
|||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Grid
|
<AFFiNEHeader />
|
||||||
container
|
|
||||||
spacing={2}
|
|
||||||
sx={{
|
|
||||||
maxWidth: '1280px',
|
|
||||||
margin: 'auto',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Grid xs={6}>
|
|
||||||
<Button
|
|
||||||
size="lg"
|
|
||||||
variant="plain"
|
|
||||||
sx={{
|
|
||||||
padding: matches ? '0' : '0 0.5em',
|
|
||||||
':hover': { backgroundColor: 'unset' },
|
|
||||||
fontSize: '24px',
|
|
||||||
'@media (max-width: 1024px)': {
|
|
||||||
fontSize: '16px',
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
AFFiNE
|
|
||||||
</Button>
|
|
||||||
</Grid>
|
|
||||||
<Grid xs={6} sx={{ display: 'flex', justifyContent: 'right' }}>
|
|
||||||
<GitHub flat />
|
|
||||||
<Button
|
|
||||||
onClick={() => window.open('https://blog.affine.pro')}
|
|
||||||
variant="plain"
|
|
||||||
sx={{
|
|
||||||
padding: matches ? '0' : '0 0.5em',
|
|
||||||
':hover': { backgroundColor: 'unset' },
|
|
||||||
fontSize: '24px',
|
|
||||||
'@media (max-width: 1024px)': {
|
|
||||||
fontSize: '16px',
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
size="lg"
|
|
||||||
>
|
|
||||||
{t('Blog')}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
onClick={() => navigate('/aboutus')}
|
|
||||||
variant="plain"
|
|
||||||
sx={{
|
|
||||||
padding: matches ? '0' : '0 0.5em',
|
|
||||||
':hover': { backgroundColor: 'unset' },
|
|
||||||
fontSize: '24px',
|
|
||||||
'@media (max-width: 1024px)': {
|
|
||||||
fontSize: '16px',
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
size="lg"
|
|
||||||
>
|
|
||||||
{t('AboutUs')}
|
|
||||||
</Button>
|
|
||||||
<Select defaultValue="en" onChange={changeLanguage}>
|
|
||||||
{options.map(option => (
|
|
||||||
<Option key={option.value} value={option.value}>
|
|
||||||
{option.text}
|
|
||||||
</Option>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
<Grid xs={12} sx={{ display: 'flex', marginTop: '12vh!important' }}>
|
<Grid xs={12} sx={{ display: 'flex', marginTop: '12vh!important' }}>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
|
|||||||
@@ -1,12 +1,20 @@
|
|||||||
/* eslint-disable @typescript-eslint/naming-convention */
|
/* eslint-disable @typescript-eslint/naming-convention */
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { Box, Button, Grid, Typography } from '@mui/joy';
|
||||||
|
import Option from '@mui/joy/Option';
|
||||||
|
import Select from '@mui/joy/Select';
|
||||||
|
import { styled } from '@mui/joy/styles';
|
||||||
|
// eslint-disable-next-line no-restricted-imports
|
||||||
|
import { useMediaQuery } from '@mui/material';
|
||||||
|
|
||||||
import GitHubIcon from '@mui/icons-material/GitHub';
|
import GitHubIcon from '@mui/icons-material/GitHub';
|
||||||
import RedditIcon from '@mui/icons-material/Reddit';
|
import RedditIcon from '@mui/icons-material/Reddit';
|
||||||
import TelegramIcon from '@mui/icons-material/Telegram';
|
import TelegramIcon from '@mui/icons-material/Telegram';
|
||||||
import { Box, Button, Grid, Typography } from '@mui/joy';
|
import { options } from './i18n';
|
||||||
import { styled } from '@mui/joy/styles';
|
|
||||||
// eslint-disable-next-line no-restricted-imports
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { DiscordIcon, GitHub } from './Icons';
|
import { DiscordIcon, GitHub } from './Icons';
|
||||||
|
// eslint-disable-next-line no-restricted-imports
|
||||||
import LogoImage from './logo.png';
|
import LogoImage from './logo.png';
|
||||||
|
|
||||||
export const AFFiNEImage = styled('img')({
|
export const AFFiNEImage = styled('img')({
|
||||||
@@ -333,3 +341,86 @@ export const AFFiNEFooter = ({
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const AFFiNEHeader = () => {
|
||||||
|
const matches = useMediaQuery('(max-width: 1024px)');
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const { i18n } = useTranslation();
|
||||||
|
|
||||||
|
const changeLanguage = (event: any) => {
|
||||||
|
i18n.changeLanguage(event);
|
||||||
|
};
|
||||||
|
const matchesIPAD = useMediaQuery('(max-width: 768px)');
|
||||||
|
return (
|
||||||
|
<Grid
|
||||||
|
container
|
||||||
|
spacing={2}
|
||||||
|
sx={{
|
||||||
|
maxWidth: '1280px',
|
||||||
|
margin: 'auto',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Grid xs={6}>
|
||||||
|
<Button
|
||||||
|
size="lg"
|
||||||
|
variant="plain"
|
||||||
|
sx={{
|
||||||
|
padding: matches ? '0' : '0 0.5em',
|
||||||
|
':hover': { backgroundColor: 'unset' },
|
||||||
|
fontSize: '24px',
|
||||||
|
'@media (max-width: 1024px)': {
|
||||||
|
fontSize: '16px',
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
onClick={() => navigate('/')}
|
||||||
|
>
|
||||||
|
AFFiNE
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
<Grid xs={6} sx={{ display: 'flex', justifyContent: 'right' }}>
|
||||||
|
<GitHub flat />
|
||||||
|
<Button
|
||||||
|
onClick={() => window.open('https://blog.affine.pro')}
|
||||||
|
variant="plain"
|
||||||
|
sx={{
|
||||||
|
padding: matches ? '0' : '0 0.5em',
|
||||||
|
':hover': { backgroundColor: 'unset' },
|
||||||
|
fontSize: '24px',
|
||||||
|
'@media (max-width: 1024px)': {
|
||||||
|
fontSize: '16px',
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
size="lg"
|
||||||
|
>
|
||||||
|
Blog
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={() => navigate('/aboutus')}
|
||||||
|
variant="plain"
|
||||||
|
sx={{
|
||||||
|
padding: matches ? '0' : '0 0.5em',
|
||||||
|
':hover': { backgroundColor: 'unset' },
|
||||||
|
fontSize: '24px',
|
||||||
|
'@media (max-width: 1024px)': {
|
||||||
|
fontSize: '16px',
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
size="lg"
|
||||||
|
>
|
||||||
|
About Us
|
||||||
|
</Button>
|
||||||
|
<Select
|
||||||
|
defaultValue="en"
|
||||||
|
sx={{ display: matchesIPAD ? 'none' : 'intial' }}
|
||||||
|
onChange={changeLanguage}
|
||||||
|
>
|
||||||
|
{options.map(option => (
|
||||||
|
<Option key={option.value} value={option.value}>
|
||||||
|
{option.text}
|
||||||
|
</Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|||||||
BIN
apps/venus/src/assets/images/og.png
Normal file
BIN
apps/venus/src/assets/images/og.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
@@ -6,6 +6,27 @@
|
|||||||
<base href="/" />
|
<base href="/" />
|
||||||
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
|
||||||
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
|
<meta name="twitter:url" content="https://affine.pro/" />
|
||||||
|
<meta name="twitter:title" content="AFFiNE - All In One Workos" />
|
||||||
|
<meta
|
||||||
|
name="twitter:description"
|
||||||
|
content="Affine is the next-generation collaborative knowledge base for professionals."
|
||||||
|
/>
|
||||||
|
<meta name="twitter:site" content="@AffineOfficial" />
|
||||||
|
<meta name="twitter:image" content="https://affine.pro/og.png" />
|
||||||
|
|
||||||
|
<meta property="og:type" content="website" />
|
||||||
|
<meta property="og:title" content="AFFiNE - All In One Workos" />
|
||||||
|
<meta property="og:site_name" content="AFFiNE - All In One Workos" />
|
||||||
|
<meta property="og:url" content="https://affine.pro/" />
|
||||||
|
<meta property="og:image" content="https://affine.pro/og.png" />
|
||||||
|
<meta
|
||||||
|
property="og:description"
|
||||||
|
content="Affine is the next-generation collaborative knowledge base for professionals."
|
||||||
|
/>
|
||||||
|
|
||||||
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -66,10 +66,10 @@ export const AddViewMenu = () => {
|
|||||||
key={name}
|
key={name}
|
||||||
active={viewType === scene}
|
active={viewType === scene}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (scene === RecastScene.Table) {
|
// if (scene === RecastScene.Table) {
|
||||||
// The table view is under progress
|
// // The table view is under progress
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
setViewType(scene);
|
setViewType(scene);
|
||||||
}}
|
}}
|
||||||
style={{ textTransform: 'uppercase' }}
|
style={{ textTransform: 'uppercase' }}
|
||||||
|
|||||||
@@ -99,10 +99,10 @@ export const ViewsMenu = () => {
|
|||||||
key={name}
|
key={name}
|
||||||
active={viewType === scene}
|
active={viewType === scene}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (scene === RecastScene.Table) {
|
// if (scene === RecastScene.Table) {
|
||||||
// The table view is under progress
|
// // The table view is under progress
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
setViewType(scene);
|
setViewType(scene);
|
||||||
}}
|
}}
|
||||||
style={{ textTransform: 'uppercase' }}
|
style={{ textTransform: 'uppercase' }}
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
import { RecastScene } from '@toeverything/components/editor-core';
|
import { RecastScene } from '@toeverything/components/editor-core';
|
||||||
import {
|
import { KanBanIcon, TodoListIcon } from '@toeverything/components/icons';
|
||||||
KanBanIcon,
|
|
||||||
TableIcon,
|
|
||||||
TodoListIcon,
|
|
||||||
} from '@toeverything/components/icons';
|
|
||||||
|
|
||||||
export const VIEW_LIST = [
|
export const VIEW_LIST = [
|
||||||
{
|
{
|
||||||
@@ -16,9 +12,9 @@ export const VIEW_LIST = [
|
|||||||
scene: RecastScene.Kanban,
|
scene: RecastScene.Kanban,
|
||||||
icon: <KanBanIcon fontSize="small" />,
|
icon: <KanBanIcon fontSize="small" />,
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
name: 'Table',
|
// name: 'Table',
|
||||||
scene: RecastScene.Table,
|
// scene: RecastScene.Table,
|
||||||
icon: <TableIcon fontSize="small" />,
|
// icon: <TableIcon fontSize="small" />,
|
||||||
},
|
// },
|
||||||
] as const;
|
] as const;
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ export class Editor implements Virgo {
|
|||||||
private _cacheManager = new Map<string, Promise<AsyncBlock | null>>();
|
private _cacheManager = new Map<string, Promise<AsyncBlock | null>>();
|
||||||
public mouseManager = new MouseManager(this);
|
public mouseManager = new MouseManager(this);
|
||||||
public selectionManager = new SelectionManager(this);
|
public selectionManager = new SelectionManager(this);
|
||||||
public keyboardManager = new KeyboardManager(this);
|
public keyboardManager: KeyboardManager;
|
||||||
public scrollManager = new ScrollManager(this);
|
public scrollManager = new ScrollManager(this);
|
||||||
public dragDropManager = new DragDropManager(this);
|
public dragDropManager = new DragDropManager(this);
|
||||||
public commands = new EditorCommands(this);
|
public commands = new EditorCommands(this);
|
||||||
@@ -83,6 +83,8 @@ export class Editor implements Virgo {
|
|||||||
if (props.isEdgeless) {
|
if (props.isEdgeless) {
|
||||||
this.isEdgeless = true;
|
this.isEdgeless = true;
|
||||||
}
|
}
|
||||||
|
// Wait for rootId/isEdgeless set
|
||||||
|
this.keyboardManager = new KeyboardManager(this);
|
||||||
for (const [name, block] of Object.entries(props.views)) {
|
for (const [name, block] of Object.entries(props.views)) {
|
||||||
services.api.editorBlock.registerContentExporter(
|
services.api.editorBlock.registerContentExporter(
|
||||||
this.workspace,
|
this.workspace,
|
||||||
|
|||||||
@@ -2,19 +2,19 @@ import HotKeys from 'hotkeys-js';
|
|||||||
|
|
||||||
import { uaHelper } from '@toeverything/utils';
|
import { uaHelper } from '@toeverything/utils';
|
||||||
|
|
||||||
|
import { Protocol } from '@toeverything/datasource/db-service';
|
||||||
import { AsyncBlock, BlockEditor } from '../..';
|
import { AsyncBlock, BlockEditor } from '../..';
|
||||||
|
import { supportChildren } from '../../utils';
|
||||||
import { SelectionManager } from '../selection';
|
import { SelectionManager } from '../selection';
|
||||||
import {
|
import {
|
||||||
HotKeyTypes,
|
|
||||||
HotkeyMap,
|
|
||||||
MacHotkeyMap,
|
|
||||||
WinHotkeyMap,
|
|
||||||
GlobalHotkeyMap,
|
GlobalHotkeyMap,
|
||||||
GlobalMacHotkeyMap,
|
GlobalMacHotkeyMap,
|
||||||
GlobalWinHotkeyMap,
|
GlobalWinHotkeyMap,
|
||||||
|
HotkeyMap,
|
||||||
|
HotKeyTypes,
|
||||||
|
MacHotkeyMap,
|
||||||
|
WinHotkeyMap,
|
||||||
} from './hotkey-map';
|
} from './hotkey-map';
|
||||||
import { supportChildren } from '../../utils';
|
|
||||||
import { Protocol } from '@toeverything/datasource/db-service';
|
|
||||||
type KeyboardEventHandler = (event: KeyboardEvent) => void;
|
type KeyboardEventHandler = (event: KeyboardEvent) => void;
|
||||||
export class KeyboardManager {
|
export class KeyboardManager {
|
||||||
private _editor: BlockEditor;
|
private _editor: BlockEditor;
|
||||||
@@ -22,8 +22,20 @@ export class KeyboardManager {
|
|||||||
private hotkeys: HotkeyMap;
|
private hotkeys: HotkeyMap;
|
||||||
private global_hotkeys: GlobalHotkeyMap;
|
private global_hotkeys: GlobalHotkeyMap;
|
||||||
private handler_map: { [k: string]: Array<KeyboardEventHandler> };
|
private handler_map: { [k: string]: Array<KeyboardEventHandler> };
|
||||||
|
/**
|
||||||
|
* Every editor should have its own hotkey scope,
|
||||||
|
* but edgeless had multiple editor instances,
|
||||||
|
* all edgeless editors should have shared scope
|
||||||
|
*/
|
||||||
|
private hotkeyScope: string;
|
||||||
|
|
||||||
constructor(editor: BlockEditor) {
|
constructor(editor: BlockEditor) {
|
||||||
|
if (editor.isEdgeless) {
|
||||||
|
// edgeless editors should have shared scope
|
||||||
|
this.hotkeyScope = 'whiteboard';
|
||||||
|
} else {
|
||||||
|
this.hotkeyScope = 'editor_' + editor.getRootBlockId();
|
||||||
|
}
|
||||||
this._editor = editor;
|
this._editor = editor;
|
||||||
this.selection_manager = this._editor.selectionManager;
|
this.selection_manager = this._editor.selectionManager;
|
||||||
if (uaHelper.isMacOs) {
|
if (uaHelper.isMacOs) {
|
||||||
@@ -35,7 +47,7 @@ export class KeyboardManager {
|
|||||||
}
|
}
|
||||||
this.handler_map = {};
|
this.handler_map = {};
|
||||||
|
|
||||||
HotKeys.setScope('editor');
|
HotKeys.setScope(this.hotkeyScope);
|
||||||
|
|
||||||
// this.init_common_shortcut_cb();
|
// this.init_common_shortcut_cb();
|
||||||
this.bind_hot_key_handlers();
|
this.bind_hot_key_handlers();
|
||||||
@@ -44,43 +56,63 @@ export class KeyboardManager {
|
|||||||
private bind_hot_key_handlers() {
|
private bind_hot_key_handlers() {
|
||||||
this.bind_hotkey(
|
this.bind_hotkey(
|
||||||
this.hotkeys.selectAll,
|
this.hotkeys.selectAll,
|
||||||
'editor',
|
this.hotkeyScope,
|
||||||
this.handle_select_all
|
this.handle_select_all
|
||||||
);
|
);
|
||||||
|
|
||||||
this.bind_hotkey(this.hotkeys.undo, 'editor', this.handle_undo);
|
this.bind_hotkey(this.hotkeys.undo, this.hotkeyScope, this.handle_undo);
|
||||||
this.bind_hotkey(this.hotkeys.redo, 'editor', this.handle_redo);
|
this.bind_hotkey(this.hotkeys.redo, this.hotkeyScope, this.handle_redo);
|
||||||
this.bind_hotkey(this.hotkeys.remove, 'editor', this.handle_remove);
|
this.bind_hotkey(this.hotkeys.remove, 'all', this.handle_remove);
|
||||||
this.bind_hotkey(
|
this.bind_hotkey(
|
||||||
this.hotkeys.checkUncheck,
|
this.hotkeys.checkUncheck,
|
||||||
'editor',
|
this.hotkeyScope,
|
||||||
this.handle_check_uncheck
|
this.handle_check_uncheck
|
||||||
);
|
);
|
||||||
this.bind_hotkey(
|
this.bind_hotkey(
|
||||||
this.hotkeys.preExpendSelect,
|
this.hotkeys.preExpendSelect,
|
||||||
'editor',
|
this.hotkeyScope,
|
||||||
this.handle_pre_expend_select
|
this.handle_pre_expend_select
|
||||||
);
|
);
|
||||||
this.bind_hotkey(
|
this.bind_hotkey(
|
||||||
this.hotkeys.nextExpendSelect,
|
this.hotkeys.nextExpendSelect,
|
||||||
'editor',
|
this.hotkeyScope,
|
||||||
this.handle_next_expend_select
|
this.handle_next_expend_select
|
||||||
);
|
);
|
||||||
this.bind_hotkey(this.hotkeys.up, 'editor', this.handle_click_up);
|
this.bind_hotkey(
|
||||||
this.bind_hotkey(this.hotkeys.down, 'editor', this.handleClickDown);
|
this.hotkeys.up,
|
||||||
this.bind_hotkey(this.hotkeys.left, 'editor', this.handle_click_up);
|
this.hotkeyScope,
|
||||||
this.bind_hotkey(this.hotkeys.right, 'editor', this.handleClickDown);
|
this.handle_click_up
|
||||||
this.bind_hotkey(this.hotkeys.mergeGroup, 'editor', this.mergeGroup);
|
);
|
||||||
|
this.bind_hotkey(
|
||||||
|
this.hotkeys.down,
|
||||||
|
this.hotkeyScope,
|
||||||
|
this.handleClickDown
|
||||||
|
);
|
||||||
|
this.bind_hotkey(
|
||||||
|
this.hotkeys.left,
|
||||||
|
this.hotkeyScope,
|
||||||
|
this.handle_click_up
|
||||||
|
);
|
||||||
|
this.bind_hotkey(
|
||||||
|
this.hotkeys.right,
|
||||||
|
this.hotkeyScope,
|
||||||
|
this.handleClickDown
|
||||||
|
);
|
||||||
|
this.bind_hotkey(
|
||||||
|
this.hotkeys.mergeGroup,
|
||||||
|
this.hotkeyScope,
|
||||||
|
this.mergeGroup
|
||||||
|
);
|
||||||
this.bind_hotkey(this.hotkeys.enter, 'all', this.handleEnter);
|
this.bind_hotkey(this.hotkeys.enter, 'all', this.handleEnter);
|
||||||
this.bind_hotkey(this.global_hotkeys.search, 'all', this.handle_search);
|
this.bind_hotkey(this.global_hotkeys.search, 'all', this.handle_search);
|
||||||
this.bind_hotkey(
|
this.bind_hotkey(
|
||||||
this.hotkeys.mergeGroupDown,
|
this.hotkeys.mergeGroupDown,
|
||||||
'editor',
|
this.hotkeyScope,
|
||||||
this.mergeGroupDown
|
this.mergeGroupDown
|
||||||
);
|
);
|
||||||
this.bind_hotkey(
|
this.bind_hotkey(
|
||||||
this.hotkeys.mergeGroupUp,
|
this.hotkeys.mergeGroupUp,
|
||||||
'editor',
|
this.hotkeyScope,
|
||||||
this.mergeGroupUp
|
this.mergeGroupUp
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -93,24 +125,12 @@ export class KeyboardManager {
|
|||||||
handler.forEach(h => {
|
handler.forEach(h => {
|
||||||
HotKeys(key, scope, h);
|
HotKeys(key, scope, h);
|
||||||
if (!this.handler_map[key]) {
|
if (!this.handler_map[key]) {
|
||||||
this.handler_map[key] = [h];
|
this.handler_map[key] = [];
|
||||||
} else {
|
|
||||||
this.handler_map[key].push(h);
|
|
||||||
}
|
}
|
||||||
|
this.handler_map[key].push(h);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* bind global shortcut event
|
|
||||||
* @param {HotkeyMapKeys} type
|
|
||||||
* @param {KeyboardEventHandler} handler
|
|
||||||
* @memberof KeyboardManager
|
|
||||||
*/
|
|
||||||
public bind(type: HotKeyTypes, handler: KeyboardEventHandler) {
|
|
||||||
this.bind_hotkey(this.hotkeys[type], 'editor', handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* emit a shortcut event,
|
* emit a shortcut event,
|
||||||
@@ -127,21 +147,12 @@ export class KeyboardManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* unbind keyboard event
|
|
||||||
* @param {HotKeyTypes} key
|
|
||||||
* @param {KeyboardEventHandler} cb
|
|
||||||
* @memberof KeyboardManager
|
|
||||||
*/
|
|
||||||
public unbind(key: HotKeyTypes, cb: KeyboardEventHandler) {
|
|
||||||
HotKeys.unbind(key, 'editor', cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
public dispose() {
|
public dispose() {
|
||||||
Object.keys(this.handler_map).map(key => HotKeys.unbind(key, 'editor'));
|
Object.entries(this.handler_map).forEach(([key, fns]) =>
|
||||||
|
fns.forEach(fn => HotKeys.unbind(key, fn))
|
||||||
|
);
|
||||||
this.handler_map = {};
|
this.handler_map = {};
|
||||||
|
HotKeys.deleteScope(this.hotkeyScope);
|
||||||
}
|
}
|
||||||
|
|
||||||
private handle_select_all = (event: KeyboardEvent) => {
|
private handle_select_all = (event: KeyboardEvent) => {
|
||||||
@@ -228,20 +239,20 @@ export class KeyboardManager {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// suspend(true)
|
// suspend(true)
|
||||||
let textBlock = await this._editor.createBlock('text');
|
const textBlock = await this._editor.createBlock('text');
|
||||||
await selectedNode.after(textBlock);
|
await selectedNode.after(textBlock);
|
||||||
this._editor.selectionManager.setActivatedNodeId(textBlock.id);
|
this._editor.selectionManager.setActivatedNodeId(textBlock.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
private mergeGroup = async (event: Event) => {
|
private mergeGroup = async (event: Event) => {
|
||||||
let selectedGroup = await this.getSelectedGroups();
|
const selectedGroup = await this.getSelectedGroups();
|
||||||
this._editor.commands.blockCommands.mergeGroup(...selectedGroup);
|
this._editor.commands.blockCommands.mergeGroup(...selectedGroup);
|
||||||
};
|
};
|
||||||
private mergeGroupDown = async (event: Event) => {
|
private mergeGroupDown = async (event: Event) => {
|
||||||
let selectedGroup = await this.getSelectedGroups();
|
const selectedGroup = await this.getSelectedGroups();
|
||||||
if (selectedGroup.length) {
|
if (selectedGroup.length) {
|
||||||
let nextGroup = await selectedGroup[
|
const nextGroup = await selectedGroup[
|
||||||
selectedGroup.length - 1
|
selectedGroup.length - 1
|
||||||
].nextSibling();
|
].nextSibling();
|
||||||
if (nextGroup?.type === Protocol.Block.Type.group) {
|
if (nextGroup?.type === Protocol.Block.Type.group) {
|
||||||
@@ -253,9 +264,9 @@ export class KeyboardManager {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
private mergeGroupUp = async (event: Event) => {
|
private mergeGroupUp = async (event: Event) => {
|
||||||
let selectedGroup = await this.getSelectedGroups();
|
const selectedGroup = await this.getSelectedGroups();
|
||||||
if (selectedGroup.length) {
|
if (selectedGroup.length) {
|
||||||
let preGroup = await selectedGroup[0].previousSibling();
|
const preGroup = await selectedGroup[0].previousSibling();
|
||||||
if (preGroup?.type === Protocol.Block.Type.group) {
|
if (preGroup?.type === Protocol.Block.Type.group) {
|
||||||
this._editor.commands.blockCommands.mergeGroup(
|
this._editor.commands.blockCommands.mergeGroup(
|
||||||
preGroup,
|
preGroup,
|
||||||
|
|||||||
Reference in New Issue
Block a user