From 5bf72f61f8eadcf21d11a0639d7bc5f5b390c2e6 Mon Sep 17 00:00:00 2001 From: 4eb0da <4eb0da@yandex-team.com> Date: Fri, 1 Dec 2023 12:35:12 +0300 Subject: [PATCH] DivKitPro editor --- .mapping.json | 7 + site/.eslintignore | 1 + .../src/assets/divkitpro/components.svg | 1 + site/client/src/assets/divkitpro/palette.svg | 1 + site/client/src/assets/divkitpro/sources.svg | 1 + site/client/src/auto/lang.json | 12 +- site/client/src/components/App.svelte | 4 +- site/client/src/components/Design.svelte | 284 ++++++++++++++++++ site/client/src/components/Editor.svelte | 189 +++++++----- site/client/src/components/Header.svelte | 5 + site/client/src/components/Main.svelte | 9 +- site/client/src/components/ToolbarItem.svelte | 112 +++++++ site/client/src/data/defaultEditorValue.ts | 130 ++++++++ site/client/src/data/editorModule.ts | 2 + site/client/src/data/languageContext.ts | 2 +- site/client/src/data/session.ts | 2 + site/client/src/data/sessionController.ts | 15 +- 17 files changed, 686 insertions(+), 91 deletions(-) create mode 100644 site/client/src/assets/divkitpro/components.svg create mode 100644 site/client/src/assets/divkitpro/palette.svg create mode 100644 site/client/src/assets/divkitpro/sources.svg create mode 100644 site/client/src/components/Design.svelte create mode 100644 site/client/src/components/ToolbarItem.svelte create mode 100644 site/client/src/data/defaultEditorValue.ts create mode 100644 site/client/src/data/editorModule.ts diff --git a/.mapping.json b/.mapping.json index e98526e9b..12b431428 100644 --- a/.mapping.json +++ b/.mapping.json @@ -14968,6 +14968,9 @@ "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/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/dropdown.svg":"divkit/public/site/client/src/assets/dropdown.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/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/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/ErrorPage.svelte":"divkit/public/site/client/src/components/ErrorPage.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/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/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/TreeLeaf.svelte":"divkit/public/site/client/src/components/TreeLeaf.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/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/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/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/initialValue.ts":"divkit/public/site/client/src/data/initialValue.ts", "site/client/src/data/jsonStore.ts":"divkit/public/site/client/src/data/jsonStore.ts", diff --git a/site/.eslintignore b/site/.eslintignore index 6fb80054f..4b32ab292 100644 --- a/site/.eslintignore +++ b/site/.eslintignore @@ -1 +1,2 @@ +/client/artifacts /server/artifacts diff --git a/site/client/src/assets/divkitpro/components.svg b/site/client/src/assets/divkitpro/components.svg new file mode 100644 index 000000000..b0c9885f4 --- /dev/null +++ b/site/client/src/assets/divkitpro/components.svg @@ -0,0 +1 @@ + diff --git a/site/client/src/assets/divkitpro/palette.svg b/site/client/src/assets/divkitpro/palette.svg new file mode 100644 index 000000000..88066f2a3 --- /dev/null +++ b/site/client/src/assets/divkitpro/palette.svg @@ -0,0 +1 @@ + diff --git a/site/client/src/assets/divkitpro/sources.svg b/site/client/src/assets/divkitpro/sources.svg new file mode 100644 index 000000000..faf0fbb9b --- /dev/null +++ b/site/client/src/assets/divkitpro/sources.svg @@ -0,0 +1 @@ + diff --git a/site/client/src/auto/lang.json b/site/client/src/auto/lang.json index 4c2e3b551..8dc69e377 100644 --- a/site/client/src/auto/lang.json +++ b/site/client/src/auto/lang.json @@ -4,6 +4,7 @@ "languageChooser": "Выбранный язык", "playground": "Веб песочница", "samples": "Примеры", + "design": "Визуальный редактор", "share": "Поделиться", "components": "Компоненты: ", "timeToRender": "Время на отрисовку: ", @@ -32,13 +33,17 @@ "webSupportWarning": "Данный пример содержит функционал, который не поддержан в реализации для Веба. Он может отличаться от нативных платформ.", "collapse": "Свернуть", "expand": "Развернуть", - "selectComponent": "Выбрать компонент" + "selectComponent": "Выбрать компонент", + "designComponents": "Компоненты", + "designPalette": "Палитра", + "designVariables": "Переменные" }, "en": { "name": "Eng", "languageChooser": "Selected language", "playground": "Web playground", "samples": "Samples", + "design": "Visual editor", "share": "Share", "components": "Components: ", "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.", "collapse": "Collapse", "expand": "Expand", - "selectComponent": "Select component" + "selectComponent": "Select component", + "designComponents": "Components", + "designPalette": "Palette", + "designVariables": "Variables" } } diff --git a/site/client/src/components/App.svelte b/site/client/src/components/App.svelte index e37a2425e..524f05ac8 100644 --- a/site/client/src/components/App.svelte +++ b/site/client/src/components/App.svelte @@ -17,7 +17,7 @@ if (langVal !== 'ru' && langVal !== 'en') { langVal = 'en'; } - let lang = writable(langVal); + let lang = writable<'ru' | 'en'>(langVal as 'ru' | 'en'); const l10n = derived(lang, lang => { return (key: keyof typeof langObj['en'], overrideLang?: string) => // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -36,7 +36,7 @@ getLanguage(): string { return get(lang); }, - setLanguage(name: string): void { + setLanguage(name: 'ru' | 'en'): void { lang.set(name); }, l10n, diff --git a/site/client/src/components/Design.svelte b/site/client/src/components/Design.svelte new file mode 100644 index 000000000..89b2cc215 --- /dev/null +++ b/site/client/src/components/Design.svelte @@ -0,0 +1,284 @@ + + +
+
+ {#each TOOLBAR_ITEMS as item} + onToolbarClick(item)} + /> + {/each} +
+
+
+ + diff --git a/site/client/src/components/Editor.svelte b/site/client/src/components/Editor.svelte index e439bd3af..7ba2c6913 100644 --- a/site/client/src/components/Editor.svelte +++ b/site/client/src/components/Editor.svelte @@ -1,49 +1,82 @@
- + {#if $isDesign} + + {:else} + + {/if}
diff --git a/site/client/src/data/defaultEditorValue.ts b/site/client/src/data/defaultEditorValue.ts new file mode 100644 index 000000000..fc3de1ccc --- /dev/null +++ b/site/client/src/data/defaultEditorValue.ts @@ -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 + } + } + ] + } + } + }`; diff --git a/site/client/src/data/editorModule.ts b/site/client/src/data/editorModule.ts new file mode 100644 index 000000000..3ab885424 --- /dev/null +++ b/site/client/src/data/editorModule.ts @@ -0,0 +1,2 @@ +import '@yandex-portal/divkit-editor/dist/divkit-editor.css'; +export { DivProEditor } from '@yandex-portal/divkit-editor'; diff --git a/site/client/src/data/languageContext.ts b/site/client/src/data/languageContext.ts index 3e7a07335..acdb8df56 100644 --- a/site/client/src/data/languageContext.ts +++ b/site/client/src/data/languageContext.ts @@ -4,7 +4,7 @@ import type lang from '../auto/lang.json'; export const LANGUAGE_CTX = Symbol('language'); export interface LanguageContext { - lang: Readable; + lang: Readable<'ru' | 'en'>; getLanguage(): string; setLanguage(name: string): void; languagesList(): string[]; diff --git a/site/client/src/data/session.ts b/site/client/src/data/session.ts index f58a5bc60..f9798454a 100644 --- a/site/client/src/data/session.ts +++ b/site/client/src/data/session.ts @@ -10,3 +10,5 @@ export const isInitialLoading = writable(false); export const isLoadError = writable(false); export const isSamples = writable(false); + +export const isDesign = writable(false); diff --git a/site/client/src/data/sessionController.ts b/site/client/src/data/sessionController.ts index edc9d00e9..7878e27b5 100644 --- a/site/client/src/data/sessionController.ts +++ b/site/client/src/data/sessionController.ts @@ -1,6 +1,6 @@ import { get } from 'svelte/store'; 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 { clientHostPath, serverHostPath } from '../utils/const'; import { savedStore } from './savedStore'; @@ -10,6 +10,7 @@ import { jsonStore } from './jsonStore'; // import { addListener, wsPromise } from './ws'; // import { listenToDevices } from './externalViewers'; import { getLs, setLs } from '../utils/localStorage'; +import { DEFAULT_EDITOR_VALUE } from './defaultEditorValue'; /* function listenJsonForPreview(uuid: string): void { wsPromise.then(ws => { @@ -35,9 +36,13 @@ async function init() { const uuid = params.get('uuid'); // mode = params.get('mode') || ''; + const design = params.get('design') === '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); } @@ -134,8 +139,10 @@ function unsavedPrompt(event: BeforeUnloadEvent) { } async function genLinks(uuid: string) { + const isEditor = get(isDesign); + return { - linkToEdit: `${location.protocol}//${clientHostPath}?uuid=${uuid}`, + linkToEdit: `${location.protocol}//${clientHostPath}?uuid=${uuid}${isEditor ? '&design=1' : ''}`, linkToPreview: `${location.protocol}//${clientHostPath}?uuid=${uuid}&mode=preview`, linkToJSON: `${location.protocol}//${serverHostPath}api/json?uuid=${uuid}` }; @@ -190,4 +197,4 @@ export async function save() { } } -init(); +export const initPromise = init();