feat: rich command templates with public links + media text-first flow

- Command templates now match notification template style: type icons,
  linked filenames via album shared links, location, favorite status
- Media mode sends text message first, then media as reply (was media-only)
- Search/find/person/place resolve asset public URLs from tracked albums'
  shared links (share/{key}/photos/{id})
- Albums/summary commands include album public_url in context
- Enriched command template preview sample context with public_url, city,
  country, is_favorite
- Extract sanitizePreview to shared lib/sanitize.ts
- Command template preview now renders HTML links (was raw text)
- Global provider filter moved above search in sidebar
- CLAUDE.md: template consistency + context variable sync rules
This commit is contained in:
2026-03-24 16:48:57 +03:00
parent f90cc36ebd
commit d0bc767e98
26 changed files with 253 additions and 116 deletions
@@ -211,7 +211,12 @@ async def _poll_bot(bot_id: int) -> None:
message_id = message.get("message_id")
cmd_response = await handle_command(bot_obj, chat_id, text, language_code=effective_lang)
if cmd_response is not None:
if isinstance(cmd_response, list):
if isinstance(cmd_response, dict) and "media" in cmd_response:
# Text + media: send text first, media as reply
from ..commands.handler import send_reply as _reply
await _reply(bot_token, chat_id, cmd_response["text"], reply_to_message_id=message_id)
await send_media_group(bot_token, chat_id, cmd_response["media"], reply_to_message_id=message_id)
elif isinstance(cmd_response, list):
await send_media_group(bot_token, chat_id, cmd_response, reply_to_message_id=message_id)
else:
await send_reply(bot_token, chat_id, cmd_response, reply_to_message_id=message_id)