From ff5ae52cfd6dce6eadc149932189c500f3d24987 Mon Sep 17 00:00:00 2001 From: Botho <1258870+elbotho@users.noreply.github.com> Date: Tue, 5 Nov 2024 22:43:08 +0100 Subject: [PATCH 1/4] refactor(editor): broaden scope of cariant context to EditorMetaContext --- .../editor/src/core/contexts/editor-meta-context.tsx | 10 ++++++++++ .../src/core/contexts/editor-variant-context.tsx | 4 ---- packages/editor/src/package/editor.tsx | 7 +++---- packages/editor/src/plugins/image/utils/upload-file.ts | 6 +++--- 4 files changed, 16 insertions(+), 11 deletions(-) create mode 100644 packages/editor/src/core/contexts/editor-meta-context.tsx delete mode 100644 packages/editor/src/core/contexts/editor-variant-context.tsx diff --git a/packages/editor/src/core/contexts/editor-meta-context.tsx b/packages/editor/src/core/contexts/editor-meta-context.tsx new file mode 100644 index 0000000000..9e6b1a0555 --- /dev/null +++ b/packages/editor/src/core/contexts/editor-meta-context.tsx @@ -0,0 +1,10 @@ +import type { EditorVariant } from '@editor/package/storage-format' +import { createContext } from 'react' + +interface EditorMeta { + variant: EditorVariant +} + +export const EditorMetaContext = createContext({ + variant: 'unknown', +}) diff --git a/packages/editor/src/core/contexts/editor-variant-context.tsx b/packages/editor/src/core/contexts/editor-variant-context.tsx deleted file mode 100644 index 11f78bf50b..0000000000 --- a/packages/editor/src/core/contexts/editor-variant-context.tsx +++ /dev/null @@ -1,4 +0,0 @@ -import type { EditorVariant } from '@editor/package/storage-format' -import { createContext } from 'react' - -export const EditorVariantContext = createContext('unknown') diff --git a/packages/editor/src/package/editor.tsx b/packages/editor/src/package/editor.tsx index 924a45ef05..03ed5b97a0 100644 --- a/packages/editor/src/package/editor.tsx +++ b/packages/editor/src/package/editor.tsx @@ -1,5 +1,5 @@ import { Editor, type EditorProps } from '@editor/core' -import { EditorVariantContext } from '@editor/core/contexts/editor-variant-context' +import { EditorMetaContext } from '@editor/core/contexts/editor-meta-context' import { type GetDocument } from '@editor/core/types' import { createBasicPlugins } from '@editor/editor-integration/create-basic-plugins' import { createRenderers } from '@editor/editor-integration/create-renderers' @@ -23,7 +23,6 @@ import { type EditorVariant, } from './storage-format' -// TODO: figure out styling // eslint-disable-next-line import/no-unassigned-import import '../tailwind/editor.css' @@ -76,7 +75,7 @@ export function SerloEditor(props: SerloEditorProps) { return ( - + {isProductionEnvironment ? null : renderTestEnvironmentWarning()} - + ) diff --git a/packages/editor/src/plugins/image/utils/upload-file.ts b/packages/editor/src/plugins/image/utils/upload-file.ts index d3b74b5676..6927456903 100644 --- a/packages/editor/src/plugins/image/utils/upload-file.ts +++ b/packages/editor/src/plugins/image/utils/upload-file.ts @@ -1,4 +1,4 @@ -import { EditorVariantContext } from '@editor/core/contexts/editor-variant-context' +import { EditorMetaContext } from '@editor/core/contexts/editor-meta-context' import { type EditorVariant } from '@editor/package/storage-format' import { type UploadHandler } from '@editor/plugin' import { useContext } from 'react' @@ -6,9 +6,9 @@ import { useContext } from 'react' import { handleError, validateFile } from './validate-file' export function useUploadFile(oldFileUploader: UploadHandler) { - const editorVariant = useContext(EditorVariantContext) + const { variant } = useContext(EditorMetaContext) return shouldUseNewUpload() - ? (file: File) => uploadFile(file, editorVariant) + ? (file: File) => uploadFile(file, variant) : oldFileUploader } From 3d52d54625b5b8883a7527529b3bc733351843b4 Mon Sep 17 00:00:00 2001 From: Botho <1258870+elbotho@users.noreply.github.com> Date: Tue, 5 Nov 2024 23:01:05 +0100 Subject: [PATCH 2/4] refactor(editor): add userId to context and use in upload --- .../src/core/contexts/editor-meta-context.tsx | 7 +-- packages/editor/src/package/editor.tsx | 2 +- .../src/plugins/image/utils/upload-file.ts | 46 +++++++++++++------ 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/packages/editor/src/core/contexts/editor-meta-context.tsx b/packages/editor/src/core/contexts/editor-meta-context.tsx index 9e6b1a0555..8b988ae20f 100644 --- a/packages/editor/src/core/contexts/editor-meta-context.tsx +++ b/packages/editor/src/core/contexts/editor-meta-context.tsx @@ -1,10 +1,11 @@ import type { EditorVariant } from '@editor/package/storage-format' import { createContext } from 'react' -interface EditorMeta { - variant: EditorVariant +export interface EditorMeta { + editorVariant: EditorVariant + userId?: string } export const EditorMetaContext = createContext({ - variant: 'unknown', + editorVariant: 'unknown', }) diff --git a/packages/editor/src/package/editor.tsx b/packages/editor/src/package/editor.tsx index 03ed5b97a0..2b5eefb898 100644 --- a/packages/editor/src/package/editor.tsx +++ b/packages/editor/src/package/editor.tsx @@ -75,7 +75,7 @@ export function SerloEditor(props: SerloEditorProps) { return ( - + {isProductionEnvironment ? null : renderTestEnvironmentWarning()} ) { - const { variant } = useContext(EditorMetaContext) - return shouldUseNewUpload() - ? (file: File) => uploadFile(file, variant) - : oldFileUploader +type UploadMeta = Pick + +export function useUploadFile(oldUploader: UploadHandler) { + const { editorVariant, userId } = useContext(EditorMetaContext) + + const uploader = (file: File) => uploadFile({ file, editorVariant, userId }) + return shouldUseNewUpload() ? uploader : oldUploader } // while testing @@ -30,11 +34,21 @@ export function shouldUseNewUpload() { return isDevOrPreviewOrStaging } -export async function uploadFile(file: File, editorVariant: EditorVariant) { +async function uploadFile({ + file, + editorVariant, + userId, +}: UploadMeta & { + file: File +}) { const validated = validateFile(file) if (!validated) return Promise.reject() - const data = await getSignedUrlAndSrc(file.type, editorVariant) + const data = await getSignedUrlAndSrc({ + mimeType: file.type, + editorVariant, + userId, + }) if (!data) return Promise.reject('Could not get signed URL') const { signedUrl, imgSrc } = data @@ -49,11 +63,15 @@ const signedUrlHost = ? 'editor.serlo.dev' : 'editor.serlo.dev' // TODO: Change to production bucket after testing -async function getSignedUrlAndSrc( - mimeType: string, - editorVariant: EditorVariant -) { - const url = `https://${signedUrlHost}/media/presigned-url?mimeType=${encodeURIComponent(mimeType)}&editorVariant=${encodeURIComponent(editorVariant)}` +async function getSignedUrlAndSrc({ + mimeType, + editorVariant, + userId, +}: UploadMeta & { + mimeType: string +}) { + const params = `mimeType=${encodeURIComponent(mimeType)}&editorVariant=${encodeURIComponent(editorVariant)}&userId=${encodeURIComponent(userId ?? '')}` + const url = `https://${signedUrlHost}/media/presigned-url?${params}` const result = await fetch(url).catch((e) => { // eslint-disable-next-line no-console From e30695057bb8a174758f1edcf983814e4b90e89f Mon Sep 17 00:00:00 2001 From: Botho <1258870+elbotho@users.noreply.github.com> Date: Tue, 5 Nov 2024 23:13:08 +0100 Subject: [PATCH 3/4] refactor(editor): move ltik into EditorMetaContext --- .../src/core/contexts/editor-meta-context.tsx | 1 + packages/editor/src/package/editor.tsx | 23 ++++++++++--------- .../editor/src/package/serlo-renderer.tsx | 6 ++--- .../src/plugins/edusharing-asset/editor.tsx | 4 ++-- .../plugins/edusharing-asset/ltik-context.ts | 3 --- .../src/plugins/edusharing-asset/static.tsx | 4 ++-- 6 files changed, 20 insertions(+), 21 deletions(-) delete mode 100644 packages/editor/src/plugins/edusharing-asset/ltik-context.ts diff --git a/packages/editor/src/core/contexts/editor-meta-context.tsx b/packages/editor/src/core/contexts/editor-meta-context.tsx index 8b988ae20f..b6bf17e25e 100644 --- a/packages/editor/src/core/contexts/editor-meta-context.tsx +++ b/packages/editor/src/core/contexts/editor-meta-context.tsx @@ -4,6 +4,7 @@ import { createContext } from 'react' export interface EditorMeta { editorVariant: EditorVariant userId?: string + ltik?: string } export const EditorMetaContext = createContext({ diff --git a/packages/editor/src/package/editor.tsx b/packages/editor/src/package/editor.tsx index 2b5eefb898..519c3c4ef0 100644 --- a/packages/editor/src/package/editor.tsx +++ b/packages/editor/src/package/editor.tsx @@ -7,7 +7,6 @@ import { EditStringsProvider } from '@editor/i18n/edit-strings-provider' import { StaticStringsProvider } from '@editor/i18n/static-strings-provider' import { editorPlugins } from '@editor/plugin/helpers/editor-plugins' import { editorRenderers } from '@editor/plugin/helpers/editor-renderer' -import { LtikContext } from '@editor/plugins/edusharing-asset/ltik-context' import { EditorPluginType } from '@editor/types/editor-plugin-type' import { SupportedLanguage } from '@editor/types/language-data' import { TemplatePluginType } from '@editor/types/template-plugin-type' @@ -34,6 +33,7 @@ export interface SerloEditorProps { language?: SupportedLanguage editorVariant: EditorVariant isProductionEnvironment?: boolean + userId?: string _testingSecret?: string | null _ltik?: string } @@ -47,6 +47,7 @@ export function SerloEditor(props: SerloEditorProps) { language, plugins, isProductionEnvironment, + userId, _testingSecret, _ltik, } = { @@ -75,16 +76,16 @@ export function SerloEditor(props: SerloEditorProps) { return ( - - - {isProductionEnvironment ? null : renderTestEnvironmentWarning()} - - {children} - - + + {isProductionEnvironment ? null : renderTestEnvironmentWarning()} + + {children} + diff --git a/packages/editor/src/package/serlo-renderer.tsx b/packages/editor/src/package/serlo-renderer.tsx index 35dec7295d..3c9ef5f7d3 100644 --- a/packages/editor/src/package/serlo-renderer.tsx +++ b/packages/editor/src/package/serlo-renderer.tsx @@ -1,8 +1,8 @@ +import { EditorMetaContext } from '@editor/core/contexts/editor-meta-context' import { createRenderers } from '@editor/editor-integration/create-renderers' import { EditStringsProvider } from '@editor/i18n/edit-strings-provider' import { StaticStringsProvider } from '@editor/i18n/static-strings-provider' import { editorRenderers } from '@editor/plugin/helpers/editor-renderer' -import { LtikContext } from '@editor/plugins/edusharing-asset/ltik-context' import { StaticRenderer } from '@editor/static-renderer/static-renderer' import type { SupportedLanguage } from '@editor/types/language-data' @@ -37,14 +37,14 @@ export function SerloRenderer(props: SerloRendererProps) { return ( - +
-
+
) diff --git a/packages/editor/src/plugins/edusharing-asset/editor.tsx b/packages/editor/src/plugins/edusharing-asset/editor.tsx index 242968c19b..0af5b0383f 100644 --- a/packages/editor/src/plugins/edusharing-asset/editor.tsx +++ b/packages/editor/src/plugins/edusharing-asset/editor.tsx @@ -1,10 +1,10 @@ +import { EditorMetaContext } from '@editor/core/contexts/editor-meta-context' import { useEditStrings } from '@editor/i18n/edit-strings-provider' import * as t from 'io-ts' import { useContext, useEffect, useRef, useState } from 'react' import Modal from 'react-modal' import type { EdusharingAssetProps } from '.' -import { LtikContext } from './ltik-context' import { EdusharingAssetRenderer } from './renderer' import { PluginToolbar } from '../../editor-ui/plugin-toolbar' import { PluginDefaultTools } from '../../editor-ui/plugin-toolbar/plugin-tool-menu/plugin-default-tools' @@ -52,7 +52,7 @@ export function EdusharingAssetEditor({ return () => window.removeEventListener('message', handleIFrameEvent) }, [state.edusharingAsset]) - const ltik = useContext(LtikContext) + const { ltik } = useContext(EditorMetaContext) if (!ltik) return

