Dialogs: Support alert-style answers from bots (#1239)
This commit is contained in:
parent
55ff760f03
commit
fc975f87cc
@ -5,22 +5,16 @@ import { buildInputPeer } from '../gramjsBuilders';
|
|||||||
export function init() {
|
export function init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function answerCallbackButton(
|
export function answerCallbackButton(
|
||||||
{
|
{
|
||||||
chatId, accessHash, messageId, data,
|
chatId, accessHash, messageId, data,
|
||||||
}: {
|
}: {
|
||||||
chatId: number; accessHash?: string; messageId: number; data: string;
|
chatId: number; accessHash?: string; messageId: number; data: string;
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
const result = await invokeRequest(new GramJs.messages.GetBotCallbackAnswer({
|
return invokeRequest(new GramJs.messages.GetBotCallbackAnswer({
|
||||||
peer: buildInputPeer(chatId, accessHash),
|
peer: buildInputPeer(chatId, accessHash),
|
||||||
msgId: messageId,
|
msgId: messageId,
|
||||||
data: Buffer.from(data),
|
data: Buffer.from(data),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -261,6 +261,7 @@ export function dispatchErrorUpdate<T extends GramJs.AnyRequest>(err: Error, req
|
|||||||
error: {
|
error: {
|
||||||
message,
|
message,
|
||||||
isSlowMode,
|
isSlowMode,
|
||||||
|
hasErrorKey: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -313,6 +313,7 @@ export type ApiNotification = {
|
|||||||
|
|
||||||
export type ApiError = {
|
export type ApiError = {
|
||||||
message: string;
|
message: string;
|
||||||
|
hasErrorKey?: boolean;
|
||||||
isSlowMode?: boolean;
|
isSlowMode?: boolean;
|
||||||
textParams?: Record<string, string>;
|
textParams?: Record<string, string>;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -78,6 +78,7 @@ const SettingsFoldersMain: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
showDialog({
|
showDialog({
|
||||||
data: {
|
data: {
|
||||||
message: 'DIALOG_FILTERS_TOO_MUCH',
|
message: 'DIALOG_FILTERS_TOO_MUCH',
|
||||||
|
hasErrorKey: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -114,6 +115,7 @@ const SettingsFoldersMain: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
showDialog({
|
showDialog({
|
||||||
data: {
|
data: {
|
||||||
message: 'DIALOG_FILTERS_TOO_MUCH',
|
message: 'DIALOG_FILTERS_TOO_MUCH',
|
||||||
|
hasErrorKey: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -6,11 +6,3 @@
|
|||||||
height: 100vh;
|
height: 100vh;
|
||||||
z-index: var(--z-modal);
|
z-index: var(--z-modal);
|
||||||
}
|
}
|
||||||
|
|
||||||
.buttons {
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
button {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import { ApiError, ApiInviteInfo } from '../../api/types';
|
|||||||
import getReadableErrorText from '../../util/getReadableErrorText';
|
import getReadableErrorText from '../../util/getReadableErrorText';
|
||||||
import { pick } from '../../util/iteratees';
|
import { pick } from '../../util/iteratees';
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
|
import renderText from '../common/helpers/renderText';
|
||||||
|
|
||||||
import Modal from '../ui/Modal';
|
import Modal from '../ui/Modal';
|
||||||
import Button from '../ui/Button';
|
import Button from '../ui/Button';
|
||||||
@ -66,8 +67,8 @@ const Dialogs: FC<StateProps & DispatchProps> = ({ dialogs, dismissDialog, accep
|
|||||||
className="error"
|
className="error"
|
||||||
title={getErrorHeader(error)}
|
title={getErrorHeader(error)}
|
||||||
>
|
>
|
||||||
<p>{getReadableErrorText(error)}</p>
|
{error.hasErrorKey ? getReadableErrorText(error) : renderText(error.message!, ['emoji', 'br'])}
|
||||||
<div className="buttons">
|
<div>
|
||||||
<Button isText onClick={dismissDialog}>{lang('OK')}</Button>
|
<Button isText onClick={dismissDialog}>{lang('OK')}</Button>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
@ -94,6 +95,10 @@ function getErrorHeader(error: ApiError) {
|
|||||||
return 'Slowmode enabled';
|
return 'Slowmode enabled';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!error.hasErrorKey) {
|
||||||
|
return 'Telegram';
|
||||||
|
}
|
||||||
|
|
||||||
return 'Something went wrong';
|
return 'Something went wrong';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -40,7 +40,7 @@ import {
|
|||||||
isChatPrivate,
|
isChatPrivate,
|
||||||
isChatAdmin,
|
isChatAdmin,
|
||||||
} from '../../../modules/helpers';
|
} from '../../../modules/helpers';
|
||||||
import { formatVoiceRecordDuration, getDayStartAt } from '../../../util/dateFormat';
|
import { formatMediaDuration, formatVoiceRecordDuration, getDayStartAt } from '../../../util/dateFormat';
|
||||||
import focusEditableElement from '../../../util/focusEditableElement';
|
import focusEditableElement from '../../../util/focusEditableElement';
|
||||||
import parseMessageInput from './helpers/parseMessageInput';
|
import parseMessageInput from './helpers/parseMessageInput';
|
||||||
import buildAttachment from './helpers/buildAttachment';
|
import buildAttachment from './helpers/buildAttachment';
|
||||||
@ -211,6 +211,7 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
const [
|
const [
|
||||||
scheduledMessageArgs, setScheduledMessageArgs,
|
scheduledMessageArgs, setScheduledMessageArgs,
|
||||||
] = useState<GlobalState['messages']['contentToBeScheduled'] | undefined>();
|
] = useState<GlobalState['messages']['contentToBeScheduled'] | undefined>();
|
||||||
|
const lang = useLang();
|
||||||
|
|
||||||
// Cache for frequently updated state
|
// Cache for frequently updated state
|
||||||
const htmlRef = useRef<string>(html);
|
const htmlRef = useRef<string>(html);
|
||||||
@ -435,6 +436,7 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
'{EXTRA_CHARS_COUNT}': extraLength,
|
'{EXTRA_CHARS_COUNT}': extraLength,
|
||||||
'{PLURAL_S}': extraLength > 1 ? 's' : '',
|
'{PLURAL_S}': extraLength > 1 ? 's' : '',
|
||||||
},
|
},
|
||||||
|
hasErrorKey: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@ -456,8 +458,9 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
: slowMode.seconds - secondsSinceLastMessage!;
|
: slowMode.seconds - secondsSinceLastMessage!;
|
||||||
showDialog({
|
showDialog({
|
||||||
data: {
|
data: {
|
||||||
message: `A wait of ${secondsRemaining} seconds is required before sending another message in this chat`,
|
message: lang('SlowModeHint', formatMediaDuration(secondsRemaining)),
|
||||||
isSlowMode: true,
|
isSlowMode: true,
|
||||||
|
hasErrorKey: false,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -488,7 +491,7 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
requestAnimationFrame(resetComposer);
|
requestAnimationFrame(resetComposer);
|
||||||
}, [
|
}, [
|
||||||
connectionState, attachments, activeVoiceRecording, isForwarding, serverTimeOffset, clearDraft, chatId,
|
connectionState, attachments, activeVoiceRecording, isForwarding, serverTimeOffset, clearDraft, chatId,
|
||||||
resetComposer, stopRecordingVoice, showDialog, slowMode, isAdmin, sendMessage, forwardMessages,
|
resetComposer, stopRecordingVoice, showDialog, slowMode, isAdmin, sendMessage, forwardMessages, lang,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const handleStickerSelect = useCallback((sticker: ApiSticker) => {
|
const handleStickerSelect = useCallback((sticker: ApiSticker) => {
|
||||||
@ -635,8 +638,6 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
activeVoiceRecording, openCalendar, pauseRecordingVoice, handleSend,
|
activeVoiceRecording, openCalendar, pauseRecordingVoice, handleSend,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const lang = useLang();
|
|
||||||
|
|
||||||
const areVoiceMessagesNotAllowed = mainButtonState === MainButtonState.Record
|
const areVoiceMessagesNotAllowed = mainButtonState === MainButtonState.Record
|
||||||
&& !allowedAttachmentOptions.canAttachMedia;
|
&& !allowedAttachmentOptions.canAttachMedia;
|
||||||
|
|
||||||
|
|||||||
@ -59,7 +59,7 @@ addReducer('apiUpdate', (global, actions, update: ApiUpdate) => {
|
|||||||
actions.signOut();
|
actions.signOut();
|
||||||
}
|
}
|
||||||
|
|
||||||
actions.showDialog({ data: update.error });
|
actions.showDialog({ data: { ...update.error, hasErrorKey: true } });
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -163,7 +163,7 @@ addReducer('showDialog', (global, actions, payload) => {
|
|||||||
const { data } = payload!;
|
const { data } = payload!;
|
||||||
|
|
||||||
// Filter out errors that we don't want to show to the user
|
// Filter out errors that we don't want to show to the user
|
||||||
if ('message' in data && !getReadableErrorText(data)) {
|
if ('message' in data && data.hasErrorKey && !getReadableErrorText(data)) {
|
||||||
return global;
|
return global;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -95,7 +95,7 @@ const SHIPPING_ERRORS: Record<string, Record<string, string>> = {
|
|||||||
|
|
||||||
export function getShippingErrors(dialogs: (ApiError | ApiInviteInfo)[]) {
|
export function getShippingErrors(dialogs: (ApiError | ApiInviteInfo)[]) {
|
||||||
return Object.values(dialogs).reduce((acc, cur) => {
|
return Object.values(dialogs).reduce((acc, cur) => {
|
||||||
if (!('message' in cur)) return acc;
|
if (!('hasErrorKey' in cur) || !cur.hasErrorKey) return acc;
|
||||||
const error = SHIPPING_ERRORS[cur.message];
|
const error = SHIPPING_ERRORS[cur.message];
|
||||||
if (error) {
|
if (error) {
|
||||||
acc = {
|
acc = {
|
||||||
|
|||||||
@ -64,7 +64,7 @@ const READABLE_ERROR_MESSAGES: Record<string, string> = {
|
|||||||
|
|
||||||
export default function getReadableErrorText(error: ApiError) {
|
export default function getReadableErrorText(error: ApiError) {
|
||||||
const { message, isSlowMode, textParams } = error;
|
const { message, isSlowMode, textParams } = error;
|
||||||
// Currently Telegram API doesn't return `SLOWMODE_WAIT_X` error as described in the docs
|
// Currently, Telegram API doesn't return `SLOWMODE_WAIT_X` error as described in the docs
|
||||||
if (isSlowMode) {
|
if (isSlowMode) {
|
||||||
const extraPartIndex = message.indexOf(' (caused by');
|
const extraPartIndex = message.indexOf(' (caused by');
|
||||||
return extraPartIndex > 0 ? message.substring(0, extraPartIndex) : message;
|
return extraPartIndex > 0 ? message.substring(0, extraPartIndex) : message;
|
||||||
|
|||||||
@ -52,7 +52,7 @@ if (IS_SERVICE_WORKER_SUPPORTED) {
|
|||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.error('[SW] ServiceWorker not available');
|
console.error('[SW] ServiceWorker not available');
|
||||||
}
|
}
|
||||||
getDispatch().showDialog({ data: { message: 'SERVICE_WORKER_DISABLED' } });
|
getDispatch().showDialog({ data: { message: 'SERVICE_WORKER_DISABLED', hasErrorKey: true } });
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user