feat: implement adaptive layout and sync navigation state

This commit is contained in:
Flook
2026-05-07 04:59:47 +07:00
parent 2d9cbb3376
commit 5ac9799b5d
3 changed files with 57 additions and 25 deletions
+21 -7
View File
@@ -1,17 +1,31 @@
import flet as ft
from app.widgets.adaptive_menu import adaptive_menu
from app.widgets.adaptive_menu import adaptive_menu, get_selected_index_from_route
MOBILE_BREAKPOINT = 600
def get_layout_mode(page: ft.Page):
width = page.width if page.width and page.width > 0 else 1024
return "mobile" if width < MOBILE_BREAKPOINT else "desktop"
def main_layout(page: ft.Page, content_container: ft.Container):
print(">>> ENTER main_layout")
menu = adaptive_menu(page)
# ตรวจสอบโหมด (ป้องกันหน้าจอขาวจาก width=0)
width = page.width if page.width > 0 else 1024 # default ไว้ที่ desktop ก่อนถ้ายังไม่รู้ width
is_mobile = width < 600
print(f">>> Device mode: {'MOBILE' if is_mobile else 'DESKTOP'} (Width: {page.width})")
mode = get_layout_mode(page)
if is_mobile:
# เก็บ mode instance ไว้ที่ page
page._layout_mode = mode
selected_index = get_selected_index_from_route(page.route)
menu = adaptive_menu(page, selected_index)
# เก็บ menu instance ไว้ที่ page
page._menu_control = menu
print(f">>> Device mode: {mode}")
if mode == "mobile":
return ft.Column(
controls=[
content_container,
+13 -17
View File
@@ -1,13 +1,19 @@
import flet as ft
def adaptive_menu(page: ft.Page):
is_mobile = page.width < 600
MENU_KEYS = ['articles', 'courses', 'my_courses', 'progress', 'profile', 'logout']
menu_keys = ['articles', 'courses', 'my_courses', 'progress', 'profile', 'logout']
def get_selected_index_from_route(route: str):
key = route.replace("/", "").split("/")[0]
if key in MENU_KEYS:
return MENU_KEYS.index(key)
return 0
def adaptive_menu(page: ft.Page, selected_index: int):
is_mobile = page.width < 600
async def handle_change(e):
index = int(e.control.selected_index)
key = menu_keys[index]
key = MENU_KEYS[index]
if key == "logout":
from app.state import state
@@ -15,17 +21,7 @@ def adaptive_menu(page: ft.Page):
await page.push_route("/login") # หรือ page.go
return
route = f"/{menu_keys[index]}"
print(f">>> Navigating to: {route}")
await page.push_route(route)
# sync selected index กับ route
current_route = page.route.replace("/", "") or "articles"
if current_route not in menu_keys:
current_route = "articles"
current_selected_index = menu_keys.index(current_route)
await page.push_route(f"/{key}")
if is_mobile:
return ft.NavigationBar(
@@ -38,7 +34,7 @@ def adaptive_menu(page: ft.Page):
ft.NavigationBarDestination(icon=ft.Icons.LOGOUT, label="ออกจากระบบ"
),
],
selected_index=current_selected_index,
selected_index=selected_index,
on_change=handle_change,
)
else:
@@ -52,7 +48,7 @@ def adaptive_menu(page: ft.Page):
ft.NavigationRailDestination(icon=ft.Icons.LOGOUT, label="Logout"
),
],
selected_index=current_selected_index,
selected_index=selected_index,
on_change=handle_change,
extended=True,
)