diff --git a/soul_diary/ui/app/app.py b/soul_diary/ui/app/app.py index a17e2fb..9d28479 100644 --- a/soul_diary/ui/app/app.py +++ b/soul_diary/ui/app/app.py @@ -6,9 +6,10 @@ from flet_route import Routing, path from .local_storage import LocalStorage from .middleware import middleware from .models import BackendType -from .routes import AUTH, INDEX, SENSE_ADD, SENSE_LIST +from .routes import AUTH, INDEX, SENSE, SENSE_ADD, SENSE_LIST from .views.auth import AuthView from .views.base import BaseView +from .views.sense import SenseView from .views.sense_add import SenseAddView from .views.sense_list import SenseListView @@ -33,6 +34,7 @@ class SoulDiaryApp: ), SENSE_LIST: sense_list_view, SENSE_ADD: SenseAddView(), + SENSE: SenseView(), } async def run(self, page: flet.Page): diff --git a/soul_diary/ui/app/pages/sense.py b/soul_diary/ui/app/pages/sense.py new file mode 100644 index 0000000..1cc06fa --- /dev/null +++ b/soul_diary/ui/app/pages/sense.py @@ -0,0 +1,76 @@ +import uuid + +import flet +from soul_diary.ui.app.backend.utils import get_backend_client + +from soul_diary.ui.app.local_storage import LocalStorage +from soul_diary.ui.app.pages.base import BasePage +from soul_diary.ui.app.routes import SENSE_LIST + + +class SensePage(BasePage): + def __init__(self, view: flet.View, local_storage: LocalStorage, sense_id: uuid.UUID): + self.local_storage = local_storage + self.sense_id = sense_id + + self.title: flet.Text + self.emotions: flet.Row + + super().__init__(view=view) + + def build(self): + self.title = flet.Text() + close_button = flet.IconButton(icon=flet.icons.CLOSE, on_click=self.callback_close) + top_row = flet.Row( + controls=[self.title, close_button], + alignment=flet.MainAxisAlignment.SPACE_BETWEEN, + ) + + self.emotions = flet.Row(wrap=True) + emotions_title = flet.Text("Эмоции", style=flet.TextThemeStyle.HEADLINE_MEDIUM) + self.feelings = flet.Text(style=flet.TextThemeStyle.BODY_LARGE) + feelings_container = flet.Container( + content=flet.Column(controls=[emotions_title, self.feelings]), + margin=flet.margin.symmetric(vertical=15), + ) + body_title = flet.Text("Телесные ощущения", style=flet.TextThemeStyle.HEADLINE_MEDIUM) + self.body = flet.Text(style=flet.TextThemeStyle.BODY_LARGE) + body_container = flet.Container( + content=flet.Column(controls=[body_title, self.body]), + margin=flet.margin.symmetric(vertical=30), + ) + desires_title = flet.Text("Желания", style=flet.TextThemeStyle.HEADLINE_MEDIUM) + self.desires = flet.Text(style=flet.TextThemeStyle.BODY_LARGE) + desires_container = flet.Container( + content=flet.Column(controls=[desires_title, self.desires]), + margin=flet.margin.symmetric(vertical=30), + ) + + return flet.Container( + content=flet.Column( + controls=[top_row, self.emotions, feelings_container, body_container, + desires_container], + width=600, + ), + alignment=flet.alignment.center, + ) + + async def did_mount_async(self): + backend_client = await get_backend_client(local_storage=self.local_storage) + sense = await backend_client.get_sense(sense_id=self.sense_id) + self.title.value = f"Запись от {sense.created_at.strftime('%d %b %H:%M')}" + self.emotions.controls = [ + flet.Chip( + label=flet.Text(emotion.value), + show_checkmark=False, + selected=True, + ) + for emotion in sense.emotions + ] + self.feelings.value = sense.feelings + self.body.value = sense.body + self.desires.value = sense.desires + await self.update_async() + + async def callback_close(self, event: flet.ControlEvent): + await event.page.go_async(SENSE_LIST) diff --git a/soul_diary/ui/app/pages/sense_list.py b/soul_diary/ui/app/pages/sense_list.py index bd3ec7d..867a1ef 100644 --- a/soul_diary/ui/app/pages/sense_list.py +++ b/soul_diary/ui/app/pages/sense_list.py @@ -1,16 +1,20 @@ +import uuid +from functools import partial + import flet from soul_diary.ui.app.backend.utils import get_backend_client from soul_diary.ui.app.controls.utils import in_progress from soul_diary.ui.app.local_storage import LocalStorage from soul_diary.ui.app.models import Sense -from soul_diary.ui.app.routes import AUTH, SENSE_ADD +from soul_diary.ui.app.routes import AUTH, SENSE, SENSE_ADD from .base import BasePage, callback_error_handle class SenseListPage(BasePage): def __init__(self, view: flet.View, local_storage: LocalStorage): self.local_storage = local_storage + self.senses = [] self.senses_cards: flet.Column super().__init__(view=view) @@ -51,10 +55,10 @@ class SenseListPage(BasePage): async def render_cards(self): backend_client = await get_backend_client(self.local_storage) - senses = await backend_client.get_sense_list() + self.senses = await backend_client.get_sense_list() self.senses_cards.controls = [ await self.render_card(sense) - for sense in senses + for sense in self.senses ] await self.update_async() @@ -62,14 +66,27 @@ class SenseListPage(BasePage): feelings = flet.Container(content=flet.Text(sense.feelings), expand=True) created_datetime = flet.Text(sense.created_at.strftime("%d %b %H:%M")) - return flet.Card( - content=flet.Container( - content=flet.Column(controls=[feelings, created_datetime]), - padding=10, + card = flet.Container( + content=flet.Card( + content=flet.Container( + content=flet.Column(controls=[feelings, created_datetime]), + padding=10, + ), + width=400, + height=100, ), - width=400, - height=100, + on_click=partial(self.callback_card_click, sense_id=sense.id), ) + gesture_detector = flet.GestureDetector( + mouse_cursor=flet.MouseCursor.CLICK, + content=card, + ) + + return gesture_detector + + @callback_error_handle + async def callback_card_click(self, event: flet.ControlEvent, sense_id: uuid.UUID): + await event.page.go_async(SENSE.replace(":sense_id", str(sense_id))) @callback_error_handle async def callback_add_sense(self, event: flet.ControlEvent): diff --git a/soul_diary/ui/app/routes.py b/soul_diary/ui/app/routes.py index c206578..43c3cc5 100644 --- a/soul_diary/ui/app/routes.py +++ b/soul_diary/ui/app/routes.py @@ -2,3 +2,4 @@ INDEX = "/" AUTH = "/auth" SENSE_LIST = "/senses" SENSE_ADD = "/senses/add" +SENSE = "/sense/:sense_id" diff --git a/soul_diary/ui/app/views/auth.py b/soul_diary/ui/app/views/auth.py index ad8e87f..2eb56bf 100644 --- a/soul_diary/ui/app/views/auth.py +++ b/soul_diary/ui/app/views/auth.py @@ -1,7 +1,7 @@ -import asyncio from typing import Any import flet +from flet_route import Params from soul_diary.ui.app.backend.soul import SoulBackend from soul_diary.ui.app.controls.utils import in_progress @@ -23,7 +23,7 @@ class AuthView(BaseView): self.backend = backend self.backend_data = backend_data - async def entrypoint(self, page: flet.Page) -> BasePage: + async def entrypoint(self, page: flet.Page, params: Params) -> BasePage: local_storage = LocalStorage(client_storage=page.client_storage) if self.backend == BackendType.SOUL: return await self.connect_to_soul_server( diff --git a/soul_diary/ui/app/views/base.py b/soul_diary/ui/app/views/base.py index 63c0436..70b066a 100644 --- a/soul_diary/ui/app/views/base.py +++ b/soul_diary/ui/app/views/base.py @@ -8,10 +8,10 @@ class BaseView: async def __call__(self, page: flet.Page, params: Params, basket: Basket) -> flet.View: self.view = flet.View(vertical_alignment=flet.MainAxisAlignment.CENTER) - page = await self.entrypoint(page=page) + page = await self.entrypoint(page=page, params=params) self.view.controls = [page] return self.view - async def entrypoint(self, page: flet.Page) -> BasePage: + async def entrypoint(self, page: flet.Page, params: Params) -> BasePage: raise NotImplementedError diff --git a/soul_diary/ui/app/views/sense.py b/soul_diary/ui/app/views/sense.py new file mode 100644 index 0000000..2b59be2 --- /dev/null +++ b/soul_diary/ui/app/views/sense.py @@ -0,0 +1,16 @@ +import uuid + +import flet +from flet_route import Params + +from soul_diary.ui.app.local_storage import LocalStorage +from soul_diary.ui.app.pages.base import BasePage +from soul_diary.ui.app.pages.sense import SensePage +from .base import BaseView + + +class SenseView(BaseView): + async def entrypoint(self, page: flet.Page, params: Params) -> BasePage: + sense_id = uuid.UUID(params.sense_id) + local_storage = LocalStorage(page.client_storage) + return SensePage(view=self.view, local_storage=local_storage, sense_id=sense_id) diff --git a/soul_diary/ui/app/views/sense_add.py b/soul_diary/ui/app/views/sense_add.py index f8bfbf5..6eae8af 100644 --- a/soul_diary/ui/app/views/sense_add.py +++ b/soul_diary/ui/app/views/sense_add.py @@ -1,12 +1,13 @@ import flet -from soul_diary.ui.app.local_storage import LocalStorage +from flet_route import Params +from soul_diary.ui.app.local_storage import LocalStorage from soul_diary.ui.app.pages.base import BasePage from soul_diary.ui.app.pages.sense_add.emotions import EmotionsPage from .base import BaseView class SenseAddView(BaseView): - async def entrypoint(self, page: flet.Page) -> BasePage: + async def entrypoint(self, page: flet.Page, params: Params) -> BasePage: local_storage = LocalStorage(page.client_storage) return EmotionsPage(view=self.view, local_storage=local_storage) diff --git a/soul_diary/ui/app/views/sense_list.py b/soul_diary/ui/app/views/sense_list.py index a1c0329..2ce9039 100644 --- a/soul_diary/ui/app/views/sense_list.py +++ b/soul_diary/ui/app/views/sense_list.py @@ -1,4 +1,5 @@ import flet +from flet_route import Params from soul_diary.ui.app.local_storage import LocalStorage from soul_diary.ui.app.pages.base import BasePage @@ -7,6 +8,6 @@ from .base import BaseView class SenseListView(BaseView): - async def entrypoint(self, page: flet.Page) -> BasePage: + async def entrypoint(self, page: flet.Page, params: Params) -> BasePage: local_storage = LocalStorage(client_storage=page.client_storage) return SenseListPage(view=self.view, local_storage=local_storage)