Composer: Support disabling web link (#1020)

This commit is contained in:
Alexander Zinchuk 2021-04-19 18:36:54 +03:00
parent 0b59ebd7b0
commit b7f776593e
7 changed files with 53 additions and 13 deletions

View File

@ -182,6 +182,7 @@ export function sendMessage(
isSilent,
scheduledAt,
groupedId,
noWebPage,
}: {
chat: ApiChat;
text?: string;
@ -194,6 +195,7 @@ export function sendMessage(
isSilent?: boolean;
scheduledAt?: number;
groupedId?: string;
noWebPage?: boolean;
},
onProgress?: ApiOnProgress,
) {
@ -267,6 +269,7 @@ export function sendMessage(
...(scheduledAt && { scheduleDate: scheduledAt }),
...(replyingTo && { replyToMsgId: replyingTo }),
...(media && { media }),
...(noWebPage && { noWebpage: noWebPage }),
}), true);
})();

View File

@ -701,7 +701,7 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
<div className="svg-appendix" ref={appendixRef} />
<ComposerEmbeddedMessage />
{allowedAttachmentOptions.canAttachEmbedLinks && (
<WebPagePreview chatId={chatId} messageText={!attachments.length ? html : ''} />
<WebPagePreview chatId={chatId} threadId={threadId} messageText={!attachments.length ? html : ''} />
)}
<div className="message-input-wrapper">
{IS_MOBILE_SCREEN ? (

View File

@ -5,9 +5,6 @@
padding-right: 0.625rem;
padding-top: 0.45rem;
// TODO: Remove this when support for disabling webpage preview is added
padding-left: 3.375rem;
--accent-color: var(--color-primary);
.ComposerEmbeddedMessage + & {

View File

@ -3,33 +3,42 @@ import React, {
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions, GlobalState } from '../../../global/types';
import { ApiMessage, ApiMessageEntityTypes } from '../../../api/types';
import { GlobalActions } from '../../../global/types';
import { ApiMessage, ApiMessageEntityTypes, ApiWebPage } from '../../../api/types';
import { selectNoWebPage } from '../../../modules/selectors';
import { pick } from '../../../util/iteratees';
import parseMessageInput from './helpers/parseMessageInput';
import useOnChange from '../../../hooks/useOnChange';
import WebPage from '../message/WebPage';
import Button from '../../ui/Button';
import './WebPagePreview.scss';
type OwnProps = {
chatId: number;
threadId: number;
messageText: string;
};
type StateProps = Pick<GlobalState, 'webPagePreview'>;
type DispatchProps = Pick<GlobalActions, 'loadWebPagePreview' | 'clearWebPagePreview'>;
type StateProps = {
webPagePreview?: ApiWebPage;
noWebPage?: boolean;
};
type DispatchProps = Pick<GlobalActions, 'loadWebPagePreview' | 'clearWebPagePreview' | 'toggleMessageWebPage'>;
const RE_LINK = /https?:\/\/(www.)?([a-zA-Z0-9.-]{2,256})([a-zA-Z/.-]{1,256})([?|#][=&#a-zA-Z0-9]{2,128})?/;
const WebPagePreview: FC<OwnProps & StateProps & DispatchProps> = ({
chatId,
threadId,
messageText,
webPagePreview,
noWebPage,
loadWebPagePreview,
clearWebPagePreview,
toggleMessageWebPage,
}) => {
const link = useMemo(() => {
const { text, entities } = parseMessageInput(messageText);
@ -52,14 +61,20 @@ const WebPagePreview: FC<OwnProps & StateProps & DispatchProps> = ({
loadWebPagePreview({ text: link });
} else {
clearWebPagePreview();
toggleMessageWebPage({ chatId, threadId });
}
}, [clearWebPagePreview, link, loadWebPagePreview]);
}, [chatId, toggleMessageWebPage, clearWebPagePreview, link, loadWebPagePreview, threadId]);
useOnChange(() => {
clearWebPagePreview();
toggleMessageWebPage({ chatId, threadId });
}, [chatId]);
if (!webPagePreview || !messageText.length) {
const handleClearWebpagePreview = () => {
toggleMessageWebPage({ chatId, threadId, noWebPage: true });
};
if (!webPagePreview || !messageText.length || noWebPage) {
return undefined;
}
@ -73,12 +88,23 @@ const WebPagePreview: FC<OwnProps & StateProps & DispatchProps> = ({
return (
<div className="WebPagePreview">
<Button round color="translucent" ariaLabel="Clear Webpage Preview" onClick={handleClearWebpagePreview}>
<i className="icon-close" />
</Button>
<WebPage message={messageStub} inPreview />
</div>
);
};
export default memo(withGlobal<OwnProps>(
(global): StateProps => pick(global, ['webPagePreview']),
(setGlobal, actions): DispatchProps => pick(actions, ['loadWebPagePreview', 'clearWebPagePreview']),
(global, { chatId, threadId }): StateProps => {
const noWebPage = selectNoWebPage(global, chatId, threadId);
return {
webPagePreview: global.webPagePreview,
noWebPage,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'loadWebPagePreview', 'clearWebPagePreview', 'toggleMessageWebPage',
]),
)(WebPagePreview));

View File

@ -49,6 +49,7 @@ export interface Thread {
editingId?: number;
editingScheduledId?: number;
draft?: ApiFormattedText;
noWebPage?: boolean;
threadInfo?: ApiThreadInfo;
firstMessageId?: number;
}
@ -397,7 +398,7 @@ export type ActionTypes = (
'editMessage' | 'deleteHistory' | 'enterMessageSelectMode' | 'toggleMessageSelection' | 'exitMessageSelectMode' |
'openTelegramLink' | 'openChatByUsername' | 'requestThreadInfoUpdate' | 'setScrollOffset' | 'unpinAllMessages' |
'setReplyingToId' | 'setEditingId' | 'editLastMessage' | 'saveDraft' | 'clearDraft' | 'loadPinnedMessages' |
'loadMessageLink' |
'loadMessageLink' | 'toggleMessageWebPage' |
// scheduled messages
'loadScheduledHistory' | 'sendScheduledMessages' | 'rescheduleMessage' | 'deleteScheduledMessages' |
// poll result

View File

@ -48,6 +48,7 @@ import {
selectEditingScheduledId,
selectEditingMessage,
selectScheduledMessage,
selectNoWebPage,
} from '../../selectors';
import { rafPromise } from '../../../util/schedulers';
import { copyTextToClipboard } from '../../../util/clipboard';
@ -171,11 +172,13 @@ addReducer('sendMessage', (global, actions, payload) => {
const chat = selectChat(global, chatId)!;
actions.setReplyingToId({ messageId: undefined });
actions.clearWebPagePreview({ chatId, threadId, value: false });
const params = {
...payload,
chat,
replyingTo: selectReplyingToId(global, chatId, threadId),
noWebPage: selectNoWebPage(global, chatId, threadId),
};
const isSingle = !payload.attachments || payload.attachments.length <= 1;
@ -310,6 +313,12 @@ addReducer('clearDraft', (global, actions, payload) => {
return replaceThreadParam(global, chatId, threadId, 'draft', undefined);
});
addReducer('toggleMessageWebPage', (global, actions, payload) => {
const { chatId, threadId, noWebPage } = payload!;
return replaceThreadParam(global, chatId, threadId, 'noWebPage', noWebPage);
});
addReducer('pinMessage', (global, actions, payload) => {
const chat = selectCurrentChat(global);
if (!chat) {

View File

@ -137,6 +137,10 @@ export function selectDraft(global: GlobalState, chatId: number, threadId: numbe
return selectThreadParam(global, chatId, threadId, 'draft');
}
export function selectNoWebPage(global: GlobalState, chatId: number, threadId: number) {
return selectThreadParam(global, chatId, threadId, 'noWebPage');
}
export function selectThreadInfo(global: GlobalState, chatId: number, threadId: number) {
return selectThreadParam(global, chatId, threadId, 'threadInfo');
}