mirror of
https://github.com/anyproto/anytype-ts.git
synced 2025-06-09 09:35:02 +09:00
merge
This commit is contained in:
commit
f36210e3e4
42 changed files with 756 additions and 473 deletions
8
dist/extension/js/background.js
vendored
8
dist/extension/js/background.js
vendored
|
@ -134,11 +134,7 @@
|
|||
};
|
||||
|
||||
sendToActiveTab = async (msg) => {
|
||||
const tab = await getActiveTab();
|
||||
|
||||
console.log('[sendToActiveTab]', tab, msg);
|
||||
|
||||
await sendToTab(tab, msg);
|
||||
await sendToTab(await getActiveTab(), msg);
|
||||
};
|
||||
|
||||
sendToTab = async (tab, msg) => {
|
||||
|
@ -146,6 +142,8 @@
|
|||
return;
|
||||
};
|
||||
|
||||
msg.url = tab.url;
|
||||
|
||||
const response = await chrome.tabs.sendMessage(tab.id, msg);
|
||||
|
||||
console.log('[sendToTab]', tab, msg, response);
|
||||
|
|
|
@ -137,7 +137,7 @@ class MenuManager {
|
|||
label: Util.translate('electronMenuHelp'),
|
||||
submenu: [
|
||||
{
|
||||
label: Util.translate('electronMenuReleaseNotes') + ` (${app.getVersion()})`,
|
||||
label: `${Util.translate('electronMenuReleaseNotes')} (${app.getVersion()})`,
|
||||
click: () => Util.send(this.win, 'popup', 'help', { preventResize: true, data: { document: 'whatsNew' } })
|
||||
},
|
||||
{
|
||||
|
@ -228,6 +228,13 @@ class MenuManager {
|
|||
|
||||
Separator,
|
||||
|
||||
{
|
||||
label: 'Experience gallery',
|
||||
click: () => Util.send(this.win, 'popup', 'usecase', {})
|
||||
},
|
||||
|
||||
Separator,
|
||||
|
||||
{ label: 'Export templates', click: () => Util.send(this.win, 'commandGlobal', 'exportTemplates') },
|
||||
{ label: 'Export objects', click: () => Util.send(this.win, 'commandGlobal', 'exportObjects') },
|
||||
{ label: 'Export localstore', click: () => Util.send(this.win, 'commandGlobal', 'exportLocalstore') },
|
||||
|
|
|
@ -1,18 +1,42 @@
|
|||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import $ from 'jquery';
|
||||
import { C, UtilCommon, UtilRouter } from 'Lib';
|
||||
import Popup from './popup';
|
||||
import Iframe from './iframe';
|
||||
import Util from './lib/util';
|
||||
import Extension from 'json/extension.json';
|
||||
import * as Store from 'Store';
|
||||
|
||||
import './scss/common.scss';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
isExtension: boolean;
|
||||
Electron: any;
|
||||
$: any;
|
||||
Anytype: any;
|
||||
isWebVersion: boolean;
|
||||
AnytypeGlobalConfig: any;
|
||||
}
|
||||
};
|
||||
|
||||
window.$ = $;
|
||||
window.isExtension = true;
|
||||
window.Electron = {
|
||||
currentWindow: () => ({ windowId: 1 }),
|
||||
Api: () => {},
|
||||
};
|
||||
|
||||
window.Anytype = {
|
||||
Store,
|
||||
Lib: {
|
||||
C,
|
||||
UtilCommon,
|
||||
UtilRouter,
|
||||
},
|
||||
};
|
||||
|
||||
window.AnytypeGlobalConfig = {
|
||||
emojiUrl: Extension.clipper.emojiUrl,
|
||||
menuBorderTop: 16,
|
||||
|
@ -32,6 +56,8 @@ if (Util.isIframe()) {
|
|||
component = <Iframe />;
|
||||
};
|
||||
|
||||
console.log(window.Anytype);
|
||||
|
||||
if (!rootId) {
|
||||
console.error('[Entry] rootId is not defined');
|
||||
} else {
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import * as React from 'react';
|
||||
import * as hs from 'history';
|
||||
import $ from 'jquery';
|
||||
import { Router, Route, Switch } from 'react-router-dom';
|
||||
import { RouteComponentProps } from 'react-router';
|
||||
import { Provider } from 'mobx-react';
|
||||
import { configure } from 'mobx';
|
||||
import { ListMenu } from 'Component';
|
||||
import { dispatcher, C, UtilCommon, UtilRouter } from 'Lib';
|
||||
import { UtilRouter } from 'Lib';
|
||||
import { commonStore, authStore, blockStore, detailStore, dbStore, menuStore, popupStore, extensionStore } from 'Store';
|
||||
|
||||
import Index from './iframe/index';
|
||||
|
@ -41,28 +40,6 @@ const rootStore = {
|
|||
extensionStore,
|
||||
};
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
Electron: any;
|
||||
$: any;
|
||||
Anytype: any;
|
||||
isWebVersion: boolean;
|
||||
AnytypeGlobalConfig: any;
|
||||
}
|
||||
};
|
||||
|
||||
window.$ = $;
|
||||
window.$ = $;
|
||||
window.Anytype = {
|
||||
Store: rootStore,
|
||||
Lib: {
|
||||
C,
|
||||
UtilCommon,
|
||||
dispatcher,
|
||||
Storage,
|
||||
},
|
||||
};
|
||||
|
||||
class RoutePage extends React.Component<RouteComponentProps> {
|
||||
render () {
|
||||
const { match } = this.props;
|
||||
|
@ -118,6 +95,7 @@ class Iframe extends React.Component {
|
|||
break;
|
||||
|
||||
case 'clickMenu': {
|
||||
extensionStore.setTabUrl(msg.url);
|
||||
extensionStore.setHtml(msg.html);
|
||||
|
||||
sendResponse({});
|
||||
|
|
|
@ -88,7 +88,7 @@ const Create = observer(class Create extends React.Component<I.PageComponent, St
|
|||
);
|
||||
};
|
||||
|
||||
componentDidMount(): void {
|
||||
componentDidMount (): void {
|
||||
const spaces = dbStore.getSpaces().map(it => ({ ...it, id: it.targetSpaceId, object: it, iconSize: 16 })).filter(it => it);
|
||||
|
||||
if (this.refSpace && spaces.length) {
|
||||
|
@ -105,7 +105,7 @@ const Create = observer(class Create extends React.Component<I.PageComponent, St
|
|||
};
|
||||
|
||||
initBlocks () {
|
||||
const { html } = extensionStore;
|
||||
const { html, tabUrl } = extensionStore;
|
||||
|
||||
if (!html || (html == this.html)) {
|
||||
return;
|
||||
|
@ -113,7 +113,7 @@ const Create = observer(class Create extends React.Component<I.PageComponent, St
|
|||
|
||||
this.html = html;
|
||||
|
||||
C.BlockPreview(html, (message: any) => {
|
||||
C.BlockPreview(html, tabUrl, (message: any) => {
|
||||
if (message.error.code) {
|
||||
return;
|
||||
};
|
||||
|
@ -167,13 +167,14 @@ const Create = observer(class Create extends React.Component<I.PageComponent, St
|
|||
};
|
||||
|
||||
onSave () {
|
||||
const { html, tabUrl } = extensionStore;
|
||||
const { object } = this.state;
|
||||
|
||||
if (!object) {
|
||||
return;
|
||||
};
|
||||
|
||||
C.BlockPaste (object.id, '', { from: 0, to: 0 }, [], false, { html: this.html }, () => {
|
||||
C.BlockPaste(object.id, '', { from: 0, to: 0 }, [], false, { html }, tabUrl, () => {
|
||||
this.onClose();
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import * as React from 'react';
|
||||
import * as hs from 'history';
|
||||
import $ from 'jquery';
|
||||
import { Router, Route, Switch } from 'react-router-dom';
|
||||
import { RouteComponentProps } from 'react-router';
|
||||
import { Provider } from 'mobx-react';
|
||||
import { configure } from 'mobx';
|
||||
import { ListMenu } from 'Component';
|
||||
import { dispatcher, C, UtilCommon, UtilRouter } from 'Lib';
|
||||
import { UtilRouter } from 'Lib';
|
||||
import { commonStore, authStore, blockStore, detailStore, dbStore, menuStore, popupStore, extensionStore } from 'Store';
|
||||
import Extension from 'json/extension.json';
|
||||
|
||||
|
@ -45,27 +44,6 @@ const rootStore = {
|
|||
extensionStore,
|
||||
};
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
Electron: any;
|
||||
$: any;
|
||||
Anytype: any;
|
||||
isWebVersion: boolean;
|
||||
AnytypeGlobalConfig: any;
|
||||
}
|
||||
};
|
||||
|
||||
window.$ = $;
|
||||
window.Anytype = {
|
||||
Store: rootStore,
|
||||
Lib: {
|
||||
C,
|
||||
UtilCommon,
|
||||
dispatcher,
|
||||
Storage,
|
||||
},
|
||||
};
|
||||
|
||||
class RoutePage extends React.Component<RouteComponentProps> {
|
||||
render () {
|
||||
const { match } = this.props;
|
||||
|
|
|
@ -81,4 +81,6 @@ html.anytypeWebclipper-popup {
|
|||
.inner { border-color: var(--color-ice) !important; box-shadow: 0px 0px 0px 1px var(--color-ice) !important; }
|
||||
.input { border: unset !important; box-shadow: unset !important; }
|
||||
}
|
||||
|
||||
.passThrough { pointer-events: all; }
|
||||
}
|
|
@ -3,7 +3,6 @@
|
|||
.blocks {
|
||||
.block.blockFeatured {
|
||||
@include text-common; line-height: 28px; color: var(--color-text-secondary); padding: 0px 0px 24px 0px; white-space: nowrap; display: flex;
|
||||
margin-top: -3px;
|
||||
}
|
||||
.block.blockFeatured {
|
||||
.icon.checkbox { width: 20px; height: 20px; vertical-align: middle; margin-top: -4px; background-image: url('~img/icon/dataview/checkbox0.svg'); }
|
||||
|
@ -58,6 +57,7 @@
|
|||
.iconObject * { position: static; vertical-align: middle; margin: 0px; }
|
||||
.name { display: none; }
|
||||
.empty { padding: 0px 4px; }
|
||||
.more { margin-top: 2px; }
|
||||
}
|
||||
|
||||
.cellContent.c-object, .cellContent.c-file {
|
||||
|
@ -72,6 +72,10 @@
|
|||
.cellContent.c-checkbox {
|
||||
.icon { margin: 0px 5px 0px 0px; }
|
||||
}
|
||||
|
||||
.cellContent.c-longText {
|
||||
.name { display: inline-block; vertical-align: top; max-width: 220px; @include text-overflow-nw; }
|
||||
}
|
||||
}
|
||||
.block.blockFeatured > .wrapMenu:hover > .icon.dnd { opacity: 1; }
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ html.platformWindows, html.platformLinux {
|
|||
.txt { vertical-align: middle; display: inline-block; line-height: 1; }
|
||||
.flex { display: flex; }
|
||||
.nw { white-space: nowrap; }
|
||||
.through { pointer-events: none; }
|
||||
.passThrough { pointer-events: none; }
|
||||
.rel { position: relative; }
|
||||
.disabled { opacity: 0.5; cursor: default !important; }
|
||||
.dis { cursor: default !important; }
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
.tab:last-child { margin: 0px; }
|
||||
}
|
||||
|
||||
.titleWrapper { display: flex; gap: 0 6px; padding: 8px 14px; align-items: center; }
|
||||
.titleWrapper { display: flex; gap: 0 6px; padding: 8px 14px 0px; align-items: center; }
|
||||
.titleWrapper {
|
||||
.icon.back { width: 20px; height: 20px; background-image: url('~img/arrow/menu.svg'); transform: rotateZ(180deg); }
|
||||
.title { @include text-common; font-weight: 600; color: var(--color-text-primary); padding: 0; }
|
||||
|
@ -270,4 +270,4 @@ html.platformWindows {
|
|||
@import "./dataview/source.scss";
|
||||
@import "./dataview/text.scss";
|
||||
@import "./dataview/view.scss";
|
||||
@import "./dataview/template.scss";
|
||||
@import "./dataview/template.scss";
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
.content { padding-top: 12px; padding-bottom: 0px; transition: none; }
|
||||
.wrap { height: 100%; display: flex; flex-direction: column; }
|
||||
|
||||
.items { height: calc(100% - 34px); }
|
||||
.items { height: calc(100% - 28px); }
|
||||
.item {
|
||||
.name { @include text-overflow-nw; width: calc(100% - 26px); }
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
|||
}
|
||||
|
||||
.menu.menuDataviewFileValues {
|
||||
.titleWrapper,
|
||||
.content { padding-bottom: 0px; }
|
||||
|
||||
.item { display: flex; color: var(--color-text-secondary); }
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
|
||||
.menu.menuDataviewObjectValues { width: 288px; }
|
||||
.menu.menuDataviewObjectValues {
|
||||
.titleWrapper { padding-bottom: 0px; }
|
||||
.content { padding: 0px; }
|
||||
|
||||
.item:not(.add) { padding: 4px 16px 4px 12px; }
|
||||
|
|
|
@ -72,8 +72,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.menu.menuDataviewOptionList.featuredRelation {
|
||||
.titleWrapper { padding-bottom: 0px; }
|
||||
.menu.menuDataviewOptionList.fromFeatured {
|
||||
.filter { padding-top: 8px; }
|
||||
.item {
|
||||
.buttons,
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
@import "~scss/_vars";
|
||||
|
||||
.menus {
|
||||
.menu.menuDataviewText { box-shadow: 0px 0px; background: transparent; }
|
||||
.menu.menuDataviewText {
|
||||
.menu.menuDataviewText:not(.fromFeatured) { box-shadow: 0px 0px; background: transparent; }
|
||||
.menu.menuDataviewText:not(.fromFeatured) {
|
||||
.content { overflow: visible !important; max-height: none; height: 100%; transition: $transitionAllCommon; padding: 0px; }
|
||||
.editableWrap { height: 100%; }
|
||||
|
||||
|
@ -16,9 +16,13 @@
|
|||
#input { padding: 5px 8px; }
|
||||
#placeholder { padding: 5px 8px; }
|
||||
}
|
||||
.menu.menuDataviewText.show {
|
||||
.menu.menuDataviewText.show:not(.fromFeatured) {
|
||||
#input { box-shadow: 0px 0px 0px 2px var(--color-system-accent-50); }
|
||||
}
|
||||
|
||||
.menu.menuDataviewText.fromFeatured {
|
||||
.content { padding: 8px 14px; }
|
||||
}
|
||||
}
|
||||
|
||||
html.platformWindows {
|
||||
|
@ -27,4 +31,4 @@ html.platformWindows {
|
|||
#input { overflow: overlay; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
}
|
||||
|
||||
.menu.menuDataviewViewSettings {
|
||||
.content { padding-top: 0; }
|
||||
.filter.isName { margin-bottom: 4px; }
|
||||
}
|
||||
|
||||
|
|
|
@ -73,7 +73,6 @@
|
|||
|
||||
/* Links, Backlinks */
|
||||
.menu.menuSelect.featuredLinks {
|
||||
.titleWrapper { padding-bottom: 0px; }
|
||||
.item {
|
||||
.info { width: 100%; }
|
||||
.iconObject { margin: 0px; background-color: var(--color-shape-highlight-medium); }
|
||||
|
|
|
@ -137,7 +137,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.phraseWrapper { border-radius: 12px; background-color: var(--color-shape-tertiary); padding: 16px 12px; line-height: unset; }
|
||||
.phraseWrapper { border-radius: 12px; background-color: var(--color-shape-tertiary); padding: 16px 44px; line-height: unset; }
|
||||
.phraseWrapper {
|
||||
.phraseInnerWrapper { min-height: unset; display: flex; justify-content: center; gap: 8px; flex-wrap: wrap; word-break: unset; }
|
||||
.word { font-size: 12px; line-height: 18px; font-weight: 500; margin: 0; }
|
||||
|
|
|
@ -2,54 +2,70 @@
|
|||
|
||||
.popups {
|
||||
.popup.popupUsecase {
|
||||
.innerWrap { width: 816px; padding: 32px 56px; }
|
||||
.innerWrap { width: 816px; max-height: calc(100% - 128px); }
|
||||
|
||||
.titleWrap {
|
||||
margin: 0px 0px 40px 0px; display: flex; flex-direction: row; align-items: center; justify-content: stretch; gap: 0px 16px;
|
||||
}
|
||||
.titleWrap {
|
||||
.side.left { flex-grow: 1; display: flex; flex-direction: column; gap: 8px 0px; }
|
||||
.side.right { flex-shrink: 0; }
|
||||
.page { padding: 32px 56px; }
|
||||
|
||||
.title { @include text-header1; }
|
||||
.label { @include text-small; color: var(--color-text-secondary); }
|
||||
}
|
||||
|
||||
.screenWrap {
|
||||
height: 480px; background: var(--color-shape-highlight-light); margin: 0px -56px 20px -56px; padding: 20px 56px; overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
.screenWrap {
|
||||
.swiper { height: 100%; overflow: visible; }
|
||||
.swiper-slide { display: flex; align-items: center; justify-content: center; }
|
||||
|
||||
.screen {
|
||||
width: 100%; box-shadow: 0px 2px 28px 0px rgba(0, 0, 0, 0.20); background-size: contain;
|
||||
background-position: center; background-repeat: no-repeat; border-radius: 6px; background-color: var(--color-bg-primary);
|
||||
}
|
||||
|
||||
.icon.arrow {
|
||||
position: absolute; width: 44px; height: 44px; top: 50%; margin-top: -22px; background-color: var(--color-bg-primary); z-index: 1;
|
||||
border-radius: 50%; box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.2); background-image: url('~img/arrow/usecase.svg'); background-size: 20px;
|
||||
transition: $transitionAllCommon; border: 1px solid var(--color-shape-primary);
|
||||
}
|
||||
.icon.arrow.hide { opacity: 0; }
|
||||
.icon.arrow.left { left: 24px; transform: rotateZ(180deg); }
|
||||
.icon.arrow.right { right: 24px; }
|
||||
}
|
||||
|
||||
.footerWrap { display: flex; flex-direction: row; align-items: flex-start; justify-content: stretch; }
|
||||
.footerWrap {
|
||||
.side { max-height: 240px; overflow: auto; }
|
||||
|
||||
.side.left { flex-grow: 1; padding-right: 16px; }
|
||||
.side.right { flex-shrink: 0; width: 220px; padding-left: 16px; }
|
||||
.side.right {
|
||||
.tags {
|
||||
.tagItem { @include text-small; margin: 0px 8px 8px 0px; background: var(--color-shape-highlight-medium); color: var(--color-text-secondary); }
|
||||
.page.pageList {
|
||||
.items { display: grid; gap: 32px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
||||
.item {
|
||||
.picture {
|
||||
aspect-ratio: 16/9; background-size: cover; background-repeat: no-repeat; background-position: center; border-radius: 8px;
|
||||
margin: 0px 0px 12px 0px;
|
||||
}
|
||||
.name { @include text-paragraph; @include clamp1; margin: 0px 0px 4px 0px; font-weight: 600; }
|
||||
.descr { @include text-small; @include clamp2; }
|
||||
}
|
||||
}
|
||||
|
||||
.page.pageItem {
|
||||
.titleWrap {
|
||||
margin: 0px 0px 40px 0px; display: flex; flex-direction: row; align-items: center; justify-content: stretch; gap: 0px 16px;
|
||||
}
|
||||
.titleWrap {
|
||||
.side.left { flex-grow: 1; display: flex; flex-direction: column; gap: 8px 0px; }
|
||||
.side.right { flex-shrink: 0; }
|
||||
|
||||
.title { @include text-header1; }
|
||||
.label { @include text-small; color: var(--color-text-secondary); }
|
||||
}
|
||||
|
||||
.screenWrap {
|
||||
height: 480px; background: var(--color-shape-highlight-light); margin: 0px -56px 20px -56px; padding: 20px 56px; overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
.screenWrap {
|
||||
.swiper { height: 100%; overflow: visible; }
|
||||
.swiper-slide { display: flex; align-items: center; justify-content: center; }
|
||||
|
||||
.screen {
|
||||
width: 100%; box-shadow: 0px 2px 28px 0px rgba(0, 0, 0, 0.20); background-size: contain;
|
||||
background-position: center; background-repeat: no-repeat; border-radius: 6px; background-color: var(--color-bg-primary);
|
||||
}
|
||||
|
||||
.icon.arrow {
|
||||
position: absolute; width: 44px; height: 44px; top: 50%; margin-top: -22px; background-color: var(--color-bg-primary); z-index: 1;
|
||||
border-radius: 50%; box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.2); background-image: url('~img/arrow/usecase.svg'); background-size: 20px;
|
||||
transition: $transitionAllCommon; border: 1px solid var(--color-shape-primary);
|
||||
}
|
||||
.icon.arrow.hide { opacity: 0; }
|
||||
.icon.arrow.left { left: 24px; transform: rotateZ(180deg); }
|
||||
.icon.arrow.right { right: 24px; }
|
||||
}
|
||||
|
||||
.footerWrap { display: flex; flex-direction: row; align-items: flex-start; justify-content: stretch; }
|
||||
.footerWrap {
|
||||
.side { max-height: 240px; overflow: auto; }
|
||||
|
||||
.side.left { flex-grow: 1; padding-right: 16px; }
|
||||
.side.right { flex-shrink: 0; width: 220px; padding-left: 16px; }
|
||||
.side.right {
|
||||
.tags {
|
||||
.tagItem { @include text-small; margin: 0px 8px 8px 0px; background: var(--color-shape-highlight-medium); color: var(--color-text-secondary); }
|
||||
}
|
||||
.label { @include text-small; color: var(--color-text-secondary); margin: 0px 0px 8px 0px; }
|
||||
.label:last-child { margin: 0px; }
|
||||
}
|
||||
.label { @include text-small; color: var(--color-text-secondary); margin: 0px 0px 8px 0px; }
|
||||
.label:last-child { margin: 0px; }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -112,8 +112,10 @@
|
|||
/* PopupUsecase */
|
||||
|
||||
.popup.popupUsecase {
|
||||
.screenWrap {
|
||||
.icon.arrow { background-color: var(--color-bg-secondary); background-image: url('#{$themePath}/arrow/usecase.svg'); }
|
||||
.page.pageItem {
|
||||
.screenWrap {
|
||||
.icon.arrow { background-color: var(--color-bg-secondary); background-image: url('#{$themePath}/arrow/usecase.svg'); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ interface State {
|
|||
|
||||
declare global {
|
||||
interface Window {
|
||||
isExtension: boolean;
|
||||
$: any;
|
||||
Electron: any;
|
||||
Anytype: any;
|
||||
|
|
|
@ -595,27 +595,83 @@ const BlockFeatured = observer(class BlockFeatured extends React.Component<Props
|
|||
return;
|
||||
};
|
||||
|
||||
const { isPopup, rootId, readonly } = this.props;
|
||||
const { isPopup, rootId, block, readonly } = this.props;
|
||||
const storeId = this.getStoreId();
|
||||
const object = detailStore.get(rootId, storeId, [ relationKey ]);
|
||||
const relation = dbStore.getRelationByKey(relationKey);
|
||||
|
||||
if (readonly || relation.isReadonlyValue) {
|
||||
return;
|
||||
};
|
||||
|
||||
let menuId: string = '';
|
||||
let menuParam: any = {};
|
||||
let menuData: any = {};
|
||||
|
||||
switch (relation.format) {
|
||||
case I.RelationType.Object: {
|
||||
this.onCellObject(e, relationKey);
|
||||
menuId = 'dataviewObjectValues';
|
||||
menuParam.subIds = [ 'dataviewObjectList' ];
|
||||
menuData = {
|
||||
value: Relation.getArrayValue(object[relationKey]),
|
||||
filters: []
|
||||
};
|
||||
|
||||
break;
|
||||
};
|
||||
|
||||
case I.RelationType.Date: {
|
||||
this.onCellDate(e, relationKey);
|
||||
let value = null;
|
||||
let isEmpty = false;
|
||||
|
||||
if (object[relationKey]) {
|
||||
value = Number(object[relationKey]);
|
||||
} else {
|
||||
value = Number(UtilDate.now());
|
||||
isEmpty = true;
|
||||
};
|
||||
|
||||
menuId = 'dataviewCalendar';
|
||||
menuData = {
|
||||
value,
|
||||
isEmpty
|
||||
};
|
||||
|
||||
break;
|
||||
};
|
||||
|
||||
case I.RelationType.Select:
|
||||
case I.RelationType.MultiSelect: {
|
||||
this.onCellSelect(e, relationKey);
|
||||
menuId = 'dataviewOptionList';
|
||||
menuData = {
|
||||
value: Relation.getArrayValue(object[relationKey]),
|
||||
canAdd: true,
|
||||
maxCount: relation.maxCount,
|
||||
};
|
||||
|
||||
break;
|
||||
};
|
||||
|
||||
case I.RelationType.File: {
|
||||
menuId = 'dataviewFileValues';
|
||||
menuParam = {
|
||||
width: 280,
|
||||
subIds: [ 'dataviewFileList' ],
|
||||
};
|
||||
menuData = {
|
||||
value: object[relationKey] || [],
|
||||
subId: rootId,
|
||||
};
|
||||
|
||||
break;
|
||||
};
|
||||
|
||||
case I.RelationType.Number:
|
||||
case I.RelationType.LongText: {
|
||||
menuId = 'dataviewText';
|
||||
menuParam.width = 288;
|
||||
menuData.value = object[relationKey] || '';
|
||||
|
||||
break;
|
||||
};
|
||||
|
||||
|
@ -659,6 +715,56 @@ const BlockFeatured = observer(class BlockFeatured extends React.Component<Props
|
|||
break;
|
||||
};
|
||||
};
|
||||
|
||||
if (menuId) {
|
||||
this.onCellMenu(relationKey, menuId, menuParam, menuData);
|
||||
};
|
||||
};
|
||||
|
||||
onCellMenu (relationKey: string, menuId: string, param: any, data: any) {
|
||||
const { rootId, block } = this.props;
|
||||
const storeId = this.getStoreId();
|
||||
const object = detailStore.get(rootId, storeId, [ relationKey ]);
|
||||
const relation = dbStore.getRelationByKey(relationKey);
|
||||
const elementId = Relation.cellId(PREFIX + block.id, relationKey, object.id);
|
||||
|
||||
if (!relation) {
|
||||
return;
|
||||
};
|
||||
|
||||
let menuParam = {
|
||||
element: `#${elementId}`,
|
||||
className: 'fromFeatured',
|
||||
horizontal: I.MenuDirection.Left,
|
||||
offsetY: 4,
|
||||
noFlipX: true,
|
||||
title: relation.name,
|
||||
onClose: () => {
|
||||
menuStore.closeAll();
|
||||
},
|
||||
data: {
|
||||
rootId,
|
||||
blockId: block.id,
|
||||
relation: observable.box(relation),
|
||||
onChange: (v: any, callBack?: () => void) => {
|
||||
const details = [
|
||||
{ key: relationKey, value: Relation.formatValue(relation, v, true) },
|
||||
];
|
||||
C.ObjectSetDetails(rootId, details);
|
||||
|
||||
if (callBack) {
|
||||
callBack();
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
menuParam = Object.assign(menuParam, param);
|
||||
menuParam.data = Object.assign(menuParam.data, data);
|
||||
|
||||
menuStore.closeAll(Constant.menuIds.cell, () => {
|
||||
menuStore.open(menuId, menuParam);
|
||||
});
|
||||
};
|
||||
|
||||
onLinks (e: React.MouseEvent, relationKey: string) {
|
||||
|
@ -700,122 +806,6 @@ const BlockFeatured = observer(class BlockFeatured extends React.Component<Props
|
|||
});
|
||||
};
|
||||
|
||||
onCellObject (e: React.MouseEvent, relationKey: string) {
|
||||
const { rootId, block } = this.props;
|
||||
const storeId = this.getStoreId();
|
||||
const object = detailStore.get(rootId, storeId, [ relationKey ]);
|
||||
const relation = dbStore.getRelationByKey(relationKey);
|
||||
const value = Relation.getArrayValue(object[relationKey]);
|
||||
const elementId = Relation.cellId(PREFIX + block.id, relationKey, object.id);
|
||||
const filters = [];
|
||||
|
||||
menuStore.closeAll(Constant.menuIds.cell, () => {
|
||||
menuStore.open('dataviewObjectValues', {
|
||||
element: `#${elementId}`,
|
||||
horizontal: I.MenuDirection.Left,
|
||||
offsetY: 4,
|
||||
noFlipX: true,
|
||||
title: relation.name,
|
||||
subIds: [ 'dataviewObjectList' ],
|
||||
onClose: () => {
|
||||
menuStore.closeAll();
|
||||
},
|
||||
data: {
|
||||
rootId,
|
||||
value,
|
||||
filters,
|
||||
types: relation.objectTypes,
|
||||
relation: observable.box(relation),
|
||||
onChange: (v: any, callBack?: () => void) => {
|
||||
const details = [
|
||||
{ key: relationKey, value: Relation.formatValue(relation, v, true) },
|
||||
];
|
||||
C.ObjectSetDetails(rootId, details);
|
||||
|
||||
if (callBack) {
|
||||
callBack();
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
onCellDate (e: React.MouseEvent, relationKey: string) {
|
||||
const { rootId, block } = this.props;
|
||||
const storeId = this.getStoreId();
|
||||
const object = detailStore.get(rootId, storeId, [ relationKey ]);
|
||||
const relation = dbStore.getRelationByKey(relationKey);
|
||||
const elementId = Relation.cellId(PREFIX + block.id, relationKey, object.id);
|
||||
|
||||
let value = null;
|
||||
let isEmpty = false;
|
||||
|
||||
if (object[relationKey]) {
|
||||
value = Number(object[relationKey]);
|
||||
} else {
|
||||
value = Number(UtilDate.now());
|
||||
isEmpty = true;
|
||||
};
|
||||
|
||||
menuStore.closeAll(Constant.menuIds.cell, () => {
|
||||
menuStore.open('dataviewCalendar', {
|
||||
element: `#${elementId}`,
|
||||
horizontal: I.MenuDirection.Left,
|
||||
offsetY: 4,
|
||||
noFlipX: true,
|
||||
title: relation.name,
|
||||
data: {
|
||||
value,
|
||||
isEmpty,
|
||||
onChange: (v: number) => {
|
||||
const details = [
|
||||
{ key: relationKey, value: Relation.formatValue(relation, v, true) },
|
||||
];
|
||||
C.ObjectSetDetails(rootId, details);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
onCellSelect (e: React.MouseEvent, relationKey: string) {
|
||||
const { rootId, block } = this.props;
|
||||
const storeId = this.getStoreId();
|
||||
const object = detailStore.get(rootId, storeId, [ relationKey ]);
|
||||
const relation = dbStore.getRelationByKey(relationKey);
|
||||
const value = Relation.getArrayValue(object[relationKey]);
|
||||
const elementId = Relation.cellId(PREFIX + block.id, relationKey, object.id);
|
||||
|
||||
menuStore.closeAll(Constant.menuIds.cell, () => {
|
||||
menuStore.open('dataviewOptionList', {
|
||||
element: `#${elementId}`,
|
||||
className: 'featuredRelation',
|
||||
horizontal: I.MenuDirection.Left,
|
||||
noFlipY: true,
|
||||
offsetY: 4,
|
||||
title: relation.name,
|
||||
onClose: () => {
|
||||
menuStore.closeAll();
|
||||
},
|
||||
data: {
|
||||
rootId: rootId,
|
||||
blockId: block.id,
|
||||
value,
|
||||
relation: observable.box(relation),
|
||||
maxCount: relation.maxCount,
|
||||
canAdd: true,
|
||||
onChange: (v) => {
|
||||
const details = [
|
||||
{ key: relationKey, value: Relation.formatValue(relation, v, true) },
|
||||
];
|
||||
C.ObjectSetDetails(rootId, details);
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
elementMapper (relation: any, item: any) {
|
||||
item = UtilCommon.objectCopy(item);
|
||||
|
||||
|
|
|
@ -170,7 +170,7 @@ const DragProvider = observer(class DragProvider extends React.Component<Props>
|
|||
// String items drop
|
||||
if (items && items.length) {
|
||||
UtilCommon.getDataTransferString(items, (html: string) => {
|
||||
C.BlockPaste(rootId, targetId, { from: 0, to: 0 }, [], false, { html });
|
||||
C.BlockPaste(rootId, targetId, { from: 0, to: 0 }, [], false, { html }, '');
|
||||
});
|
||||
|
||||
this.clearState();
|
||||
|
|
|
@ -1691,7 +1691,7 @@ const EditorPage = observer(class EditorPage extends React.Component<Props, Stat
|
|||
let from = 0;
|
||||
let to = 0;
|
||||
|
||||
C.BlockPaste(rootId, focused, range, selection.get(I.SelectType.Block, true), data.anytype.range.to > 0, { ...data, anytype: data.anytype.blocks }, (message: any) => {
|
||||
C.BlockPaste(rootId, focused, range, selection.get(I.SelectType.Block, true), data.anytype.range.to > 0, { ...data, anytype: data.anytype.blocks }, '', (message: any) => {
|
||||
if (message.error.code) {
|
||||
return;
|
||||
};
|
||||
|
|
|
@ -165,8 +165,10 @@ class Input extends React.Component<Props, State> {
|
|||
};
|
||||
|
||||
this.isFocused = true;
|
||||
keyboard.setFocus(true);
|
||||
this.addClass('isFocused');
|
||||
|
||||
keyboard.setFocus(true);
|
||||
keyboard.disableSelection(true);
|
||||
};
|
||||
|
||||
onBlur (e: any) {
|
||||
|
@ -175,8 +177,10 @@ class Input extends React.Component<Props, State> {
|
|||
};
|
||||
|
||||
this.isFocused = false;
|
||||
keyboard.setFocus(false);
|
||||
this.removeClass('isFocused');
|
||||
|
||||
keyboard.setFocus(false);
|
||||
keyboard.disableSelection(false);
|
||||
};
|
||||
|
||||
onPaste (e: any) {
|
||||
|
|
|
@ -3,7 +3,7 @@ import $ from 'jquery';
|
|||
import { observer } from 'mobx-react';
|
||||
import { AutoSizer, CellMeasurer, InfiniteLoader, List, CellMeasurerCache } from 'react-virtualized';
|
||||
import { Filter, MenuItemVertical, Icon, Loader } from 'Component';
|
||||
import { I, UtilCommon, Relation, keyboard, UtilData, UtilObject, UtilFile, translate } from 'Lib';
|
||||
import { I, UtilCommon, Relation, keyboard, UtilData, UtilObject, UtilFile, translate, Action, C } from 'Lib';
|
||||
import { commonStore, menuStore, dbStore } from 'Store';
|
||||
import Constant from 'json/constant.json';
|
||||
|
||||
|
@ -12,6 +12,7 @@ interface State {
|
|||
};
|
||||
|
||||
const HEIGHT = 28;
|
||||
const HEIGHT_DIV = 16;
|
||||
const MENU_ID = 'dataviewFileValues';
|
||||
const LIMIT_HEIGHT = 20;
|
||||
|
||||
|
@ -36,6 +37,8 @@ const MenuDataviewFileList = observer(class MenuDataviewFileList extends React.C
|
|||
|
||||
this.loadMoreRows = this.loadMoreRows.bind(this);
|
||||
this.onClick = this.onClick.bind(this);
|
||||
this.onUpload = this.onUpload.bind(this);
|
||||
this.onChange = this.onChange.bind(this);
|
||||
this.onFilterChange = this.onFilterChange.bind(this);
|
||||
this.onScroll = this.onScroll.bind(this);
|
||||
};
|
||||
|
@ -49,6 +52,7 @@ const MenuDataviewFileList = observer(class MenuDataviewFileList extends React.C
|
|||
|
||||
const rowRenderer = (param: any) => {
|
||||
const item: any = items[param.index];
|
||||
|
||||
if (!item) {
|
||||
return null;
|
||||
};
|
||||
|
@ -56,10 +60,17 @@ const MenuDataviewFileList = observer(class MenuDataviewFileList extends React.C
|
|||
const type = dbStore.getTypeById(item.type);
|
||||
|
||||
let content = null;
|
||||
if (item.id == 'add') {
|
||||
if (item.isDiv) {
|
||||
content = (
|
||||
<div id="item-add" className="item add" onMouseEnter={e => this.onOver(e, item)} onClick={e => this.onClick(e, item)} style={param.style}>
|
||||
<Icon className="plus" />
|
||||
<div className="separator" style={param.style}>
|
||||
<div className="inner" />
|
||||
</div>
|
||||
);
|
||||
} else
|
||||
if (item.id == 'upload') {
|
||||
content = (
|
||||
<div id="item-upload" className="item upload" onMouseEnter={e => this.onOver(e, item)} onClick={this.onUpload} style={param.style}>
|
||||
<Icon className="upload" />
|
||||
<div className="name">{item.name}</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -118,7 +129,7 @@ const MenuDataviewFileList = observer(class MenuDataviewFileList extends React.C
|
|||
height={height}
|
||||
deferredMeasurmentCache={this.cache}
|
||||
rowCount={items.length}
|
||||
rowHeight={HEIGHT}
|
||||
rowHeight={({ index }) => this.getRowHeight(items[index])}
|
||||
rowRenderer={rowRenderer}
|
||||
onRowsRendered={onRowsRendered}
|
||||
overscanRowCount={LIMIT_HEIGHT}
|
||||
|
@ -149,16 +160,14 @@ const MenuDataviewFileList = observer(class MenuDataviewFileList extends React.C
|
|||
const { filter } = data;
|
||||
|
||||
if (filter != this.filter) {
|
||||
this.n = -1;
|
||||
this.offset = 0;
|
||||
this.filter = filter;
|
||||
this.load(true);
|
||||
this.reload();
|
||||
return;
|
||||
};
|
||||
|
||||
this.cache = new CellMeasurerCache({
|
||||
fixedWidth: true,
|
||||
defaultHeight: HEIGHT,
|
||||
defaultHeight: i => this.getRowHeight(items[i]),
|
||||
keyMapper: i => (items[i] || {}).id,
|
||||
});
|
||||
|
||||
|
@ -195,7 +204,20 @@ const MenuDataviewFileList = observer(class MenuDataviewFileList extends React.C
|
|||
const { data } = param;
|
||||
const value = Relation.getArrayValue(data.value);
|
||||
|
||||
return UtilCommon.objectCopy(this.items).filter(it => it && !it._empty_ && !it.isArchived && !it.isDeleted && !value.includes(it.id));
|
||||
let items = UtilCommon.objectCopy(this.items).filter(it => it && !it._empty_ && !it.isArchived && !it.isDeleted && !value.includes(it.id));
|
||||
|
||||
items = items.concat([
|
||||
{ isDiv: true },
|
||||
{ id: 'upload', name: translate('commonUpload') },
|
||||
]);
|
||||
|
||||
return items;
|
||||
};
|
||||
|
||||
reload () {
|
||||
this.n = -1;
|
||||
this.offset = 0;
|
||||
this.load(true);
|
||||
};
|
||||
|
||||
load (clear: boolean, callBack?: (message: any) => void) {
|
||||
|
@ -265,9 +287,7 @@ const MenuDataviewFileList = observer(class MenuDataviewFileList extends React.C
|
|||
};
|
||||
|
||||
onClick (e: any, item: any) {
|
||||
const { param, close, position } = this.props;
|
||||
const { data } = param;
|
||||
const { onChange, maxCount } = data;
|
||||
const { close } = this.props;
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
@ -277,8 +297,27 @@ const MenuDataviewFileList = observer(class MenuDataviewFileList extends React.C
|
|||
return;
|
||||
};
|
||||
|
||||
this.onChange(item.id);
|
||||
};
|
||||
|
||||
onUpload () {
|
||||
Action.openFile([], paths => {
|
||||
C.FileUpload(commonStore.space, '', paths[0], I.FileType.None, {}, (message: any) => {
|
||||
if (!message.error.code) {
|
||||
this.onChange(message.objectId);
|
||||
this.reload();
|
||||
};
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
onChange (id) {
|
||||
const { param, position } = this.props;
|
||||
const { data } = param;
|
||||
const { onChange, maxCount } = data;
|
||||
|
||||
let value = Relation.getArrayValue(data.value);
|
||||
value.push(item.id);
|
||||
value.push(id);
|
||||
value = UtilCommon.arrayUnique(value);
|
||||
|
||||
if (maxCount) {
|
||||
|
@ -292,11 +331,20 @@ const MenuDataviewFileList = observer(class MenuDataviewFileList extends React.C
|
|||
});
|
||||
};
|
||||
|
||||
getRowHeight (item: any) {
|
||||
if (item.isDiv) {
|
||||
return HEIGHT_DIV;
|
||||
};
|
||||
return HEIGHT;
|
||||
};
|
||||
|
||||
resize () {
|
||||
const { getId, position } = this.props;
|
||||
const items = this.getItems();
|
||||
const obj = $(`#${getId()} .content`);
|
||||
const height = Math.max(HEIGHT * 2, Math.min(360, items.length * HEIGHT + 58));
|
||||
const offset = 58;
|
||||
const itemsHeight = items.reduce((res: number, current: any) => { return res + this.getRowHeight(current); }, offset);
|
||||
const height = Math.max(HEIGHT + offset, Math.min(360, itemsHeight));
|
||||
|
||||
obj.css({ height: height });
|
||||
position();
|
||||
|
|
|
@ -49,9 +49,10 @@ const MenuDataviewFileValues = observer(class MenuDataviewFileValues extends Rea
|
|||
);
|
||||
|
||||
const Item = SortableElement((item: any) => {
|
||||
let content = null;
|
||||
const cn = [ 'item' ];
|
||||
|
||||
let content = null;
|
||||
|
||||
switch (item.layout) {
|
||||
default:
|
||||
case I.ObjectLayout.File: {
|
||||
|
@ -70,7 +71,7 @@ const MenuDataviewFileValues = observer(class MenuDataviewFileValues extends Rea
|
|||
return (
|
||||
<div id={'item-' + item.id} className={cn.join(' ')}>
|
||||
<Handle />
|
||||
<div className="clickable" onClick={e => UtilObject.openPopup(item)}>
|
||||
<div className="clickable" onClick={() => UtilObject.openPopup(item)} onContextMenu={e => this.onMore(e, item)}>
|
||||
{content}
|
||||
</div>
|
||||
<div className="buttons">
|
||||
|
@ -95,11 +96,6 @@ const MenuDataviewFileValues = observer(class MenuDataviewFileValues extends Rea
|
|||
ref={node => this.node = node}
|
||||
className="items"
|
||||
>
|
||||
<div className="section">
|
||||
<MenuItemVertical id="add" icon="plus" name={translate('commonAdd')} onClick={this.onAdd} />
|
||||
<MenuItemVertical id="upload" icon="upload" name={translate('commonUpload')} onClick={this.onUpload} />
|
||||
</div>
|
||||
|
||||
{value.length ? (
|
||||
<div className="section">
|
||||
<List
|
||||
|
@ -116,6 +112,10 @@ const MenuDataviewFileValues = observer(class MenuDataviewFileValues extends Rea
|
|||
/>
|
||||
</div>
|
||||
) : ''}
|
||||
|
||||
<div className="section">
|
||||
<MenuItemVertical id="add" icon="plus" name={translate('commonAdd')} onClick={this.onAdd} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -172,6 +172,13 @@ const MenuDataviewFileValues = observer(class MenuDataviewFileValues extends Rea
|
|||
onChange: (value: string[], callBack?: () => void) => {
|
||||
this.save(value);
|
||||
|
||||
if (callBack) {
|
||||
callBack();
|
||||
};
|
||||
},
|
||||
onUpload: (id: string, callBack?: () => void) => {
|
||||
this.add(id);
|
||||
|
||||
if (callBack) {
|
||||
callBack();
|
||||
};
|
||||
|
@ -217,7 +224,7 @@ const MenuDataviewFileValues = observer(class MenuDataviewFileValues extends Rea
|
|||
|
||||
element.addClass('active');
|
||||
menuStore.open('select', {
|
||||
element: element.find('.icon.more'),
|
||||
element,
|
||||
horizontal: I.MenuDirection.Center,
|
||||
classNameWrap: classNameWrap,
|
||||
onClose: () => {
|
||||
|
@ -226,12 +233,18 @@ const MenuDataviewFileValues = observer(class MenuDataviewFileValues extends Rea
|
|||
data: {
|
||||
value: '',
|
||||
options: [
|
||||
{ id: 'open', icon: 'expand', name: translate('commonOpen') },
|
||||
{ id: 'download', icon: 'download', name: translate('commonDownload') },
|
||||
{ isDiv: true },
|
||||
{ id: 'remove', icon: 'remove', name: translate('commonDelete') },
|
||||
],
|
||||
onSelect: (event: any, el: any) => {
|
||||
|
||||
switch (el.id) {
|
||||
case 'open': {
|
||||
UtilObject.openPopup(item);
|
||||
break;
|
||||
};
|
||||
case 'download': {
|
||||
let url = '';
|
||||
switch (item.layout) {
|
||||
|
|
|
@ -248,7 +248,7 @@ const Menu = observer(class Menu extends React.Component<I.Menu, State> {
|
|||
};
|
||||
|
||||
if (passThrough) {
|
||||
cd.push('through');
|
||||
cd.push('passThrough');
|
||||
};
|
||||
|
||||
const Tab = (item: any) => (
|
||||
|
|
|
@ -596,7 +596,7 @@ class MenuQuickCapture extends React.Component<I.Menu, State> {
|
|||
|
||||
const object = message.details;
|
||||
|
||||
C.BlockPaste (object.id, '', { from: 0, to: 0 }, [], false, { html, text }, () => {
|
||||
C.BlockPaste (object.id, '', { from: 0, to: 0 }, [], false, { html, text }, '', () => {
|
||||
UtilObject.openAuto(object);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -42,7 +42,7 @@ class PageMainImport extends React.Component<I.PageComponent, State> {
|
|||
componentDidMount (): void {
|
||||
const search = this.getSearch();
|
||||
|
||||
C.DownloadManifest(search.source, (message: any) => {
|
||||
C.GalleryDownloadManifest(search.source, (message: any) => {
|
||||
if (message.error.code) {
|
||||
this.setState({ error: message.error.description });
|
||||
} else {
|
||||
|
|
202
src/ts/component/popup/page/usecase/item.tsx
Normal file
202
src/ts/component/popup/page/usecase/item.tsx
Normal file
|
@ -0,0 +1,202 @@
|
|||
import * as React from 'react';
|
||||
import $ from 'jquery';
|
||||
import { Title, Label, Button, Tag, Icon, Loader, Error } from 'Component';
|
||||
import { I, C, UtilCommon, UtilFile, UtilDate, translate, Renderer, analytics } from 'Lib';
|
||||
import { menuStore, dbStore } from 'Store';
|
||||
import { Swiper, SwiperSlide } from 'swiper/react';
|
||||
import Constant from 'json/constant.json';
|
||||
|
||||
interface State {
|
||||
isLoading: boolean;
|
||||
error: string;
|
||||
};
|
||||
|
||||
class PopupUsecasePageItem extends React.Component<I.PopupUsecase, State> {
|
||||
|
||||
node = null;
|
||||
swiper = null;
|
||||
refButton = null;
|
||||
state = {
|
||||
isLoading: false,
|
||||
error: '',
|
||||
};
|
||||
|
||||
constructor (props: I.PopupUsecase) {
|
||||
super(props);
|
||||
|
||||
this.onMenu = this.onMenu.bind(this);
|
||||
this.onAuthor = this.onAuthor.bind(this);
|
||||
this.onSwiper = this.onSwiper.bind(this);
|
||||
};
|
||||
|
||||
render () {
|
||||
const { isLoading, error } = this.state;
|
||||
const object = this.getObject();
|
||||
const author = this.getAuthor();
|
||||
const screenshots = object.screenshots || [];
|
||||
const categories = (object.categories || []).slice(0, 10);
|
||||
|
||||
return (
|
||||
<div ref={ref => this.node = ref}>
|
||||
{isLoading ? <Loader id="loader" /> : ''}
|
||||
|
||||
<div className="titleWrap">
|
||||
<div className="side left">
|
||||
<Title text={object.title} />
|
||||
<Label text={UtilCommon.sprintf(translate('popupUsecaseAuthor'), author)} onClick={this.onAuthor} />
|
||||
</div>
|
||||
<div className="side right">
|
||||
<Button ref={ref => this.refButton = ref} id="button-install" text={translate('popupUsecaseInstall')} arrow={true} onClick={this.onMenu} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Error text={error} />
|
||||
|
||||
<div className="screenWrap">
|
||||
<Swiper
|
||||
spaceBetween={20}
|
||||
slidesPerView={1}
|
||||
onSlideChange={() => this.checkArrows()}
|
||||
onSwiper={swiper => this.onSwiper(swiper)}
|
||||
>
|
||||
{screenshots.map((url: string, i: number) => (
|
||||
<SwiperSlide key={i}>
|
||||
<img className="screen" src={url} />
|
||||
</SwiperSlide>
|
||||
))}
|
||||
</Swiper>
|
||||
|
||||
<Icon id="arrowLeft" className="arrow left" onClick={() => this.onArrow(-1)} />
|
||||
<Icon id="arrowRight" className="arrow right" onClick={() => this.onArrow(1)} />
|
||||
</div>
|
||||
|
||||
<div className="footerWrap">
|
||||
<div className="side left">
|
||||
<Label text={object.description} />
|
||||
</div>
|
||||
<div className="side right">
|
||||
<div className="tags">
|
||||
{categories.map((name: string, i: number) => (
|
||||
<Tag key={i} text={name} />
|
||||
))}
|
||||
</div>
|
||||
<Label text={UtilCommon.sprintf(translate('popupUsecaseUpdated'), UtilDate.date(UtilDate.dateFormat(I.DateFormat.MonthAbbrBeforeDay), UtilDate.now()))} />
|
||||
<Label text={UtilFile.size(object.size)} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
componentDidMount(): void {
|
||||
const object = this.getObject();
|
||||
|
||||
window.setTimeout(() => this.checkArrows(), 10);
|
||||
analytics.event('ScreenGalleryInstall', { name: object.name });
|
||||
};
|
||||
|
||||
onSwiper (swiper) {
|
||||
this.swiper = swiper;
|
||||
};
|
||||
|
||||
onArrow (dir: number) {
|
||||
dir < 0 ? this.swiper.slidePrev() : this.swiper.slideNext();
|
||||
};
|
||||
|
||||
checkArrows () {
|
||||
const node = $(this.node);
|
||||
const arrowLeft = node.find('#arrowLeft');
|
||||
const arrowRight = node.find('#arrowRight');
|
||||
const idx = this.swiper.activeIndex;
|
||||
const length = (this.swiper.slides || []).length;
|
||||
|
||||
!idx ? arrowLeft.addClass('hide') : arrowLeft.removeClass('hide');
|
||||
idx >= length - 1 ? arrowRight.addClass('hide') : arrowRight.removeClass('hide');
|
||||
};
|
||||
|
||||
onMenu () {
|
||||
const { getId, close } = this.props;
|
||||
const object = this.getObject();
|
||||
|
||||
const cb = (spaceId: string, isNew: boolean) => {
|
||||
C.ObjectImportExperience(spaceId, object.downloadLink, object.title, isNew, (message: any) => {
|
||||
if (!message.error.code) {
|
||||
analytics.event('GalleryInstall', { name: object.name });
|
||||
};
|
||||
});
|
||||
close();
|
||||
};
|
||||
|
||||
menuStore.open('select', {
|
||||
element: `#${getId()} #button-install`,
|
||||
offsetY: 2,
|
||||
noFlipX: true,
|
||||
className: 'spaceSelect',
|
||||
data: {
|
||||
options: this.getSpaceOptions(),
|
||||
noVirtualisation: true,
|
||||
noScroll: true,
|
||||
onSelect: (e: any, item: any) => {
|
||||
const isNew = item.id == 'add';
|
||||
|
||||
this.setState({ isLoading: true });
|
||||
analytics.event('ClickGalleryInstallSpace', { type: isNew ? 'New' : 'Existing' });
|
||||
|
||||
if (isNew) {
|
||||
C.WorkspaceCreate({ name: object.title, iconOption: UtilCommon.rand(1, Constant.iconCnt) }, I.Usecase.None, (message: any) => {
|
||||
if (!message.error.code) {
|
||||
cb(message.objectId, true);
|
||||
} else {
|
||||
this.setState({ isLoading: false, error: message.error.description });
|
||||
};
|
||||
});
|
||||
} else {
|
||||
cb(item.targetSpaceId, false);
|
||||
};
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
analytics.event('ClickGalleryInstall', { name: object.name });
|
||||
};
|
||||
|
||||
getSpaceOptions (): any[] {
|
||||
const list: any[] = dbStore.getSpaces().map(it => ({ ...it, iconSize: 48, object: it }));
|
||||
if (list.length < Constant.limit.space) {
|
||||
list.unshift({ id: 'add', icon: 'add', name: translate('popupUsecaseSpaceCreate') });
|
||||
};
|
||||
list.unshift({ name: translate('popupUsecaseMenuLabel'), isSection: true });
|
||||
return list;
|
||||
};
|
||||
|
||||
onAuthor () {
|
||||
const object = this.getObject();
|
||||
|
||||
if (object.author) {
|
||||
Renderer.send('urlOpen', object.author);
|
||||
};
|
||||
};
|
||||
|
||||
getObject (): any {
|
||||
const { param } = this.props;
|
||||
const { data } = param;
|
||||
|
||||
return data.object || {};
|
||||
};
|
||||
|
||||
getAuthor (): string {
|
||||
const object = this.getObject();
|
||||
|
||||
if (!object.author) {
|
||||
return '';
|
||||
};
|
||||
|
||||
let a: any = {};
|
||||
try { a = new URL(object.author); } catch (e) {};
|
||||
|
||||
return String(a.pathname || '').replace(/^\//, '');
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
export default PopupUsecasePageItem;
|
103
src/ts/component/popup/page/usecase/list.tsx
Normal file
103
src/ts/component/popup/page/usecase/list.tsx
Normal file
|
@ -0,0 +1,103 @@
|
|||
import * as React from 'react';
|
||||
import { I, C } from 'Lib';
|
||||
import { AutoSizer, CellMeasurer, CellMeasurerCache, List, WindowScroller } from 'react-virtualized';
|
||||
|
||||
const HEIGHT = 450;
|
||||
|
||||
class PopupUsecasePageList extends React.Component<I.PopupUsecase> {
|
||||
|
||||
node = null;
|
||||
refList = null;
|
||||
list: any = [];
|
||||
categories: any = [];
|
||||
cache: any = {};
|
||||
|
||||
constructor (props: I.PopupUsecase) {
|
||||
super(props);
|
||||
};
|
||||
|
||||
render () {
|
||||
const Item = (item: any) => {
|
||||
const screenshot = item.screenshots.length ? item.screenshots[0] : '';
|
||||
|
||||
return (
|
||||
<div className="item" onClick={e => this.onClick(e, item)}>
|
||||
<div className="picture" style={{ backgroundImage: `url("${screenshot}")` }}></div>
|
||||
<div className="name">{item.title}</div>
|
||||
<div className="descr">{item.description}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const rowRenderer = (param: any) => {
|
||||
const item: any = this.list[param.index];
|
||||
return (
|
||||
<CellMeasurer
|
||||
key={param.key}
|
||||
parent={param.parent}
|
||||
cache={this.cache}
|
||||
columnIndex={0}
|
||||
rowIndex={param.index}
|
||||
hasFixedWidth={() => {}}
|
||||
>
|
||||
<Item key={item.id} {...item} index={param.index} style={param.style} />
|
||||
</CellMeasurer>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div ref={ref => this.node = ref}>
|
||||
<div className="items">
|
||||
{this.list.map((item: any) => (
|
||||
<Item key={item.id} {...item} />
|
||||
))}
|
||||
<WindowScroller scrollElement={$('#popupUsecase-innerWrap').get(0)}>
|
||||
{({ height, isScrolling, registerChild, scrollTop }) => (
|
||||
<AutoSizer disableHeight={true} className="scrollArea">
|
||||
{({ width }) => (
|
||||
<List
|
||||
ref={ref => this.refList = ref}
|
||||
autoHeight={true}
|
||||
height={Number(height) || 0}
|
||||
width={Number(width) || 0}
|
||||
deferredMeasurmentCache={this.cache}
|
||||
rowCount={length}
|
||||
rowHeight={HEIGHT}
|
||||
rowRenderer={rowRenderer}
|
||||
isScrolling={isScrolling}
|
||||
scrollTop={scrollTop}
|
||||
/>
|
||||
)}
|
||||
</AutoSizer>
|
||||
)}
|
||||
</WindowScroller>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
componentDidMount (): void {
|
||||
C.GalleryDownloadIndex((message: any) => {
|
||||
this.categories = message.categories;
|
||||
this.list = message.list;
|
||||
this.forceUpdate();
|
||||
});
|
||||
};
|
||||
|
||||
componentDidUpdate (): void {
|
||||
this.cache = new CellMeasurerCache({
|
||||
fixedWidth: true,
|
||||
defaultHeight: HEIGHT,
|
||||
keyMapper: i => this.list[i].id,
|
||||
});
|
||||
|
||||
this.props.position();
|
||||
};
|
||||
|
||||
onClick (e: any, item: any) {
|
||||
this.props.onPage('item', { object: item });
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
export default PopupUsecasePageList;
|
|
@ -1,202 +1,66 @@
|
|||
import * as React from 'react';
|
||||
import $ from 'jquery';
|
||||
import { Title, Label, Button, Tag, Icon, Loader, Error } from 'Component';
|
||||
import { I, C, UtilCommon, UtilFile, UtilDate, translate, Renderer, analytics } from 'Lib';
|
||||
import { menuStore, dbStore } from 'Store';
|
||||
import { Swiper, SwiperSlide } from 'swiper/react';
|
||||
import Constant from 'json/constant.json';
|
||||
import { observer } from 'mobx-react';
|
||||
import { I, UtilCommon } from 'Lib';
|
||||
|
||||
interface State {
|
||||
isLoading: boolean;
|
||||
error: string;
|
||||
import PopupUsecasePageList from './page/usecase/list';
|
||||
import PopupUsecasePageItem from './page/usecase/item';
|
||||
|
||||
const Components: any = {
|
||||
list: PopupUsecasePageList,
|
||||
item: PopupUsecasePageItem,
|
||||
};
|
||||
|
||||
class PopupUsecase extends React.Component<I.Popup, State> {
|
||||
const PopupUsecase = observer(class PopupUsecase extends React.Component<I.PopupUsecase> {
|
||||
|
||||
node = null;
|
||||
swiper = null;
|
||||
refButton = null;
|
||||
state = {
|
||||
isLoading: false,
|
||||
error: '',
|
||||
};
|
||||
ref = null;
|
||||
|
||||
constructor (props: I.Popup) {
|
||||
constructor (props: I.PopupUsecase) {
|
||||
super(props);
|
||||
|
||||
this.onMenu = this.onMenu.bind(this);
|
||||
this.onAuthor = this.onAuthor.bind(this);
|
||||
this.onSwiper = this.onSwiper.bind(this);
|
||||
this.onPage = this.onPage.bind(this);
|
||||
};
|
||||
|
||||
render () {
|
||||
const { isLoading, error } = this.state;
|
||||
const object = this.getObject();
|
||||
const author = this.getAuthor();
|
||||
const screenshots = object.screenshots || [];
|
||||
const categories = (object.categories || []).slice(0, 10);
|
||||
const { param } = this.props;
|
||||
const { data } = param;
|
||||
const page = data.page || 'list';
|
||||
|
||||
let content = null;
|
||||
if (Components[page]) {
|
||||
const Component = Components[page];
|
||||
content = (
|
||||
<Component
|
||||
ref={ref => this.ref = ref}
|
||||
{...this.props}
|
||||
onPage={this.onPage}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div ref={ref => this.node = ref}>
|
||||
{isLoading ? <Loader id="loader" /> : ''}
|
||||
|
||||
<div className="titleWrap">
|
||||
<div className="side left">
|
||||
<Title text={object.title} />
|
||||
<Label text={UtilCommon.sprintf(translate('popupUsecaseAuthor'), author)} onClick={this.onAuthor} />
|
||||
</div>
|
||||
<div className="side right">
|
||||
<Button ref={ref => this.refButton = ref} id="button-install" text={translate('popupUsecaseInstall')} arrow={true} onClick={this.onMenu} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Error text={error} />
|
||||
|
||||
<div className="screenWrap">
|
||||
<Swiper
|
||||
spaceBetween={20}
|
||||
slidesPerView={1}
|
||||
onSlideChange={() => this.checkArrows()}
|
||||
onSwiper={swiper => this.onSwiper(swiper)}
|
||||
>
|
||||
{screenshots.map((url: string, i: number) => (
|
||||
<SwiperSlide key={i}>
|
||||
<img className="screen" src={url} />
|
||||
</SwiperSlide>
|
||||
))}
|
||||
</Swiper>
|
||||
|
||||
<Icon id="arrowLeft" className="arrow left" onClick={() => this.onArrow(-1)} />
|
||||
<Icon id="arrowRight" className="arrow right" onClick={() => this.onArrow(1)} />
|
||||
</div>
|
||||
|
||||
<div className="footerWrap">
|
||||
<div className="side left">
|
||||
<Label text={object.description} />
|
||||
</div>
|
||||
<div className="side right">
|
||||
<div className="tags">
|
||||
{categories.map((name: string, i: number) => (
|
||||
<Tag key={i} text={name} />
|
||||
))}
|
||||
</div>
|
||||
<Label text={UtilCommon.sprintf(translate('popupUsecaseUpdated'), UtilDate.date(UtilDate.dateFormat(I.DateFormat.MonthAbbrBeforeDay), UtilDate.now()))} />
|
||||
<Label text={UtilFile.size(object.size)} />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
ref={ref => this.node = ref}
|
||||
className={[ 'page', UtilCommon.toCamelCase(`page-${page}`) ].join(' ')}
|
||||
>
|
||||
{content}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
componentDidMount(): void {
|
||||
const object = this.getObject();
|
||||
|
||||
window.setTimeout(() => this.checkArrows(), 10);
|
||||
analytics.event('ScreenGalleryInstall', { name: object.name });
|
||||
};
|
||||
|
||||
onSwiper (swiper) {
|
||||
this.swiper = swiper;
|
||||
};
|
||||
|
||||
onArrow (dir: number) {
|
||||
dir < 0 ? this.swiper.slidePrev() : this.swiper.slideNext();
|
||||
};
|
||||
|
||||
checkArrows () {
|
||||
const node = $(this.node);
|
||||
const arrowLeft = node.find('#arrowLeft');
|
||||
const arrowRight = node.find('#arrowRight');
|
||||
const idx = this.swiper.activeIndex;
|
||||
const length = (this.swiper.slides || []).length;
|
||||
|
||||
!idx ? arrowLeft.addClass('hide') : arrowLeft.removeClass('hide');
|
||||
idx >= length - 1 ? arrowRight.addClass('hide') : arrowRight.removeClass('hide');
|
||||
};
|
||||
|
||||
onMenu () {
|
||||
const { getId, close } = this.props;
|
||||
const object = this.getObject();
|
||||
|
||||
const cb = (spaceId: string, isNew: boolean) => {
|
||||
C.ObjectImportExperience(spaceId, object.downloadLink, object.title, isNew, (message: any) => {
|
||||
if (!message.error.code) {
|
||||
analytics.event('GalleryInstall', { name: object.name });
|
||||
};
|
||||
});
|
||||
close();
|
||||
};
|
||||
|
||||
menuStore.open('select', {
|
||||
element: `#${getId()} #button-install`,
|
||||
offsetY: 2,
|
||||
noFlipX: true,
|
||||
className: 'spaceSelect',
|
||||
data: {
|
||||
options: this.getSpaceOptions(),
|
||||
noVirtualisation: true,
|
||||
noScroll: true,
|
||||
onSelect: (e: any, item: any) => {
|
||||
const isNew = item.id == 'add';
|
||||
|
||||
this.setState({ isLoading: true });
|
||||
analytics.event('ClickGalleryInstallSpace', { type: isNew ? 'New' : 'Existing' });
|
||||
|
||||
if (isNew) {
|
||||
C.WorkspaceCreate({ name: object.title, iconOption: UtilCommon.rand(1, Constant.iconCnt) }, I.Usecase.None, (message: any) => {
|
||||
if (!message.error.code) {
|
||||
cb(message.objectId, true);
|
||||
} else {
|
||||
this.setState({ isLoading: false, error: message.error.description });
|
||||
};
|
||||
});
|
||||
} else {
|
||||
cb(item.targetSpaceId, false);
|
||||
};
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
analytics.event('ClickGalleryInstall', { name: object.name });
|
||||
};
|
||||
|
||||
getSpaceOptions (): any[] {
|
||||
const list: any[] = dbStore.getSpaces().map(it => ({ ...it, iconSize: 48, object: it }));
|
||||
if (list.length < Constant.limit.space) {
|
||||
list.unshift({ id: 'add', icon: 'add', name: translate('popupUsecaseSpaceCreate') });
|
||||
};
|
||||
list.unshift({ name: translate('popupUsecaseMenuLabel'), isSection: true });
|
||||
return list;
|
||||
};
|
||||
|
||||
onAuthor () {
|
||||
const object = this.getObject();
|
||||
|
||||
if (object.author) {
|
||||
Renderer.send('urlOpen', object.author);
|
||||
};
|
||||
};
|
||||
|
||||
getObject (): any {
|
||||
const { param } = this.props;
|
||||
const { data } = param;
|
||||
const { page } = data;
|
||||
|
||||
return data.object || {};
|
||||
this.onPage(page || 'list');
|
||||
};
|
||||
|
||||
getAuthor (): string {
|
||||
const object = this.getObject();
|
||||
|
||||
if (!object.author) {
|
||||
return '';
|
||||
};
|
||||
|
||||
let a: any = {};
|
||||
try { a = new URL(object.author); } catch (e) {};
|
||||
|
||||
return String(a.pathname || '').replace(/^\//, '');
|
||||
onPage (page: string, data?: any): void {
|
||||
data = data || {};
|
||||
this.props.param.data = Object.assign(this.props.param.data, { ...data, page });
|
||||
};
|
||||
|
||||
};
|
||||
});
|
||||
|
||||
export default PopupUsecase;
|
|
@ -137,7 +137,6 @@ const SelectionProvider = observer(class SelectionProvider extends React.Compone
|
|||
this.setIsSelecting(true);
|
||||
|
||||
keyboard.disablePreview(true);
|
||||
UtilCommon.clearSelection();
|
||||
|
||||
if (isPopup && container.length) {
|
||||
this.containerOffset = container.offset();
|
||||
|
@ -199,6 +198,7 @@ const SelectionProvider = observer(class SelectionProvider extends React.Compone
|
|||
};
|
||||
|
||||
const isPopup = keyboard.isPopup();
|
||||
|
||||
this.top = UtilCommon.getScrollContainer(isPopup).scrollTop();
|
||||
this.checkNodes(e);
|
||||
this.drawRect(e.pageX, e.pageY);
|
||||
|
|
|
@ -35,7 +35,7 @@ import {
|
|||
} from './common';
|
||||
import { ThreadStatus, ThreadSummary, ThreadDevice, ThreadAccount, ThreadCafe, FilesStatus } from './thread';
|
||||
import { Progress, ProgressType, ProgressState } from './progress';
|
||||
import { PopupParam, Popup, PopupSettings } from './popup';
|
||||
import { PopupParam, Popup, PopupSettings, PopupUsecase } from './popup';
|
||||
import { Preview, PreviewLink, PreviewType, PreviewSize } from './preview';
|
||||
import { MenuTab, MenuType, MenuDirection, MenuParam, Menu, MenuItem } from './menu';
|
||||
import { ObjectLayout, ObjectFlag, RelationType, RelationScope, ObjectOrigin } from './object';
|
||||
|
@ -134,6 +134,7 @@ export {
|
|||
PopupParam,
|
||||
Popup,
|
||||
PopupSettings,
|
||||
PopupUsecase,
|
||||
|
||||
Preview,
|
||||
PreviewLink,
|
||||
|
|
|
@ -27,3 +27,7 @@ export interface PopupSettings extends Popup {
|
|||
onExport: (format: I.ExportType, param: any) => void;
|
||||
onSpaceTypeTooltip: (e: any) => void;
|
||||
};
|
||||
|
||||
export interface PopupUsecase extends Popup {
|
||||
onPage(page: string, data: any): void;
|
||||
};
|
|
@ -31,12 +31,20 @@ export const LinkPreview = (url: string, callBack?: (message: any) => void) => {
|
|||
dispatcher.request(LinkPreview.name, request, callBack);
|
||||
};
|
||||
|
||||
export const DownloadManifest = (url: string, callBack?: (message: any) => void) => {
|
||||
const request = new Rpc.DownloadManifest.Request();
|
||||
// ---------------------- GALLERY ---------------------- //
|
||||
|
||||
export const GalleryDownloadIndex = (callBack?: (message: any) => void) => {
|
||||
const request = new Commands.Empty();
|
||||
|
||||
dispatcher.request(GalleryDownloadIndex.name, request, callBack);
|
||||
};
|
||||
|
||||
export const GalleryDownloadManifest = (url: string, callBack?: (message: any) => void) => {
|
||||
const request = new Rpc.Gallery.DownloadManifest.Request();
|
||||
|
||||
request.setUrl(url);
|
||||
|
||||
dispatcher.request(DownloadManifest.name, request, callBack);
|
||||
dispatcher.request(GalleryDownloadManifest.name, request, callBack);
|
||||
};
|
||||
|
||||
// ---------------------- APP ---------------------- //
|
||||
|
@ -379,10 +387,11 @@ export const BlockWidgetSetViewId = (contextId: string, blockId: string, viewId:
|
|||
dispatcher.request(BlockWidgetSetViewId.name, request, callBack);
|
||||
};
|
||||
|
||||
export const BlockPreview = (html: string, callBack?: (message: any) => void) => {
|
||||
export const BlockPreview = (html: string, url: string, callBack?: (message: any) => void) => {
|
||||
const request = new Rpc.Block.Preview.Request();
|
||||
|
||||
request.setHtml(html);
|
||||
request.setUrl(url);
|
||||
|
||||
dispatcher.request(BlockPreview.name, request, callBack);
|
||||
};
|
||||
|
@ -517,7 +526,7 @@ export const BlockCut = (contextId: string, blocks: I.Block[], range: I.TextRang
|
|||
dispatcher.request(BlockCut.name, request, callBack);
|
||||
};
|
||||
|
||||
export const BlockPaste = (contextId: string, focusedId: string, range: I.TextRange, blockIds: string[], isPartOfBlock: boolean, data: any, callBack?: (message: any) => void) => {
|
||||
export const BlockPaste = (contextId: string, focusedId: string, range: I.TextRange, blockIds: string[], isPartOfBlock: boolean, data: any, url: string, callBack?: (message: any) => void) => {
|
||||
data = UtilCommon.objectCopy(data);
|
||||
|
||||
const request = new Rpc.Block.Paste.Request();
|
||||
|
@ -531,6 +540,7 @@ export const BlockPaste = (contextId: string, focusedId: string, range: I.TextRa
|
|||
request.setHtmlslot(data.html);
|
||||
request.setAnyslotList((data.anytype || []).map(Mapper.To.Block));
|
||||
request.setFileslotList((data.files || []).map(Mapper.To.PasteFile));
|
||||
request.setUrl(url);
|
||||
|
||||
dispatcher.request(BlockPaste.name, request, callBack);
|
||||
};
|
||||
|
|
|
@ -67,9 +67,12 @@ class Dispatcher {
|
|||
this.stream.on('end', () => {
|
||||
console.error('[Dispatcher.stream] end, restarting');
|
||||
|
||||
let t = 1000;
|
||||
let t = 3;
|
||||
if (this.reconnects == 20) {
|
||||
t = 5000;
|
||||
t = 5;
|
||||
};
|
||||
if (this.reconnects == 40) {
|
||||
t = 60;
|
||||
this.reconnects = 0;
|
||||
};
|
||||
|
||||
|
@ -77,7 +80,7 @@ class Dispatcher {
|
|||
this.timeoutStream = window.setTimeout(() => {
|
||||
this.listenEvents();
|
||||
this.reconnects++;
|
||||
}, t);
|
||||
}, t * 1000);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -538,6 +538,22 @@ export const Mapper = {
|
|||
};
|
||||
},
|
||||
|
||||
Manifest: (obj: Model.ManifestInfo) => {
|
||||
return {
|
||||
id: obj.getId(),
|
||||
schema: obj.getSchema(),
|
||||
name: obj.getName(),
|
||||
author: obj.getAuthor(),
|
||||
license: obj.getLicense(),
|
||||
title: obj.getTitle(),
|
||||
description: obj.getDescription(),
|
||||
downloadLink: obj.getDownloadlink(),
|
||||
size: obj.getFilesize(),
|
||||
screenshots: obj.getScreenshotsList() || [],
|
||||
categories: obj.getCategoriesList() || [],
|
||||
};
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
|
|
@ -423,23 +423,21 @@ export const UnsplashDownload = (response: Rpc.Unsplash.Download.Response) => {
|
|||
};
|
||||
};
|
||||
|
||||
export const DownloadManifest = (response: Rpc.DownloadManifest.Response) => {
|
||||
const info = response.getInfo();
|
||||
|
||||
export const GalleryDownloadIndex = (response: Rpc.Gallery.DownloadIndex.Response) => {
|
||||
return {
|
||||
info: {
|
||||
id: info.getId(),
|
||||
schema: info.getSchema(),
|
||||
name: info.getName(),
|
||||
author: info.getAuthor(),
|
||||
license: info.getLicense(),
|
||||
title: info.getTitle(),
|
||||
description: info.getDescription(),
|
||||
downloadLink: info.getDownloadlink(),
|
||||
size: info.getFilesize(),
|
||||
screenshots: info.getScreenshotsList() || [],
|
||||
categories: info.getCategoriesList() || [],
|
||||
},
|
||||
categories: (response.getCategoriesList() || []).map((it: Rpc.Gallery.DownloadIndex.Response.Category) => {
|
||||
return {
|
||||
name: it.getName(),
|
||||
list: it.getExperiencesList() || [],
|
||||
};
|
||||
}),
|
||||
list: (response.getExperiencesList() || []).map(Mapper.From.Manifest),
|
||||
};
|
||||
};
|
||||
|
||||
export const GalleryDownloadManifest = (response: Rpc.Gallery.DownloadManifest.Response) => {
|
||||
return {
|
||||
info: Mapper.From.Manifest(response.getInfo()),
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -427,10 +427,6 @@ class Keyboard {
|
|||
if ((route.page == 'main') && !account) {
|
||||
return false;
|
||||
};
|
||||
|
||||
if ((route.page == 'main') && (route.action == 'usecase')) {
|
||||
return false;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ class ExtensionStore {
|
|||
public challengeId = '';
|
||||
public serverPort = '';
|
||||
public gatewayPort = '';
|
||||
public tabUrlValue = '';
|
||||
public htmlValue = '';
|
||||
|
||||
constructor() {
|
||||
|
@ -19,10 +20,18 @@ class ExtensionStore {
|
|||
return String(this.htmlValue || '');
|
||||
};
|
||||
|
||||
get tabUrl (): string {
|
||||
return String(this.tabUrlValue || '');
|
||||
};
|
||||
|
||||
setHtml (v: string) {
|
||||
this.htmlValue = String(v || '');
|
||||
};
|
||||
|
||||
setTabUrl (v: string) {
|
||||
this.tabUrlValue = String(v || '');
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
export const extensionStore: ExtensionStore = new ExtensionStore();
|
|
@ -50,6 +50,14 @@ class PopupStore {
|
|||
|
||||
param.data = param.data || {};
|
||||
|
||||
// Auto-confirm in extension
|
||||
if (window.isExtension && (id == 'confirm')) {
|
||||
if (param.data.onConfirm) {
|
||||
param.data.onConfirm();
|
||||
};
|
||||
return;
|
||||
};
|
||||
|
||||
if (!param.preventMenuClose) {
|
||||
menuStore.closeAll();
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue