GrapesJS / grapesjs

Free and Open source Web Builder Framework. Next generation tool for building templates without coding
https://grapesjs.com
BSD 3-Clause "New" or "Revised" License
22.36k stars 4.05k forks source link

BUG: Target :null when adding video #3806

Closed throne1986 closed 2 years ago

throne1986 commented 3 years ago

GrapesJS version

What browser are you using?

chrome new version

Reproducible demo link

https://codesandbox.io/s/react-redux-toolkit-application-forked-l5rhp?file=/src/pages/Editor.js

Describe the bug

How to reproduce the bug?

  1. Drag and drop the video to canvas area from block manager
  2. Try to add video on the modal by hovering the video and click the button use video

What is the expected behavior? When the user hovers a video and clicks use video button it should add a video to the video tag in a canvas

What is the current behavior? When the user hovers on a video in a modal and clicks use video button the video is not added at all and on console it shows target: null

If is necessary to execute some code in order to reproduce the bug, paste it here below: here is grapes js editor code, full code can be found here https://codesandbox.io/s/react-redux-toolkit-application-forked-l5rhp?file=/src/pages/Editor.js:715-4094


  useEffect(() => {
    const editor = grapesjs.init({
      container: "#editor",
      storageManager: false,
      blockManager: true,
      plugins: [block]
    });

    editor.on("component:create", (model) => {
      if (model.get("type") === "video") {
        setAddVideo(false);
        console.log("video url.", videos.videoUrl);
        editor.Commands.run("open-assets", {
          target: editor.getSelected(),
          url: videos.videoUrl
        });
      }
    });

    editor.DomComponents.addType("video", {
      model: {
        defaults: {
          tagName: "video",
          autoplay: true,
          loop: true,
          muted: true,
          controls: false,
          poster: "poster.png",
          src: "",
          draggable: true,
          removable: true,
          copyable: true,
          resizable: true,
          stylable: [],
          traits: []
        },
        init() {
          console.debug("video - model - init");
        },
        updated(property, value) {
          if (property === "src") this.set("src", value);
        }
      },
      view: {
        events: {
          dblclick: "onActive"
        },
        init() {
          console.debug("video - view - init");
          const { model } = this;

          const props = [
            "loop",
            "autoplay",
            "controls",
            "color",
            "rel",
            "modestbranding",
            "poster"
          ];
          const events = props.map((p) => `change:${p}`).join(" ");

          this.listenTo(model, "change:src", this.updateSrc);
          this.listenTo(model, events, this.updateVideo);
        },
        onRender() {
          console.debug("video - view - onRender");

          this.updateVideo();
        },
        updateVideo() {
          const { model, el } = this;

          el.loop = model.get("loop");
          el.autoplay = model.get("autoplay");
          el.controls = model.get("controls");
          el.poster = model.get("poster");
        },
        updateSrc() {
          console.debug("video - view - updateSrc");

          const { model, el } = this;
          if (!el) return;

          let src = model.get("src");
          el.src = src;
        },
        onActive(e) {
          console.debug("video - view - onActive");

          editor.runCommand("open-assets", {
            target: this.model,
            types: ["videos"],
            accept: "video/*",
            onSelect() {
              console.debug("video - upload - onSelect");
              editor.Modal.close();
              editor.AssetManager.setTarget(null);
            }
          });

          e.stopPropagation();
        }
      }
    });

    setEditor(editor);
  }, [dispatch]);

  if (editor) {
    editor.Commands.add("open-assets", {
      run(editor, sender, opts = {}) {
        dispatch(setIsOpen(true));
        console.log("opts", opts);
        console.log("opts url", opts.url);
        if (addVideo) {
          opts.target.set("src", opts.url);
          if (opts.url) {
            dispatch(setIsOpen(false));
          }
        }
      }
    });
  }
  const handleUseVideo = (video) => {
    console.log("video..", video);
    setAddVideo(true);
    dispatch(setVideoUrl(video));
    editor.Commands.run("open-assets", {
      target: editor.getSelected(),
      url: video
    });
  };

@artf I am out of ideas and I need help

Code of Conduct

throne1986 commented 2 years ago

@artf can you please help me with this?

artf commented 2 years ago

The issue is here

editor.on("component:create", (model) => {
      if (model.get("type") === "video") {
        setAddVideo(false);
        console.log("video url.", videos.videoUrl);
        editor.Commands.run("open-assets", {
          // target: editor.getSelected(), // <- when you drop the video, is not selected
          target: model,
          url: videos.videoUrl
        });
      }
    });

You can also remove that global listener and update the video Block with activate: true, way more cleaner.

throne1986 commented 2 years ago

The issue is here

editor.on("component:create", (model) => {
      if (model.get("type") === "video") {
        setAddVideo(false);
        console.log("video url.", videos.videoUrl);
        editor.Commands.run("open-assets", {
          // target: editor.getSelected(), // <- when you drop the video, is not selected
          target: model,
          url: videos.videoUrl
        });
      }
    });

You can also remove that global listener and update the video Block with activate: true, way more cleaner.

Hi @artf changing as u suggested but still when I drag the video block and select a video I see on a console that the target is null meaning I cant set the selected video url like this opts.target.set("src", opts.url);

Here is updated codesanbox https://codesandbox.io/s/react-redux-toolkit-application-forked-l5rhp?file=/src/pages/Editor.js:4197-4230 u can try yourself by draging the video to canvas after the modal will open with list of movies just select a video by clicking the button use video on hover any listed video on modaL

image

@artf can you help me with this?

artf commented 2 years ago

@throne1986 you still have this... Schermata 2021-11-03 alle 14 30 02

throne1986 commented 2 years ago

@throne1986 you still have this... Schermata 2021-11-03 alle 14 30 02

Thanks I solved the problem by adding editor.selectAdd(model); like this below

editor.on("component:create", (model) => { if (model.get("type") === "video") { editor.selectAdd(model); } });

Thanks