mirror of
https://github.com/divkit/divkit.git
synced 2026-05-07 20:02:32 +00:00
DivKitPro editor
This commit is contained in:
@@ -14968,6 +14968,9 @@
|
|||||||
"site/client/src/assets/closeWhite.svg":"divkit/public/site/client/src/assets/closeWhite.svg",
|
"site/client/src/assets/closeWhite.svg":"divkit/public/site/client/src/assets/closeWhite.svg",
|
||||||
"site/client/src/assets/copy.svg":"divkit/public/site/client/src/assets/copy.svg",
|
"site/client/src/assets/copy.svg":"divkit/public/site/client/src/assets/copy.svg",
|
||||||
"site/client/src/assets/copyOk.svg":"divkit/public/site/client/src/assets/copyOk.svg",
|
"site/client/src/assets/copyOk.svg":"divkit/public/site/client/src/assets/copyOk.svg",
|
||||||
|
"site/client/src/assets/divkitpro/components.svg":"divkit/public/site/client/src/assets/divkitpro/components.svg",
|
||||||
|
"site/client/src/assets/divkitpro/palette.svg":"divkit/public/site/client/src/assets/divkitpro/palette.svg",
|
||||||
|
"site/client/src/assets/divkitpro/sources.svg":"divkit/public/site/client/src/assets/divkitpro/sources.svg",
|
||||||
"site/client/src/assets/dot.svg":"divkit/public/site/client/src/assets/dot.svg",
|
"site/client/src/assets/dot.svg":"divkit/public/site/client/src/assets/dot.svg",
|
||||||
"site/client/src/assets/dropdown.svg":"divkit/public/site/client/src/assets/dropdown.svg",
|
"site/client/src/assets/dropdown.svg":"divkit/public/site/client/src/assets/dropdown.svg",
|
||||||
"site/client/src/assets/errors.svg":"divkit/public/site/client/src/assets/errors.svg",
|
"site/client/src/assets/errors.svg":"divkit/public/site/client/src/assets/errors.svg",
|
||||||
@@ -14981,6 +14984,7 @@
|
|||||||
"site/client/src/components/App.svelte":"divkit/public/site/client/src/components/App.svelte",
|
"site/client/src/components/App.svelte":"divkit/public/site/client/src/components/App.svelte",
|
||||||
"site/client/src/components/Button.svelte":"divkit/public/site/client/src/components/Button.svelte",
|
"site/client/src/components/Button.svelte":"divkit/public/site/client/src/components/Button.svelte",
|
||||||
"site/client/src/components/CopyButton.svelte":"divkit/public/site/client/src/components/CopyButton.svelte",
|
"site/client/src/components/CopyButton.svelte":"divkit/public/site/client/src/components/CopyButton.svelte",
|
||||||
|
"site/client/src/components/Design.svelte":"divkit/public/site/client/src/components/Design.svelte",
|
||||||
"site/client/src/components/Editor.svelte":"divkit/public/site/client/src/components/Editor.svelte",
|
"site/client/src/components/Editor.svelte":"divkit/public/site/client/src/components/Editor.svelte",
|
||||||
"site/client/src/components/ErrorPage.svelte":"divkit/public/site/client/src/components/ErrorPage.svelte",
|
"site/client/src/components/ErrorPage.svelte":"divkit/public/site/client/src/components/ErrorPage.svelte",
|
||||||
"site/client/src/components/ErrorView.svelte":"divkit/public/site/client/src/components/ErrorView.svelte",
|
"site/client/src/components/ErrorView.svelte":"divkit/public/site/client/src/components/ErrorView.svelte",
|
||||||
@@ -15001,6 +15005,7 @@
|
|||||||
"site/client/src/components/StructureBox.svelte":"divkit/public/site/client/src/components/StructureBox.svelte",
|
"site/client/src/components/StructureBox.svelte":"divkit/public/site/client/src/components/StructureBox.svelte",
|
||||||
"site/client/src/components/StructureCurrent.svelte":"divkit/public/site/client/src/components/StructureCurrent.svelte",
|
"site/client/src/components/StructureCurrent.svelte":"divkit/public/site/client/src/components/StructureCurrent.svelte",
|
||||||
"site/client/src/components/StructureTemplates.svelte":"divkit/public/site/client/src/components/StructureTemplates.svelte",
|
"site/client/src/components/StructureTemplates.svelte":"divkit/public/site/client/src/components/StructureTemplates.svelte",
|
||||||
|
"site/client/src/components/ToolbarItem.svelte":"divkit/public/site/client/src/components/ToolbarItem.svelte",
|
||||||
"site/client/src/components/Tree.svelte":"divkit/public/site/client/src/components/Tree.svelte",
|
"site/client/src/components/Tree.svelte":"divkit/public/site/client/src/components/Tree.svelte",
|
||||||
"site/client/src/components/TreeLeaf.svelte":"divkit/public/site/client/src/components/TreeLeaf.svelte",
|
"site/client/src/components/TreeLeaf.svelte":"divkit/public/site/client/src/components/TreeLeaf.svelte",
|
||||||
"site/client/src/components/Viewer.svelte":"divkit/public/site/client/src/components/Viewer.svelte",
|
"site/client/src/components/Viewer.svelte":"divkit/public/site/client/src/components/Viewer.svelte",
|
||||||
@@ -15011,7 +15016,9 @@
|
|||||||
"site/client/src/components/WebViewerSidebar.svelte":"divkit/public/site/client/src/components/WebViewerSidebar.svelte",
|
"site/client/src/components/WebViewerSidebar.svelte":"divkit/public/site/client/src/components/WebViewerSidebar.svelte",
|
||||||
"site/client/src/components/WebViewerWrapper.svelte":"divkit/public/site/client/src/components/WebViewerWrapper.svelte",
|
"site/client/src/components/WebViewerWrapper.svelte":"divkit/public/site/client/src/components/WebViewerWrapper.svelte",
|
||||||
"site/client/src/ctx/tree.ts":"divkit/public/site/client/src/ctx/tree.ts",
|
"site/client/src/ctx/tree.ts":"divkit/public/site/client/src/ctx/tree.ts",
|
||||||
|
"site/client/src/data/defaultEditorValue.ts":"divkit/public/site/client/src/data/defaultEditorValue.ts",
|
||||||
"site/client/src/data/editorMode.ts":"divkit/public/site/client/src/data/editorMode.ts",
|
"site/client/src/data/editorMode.ts":"divkit/public/site/client/src/data/editorMode.ts",
|
||||||
|
"site/client/src/data/editorModule.ts":"divkit/public/site/client/src/data/editorModule.ts",
|
||||||
"site/client/src/data/externalViewers.ts":"divkit/public/site/client/src/data/externalViewers.ts",
|
"site/client/src/data/externalViewers.ts":"divkit/public/site/client/src/data/externalViewers.ts",
|
||||||
"site/client/src/data/initialValue.ts":"divkit/public/site/client/src/data/initialValue.ts",
|
"site/client/src/data/initialValue.ts":"divkit/public/site/client/src/data/initialValue.ts",
|
||||||
"site/client/src/data/jsonStore.ts":"divkit/public/site/client/src/data/jsonStore.ts",
|
"site/client/src/data/jsonStore.ts":"divkit/public/site/client/src/data/jsonStore.ts",
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
|
/client/artifacts
|
||||||
/server/artifacts
|
/server/artifacts
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none"><path fill="#fff" d="M4.167 4.167V7.5H7.5V4.167H4.167Zm-1.667 0c0-.92.746-1.667 1.667-1.667H7.5c.92 0 1.667.746 1.667 1.667V7.5c0 .92-.747 1.667-1.667 1.667H4.167C3.247 9.167 2.5 8.42 2.5 7.5V4.167ZM4.167 12.5v3.333H7.5V12.5H4.167Zm-1.667 0c0-.92.746-1.667 1.667-1.667H7.5c.92 0 1.667.746 1.667 1.667v3.333c0 .92-.747 1.667-1.667 1.667H4.167c-.92 0-1.667-.746-1.667-1.667V12.5Zm13.333 3.333H12.5V12.5h3.333v3.333Zm-3.333-5c-.92 0-1.667.746-1.667 1.667v3.333c0 .92.746 1.667 1.667 1.667h3.333c.92 0 1.667-.746 1.667-1.667V12.5c0-.92-.746-1.667-1.667-1.667H12.5Zm.833-7.5a.833.833 0 0 1 1.667 0V5h1.667a.833.833 0 0 1 0 1.667H15v1.666a.833.833 0 1 1-1.667 0V6.667h-1.666a.833.833 0 1 1 0-1.667h1.666V3.333Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 789 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none"><path fill="#fff" fill-rule="evenodd" d="M6.559 4.023C5.139 5.63 4.198 7.817 4.15 9.933c-.052 2.342.882 4.323 2.044 5.782a9.788 9.788 0 0 0 1.78 1.74c.586.435 1.059.66 1.321.726.782.196 1.495.244 2.018.035.425-.17.902-.396 1.085-1.578-.01-.396-.134-.988-.307-1.587l-.08-.274c-.212-.745-.443-1.656-.443-2.802 0-.856.456-1.428.952-1.835.24-.196.507-.37.76-.529l.225-.14c.182-.113.358-.223.542-.345.502-.335.961-.706 1.322-1.218.35-.498.637-1.17.732-2.15-.008-.86-.27-1.77-.925-2.507-.658-.74-1.788-1.392-3.69-1.582-1.707-.17-3.501.74-4.927 2.354Zm-1.236-1.09C6.961 1.077 9.236-.213 11.65.028c2.219.222 3.768 1.013 4.758 2.127.983 1.107 1.341 2.448 1.341 3.638v.037l-.003.038c-.115 1.266-.496 2.23-1.03 2.988-.527.75-1.175 1.254-1.755 1.64-.207.139-.419.27-.609.388l-.196.122a5.886 5.886 0 0 0-.591.408c-.29.237-.349.387-.349.56 0 .915.182 1.652.38 2.35l.075.256c.175.595.376 1.445.376 2.113v.058l-.008.058c-.237 1.655-1 2.49-2.114 2.936-1.022.409-2.163.251-3.03.034-.561-.14-1.236-.506-1.904-1.003a11.436 11.436 0 0 1-2.086-2.035C3.566 15.06 2.44 12.715 2.502 9.897c.057-2.55 1.176-5.102 2.821-6.965Z" clip-rule="evenodd"/><path fill="#fff" fill-rule="evenodd" d="M11.568 4.146a1.648 1.648 0 1 0 0 3.297 1.648 1.648 0 0 0 0-3.297ZM8.27 5.794a3.297 3.297 0 1 1 6.594 0 3.297 3.297 0 0 1-6.594 0ZM7.341 9.844a.789.789 0 1 0 0 1.578.789.789 0 0 0 0-1.578Zm-2.367.79a2.367 2.367 0 1 1 4.734 0 2.367 2.367 0 0 1-4.734 0ZM9.341 14.727a.379.379 0 1 0 0 .757.379.379 0 0 0 0-.757Zm-1.894.379a1.894 1.894 0 1 1 3.788 0 1.894 1.894 0 0 1-3.788 0Z" clip-rule="evenodd"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none"><path fill="#fff" d="M16.286 4.857A.857.857 0 0 0 15.429 4h-2.572a.857.857 0 0 0 0 1.714h1.714v2.572c0 .227.09.445.252.606l.566.566c.24.22.454.328.642.381.201.057.566.1.566.1v.118s-.415.04-.566.09l-.022.008c-.13.043-.313.103-.553.32l-.633.633a.857.857 0 0 0-.252.606v2.572h-1.714a.857.857 0 0 0 0 1.714h2.572a.857.857 0 0 0 .857-.857v-3.074l1.463-1.463a.857.857 0 0 0 0-1.212L16.286 7.93V4.857ZM3.714 4.857c0-.473.384-.857.857-.857h2.572a.857.857 0 0 1 0 1.714H5.429v2.572c0 .227-.09.445-.251.606l-.52.52c-.261.25-.493.37-.693.427-.201.057-.566.1-.566.1v.118s.415.04.566.09l.022.008c.15.05.371.122.67.434l.52.52c.161.16.252.378.252.605v2.572h1.714a.857.857 0 0 1 0 1.714H4.57a.857.857 0 0 1-.857-.857v-3.074l-1.463-1.463a.857.857 0 0 1 0-1.212L3.714 7.93V4.857Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 846 B |
@@ -4,6 +4,7 @@
|
|||||||
"languageChooser": "Выбранный язык",
|
"languageChooser": "Выбранный язык",
|
||||||
"playground": "Веб песочница",
|
"playground": "Веб песочница",
|
||||||
"samples": "Примеры",
|
"samples": "Примеры",
|
||||||
|
"design": "Визуальный редактор",
|
||||||
"share": "Поделиться",
|
"share": "Поделиться",
|
||||||
"components": "Компоненты: ",
|
"components": "Компоненты: ",
|
||||||
"timeToRender": "Время на отрисовку: ",
|
"timeToRender": "Время на отрисовку: ",
|
||||||
@@ -32,13 +33,17 @@
|
|||||||
"webSupportWarning": "Данный пример содержит функционал, который не поддержан в реализации для Веба. Он может отличаться от нативных платформ.",
|
"webSupportWarning": "Данный пример содержит функционал, который не поддержан в реализации для Веба. Он может отличаться от нативных платформ.",
|
||||||
"collapse": "Свернуть",
|
"collapse": "Свернуть",
|
||||||
"expand": "Развернуть",
|
"expand": "Развернуть",
|
||||||
"selectComponent": "Выбрать компонент"
|
"selectComponent": "Выбрать компонент",
|
||||||
|
"designComponents": "Компоненты",
|
||||||
|
"designPalette": "Палитра",
|
||||||
|
"designVariables": "Переменные"
|
||||||
},
|
},
|
||||||
"en": {
|
"en": {
|
||||||
"name": "Eng",
|
"name": "Eng",
|
||||||
"languageChooser": "Selected language",
|
"languageChooser": "Selected language",
|
||||||
"playground": "Web playground",
|
"playground": "Web playground",
|
||||||
"samples": "Samples",
|
"samples": "Samples",
|
||||||
|
"design": "Visual editor",
|
||||||
"share": "Share",
|
"share": "Share",
|
||||||
"components": "Components: ",
|
"components": "Components: ",
|
||||||
"timeToRender": "Time to render: ",
|
"timeToRender": "Time to render: ",
|
||||||
@@ -67,6 +72,9 @@
|
|||||||
"webSupportWarning": "This sample contains functionality that is not supported in the implementation for the Web. It may differ from native platforms.",
|
"webSupportWarning": "This sample contains functionality that is not supported in the implementation for the Web. It may differ from native platforms.",
|
||||||
"collapse": "Collapse",
|
"collapse": "Collapse",
|
||||||
"expand": "Expand",
|
"expand": "Expand",
|
||||||
"selectComponent": "Select component"
|
"selectComponent": "Select component",
|
||||||
|
"designComponents": "Components",
|
||||||
|
"designPalette": "Palette",
|
||||||
|
"designVariables": "Variables"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
if (langVal !== 'ru' && langVal !== 'en') {
|
if (langVal !== 'ru' && langVal !== 'en') {
|
||||||
langVal = 'en';
|
langVal = 'en';
|
||||||
}
|
}
|
||||||
let lang = writable(langVal);
|
let lang = writable<'ru' | 'en'>(langVal as 'ru' | 'en');
|
||||||
const l10n = derived(lang, lang => {
|
const l10n = derived(lang, lang => {
|
||||||
return (key: keyof typeof langObj['en'], overrideLang?: string) =>
|
return (key: keyof typeof langObj['en'], overrideLang?: string) =>
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
getLanguage(): string {
|
getLanguage(): string {
|
||||||
return get(lang);
|
return get(lang);
|
||||||
},
|
},
|
||||||
setLanguage(name: string): void {
|
setLanguage(name: 'ru' | 'en'): void {
|
||||||
lang.set(name);
|
lang.set(name);
|
||||||
},
|
},
|
||||||
l10n,
|
l10n,
|
||||||
|
|||||||
@@ -0,0 +1,284 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { getContext, onDestroy, onMount } from 'svelte';
|
||||||
|
import type * as monaco from 'monaco-editor';
|
||||||
|
import type { DivProEditorInstance, EditorOptions, Layout, LayoutItem } from '@yandex-portal/divkit-editor';
|
||||||
|
import { loadMonaco } from './Editor.svelte';
|
||||||
|
import { valueStore } from '../data/valueStore';
|
||||||
|
import { initPromise } from '../data/sessionController';
|
||||||
|
import ToolbarItem from './ToolbarItem.svelte';
|
||||||
|
import { LANGUAGE_CTX, type LanguageContext } from '../data/languageContext';
|
||||||
|
|
||||||
|
const {l10n, lang} = getContext<LanguageContext>(LANGUAGE_CTX);
|
||||||
|
|
||||||
|
let root: HTMLElement;
|
||||||
|
let instance: DivProEditorInstance;
|
||||||
|
let alive = false;
|
||||||
|
let selectedPanel = 'components';
|
||||||
|
|
||||||
|
const TOOLBAR_ITEMS = [
|
||||||
|
'components',
|
||||||
|
'palette',
|
||||||
|
'sources',
|
||||||
|
] as const;
|
||||||
|
$: TOOLBAR_TEXTS = {
|
||||||
|
components: $l10n('designComponents'),
|
||||||
|
palette: $l10n('designPalette'),
|
||||||
|
sources: $l10n('designVariables'),
|
||||||
|
};
|
||||||
|
|
||||||
|
function getEditorLayoutByPanel(panel: string): Layout {
|
||||||
|
let leftList: LayoutItem[];
|
||||||
|
|
||||||
|
if (panel === 'palette') {
|
||||||
|
leftList = ['palette'];
|
||||||
|
} else if (panel === 'sources') {
|
||||||
|
leftList = ['custom-variables'];
|
||||||
|
} else if (panel === 'tanker') {
|
||||||
|
leftList = ['tanker-overview'];
|
||||||
|
} else {
|
||||||
|
leftList = ['new-component', 'component-tree'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
items: leftList,
|
||||||
|
minWidth: 400,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
items: ['preview'],
|
||||||
|
weight: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
items: ['component-props:code'],
|
||||||
|
minWidth: 360,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function onToolbarClick(item: string): void {
|
||||||
|
selectedPanel = item;
|
||||||
|
if (instance) {
|
||||||
|
instance.setLayout(getEditorLayoutByPanel(selectedPanel));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
alive = true;
|
||||||
|
|
||||||
|
Promise.all([
|
||||||
|
initPromise,
|
||||||
|
import('../data/editorModule'),
|
||||||
|
loadMonaco()
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
]).then(([_, {DivProEditor}, { monaco, jsonModelUri }]) => {
|
||||||
|
if (!alive) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
instance = DivProEditor.init({
|
||||||
|
renderTo: root,
|
||||||
|
value: $valueStore,
|
||||||
|
theme: 'light',
|
||||||
|
locale: $lang,
|
||||||
|
sources: [],
|
||||||
|
layout: getEditorLayoutByPanel(selectedPanel),
|
||||||
|
paletteEnabled: true,
|
||||||
|
api: {
|
||||||
|
onChange() {
|
||||||
|
valueStore.set(instance.getValue());
|
||||||
|
},
|
||||||
|
editorFabric(options: EditorOptions) {
|
||||||
|
const model = monaco.editor.getModel(jsonModelUri) || monaco.editor.createModel(options.value, 'json', jsonModelUri);
|
||||||
|
const opts: monaco.editor.IStandaloneEditorConstructionOptions = {
|
||||||
|
theme: 'vs',
|
||||||
|
minimap: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
automaticLayout: true,
|
||||||
|
wordWrap: 'on',
|
||||||
|
model,
|
||||||
|
lineNumbers: 'off',
|
||||||
|
bracketPairColorization: {
|
||||||
|
enabled: true,
|
||||||
|
independentColorPoolPerBracketType: true
|
||||||
|
},
|
||||||
|
smoothScrolling: true
|
||||||
|
};
|
||||||
|
|
||||||
|
const editor = monaco.editor.create(options.node, opts);
|
||||||
|
editor.setValue(options.value);
|
||||||
|
let editorDecorations: monaco.editor.IEditorDecorationsCollection | null = null;
|
||||||
|
|
||||||
|
editor.onDidChangeModelContent(() => {
|
||||||
|
let val = editor && editor.getModel()?.getValue();
|
||||||
|
options.onChange(val || '');
|
||||||
|
});
|
||||||
|
|
||||||
|
editor.onMouseMove(function (e) {
|
||||||
|
const pos = e.target.position;
|
||||||
|
if (!pos || !pos.lineNumber) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
options.onOver(model.getOffsetAt(pos));
|
||||||
|
});
|
||||||
|
|
||||||
|
editor.onMouseLeave(() => {
|
||||||
|
options.onOver(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
editor.onMouseDown((e) => {
|
||||||
|
const pos = e.target.position;
|
||||||
|
if (!pos || !pos.lineNumber) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
options.onClick(model.getOffsetAt(pos));
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
setValue(value) {
|
||||||
|
if (!editor.hasTextFocus()) {
|
||||||
|
editor.setValue(value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setTheme() {
|
||||||
|
// not realized
|
||||||
|
},
|
||||||
|
setReadOnly(/* readOnly */) {
|
||||||
|
// not realized
|
||||||
|
},
|
||||||
|
revealLoc(loc) {
|
||||||
|
editor.revealPositionNearTop({ lineNumber: loc.line, column: loc.column });
|
||||||
|
},
|
||||||
|
decorateRanges(typedRanges) {
|
||||||
|
if (editorDecorations) {
|
||||||
|
editorDecorations.clear();
|
||||||
|
editorDecorations = null;
|
||||||
|
}
|
||||||
|
if (typedRanges) {
|
||||||
|
editorDecorations = editor.createDecorationsCollection(typedRanges.map(typedRange => {
|
||||||
|
return {
|
||||||
|
range: new monaco.Range(
|
||||||
|
typedRange.range.start.line,
|
||||||
|
typedRange.range.start.column,
|
||||||
|
typedRange.range.end.line,
|
||||||
|
typedRange.range.end.column
|
||||||
|
),
|
||||||
|
options: {
|
||||||
|
blockClassName: typedRange.type === 'highlight' ? 'design__code-highlight' : 'design__code-selection'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
destroy() {
|
||||||
|
editor.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
uploadFile(file: File) {
|
||||||
|
const name = file.name.toLowerCase();
|
||||||
|
let type: string;
|
||||||
|
|
||||||
|
if (name.endsWith('.png')) {
|
||||||
|
type = 'image/png';
|
||||||
|
} else if (name.endsWith('.jpg') || name.endsWith('.jpeg')) {
|
||||||
|
type = 'image/jpg';
|
||||||
|
} else if (name.endsWith('.svg')) {
|
||||||
|
type = 'image/svg+xml';
|
||||||
|
} else if (name.endsWith('.gif')) {
|
||||||
|
type = 'image/gif';
|
||||||
|
} else if (name.endsWith('.json')) {
|
||||||
|
type = 'application/json';
|
||||||
|
} else {
|
||||||
|
return Promise.reject(new Error('Unknown image'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
reader.onload = () => {
|
||||||
|
const request = fetch('/api/uploadFile', {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({
|
||||||
|
imageData: (reader.result as string).split(',')[1],
|
||||||
|
contentType: type
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error('Requst failed');
|
||||||
|
}
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then(json => {
|
||||||
|
if (!json.ok) {
|
||||||
|
throw new Error('Something went wrong');
|
||||||
|
}
|
||||||
|
return json.url;
|
||||||
|
});
|
||||||
|
|
||||||
|
resolve(request);
|
||||||
|
};
|
||||||
|
reader.onerror = error => {
|
||||||
|
reject(error);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
onDestroy(() => {
|
||||||
|
alive = false;
|
||||||
|
instance?.destroy();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="design">
|
||||||
|
<div class="design__sidebar">
|
||||||
|
{#each TOOLBAR_ITEMS as item}
|
||||||
|
<ToolbarItem
|
||||||
|
icon={item}
|
||||||
|
selected={selectedPanel === item}
|
||||||
|
text={TOOLBAR_TEXTS[item]}
|
||||||
|
on:click={() => onToolbarClick(item)}
|
||||||
|
/>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
<div class="design__editor" bind:this={root}></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.design {
|
||||||
|
display: flex;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.design__sidebar {
|
||||||
|
display: flex;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 56px;
|
||||||
|
padding-top: 10px;
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.design__editor {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.design__code-highlight) {
|
||||||
|
background: rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.design__code-selection) {
|
||||||
|
background: rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,49 +1,82 @@
|
|||||||
<script lang="ts" context="module">
|
<script lang="ts" context="module">
|
||||||
import * as monaco from 'monaco-editor';
|
import { urlPath } from '../utils/const';
|
||||||
|
import type * as monaco from 'monaco-editor';
|
||||||
import tsBuilderTypes from '../../artifacts/jsonbuilder.d.ts?inline';
|
import tsBuilderTypes from '../../artifacts/jsonbuilder.d.ts?inline';
|
||||||
|
|
||||||
const jsonModelUri = monaco.Uri.parse('a://b/divview.json');
|
let monacoPromose: Promise<{
|
||||||
const tsModelUri = monaco.Uri.parse('file:///main.tsx');
|
monaco: typeof import('monaco-editor');
|
||||||
|
jsonModelUri: monaco.Uri;
|
||||||
|
tsModelUri: monaco.Uri;
|
||||||
|
}> | undefined;
|
||||||
|
export function loadMonaco() {
|
||||||
|
if (monacoPromose) {
|
||||||
|
return monacoPromose;
|
||||||
|
}
|
||||||
|
|
||||||
const schemas = require.context('../../../../schema/', false, /\.json$/);
|
monacoPromose = import('monaco-editor').then(monaco => {
|
||||||
let schema = schemas.keys().map((key: string) => {
|
const jsonModelUri = monaco.Uri.parse('a://b/divview.json');
|
||||||
const filename = key.replace(/^\.\//, '');
|
const tsModelUri = monaco.Uri.parse('file:///main.tsx');
|
||||||
|
|
||||||
return {
|
const schemas = require.context('../../../../schema/', false, /\.json$/);
|
||||||
uri: 'schema://div2/' + filename,
|
let schema = schemas.keys().map((key: string) => {
|
||||||
fileMatch: [] as string [],
|
const filename = key.replace(/^\.\//, '');
|
||||||
schema: schemas(key)
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
schema.push({
|
return {
|
||||||
uri: 'schema://div2/root.json',
|
uri: 'schema://div2/' + filename,
|
||||||
fileMatch: [jsonModelUri.toString()],
|
fileMatch: [] as string [],
|
||||||
schema: require('../schema/root.json')
|
schema: schemas(key)
|
||||||
});
|
};
|
||||||
|
});
|
||||||
|
|
||||||
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
|
schema.push({
|
||||||
validate: true,
|
uri: 'schema://div2/root.json',
|
||||||
schemas: schema,
|
fileMatch: [jsonModelUri.toString()],
|
||||||
allowComments: false
|
schema: require('../schema/root.json')
|
||||||
});
|
});
|
||||||
|
|
||||||
// validation settings
|
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
|
||||||
monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
|
validate: true,
|
||||||
noSemanticValidation: true,
|
schemas: schema,
|
||||||
noSyntaxValidation: false
|
allowComments: false
|
||||||
});
|
});
|
||||||
|
|
||||||
// compiler options
|
// validation settings
|
||||||
monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
|
monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
|
||||||
target: monaco.languages.typescript.ScriptTarget.ES2015,
|
noSemanticValidation: true,
|
||||||
allowNonTsExtensions: true
|
noSyntaxValidation: false
|
||||||
});
|
});
|
||||||
|
|
||||||
monaco.languages.typescript.typescriptDefaults.addExtraLib(
|
// compiler options
|
||||||
`declare module '@divkitframework/jsonbuilder' {${tsBuilderTypes}}`,
|
monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
|
||||||
'@types/divcard2/index.d.ts'
|
target: monaco.languages.typescript.ScriptTarget.ES2015,
|
||||||
);
|
allowNonTsExtensions: true
|
||||||
|
});
|
||||||
|
|
||||||
|
monaco.languages.typescript.typescriptDefaults.addExtraLib(
|
||||||
|
`declare module '@divkitframework/jsonbuilder' {${tsBuilderTypes}}`,
|
||||||
|
'@types/divcard2/index.d.ts'
|
||||||
|
);
|
||||||
|
|
||||||
|
window.MonacoEnvironment = {
|
||||||
|
getWorkerUrl(_moduleId: string, label: string) {
|
||||||
|
if (label === 'json') {
|
||||||
|
return urlPath + '/json.worker.js';
|
||||||
|
} else if (label === 'typescript') {
|
||||||
|
return urlPath + '/typescript.worker.js';
|
||||||
|
}
|
||||||
|
return urlPath + '/editor.worker.js';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
monaco,
|
||||||
|
jsonModelUri,
|
||||||
|
tsModelUri,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return monacoPromose;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@@ -52,7 +85,7 @@
|
|||||||
import { codeRunStore, valueStore } from '../data/valueStore';
|
import { codeRunStore, valueStore } from '../data/valueStore';
|
||||||
import PanelHeader from './PanelHeader.svelte';
|
import PanelHeader from './PanelHeader.svelte';
|
||||||
import Select from './Select.svelte';
|
import Select from './Select.svelte';
|
||||||
import { urlPath, serverHostPath } from '../utils/const';
|
import { serverHostPath } from '../utils/const';
|
||||||
import { LANGUAGE_CTX, LanguageContext } from '../data/languageContext';
|
import { LANGUAGE_CTX, LanguageContext } from '../data/languageContext';
|
||||||
import { runCode as runCodeShortcut } from '../utils/shortcuts';
|
import { runCode as runCodeShortcut } from '../utils/shortcuts';
|
||||||
import { jsonStore } from '../data/jsonStore';
|
import { jsonStore } from '../data/jsonStore';
|
||||||
@@ -62,17 +95,6 @@
|
|||||||
import type { ShortcutList } from '../utils/useShortcuts';
|
import type { ShortcutList } from '../utils/useShortcuts';
|
||||||
import { shortcuts } from '../utils/useShortcuts';
|
import { shortcuts } from '../utils/useShortcuts';
|
||||||
|
|
||||||
window.MonacoEnvironment = {
|
|
||||||
getWorkerUrl(_moduleId: string, label: string) {
|
|
||||||
if (label === 'json') {
|
|
||||||
return urlPath + '/json.worker.js';
|
|
||||||
} else if (label === 'typescript') {
|
|
||||||
return urlPath + '/typescript.worker.js';
|
|
||||||
}
|
|
||||||
return urlPath + '/editor.worker.js';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const {l10n} = getContext<LanguageContext>(LANGUAGE_CTX);
|
const {l10n} = getContext<LanguageContext>(LANGUAGE_CTX);
|
||||||
|
|
||||||
type Language = 'json' | 'ts';
|
type Language = 'json' | 'ts';
|
||||||
@@ -90,35 +112,6 @@
|
|||||||
let isRunning = false;
|
let isRunning = false;
|
||||||
let runButton: HTMLElement;
|
let runButton: HTMLElement;
|
||||||
|
|
||||||
valueStore.subscribe(val => {
|
|
||||||
if (editor && editor.getValue() !== val) {
|
|
||||||
editor.setValue(val);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function getModel(type: 'ts' | 'json' | null): monaco.editor.ITextModel {
|
|
||||||
if (type === 'json') {
|
|
||||||
const model = monaco.editor.getModel(jsonModelUri) ||
|
|
||||||
monaco.editor.createModel($valueStore, 'json', jsonModelUri);
|
|
||||||
model.setValue($valueStore);
|
|
||||||
return model;
|
|
||||||
} else {
|
|
||||||
const model = monaco.editor.getModel(tsModelUri) ||
|
|
||||||
monaco.editor.createModel($valueStore, 'typescript', tsModelUri);
|
|
||||||
model.setValue($valueStore);
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
editorMode.subscribe(val => {
|
|
||||||
if (val) {
|
|
||||||
if (editor) {
|
|
||||||
editor.setModel(getModel(val));
|
|
||||||
}
|
|
||||||
currentLanguage = val;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function onLanguageChange(): void {
|
function onLanguageChange(): void {
|
||||||
if (currentLanguage === $editorMode) {
|
if (currentLanguage === $editorMode) {
|
||||||
return;
|
return;
|
||||||
@@ -182,16 +175,52 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(async() => {
|
||||||
|
const { monaco, jsonModelUri, tsModelUri } = await loadMonaco();
|
||||||
|
|
||||||
|
function getModel(type: 'ts' | 'json' | null): monaco.editor.ITextModel {
|
||||||
|
if (type === 'json') {
|
||||||
|
const model = monaco.editor.getModel(jsonModelUri) ||
|
||||||
|
monaco.editor.createModel($valueStore, 'json', jsonModelUri);
|
||||||
|
model.setValue($valueStore);
|
||||||
|
return model;
|
||||||
|
} else {
|
||||||
|
const model = monaco.editor.getModel(tsModelUri) ||
|
||||||
|
monaco.editor.createModel($valueStore, 'typescript', tsModelUri);
|
||||||
|
model.setValue($valueStore);
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
valueStore.subscribe(val => {
|
||||||
|
if (editor && editor.getValue() !== val) {
|
||||||
|
editor.setValue(val);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
editorMode.subscribe(val => {
|
||||||
|
if (val) {
|
||||||
|
if (editor) {
|
||||||
|
editor.setModel(getModel(val));
|
||||||
|
}
|
||||||
|
currentLanguage = val;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const opts: monaco.editor.IStandaloneEditorConstructionOptions = {
|
const opts: monaco.editor.IStandaloneEditorConstructionOptions = {
|
||||||
theme: 'vs',
|
theme: 'vs',
|
||||||
minimap: {
|
minimap: {
|
||||||
enabled: false
|
enabled: false
|
||||||
},
|
},
|
||||||
automaticLayout: true,
|
automaticLayout: true,
|
||||||
wordWrap: 'on',
|
wordWrap: 'off',
|
||||||
scrollBeyondLastLine: false,
|
scrollBeyondLastLine: false,
|
||||||
model: getModel($editorMode)
|
model: getModel($editorMode),
|
||||||
|
bracketPairColorization: {
|
||||||
|
enabled: true,
|
||||||
|
independentColorPoolPerBracketType: true
|
||||||
|
},
|
||||||
|
smoothScrolling: true
|
||||||
};
|
};
|
||||||
|
|
||||||
editor = monaco.editor.create(node, opts);
|
editor = monaco.editor.create(node, opts);
|
||||||
|
|||||||
@@ -64,6 +64,11 @@
|
|||||||
{$l10n('samples')}
|
{$l10n('samples')}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="header__subnav-item">
|
||||||
|
<a class="header__subnav-link" href="/playground?design=1">
|
||||||
|
{$l10n('design')}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,10 @@
|
|||||||
import SplitView from './SplitView.svelte';
|
import SplitView from './SplitView.svelte';
|
||||||
import Editor from './Editor.svelte';
|
import Editor from './Editor.svelte';
|
||||||
import Viewer from './Viewer.svelte';
|
import Viewer from './Viewer.svelte';
|
||||||
import { isSamples } from '../data/session';
|
import { isDesign, isSamples } from '../data/session';
|
||||||
import Samples from './Samples.svelte';
|
import Samples from './Samples.svelte';
|
||||||
import { Truthy } from '../utils/truthy';
|
import { Truthy } from '../utils/truthy';
|
||||||
|
import Design from './Design.svelte';
|
||||||
|
|
||||||
$: components = [$isSamples && {
|
$: components = [$isSamples && {
|
||||||
component: Samples,
|
component: Samples,
|
||||||
@@ -20,7 +21,11 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<main class="main">
|
<main class="main">
|
||||||
<SplitView {components} />
|
{#if $isDesign}
|
||||||
|
<Design />
|
||||||
|
{:else}
|
||||||
|
<SplitView {components} />
|
||||||
|
{/if}
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -0,0 +1,112 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export let icon: string;
|
||||||
|
export let selected: boolean;
|
||||||
|
export let text: string;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button class="toolbar-item" class:toolbar-item_selected={selected} on:click>
|
||||||
|
<div class="toolbar-item__border">
|
||||||
|
<div class="toolbar-item__icon toolbar-item__icon_{icon}"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="toolbar-item__tooltip">
|
||||||
|
{text}
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.toolbar-item {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 36px;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
font: inherit;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-item:not(.toolbar-item_selected) {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-item__border {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
border-radius: 8px;
|
||||||
|
transition: background-color .15s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-item:not(.toolbar-item_selected):hover .toolbar-item__border {
|
||||||
|
background-color: rgba(0, 0, 0, .12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-item_selected .toolbar-item__border {
|
||||||
|
background: #5959E8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-item__icon {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
filter: invert(100%);
|
||||||
|
background: no-repeat 50% 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-item_selected .toolbar-item__icon {
|
||||||
|
filter: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-item__icon_components {
|
||||||
|
background-image: url(../assets/divkitpro/components.svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-item__icon_palette {
|
||||||
|
background-image: url(../assets/divkitpro/palette.svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-item__icon_sources {
|
||||||
|
background-image: url(../assets/divkitpro/sources.svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-item__tooltip {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
left: 100%;
|
||||||
|
padding: 8px 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
|
color: #000;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: #fff;
|
||||||
|
filter: drop-shadow(0 1px 8px rgba(0, 0, 0, 0.14));
|
||||||
|
pointer-events: none;
|
||||||
|
transform: translateX(1rem);
|
||||||
|
transition: .2s ease-in-out;
|
||||||
|
transition-property: visibility, opacity, transform;
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-item:hover .toolbar-item__tooltip {
|
||||||
|
opacity: 1;
|
||||||
|
visibility: visible;
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-item__tooltip::before {
|
||||||
|
position: absolute;
|
||||||
|
z-index: -1;
|
||||||
|
top: 10px;
|
||||||
|
left: -4px;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
background: inherit;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
content: '';
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
export const DEFAULT_EDITOR_VALUE = `{
|
||||||
|
"card": {
|
||||||
|
"log_id": "div2_sample_card",
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"state_id": 0,
|
||||||
|
"div": {
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "_template_close",
|
||||||
|
"alignment_horizontal": "right",
|
||||||
|
"height": {
|
||||||
|
"type": "fixed",
|
||||||
|
"value": 28
|
||||||
|
},
|
||||||
|
"margins": {
|
||||||
|
"top": 20,
|
||||||
|
"right": 24
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"type": "fixed",
|
||||||
|
"value": 28
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"background": [
|
||||||
|
{
|
||||||
|
"color": "#F1EBDC",
|
||||||
|
"type": "solid"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"height": {
|
||||||
|
"type": "match_parent"
|
||||||
|
},
|
||||||
|
"orientation": "overlap",
|
||||||
|
"type": "container"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"palette": {
|
||||||
|
"light": [],
|
||||||
|
"dark": []
|
||||||
|
},
|
||||||
|
"templates": {
|
||||||
|
"_template_lottie": {
|
||||||
|
"type": "gif",
|
||||||
|
"scale": "fit",
|
||||||
|
"extensions": [
|
||||||
|
{
|
||||||
|
"id": "lottie",
|
||||||
|
"params": {
|
||||||
|
"$lottie_url": "lottie_url"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"gif_url": "https://empty"
|
||||||
|
},
|
||||||
|
"_template_button": {
|
||||||
|
"type": "text",
|
||||||
|
"content_alignment_horizontal": "center",
|
||||||
|
"border": {
|
||||||
|
"$corner_radius": "corners"
|
||||||
|
},
|
||||||
|
"paddings": {
|
||||||
|
"bottom": 24,
|
||||||
|
"left": 28,
|
||||||
|
"right": 28,
|
||||||
|
"top": 22
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"type": "wrap_content"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"_template_close": {
|
||||||
|
"accessibility": {
|
||||||
|
"description": "Закрыть",
|
||||||
|
"mode": "merge",
|
||||||
|
"type": "button"
|
||||||
|
},
|
||||||
|
"actions": [
|
||||||
|
{
|
||||||
|
"log_id": "close_popup",
|
||||||
|
"url": "div-screen://close"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"image_url": "https://yastatic.net/s3/home/div/div_fullscreens/cross2.3.png",
|
||||||
|
"tint_color": "#73000000",
|
||||||
|
"type": "image"
|
||||||
|
},
|
||||||
|
"_template_list_item": {
|
||||||
|
"type": "container",
|
||||||
|
"orientation": "horizontal",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"image_url": "https://yastatic.net/s3/home/div/div_fullscreens/hyphen.4.png",
|
||||||
|
"$tint_color": "list_color",
|
||||||
|
"width": {
|
||||||
|
"type": "fixed",
|
||||||
|
"value": 28,
|
||||||
|
"unit": 28
|
||||||
|
},
|
||||||
|
"height": {
|
||||||
|
"type": "fixed",
|
||||||
|
"value": 28,
|
||||||
|
"unit": 28
|
||||||
|
},
|
||||||
|
"margins": {
|
||||||
|
"top": 2,
|
||||||
|
"right": 12,
|
||||||
|
"bottom": 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "text",
|
||||||
|
"$text": "list_text",
|
||||||
|
"$text_color": "list_color",
|
||||||
|
"font_size": 24,
|
||||||
|
"line_height": 32,
|
||||||
|
"font_weight": "medium",
|
||||||
|
"width": {
|
||||||
|
"type": "wrap_content",
|
||||||
|
"constrained": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
import '@yandex-portal/divkit-editor/dist/divkit-editor.css';
|
||||||
|
export { DivProEditor } from '@yandex-portal/divkit-editor';
|
||||||
@@ -4,7 +4,7 @@ import type lang from '../auto/lang.json';
|
|||||||
export const LANGUAGE_CTX = Symbol('language');
|
export const LANGUAGE_CTX = Symbol('language');
|
||||||
|
|
||||||
export interface LanguageContext {
|
export interface LanguageContext {
|
||||||
lang: Readable<string>;
|
lang: Readable<'ru' | 'en'>;
|
||||||
getLanguage(): string;
|
getLanguage(): string;
|
||||||
setLanguage(name: string): void;
|
setLanguage(name: string): void;
|
||||||
languagesList(): string[];
|
languagesList(): string[];
|
||||||
|
|||||||
@@ -10,3 +10,5 @@ export const isInitialLoading = writable(false);
|
|||||||
export const isLoadError = writable(false);
|
export const isLoadError = writable(false);
|
||||||
|
|
||||||
export const isSamples = writable(false);
|
export const isSamples = writable(false);
|
||||||
|
|
||||||
|
export const isDesign = writable(false);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { get } from 'svelte/store';
|
import { get } from 'svelte/store';
|
||||||
import { initialValueStore, valueStore } from './valueStore';
|
import { initialValueStore, valueStore } from './valueStore';
|
||||||
import { isInitialLoading, isLoadError, isSamples, session } from './session';
|
import { isDesign, isInitialLoading, isLoadError, isSamples, session } from './session';
|
||||||
import { debounce } from '../utils/debounce';
|
import { debounce } from '../utils/debounce';
|
||||||
import { clientHostPath, serverHostPath } from '../utils/const';
|
import { clientHostPath, serverHostPath } from '../utils/const';
|
||||||
import { savedStore } from './savedStore';
|
import { savedStore } from './savedStore';
|
||||||
@@ -10,6 +10,7 @@ import { jsonStore } from './jsonStore';
|
|||||||
// import { addListener, wsPromise } from './ws';
|
// import { addListener, wsPromise } from './ws';
|
||||||
// import { listenToDevices } from './externalViewers';
|
// import { listenToDevices } from './externalViewers';
|
||||||
import { getLs, setLs } from '../utils/localStorage';
|
import { getLs, setLs } from '../utils/localStorage';
|
||||||
|
import { DEFAULT_EDITOR_VALUE } from './defaultEditorValue';
|
||||||
|
|
||||||
/* function listenJsonForPreview(uuid: string): void {
|
/* function listenJsonForPreview(uuid: string): void {
|
||||||
wsPromise.then(ws => {
|
wsPromise.then(ws => {
|
||||||
@@ -35,9 +36,13 @@ async function init() {
|
|||||||
const uuid = params.get('uuid');
|
const uuid = params.get('uuid');
|
||||||
// mode = params.get('mode') || '';
|
// mode = params.get('mode') || '';
|
||||||
|
|
||||||
|
const design = params.get('design') === '1';
|
||||||
const samples = params.get('samples') === '1';
|
const samples = params.get('samples') === '1';
|
||||||
|
|
||||||
if (samples) {
|
if (design) {
|
||||||
|
isDesign.set(true);
|
||||||
|
valueStore.set(DEFAULT_EDITOR_VALUE);
|
||||||
|
} else if (samples) {
|
||||||
isSamples.set(true);
|
isSamples.set(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,8 +139,10 @@ function unsavedPrompt(event: BeforeUnloadEvent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function genLinks(uuid: string) {
|
async function genLinks(uuid: string) {
|
||||||
|
const isEditor = get(isDesign);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
linkToEdit: `${location.protocol}//${clientHostPath}?uuid=${uuid}`,
|
linkToEdit: `${location.protocol}//${clientHostPath}?uuid=${uuid}${isEditor ? '&design=1' : ''}`,
|
||||||
linkToPreview: `${location.protocol}//${clientHostPath}?uuid=${uuid}&mode=preview`,
|
linkToPreview: `${location.protocol}//${clientHostPath}?uuid=${uuid}&mode=preview`,
|
||||||
linkToJSON: `${location.protocol}//${serverHostPath}api/json?uuid=${uuid}`
|
linkToJSON: `${location.protocol}//${serverHostPath}api/json?uuid=${uuid}`
|
||||||
};
|
};
|
||||||
@@ -190,4 +197,4 @@ export async function save() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init();
|
export const initPromise = init();
|
||||||
|
|||||||
Reference in New Issue
Block a user