mirror of
https://github.com/anyproto/anytype-ts.git
synced 2025-06-08 05:57:02 +09:00
Merge branch 'main' of github.com:anyproto/anytype-ts into feature/native-messaging-host
This commit is contained in:
commit
11ee7a57fa
36 changed files with 362 additions and 182 deletions
1
dist/embed/iframe.html
vendored
1
dist/embed/iframe.html
vendored
|
@ -21,6 +21,7 @@
|
|||
|
||||
.twitter-tweet, .instagram-media { margin: 0px !important; display: inline-flex !important; }
|
||||
.gist-file { margin: 0px !important; }
|
||||
.cp_embed_iframe { border: 0px !important; }
|
||||
|
||||
html.align1 .twitter-tweet, body.align1 .instagram-media { justify-content: center; }
|
||||
html.align2 .twitter-tweet, body.align2 .instagram-media { justify-content: flex-end; }
|
||||
|
|
|
@ -144,8 +144,6 @@ function createWindow () {
|
|||
console.error('[Api] method not defined:', cmd);
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
};
|
||||
|
||||
app.on('ready', () => {
|
||||
|
|
|
@ -62,10 +62,9 @@ class WindowManager {
|
|||
win.on('enter-full-screen', () => Util.send(win, 'enter-full-screen'));
|
||||
win.on('leave-full-screen', () => Util.send(win, 'leave-full-screen'));
|
||||
|
||||
win.webContents.on('context-menu', (e, param) => Util.send(win, 'spellcheck', param));
|
||||
|
||||
Api.setSpellingLang(win, languages);
|
||||
Api.setZoom(win, zoom);
|
||||
win.webContents.on('context-menu', (e, param) => {
|
||||
Util.send(win, 'spellcheck', param.misspelledWord, param.dictionarySuggestions, param.x, param.y, param.selectionRect);
|
||||
});
|
||||
|
||||
if (hideMenuBar) {
|
||||
win.setMenuBarVisibility(false);
|
||||
|
|
|
@ -46,7 +46,11 @@
|
|||
"https://*.fbcdn.net",
|
||||
"https://static.cdninstagram.com",
|
||||
"https://telegram.org",
|
||||
"https://github.githubassets.com"
|
||||
"https://github.githubassets.com",
|
||||
"https://cpwebassets.codepen.io",
|
||||
"https://cdnjs.cloudflare.com",
|
||||
"https://*.bilibili.com",
|
||||
"https://s1.hdslb.com"
|
||||
],
|
||||
|
||||
"font-src": [
|
||||
|
@ -99,7 +103,16 @@
|
|||
"https://*.reddit.com",
|
||||
"https://www.instagram.com",
|
||||
"https://t.me",
|
||||
"https://gist.github.com"
|
||||
"https://gist.github.com",
|
||||
"https://codepen.io",
|
||||
"https://www.facebook.com",
|
||||
"https://*.bilibili.com",
|
||||
"https://*.bilibili.tv",
|
||||
"https://*.bilivideo.cn:*",
|
||||
"https://*.bilivideo.com",
|
||||
"https://*.hdslb.com",
|
||||
"wss://*.bilibili.com:*",
|
||||
"wss://*.biliapi.net"
|
||||
],
|
||||
|
||||
"script-src-elem": [
|
||||
|
@ -128,7 +141,11 @@
|
|||
"https://static.cdninstagram.com",
|
||||
"https://telegram.org",
|
||||
"https://oauth.tg.dev",
|
||||
"https://gist.github.com"
|
||||
"https://gist.github.com",
|
||||
"https://cpwebassets.codepen.io",
|
||||
"https://codepen.io",
|
||||
"https://cdnjs.cloudflare.com",
|
||||
"https://*.hdslb.com"
|
||||
],
|
||||
|
||||
"frame-src": [
|
||||
|
@ -147,7 +164,10 @@
|
|||
"https://embed.reddit.com",
|
||||
"https://www.facebook.com",
|
||||
"https://www.instagram.com",
|
||||
"https://t.me"
|
||||
"https://t.me",
|
||||
"https://codepen.io",
|
||||
"https://cdpn.io",
|
||||
"https://*.bilibili.com"
|
||||
],
|
||||
|
||||
"worker-src": [
|
||||
|
|
|
@ -459,6 +459,8 @@
|
|||
"blockDataviewCreateNew": "Create new Object",
|
||||
"blockDataviewCreateNewCollection": "Create new Collection",
|
||||
"blockDataviewCreateNewSet": "Create new Set",
|
||||
"blockDataviewCreateNewTooltipCollection": "Create new Object in this Collection",
|
||||
"blockDataviewCreateNewTooltipType": "Create new %s object",
|
||||
"blockDataviewShowTemplates": "Show Templates",
|
||||
"blockDataviewSearch": "Search",
|
||||
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
.archive { position: absolute; right: 10px; top: 10px; z-index: 1; }
|
||||
}
|
||||
|
||||
.inner.vertical { display: flex; flex-direction: column-reverse; }
|
||||
.inner.vertical {
|
||||
.inner.isVertical { display: flex; flex-direction: column-reverse; }
|
||||
.inner.isVertical {
|
||||
.side.left { width: 100%; border-radius: 0px; }
|
||||
.side.right { aspect-ratio: 7/3; width: 100%; border-radius: 0px; border-bottom: 0.05em solid $colorShapeSecondary; }
|
||||
}
|
||||
|
@ -40,7 +40,7 @@
|
|||
.side.right { width: 28%; min-height: 90px; display: block; position: relative; overflow: hidden; }
|
||||
}
|
||||
|
||||
.inner.withImage.vertical {
|
||||
.inner.withImage.isVertical {
|
||||
.side.left { width: 100%; }
|
||||
.side.right { width: 100%; }
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
> .sides { gap: 0px 16px; display: flex; flex-direction: row; align-items: center; justify-content: stretch; width: 100%; }
|
||||
> .sides {
|
||||
> .side { padding: 15px 0px; white-space: nowrap; line-height: 28px; display: flex; flex-direction: row; align-items: center; }
|
||||
> .side.left { flex-grow: 1; padding-left: 14px; }
|
||||
> .side.left { flex-grow: 1; padding-left: 14px; max-width: 100%; }
|
||||
> .side.right { flex-shrink: 0; gap: 0px 4px; justify-content: flex-end; }
|
||||
> .side.right {
|
||||
.filter { color: $colorTextPrimary; padding: 0px; }
|
||||
|
@ -253,11 +253,6 @@
|
|||
.icon.plus:hover { background-color: transparent; }
|
||||
}
|
||||
.dataviewControls::after { display: none !important; }
|
||||
.dataviewControls.active {
|
||||
> .sides {
|
||||
> .side.right { opacity: 1; }
|
||||
}
|
||||
}
|
||||
|
||||
.dataviewSelection {
|
||||
.side.left { @include text-paragraph; }
|
||||
|
@ -268,6 +263,12 @@
|
|||
}
|
||||
}
|
||||
|
||||
.block.blockDataview.isInline.isVertical {
|
||||
.dataviewControls {
|
||||
> .sides { flex-direction: column; align-items: flex-start; justify-content: flex-start; }
|
||||
}
|
||||
}
|
||||
|
||||
.block.blockDataview.showMenu {
|
||||
.dataviewHead {
|
||||
.icon.source { opacity: 1; }
|
||||
|
|
|
@ -11,4 +11,8 @@
|
|||
canvas.move { cursor: move; }
|
||||
}
|
||||
}
|
||||
|
||||
.block.blockDataview.isInline {
|
||||
.viewContent.viewGraph { height: 500px; }
|
||||
}
|
||||
}
|
|
@ -44,7 +44,10 @@
|
|||
}
|
||||
|
||||
.cellContent.c-select {
|
||||
.over { display: inline-flex; gap: 6px; align-items: center; }
|
||||
.over { display: inline; }
|
||||
.tagItem { margin: 0px 6px 0px 0px; vertical-align: middle; }
|
||||
.tagItem:last-child { margin-right: 0px; }
|
||||
.tagItem.isStatus { line-height: 16px; }
|
||||
.more { margin: 0px; vertical-align: middle; }
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
.iconObject { position: absolute; left: 16px; top: 15px; background-color: $colorShapeTertiary; border-radius: 10px; }
|
||||
}
|
||||
|
||||
.linkCard.c48.withIcon.withCover.vertical {
|
||||
.linkCard.c48.withIcon.withCover.isVertical {
|
||||
.sides { min-height: 62px; }
|
||||
.side.left { padding: 24px 16px 16px 16px; z-index: 10; }
|
||||
.iconObject { top: -32px; transform: none; }
|
||||
|
@ -81,18 +81,18 @@
|
|||
.side.right { width: 28%; display: block; border: 1px solid $colorShapeSecondary; border-left: 0px; }
|
||||
}
|
||||
|
||||
.linkCard.vertical { display: block; }
|
||||
.linkCard.vertical {
|
||||
.linkCard.isVertical { display: block; }
|
||||
.linkCard.isVertical {
|
||||
.sides { flex-direction: column-reverse; }
|
||||
.side.left { width: 100%; border-right-width: 1px; }
|
||||
.side.right { aspect-ratio: 7/3; width: 100%; border-radius: 12px 12px 0px 0px !important; border: 1px solid $colorShapeSecondary; border-bottom: 0px; }
|
||||
}
|
||||
|
||||
.linkCard.withCover.vertical {
|
||||
.linkCard.withCover.isVertical {
|
||||
.side.left { border-radius: 0px 0px 12px 12px !important; }
|
||||
}
|
||||
|
||||
.linkCard.withCover.vertical.text { padding-top: 0px; }
|
||||
.linkCard.withCover.isVertical.text { padding-top: 0px; }
|
||||
}
|
||||
|
||||
.block.blockLink.text {
|
||||
|
|
|
@ -12,47 +12,47 @@
|
|||
smile * { display: inline; vertical-align: middle; }
|
||||
smile .loaderWrapper { display: inline-block; }
|
||||
|
||||
markupCode {
|
||||
markupcode {
|
||||
display: inline; font-family: 'Plex'; border-radius: 4px; background: $colorShapeSecondary; padding: 2px 4px;
|
||||
}
|
||||
|
||||
markupEmoji { display: inline; user-select: all; }
|
||||
markupEmoji * { user-select: all; }
|
||||
markupEmoji {
|
||||
markupemoji { display: inline; user-select: all; }
|
||||
markupemoji * { user-select: all; }
|
||||
markupemoji {
|
||||
smile img { vertical-align: top; }
|
||||
}
|
||||
|
||||
markupLink { position: relative; }
|
||||
markupLink, markupObject { color: inherit; text-decoration: none; border-bottom: 0.075em solid; transition: border-color $transitionCommon; cursor: default; }
|
||||
markupLink.disabled, markupObject.disabled { border-width: 0px; }
|
||||
markuplink { position: relative; }
|
||||
markuplink, markupobject { color: inherit; text-decoration: none; border-bottom: 0.075em solid; transition: border-color $transitionCommon; cursor: default; }
|
||||
markuplink.disabled, markupobject.disabled { border-width: 0px; }
|
||||
|
||||
markupMention { display: inline; user-select: all !important; position: relative; cursor: default; }
|
||||
markupMention * { user-select: text !important; }
|
||||
markupMention {
|
||||
markupmention { display: inline; user-select: all !important; position: relative; cursor: default; }
|
||||
markupmention * { user-select: text !important; }
|
||||
markupmention {
|
||||
smile { display: none; position: relative; z-index: 1; }
|
||||
.space { width: 6px; height: 20px; margin-top: -4px; vertical-align: middle; display: none; }
|
||||
|
||||
name { display: inline; white-space: normal; position: relative; border-bottom: 0.075em solid; border-color: inherit; }
|
||||
}
|
||||
markupMention.disabled {
|
||||
markupmention.disabled {
|
||||
name { border-width: 0px; }
|
||||
}
|
||||
markupMention.withImage {
|
||||
markupmention.withImage {
|
||||
smile { display: inline; }
|
||||
.space { display: inline; }
|
||||
}
|
||||
markupMention.withImage.c24 name markupBgcolor:first-child { margin-left: -22px; padding-left: 22px; }
|
||||
markupMention.withImage.c26 name markupBgcolor:first-child { margin-left: -22px; padding-left: 22px; }
|
||||
markupMention.withImage.c28 name markupBgcolor:first-child { margin-left: -27px; padding-left: 27px; }
|
||||
markupMention.withImage.c32 name markupBgcolor:first-child { margin-left: -34px; padding-left: 34px; }
|
||||
markupMention:hover {
|
||||
markupmention.withImage.c24 name markupBgcolor:first-child { margin-left: -22px; padding-left: 22px; }
|
||||
markupmention.withImage.c26 name markupBgcolor:first-child { margin-left: -22px; padding-left: 22px; }
|
||||
markupmention.withImage.c28 name markupBgcolor:first-child { margin-left: -27px; padding-left: 27px; }
|
||||
markupmention.withImage.c32 name markupBgcolor:first-child { margin-left: -34px; padding-left: 34px; }
|
||||
markupmention:hover {
|
||||
name::before { border-color: $colorTextPrimary; }
|
||||
}
|
||||
|
||||
markupBold { font-weight: 600; }
|
||||
markupItalic { font-style: italic; }
|
||||
markupStrike { text-decoration: line-through; }
|
||||
markupUnderline { border-bottom: 0.05em solid; }
|
||||
markupbold { font-weight: 600; }
|
||||
markupitalic { font-style: italic; }
|
||||
markupstrike { text-decoration: line-through; }
|
||||
markupunderline { border-bottom: 0.05em solid; }
|
||||
|
||||
.markers { display: flex; padding: 1px 0px; }
|
||||
.markers {
|
||||
|
|
|
@ -24,43 +24,27 @@
|
|||
.content { padding: 0px; }
|
||||
.wrap { height: 100%; }
|
||||
.items { height: 100%; }
|
||||
.item.empty { padding: 14px; }
|
||||
|
||||
.sectionName { padding: 0px 14px 4px 14px; }
|
||||
.sectionName::before { content: ""; display: block; width: 100%; height: 1px; margin: 8px 0px 11px 0px; background: $colorShapeSecondary; }
|
||||
.sectionName.first { padding-top: 4px; }
|
||||
.sectionName.first::before { display: none; }
|
||||
|
||||
.item { padding: 4px 16px; }
|
||||
.item.add { padding: 6px 16px; }
|
||||
.item.sides { display: flex; padding: 6px 16px; }
|
||||
|
||||
.info {
|
||||
width: 154px; @include text-overflow-nw; line-height: 20px; border-radius: 4px; transition: background $transitionCommon;
|
||||
flex-shrink: 0; margin-right: 6px;
|
||||
}
|
||||
|
||||
.cell { width: calc(100% - 160px); white-space: nowrap; }
|
||||
.cell.c-select {
|
||||
.tagItem { margin-bottom: 0px; vertical-align: middle; }
|
||||
}
|
||||
.item { padding: 4px 16px; }
|
||||
.item.add { padding: 6px 16px; }
|
||||
.item.sides { display: flex; padding: 6px 16px; }
|
||||
.item.empty { padding: 16px; }
|
||||
|
||||
.item {
|
||||
.icon.plus { margin-right: 4px; background-image: url('~img/icon/plus/menu0.svg'); }
|
||||
}
|
||||
.item * { }
|
||||
.item::before { transition: none; }
|
||||
|
||||
.cellContent { overflow: hidden; height: 20px; line-height: 20px; }
|
||||
.cellContent {
|
||||
.empty { display: block; }
|
||||
}
|
||||
|
||||
.cellContent.c-longText {
|
||||
.name { -webkit-line-clamp: 1; -webkit-box-orient: vertical; display: -webkit-box; }
|
||||
}
|
||||
}
|
||||
.menu.menuBlockAdd {
|
||||
.item.isBig {
|
||||
.iconObject { background-color: $colorShapeTertiary; }
|
||||
}
|
||||
|
@ -105,7 +89,19 @@
|
|||
.icon.collection { background-image: url('~img/icon/menu/action/block/collection1.svg'); }
|
||||
}
|
||||
|
||||
.icon.arrow { width: 20px !important; height: 20px !important; background-color: unset !important; left: auto !important; top: 50% !important; }
|
||||
.cell { width: calc(100% - 160px); white-space: nowrap; }
|
||||
.cell.c-select {
|
||||
.tagItem { margin-bottom: 0px; vertical-align: middle; }
|
||||
}
|
||||
|
||||
.cellContent { overflow: hidden; height: 20px; line-height: 20px; }
|
||||
.cellContent {
|
||||
.empty { display: block; }
|
||||
}
|
||||
|
||||
.cellContent.c-longText {
|
||||
.name { -webkit-line-clamp: 1; -webkit-box-orient: vertical; display: -webkit-box; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -237,6 +237,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
.viewContent.viewGraph {
|
||||
canvas { background: $colorBgPrimary; }
|
||||
}
|
||||
|
||||
.content {
|
||||
.scrollWrap { background: $colorBgPrimary; }
|
||||
}
|
||||
|
|
|
@ -512,8 +512,8 @@ class App extends React.Component<object, State> {
|
|||
});
|
||||
};
|
||||
|
||||
onSpellcheck (e: any, param: any) {
|
||||
if (!param.misspelledWord) {
|
||||
onSpellcheck (e: any, misspelledWord: string, dictionarySuggestions: string[], x: number, y: number, rect: any) {
|
||||
if (!misspelledWord) {
|
||||
return;
|
||||
};
|
||||
|
||||
|
@ -522,34 +522,60 @@ class App extends React.Component<object, State> {
|
|||
const win = $(window);
|
||||
const rootId = keyboard.getRootId();
|
||||
const { focused, range } = focus.state;
|
||||
const options: any = param.dictionarySuggestions.map(it => ({ id: it, name: it }));
|
||||
const obj = Mark.cleanHtml($(`#block-${focused} #value`).html());
|
||||
const value = String(obj.get(0).innerText || '');
|
||||
const options: any = dictionarySuggestions.map(it => ({ id: it, name: it }));
|
||||
const element = $(document.elementFromPoint(x, y));
|
||||
const isInput = element.is('input');
|
||||
const isTextarea = element.is('textarea');
|
||||
const isEditable = element.is('.editable');
|
||||
|
||||
options.push({ id: 'add-to-dictionary', name: translate('spellcheckAdd') });
|
||||
|
||||
menuStore.open('select', {
|
||||
className: 'fromBlock',
|
||||
classNameWrap: 'fromPopup',
|
||||
recalcRect: () => {
|
||||
const rect = UtilCommon.getSelectionRect();
|
||||
return rect ? { ...rect, y: rect.y + win.scrollTop() } : null;
|
||||
},
|
||||
onOpen: () => { menuStore.close('blockContext'); },
|
||||
onClose: () => { keyboard.disableContextOpen(false); },
|
||||
onOpen: () => menuStore.close('blockContext'),
|
||||
onClose: () => keyboard.disableContextOpen(false),
|
||||
data: {
|
||||
options,
|
||||
onSelect: (e: any, item: any) => {
|
||||
raf(() => {
|
||||
focus.apply();
|
||||
|
||||
switch (item.id) {
|
||||
default: {
|
||||
blockStore.updateContent(rootId, focused, { text: value });
|
||||
UtilData.blockInsertText(rootId, focused, item.id, range.from, range.to);
|
||||
if (focused) {
|
||||
focus.apply();
|
||||
|
||||
const obj = Mark.cleanHtml($(`#block-${focused} #value`).html());
|
||||
const value = String(obj.get(0).innerText || '');
|
||||
|
||||
blockStore.updateContent(rootId, focused, { text: value });
|
||||
UtilData.blockInsertText(rootId, focused, item.id, range.from, range.to);
|
||||
} else
|
||||
if (isInput || isTextarea || isEditable) {
|
||||
let value = '';
|
||||
if (isInput || isTextarea) {
|
||||
value = String(element.val());
|
||||
} else
|
||||
if (isEditable) {
|
||||
value = String((element.get(0) as any).innerText || '');
|
||||
};
|
||||
;
|
||||
value = value.replace(new RegExp(`${misspelledWord}`, 'g'), item.id);
|
||||
|
||||
if (isInput || isTextarea) {
|
||||
element.val(value);
|
||||
} else
|
||||
if (isEditable) {
|
||||
element.text(value);
|
||||
};
|
||||
};
|
||||
break;
|
||||
};
|
||||
|
||||
case 'add-to-dictionary': {
|
||||
Renderer.send('spellcheckAdd', param.misspelledWord);
|
||||
Renderer.send('spellcheckAdd', misspelledWord);
|
||||
break;
|
||||
};
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ const BlockBookmark = observer(class BlockBookmark extends React.Component<I.Blo
|
|||
|
||||
_isMounted = false;
|
||||
node: any = null;
|
||||
frame = 0;
|
||||
|
||||
constructor (props: I.BlockComponent) {
|
||||
super(props);
|
||||
|
@ -262,11 +261,7 @@ const BlockBookmark = observer(class BlockBookmark extends React.Component<I.Blo
|
|||
};
|
||||
|
||||
resize () {
|
||||
if (this.frame) {
|
||||
raf.cancel(this.frame);
|
||||
};
|
||||
|
||||
this.frame = raf(() => {
|
||||
window.setTimeout(() => {
|
||||
if (!this._isMounted) {
|
||||
return;
|
||||
};
|
||||
|
@ -274,10 +269,8 @@ const BlockBookmark = observer(class BlockBookmark extends React.Component<I.Blo
|
|||
const { getWrapperWidth } = this.props;
|
||||
const node = $(this.node);
|
||||
const inner = node.find('.inner');
|
||||
const rect = (node.get(0) as Element).getBoundingClientRect();
|
||||
const mw = getWrapperWidth();
|
||||
|
||||
rect.width <= mw / 2 ? inner.addClass('vertical') : inner.removeClass('vertical');
|
||||
inner.width() <= getWrapperWidth() / 2 ? inner.addClass('isVertical') : inner.removeClass('isVertical');
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -659,6 +659,15 @@ const BlockDataview = observer(class BlockDataview extends React.Component<Props
|
|||
dbStore.recordsSet(subId, '', records);
|
||||
};
|
||||
|
||||
if ([ I.ViewType.Graph ].includes(view.type)) {
|
||||
const refGraph = this.refView?.refGraph;
|
||||
if (refGraph) {
|
||||
refGraph.addNewNode(object.id, '', null, () => {
|
||||
refGraph.setRootId(object.id);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
if ([ I.ViewType.Calendar ].includes(view.type)) {
|
||||
UtilObject.openPopup(object);
|
||||
} else {
|
||||
|
@ -1334,6 +1343,15 @@ const BlockDataview = observer(class BlockDataview extends React.Component<Props
|
|||
};
|
||||
|
||||
this.frame = raf(() => {
|
||||
const { block, getWrapperWidth } = this.props;
|
||||
|
||||
if (getWrapperWidth) {
|
||||
const node = $(this.node);
|
||||
const obj = $(`#block-${block.id}`);
|
||||
|
||||
node.width() <= getWrapperWidth() / 2 ? obj.addClass('isVertical') : obj.removeClass('isVertical');
|
||||
};
|
||||
|
||||
if (this.refControls && this.refControls.resize) {
|
||||
this.refControls.resize();
|
||||
};
|
||||
|
|
|
@ -3,7 +3,7 @@ import $ from 'jquery';
|
|||
import { observer } from 'mobx-react';
|
||||
import { observable } from 'mobx';
|
||||
import { Icon, Button, Filter } from 'Component';
|
||||
import { C, I, UtilCommon, analytics, Relation, keyboard, translate, UtilObject, UtilMenu } from 'Lib';
|
||||
import { C, I, UtilCommon, analytics, Relation, keyboard, translate, UtilObject, UtilMenu, Dataview } from 'Lib';
|
||||
import { menuStore, dbStore, blockStore } from 'Store';
|
||||
import { SortableContainer, SortableElement } from 'react-sortable-hoc';
|
||||
import Head from './head';
|
||||
|
@ -49,6 +49,7 @@ const Controls = observer(class Controls extends React.Component<Props> {
|
|||
const isAllowedObject = this.props.isAllowedObject();
|
||||
const isAllowedTemplate = UtilObject.isAllowedTemplate(getTypeId()) || (target && UtilObject.isSetLayout(target.layout) && hasSources);
|
||||
const cmd = keyboard.cmdSymbol();
|
||||
const tooltip = Dataview.getCreateTooltip(rootId, block.id, target.id, view.id);
|
||||
|
||||
if (isAllowedTemplate) {
|
||||
buttonWrapCn.push('withSelect');
|
||||
|
@ -163,7 +164,7 @@ const Controls = observer(class Controls extends React.Component<Props> {
|
|||
<Button
|
||||
id={`button-${block.id}-add-record`}
|
||||
className="addRecord c28"
|
||||
tooltip={translate('blockDataviewCreateNew')}
|
||||
tooltip={tooltip}
|
||||
text={translate('commonNew')}
|
||||
onClick={e => onRecordAdd(e, -1)}
|
||||
/>
|
||||
|
@ -263,7 +264,6 @@ const Controls = observer(class Controls extends React.Component<Props> {
|
|||
} = this.props;
|
||||
const view = getView();
|
||||
const obj = $(element);
|
||||
const node = $(this.node);
|
||||
|
||||
const param: any = {
|
||||
element,
|
||||
|
@ -271,12 +271,12 @@ const Controls = observer(class Controls extends React.Component<Props> {
|
|||
offsetY: 10,
|
||||
noFlipY: true,
|
||||
onOpen: () => {
|
||||
node.addClass('active');
|
||||
obj.addClass('active');
|
||||
this.toggleHoverArea(true);
|
||||
},
|
||||
onClose: () => {
|
||||
node.removeClass('active');
|
||||
obj.removeClass('active');
|
||||
this.toggleHoverArea(false);
|
||||
},
|
||||
onBack: (id) => {
|
||||
menuStore.replace(id, component, { ...param, noAnimation: true });
|
||||
|
@ -416,11 +416,14 @@ const Controls = observer(class Controls extends React.Component<Props> {
|
|||
return;
|
||||
};
|
||||
|
||||
const { isPopup, isInline } = this.props;
|
||||
const { block, isPopup, isInline } = this.props;
|
||||
const container = UtilCommon.getPageContainer(isPopup);
|
||||
const win = $(window);
|
||||
const obj = $(`#block-${block.id}`);
|
||||
const hoverArea = obj.find('.hoverArea');
|
||||
|
||||
this.refFilter.setActive(true);
|
||||
this.toggleHoverArea(true);
|
||||
|
||||
if (!isInline) {
|
||||
this.refFilter.focus();
|
||||
|
@ -453,10 +456,19 @@ const Controls = observer(class Controls extends React.Component<Props> {
|
|||
this.refFilter.setActive(false);
|
||||
this.refFilter.setValue('');
|
||||
this.refFilter.blur();
|
||||
this.toggleHoverArea(false);
|
||||
|
||||
this.props.onFilterChange('');
|
||||
};
|
||||
|
||||
toggleHoverArea (v: boolean) {
|
||||
const { block } = this.props;
|
||||
const obj = $(`#block-${block.id}`);
|
||||
const hoverArea = obj.find('.hoverArea');
|
||||
|
||||
v ? hoverArea.addClass('active') : hoverArea.removeClass('active');
|
||||
};
|
||||
|
||||
resize () {
|
||||
if (!this._isMounted) {
|
||||
return;
|
||||
|
|
|
@ -33,8 +33,9 @@ const Column = observer(class Column extends React.Component<Props> {
|
|||
};
|
||||
|
||||
render () {
|
||||
const { rootId, block, id, getSubId, getView, getLimit, value, onDragStartColumn } = this.props;
|
||||
const { rootId, block, id, getSubId, getView, getLimit, value, onDragStartColumn, getTarget } = this.props;
|
||||
const view = getView();
|
||||
const target = getTarget();
|
||||
const subId = getSubId();
|
||||
const items = this.getItems();
|
||||
const { total } = dbStore.getMeta(subId, '');
|
||||
|
@ -46,6 +47,7 @@ const Column = observer(class Column extends React.Component<Props> {
|
|||
const order = (block.content.groupOrder || []).find(it => it.viewId == view.id);
|
||||
const orderGroup = (order?.groups || []).find(it => it.groupId == id) || {};
|
||||
const isAllowedObject = this.props.isAllowedObject();
|
||||
const tooltip = Dataview.getCreateTooltip(rootId, block.id, target.id, view.id);
|
||||
|
||||
if (view.groupBackgroundColors) {
|
||||
cn.push('withColor');
|
||||
|
@ -92,7 +94,7 @@ const Column = observer(class Column extends React.Component<Props> {
|
|||
|
||||
<div className="side right">
|
||||
<Icon id={`button-${id}-more`} className="more" tooltip={translate('blockDataviewBoardColumnSettings')} onClick={this.onMore} />
|
||||
{isAllowedObject ? <Icon className="add" tooltip={translate('blockDataviewCreateNew')} onClick={e => this.onAdd(e, -1)} /> : ''}
|
||||
{isAllowedObject ? <Icon className="add" tooltip={tooltip} onClick={e => this.onAdd(e, -1)} /> : ''}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ const ViewGraph = observer(class ViewGraph extends React.Component<I.ViewCompone
|
|||
};
|
||||
|
||||
render () {
|
||||
const { className } = this.props;
|
||||
const { block, className } = this.props;
|
||||
const cn = [ 'viewContent', className ];
|
||||
|
||||
return (
|
||||
|
@ -41,6 +41,7 @@ const ViewGraph = observer(class ViewGraph extends React.Component<I.ViewCompone
|
|||
key="graph"
|
||||
{...this.props}
|
||||
ref={ref => this.refGraph = ref}
|
||||
id={block.id}
|
||||
rootId=""
|
||||
data={this.data}
|
||||
/>
|
||||
|
@ -88,10 +89,15 @@ const ViewGraph = observer(class ViewGraph extends React.Component<I.ViewCompone
|
|||
};
|
||||
|
||||
load () {
|
||||
const { getView } = this.props;
|
||||
const { getView, getSearchIds } = this.props;
|
||||
const view = getView();
|
||||
const searchIds = getSearchIds();
|
||||
const filters = [].concat(view.filters).concat(UtilData.graphFilters()).map(it => Dataview.filterMapper(view, it));
|
||||
|
||||
if (searchIds) {
|
||||
filters.push({ operator: I.FilterOperator.And, relationKey: 'id', condition: I.FilterCondition.In, value: searchIds || [] });
|
||||
};
|
||||
|
||||
this.setLoading(true);
|
||||
|
||||
C.ObjectGraph(commonStore.space, filters, 0, [], Constant.graphRelationKeys, (message: any) => {
|
||||
|
@ -143,23 +149,25 @@ const ViewGraph = observer(class ViewGraph extends React.Component<I.ViewCompone
|
|||
};
|
||||
|
||||
resize () {
|
||||
const { isPopup } = this.props;
|
||||
const { isPopup, isInline } = this.props;
|
||||
const node = $(this.node);
|
||||
|
||||
if (!node || !node.length) {
|
||||
return;
|
||||
};
|
||||
|
||||
node.css({ width: 0, height: 0, marginLeft: 0 });
|
||||
if (!isInline) {
|
||||
node.css({ width: 0, height: 0, marginLeft: 0 });
|
||||
|
||||
const container = UtilCommon.getPageContainer(isPopup);
|
||||
const cw = container.width();
|
||||
const ch = container.height();
|
||||
const mw = cw - PADDING * 2;
|
||||
const margin = (cw - mw) / 2;
|
||||
const { top } = node.offset();
|
||||
const container = UtilCommon.getPageContainer(isPopup);
|
||||
const cw = container.width();
|
||||
const ch = container.height();
|
||||
const mw = cw - PADDING * 2;
|
||||
const margin = (cw - mw) / 2;
|
||||
const { top } = node.offset();
|
||||
|
||||
node.css({ width: cw, height: Math.max(600, ch - top - 90), marginLeft: -margin - 2 });
|
||||
node.css({ width: cw, height: Math.max(600, ch - top), marginLeft: -margin - 2 });
|
||||
};
|
||||
|
||||
if (this.refGraph) {
|
||||
this.refGraph.resize();
|
||||
|
|
|
@ -489,7 +489,7 @@ const Block = observer(class Block extends React.Component<Props> {
|
|||
const { rootId, block, readonly } = this.props;
|
||||
const root = blockStore.getLeaf(rootId, rootId);
|
||||
|
||||
if (readonly || !block.isSelectable() || (block.isText() && (focused == block.id)) || block.isTable()) {
|
||||
if (readonly || !block.isSelectable() || (block.isText() && (focused == block.id)) || block.isTable() || block.isDataview()) {
|
||||
return;
|
||||
};
|
||||
|
||||
|
|
|
@ -362,7 +362,7 @@ const BlockLink = observer(class BlockLink extends React.Component<I.BlockCompon
|
|||
UtilCommon.textStyle(name, { border: 0.4 });
|
||||
|
||||
icon.length ? card.addClass('withIcon') : card.removeClass('withIcon');
|
||||
rect.width <= mw / 2 ? card.addClass('vertical') : card.removeClass('vertical');
|
||||
rect.width <= mw / 2 ? card.addClass('isVertical') : card.removeClass('isVertical');
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -344,6 +344,10 @@ const BlockTable = observer(class BlockTable extends React.Component<I.BlockComp
|
|||
};
|
||||
},
|
||||
onOver: (e: any, item: any) => {
|
||||
if (menuStore.isAnimating(menuContext.props.id)) {
|
||||
return;
|
||||
};
|
||||
|
||||
if (!menuContext) {
|
||||
return;
|
||||
};
|
||||
|
|
|
@ -7,7 +7,7 @@ import { I, Mark, keyboard, C, focus, Action, UtilCommon, UtilData, UtilMenu, Ut
|
|||
import { blockStore, commonStore, dbStore, menuStore, detailStore, popupStore } from 'Store';
|
||||
import Constant from 'json/constant.json';
|
||||
|
||||
const HEIGHT_ITEM = 28;
|
||||
const HEIGHT_ITEM = 32;
|
||||
const HEIGHT_SECTION = 42;
|
||||
const HEIGHT_DESCRIPTION = 56;
|
||||
const HEIGHT_RELATION = 32;
|
||||
|
|
|
@ -288,12 +288,10 @@ const MenuBlockContext = observer(class MenuBlockContext extends React.Component
|
|||
menuParam.data = Object.assign(menuParam.data, {
|
||||
value: (mark ? mark.param : ''),
|
||||
onChange: (param: string) => {
|
||||
if (!mark && !param) {
|
||||
return;
|
||||
if (param) {
|
||||
Storage.set(storageKey, param);
|
||||
};
|
||||
|
||||
Storage.set(storageKey, param);
|
||||
|
||||
marks = Mark.toggle(marks, { type, param, range: { from, to } });
|
||||
menuStore.updateData(this.props.id, { marks });
|
||||
onChange(marks);
|
||||
|
|
|
@ -94,7 +94,7 @@ const PageAuthSetup = observer(class PageAuthSetup extends React.Component<I.Pag
|
|||
const { match } = this.props;
|
||||
const { account, walletPath } = authStore;
|
||||
|
||||
switch (match.params.id) {
|
||||
switch (match?.params?.id) {
|
||||
case 'init': {
|
||||
this.init();
|
||||
break;
|
||||
|
|
|
@ -51,6 +51,7 @@ const PageMainGraph = observer(class PageMainGraph extends React.Component<I.Pag
|
|||
key="graph"
|
||||
{...this.props}
|
||||
ref={ref => this.refGraph = ref}
|
||||
id="global"
|
||||
rootId={rootId}
|
||||
data={this.data}
|
||||
/>
|
||||
|
|
|
@ -9,6 +9,7 @@ import { commonStore, menuStore } from 'Store';
|
|||
import Constant from 'json/constant.json';
|
||||
|
||||
interface Props {
|
||||
id?: string;
|
||||
isPopup?: boolean;
|
||||
rootId: string;
|
||||
data: any;
|
||||
|
@ -39,19 +40,12 @@ const Graph = observer(class Graph extends React.Component<Props> {
|
|||
};
|
||||
|
||||
render () {
|
||||
const { isPopup } = this.props;
|
||||
const id = [ 'graph' ];
|
||||
|
||||
if (isPopup) {
|
||||
id.push('popup');
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={node => this.node = node}
|
||||
id="graphWrapper"
|
||||
>
|
||||
<div id={id.join('-')} />
|
||||
<div id={this.getId()} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -86,15 +80,28 @@ const Graph = observer(class Graph extends React.Component<Props> {
|
|||
$(window).off(events.map(it => `${it}.graph`).join(' '));
|
||||
};
|
||||
|
||||
getId (): string {
|
||||
const { id, isPopup } = this.props;
|
||||
const ret = [ 'graph' ];
|
||||
|
||||
if (id) {
|
||||
ret.push(id);
|
||||
};
|
||||
if (isPopup) {
|
||||
ret.push('popup');
|
||||
};
|
||||
return ret.join('-');
|
||||
};
|
||||
|
||||
init () {
|
||||
const { data, isPopup, rootId } = this.props;
|
||||
const { data, rootId } = this.props;
|
||||
const node = $(this.node);
|
||||
const density = window.devicePixelRatio;
|
||||
const elementId = `#graph${isPopup ? '-popup' : ''}`;
|
||||
const elementId = `#${this.getId()}`;
|
||||
const width = node.width();
|
||||
const height = node.height();
|
||||
|
||||
this.zoom = d3.zoom().scaleExtent([ 1, 6 ]).on('zoom', e => this.onZoom(e));
|
||||
|
||||
this.zoom = d3.zoom().scaleExtent([ 0.2, 10 ]).on('zoom', e => this.onZoom(e));
|
||||
this.edges = (data.edges || []).map(this.edgeMapper);
|
||||
this.nodes = (data.nodes || []).map(this.nodeMapper);
|
||||
|
||||
|
@ -393,7 +400,7 @@ const Graph = observer(class Graph extends React.Component<Props> {
|
|||
this.edges.push(this.edgeMapper({ type: I.EdgeType.Link, source: sourceId, target: targetId }));
|
||||
this.send('onSetEdges', { edges: this.edges });
|
||||
} else {
|
||||
this.addNewNode(targetId, target => this.send('onAddNode', { target, sourceId }));
|
||||
this.addNewNode(targetId, sourceId, null);
|
||||
};
|
||||
},
|
||||
onSelect: (itemId: string) => {
|
||||
|
@ -449,12 +456,7 @@ const Graph = observer(class Graph extends React.Component<Props> {
|
|||
|
||||
UtilObject.create('', '', {}, I.BlockPosition.Bottom, '', {}, flags, (message: any) => {
|
||||
UtilObject.openPopup({ id: message.targetId }, {
|
||||
onClose: () => {
|
||||
this.addNewNode(message.targetId, target => {
|
||||
target = Object.assign(target, { x: data.x, y: data.y });
|
||||
this.send('onAddNode', { target });
|
||||
});
|
||||
}
|
||||
onClose: () => this.addNewNode(message.targetId, '', data),
|
||||
});
|
||||
|
||||
analytics.event('CreateObject', { objectType: commonStore.type, route: 'Graph' });
|
||||
|
@ -499,12 +501,20 @@ const Graph = observer(class Graph extends React.Component<Props> {
|
|||
UtilObject.openAuto(this.nodes.find(d => d.id == id));
|
||||
};
|
||||
|
||||
addNewNode (id: string, cb: (target: any) => void) {
|
||||
addNewNode (id: string, sourceId?: string, param?: any, callBack?: (object: any) => void) {
|
||||
UtilObject.getById(id, (object: any) => {
|
||||
object = this.nodeMapper(object);
|
||||
|
||||
if (param) {
|
||||
object = Object.assign(object, param);
|
||||
};
|
||||
|
||||
this.nodes.push(object);
|
||||
cb(object);
|
||||
this.send('onAddNode', { target: object, sourceId });
|
||||
|
||||
if (callBack) {
|
||||
callBack(object);
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@ export enum EmbedProcessor {
|
|||
Instagram = 13,
|
||||
Telegram = 14,
|
||||
GithubGist = 15,
|
||||
Codepen = 16,
|
||||
Bilibili = 17,
|
||||
};
|
||||
|
||||
export interface ContentEmbed {
|
||||
|
|
|
@ -328,7 +328,6 @@ class Dataview {
|
|||
|
||||
getTypeId (rootId: string, blockId: string, objectId: string, viewId?: string) {
|
||||
const view = this.getView(rootId, blockId, viewId);
|
||||
|
||||
const types = Relation.getSetOfObjects(rootId, objectId, I.ObjectLayout.Type);
|
||||
const relations = Relation.getSetOfObjects(rootId, objectId, I.ObjectLayout.Relation);
|
||||
const isAllowedDefaultType = this.isCollection(rootId, blockId) || !!Relation.getSetOfObjects(rootId, objectId, I.ObjectLayout.Relation).map(it => it.id).length;
|
||||
|
@ -359,6 +358,22 @@ class Dataview {
|
|||
return typeId;
|
||||
};
|
||||
|
||||
getCreateTooltip (rootId: string, blockId: string, objectId: string, viewId: string): string {
|
||||
const isCollection = this.isCollection(rootId, blockId);
|
||||
|
||||
if (isCollection) {
|
||||
return translate('blockDataviewCreateNewTooltipCollection');
|
||||
} else {
|
||||
const typeId = this.getTypeId(rootId, blockId, objectId, viewId);
|
||||
const type = dbStore.getTypeById(typeId);
|
||||
|
||||
if (type) {
|
||||
return UtilCommon.sprintf(translate('blockDataviewCreateNewTooltipType'), type.name);
|
||||
};
|
||||
};
|
||||
return translate('blockDataviewCreateNew');
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
export default new Dataview();
|
||||
|
|
|
@ -3,19 +3,13 @@ import { I, UtilCommon, analytics } from 'Lib';
|
|||
import Constant from 'json/constant.json';
|
||||
|
||||
const Tags = {};
|
||||
Tags[I.MarkType.Strike] = 'markupStrike';
|
||||
Tags[I.MarkType.Code] = 'markupCode';
|
||||
Tags[I.MarkType.Italic] = 'markupItalic';
|
||||
Tags[I.MarkType.Bold] = 'markupBold';
|
||||
Tags[I.MarkType.Underline] = 'markupUnderline';
|
||||
Tags[I.MarkType.Link] = 'markupLink';
|
||||
Tags[I.MarkType.Color] = 'markupColor';
|
||||
Tags[I.MarkType.BgColor] = 'markupBgcolor';
|
||||
Tags[I.MarkType.Mention] = 'markupMention';
|
||||
Tags[I.MarkType.Emoji] = 'markupEmoji';
|
||||
Tags[I.MarkType.Object] = 'markupObject';
|
||||
for (const i in I.MarkType) {
|
||||
if (isNaN(Number(i))) {
|
||||
continue;
|
||||
};
|
||||
|
||||
const LCTags = Object.values(Tags).map(it => String(it).toLowerCase());
|
||||
Tags[i] = `markup${I.MarkType[i].toLowerCase()}`;
|
||||
};
|
||||
|
||||
const Patterns = {
|
||||
'-→': '⟶',
|
||||
|
@ -461,7 +455,7 @@ class Mark {
|
|||
|
||||
const end = p1 == '/';
|
||||
const offset = Number(text.indexOf(s)) || 0;
|
||||
const type = LCTags.indexOf(p2);
|
||||
const type = Object.values(Tags).indexOf(p2);
|
||||
|
||||
if (type < 0) {
|
||||
return;
|
||||
|
@ -531,7 +525,8 @@ class Mark {
|
|||
};
|
||||
|
||||
if (check) {
|
||||
marks = this.adjust(marks, from, -p2.length * 2);
|
||||
marks = this.adjust(marks, from, -p2.length);
|
||||
marks = this.adjust(marks, to, -p4.length);
|
||||
marks.push({ type: item.type, range: { from, to }, param: '' });
|
||||
|
||||
text = text.replace(s, replace);
|
||||
|
|
|
@ -66,6 +66,7 @@ class ScrollOnMove {
|
|||
|
||||
const maxScrollX = this.documentWidth - this.viewportWidth;
|
||||
const maxScrollY = this.documentHeight - this.viewportHeight;
|
||||
|
||||
let currentScrollX = 0;
|
||||
let currentScrollY = 0;
|
||||
let container;
|
||||
|
@ -85,9 +86,10 @@ class ScrollOnMove {
|
|||
const canScrollDown = (currentScrollY < maxScrollY);
|
||||
const canScrollLeft = (currentScrollX > 0);
|
||||
const canScrollRight = (currentScrollX < maxScrollX);
|
||||
const maxStep = 10;
|
||||
|
||||
let nextScrollX = currentScrollX;
|
||||
let nextScrollY = currentScrollY;
|
||||
const maxStep = 10;
|
||||
let intensity = 0;
|
||||
|
||||
if (isInLeftEdge && canScrollLeft) {
|
||||
|
|
|
@ -421,7 +421,7 @@ class UtilData {
|
|||
|
||||
const diff = needle.length - (to - from);
|
||||
const text = UtilCommon.stringInsert(block.content.text, needle, from, to);
|
||||
const marks = Mark.adjust(block.content.marks, 0, diff);
|
||||
const marks = Mark.adjust(block.content.marks, from, diff);
|
||||
|
||||
this.blockSetText(rootId, blockId, text, marks, true, callBack);
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { I, UtilCommon } from 'Lib';
|
||||
import Constant from 'json/constant.json';
|
||||
|
||||
const DOMAINS: any = {};
|
||||
const DOMAINS: any = {};
|
||||
DOMAINS[I.EmbedProcessor.Youtube] = [ 'youtube.com', 'youtu.be' ];
|
||||
DOMAINS[I.EmbedProcessor.Vimeo] = [ 'vimeo.com' ];
|
||||
DOMAINS[I.EmbedProcessor.GoogleMaps] = [ 'google.[^\/]+/maps' ];
|
||||
|
@ -9,13 +9,15 @@ DOMAINS[I.EmbedProcessor.Miro] = [ 'miro.com' ];
|
|||
DOMAINS[I.EmbedProcessor.Figma] = [ 'figma.com' ];
|
||||
DOMAINS[I.EmbedProcessor.OpenStreetMap] = [ 'openstreetmap.org\/\#map' ];
|
||||
DOMAINS[I.EmbedProcessor.Telegram] = [ 't.me' ];
|
||||
DOMAINS[I.EmbedProcessor.Codepen] = [ 'codepen.io' ];
|
||||
DOMAINS[I.EmbedProcessor.Bilibili] = [ 'bilibili.com', 'b23.tv'];
|
||||
|
||||
const IFRAME_PARAM = 'frameborder="0" scrolling="no" allowfullscreen';
|
||||
|
||||
class UtilEmbed {
|
||||
|
||||
getHtml (processor: I.EmbedProcessor, content: any): string {
|
||||
const fn = UtilCommon.toCamelCase(`get-${I.EmbedProcessor[processor]}-html`)
|
||||
const fn = UtilCommon.toCamelCase(`get-${I.EmbedProcessor[processor]}-html`);
|
||||
return this[fn] ? this[fn](content) : '';
|
||||
};
|
||||
|
||||
|
@ -52,9 +54,24 @@ class UtilEmbed {
|
|||
return `<script src="${content}.js"></script>`;
|
||||
};
|
||||
|
||||
getCodepenHtml (content: string): string {
|
||||
const a = new URL(content);
|
||||
const p = a.pathname.split('/');
|
||||
|
||||
if (!p.length) {
|
||||
return '';
|
||||
};
|
||||
|
||||
return `<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="${p[3]}" data-user="${p[1]}"></p>`;
|
||||
};
|
||||
|
||||
getBilibiliHtml (content: string): string {
|
||||
return `<iframe src="${content}" ${IFRAME_PARAM}></iframe>`;
|
||||
};
|
||||
|
||||
getProcessorByUrl (url: string): I.EmbedProcessor {
|
||||
let p = null;
|
||||
for (let i in DOMAINS) {
|
||||
for (const i in DOMAINS) {
|
||||
const reg = new RegExp(DOMAINS[i].join('|'), 'gi');
|
||||
if (url.match(reg)) {
|
||||
p = Number(i);
|
||||
|
@ -132,6 +149,26 @@ class UtilEmbed {
|
|||
break;
|
||||
};
|
||||
|
||||
case I.EmbedProcessor.Bilibili: {
|
||||
const { pathname, searchParams } = new URL(url);
|
||||
if (!pathname) {
|
||||
break;
|
||||
};
|
||||
|
||||
const a = pathname.split('/');
|
||||
if (a.length < 3) {
|
||||
return;
|
||||
};
|
||||
|
||||
const bvid = pathname.split('/')[2];
|
||||
const [ p = 1, t = 0 ] = [ searchParams.get('p'), searchParams.get('t') ];
|
||||
|
||||
if (bvid) {
|
||||
url = `https://player.bilibili.com/player.html?bvid=${bvid}&p=${p}&t=${t}&high_quality=1&autoplay=0`;
|
||||
};
|
||||
break;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
return url;
|
||||
|
@ -167,6 +204,11 @@ class UtilEmbed {
|
|||
libs.push('https://www.instagram.com/embed.js');
|
||||
break;
|
||||
};
|
||||
|
||||
case I.EmbedProcessor.Codepen: {
|
||||
libs.push('https://cpwebassets.codepen.io/assets/embed/ei.js');
|
||||
break;
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
|
@ -184,6 +226,7 @@ class UtilEmbed {
|
|||
};
|
||||
};
|
||||
|
||||
// Allow to use same origin in iframe sandbox
|
||||
allowSameOrigin (p: I.EmbedProcessor) {
|
||||
return [
|
||||
I.EmbedProcessor.Youtube,
|
||||
|
@ -196,16 +239,21 @@ class UtilEmbed {
|
|||
I.EmbedProcessor.Reddit,
|
||||
I.EmbedProcessor.Instagram,
|
||||
I.EmbedProcessor.Telegram,
|
||||
I.EmbedProcessor.Codepen,
|
||||
I.EmbedProcessor.Bilibili,
|
||||
].includes(p);
|
||||
};
|
||||
|
||||
// Allow to use presentation mode in iframe sandbox
|
||||
allowPresentation (p: I.EmbedProcessor) {
|
||||
return [
|
||||
I.EmbedProcessor.Youtube,
|
||||
I.EmbedProcessor.Vimeo,
|
||||
I.EmbedProcessor.Bilibili
|
||||
].includes(p);
|
||||
};
|
||||
|
||||
// Allow url embedding
|
||||
allowEmbedUrl (p: I.EmbedProcessor) {
|
||||
return [
|
||||
I.EmbedProcessor.Youtube,
|
||||
|
@ -216,23 +264,29 @@ class UtilEmbed {
|
|||
I.EmbedProcessor.OpenStreetMap,
|
||||
I.EmbedProcessor.Telegram,
|
||||
I.EmbedProcessor.GithubGist,
|
||||
I.EmbedProcessor.Codepen,
|
||||
I.EmbedProcessor.Bilibili,
|
||||
].includes(p);
|
||||
};
|
||||
|
||||
// Pass block data as js code
|
||||
allowJs (p: I.EmbedProcessor) {
|
||||
return [
|
||||
I.EmbedProcessor.Chart,
|
||||
].includes(p);
|
||||
};
|
||||
|
||||
// Allow to use popup mode in iframe sandbox
|
||||
allowPopup (p: I.EmbedProcessor) {
|
||||
return [].includes(p);
|
||||
return [ I.EmbedProcessor.Bilibili ].includes(p);
|
||||
};
|
||||
|
||||
// Allow block resizing
|
||||
allowBlockResize (p: I.EmbedProcessor) {
|
||||
return ![ I.EmbedProcessor.Latex, I.EmbedProcessor.Mermaid, I.EmbedProcessor.Chart ].includes(p);
|
||||
};
|
||||
|
||||
// Use iframe height instead of fixed aspect ratio
|
||||
allowIframeResize (p: I.EmbedProcessor) {
|
||||
return [
|
||||
I.EmbedProcessor.Twitter,
|
||||
|
@ -241,15 +295,18 @@ class UtilEmbed {
|
|||
I.EmbedProcessor.Instagram,
|
||||
I.EmbedProcessor.Telegram,
|
||||
I.EmbedProcessor.GithubGist,
|
||||
I.EmbedProcessor.Codepen,
|
||||
].includes(p);
|
||||
};
|
||||
|
||||
// Render blocks on scroll
|
||||
allowScroll (p: I.EmbedProcessor) {
|
||||
return ![
|
||||
I.EmbedProcessor.Latex,
|
||||
].includes(p);
|
||||
};
|
||||
|
||||
// Render blocks on mount
|
||||
allowAutoRender (p: I.EmbedProcessor) {
|
||||
return [
|
||||
I.EmbedProcessor.Latex,
|
||||
|
@ -259,23 +316,29 @@ class UtilEmbed {
|
|||
I.EmbedProcessor.Instagram,
|
||||
I.EmbedProcessor.Telegram,
|
||||
I.EmbedProcessor.GithubGist,
|
||||
I.EmbedProcessor.Codepen,
|
||||
I.EmbedProcessor.Bilibili,
|
||||
].includes(p);
|
||||
};
|
||||
|
||||
// Insert html content before loading libs
|
||||
insertBeforeLoad (p: I.EmbedProcessor) {
|
||||
return [
|
||||
I.EmbedProcessor.Twitter,
|
||||
I.EmbedProcessor.Reddit,
|
||||
I.EmbedProcessor.Instagram,
|
||||
I.EmbedProcessor.Codepen,
|
||||
].includes(p);
|
||||
};
|
||||
|
||||
// Use root height instead of iframe scroll height
|
||||
useRootHeight (p: I.EmbedProcessor) {
|
||||
return [
|
||||
I.EmbedProcessor.Twitter,
|
||||
I.EmbedProcessor.Telegram,
|
||||
I.EmbedProcessor.Instagram,
|
||||
I.EmbedProcessor.GithubGist,
|
||||
I.EmbedProcessor.Codepen,
|
||||
].includes(p);
|
||||
};
|
||||
|
||||
|
|
|
@ -30,11 +30,11 @@ class UtilMenu {
|
|||
getBlockText () {
|
||||
return [
|
||||
{ id: I.TextStyle.Paragraph, lang: 'Paragraph' },
|
||||
{ id: I.TextStyle.Header1, lang: 'Header1', aliases: [ 'h1', 'head1' ] },
|
||||
{ id: I.TextStyle.Header2, lang: 'Header2', aliases: [ 'h2', 'head2' ] },
|
||||
{ id: I.TextStyle.Header3, lang: 'Header3', aliases: [ 'h3', 'head3' ] },
|
||||
{ id: I.TextStyle.Quote, lang: 'Quote' },
|
||||
{ id: I.TextStyle.Callout, lang: 'Callout' },
|
||||
{ id: I.TextStyle.Header1, lang: 'Header1', aliases: [ 'h1', 'head1', 'header1' ] },
|
||||
{ id: I.TextStyle.Header2, lang: 'Header2', aliases: [ 'h2', 'head2', 'header2' ] },
|
||||
{ id: I.TextStyle.Header3, lang: 'Header3', aliases: [ 'h3', 'head3', 'header3' ] },
|
||||
{ id: I.TextStyle.Quote, lang: 'Quote', aliases: [ 'quote' ] },
|
||||
{ id: I.TextStyle.Callout, lang: 'Callout', aliases: [ 'callout' ] },
|
||||
].map((it: any) => {
|
||||
it.type = I.BlockType.Text;
|
||||
it.icon = UtilData.blockTextClass(it.id);
|
||||
|
@ -44,10 +44,10 @@ class UtilMenu {
|
|||
|
||||
getBlockList () {
|
||||
return [
|
||||
{ id: I.TextStyle.Checkbox, lang: 'Checkbox', aliases: [ 'todo' ] },
|
||||
{ id: I.TextStyle.Bulleted, lang: 'Bulleted' },
|
||||
{ id: I.TextStyle.Numbered, lang: 'Numbered' },
|
||||
{ id: I.TextStyle.Toggle, lang: 'Toggle' },
|
||||
{ id: I.TextStyle.Checkbox, lang: 'Checkbox', aliases: [ 'todo', 'checkbox' ] },
|
||||
{ id: I.TextStyle.Bulleted, lang: 'Bulleted', aliases: [ 'bulleted list' ] },
|
||||
{ id: I.TextStyle.Numbered, lang: 'Numbered', aliases: [ 'numbered list' ] },
|
||||
{ id: I.TextStyle.Toggle, lang: 'Toggle', aliases: [ 'toggle' ] },
|
||||
].map((it: any) => {
|
||||
it.type = I.BlockType.Text;
|
||||
it.icon = UtilData.blockTextClass(it.id);
|
||||
|
@ -57,13 +57,13 @@ class UtilMenu {
|
|||
|
||||
getBlockMedia () {
|
||||
return [
|
||||
{ type: I.BlockType.File, id: I.FileType.File, icon: 'mediaFile', lang: 'File' },
|
||||
{ type: I.BlockType.File, id: I.FileType.Image, icon: 'mediaImage', lang: 'Image' },
|
||||
{ type: I.BlockType.File, id: I.FileType.Video, icon: 'mediaVideo', lang: 'Video' },
|
||||
{ type: I.BlockType.File, id: I.FileType.Audio, icon: 'mediaAudio', lang: 'Audio' },
|
||||
{ type: I.BlockType.File, id: I.FileType.Pdf, icon: 'mediaPdf', lang: 'Pdf' },
|
||||
{ type: I.BlockType.Bookmark, id: 'bookmark', icon: 'bookmark', lang: 'Bookmark' },
|
||||
{ type: I.BlockType.Text, id: I.TextStyle.Code, icon: 'code', lang: 'Code' },
|
||||
{ type: I.BlockType.File, id: I.FileType.File, icon: 'mediaFile', lang: 'File', aliases: [ 'file' ] },
|
||||
{ type: I.BlockType.File, id: I.FileType.Image, icon: 'mediaImage', lang: 'Image', aliases: [ 'image', 'picture' ] },
|
||||
{ type: I.BlockType.File, id: I.FileType.Video, icon: 'mediaVideo', lang: 'Video', aliases: [ 'video' ] },
|
||||
{ type: I.BlockType.File, id: I.FileType.Audio, icon: 'mediaAudio', lang: 'Audio', aliases: [ 'audio' ] },
|
||||
{ type: I.BlockType.File, id: I.FileType.Pdf, icon: 'mediaPdf', lang: 'Pdf', aliases: [ 'pdf' ] },
|
||||
{ type: I.BlockType.Bookmark, id: 'bookmark', icon: 'bookmark', lang: 'Bookmark', aliases: [ 'bookmark' ] },
|
||||
{ type: I.BlockType.Text, id: I.TextStyle.Code, icon: 'code', lang: 'Code', aliases: [ 'code' ] },
|
||||
].map(this.mapperBlock);
|
||||
};
|
||||
|
||||
|
@ -92,6 +92,8 @@ class UtilMenu {
|
|||
{ id: I.EmbedProcessor.Instagram, icon: 'instagram', name: 'Instagram' },
|
||||
{ id: I.EmbedProcessor.Telegram, icon: 'telegram', name: 'Telegram' },
|
||||
{ id: I.EmbedProcessor.GithubGist, icon: 'githubGist', name: 'Github Gist' },
|
||||
{ id: I.EmbedProcessor.Codepen, icon: 'codepen', name: 'Codepen' },
|
||||
{ id: I.EmbedProcessor.Bilibili, icon: 'bilibili', name: 'Bilibili' },
|
||||
]);
|
||||
};
|
||||
|
||||
|
@ -127,12 +129,12 @@ class UtilMenu {
|
|||
|
||||
getBlockOther () {
|
||||
return [
|
||||
{ type: I.BlockType.Div, id: I.DivStyle.Line, icon: 'divLine', lang: 'Line' },
|
||||
{ type: I.BlockType.Div, id: I.DivStyle.Dot, icon: 'divDot', lang: 'Dot' },
|
||||
{ type: I.BlockType.TableOfContents, id: I.BlockType.TableOfContents, icon: 'tableOfContents', lang: 'TableOfContents', aliases: [ 'tc', 'toc' ] },
|
||||
{ type: I.BlockType.Table, id: I.BlockType.Table, icon: 'table', lang: 'SimpleTable' },
|
||||
{ type: I.BlockType.Dataview, id: 'collection', icon: 'collection', lang: 'Collection', aliases: [ 'grid', 'table', 'gallery', 'list', 'board', 'kanban' ] },
|
||||
{ type: I.BlockType.Dataview, id: 'set', icon: 'set', lang: 'Set', aliases: [ 'grid', 'table', 'gallery', 'list', 'board', 'kanban' ] },
|
||||
{ type: I.BlockType.Div, id: I.DivStyle.Line, icon: 'divLine', lang: 'Line', aliases: [ 'hr', 'line divider' ] },
|
||||
{ type: I.BlockType.Div, id: I.DivStyle.Dot, icon: 'divDot', lang: 'Dot', aliases: [ 'dot', 'dots divider' ] },
|
||||
{ type: I.BlockType.TableOfContents, id: I.BlockType.TableOfContents, icon: 'tableOfContents', lang: 'TableOfContents', aliases: [ 'tc', 'toc', 'table of contents'] },
|
||||
{ type: I.BlockType.Table, id: I.BlockType.Table, icon: 'table', lang: 'SimpleTable', aliases: [ 'table' ] },
|
||||
{ type: I.BlockType.Dataview, id: 'collection', icon: 'collection', lang: 'Collection', aliases: [ 'grid', 'table', 'gallery', 'list', 'board', 'kanban', 'inline collection' ] },
|
||||
{ type: I.BlockType.Dataview, id: 'set', icon: 'set', lang: 'Set', aliases: [ 'grid', 'table', 'gallery', 'list', 'board', 'kanban', 'inline set' ] },
|
||||
].map(this.mapperBlock);
|
||||
};
|
||||
|
||||
|
|
|
@ -422,7 +422,7 @@ class BlockStore {
|
|||
};
|
||||
|
||||
updateMarkup (rootId: string) {
|
||||
const blocks = UtilCommon.objectCopy(this.getBlocks(rootId, it => it.isText()));
|
||||
const blocks = this.getBlocks(rootId, it => it.isText());
|
||||
|
||||
for (const block of blocks) {
|
||||
let marks = block.content.marks || [];
|
||||
|
@ -431,6 +431,7 @@ class BlockStore {
|
|||
continue;
|
||||
};
|
||||
|
||||
marks = UtilCommon.objectCopy(marks);
|
||||
marks.sort(Mark.sort);
|
||||
|
||||
let { text } = block.content;
|
||||
|
|
|
@ -164,7 +164,7 @@ class MenuStore {
|
|||
};
|
||||
|
||||
isAnimating (id: string): boolean {
|
||||
return this.isAnimatingFlag.get(id);
|
||||
return !!this.isAnimatingFlag.get(id);
|
||||
};
|
||||
|
||||
closeAll (ids?: string[], callBack?: () => void) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue