Skip to content

Commit

Permalink
feat: add "leave room" feature
Browse files Browse the repository at this point in the history
  • Loading branch information
Makcal committed May 20, 2024
1 parent 7d5fcd4 commit 2a5c04a
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 101 deletions.
2 changes: 1 addition & 1 deletion src/bot/dialogs/confirmation.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ async def on_select(callback: CallbackQuery, select, manager: DialogManager, ite
answer = confirmation.yes_message if confirmed else confirmation.no_message
if answer is not None:
await callback.bot.send_message(callback.message.chat.id, answer)
await manager.done(confirmed, show_mode=ShowMode.SEND)
await manager.done(confirmed, show_mode=ShowMode.NO_UPDATE)


confirmation_dialog = Dialog(
Expand Down
148 changes: 77 additions & 71 deletions src/bot/dialogs/incoming_invitations.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,84 +31,90 @@ async def load_invitations(manager: DialogManager):
manager.dialog_data["invitations"] = invitations_data


async def on_start(_, manager: DialogManager):
await Loader.load_invitations(manager)


def select_invitation(func):
async def wrapped(callback: CallbackQuery, widget, manager: DialogManager):
assert isinstance(manager, SubManager)

invitations: list[IncomingInvitationInfo] = manager.dialog_data["invitations"]
for i in invitations:
if i.id == int(manager.item_id):
manager.dialog_data["selected_item"] = i
break
else:
raise RuntimeError("Selected non-existent room")
class Events:
@staticmethod
async def on_start(_, manager: DialogManager):
await Loader.load_invitations(manager)

await func(callback, widget, manager)
@staticmethod
def _select_invitation(func):
async def wrapped(callback: CallbackQuery, widget, manager: DialogManager):
assert isinstance(manager, SubManager)

return wrapped
invitations: list[IncomingInvitationInfo] = manager.dialog_data["invitations"]
for i in invitations:
if i.id == int(manager.item_id):
manager.dialog_data["selected_item"] = i
break
else:
raise RuntimeError("Selected non-existent room")

await func(callback, widget, manager)

@select_invitation
async def on_accept_invitation(callback: CallbackQuery, widget, manager: DialogManager):
invitation: IncomingInvitationInfo = manager.dialog_data["selected_item"]
room_name: str = invitation.room_name
return wrapped

await manager.start(
ConfirmationSG.main,
data={
"intent": "accept",
"input": dataclasses.asdict(
ConfirmationDialogStartData(
f"you want to accept the invitation to {room_name}",
"Accepted",
)
),
},
show_mode=ShowMode.SEND,
)


@select_invitation
async def on_reject_invitation(callback: CallbackQuery, widget, manager: DialogManager):
invitation: IncomingInvitationInfo = manager.dialog_data["selected_item"]
room_name: str = invitation.room_name

await manager.start(
ConfirmationSG.main,
data={
"intent": "reject",
"input": dataclasses.asdict(
ConfirmationDialogStartData(
f"you want to reject the invitation to {room_name}",
"Rejected",
)
),
},
show_mode=ShowMode.SEND,
)
@staticmethod
@_select_invitation
async def on_accept_invitation(callback: CallbackQuery, widget, manager: DialogManager):
invitation: IncomingInvitationInfo = manager.dialog_data["selected_item"]
room_name: str = invitation.room_name

await manager.start(
ConfirmationSG.main,
data={
"intent": "accept",
"input": dataclasses.asdict(
ConfirmationDialogStartData(
f"you want to accept the invitation to {room_name}",
"Accepted",
)
),
},
show_mode=ShowMode.SEND,
)

async def process_result(start_data: dict, result: dict, manager: DialogManager):
if not start_data or not result:
return
@staticmethod
@_select_invitation
async def on_reject_invitation(callback: CallbackQuery, widget, manager: DialogManager):
invitation: IncomingInvitationInfo = manager.dialog_data["selected_item"]
room_name: str = invitation.room_name

invitation: IncomingInvitationInfo = manager.dialog_data["selected_item"]
user_id = manager.event.from_user.id
if start_data["intent"] == "accept":
await client.accept_invitation(invitation.id, user_id)
await manager.start(
RoomSG.main,
data={"input": dataclasses.asdict(RoomDialogStartData(invitation.room, invitation.room_name))},
mode=StartMode.RESET_STACK,
ConfirmationSG.main,
data={
"intent": "reject",
"input": dataclasses.asdict(
ConfirmationDialogStartData(
f"you want to reject the invitation to {room_name}",
"Rejected",
)
),
},
show_mode=ShowMode.SEND,
)
elif start_data["intent"] == "reject":
await client.reject_invitation(invitation.id, user_id)
await Loader.load_invitations(manager)

@staticmethod
async def on_process_result(start_data: dict, result: bool, manager: DialogManager):
if not isinstance(start_data, dict):
return
if not result:
await manager.show(ShowMode.SEND)
return

invitation: IncomingInvitationInfo = manager.dialog_data["selected_item"]
user_id = manager.event.from_user.id
if start_data["intent"] == "accept":
await client.accept_invitation(invitation.id, user_id)
await manager.start(
RoomSG.main,
data={"input": dataclasses.asdict(RoomDialogStartData(invitation.room, invitation.room_name))},
mode=StartMode.RESET_STACK,
show_mode=ShowMode.SEND,
)
elif start_data["intent"] == "reject":
await client.reject_invitation(invitation.id, user_id)
await Loader.load_invitations(manager)
await manager.show(ShowMode.SEND)


async def invitations_getter(dialog_manager: DialogManager, **kwargs):
Expand Down Expand Up @@ -148,12 +154,12 @@ async def invitations_getter(dialog_manager: DialogManager, **kwargs):
Row(
Button(
Format("{pos}. {item.room_name}"),
on_click=on_accept_invitation,
on_click=Events.on_accept_invitation,
id=InvitationsWindowConsts.ACCEPT_BUTTON_ID,
),
Button(
Const("Reject"),
on_click=on_reject_invitation,
on_click=Events.on_reject_invitation,
id=InvitationsWindowConsts.REJECT_BUTTON_ID,
),
),
Expand All @@ -164,6 +170,6 @@ async def invitations_getter(dialog_manager: DialogManager, **kwargs):
state=IncomingInvitationsSG.list,
getter=invitations_getter,
),
on_process_result=process_result,
on_start=on_start,
on_process_result=Events.on_process_result,
on_start=Events.on_start,
)
61 changes: 51 additions & 10 deletions src/bot/dialogs/room.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import dataclasses

