Напоминалки: кнопка удаления списком и ФИО получателей вместо голых id

- В разделе «Напоминалки» добавлена кнопка «🗑 Удалить напоминание» с выбором
  из списка (как в разделе «Быстрые ответы»), не только текстовая команда.
- При выборе получателей и в списке напоминаний теперь показывается ФИО
  админа из VK рядом со ссылкой (если удалось получить), чтобы не кликать
  по каждой ссылке для опознания.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Kenik
2026-09-05 14:08:49 +03:00
parent 6d4dd16caf
commit fc79da8f83
2 changed files with 47 additions and 4 deletions
+32 -4
View File
@@ -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"
"Чтобы удалить: напоминалка удалить <id>\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,
+15
View File
@@ -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()