keep back button in dialog window: single photo via DynamicMedia, media group via bot with caption

This commit is contained in:
2026-07-15 01:05:02 +03:00
parent 16e9d7f124
commit 504c454afb
4 changed files with 104 additions and 36 deletions
@@ -1,10 +1,13 @@
from aiogram import Bot
from aiogram.enums import ContentType
from aiogram.types import Message, CallbackQuery, InputMediaPhoto
from aiogram.utils.markdown import html_decoration as hd
from aiogram_dialog import Window, DialogManager
from aiogram_dialog.widgets.text import Format, Const
from aiogram_dialog.widgets.kbd import Row, SwitchTo, Button, ScrollingGroup, Select, Group
from aiogram_dialog.widgets.input import MessageInput
from aiogram_dialog.widgets.media import DynamicMedia
from aiogram_dialog.api.entities.media import MediaAttachment, MediaId
from magic_filter import F
from dishka import FromDishka
from dishka.integrations.aiogram_dialog import inject
@@ -633,7 +636,7 @@ async def on_transaction_selected(
tx = await transactions_repository.get_transaction_by_id(int(item_id))
if tx:
photo_file_ids = HoursTransactionsRepository.get_photo_file_ids(tx)
if photo_file_ids:
if len(photo_file_ids) > 1:
operation = "Начислено" if tx.transaction_type == "increase" else "Списано"
emoji = "+" if tx.transaction_type == "increase" else ""
msk_time = tx.created_at.astimezone(msk_now().tzinfo).replace(tzinfo=None)
@@ -648,11 +651,8 @@ async def on_transaction_selected(
caption = f"📋 <b>Детали транзакции</b>\n\n⚙️ <b>Операция:</b> {operation}\n🔢 <b>Количество:</b> {emoji}<code>{tx.amount}</code> ч\n📅 <b>Дата:</b> {date_str}{remark_text}{admin_info}"
bot: Bot = dialog_manager.middleware_data.get("bot")
try:
if len(photo_file_ids) == 1:
await bot.send_photo(callback.message.chat.id, photo_file_ids[0], caption=caption)
else:
media = [InputMediaPhoto(media=fid, caption=caption if i == 0 else None) for i, fid in enumerate(photo_file_ids)]
await bot.send_media_group(callback.message.chat.id, media=media)
media = [InputMediaPhoto(media=fid, caption=caption if i == 0 else None) for i, fid in enumerate(photo_file_ids)]
await bot.send_media_group(callback.message.chat.id, media=media)
except Exception:
pass
await dialog_manager.switch_to(AdminMenuSG.resident_history_detail)
@@ -669,12 +669,12 @@ async def get_transaction_detail_data(
tx_id = dialog_manager.dialog_data.get("selected_transaction_id")
if not tx_id:
return {"detail_content": "Ошибка: транзакция не выбрана"}
return {"detail_content": "Ошибка: транзакция не выбрана", "photo_media": None, "has_multiple_photos": False}
tx = await transactions_repository.get_transaction_by_id(int(tx_id))
if not tx:
return {"detail_content": "Ошибка: транзакция не найдена"}
return {"detail_content": "Ошибка: транзакция не найдена", "photo_media": None, "has_multiple_photos": False}
operation = "Начислено" if tx.transaction_type == "increase" else "Списано"
emoji = "+" if tx.transaction_type == "increase" else ""
@@ -698,8 +698,24 @@ async def get_transaction_detail_data(
📅 <b>Дата:</b> {date_str}{remark_text}{admin_info}
"""
photo_file_ids = HoursTransactionsRepository.get_photo_file_ids(tx)
photo_media = None
has_multiple_photos = len(photo_file_ids) > 1
if photo_file_ids and not has_multiple_photos:
photo_media = MediaAttachment(
type=ContentType.PHOTO,
file_id=MediaId(file_id=photo_file_ids[0]),
)
if has_multiple_photos:
detail_content = ""
else:
detail_content = content
return {
"detail_content": content,
"detail_content": detail_content,
"photo_media": photo_media,
"has_multiple_photos": has_multiple_photos,
}
@@ -1125,6 +1141,7 @@ resident_history_window = Window(
)
resident_history_detail_window = Window(
DynamicMedia("photo_media"),
Format("{detail_content}"),
SwitchTo(
Const("◀️ К списку"),
@@ -1,12 +1,15 @@
import json
from aiogram import Bot
from aiogram.enums import ContentType
from aiogram.exceptions import TelegramBadRequest, TelegramForbiddenError, TelegramRetryAfter
from aiogram.types import Message, CallbackQuery, InputMediaPhoto
from aiogram_dialog import Window, DialogManager
from aiogram_dialog.widgets.text import Format, Const
from aiogram_dialog.widgets.kbd import SwitchTo, Button, ScrollingGroup, Select, Row, Group
from aiogram_dialog.widgets.input import MessageInput
from aiogram_dialog.widgets.media import DynamicMedia
from aiogram_dialog.api.entities.media import MediaAttachment, MediaId
from dishka import FromDishka
from dishka.integrations.aiogram_dialog import inject
@@ -514,7 +517,7 @@ async def on_room_transaction_selected(
tx = await transactions_repository.get_transaction_by_id(int(item_id))
if tx:
photo_file_ids = HoursTransactionsRepository.get_photo_file_ids(tx)
if photo_file_ids:
if len(photo_file_ids) > 1:
operation = "Начислено" if tx.transaction_type == "increase" else "Списано"
emoji = "+" if tx.transaction_type == "increase" else ""
msk_time = tx.created_at.astimezone(msk_now().tzinfo).replace(tzinfo=None)
@@ -529,11 +532,8 @@ async def on_room_transaction_selected(
caption = f"📋 <b>Детали транзакции</b>\n\n⚙️ <b>Операция:</b> {operation}\n🔢 <b>Количество:</b> {emoji}<code>{tx.amount}</code> ч\n📅 <b>Дата:</b> {date_str}{remark_text}{admin_info}"
bot: Bot = dialog_manager.middleware_data.get("bot")
try:
if len(photo_file_ids) == 1:
await bot.send_photo(callback.message.chat.id, photo_file_ids[0], caption=caption)
else:
media = [InputMediaPhoto(media=fid, caption=caption if i == 0 else None) for i, fid in enumerate(photo_file_ids)]
await bot.send_media_group(callback.message.chat.id, media=media)
media = [InputMediaPhoto(media=fid, caption=caption if i == 0 else None) for i, fid in enumerate(photo_file_ids)]
await bot.send_media_group(callback.message.chat.id, media=media)
except Exception:
pass
await dialog_manager.switch_to(AdminMenuSG.room_history_detail)
@@ -549,12 +549,12 @@ async def get_room_transaction_detail_data(
tx_id = dialog_manager.dialog_data.get("selected_transaction_id")
if not tx_id:
return {"detail_content": "Ошибка: транзакция не выбрана"}
return {"detail_content": "Ошибка: транзакция не выбрана", "photo_media": None, "has_multiple_photos": False}
tx = await transactions_repository.get_transaction_by_id(int(tx_id))
if not tx:
return {"detail_content": "Ошибка: транзакция не найдена"}
return {"detail_content": "Ошибка: транзакция не найдена", "photo_media": None, "has_multiple_photos": False}
operation = "Начислено" if tx.transaction_type == "increase" else "Списано"
emoji = "+" if tx.transaction_type == "increase" else ""
@@ -578,8 +578,24 @@ async def get_room_transaction_detail_data(
📅 <b>Дата:</b> {date_str}{remark_text}{admin_info}
"""
photo_file_ids = HoursTransactionsRepository.get_photo_file_ids(tx)
photo_media = None
has_multiple_photos = len(photo_file_ids) > 1
if photo_file_ids and not has_multiple_photos:
photo_media = MediaAttachment(
type=ContentType.PHOTO,
file_id=MediaId(file_id=photo_file_ids[0]),
)
if has_multiple_photos:
detail_content = ""
else:
detail_content = content
return {
"detail_content": content,
"detail_content": detail_content,
"photo_media": photo_media,
"has_multiple_photos": has_multiple_photos,
}
@@ -822,6 +838,7 @@ room_history_window = Window(
)
room_history_detail_window = Window(
DynamicMedia("photo_media"),
Format("{detail_content}"),
SwitchTo(
Const("◀️ К списку"),
@@ -1,10 +1,13 @@
import json
from aiogram import Bot
from aiogram.enums import ContentType
from aiogram.types import CallbackQuery, InputMediaPhoto
from aiogram_dialog import Window
from aiogram_dialog.widgets.text import Format, Const
from aiogram_dialog.widgets.kbd import SwitchTo, ScrollingGroup, Select, Button
from aiogram_dialog.widgets.media import DynamicMedia
from aiogram_dialog.api.entities.media import MediaAttachment, MediaId
from dishka import FromDishka
from dishka.integrations.aiogram_dialog import inject
@@ -83,7 +86,7 @@ async def on_creator_transaction_selected(
tx = await transactions_repository.get_transaction_by_id(int(item_id))
if tx:
photo_file_ids = HoursTransactionsRepository.get_photo_file_ids(tx)
if photo_file_ids:
if len(photo_file_ids) > 1:
operation = "Начислено" if tx.transaction_type == "increase" else "Списано"
emoji = "+" if tx.transaction_type == "increase" else ""
room_mark = " 🚪" if tx.per_room else ""
@@ -103,11 +106,8 @@ async def on_creator_transaction_selected(
caption = f"📋 <b>Детали транзакции</b>\n\n⚙️ <b>Операция:</b> {operation}\n🔢 <b>Количество:</b> {emoji}<code>{tx.amount}</code> ч{room_mark}\n👤 <b>Резидент:</b> {resident_name} (к. {room_number}){admin_info}\n📅 <b>Дата:</b> {date_str}{remark_text}"
bot: Bot = dialog_manager.middleware_data.get("bot")
try:
if len(photo_file_ids) == 1:
await bot.send_photo(callback.message.chat.id, photo_file_ids[0], caption=caption)
else:
media = [InputMediaPhoto(media=fid, caption=caption if i == 0 else None) for i, fid in enumerate(photo_file_ids)]
await bot.send_media_group(callback.message.chat.id, media=media)
media = [InputMediaPhoto(media=fid, caption=caption if i == 0 else None) for i, fid in enumerate(photo_file_ids)]
await bot.send_media_group(callback.message.chat.id, media=media)
except Exception:
pass
await dialog_manager.switch_to(AdminMenuSG.transactions_history_detail)
@@ -125,12 +125,12 @@ async def get_transaction_detail_data(
tx_id = dialog_manager.dialog_data.get("selected_transaction_id")
if not tx_id:
return {"detail_content": "Ошибка: транзакция не выбрана"}
return {"detail_content": "Ошибка: транзакция не выбрана", "photo_media": None, "has_multiple_photos": False}
tx = await transactions_repository.get_transaction_by_id(int(tx_id))
if not tx:
return {"detail_content": "Ошибка: транзакция не найдена"}
return {"detail_content": "Ошибка: транзакция не найдена", "photo_media": None, "has_multiple_photos": False}
operation = "Начислено" if tx.transaction_type == "increase" else "Списано"
emoji = "+" if tx.transaction_type == "increase" else ""
@@ -162,8 +162,24 @@ async def get_transaction_detail_data(
📅 <b>Дата:</b> {date_str}{remark_text}
"""
photo_file_ids = HoursTransactionsRepository.get_photo_file_ids(tx)
photo_media = None
has_multiple_photos = len(photo_file_ids) > 1
if photo_file_ids and not has_multiple_photos:
photo_media = MediaAttachment(
type=ContentType.PHOTO,
file_id=MediaId(file_id=photo_file_ids[0]),
)
if has_multiple_photos:
detail_content = ""
else:
detail_content = content
return {
"detail_content": content,
"detail_content": detail_content,
"photo_media": photo_media,
"has_multiple_photos": has_multiple_photos,
}
@@ -192,6 +208,7 @@ transactions_history_window = Window(
)
transactions_history_detail_window = Window(
DynamicMedia("photo_media"),
Format("{detail_content}"),
SwitchTo(
Const("◀️ К списку"),
@@ -1,8 +1,11 @@
from aiogram import Bot
from aiogram.enums import ContentType
from aiogram.types import User, CallbackQuery, InputMediaPhoto
from aiogram_dialog import Window
from aiogram_dialog.widgets.text import Format, Const
from aiogram_dialog.widgets.kbd import Back, ScrollingGroup, Select, SwitchTo, Button
from aiogram_dialog.widgets.media import DynamicMedia
from aiogram_dialog.api.entities.media import MediaAttachment, MediaId
from dishka import FromDishka
from dishka.integrations.aiogram_dialog import inject
@@ -75,7 +78,7 @@ async def on_user_transaction_selected(
tx = await transactions_repository.get_transaction_by_id(int(item_id))
if tx:
photo_file_ids = HoursTransactionsRepository.get_photo_file_ids(tx)
if photo_file_ids:
if len(photo_file_ids) > 1:
operation = "Начислено" if tx.transaction_type == "increase" else "Списано"
emoji = "+" if tx.transaction_type == "increase" else ""
msk_time = tx.created_at.astimezone(msk_now().tzinfo).replace(tzinfo=None)
@@ -90,11 +93,8 @@ async def on_user_transaction_selected(
caption = f"📋 <b>Детали транзакции</b>\n\n⚙️ <b>Операция:</b> {operation}\n🔢 <b>Количество:</b> {emoji}<code>{tx.amount}</code> ч\n📅 <b>Дата:</b> {date_str}{remark_text}{admin_info}"
bot: Bot = dialog_manager.middleware_data.get("bot")
try:
if len(photo_file_ids) == 1:
await bot.send_photo(callback.message.chat.id, photo_file_ids[0], caption=caption)
else:
media = [InputMediaPhoto(media=fid, caption=caption if i == 0 else None) for i, fid in enumerate(photo_file_ids)]
await bot.send_media_group(callback.message.chat.id, media=media)
media = [InputMediaPhoto(media=fid, caption=caption if i == 0 else None) for i, fid in enumerate(photo_file_ids)]
await bot.send_media_group(callback.message.chat.id, media=media)
except Exception:
pass
await dialog_manager.switch_to(MainMenuSG.history_detail)
@@ -112,12 +112,12 @@ async def get_history_detail_data(
tx_id = dialog_manager.dialog_data.get("selected_transaction_id")
if not tx_id:
return {"detail_content": "Ошибка: транзакция не выбрана"}
return {"detail_content": "Ошибка: транзакция не выбрана", "photo_media": None, "has_multiple_photos": False}
tx = await transactions_repository.get_transaction_by_id(int(tx_id))
if not tx:
return {"detail_content": "Ошибка: транзакция не найдена"}
return {"detail_content": "Ошибка: транзакция не найдена", "photo_media": None, "has_multiple_photos": False}
operation = "Начислено" if tx.transaction_type == "increase" else "Списано"
emoji = "+" if tx.transaction_type == "increase" else ""
@@ -141,8 +141,24 @@ async def get_history_detail_data(
📅 <b>Дата:</b> {date_str}{remark_text}{admin_info}
"""
photo_file_ids = HoursTransactionsRepository.get_photo_file_ids(tx)
photo_media = None
has_multiple_photos = len(photo_file_ids) > 1
if photo_file_ids and not has_multiple_photos:
photo_media = MediaAttachment(
type=ContentType.PHOTO,
file_id=MediaId(file_id=photo_file_ids[0]),
)
if has_multiple_photos:
detail_content = ""
else:
detail_content = content
return {
"detail_content": content,
"detail_content": detail_content,
"photo_media": photo_media,
"has_multiple_photos": has_multiple_photos,
}
@@ -167,6 +183,7 @@ history_window = Window(
)
history_detail_window = Window(
DynamicMedia("photo_media"),
Format("{detail_content}"),
SwitchTo(
Const("◀️ К списку"),