Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Media library button appends image to the end #17

Closed
jkomkin opened this issue Jun 24, 2022 · 7 comments · Fixed by #21
Closed

Media library button appends image to the end #17

jkomkin opened this issue Jun 24, 2022 · 7 comments · Fixed by #21

Comments

@jkomkin
Copy link

jkomkin commented Jun 24, 2022

When using the Strapi media library button the image always gets appended at the end of the content instead of where the mouse cursor/caret is.

Strapi 4.2.0

@emmarvpol
Copy link
Contributor

emmarvpol commented Jun 27, 2022

Same problem here. I had to modify the following file:
/node_modules/@_sh/strapi-plugin-ckeditor/admin/src/components/CKEditor/index.js

Is working pretty well for me. If you want give it a try.

Replace the content of this file with the following one (updated):

import React, { useEffect, useState } from "react";
import { auth, prefixFileUrlWithBackendUrl, request } from "@strapi/helper-plugin";
import styled, { createGlobalStyle } from "styled-components";

import { Box } from "@strapi/design-system/Box";
import { CKEditor } from "@ckeditor/ckeditor5-react";
import { Editor as CustomClassicEditor } from "./build/ckeditor";
import MediaLib from "../MediaLib";
import PropTypes from "prop-types";
import pluginId from "../../pluginId";
import styles from "./styles";
import theme from "./theme";

const EditorStyle = createGlobalStyle`
${styles}
${({ strapiTheme }) => strapiTheme}
${({ custom }) => custom}

.ck-editor__styled__container{
	position: relative;
	width:100%;
}
`;
const Wrapper = styled(Box)``;

const Editor = ({ onChange, name, value, disabled }) => {
  //####### strapi media lib connector #############################################################################################
  const [mediaLibVisible, setMediaLibVisible] = useState(false);
  const [editor, setEditor] = useState();

  const toggleMediaLib = (editor) => {
    if (editor) {
      setEditor(editor);
    }
    setMediaLibVisible((prev) => !prev);
  };

  const handleChangeAssets = (assets) => {
    let newValue = "";

    assets.map((asset) => {
      if (asset.mime.includes("image")) {
        if (uploadCfg?.responsiveDimensions) {
          let set = "";
          let keys = Object.keys(asset.formats).sort((a, b) => {
            return asset.formats[a].width - asset.formats[b].width;
          });
          keys?.map((k) => {
            let str =
              prefixFileUrlWithBackendUrl(asset.formats[k].url) + ` ${asset.formats[k].width}w,`;
            set = set + str;
          });
          const imgTag = `<img src="${asset.url}" alt="${asset.alt}" srcset="${set}"></img>`;
          newValue = `${newValue}${imgTag}`;
        } else {
          const imgTag = `<img src="${asset.url}" alt="${asset.alt}"></img>`;
          newValue = `${newValue}${imgTag}`;
        }
      }
      // Handle videos and other type of files by adding some code
    });

    const viewFragment = editor.data.processor.toView( newValue );
    const modelFragment = editor.data.toModel( viewFragment );
    editor.model.insertContent( modelFragment );
    
    toggleMediaLib();
  };

  //####### config #############################################################################################
  const [config, setConfig] = useState();
  const [pluginCfg, setPluginCfg] = useState({});
  const [uploadCfg, setUploadCfg] = useState();
  const uploadUrl = `${prefixFileUrlWithBackendUrl("/upload")}`;
  const headers = { Authorization: "Bearer " + auth.getToken() };
  useEffect(() => {
    // load the editor config
    (async () => {
      const editor = await request(`/${pluginId}/config/editor`, { method: "GET" });
      const plugin = await request(`/${pluginId}/config/plugin`, { method: "GET" });
      const upload = await request(`/${pluginId}/config/uploadcfg`, { method: "GET" });

      if (editor) {
        setConfig({
          ...config,
          editor: {
            ...editor,
            language: editor.language ? editor.language : auth.getUserInfo().preferedLanguage,
            strapiMediaLib: {
              onToggle: toggleMediaLib,
              label: "Media library",
            },
            strapiUpload: {
              uploadUrl,
              headers,
            },
          },
        });

        if (editor.language) {
          if (editor.language.ui) {
            import(
              /* webpackMode: "eager" */ `./build/translations/${editor.language.ui}.js`
            ).catch(() => null);
          }
          if (editor.language.content) {
            import(
              /* webpackMode: "eager" */ `./build/translations/${editor.language.content}.js`
            ).catch(() => null);
          }
          if (typeof editor.language !== "object") {
            import(/* webpackMode: "eager" */ `./build/translations/${editor.language}.js`).catch(
              () => null
            );
          }
        }
        if (!editor.language) {
          import(
            /* webpackMode: "eager" */ `./build/translations/${
              auth.getUserInfo().preferedLanguage
            }.js`
          ).catch(() => null);
        }
      }
      if (plugin) {
        setPluginCfg({
          ...pluginCfg,
          ...plugin,
        });
        if (plugin.setAttribute !== false && localStorage.getItem("STRAPI_THEME")) {
          document.documentElement.setAttribute("data-theme", localStorage.getItem("STRAPI_THEME"));
        }
      }
      if (upload) {
        setUploadCfg({
          ...uploadCfg,
          ...upload,
        });
      }
    })();

    return () => {};
  }, []);

  //###########################################################################################################

   return (
    <Wrapper className="ck-editor__styled__container">
      <EditorStyle
        custom={pluginCfg.styles}
        strapiTheme={pluginCfg.strapiTheme !== false ? theme : ""}
      />
      {config && (
        <CKEditor
          editor={CustomClassicEditor}
          disabled={disabled}
          data={value || ""}
          onReady={(editor) => editor.setData(value || "")}
          onChange={(event, editor) => {
            setEditor(editor)
            const data = editor.getData();
            onChange({ target: { name, value: data } });
          }}
          
          config={config?.editor}
        />
      )}
      <MediaLib isOpen={mediaLibVisible} onChange={handleChangeAssets} onToggle={toggleMediaLib} />
    </Wrapper>
  );
};

Editor.defaultProps = {
  value: "",
  disabled: false,
};

Editor.propTypes = {
  onChange: PropTypes.func.isRequired,
  name: PropTypes.string.isRequired,
  value: PropTypes.string,
  disabled: PropTypes.bool,
};

export default Editor;

@emmarvpol
Copy link
Contributor

@jkomkin
I updated the code. Try the new one.

@jkomkin
Copy link
Author

jkomkin commented Jun 27, 2022

@jkomkin I updated the code. Try the new one.

@emmarvpol
The previous snippet worked fine too! Thanks.
I think this should be added to main repo.

@emmarvpol
Copy link
Contributor

I tested the previous again and I realize that the image is added at the top!

@jkomkin
Copy link
Author

jkomkin commented Jul 14, 2022

Maybe @emmarvpol can create a PR please, so that @nshenderov can merge into main?

@emmarvpol
Copy link
Contributor

@jkomkin Ok, I'll do it today!

@emmarvpol
Copy link
Contributor

emmarvpol commented Jul 15, 2022

@jkomkin I did the PR #21

@nshenderov nshenderov linked a pull request Jul 22, 2022 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants