add managing UI
This commit is contained in:
parent
438762730b
commit
e386d89c6f
@ -1,32 +1,117 @@
|
|||||||
import logging
|
import logging
|
||||||
|
from datetime import datetime
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from rio import Column, Component, event, TextStyle, Text, Spacer
|
from from_root import from_root
|
||||||
|
from rio import Column, Component, event, TextStyle, Text, Spacer, Row, Image, Tooltip, IconButton, Popup, Rectangle, Dropdown, ThemeContextSwitcher, Button
|
||||||
|
|
||||||
from src.ezgg_lan_manager import ConfigurationService
|
from src.ezgg_lan_manager import ConfigurationService, TournamentService, UserService
|
||||||
from src.ezgg_lan_manager.components.MainViewContentBox import MainViewContentBox
|
from src.ezgg_lan_manager.components.MainViewContentBox import MainViewContentBox
|
||||||
|
from src.ezgg_lan_manager.types.DateUtil import weekday_to_display_text
|
||||||
|
from src.ezgg_lan_manager.types.Participant import Participant
|
||||||
|
from src.ezgg_lan_manager.types.Tournament import Tournament
|
||||||
|
from src.ezgg_lan_manager.types.TournamentBase import TournamentStatus
|
||||||
|
|
||||||
logger = logging.getLogger(__name__.split(".")[-1])
|
logger = logging.getLogger(__name__.split(".")[-1])
|
||||||
|
|
||||||
class ManageTournamentsPage(Component):
|
class ManageTournamentsPage(Component):
|
||||||
|
tournaments: list[Tournament] = []
|
||||||
|
remove_participant_popup_open: bool = False
|
||||||
|
cancel_options: dict[str, Optional[Participant]] = {"": None}
|
||||||
|
tournament_id_selected_for_participant_removal: Optional[int] = None
|
||||||
|
participant_selected_for_removal: Optional[Participant] = None
|
||||||
|
|
||||||
@event.on_populate
|
@event.on_populate
|
||||||
async def on_populate(self) -> None:
|
async def on_populate(self) -> None:
|
||||||
|
self.tournaments = await self.session[TournamentService].get_tournaments()
|
||||||
await self.session.set_title(f"{self.session[ConfigurationService].get_lan_info().name} - Turnier Verwaltung")
|
await self.session.set_title(f"{self.session[ConfigurationService].get_lan_info().name} - Turnier Verwaltung")
|
||||||
|
|
||||||
|
async def on_start_pressed(self, tournament_id: int) -> None:
|
||||||
|
logger.info(f"Starting tournament with ID {tournament_id}")
|
||||||
|
await self.session[TournamentService].start_tournament(tournament_id)
|
||||||
|
|
||||||
|
async def on_cancel_pressed(self, tournament_id: int) -> None:
|
||||||
|
logger.info(f"Canceling tournament with ID {tournament_id}")
|
||||||
|
await self.session[TournamentService].cancel_tournament(tournament_id)
|
||||||
|
|
||||||
|
async def on_remove_participant_pressed(self, tournament_id: int) -> None:
|
||||||
|
tournament = await self.session[TournamentService].get_tournament_by_id(tournament_id)
|
||||||
|
if tournament is None:
|
||||||
|
return
|
||||||
|
users = await self.session[UserService].get_all_users()
|
||||||
|
try:
|
||||||
|
self.cancel_options = {next(filter(lambda u: u.user_id == p.id, users)).user_name: p for p in tournament.participants}
|
||||||
|
except StopIteration as e:
|
||||||
|
logger.error(f"Error trying to find user for participant: {e}")
|
||||||
|
self.tournament_id_selected_for_participant_removal = tournament_id
|
||||||
|
self.remove_participant_popup_open = True
|
||||||
|
|
||||||
|
async def on_remove_participant_confirm_pressed(self) -> None:
|
||||||
|
if self.participant_selected_for_removal is not None and self.tournament_id_selected_for_participant_removal is not None:
|
||||||
|
logger.info(f"Removing participant with ID {self.participant_selected_for_removal.id} from tournament with ID {self.tournament_id_selected_for_participant_removal}")
|
||||||
|
await self.session[TournamentService].unregister_user_from_tournament(self.participant_selected_for_removal.id, self.tournament_id_selected_for_participant_removal)
|
||||||
|
await self.on_remove_participant_cancel_pressed()
|
||||||
|
|
||||||
|
async def on_remove_participant_cancel_pressed(self) -> None:
|
||||||
|
self.tournament_id_selected_for_participant_removal = None
|
||||||
|
self.participant_selected_for_removal = None
|
||||||
|
self.remove_participant_popup_open = False
|
||||||
|
|
||||||
def build(self) -> Component:
|
def build(self) -> Component:
|
||||||
return Column(
|
tournament_rows = []
|
||||||
MainViewContentBox(
|
for tournament in self.tournaments:
|
||||||
Column(
|
start_time_color = self.session.theme.background_color
|
||||||
Text(
|
if tournament.start_time < datetime.now() and tournament.status == TournamentStatus.OPEN:
|
||||||
text="Turnier Verwaltung",
|
start_time_color = self.session.theme.warning_color
|
||||||
style=TextStyle(
|
|
||||||
fill=self.session.theme.background_color,
|
tournament_rows.append(
|
||||||
font_size=1.2
|
Row(
|
||||||
),
|
Image(image=from_root(f"src/ezgg_lan_manager/assets/img/games/{tournament.game_title.image_name}"), min_width=1.5, margin_right=1),
|
||||||
margin_top=2,
|
Text(tournament.name, style=TextStyle(fill=self.session.theme.background_color, font_size=0.8), justify="left", margin_right=1.5),
|
||||||
margin_bottom=2,
|
Text(f"{weekday_to_display_text(tournament.start_time.weekday())[:2]}.{tournament.start_time.strftime('%H:%M')} Uhr", style=TextStyle(fill=start_time_color, font_size=0.8), justify="left", margin_right=1),
|
||||||
align_x=0.5
|
Spacer(),
|
||||||
)
|
Tooltip(anchor=IconButton("material/play_arrow", min_size=2, margin_right=1, on_press=lambda: self.on_start_pressed(tournament.id)), tip="Starten"),
|
||||||
|
Tooltip(anchor=IconButton("material/cancel_schedule_send", min_size=2, margin_right=1, on_press=lambda: self.on_cancel_pressed(tournament.id)), tip="Absagen"),
|
||||||
|
Tooltip(anchor=IconButton("material/person_cancel", min_size=2, margin_right=1, on_press=lambda: self.on_remove_participant_pressed(tournament.id)), tip="Spieler entfernen"),
|
||||||
|
margin=1
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
Popup(
|
||||||
|
anchor=MainViewContentBox(
|
||||||
|
Column(
|
||||||
|
Text(
|
||||||
|
text="Turnier Verwaltung",
|
||||||
|
style=TextStyle(
|
||||||
|
fill=self.session.theme.background_color,
|
||||||
|
font_size=1.2
|
||||||
|
),
|
||||||
|
margin_top=2,
|
||||||
|
margin_bottom=2,
|
||||||
|
align_x=0.5
|
||||||
|
),
|
||||||
|
*tournament_rows
|
||||||
|
)
|
||||||
|
),
|
||||||
|
content=Rectangle(
|
||||||
|
content=Row(
|
||||||
|
ThemeContextSwitcher(
|
||||||
|
content=Dropdown(options=self.cancel_options, min_width=20, selected_value=self.bind().participant_selected_for_removal), color=self.session.theme.hud_color
|
||||||
|
),
|
||||||
|
Button(content="REMOVE", shape="rectangle", grow_x=False, on_press=self.on_remove_participant_confirm_pressed),
|
||||||
|
Button(content="CANCEL", shape="rectangle", grow_x=False, on_press=self.on_remove_participant_cancel_pressed),
|
||||||
|
margin=0.5
|
||||||
|
),
|
||||||
|
min_width=30,
|
||||||
|
min_height=4,
|
||||||
|
fill=self.session.theme.primary_color,
|
||||||
|
margin_top=3.5,
|
||||||
|
stroke_width=0.3,
|
||||||
|
stroke_color=self.session.theme.neutral_color,
|
||||||
|
),
|
||||||
|
is_open=self.remove_participant_popup_open,
|
||||||
|
color="none"
|
||||||
),
|
),
|
||||||
Spacer()
|
Spacer()
|
||||||
)
|
)
|
||||||
|
|||||||
@ -56,3 +56,17 @@ class TournamentService:
|
|||||||
all_users = await self._db_service.get_all_users()
|
all_users = await self._db_service.get_all_users()
|
||||||
participant_ids = [p.id for p in participants]
|
participant_ids = [p.id for p in participants]
|
||||||
return list(filter(lambda u: u.user_id in participant_ids, all_users))
|
return list(filter(lambda u: u.user_id in participant_ids, all_users))
|
||||||
|
|
||||||
|
async def start_tournament(self, tournament_id: int):
|
||||||
|
tournament = await self.get_tournament_by_id(tournament_id)
|
||||||
|
if tournament:
|
||||||
|
tournament.start()
|
||||||
|
# ToDo: Write matches/round to database
|
||||||
|
self._cache_dirty = True
|
||||||
|
|
||||||
|
async def cancel_tournament(self, tournament_id: int):
|
||||||
|
tournament = await self.get_tournament_by_id(tournament_id)
|
||||||
|
if tournament:
|
||||||
|
tournament.cancel()
|
||||||
|
# ToDo: Update to database
|
||||||
|
self._cache_dirty = True
|
||||||
|
|||||||
@ -93,8 +93,12 @@ class Tournament:
|
|||||||
def remove_participant(self, participant: Participant) -> None:
|
def remove_participant(self, participant: Participant) -> None:
|
||||||
if participant.id not in (p.id for p in self._participants):
|
if participant.id not in (p.id for p in self._participants):
|
||||||
raise TournamentError(f"Participant with ID {participant.id} not registered for tournament")
|
raise TournamentError(f"Participant with ID {participant.id} not registered for tournament")
|
||||||
|
# ToDo: Check if tournament already started => correctly resolve matches with now missing participant
|
||||||
self._participants.remove(participant)
|
self._participants.remove(participant)
|
||||||
|
|
||||||
|
def cancel(self):
|
||||||
|
self.status = TournamentStatus.CANCELED
|
||||||
|
|
||||||
def match_has_ended_callback(self, match: Match) -> None:
|
def match_has_ended_callback(self, match: Match) -> None:
|
||||||
if self._matches is None:
|
if self._matches is None:
|
||||||
return
|
return
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user