Error: ltik missing

return ( diff --git a/packages/editor/src/plugins/edusharing-asset/ltik-context.ts b/packages/editor/src/plugins/edusharing-asset/ltik-context.ts deleted file mode 100644 index 7c63be4249..0000000000 --- a/packages/editor/src/plugins/edusharing-asset/ltik-context.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { createContext } from 'react' - -export const LtikContext = createContext(undefined) diff --git a/packages/editor/src/plugins/edusharing-asset/static.tsx b/packages/editor/src/plugins/edusharing-asset/static.tsx index c052826be8..81c866be28 100644 --- a/packages/editor/src/plugins/edusharing-asset/static.tsx +++ b/packages/editor/src/plugins/edusharing-asset/static.tsx @@ -1,7 +1,7 @@ +import { EditorMetaContext } from '@editor/core/contexts/editor-meta-context' import { EditorEdusharingAssetDocument } from '@editor/types/editor-plugins' import { useContext } from 'react' -import { LtikContext } from './ltik-context' import { EdusharingAssetRenderer } from './renderer' export function EdusharingAssetStaticRenderer( @@ -12,7 +12,7 @@ export function EdusharingAssetStaticRenderer( const { contentWidth: widthInPercent } = props.state - const ltik = useContext(LtikContext) + const { ltik } = useContext(EditorMetaContext) if (!ltik) return null From 056d32fef012639af2a65297b031ff89223fad16 Mon Sep 17 00:00:00 2001 From: Botho <1258870+elbotho@users.noreply.github.com> Date: Tue, 5 Nov 2024 23:27:05 +0100 Subject: [PATCH 4/4] feat(frontend): add EditorMetaContext to frontend --- apps/web/src/pages/___editor_preview.tsx | 117 +++++++++--------- .../serlo-editor-integration/serlo-editor.tsx | 31 +++-- 2 files changed, 80 insertions(+), 68 deletions(-) diff --git a/apps/web/src/pages/___editor_preview.tsx b/apps/web/src/pages/___editor_preview.tsx index a887ed7f28..d8c5f5e66c 100644 --- a/apps/web/src/pages/___editor_preview.tsx +++ b/apps/web/src/pages/___editor_preview.tsx @@ -1,3 +1,4 @@ +import { EditorMetaContext } from '@editor/core/contexts/editor-meta-context' import { EditStringsProvider } from '@editor/i18n/edit-strings-provider' import { editStrings as editStringsDe } from '@editor/i18n/strings/de/edit' import { editStrings as editStringsEn } from '@editor/i18n/strings/en/edit' @@ -100,64 +101,68 @@ function Content() { : editStringsEn } > -
-
-
-

Edit

-
- { - const pastedString = clipboardData - .getData('text/plain') - .trim() - const cleanJsonString = pastedString - .replace(/'/g, '') - .replace(/\\"/g, '"') + +
+
+
+

Edit

+
+ { + const pastedString = clipboardData + .getData('text/plain') + .trim() + const cleanJsonString = pastedString + .replace(/'/g, '') + .replace(/\\"/g, '"') - try { - const jsonObject = JSON.parse( - cleanJsonString - ) as AnyEditorDocument - setPreviewState(JSON.stringify(jsonObject)) - } catch (error) { - // eslint-disable-next-line no-console - console.error('Error parsing JSON:', error) - showToastNotice('sorry, invalid json', 'warning') - } - }} - className="mt-0.5 w-20 bg-gray-100 text-sm" - placeholder="paste json" - /> - {' | '} - {' '} - |{' '} - + try { + const jsonObject = JSON.parse( + cleanJsonString + ) as AnyEditorDocument + setPreviewState(JSON.stringify(jsonObject)) + } catch (error) { + // eslint-disable-next-line no-console + console.error('Error parsing JSON:', error) + showToastNotice('sorry, invalid json', 'warning') + } + }} + className="mt-0.5 w-20 bg-gray-100 text-sm" + placeholder="paste json" + /> + {' | '} + {' '} + |{' '} + +
+
+
{editor}
+
+
+

+ Preview +

+
+
-
-
{editor}
-
-
-

- Preview -

-
- -
-
-
+ + + ) } diff --git a/apps/web/src/serlo-editor-integration/serlo-editor.tsx b/apps/web/src/serlo-editor-integration/serlo-editor.tsx index e2d3e88ba5..555e035c43 100644 --- a/apps/web/src/serlo-editor-integration/serlo-editor.tsx +++ b/apps/web/src/serlo-editor-integration/serlo-editor.tsx @@ -1,4 +1,5 @@ import { type EditorProps } from '@editor/core' +import { EditorMetaContext } from '@editor/core/contexts/editor-meta-context' import { EditStringsProvider } from '@editor/i18n/edit-strings-provider' import { editStrings as editStringsDe } from '@editor/i18n/strings/de/edit' import { editStrings as editStringsEn } from '@editor/i18n/strings/en/edit' @@ -18,6 +19,7 @@ import { SaveButton } from './components/save-button' import { createPlugins } from './create-plugins' import { createRenderers } from './create-renderers' import { useSerloHandleLearnerEvent } from './use-handle-learner-event' +import { useAuthentication } from '@/auth/use-authentication' import { useInstanceData } from '@/contexts/instance-context' import type { SetEntityMutationData } from '@/mutations/use-set-entity-mutation/types' @@ -39,6 +41,7 @@ export function SerloEditor({ children, }: SerloEditorProps) { const { lang, licenses } = useInstanceData() + const auth = useAuthentication() const handleLearnerEvent = useSerloHandleLearnerEvent() @@ -57,20 +60,24 @@ export function SerloEditor({ return ( - - - - {isNewEntity ? ( - - ) : null} + + + + {isNewEntity ? ( + + ) : null} - {children} - - + {children} + + + ) }