浏览代码

update ui.upload

Falko Schindler 2 年之前
父节点
当前提交
3d2e3ad143
共有 6 个文件被更改,包括 94 次插入51 次删除
  1. 2 2
      api_docs_and_examples.py
  2. 0 47
      nicegui/elements/old/upload.py
  3. 42 0
      nicegui/elements/upload.py
  4. 39 0
      nicegui/elements/upload.vue
  5. 10 2
      nicegui/events.py
  6. 1 0
      nicegui/ui.py

+ 2 - 2
api_docs_and_examples.py

@@ -206,9 +206,9 @@ def create_full() -> None:
         picker = ui.color_picker(on_pick=lambda e: button.style(f'background-color:{e.color}!important'))
         picker = ui.color_picker(on_pick=lambda e: button.style(f'background-color:{e.color}!important'))
         button = ui.button(on_click=picker.open).props('icon=colorize')
         button = ui.button(on_click=picker.open).props('icon=colorize')
 
 
-    # @example(ui.upload)
+    @example(ui.upload, skip=False)
     def upload_example():
     def upload_example():
-        ui.upload(on_upload=lambda e: ui.notify(f'{len(e.files[0])} bytes'))
+        ui.upload(on_upload=lambda e: ui.notify(f'{e.files[0].size} bytes'))
 
 
     h3('Markdown and HTML')
     h3('Markdown and HTML')
 
 

+ 0 - 47
nicegui/elements/old/upload.py

@@ -1,47 +0,0 @@
-import base64
-import traceback
-from typing import Callable, Optional
-
-import justpy as jp
-
-from ..events import UploadEventArguments, handle_event
-from .element import Element
-
-
-class Upload(Element):
-
-    def __init__(self, *,
-                 multiple: bool = False,
-                 on_upload: Optional[Callable] = None,
-                 upload_button_text: str = 'Upload') -> None:
-        """File Upload
-
-        :param multiple: allow uploading multiple files at once (default: `False`)
-        :param on_upload: callback to execute when a file is uploaded (list of bytearrays)
-        :param upload_button_text: text for the upload button
-        """
-        self.upload_handler = on_upload
-        view = jp.Form(
-            enctype='multipart/form-data',
-            classes='flex gap-4 items-center',
-            submit=lambda sender, msg: self.submit(sender, msg),
-            temp=False,
-        )
-        jp.Input(type='file', multiple=multiple, change=lambda *_: False, a=view, temp=False)
-        jp.QBtn(type='submit', text=upload_button_text, color='primary', a=view, temp=False)
-
-        super().__init__(view)
-
-    def submit(self, _, msg) -> Optional[bool]:
-        try:
-            page_update = False
-            for form_data in msg.form_data:
-                if form_data.type == 'file':
-                    files = [base64.b64decode(f.file_content) for f in form_data.files]
-                    names = [f.name for f in form_data.files]
-                    arguments = UploadEventArguments(sender=self, socket=msg.websocket, files=files, names=names)
-                    if handle_event(self.upload_handler, arguments):
-                        page_update = None
-            return page_update
-        except Exception:
-            traceback.print_exc()

+ 42 - 0
nicegui/elements/upload.py

@@ -0,0 +1,42 @@
+from typing import Callable, Dict, Optional
+
+from ..element import Element
+from ..events import UploadEventArguments, UploadFile, handle_event
+from ..vue import register_component
+
+register_component('upload', __file__, 'upload.vue')
+
+
+class Upload(Element):
+
+    def __init__(self, *,
+                 multiple: bool = False,
+                 on_upload: Optional[Callable] = None,
+                 file_picker_label: str = '',
+                 upload_button_icon: str = 'file_upload') -> None:
+        """File Upload
+
+        :param multiple: allow uploading multiple files at once (default: `False`)
+        :param on_upload: callback to execute when a file is uploaded (list of bytearrays)
+        :param file_picker_label: label for the file picker element
+        :param upload_button_icon: icon for the upload button
+        """
+        super().__init__('upload')
+        self.classes('row items-baseline gap-2')
+        self._props['multiple'] = multiple
+        self._props['file_picker_label'] = file_picker_label
+        self._props['upload_button_icon'] = upload_button_icon
+
+        def upload(msg: Dict) -> None:
+            files = [
+                UploadFile(
+                    name=file['name'],
+                    lastModified=file['lastModified'],
+                    lastModifiedDate=file['lastModifiedDate'],
+                    size=file['size'],
+                    type=file['type'],
+                )
+                for file in msg['args']
+            ]
+            handle_event(on_upload, UploadEventArguments(sender=self, client=self.client, files=files))
+        self.on('upload', upload, ['*'])

+ 39 - 0
nicegui/elements/upload.vue

@@ -0,0 +1,39 @@
+<template>
+  <div>
+    <q-file :label="file_picker_label" v-model="file" :multiple="multiple" />
+    <q-btn :icon="upload_button_icon" @click="upload" size="sm" round color="primary" />
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      file: undefined,
+    };
+  },
+  methods: {
+    upload() {
+      if (!this.file) return;
+      const files = this.multiple ? this.file : [this.file];
+      const args = files.map((file) => ({
+        name: file.name,
+        lastModified: file.lastModified / 1000,
+        lastModifiedDate: file.lastModifiedDate,
+        size: file.size,
+        type: file.type,
+        content: file,
+      }));
+      this.$emit("upload", args);
+    },
+  },
+  props: {
+    multiple: Boolean,
+    file_picker_label: String,
+    upload_button_text: String,
+    upload_button_icon: String,
+  },
+};
+</script>
+
+<style scoped></style>

+ 10 - 2
nicegui/events.py

@@ -37,10 +37,18 @@ class MouseEventArguments(EventArguments):
     image_y: float
     image_y: float
 
 
 
 
+@dataclass
+class UploadFile:
+    name: str
+    lastModified: float
+    lastModifiedDate: str
+    size: int
+    type: str
+
+
 @dataclass
 @dataclass
 class UploadEventArguments(EventArguments):
 class UploadEventArguments(EventArguments):
-    files: List[bytes]
-    names: List[str]
+    files: List[UploadFile]
 
 
 
 
 @dataclass
 @dataclass

+ 1 - 0
nicegui/ui.py

@@ -37,6 +37,7 @@ from .elements.switch import Switch as switch
 from .elements.toggle import Toggle as toggle
 from .elements.toggle import Toggle as toggle
 from .elements.tooltip import Tooltip as tooltip
 from .elements.tooltip import Tooltip as tooltip
 from .elements.tree import Tree as tree
 from .elements.tree import Tree as tree
+from .elements.upload import Upload as upload
 from .notify import notify
 from .notify import notify
 from .page import page
 from .page import page
 from .run import run
 from .run import run