Jelajahi Sumber

avoid run_method before mounting interactive image

Falko Schindler 3 tahun lalu
induk
melakukan
9345348bc4
2 mengubah file dengan 35 tambahan dan 19 penghapusan
  1. 28 15
      nicegui/elements/interactive_image.js
  2. 7 4
      nicegui/elements/interactive_image.py

+ 28 - 15
nicegui/elements/interactive_image.js

@@ -13,29 +13,29 @@ Vue.component("interactive_image", {
   `,
   mounted() {
     comp_dict[this.$props.jp_props.id] = this;
-    const image = document.getElementById(this.$props.jp_props.id).firstChild;
+    this.image = document.getElementById(this.$props.jp_props.id).firstChild;
     const handle_completion = () => {
       if (this.waiting_source) {
-        image.src = this.waiting_source;
+        this.image.src = this.waiting_source;
         this.waiting_source = undefined;
       } else {
         this.loading = false;
       }
     };
-    image.addEventListener("load", handle_completion);
-    image.addEventListener("error", handle_completion);
+    this.image.addEventListener("load", handle_completion);
+    this.image.addEventListener("error", handle_completion);
     const svg = document.getElementById(this.$props.jp_props.id).lastChild;
     const cross = svg.firstChild;
-    image.ondragstart = () => false;
+    this.image.ondragstart = () => false;
     if (this.$props.jp_props.options.cross) {
-      image.style.cursor = "none";
-      image.addEventListener("mouseenter", (e) => {
+      this.image.style.cursor = "none";
+      this.image.addEventListener("mouseenter", (e) => {
         cross.style.display = "block";
       });
-      image.addEventListener("mouseleave", (e) => {
+      this.image.addEventListener("mouseleave", (e) => {
         cross.style.display = "none";
       });
-      image.addEventListener("mousemove", (e) => {
+      this.image.addEventListener("mousemove", (e) => {
         const x = (e.offsetX * e.target.naturalWidth) / e.target.clientWidth;
         const y = (e.offsetY * e.target.naturalHeight) / e.target.clientHeight;
         cross.firstChild.setAttribute("x1", x);
@@ -44,13 +44,13 @@ Vue.component("interactive_image", {
         cross.lastChild.setAttribute("y2", y);
       });
     }
-    image.onload = (e) => {
-      const viewBox = `0 0 ${image.naturalWidth} ${image.naturalHeight}`;
+    this.image.onload = (e) => {
+      const viewBox = `0 0 ${this.image.naturalWidth} ${this.image.naturalHeight}`;
       svg.setAttribute("viewBox", viewBox);
     };
-    image.src = this.$props.jp_props.options.source;
+    this.image.src = this.$props.jp_props.options.source;
     for (const type of this.$props.jp_props.options.events) {
-      image.addEventListener(type, (e) => {
+      this.image.addEventListener(type, (e) => {
         const event = {
           event_type: "onMouse",
           mouse_event_type: type,
@@ -64,6 +64,20 @@ Vue.component("interactive_image", {
         send_to_server(event, "event");
       });
     }
+
+    const sendConnectEvent = () => {
+      if (websocket_id === "") return;
+      const event = {
+        event_type: "onConnect",
+        vue_type: this.$props.jp_props.vue_type,
+        id: this.$props.jp_props.id,
+        page_id: page_id,
+        websocket_id: websocket_id,
+      };
+      send_to_server(event, "event");
+      clearInterval(connectInterval);
+    };
+    const connectInterval = setInterval(sendConnectEvent, 100);
   },
   methods: {
     set_source(source) {
@@ -72,8 +86,7 @@ Vue.component("interactive_image", {
         return;
       }
       this.loading = true;
-      image = document.getElementById(this.$props.jp_props.id).firstChild;
-      image.src = source;
+      this.image.src = source;
     },
   },
   props: {

+ 7 - 4
nicegui/elements/interactive_image.py

@@ -1,5 +1,4 @@
 from __future__ import annotations
-from justpy import WebPage
 from typing import Any, Callable, Dict, Optional
 import traceback
 from ..events import MouseEventArguments, handle_event
@@ -12,8 +11,12 @@ class InteractiveImageView(CustomView):
 
     def __init__(self, source: str, on_mouse: Callable, events: list[str], cross: bool):
         super().__init__('interactive_image', source=source, events=events, cross=cross, svg_content='')
-        self.allowed_events = ['onMouse']
-        self.initialize(onMouse=on_mouse)
+        self.allowed_events = ['onMouse', 'onConnect']
+        self.initialize(onMouse=on_mouse, onConnect=self.on_connect)
+        self.sockets = []
+
+    def on_connect(self, msg):
+        self.sockets.append(msg.websocket)
 
 class InteractiveImage(Element):
 
@@ -47,7 +50,7 @@ class InteractiveImage(Element):
 
     async def set_source(self, source: str):
         self.view.options.source = source
-        for socket in WebPage.sockets.get(self.page.page_id, {}).values():
+        for socket in self.view.sockets:
             await self.view.run_method(f'set_source("{source}")', socket)
 
     @property