Skip to content
Closed
6 changes: 3 additions & 3 deletions handlers/admin/create_campaign.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ async def on_description_entered(


async def on_icon_entered(mes: Message, wid: MessageInput, dialog_manager: DialogManager):
if mes.photo:
if mes.photo and mes.bot:
photo = mes.photo[-1]
file = await mes.bot.get_file(photo.file_id)
bin_stream: BinaryIO = await mes.bot.download_file(file.file_path)
bin_stream: BinaryIO | None = await mes.bot.download_file(file.file_path or "")

object_id = uuid.uuid4()
settings.minio.put_object(
Expand Down Expand Up @@ -99,7 +99,7 @@ async def on_confirm(mes: CallbackQuery, button: Button, dialog_manager: DialogM
new_campaign: Campaign = await Campaign.create(
title=campaign_data.get("title", ""),
description=campaign_data.get("description", ""),
icon=campaign_data.get("icon", ""),
icon=campaign_data.get("icon"),
verified=verified,
)

Expand Down
23 changes: 11 additions & 12 deletions handlers/admin/inventory_management.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ async def on_delete_inventory_item(callback: CallbackQuery, button: Button, dial
)

add_item_description_window = Window(
Format("Название {new_item_name}"),
Format("📦 Название: {new_item_name}"),
Const("📝 Введите описание предмета (или '-' чтобы пропустить):"),
TextInput(
id="item_description_input",
Expand All @@ -268,8 +268,8 @@ async def on_delete_inventory_item(callback: CallbackQuery, button: Button, dial
)

add_item_quantity_window = Window(
Format("Название: {new_item_name}"),
Format("Описание {new_item_description}"),
Format("📦 Название: {new_item_name}"),
Format("📄 Описание {new_item_description}"),
Const("🔢 Введите количество предмета:"),
TextInput(
id="item_quantity_input",
Expand All @@ -283,32 +283,31 @@ async def on_delete_inventory_item(callback: CallbackQuery, button: Button, dial
edit_inventory_item_window = Window(
Multi(
Const("✏️ Редактирование предмета"),
Format("📦 {item.title}"),
Format("📦 Название: {item.title}"),
Format("📝 Описание: {item.description}", when="has_description"),
Const("📝 Описание отсутствует", when=lambda data, *_: not data.get("item", {}).description),
Const("📭 Описание отсутствует", when=lambda data, *_: not data.get("item", {}).description),
Format("🔢 Количество: {item.quantity}"),
Const(""),
Const("Выберите что изменить:"),
Const("\nВыберите что изменить:"),
sep="\n",
),
Group(
SwitchTo(
Const("✏️ Название"),
Const("✏️ Изменить название"),
id="edit_name",
state=states.ManageInventory.edit_inventory_item_name,
),
SwitchTo(
Const("📝 Описание"),
Const("📝 Изменить описание"),
id="edit_description",
state=states.ManageInventory.edit_inventory_item_description,
),
SwitchTo(
Const("🔢 Количество"),
Const("🔢 Изменить количество"),
id="edit_quantity",
state=states.ManageInventory.edit_inventory_item_quantity,
),
SwitchTo(
Const("🗑️ Удалить"),
Const("🗑️ Удалить предмет"),
id="delete_item",
state=states.ManageInventory.accept_delete,
),
Expand Down Expand Up @@ -354,7 +353,7 @@ async def on_delete_inventory_item(callback: CallbackQuery, button: Button, dial
)

accept_delete_item_window = Window(
Const("🎯 Точно удалить?"),
Const("⚠️ Вы точно хотите удалить этот предмет?"),
Button(
Const("🚫 Удалить"),
id="accept_delete",
Expand Down
22 changes: 15 additions & 7 deletions handlers/admin/invitation.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from aiogram_dialog import Dialog, DialogManager, StartMode, Window
from aiogram_dialog.api.entities import MediaAttachment
from aiogram_dialog.widgets.input import ManagedTextInput, TextInput
from aiogram_dialog.widgets.kbd import Back, Button, Cancel, Next
from aiogram_dialog.widgets.kbd import Back, Button, Cancel, Next, Row
from aiogram_dialog.widgets.link_preview import LinkPreview
from aiogram_dialog.widgets.media import DynamicMedia
from aiogram_dialog.widgets.text import Const, Format, Multi
Expand All @@ -28,7 +28,7 @@
async def get_link(dialog_manager: DialogManager, **_):
created_by: User = dialog_manager.middleware_data["user"]

link = dialog_manager.dialog_data.get("link")
link = dialog_manager.dialog_data.get("link", "")
if "link" not in dialog_manager.dialog_data and isinstance(dialog_manager.start_data, dict):
campaign_id = dialog_manager.start_data.get("campaign_id", 0)
role = dialog_manager.start_data.get("role", Role.PLAYER)
Expand Down Expand Up @@ -177,16 +177,24 @@ async def on_accept(msg: CallbackQuery, _: Button, dialog_manager: DialogManager
getter=get_qr,
)


invite_window = Window(
Format("🎉 Вас пригласили в кампанию!\n\n<b>{campaign_title}</b>\nРоль: <b>{role}</b>"),
Button(Const("✅ Присоединиться"), id="accept_admin", on_click=on_accept),
Cancel(Const("❌ Отказаться")),
Multi(
Const("🎉 Вам пришло приглашение!"),
Const(""),
Format("🏰 Кампания: <b>{campaign_title}</b>"),
Format("👑 Роль: <b>{role}</b>"),
Const(""),
Const("Присоединиться к кампании?"),
sep="\n",
),
Row(
Button(Const("✅ Присоединиться"), id="accept_admin", on_click=on_accept),
Cancel(Const("❌ Отказаться")),
),
getter=invitation_getter,
state=states.InviteMenu.invite,
)


# === Создание диалога и роутера ===
dialog = Dialog(invite_menu_window, qr_window, invite_window)
router = Router()
Expand Down
64 changes: 42 additions & 22 deletions handlers/player/academy.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
from aiogram import Router
from aiogram.types import CallbackQuery
from aiogram_dialog import Dialog, DialogManager, Window
from aiogram_dialog.widgets.kbd import Button, Cancel, Column
from aiogram_dialog.widgets.kbd import Button, Cancel, Column, Row
from aiogram_dialog.widgets.media import DynamicMedia
from aiogram_dialog.widgets.text import Const, Format
from aiogram_dialog.widgets.text import Const, Format, Multi

from services.character_data import character_preview_getter
from states.academy import Academy
Expand Down Expand Up @@ -41,26 +41,46 @@ async def on_campaigns(c: CallbackQuery, b: Button, m: DialogManager):

async def character_data_getter(dialog_manager: DialogManager, **kwargs) -> dict:
user = dialog_manager.middleware_data["user"]
data = json.loads(user.data["data"])

return character_preview_getter(user, data)


router.include_router(
Dialog(
Window(
DynamicMedia("avatar", when="avatar"),
Format("{character_data_preview}", when="character_data_preview"),
Column(
Button(Const("Посмотреть инвентарь"), id="inventory", on_click=on_inventory),
Button(Const("Загрузить обновленный .json"), id="update_json", on_click=on_update),
Button(Const("Рейтинг"), id="rating", on_click=on_rating),
Button(Const("Кампании внутри академии"), id="campaigns", on_click=on_campaigns),
Cancel(Const("Назад")),

if user.data is None:
return {"has_character_data": False, "avatar": False}

data = json.loads(user.data.get("data", "{}"))

character_preview = character_preview_getter(user, data)

return {
**character_preview,
"has_character_data": True,
}


academy_dialog = Dialog(
Window(
Multi(
Const("🎓 Ваш профиль в академии"),
Const(""),
),
DynamicMedia("avatar", when="avatar"),
Format("{character_data_preview}", when="has_character_data"),
Const(
"📭 У вас пока нет загруженного персонажа", when=lambda data, *_: not data.get("has_character_data", False)
),
Column(
Row(
Button(Const("🏰 Кампании"), id="campaigns", on_click=on_campaigns),
Button(Const("🎒 Инвентарь"), id="inventory", on_click=on_inventory),
),
Row(
Button(Const("📈 Рейтинг"), id="rating", on_click=on_rating),
Button(Const("📤 Обновить .json"), id="update_json", on_click=on_update),
),
getter=character_data_getter,
state=Academy.main,
Cancel(Const("⬅️ Назад")),
),
on_start=redirect,
)
getter=character_data_getter,
state=Academy.main,
),
on_start=redirect,
)

router.include_router(academy_dialog)
87 changes: 53 additions & 34 deletions handlers/player/academy_campaigns.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
from aiogram import Router
from aiogram.types import CallbackQuery
from aiogram_dialog import Dialog, DialogManager, Window
from aiogram_dialog.widgets.kbd import Button, Cancel, ScrollingGroup, Select
from aiogram_dialog.widgets.kbd import Cancel, ScrollingGroup, Select
from aiogram_dialog.widgets.media import DynamicMedia
from aiogram_dialog.widgets.text import Const, Format
from aiogram_dialog.widgets.text import Const, Format, Multi

from db.models import Participation
from services.campaigns import campaign_getter
Expand All @@ -19,53 +19,72 @@

async def campaigns_getter(dialog_manager: DialogManager, **kwargs):
user = dialog_manager.middleware_data["user"]
participations = await Participation.filter(user=user, campaign__verified=True).prefetch_related("campaign").all()

return {
"campaigns": await Participation.filter(user=user, campaign__verified=True).prefetch_related("campaign").all()
"campaigns": participations,
"has_campaigns": len(participations) > 0,
}


async def on_campaign(c: CallbackQuery, b: Button, m: DialogManager, participation_id: UUID):
async def on_campaign(c: CallbackQuery, b: Select, m: DialogManager, participation_id: UUID):
participation = await Participation.get(id=participation_id).prefetch_related("campaign")
await m.start(
AcademyCampaignPreview.preview,
data={"campaign_id": participation.campaign.id, "participation_id": participation.id},
)


router.include_router(
Dialog(
Window(
Const("Кампании внутри академии, в которых вы участвуете"),
ScrollingGroup(
Select(
Format("{item.campaign.title}"),
id="campaign",
items="campaigns",
item_id_getter=lambda x: x.id,
on_click=on_campaign,
),
hide_on_single_page=True,
height=5,
id="campaigns",
# Диалог списка кампаний академии
campaigns_dialog = Dialog(
Window(
Multi(
Const("🏰 Кампании академии"),
Const(""),
Const("Здесь собраны официальные кампании, в которых вы участвуете."),
Const(""),
Const("📭 У вас пока нет кампаний в академии", when=lambda data, *_: not data.get("has_campaigns", False)),
sep="\n",
),
ScrollingGroup(
Select(
Format("🎮 {item.campaign.title}"),
id="campaign",
items="campaigns",
item_id_getter=lambda x: x.id,
on_click=on_campaign,
type_factory=UUID,
),
Cancel(Const("Назад")),
getter=campaigns_getter,
state=AcademyCampaigns.campaigns,
hide_on_single_page=True,
height=5,
id="campaigns",
when="has_campaigns",
),
on_start=redirect,
)
Cancel(Const("⬅️ Назад")),
getter=campaigns_getter,
state=AcademyCampaigns.campaigns,
),
on_start=redirect,
)


router.include_router(
Dialog(
Window(
Format("Информация о кампании: {title}\n\nОписание: {description}\n\nВыберите действие:"),
DynamicMedia("icon"),
Cancel(Const("Назад")),
getter=campaign_getter,
state=AcademyCampaignPreview.preview,
# Диалог предпросмотра кампании
preview_dialog = Dialog(
Window(
DynamicMedia("icon"),
Multi(
Format("🎓 Информация о кампании: {title}"),
Const(""),
Format("📝 Описание: {description}"),
Const(""),
Const("Здесь вы можете управлять своей кампанией."),
sep="\n",
),
on_start=redirect,
)
Cancel(Const("⬅️ Назад")),
getter=campaign_getter,
state=AcademyCampaignPreview.preview,
),
on_start=redirect,
)

router.include_routers(campaigns_dialog, preview_dialog)
Loading
Loading