Закрыты задачи бэклога по неочевидному поведению UI при ошибках отправки сообщений и блокировках со стороны Message-safety + добалено ограничение на размер сообщения

This commit is contained in:
mi
2026-07-29 16:45:19 +03:00
parent 41e19005fb
commit bda3ff39d7
36 changed files with 486 additions and 141 deletions
@@ -15,9 +15,11 @@ import {
clearPendingTextIntent,
createPendingTextIntent,
savePendingTextIntent,
savePendingFileIntent,
type PendingTextIntent,
} from "../src/pending-intent";
import { dialogApi, publicApi, uploadAttachment } from "../src/services";
import { DEFAULT_MESSAGE_MAX_LENGTH, normalizeMessageText } from "../src/message-text";
import { publicApi } from "../src/services";
import type { Consents } from "../src/types";
import { ErrorNotice, Loading, styles } from "../src/ui";
@@ -29,7 +31,7 @@ export default function HomeScreen() {
const [pending, setPending] = useState<PendingTextIntent | null>(null);
const [message, setMessage] = useState("");
const [sendError, setSendError] = useState<unknown>();
const [sending, setSending] = useState(false);
const [sending] = useState(false);
const [afterNotificationAuth, setAfterNotificationAuth] = useState<(() => Promise<void>) | undefined>();
const { authorize: authorizeParam } = useLocalSearchParams<{ authorize?: string }>();
const handledAuthorizeParam = useRef(false);
@@ -42,28 +44,20 @@ export default function HomeScreen() {
}
}, [authStatus, authorizeParam]);
const sendAuthenticated = async (intent: PendingTextIntent) => {
setSending(true);
const openChatWithText = (intent: PendingTextIntent) => {
setSendError(undefined);
try {
const dialog = await dialogApi.create(intent.dialogKey);
await dialogApi.sendText(dialog.dialog_id, intent.text, intent.messageKey);
setMessage("");
setPending(null);
clearPendingTextIntent();
router.push(`/dialogs/${dialog.dialog_id}`);
} catch (error) {
setSendError(error);
} finally {
setSending(false);
}
savePendingTextIntent(intent);
setMessage("");
setPending(null);
router.push("/dialogs?pending=1");
};
const send = async (text: string) => {
const normalized = text.trim();
const normalized = normalizeMessageText(text);
if (!normalized) return;
if (normalized.length > 4000) {
setSendError(new Error("Сообщение слишком длинное. Максимум — 4000 символов."));
const maxLength = config.data?.messages?.max_text_length ?? DEFAULT_MESSAGE_MAX_LENGTH;
if (normalized.length > maxLength) {
setSendError(new Error(`Сообщение слишком длинное. Максимум — ${maxLength} символов.`));
return;
}
const intent = createPendingTextIntent(normalized);
@@ -73,7 +67,7 @@ export default function HomeScreen() {
setConsentOpen(true);
return;
}
await sendAuthenticated(intent);
openChatWithText(intent);
};
const chooseFile = () => {
@@ -103,23 +97,13 @@ export default function HomeScreen() {
setSendError(new Error("Недопустимый тип файла или превышен допустимый размер."));
return;
}
setSending(true);
setSendError(undefined);
try {
const dialog = await dialogApi.create(crypto.randomUUID());
const uploaded = await uploadAttachment(dialog.dialog_id, file);
await dialogApi.sendFile(
dialog.dialog_id,
uploaded.attachmentId,
uploaded.checksum,
crypto.randomUUID(),
);
router.push(`/dialogs/${dialog.dialog_id}`);
} catch (error) {
setSendError(error);
} finally {
setSending(false);
}
savePendingFileIntent({
file,
dialogKey: crypto.randomUUID(),
messageKey: crypto.randomUUID(),
});
router.push("/dialogs?pending=1");
};
const accept = async (accepted: {
@@ -136,7 +120,7 @@ export default function HomeScreen() {
setConsentOpen(false);
try {
const authorized = await authorize(consents);
if (authorized && pending) await sendAuthenticated(pending);
if (authorized && pending) openChatWithText(pending);
else if (authorized && afterNotificationAuth) await afterNotificationAuth();
} catch (error) {
setSendError(error);
@@ -181,6 +165,7 @@ export default function HomeScreen() {
onSubmit={() => void send(message)}
sending={sending}
value={message}
maxLength={config.data?.messages?.max_text_length ?? DEFAULT_MESSAGE_MAX_LENGTH}
/>
<QuickActions
authenticated={authStatus === "authenticated"}