Unification of pagination, admins control and more

This commit is contained in:
2026-03-02 19:02:20 +07:00
parent 035170e46f
commit eab67ccfc1
13 changed files with 271 additions and 118 deletions

View File

@@ -1,12 +1,15 @@
from typing import Optional
import hashlib
from aiogram import Router, F
from aiogram.fsm.context import FSMContext
from aiogram.types import CallbackQuery, Message
from sqlalchemy.ext.asyncio import AsyncSession
from config import PAGE_SIZE
from misc.kb.client import render_products
from misc.kb.common import return_menu
from misc.redis import RedisClient
from misc.states import SearchStorage
from repositories.products import ProductRepository
@@ -28,31 +31,62 @@ async def searching(
state: FSMContext,
session: AsyncSession,
products_repo: ProductRepository,
redis_client: RedisClient,
):
data = await state.get_data()
await state.clear()
orig_msg: Optional[Message] = data.get("msg")
await msg.delete()
orig_msg: Optional[Message] = data.get("msg") or await msg.answer("")
await orig_msg.edit_text("⏳ Поиск...")
results = await products_repo.search(
session,
msg.text,
)
if not orig_msg:
await msg.answer(
"here",
reply_markup=render_products(
results,
product_cb_factory=lambda p: f"product:{p.id}",
back_cb="menu:main",
next_cb="",
),
)
return
next_cb = None
if len(results) > PAGE_SIZE:
query_hash = hashlib.sha256(msg.text.encode()).hexdigest()[:16]
await redis_client.set_search_query(query_hash, msg.text)
next_cb = f"search:{query_hash}:1"
await orig_msg.edit_text(
"here",
reply_markup=render_products(
results, product_cb_factory=lambda p: f"product:{p.id}", back_cb="menu:main"
results[:PAGE_SIZE],
product_cb_factory=lambda p: f"product:{p.id}",
back_cb="menu:main",
next_cb=next_cb,
),
)
@router.callback_query(F.data.startswith("search:"))
async def search_pagination(
cb: CallbackQuery,
state: FSMContext,
session: AsyncSession,
products_repo: ProductRepository,
redis_client: RedisClient,
):
await state.clear()
data = cb.data.split(":")
q_hash = data[1]
page = int(data[2])
query = await redis_client.get_search_query(q_hash)
if not query:
await cb.message.edit_text("🍃 Попробуйте ещё раз...")
results = await products_repo.search(session, query, offset=PAGE_SIZE * page)
await cb.message.edit_reply_markup(
reply_markup=render_products(
results[:PAGE_SIZE],
product_cb_factory=lambda p: f"product:{p.id}",
back_cb="menu:main",
next_cb=f"search:{q_hash}:{page + 1}" if len(results) > PAGE_SIZE else None,
prev_cb=f"search:{q_hash}:{page - 1}" if page > 0 else None,
)
)