from aiogram.types import CallbackQuery
from aiogram_dialog import Dialog, Window, DialogManager
from aiogram_dialog import Dialog, Window, DialogManager, ShowMode, StartMode
from aiogram_dialog.widgets.kbd import Row, Button, SwitchTo
from aiogram_dialog.widgets.text import Format, Const, List

from src.api import client
from src.api.schemas.method_output_schemas import DailyInfoResponse, UserInfo
from src.bot.dialogs.communication import RoomDialogStartData
from src.bot.dialogs.states import RoomSG
from src.bot.dialogs.communication import RoomDialogStartData, ConfirmationDialogStartData
from src.bot.dialogs.states import RoomSG, ConfirmationSG, RoomlessSG


class MainWindowConsts:
REFRESH_BUTTON_ID = "refresh_button"
ROOMMATES_BUTTON_ID = "roommates_button"
TASKS_BUTTON_ID = "tasks_button"
INVITATIONS_BUTTON_ID = "invitations_button"
INBOX_BUTTON_ID = "incoming_invitations_button"
MY_INVITATIONS_BUTTON_ID = "my_invitations_button"
LEAVE_BUTTON_ID = "leave_button"


Expand All @@ -33,9 +36,45 @@ async def getter(dialog_manager: DialogManager, **kwargs):
}


async def on_start(start_data: dict, manager: DialogManager):
manager.dialog_data["room_info"] = RoomDialogStartData(**start_data["input"])
await Loader.load_daily_info(manager)
class Events:
@staticmethod
async def on_start(start_data: dict, manager: DialogManager):
manager.dialog_data["room_info"] = RoomDialogStartData(**start_data["input"])
await Loader.load_daily_info(manager)

