1
+ import asyncio
1
2
import inspect
2
3
from typing import Callable , Dict , Union
3
4
4
5
from fastapi .routing import APIRoute
5
6
6
- from nicegui import background_tasks , helpers , ui , core , Client
7
+ from nicegui import background_tasks , helpers , ui , core , Client , app
7
8
from nicegui .app import AppConfig
8
9
9
10
@@ -19,16 +20,17 @@ def __init__(self, path: str, **kwargs) -> None:
19
20
super ().__init__ ()
20
21
21
22
self .routes : Dict [str , Callable ] = {}
22
- self . content : Union [ ui . element , None ] = None
23
+ # async access lock
23
24
self .base_path = path
24
25
self .find_api_routes ()
25
26
26
- print ("Configuring SinglePageRouter with path:" , path )
27
-
28
27
@ui .page (path , ** kwargs )
29
28
@ui .page (f'{ path } ' + '{_:path}' , ** kwargs ) # all other pages
30
- def root_page ():
31
- self .frame ()
29
+ async def root_page (client : Client ):
30
+ await client .connected ()
31
+ if app .storage .session .get ('__pageContent' , None ) is None :
32
+ content : Union [ui .element , None ] = RouterFrame (self .base_path ).on ('open' , lambda e : self .open (e .args ))
33
+ app .storage .session ['__pageContent' ] = content
32
34
33
35
def find_api_routes (self ):
34
36
page_routes = set ()
@@ -39,7 +41,7 @@ def find_api_routes(self):
39
41
Client .single_page_routes [route ] = self
40
42
self .routes [route ] = key
41
43
42
- for route in core .app .routes :
44
+ for route in core .app .routes . copy () :
43
45
if isinstance (route , APIRoute ):
44
46
if route .path in page_routes :
45
47
core .app .routes .remove (route )
@@ -68,18 +70,13 @@ def open(self, target: Union[Callable, str], server_side=False) -> None:
68
70
if server_side :
69
71
ui .run_javascript (f'window.history.pushState({{page: "{ target } "}}, "", "{ target } ");' )
70
72
71
- if self .content is None :
72
- return
73
-
74
- async def build () -> None :
75
- with self .content :
73
+ async def build (content_element ) -> None :
74
+ with content_element :
76
75
result = builder ()
77
76
if helpers .is_coroutine_function (builder ):
78
77
await result
79
78
80
- self . content . clear ()
81
- background_tasks . create ( build () )
79
+ content = app . storage . session [ '__pageContent' ]
80
+ content . clear ( )
82
81
83
- def frame (self ) -> ui .element :
84
- self .content = RouterFrame (self .base_path ).on ('open' , lambda e : self .open (e .args ))
85
- return self .content
82
+ background_tasks .create (build (content ))
0 commit comments