fix: fixed a bug with the message not changing

This commit is contained in:
Danil 2025-05-17 12:26:29 +03:00
parent ff8d23330b
commit 6f415c2378

View file

@ -1,6 +1,9 @@
from aiogram import Router, types from aiogram import Router, types
from aiogram.filters import Command from aiogram.filters import Command
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton from aiogram.types import InlineKeyboardMarkup, \
InlineKeyboardButton, \
CallbackQuery
import json
from bot import db from bot import db
from i18n.localization import I18n from i18n.localization import I18n
@ -44,8 +47,10 @@ def build_options_keyboard(
buttons.append(row) buttons.append(row)
if back_callback: if back_callback:
buttons.append([ buttons.append([
InlineKeyboardButton(text=locale.get("back"), InlineKeyboardButton(
callback_data=back_callback) text=locale.get("back"),
callback_data=back_callback
)
]) ])
return InlineKeyboardMarkup(inline_keyboard=buttons) return InlineKeyboardMarkup(inline_keyboard=buttons)
@ -75,12 +80,57 @@ def get_chart_toggle_keyboard(
], ],
]) ])
def markup_to_json(markup: InlineKeyboardMarkup | None) -> str | None:
if markup is None:
return None
# model_dump() возвращает dict с данными
return json.dumps(markup.model_dump(), sort_keys=True)
async def safe_edit_message_text(
callback: CallbackQuery,
new_text: str,
new_reply_markup: InlineKeyboardMarkup | None = None,
parse_mode: str | None = None,
) -> None:
message = callback.message
current_text = (message.text or "").strip()
new_text_clean = new_text.strip()
is_text_same = (current_text == new_text_clean)
current_markup = message.reply_markup
is_markup_same = markup_to_json(current_markup) == markup_to_json(new_reply_markup)
if is_text_same and is_markup_same:
await callback.answer()
return
await message.edit_text(
new_text,
reply_markup=new_reply_markup,
parse_mode=parse_mode
)
await callback.answer()
@router.message(Command("settings")) @router.message(Command("settings"))
async def settings_handler(message: types.Message): async def settings_handler(message: types.Message):
data = await db.fetch( data = await db.fetch(
'SELECT lang FROM users WHERE user_id = $1', 'SELECT lang FROM users WHERE user_id = $1',
message.from_user.id message.from_user.id
) )
if not data:
await db.insert(
'INSERT INTO users (user_id) VALUES (?)',
message.from_user.id
)
data = await db.fetch(
'SELECT lang FROM users WHERE user_id = $1',
message.from_user.id
)
lang = data.get('lang', 'en') lang = data.get('lang', 'en')
locale = i18n.get_locale(lang) locale = i18n.get_locale(lang)
@ -101,7 +151,7 @@ async def settings_handler(message: types.Message):
) )
@router.callback_query(lambda c: c.data == "setting_lang") @router.callback_query(lambda c: c.data == "setting_lang")
async def show_language_menu(callback: types.CallbackQuery): async def show_language_menu(callback: CallbackQuery):
data = await db.fetch( data = await db.fetch(
'SELECT lang FROM users WHERE user_id = $1', 'SELECT lang FROM users WHERE user_id = $1',
callback.from_user.id callback.from_user.id
@ -117,14 +167,14 @@ async def show_language_menu(callback: types.CallbackQuery):
buttons_per_row=2, buttons_per_row=2,
back_callback="back_to_settings" back_callback="back_to_settings"
) )
await callback.message.edit_text( await safe_edit_message_text(
locale.get("choose_language"), callback,
reply_markup=keyboard new_text=locale.get("choose_language"),
new_reply_markup=keyboard
) )
await callback.answer()
@router.callback_query(lambda c: c.data and c.data.startswith("lang_")) @router.callback_query(lambda c: c.data and c.data.startswith("lang_"))
async def language_selected(callback: types.CallbackQuery): async def language_selected(callback: CallbackQuery):
lang = callback.data.split("_")[1] lang = callback.data.split("_")[1]
await db.update( await db.update(
'UPDATE users SET lang = $1 WHERE user_id = $2', 'UPDATE users SET lang = $1 WHERE user_id = $2',
@ -141,16 +191,18 @@ async def language_selected(callback: types.CallbackQuery):
back_callback="back_to_settings" back_callback="back_to_settings"
) )
await callback.message.edit_text( await safe_edit_message_text(
locale.get("choose_language"), callback,
reply_markup=keyboard new_text=locale.get("choose_language"),
new_reply_markup=keyboard
) )
await callback.answer( await callback.answer(
locale.get("language_set").format(lang=lang.upper()) locale.get("language_set").format(lang=lang.upper())
) )
@router.callback_query(lambda c: c.data == "back_to_settings") @router.callback_query(lambda c: c.data == "back_to_settings")
async def back_to_settings(callback: types.CallbackQuery): async def back_to_settings(callback: CallbackQuery):
data = await db.fetch( data = await db.fetch(
'SELECT lang FROM users WHERE user_id = $1', 'SELECT lang FROM users WHERE user_id = $1',
callback.from_user.id callback.from_user.id
@ -169,14 +221,14 @@ async def back_to_settings(callback: types.CallbackQuery):
], ],
]) ])
await callback.message.edit_text( await safe_edit_message_text(
locale.get("settings_title"), callback,
reply_markup=settings_keyboard new_text=locale.get("settings_title"),
new_reply_markup=settings_keyboard
) )
await callback.answer()
@router.callback_query(lambda c: c.data == "setting_chart") @router.callback_query(lambda c: c.data == "setting_chart")
async def show_chart_settings(callback: types.CallbackQuery): async def show_chart_settings(callback: CallbackQuery):
data = await db.fetch( data = await db.fetch(
'SELECT chart, chart_period, lang FROM users WHERE user_id = $1', 'SELECT chart, chart_period, lang FROM users WHERE user_id = $1',
callback.from_user.id callback.from_user.id
@ -192,16 +244,23 @@ async def show_chart_settings(callback: types.CallbackQuery):
else locale.get("disabled", "Disabled") else locale.get("disabled", "Disabled")
period_text = locale.get(period, period) period_text = locale.get(period, period)
text = f'{locale.get('chart_settings')}\n' \
f'{locale.get('status')}: {status_text}\n' \ text = (
f'{locale.get('period')}: {period_text}' f"{locale.get('chart_settings')}\n"
f"{locale.get('status')}: {status_text}\n"
f"{locale.get('period')}: {period_text}"
)
keyboard = get_chart_toggle_keyboard(chart_status, locale) keyboard = get_chart_toggle_keyboard(chart_status, locale)
await callback.message.edit_text(text, reply_markup=keyboard)
await callback.answer() await safe_edit_message_text(
callback,
new_text=text,
new_reply_markup=keyboard
)
@router.callback_query(lambda c: c.data == "chart_toggle") @router.callback_query(lambda c: c.data == "chart_toggle")
async def toggle_chart(callback: types.CallbackQuery): async def toggle_chart(callback: CallbackQuery):
data = await db.fetch( data = await db.fetch(
'SELECT chart, lang FROM users WHERE user_id = $1', 'SELECT chart, lang FROM users WHERE user_id = $1',
callback.from_user.id callback.from_user.id
@ -221,10 +280,11 @@ async def toggle_chart(callback: types.CallbackQuery):
locale.get(f"chart_now_{'enabled' if new_status else 'disabled'}", locale.get(f"chart_now_{'enabled' if new_status else 'disabled'}",
f"Chart now {'enabled' if new_status else 'disabled'}") f"Chart now {'enabled' if new_status else 'disabled'}")
) )
await show_chart_settings(callback) await show_chart_settings(callback)
@router.callback_query(lambda c: c.data == "chart_period") @router.callback_query(lambda c: c.data == "chart_period")
async def change_chart_period(callback: types.CallbackQuery): async def change_chart_period(callback: CallbackQuery):
data = await db.fetch( data = await db.fetch(
'SELECT chart_period, lang FROM users WHERE user_id = $1', 'SELECT chart_period, lang FROM users WHERE user_id = $1',
callback.from_user.id callback.from_user.id
@ -242,20 +302,25 @@ async def change_chart_period(callback: types.CallbackQuery):
buttons_per_row=2, buttons_per_row=2,
back_callback="setting_chart" back_callback="setting_chart"
) )
await callback.message.edit_text( await safe_edit_message_text(
locale.get("choose_period"), callback,
reply_markup=keyboard new_text=locale.get("choose_period"),
new_reply_markup=keyboard
) )
await callback.answer()
@router.callback_query(lambda c: c.data and c.data.startswith("period_")) @router.callback_query(lambda c: c.data and c.data.startswith("period_"))
async def set_chart_period(callback: types.CallbackQuery): async def set_chart_period(callback: CallbackQuery):
period = callback.data.split("_")[1] period = callback.data.split("_")[1]
await db.update( await db.update(
'UPDATE users SET chart_period = $1 WHERE user_id = $2', 'UPDATE users SET chart_period = $1 WHERE user_id = $2',
period, callback.from_user.id period, callback.from_user.id
) )
locale = i18n.get_locale(period) data = await db.fetch(
'SELECT lang FROM users WHERE user_id = $1',
callback.from_user.id
)
lang = data.get('lang', 'en')
locale = i18n.get_locale(lang)
keyboard = build_options_keyboard( keyboard = build_options_keyboard(
options=period_options, options=period_options,
@ -266,9 +331,10 @@ async def set_chart_period(callback: types.CallbackQuery):
back_callback="setting_chart" back_callback="setting_chart"
) )
await callback.message.edit_text( await safe_edit_message_text(
locale.get("choose_period"), callback,
reply_markup=keyboard new_text=locale.get("choose_period"),
new_reply_markup=keyboard
) )
await callback.answer( await callback.answer(