@staticmethod
async def on_leave(callback: CallbackQuery, button, manager: DialogManager):
room_name: str = manager.dialog_data["room_info"].name
await manager.start(
ConfirmationSG.main,
data={
"intent": "leave",
"input": dataclasses.asdict(
ConfirmationDialogStartData(
"you want to leave the room",
f'You have left the room "{room_name}"',
)
),
},
show_mode=ShowMode.SEND,
)

@staticmethod
async def on_process_result(start_data: dict, result: bool, manager: DialogManager):
if not isinstance(start_data, dict):
return
if not result:
await manager.show(ShowMode.SEND)
return

user_id = manager.event.from_user.id
if start_data["intent"] == "leave":
await client.leave_room(user_id)
await manager.start(
RoomlessSG.welcome,
mode=StartMode.RESET_STACK,
show_mode=ShowMode.SEND,
)


class Loader:
Expand Down Expand Up @@ -87,8 +126,9 @@ async def load_roommates(manager: DialogManager):
Button(Const("Tasks"), MainWindowConsts.TASKS_BUTTON_ID),
),
Row(
Button(Const("Invitations"), MainWindowConsts.INVITATIONS_BUTTON_ID),
Button(Const("Leave"), MainWindowConsts.LEAVE_BUTTON_ID),
Button(Const("Inbox"), MainWindowConsts.INBOX_BUTTON_ID),
Button(Const("My invitations"), MainWindowConsts.MY_INVITATIONS_BUTTON_ID),
Button(Const("Leave"), MainWindowConsts.LEAVE_BUTTON_ID, on_click=Events.on_leave),
),
getter=getter,
state=RoomSG.main,
Expand All @@ -108,5 +148,6 @@ async def load_roommates(manager: DialogManager):
state=RoomSG.roommates,
getter=getter,
),
on_start=on_start,
on_start=Events.on_start,
on_process_result=Events.on_process_result,
)
38 changes: 20 additions & 18 deletions src/bot/dialogs/roomless.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,24 @@ class WelcomeWindowConsts:
CREATE_ROOM_BUTTON_ID = "create_room_button"


async def process_create_room_result(start_data: Data, result: CreateRoomDialogResult, manager: DialogManager):
if not start_data:
return

if start_data["intent"] == "create_room":
if result.created:
room_id = await client.create_room(result.name, manager.event.from_user.id)
await manager.start(
RoomSG.main,
data={"input": dataclasses.asdict(RoomDialogStartData(room_id, result.name))},
mode=StartMode.RESET_STACK,
)


async def start_creating_room(event: CallbackQuery, button: Button, dialog_manager: DialogManager):
await dialog_manager.start(CreateRoomSG.enter_name, data={"intent": "create_room"}, show_mode=ShowMode.SEND)
class Events:
@staticmethod
async def process_create_room_result(start_data: Data, result: CreateRoomDialogResult, manager: DialogManager):
if not isinstance(start_data, dict):
return

if start_data["intent"] == "create_room":
if result.created:
room_id = await client.create_room(result.name, manager.event.from_user.id)
await manager.start(
RoomSG.main,
data={"input": dataclasses.asdict(RoomDialogStartData(room_id, result.name))},
mode=StartMode.RESET_STACK,
)

@staticmethod
async def on_click_create_room(event: CallbackQuery, button: Button, dialog_manager: DialogManager):
await dialog_manager.start(CreateRoomSG.enter_name, data={"intent": "create_room"}, show_mode=ShowMode.SEND)


roomless_dialog = Dialog(
Expand All @@ -51,10 +53,10 @@ async def start_creating_room(event: CallbackQuery, button: Button, dialog_manag
Button(
Const("Create"),
WelcomeWindowConsts.CREATE_ROOM_BUTTON_ID,
on_click=start_creating_room,
on_click=Events.on_click_create_room,
),
),
state=RoomlessSG.welcome,
),
on_process_result=process_create_room_result,
on_process_result=Events.process_create_room_result,
)
1 change: 0 additions & 1 deletion src/bot/dialogs/states.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ class RoomSG(StatesGroup):
main = State()
roommates = State()
invitations = State()
leave = State()


class IncomingInvitationsSG(StatesGroup):
Expand Down

0 comments on commit 2a5c04a

Please sign in to comment.