feat: locale-aware command templates, debounced auto-sync, entity pickers
- Locale-aware templates: CommandTemplateSlot now has a locale column, allowing each slot to have per-language variants (EN/RU). Templates are resolved at runtime from the Telegram user's language_code. - Merged system configs: "Default Commands (EN)" and "(RU)" merged into a single "Default Commands" config with locale-aware slots. Migration handles existing data automatically. - Configurable command descriptions: hardcoded COMMAND_DESCRIPTIONS replaced with desc_* template slots (desc_status, desc_help, etc.) that users can customize per locale. setMyCommands registers all locales explicitly. - Removed locale from CommandConfig: no longer needed since locale is derived from the Telegram user's language at runtime. - Debounced command auto-sync: after command config/tracker changes, affected bots are marked dirty and synced after a 30s debounce window. Manual "Sync with Telegram" button still works. - Entity pickers in LinkedTargetsSection: replaced 6 plain <select> elements with EntitySelect components (search, icons, keyboard nav). Added onselect callback and size="sm" props to EntitySelect.
This commit is contained in:
@@ -62,6 +62,20 @@ IMMICH_CAPABILITIES = ProviderCapabilities(
|
||||
{"name": "memory", "description": "/memory On This Day photos"},
|
||||
{"name": "rate_limited", "description": "Rate limit warning message"},
|
||||
{"name": "no_results", "description": "Empty results fallback"},
|
||||
{"name": "desc_status", "description": "Menu description for /status"},
|
||||
{"name": "desc_albums", "description": "Menu description for /albums"},
|
||||
{"name": "desc_events", "description": "Menu description for /events"},
|
||||
{"name": "desc_summary", "description": "Menu description for /summary"},
|
||||
{"name": "desc_latest", "description": "Menu description for /latest"},
|
||||
{"name": "desc_memory", "description": "Menu description for /memory"},
|
||||
{"name": "desc_random", "description": "Menu description for /random"},
|
||||
{"name": "desc_search", "description": "Menu description for /search"},
|
||||
{"name": "desc_find", "description": "Menu description for /find"},
|
||||
{"name": "desc_person", "description": "Menu description for /person"},
|
||||
{"name": "desc_place", "description": "Menu description for /place"},
|
||||
{"name": "desc_favorites", "description": "Menu description for /favorites"},
|
||||
{"name": "desc_people", "description": "Menu description for /people"},
|
||||
{"name": "desc_help", "description": "Menu description for /help"},
|
||||
],
|
||||
events=[
|
||||
{"name": "assets_added", "description": "New assets detected in album"},
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
List tracked albums
|
||||
@@ -0,0 +1 @@
|
||||
Show recent events
|
||||
+1
@@ -0,0 +1 @@
|
||||
Show favorites
|
||||
@@ -0,0 +1 @@
|
||||
Search by filename
|
||||
@@ -0,0 +1 @@
|
||||
Show available commands
|
||||
@@ -0,0 +1 @@
|
||||
Show latest photos
|
||||
@@ -0,0 +1 @@
|
||||
On This Day memories
|
||||
@@ -0,0 +1 @@
|
||||
List detected people
|
||||
@@ -0,0 +1 @@
|
||||
Find photos of person
|
||||
@@ -0,0 +1 @@
|
||||
Find photos by location
|
||||
@@ -0,0 +1 @@
|
||||
Send random photo
|
||||
@@ -0,0 +1 @@
|
||||
Smart search (AI)
|
||||
@@ -0,0 +1 @@
|
||||
Show tracker status
|
||||
@@ -0,0 +1 @@
|
||||
Send album summary now
|
||||
@@ -7,13 +7,24 @@ _LOGGER = logging.getLogger(__name__)
|
||||
|
||||
_DEFAULTS_DIR = Path(__file__).parent
|
||||
|
||||
# All command template slot names (file stem = slot name)
|
||||
# Response template slot names (file stem = slot name)
|
||||
COMMAND_SLOT_NAMES = [
|
||||
"start", "help", "status", "albums", "events", "people",
|
||||
"search", "latest", "favorites", "random", "summary", "memory",
|
||||
"rate_limited", "no_results",
|
||||
]
|
||||
|
||||
# Description slots for Telegram command menu (desc_{cmd} -> short text)
|
||||
COMMAND_DESC_SLOT_NAMES = [
|
||||
"desc_status", "desc_albums", "desc_events", "desc_summary",
|
||||
"desc_latest", "desc_memory", "desc_random", "desc_search",
|
||||
"desc_find", "desc_person", "desc_place", "desc_favorites",
|
||||
"desc_people", "desc_help",
|
||||
]
|
||||
|
||||
# All slot names (response + description)
|
||||
ALL_SLOT_NAMES = COMMAND_SLOT_NAMES + COMMAND_DESC_SLOT_NAMES
|
||||
|
||||
|
||||
def load_default_command_templates(locale: str = "en") -> dict[str, str]:
|
||||
"""Load default command template strings for a locale.
|
||||
@@ -26,7 +37,7 @@ def load_default_command_templates(locale: str = "en") -> dict[str, str]:
|
||||
return {}
|
||||
|
||||
templates: dict[str, str] = {}
|
||||
for slot_name in COMMAND_SLOT_NAMES:
|
||||
for slot_name in ALL_SLOT_NAMES:
|
||||
filepath = locale_dir / f"{slot_name}.jinja2"
|
||||
if filepath.exists():
|
||||
templates[slot_name] = filepath.read_text(encoding="utf-8").strip()
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Список отслеживаемых альбомов
|
||||
@@ -0,0 +1 @@
|
||||
Показать последние события
|
||||
+1
@@ -0,0 +1 @@
|
||||
Показать избранное
|
||||
@@ -0,0 +1 @@
|
||||
Поиск по имени файла
|
||||
@@ -0,0 +1 @@
|
||||
Показать доступные команды
|
||||
@@ -0,0 +1 @@
|
||||
Показать последние фото
|
||||
@@ -0,0 +1 @@
|
||||
Воспоминания за этот день
|
||||
@@ -0,0 +1 @@
|
||||
Список людей
|
||||
@@ -0,0 +1 @@
|
||||
Найти фото человека
|
||||
@@ -0,0 +1 @@
|
||||
Найти фото по месту
|
||||
@@ -0,0 +1 @@
|
||||
Отправить случайное фото
|
||||
@@ -0,0 +1 @@
|
||||
Умный поиск (AI)
|
||||
@@ -0,0 +1 @@
|
||||
Показать статус трекеров
|
||||
@@ -0,0 +1 @@
|
||||
Отправить сводку альбомов
|
||||
Reference in New Issue
Block a user