浏览代码

breaking change: all pages must be created with a decorator

Rodja Trappe 2 年之前
父节点
当前提交
1d6d07cdf4
共有 5 个文件被更改,包括 25 次插入32 次删除
  1. 19 4
      nicegui/elements/page.py
  2. 2 1
      nicegui/globals.py
  3. 2 6
      nicegui/nicegui.py
  4. 0 19
      nicegui/routes.py
  5. 2 2
      nicegui/ui.py

+ 19 - 4
nicegui/elements/page.py

@@ -2,6 +2,7 @@ import asyncio
 import inspect
 import inspect
 import time
 import time
 import uuid
 import uuid
+from functools import wraps
 from typing import Callable, Optional
 from typing import Callable, Optional
 
 
 import justpy as jp
 import justpy as jp
@@ -9,7 +10,7 @@ from addict import Dict
 from pygments.formatters import HtmlFormatter
 from pygments.formatters import HtmlFormatter
 from starlette.requests import Request
 from starlette.requests import Request
 
 
-from ..globals import config, connect_handlers, disconnect_handlers, page_stack, view_stack
+from ..globals import config, connect_handlers, disconnect_handlers, page_stack, shared_pages, view_stack
 from ..helpers import is_coroutine
 from ..helpers import is_coroutine
 
 
 
 
@@ -43,7 +44,6 @@ class Page(jp.QuasarPage):
         """
         """
         super().__init__()
         super().__init__()
 
 
-        self.delete_flag = route is None
         self.title = title or config.title
         self.title = title or config.title
         self.favicon = favicon or config.favicon
         self.favicon = favicon or config.favicon
         self.dark = dark if dark is not ... else config.dark
         self.dark = dark if dark is not ... else config.dark
@@ -61,8 +61,6 @@ class Page(jp.QuasarPage):
         self.view.add_page(self)
         self.view.add_page(self)
 
 
         self.route = route
         self.route = route
-        if route is not None:
-            jp.Route(route, self._route_function)
 
 
     async def _route_function(self, request: Request):
     async def _route_function(self, request: Request):
         for connect_handler in connect_handlers + ([self.connect_handler] if self.connect_handler else []):
         for connect_handler in connect_handlers + ([self.connect_handler] if self.connect_handler else []):
@@ -130,3 +128,20 @@ def add_head_html(self, html: str) -> None:
 
 
 def add_body_html(self, html: str) -> None:
 def add_body_html(self, html: str) -> None:
     page_stack[-1].body_html += html
     page_stack[-1].body_html += html
+
+
+def page(self, path: str, *, shared: bool = False, **kwargs):
+    def decorator(func):
+        @wraps(func)
+        async def decorated():
+            with Page(None) as p:
+                p.delete_flag = not shared
+                await func() if is_coroutine(func) else func()
+            return p
+        if shared:
+            shared_pages[path] = decorated
+        else:
+            jp.Route(path, decorated)
+
+        return decorated
+    return decorator

+ 2 - 1
nicegui/globals.py

@@ -2,7 +2,7 @@ from __future__ import annotations
 
 
 import asyncio
 import asyncio
 import logging
 import logging
-from typing import TYPE_CHECKING, Awaitable, Callable, List, Union
+from typing import TYPE_CHECKING, Awaitable, Callable, Dict, List, Union
 
 
 if TYPE_CHECKING:
 if TYPE_CHECKING:
     import justpy as jp
     import justpy as jp
@@ -13,6 +13,7 @@ if TYPE_CHECKING:
 
 
 app: 'Starlette'
 app: 'Starlette'
 config: 'Config'
 config: 'Config'
+shared_pages: Dict['Page'] = {}
 page_stack: List['Page'] = []
 page_stack: List['Page'] = []
 view_stack: List['jp.HTMLBaseComponent'] = []
 view_stack: List['jp.HTMLBaseComponent'] = []
 tasks: List[asyncio.tasks.Task] = []
 tasks: List[asyncio.tasks.Task] = []

+ 2 - 6
nicegui/nicegui.py

@@ -26,7 +26,8 @@ async def patched_justpy_startup():
 
 
 
 
 @jp.app.on_event('startup')
 @jp.app.on_event('startup')
-def startup():
+async def startup():
+    [jp.Route(route, (await page())._route_function) for route, page in globals.shared_pages.items()]
     globals.tasks.extend(create_task(t.coro, name=t.name) for t in Timer.prepared_coroutines)
     globals.tasks.extend(create_task(t.coro, name=t.name) for t in Timer.prepared_coroutines)
     Timer.prepared_coroutines.clear()
     Timer.prepared_coroutines.clear()
     globals.tasks.extend(create_task(t, name='startup task')
     globals.tasks.extend(create_task(t, name='startup task')
@@ -57,8 +58,3 @@ ui = Ui()
 
 
 def handle_page_ready(socket: WebSocket):
 def handle_page_ready(socket: WebSocket):
     create_task(page.update(socket))
     create_task(page.update(socket))
-
-
-page = ui.page('/', classes=globals.config.main_page_classes, on_page_ready=handle_page_ready)
-page.__enter__()
-jp.justpy(lambda: page, start_server=False)

+ 0 - 19
nicegui/routes.py

@@ -56,22 +56,3 @@ def get(self, path: str):
         self.add_route(routing.Route(path, decorated))
         self.add_route(routing.Route(path, decorated))
         return decorated
         return decorated
     return decorator
     return decorator
-
-
-def private_page(self, path: str):
-    '''
-    Use as a decorator for a function like this:
-
-    @ui.private_page('/private')
-    def create_private_page():
-        ui.label(f'your private page {uuid4()}')
-    '''
-    def decorator(func):
-        @wraps(func)
-        async def decorated():
-            with Page(None) as page:
-                await func() if is_coroutine(func) else func()
-            return page
-        jp.Route(path, decorated)
-        return decorated
-    return decorator

+ 2 - 2
nicegui/ui.py

@@ -33,7 +33,7 @@ class Ui:
     from .elements.notify import Notify as notify
     from .elements.notify import Notify as notify
     from .elements.number import Number as number
     from .elements.number import Number as number
     from .elements.open import open, open_async
     from .elements.open import open, open_async
-    from .elements.page import Page as page, add_head_html, add_body_html
+    from .elements.page import page, add_head_html, add_body_html
     from .elements.radio import Radio as radio
     from .elements.radio import Radio as radio
     from .elements.row import Row as row
     from .elements.row import Row as row
     from .elements.select import Select as select
     from .elements.select import Select as select
@@ -45,7 +45,7 @@ class Ui:
     from .elements.update import update
     from .elements.update import update
     from .elements.upload import Upload as upload
     from .elements.upload import Upload as upload
     from .lifecycle import on_connect, on_disconnect, on_shutdown, on_startup
     from .lifecycle import on_connect, on_disconnect, on_shutdown, on_startup
-    from .routes import add_route, add_static_files, get, private_page
+    from .routes import add_route, add_static_files, get
     from .timer import Timer as timer
     from .timer import Timer as timer
 
 
     if 'colors' not in _excludes:
     if 'colors' not in _excludes: