diff --git a/bot.py b/bot.py index 4dbfb64..c66bcec 100644 --- a/bot.py +++ b/bot.py @@ -480,6 +480,12 @@ class VKBotApplication: ids |= self._runtime_admins() return sorted(ids) + def _admin_display(self, uid: int) -> str: + """ФИО из VK + ссылка, если имя удалось получить, иначе только ссылка + (используется в мастере напоминалок, чтобы не кликать по каждому id).""" + name = self._vk_name(uid) + return f"{name} (vk.com/id{uid})" if name else f"vk.com/id{uid}" + def _send_reminders_admin(self, user_id: int): """Раздел «Напоминалки»: список активных + инструкции.""" rows = db.get_active_reminders() @@ -487,7 +493,7 @@ class VKBotApplication: for r in rows: dt = datetime.strptime(r["next_at"], "%Y-%m-%d %H:%M:%S") who = "всем админам" if r["recipients"] == "all" else \ - ", ".join(f"id{uid}" for uid in r["recipients"]) + ", ".join(self._admin_display(uid) for uid in r["recipients"]) period = REMINDER_PERIOD_LABELS.get(r["recurrence"], r["recurrence"]) short = (r["text"][:50] + "…") if len(r["text"]) > 50 else r["text"] listing += (f"🔹 [{r['id']}] {dt.strftime('%d.%m.%Y %H:%M')} ({period}) → {who}\n" @@ -497,13 +503,14 @@ class VKBotApplication: kb = VkKeyboard(inline=True) kb.add_button("➕ Добавить", color=VkKeyboardColor.PRIMARY) kb.add_line() + kb.add_button("🗑 Удалить напоминание", color=VkKeyboardColor.NEGATIVE) + kb.add_line() kb.add_button("В админку ↩️", color=VkKeyboardColor.SECONDARY) self.send_message( user_id, "⏰ Напоминалки\n\n" f"{listing}\n" - "Чтобы удалить: напоминалка удалить \n" - "Чтобы добавить: нажмите «➕ Добавить»", + "Управляйте кнопками ниже: ➕ добавить • 🗑 удалить", keyboard=kb.get_keyboard() ) @@ -663,6 +670,17 @@ class VKBotApplication: elif text_lower.startswith("напоминалка удалить"): self._handle_reminder_delete(user_id, text_clean) return + elif text_lower in ["🗑 удалить напоминание", "удалить напоминание"]: + rows = db.get_active_reminders() + if not rows: + self.send_message(user_id, "Активных напоминаний нет.") + self._send_reminders_admin(user_id) + return + items = [(r["id"], r["text"]) for r in rows] + db.update_user_state(user_id, "ADMIN_REMINDER_DEL_PICK") + self.send_message(user_id, "🗑 Какое напоминание удалить? Выберите:", + keyboard=get_pick_keyboard(items)) + return elif text_lower in ["уведомления: вкл 🔔", "уведомления: выкл 🔕", "уведомления", "уведомления 🔔", "уведомления 🔕"]: self._toggle_admin_notifications(user_id) return @@ -1697,6 +1715,16 @@ class VKBotApplication: return # ---------- Напоминалки ---------- + if state == "ADMIN_REMINDER_DEL_PICK": + rid = pick_id(text) + if not rid.isdigit() or not db.delete_reminder(int(rid)): + self.send_message(user_id, "⚠️ Выберите напоминание кнопкой ниже.") + return + db.update_user_state(user_id, "FREE_CHAT") + self.send_message(user_id, f"✅ Напоминание №{rid} удалено.") + self._send_reminders_admin(user_id) + return + if state == "ADMIN_REMINDER_DATE": dt = parse_reminder_datetime(text) if not dt: @@ -1719,7 +1747,7 @@ class VKBotApplication: self._admin_ctx.setdefault(user_id, {})["text"] = text.strip() admins = self._all_admin_ids() self._admin_ctx[user_id]["admins_list"] = admins - listing = "\n".join(f"{i + 1}. vk.com/id{a}" for i, a in enumerate(admins)) + listing = "\n".join(f"{i + 1}. {self._admin_display(a)}" for i, a in enumerate(admins)) db.update_user_state(user_id, "ADMIN_REMINDER_RECIPIENTS") self.send_message( user_id, diff --git a/tests/test_flow.py b/tests/test_flow.py index 34216e9..7d95564 100644 --- a/tests/test_flow.py +++ b/tests/test_flow.py @@ -417,3 +417,18 @@ def test_admin_reminder_delete(app, monkeypatch): # поэтому проверяем все сообщения этого шага, а не только последнее. new_msgs = [s["msg"] for s in app._sent[before:]] assert any("не найдено" in m for m in new_msgs) + + +def test_admin_reminder_delete_via_picker_button(app, monkeypatch): + """Удаление через кнопку «🗑 Удалить напоминание» + выбор из списка (без ввода id вручную).""" + admin = 80005 + monkeypatch.setattr(bot.config, "ADMIN_IDS", [admin]) + rid = bot.db.add_reminder("Продлить хостинг", "2099-01-01 09:00:00", "once", [admin], created_by=admin) + + app.handle_message(admin, "⏰ Напоминалки") + app.handle_message(admin, "🗑 Удалить напоминание") + assert _state(admin) == "ADMIN_REMINDER_DEL_PICK" + + app.handle_message(admin, f"{rid}. Продлить хостинг") # клик по кнопке пикера + assert _state(admin) == "FREE_CHAT" + assert not bot.db.get_active_reminders()