feat: human error states, operator toasts and a queue/origin view in the omp UI

- classify transport and API failures into a short state with the next step
- count undelivered messages and show them next to the sent counter
- toast on owner paired, connection recovered and reply not delivered (throttled)
- second status line previews the next queued turns
- host spinner names the Telegram prompt while its turn runs
- sanitize every Telegram-controlled string that reaches the widget
This commit is contained in:
evandrodevbr committed 2026-10-01 17:33:37 -03:00
1 parent 9435ff709b
commit 057281a3bb
19 files changed
+862 -22

No files matched your search

+8 -3
View File
@@ -777,6 +777,8 @@ export interface TelegramUserPairingRuntimeDeps<TContext> {
setAllowedUserId: (userId: number) => void;
persistConfig: () => Promise<void>;
updateStatus: (ctx: TContext) => void;
/** Called once the user was accepted as owner and the config persisted. */
onPaired?: (userId: number, ctx: TContext) => void;
}
export interface TelegramUserPairingRuntime<TContext> {
@@ -827,13 +829,16 @@ export function createTelegramUserPairingRuntime<TContext>(
deps: TelegramUserPairingRuntimeDeps<TContext>,
): TelegramUserPairingRuntime<TContext> {
return {
pairIfNeeded: (userId, ctx) =>
pairTelegramUserIfNeeded(userId, {
pairIfNeeded: async (userId, ctx) => {
const paired = await pairTelegramUserIfNeeded(userId, {
allowedUserId: deps.getAllowedUserId(),
ctx,
setAllowedUserId: deps.setAllowedUserId,
persistConfig: deps.persistConfig,
updateStatus: deps.updateStatus,
}),
});
if (paired) deps.onPaired?.(userId, ctx);
return paired;
},
};
}