Untitled

 avatar
4ae4d
plain_text
4 months ago
5.7 kB
5
Indexable
--- a/src/bot/core/handlers/events_filters.py
+++ b/src/bot/core/handlers/events_filters.py
@@
 from dialog_bot_sdk.entities.messaging import UpdateInteractiveMediaEvent
 
-from core.bot_kit.fsm import FSMContext
+from core.bot_kit.fsm import FSMContext, State, StatesGroup
 from core.config import bot
 from core.handlers.events_ui import send_city_events_page, send_my_events_page, send_points_page
 from core.markups.events_filters import events_filters_menu_keyboard
+from core.markups.tags import TagChoice
 from core.services.event import EventService
+from core.services.tag import TagService
 from core.utils import delete_prev_message_by_peer
 from core.utils.events_filter import (
     format_events_filter_summary,
     get_events_filter,
     reset_events_filter,
+    set_events_filter,
 )
+from core.utils.tags_toggle_ui import TagsToggleCfg, is_done, parse_toggle_key, send_tags_toggle_ui
 
 
+class EventsFiltersTagsState(StatesGroup):
+    tags = State()
+
+
+FILTERS_TAGS_CFG = TagsToggleCfg(
+    media_id="events_filters_tags_toggle",
+    toggle_prefix="toggle:",
+    done_value="done",
+)
+
+_CTX_KEY = "events_filters_edit_ctx"
+_OFFSET_KEY = "events_filters_edit_offset"
+_TAG_IDS_KEY = "events_filters_tags_selected"
+
+
 def _split_ctx_offset(raw: object) -> tuple[str, int]:
@@
     return ctx, off
 
 
@@
 def events_filters_open_handler(
@@
     bot.messaging.send_message(
         peer=event.peer,
         text=f"🧰 *Фильтры*\n\n{summary}\n\nВыбери, что изменить:",
         interactive_media_groups=events_filters_menu_keyboard(ctx_name=ctx_name, offset=offset),
     )
 
@@
 def events_filters_not_implemented_handler(event: UpdateInteractiveMediaEvent, context: FSMContext):
@@
     bot.messaging.send_message(
         peer=event.peer,
         text=f"⚠️ Пока не реализовано в этом коммите.\n\n{summary}\n\nВыбери, что изменить:",
         interactive_media_groups=events_filters_menu_keyboard(ctx_name=ctx_name, offset=offset),
     )
+
+
+def _tag_choices_from_backend(all_tags) -> list[TagChoice]:
+    out: list[TagChoice] = []
+    for t in all_tags or []:
+        tid = getattr(t, "id", None)
+        name = getattr(t, "name", None)
+        if tid and name:
+            out.append(TagChoice(key=str(tid), label=str(name)))
+    return out
+
+
[email protected]
+def events_filters_tags_open_handler(
+    event: UpdateInteractiveMediaEvent,
+    context: FSMContext,
+    event_service: EventService,
+    tag_service: TagService,
+):
+    delete_prev_message_by_peer(bot, event.peer)
+    context.set_state(None)
+
+    ctx_name, offset = _split_ctx_offset(event.data.value)
+    flt = get_events_filter(context, ctx_name=ctx_name)
+    selected_ids = set(flt.tag_ids or [])
+
+    all_tags = tag_service.get_all_tags()
+    choices = _tag_choices_from_backend(all_tags)
+
+    # сохраняем "куда вернуться"
+    context.update_data(
+        {
+            _CTX_KEY: ctx_name,
+            _OFFSET_KEY: int(offset),
+            _TAG_IDS_KEY: list(selected_ids),
+        }
+    )
+    context.set_state(EventsFiltersTagsState.tags)
+
+    send_tags_toggle_ui(
+        peer=event.peer,
+        title="🏷️ *Фильтры: теги*\n\nВыбери теги, затем нажми «Готово»:",
+        choices=choices,
+        selected_keys=set(selected_ids),
+        cfg=FILTERS_TAGS_CFG,
+        done_label="✅ Готово",
+    )
+
+
[email protected]
+def events_filters_tags_toggle_handler(
+    event: UpdateInteractiveMediaEvent,
+    context: FSMContext,
+    event_service: EventService,
+    tag_service: TagService,
+):
+    state = context.get_state()
+    if not (state == EventsFiltersTagsState.tags or str(state) == str(EventsFiltersTagsState.tags)):
+        return
+
+    delete_prev_message_by_peer(bot, event.peer)
+
+    raw = str(event.data.value or "")
+    data = context.get_data() or {}
+
+    ctx_name = str(data.get(_CTX_KEY) or "events")
+    offset = int(data.get(_OFFSET_KEY) or 0)
+    selected = set(data.get(_TAG_IDS_KEY) or [])
+
+    # DONE -> сохранить filter.tag_ids и вернуться в меню фильтров
+    if is_done(raw, FILTERS_TAGS_CFG):
+        flt = get_events_filter(context, ctx_name=ctx_name)
+        flt.tag_ids = sorted([str(x) for x in selected if str(x).strip()])
+        set_events_filter(context, ctx_name=ctx_name, flt=flt)
+
+        context.set_state(None)
+        # чистим только "служебные" ключи экрана выбора тегов
+        context.update_data({_CTX_KEY: None, _OFFSET_KEY: None, _TAG_IDS_KEY: None})
+
+        summary = format_events_filter_summary(get_events_filter(context, ctx_name=ctx_name))
+        bot.messaging.send_message(
+            peer=event.peer,
+            text=f"🧰 *Фильтры*\n\n{summary}\n\nВыбери, что изменить:",
+            interactive_media_groups=events_filters_menu_keyboard(ctx_name=ctx_name, offset=offset),
+        )
+        return
+
+    # TOGGLE
+    key = parse_toggle_key(raw, FILTERS_TAGS_CFG)
+    if not key:
+        return
+
+    if key in selected:
+        selected.remove(key)
+    else:
+        selected.add(key)
+
+    context.update_data({_TAG_IDS_KEY: list(selected)})
+
+    all_tags = tag_service.get_all_tags()
+    choices = _tag_choices_from_backend(all_tags)
+
+    send_tags_toggle_ui(
+        peer=event.peer,
+        title="🏷️ *Фильтры: теги*\n\nВыбери теги, затем нажми «Готово»:",
+        choices=choices,
+        selected_keys=set(selected),
+        cfg=FILTERS_TAGS_CFG,
+        done_label="✅ Готово",
+    )
Editor is loading...
Leave a Comment