84 lines
2.9 KiB
Python
84 lines
2.9 KiB
Python
from fasthtml.components import *
|
|
|
|
from myfasthtml.controls.BaseCommands import BaseCommands
|
|
from myfasthtml.controls.helpers import mk
|
|
from myfasthtml.core.AuthProxy import AuthProxy
|
|
from myfasthtml.core.commands import Command
|
|
from myfasthtml.core.instances import SingleInstance, RootInstance
|
|
from myfasthtml.core.utils import retrieve_user_info
|
|
from myfasthtml.icons.material import dark_mode_filled, person_outline_sharp
|
|
from myfasthtml.icons.material_p1 import light_mode_filled, alternate_email_filled
|
|
|
|
|
|
class UserProfileState:
|
|
def __init__(self, owner):
|
|
self._owner = owner
|
|
self._session = owner.get_session()
|
|
|
|
self.theme = "light"
|
|
self.load()
|
|
|
|
def load(self):
|
|
user_info = retrieve_user_info(self._session)
|
|
user_settings = user_info.get("user_settings", {})
|
|
for k, v in user_settings.items():
|
|
if hasattr(self, k):
|
|
setattr(self, k, v)
|
|
|
|
def save(self):
|
|
user_settings = {k: v for k, v in self.__dict__.items() if not k.startswith("_")}
|
|
auth_proxy = AuthProxy(RootInstance)
|
|
auth_proxy.save_user_info(self._session["access_token"], {"user_settings": user_settings})
|
|
|
|
|
|
class Commands(BaseCommands):
|
|
def update_dark_mode(self):
|
|
return Command("UpdateDarkMode", "Set the dark mode", self._owner.update_dark_mode).htmx(target=None)
|
|
|
|
|
|
class UserProfile(SingleInstance):
|
|
def __init__(self, parent=None, _id=None):
|
|
super().__init__(parent, _id=_id)
|
|
self._state = UserProfileState(self)
|
|
self._commands = Commands(self)
|
|
|
|
def update_dark_mode(self, client_response):
|
|
self._state.theme = client_response.get("theme", "light")
|
|
self._state.save()
|
|
retrieve_user_info(self._session).get("user_settings", {})["theme"] = self._state.theme
|
|
|
|
def render(self):
|
|
user_info = retrieve_user_info(self._session)
|
|
return Div(
|
|
Div(user_info['username'],
|
|
tabindex="0",
|
|
role="button",
|
|
cls="btn btn-xs"),
|
|
Div(
|
|
Div(mk.icon(person_outline_sharp, cls="mr-1"), user_info['username'], cls="flex m-1"),
|
|
Div(mk.icon(alternate_email_filled, cls="mr-1"), user_info['email'], cls="flex m-1"),
|
|
Div(mk.icon(dark_mode_filled, cls="mr-1"), self.mk_dark_mode(), cls="flex m-1"),
|
|
Div(A("Logout", cls="btn btn-xs mr-1", href="/logout"), cls="flex justify-center items-center"),
|
|
tabindex="-1",
|
|
cls="dropdown-content menu w-52 rounded-box bg-base-300 shadow-xl"
|
|
),
|
|
cls="dropdown dropdown-end"
|
|
)
|
|
|
|
def mk_dark_mode(self):
|
|
return Label(
|
|
mk.mk(Input(type="checkbox",
|
|
name='theme',
|
|
aria_label='Dark',
|
|
value="dark",
|
|
checked='true' if self._state.theme == 'dark' else None,
|
|
cls='theme-controller'),
|
|
command=self._commands.update_dark_mode()),
|
|
light_mode_filled,
|
|
dark_mode_filled,
|
|
cls="toggle text-base-content"
|
|
)
|
|
|
|
def __ft__(self):
|
|
return self.render()
|