Attachment Modal: Support hd photo (#5994)
This commit is contained in:
parent
a85fec6c65
commit
c8360b2e5e
@ -36,6 +36,7 @@ export interface ApiOnProgress {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ApiAttachment {
|
export interface ApiAttachment {
|
||||||
|
blob: Blob;
|
||||||
blobUrl: string;
|
blobUrl: string;
|
||||||
compressedBlobUrl?: string;
|
compressedBlobUrl?: string;
|
||||||
filename: string;
|
filename: string;
|
||||||
@ -62,6 +63,7 @@ export interface ApiAttachment {
|
|||||||
|
|
||||||
uniqueId?: string;
|
uniqueId?: string;
|
||||||
ttlSeconds?: number;
|
ttlSeconds?: number;
|
||||||
|
shouldSendInHighQuality?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ApiWallpaper {
|
export interface ApiWallpaper {
|
||||||
|
|||||||
1
src/assets/font-icons/hd-photo.svg
Normal file
1
src/assets/font-icons/hd-photo.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="none"><path fill="#000" d="M27.33 2.468A4.924 4.924 0 0 1 32 7.385v17.23l-.006.254a4.924 4.924 0 0 1-4.664 4.663l-.253.006H4.923l-.253-.006A4.925 4.925 0 0 1 .006 24.87L0 24.615V7.385a4.924 4.924 0 0 1 4.67-4.917l.253-.006h22.154zM4.923 4.923a2.46 2.46 0 0 0-2.461 2.462v17.23a2.46 2.46 0 0 0 2.46 2.462h22.155a2.46 2.46 0 0 0 2.461-2.462V7.385a2.46 2.46 0 0 0-2.46-2.462zm16 3.692a6.155 6.155 0 0 1 6.154 6.155V16l-.009.316a6.154 6.154 0 0 1-6.145 5.838H17.23V8.615zm-6.154 0c.68 0 1.23.551 1.23 1.23v11.078a1.23 1.23 0 1 1-2.46 0V17.23H7.383v3.692a1.23 1.23 0 0 1-2.462 0V9.846a1.231 1.231 0 0 1 2.462 0v4.924h6.154V9.846c0-.68.55-1.23 1.23-1.23m4.923 11.077h1.23A3.69 3.69 0 0 0 24.616 16v-1.23a3.69 3.69 0 0 0-3.692-3.693h-1.23z"/></svg>
|
||||||
|
After Width: | Height: | Size: 810 B |
1
src/assets/font-icons/sd-photo.svg
Normal file
1
src/assets/font-icons/sd-photo.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="none"><path fill="#000" d="M27.33 2.467A4.924 4.924 0 0 1 32 7.384v17.232l-.006.253a4.925 4.925 0 0 1-4.664 4.664l-.253.006H4.923l-.253-.006a4.925 4.925 0 0 1-4.664-4.664L0 24.616V7.384a4.924 4.924 0 0 1 4.67-4.917l.253-.006h22.154zM4.923 4.923a2.46 2.46 0 0 0-2.461 2.461v17.232c0 1.359 1.102 2.46 2.46 2.46h22.155c1.36 0 2.46-1.101 2.461-2.46V7.384a2.46 2.46 0 0 0-2.46-2.46zm16 3.693a6.154 6.154 0 0 1 6.154 6.153V16l-.009.316a6.154 6.154 0 0 1-6.145 5.838H17.23V8.616zm-1.23 11.076h1.23A3.69 3.69 0 0 0 24.615 16V14.77a3.69 3.69 0 0 0-3.692-3.692h-1.23z"/><path fill="#000" d="M13.41 12.418c-.624 0-1.104-.523-1.504-1.002a2 2 0 0 0-.367-.335q-.675-.48-1.757-.479-.76 0-1.305.23-.544.229-.833.622t-.295.898q0 .42.19.728.198.308.532.525.334.21.74.354t.82.242l1.259.315q.76.176 1.461.479.709.3 1.266.76.564.459.891 1.108.328.65.328 1.52 0 1.181-.603 2.08-.603.89-1.744 1.396-1.134.498-2.747.498-1.566 0-2.72-.485-1.147-.486-1.797-1.416a3.7 3.7 0 0 1-.492-1.024c-.204-.66.372-1.245 1.062-1.245.636 0 1.115.536 1.479 1.058q.039.056.082.11.38.465.99.694.616.23 1.377.23.793-.001 1.39-.236.602-.243.944-.67.34-.432.347-1.009-.006-.525-.308-.865-.302-.348-.846-.577a8 8 0 0 0-1.259-.42l-1.527-.393q-1.659-.426-2.623-1.292-.957-.87-.957-2.314 0-1.186.643-2.078.649-.891 1.763-1.383 1.115-.499 2.524-.499 1.43 0 2.505.499 1.08.492 1.698 1.37.261.37.416.789c.236.64-.34 1.217-1.023 1.217"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.4 KiB |
@ -2017,6 +2017,8 @@
|
|||||||
"ValueGiftSortByNumber" = "Number";
|
"ValueGiftSortByNumber" = "Number";
|
||||||
"ResellGiftsNoFound" = "No gifts found";
|
"ResellGiftsNoFound" = "No gifts found";
|
||||||
"ResellGiftsClearFilters" = "Clear Filters";
|
"ResellGiftsClearFilters" = "Clear Filters";
|
||||||
|
"SendInStandardQuality" = "Send In Standard Quality";
|
||||||
|
"SendInHighQuality" = "Send In High Quality";
|
||||||
"MonoforumBadge" = "DIRECT";
|
"MonoforumBadge" = "DIRECT";
|
||||||
"MonoforumStatus" = "Channel messages";
|
"MonoforumStatus" = "Channel messages";
|
||||||
"MonoforumComposerPlaceholder" = "Choose a message to reply";
|
"MonoforumComposerPlaceholder" = "Choose a message to reply";
|
||||||
|
|||||||
@ -635,7 +635,6 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
shouldSuggestCompression,
|
|
||||||
shouldForceCompression,
|
shouldForceCompression,
|
||||||
shouldForceAsFile,
|
shouldForceAsFile,
|
||||||
handleAppendFiles,
|
handleAppendFiles,
|
||||||
@ -655,6 +654,7 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
canSendDocuments,
|
canSendDocuments,
|
||||||
insertNextText,
|
insertNextText,
|
||||||
editedMessage: editingMessage,
|
editedMessage: editingMessage,
|
||||||
|
shouldSendInHighQuality: attachmentSettings.shouldSendInHighQuality,
|
||||||
});
|
});
|
||||||
|
|
||||||
const [isBotKeyboardOpen, openBotKeyboard, closeBotKeyboard] = useFlag();
|
const [isBotKeyboardOpen, openBotKeyboard, closeBotKeyboard] = useFlag();
|
||||||
@ -1848,7 +1848,6 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
attachments={attachments}
|
attachments={attachments}
|
||||||
getHtml={getHtml}
|
getHtml={getHtml}
|
||||||
isReady={isReady}
|
isReady={isReady}
|
||||||
shouldSuggestCompression={shouldSuggestCompression}
|
|
||||||
shouldForceCompression={shouldForceCompression}
|
shouldForceCompression={shouldForceCompression}
|
||||||
shouldForceAsFile={shouldForceAsFile}
|
shouldForceAsFile={shouldForceAsFile}
|
||||||
isForCurrentMessageList={isForCurrentMessageList}
|
isForCurrentMessageList={isForCurrentMessageList}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import {
|
|||||||
memo, useEffect,
|
memo, useEffect,
|
||||||
useMemo,
|
useMemo,
|
||||||
} from '../../../lib/teact/teact';
|
} from '../../../lib/teact/teact';
|
||||||
|
import { getActions } from '../../../global';
|
||||||
|
|
||||||
import type { ApiAttachMenuPeerType, ApiMessage } from '../../../api/types';
|
import type { ApiAttachMenuPeerType, ApiMessage } from '../../../api/types';
|
||||||
import type { GlobalState } from '../../../global/types';
|
import type { GlobalState } from '../../../global/types';
|
||||||
@ -55,7 +56,7 @@ export type OwnProps = {
|
|||||||
peerType?: ApiAttachMenuPeerType;
|
peerType?: ApiAttachMenuPeerType;
|
||||||
shouldCollectDebugLogs?: boolean;
|
shouldCollectDebugLogs?: boolean;
|
||||||
theme: ThemeKey;
|
theme: ThemeKey;
|
||||||
onFileSelect: (files: File[], shouldSuggestCompression?: boolean) => void;
|
onFileSelect: (files: File[]) => void;
|
||||||
onPollCreate: NoneToVoidFunction;
|
onPollCreate: NoneToVoidFunction;
|
||||||
onMenuOpen: NoneToVoidFunction;
|
onMenuOpen: NoneToVoidFunction;
|
||||||
onMenuClose: NoneToVoidFunction;
|
onMenuClose: NoneToVoidFunction;
|
||||||
@ -89,6 +90,9 @@ const AttachMenu: FC<OwnProps> = ({
|
|||||||
messageListType,
|
messageListType,
|
||||||
paidMessagesStars,
|
paidMessagesStars,
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
updateAttachmentSettings,
|
||||||
|
} = getActions();
|
||||||
const [isAttachMenuOpen, openAttachMenu, closeAttachMenu] = useFlag();
|
const [isAttachMenuOpen, openAttachMenu, closeAttachMenu] = useFlag();
|
||||||
const [handleMouseEnter, handleMouseLeave, markMouseInside] = useMouseInside(isAttachMenuOpen, closeAttachMenu);
|
const [handleMouseEnter, handleMouseLeave, markMouseInside] = useMouseInside(isAttachMenuOpen, closeAttachMenu);
|
||||||
|
|
||||||
@ -126,29 +130,31 @@ const AttachMenu: FC<OwnProps> = ({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleFileSelect = useLastCallback((e: Event, shouldSuggestCompression?: boolean) => {
|
const handleFileSelect = useLastCallback((e: Event) => {
|
||||||
const { files } = e.target as HTMLInputElement;
|
const { files } = e.target as HTMLInputElement;
|
||||||
const validatedFiles = validateFiles(files);
|
const validatedFiles = validateFiles(files);
|
||||||
|
|
||||||
if (validatedFiles?.length) {
|
if (validatedFiles?.length) {
|
||||||
onFileSelect(validatedFiles, shouldSuggestCompression);
|
onFileSelect(validatedFiles);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleQuickSelect = useLastCallback(() => {
|
const handleQuickSelect = useLastCallback(() => {
|
||||||
|
updateAttachmentSettings({ shouldCompress: true });
|
||||||
openSystemFilesDialog(
|
openSystemFilesDialog(
|
||||||
Array.from(canSendVideoAndPhoto ? CONTENT_TYPES_WITH_PREVIEW : (
|
Array.from(canSendVideoAndPhoto ? CONTENT_TYPES_WITH_PREVIEW : (
|
||||||
canSendPhotos ? SUPPORTED_PHOTO_CONTENT_TYPES : SUPPORTED_VIDEO_CONTENT_TYPES
|
canSendPhotos ? SUPPORTED_PHOTO_CONTENT_TYPES : SUPPORTED_VIDEO_CONTENT_TYPES
|
||||||
)).join(','),
|
)).join(','),
|
||||||
(e) => handleFileSelect(e, true),
|
(e) => handleFileSelect(e),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleDocumentSelect = useLastCallback(() => {
|
const handleDocumentSelect = useLastCallback(() => {
|
||||||
|
updateAttachmentSettings({ shouldCompress: false });
|
||||||
openSystemFilesDialog(!canSendDocuments && canSendAudios
|
openSystemFilesDialog(!canSendDocuments && canSendAudios
|
||||||
? Array.from(SUPPORTED_AUDIO_CONTENT_TYPES).join(',') : (
|
? Array.from(SUPPORTED_AUDIO_CONTENT_TYPES).join(',') : (
|
||||||
'*'
|
'*'
|
||||||
), (e) => handleFileSelect(e, false));
|
), (e) => handleFileSelect(e));
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleSendLogs = useLastCallback(() => {
|
const handleSendLogs = useLastCallback(() => {
|
||||||
|
|||||||
@ -75,7 +75,6 @@ export type OwnProps = {
|
|||||||
isReady: boolean;
|
isReady: boolean;
|
||||||
isForMessage?: boolean;
|
isForMessage?: boolean;
|
||||||
shouldSchedule?: boolean;
|
shouldSchedule?: boolean;
|
||||||
shouldSuggestCompression?: boolean;
|
|
||||||
shouldForceCompression?: boolean;
|
shouldForceCompression?: boolean;
|
||||||
shouldForceAsFile?: boolean;
|
shouldForceAsFile?: boolean;
|
||||||
isForCurrentMessageList?: boolean;
|
isForCurrentMessageList?: boolean;
|
||||||
@ -113,6 +112,7 @@ type StateProps = {
|
|||||||
const ATTACHMENT_MODAL_INPUT_ID = 'caption-input-text';
|
const ATTACHMENT_MODAL_INPUT_ID = 'caption-input-text';
|
||||||
const DROP_LEAVE_TIMEOUT_MS = 150;
|
const DROP_LEAVE_TIMEOUT_MS = 150;
|
||||||
const MAX_LEFT_CHARS_TO_SHOW = 100;
|
const MAX_LEFT_CHARS_TO_SHOW = 100;
|
||||||
|
const CLOSE_MENU_ANIMATION_DURATION = 200;
|
||||||
|
|
||||||
const AttachmentModal: FC<OwnProps & StateProps> = ({
|
const AttachmentModal: FC<OwnProps & StateProps> = ({
|
||||||
chatId,
|
chatId,
|
||||||
@ -134,7 +134,6 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
|
|||||||
shouldSuggestCustomEmoji,
|
shouldSuggestCustomEmoji,
|
||||||
customEmojiForEmoji,
|
customEmojiForEmoji,
|
||||||
attachmentSettings,
|
attachmentSettings,
|
||||||
shouldSuggestCompression,
|
|
||||||
shouldForceCompression,
|
shouldForceCompression,
|
||||||
shouldForceAsFile,
|
shouldForceAsFile,
|
||||||
isForCurrentMessageList,
|
isForCurrentMessageList,
|
||||||
@ -176,14 +175,16 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
|
|||||||
|
|
||||||
const [isSymbolMenuOpen, openSymbolMenu, closeSymbolMenu] = useFlag();
|
const [isSymbolMenuOpen, openSymbolMenu, closeSymbolMenu] = useFlag();
|
||||||
|
|
||||||
const [shouldSendCompressed, setShouldSendCompressed] = useState(
|
const shouldSendCompressed = attachmentSettings.shouldCompress;
|
||||||
shouldSuggestCompression ?? attachmentSettings.shouldCompress,
|
|
||||||
);
|
|
||||||
const isSendingCompressed = Boolean(
|
const isSendingCompressed = Boolean(
|
||||||
(shouldSendCompressed || shouldForceCompression || isInAlbum) && !shouldForceAsFile,
|
(shouldSendCompressed || shouldForceCompression || isInAlbum) && !shouldForceAsFile,
|
||||||
);
|
);
|
||||||
const [shouldSendGrouped, setShouldSendGrouped] = useState(attachmentSettings.shouldSendGrouped);
|
const [shouldSendGrouped, setShouldSendGrouped] = useState(attachmentSettings.shouldSendGrouped);
|
||||||
const isInvertedMedia = attachmentSettings.isInvertedMedia;
|
const isInvertedMedia = attachmentSettings.isInvertedMedia;
|
||||||
|
const [shouldSendInHighQuality, setShouldSendInHighQuality] = useState(
|
||||||
|
attachmentSettings.shouldSendInHighQuality,
|
||||||
|
);
|
||||||
|
const [renderingShouldSendInHighQuality, setRenderingShouldSendInHighQuality] = useState(shouldSendInHighQuality);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
handleScroll: handleAttachmentsScroll,
|
handleScroll: handleAttachmentsScroll,
|
||||||
@ -197,6 +198,8 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
|
|||||||
const renderingIsOpen = Boolean(renderingAttachments?.length);
|
const renderingIsOpen = Boolean(renderingAttachments?.length);
|
||||||
const [isHovered, markHovered, unmarkHovered] = useFlag();
|
const [isHovered, markHovered, unmarkHovered] = useFlag();
|
||||||
|
|
||||||
|
const timerRef = useRef<number | undefined>();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isOpen) {
|
if (!isOpen) {
|
||||||
closeSymbolMenu();
|
closeSymbolMenu();
|
||||||
@ -269,16 +272,16 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
setShouldSendCompressed(shouldSuggestCompression ?? attachmentSettings.shouldCompress);
|
|
||||||
setShouldSendGrouped(attachmentSettings.shouldSendGrouped);
|
setShouldSendGrouped(attachmentSettings.shouldSendGrouped);
|
||||||
|
setShouldSendInHighQuality(attachmentSettings.shouldSendInHighQuality);
|
||||||
}
|
}
|
||||||
}, [attachmentSettings, isOpen, shouldSuggestCompression]);
|
}, [attachmentSettings, isOpen]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isOpen) {
|
if (!isOpen) {
|
||||||
updateAttachmentSettings({ isInvertedMedia: undefined });
|
updateAttachmentSettings({ isInvertedMedia: undefined });
|
||||||
}
|
}
|
||||||
}, [updateAttachmentSettings, isOpen, shouldSuggestCompression]);
|
}, [updateAttachmentSettings, isOpen]);
|
||||||
|
|
||||||
function setIsInvertedMedia(value?: true) {
|
function setIsInvertedMedia(value?: true) {
|
||||||
updateAttachmentSettings({ isInvertedMedia: value });
|
updateAttachmentSettings({ isInvertedMedia: value });
|
||||||
@ -303,9 +306,10 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
|
|||||||
: isSilent ? onSendSilent : onSend;
|
: isSilent ? onSendSilent : onSend;
|
||||||
send(isSendingCompressed, shouldSendGrouped, isInvertedMedia);
|
send(isSendingCompressed, shouldSendGrouped, isInvertedMedia);
|
||||||
updateAttachmentSettings({
|
updateAttachmentSettings({
|
||||||
shouldCompress: shouldSuggestCompression === undefined ? isSendingCompressed : undefined,
|
shouldCompress: isSendingCompressed,
|
||||||
shouldSendGrouped,
|
shouldSendGrouped,
|
||||||
isInvertedMedia,
|
isInvertedMedia,
|
||||||
|
shouldSendInHighQuality,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -387,6 +391,17 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
|
|||||||
})));
|
})));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const handleToggleShouldCompress = useLastCallback(() => {
|
||||||
|
const newValue = !shouldSendCompressed;
|
||||||
|
updateAttachmentSettings({ shouldCompress: newValue });
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleToggleQuality = useLastCallback(() => {
|
||||||
|
const newValue = !shouldSendInHighQuality;
|
||||||
|
setShouldSendInHighQuality(newValue);
|
||||||
|
updateAttachmentSettings({ shouldSendInHighQuality: newValue });
|
||||||
|
});
|
||||||
|
|
||||||
const handleDisableSpoilers = useLastCallback(() => {
|
const handleDisableSpoilers = useLastCallback(() => {
|
||||||
onAttachmentsUpdate(attachments.map((a) => ({ ...a, shouldSendAsSpoiler: undefined })));
|
onAttachmentsUpdate(attachments.map((a) => ({ ...a, shouldSendAsSpoiler: undefined })));
|
||||||
});
|
});
|
||||||
@ -458,12 +473,13 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
|
|||||||
|
|
||||||
const isQuickGallery = isSendingCompressed && hasOnlyMedia;
|
const isQuickGallery = isSendingCompressed && hasOnlyMedia;
|
||||||
|
|
||||||
const [areAllPhotos, areAllVideos, areAllAudios] = useMemo(() => {
|
const [areAllPhotos, areAllVideos, areAllAudios, hasAnyPhoto] = useMemo(() => {
|
||||||
if (!isQuickGallery || !renderingAttachments) return [false, false, false];
|
if (!isQuickGallery || !renderingAttachments) return [false, false, false];
|
||||||
const everyPhoto = renderingAttachments.every((a) => SUPPORTED_PHOTO_CONTENT_TYPES.has(a.mimeType));
|
const everyPhoto = renderingAttachments.every((a) => SUPPORTED_PHOTO_CONTENT_TYPES.has(a.mimeType));
|
||||||
const everyVideo = renderingAttachments.every((a) => SUPPORTED_VIDEO_CONTENT_TYPES.has(a.mimeType));
|
const everyVideo = renderingAttachments.every((a) => SUPPORTED_VIDEO_CONTENT_TYPES.has(a.mimeType));
|
||||||
const everyAudio = renderingAttachments.every((a) => SUPPORTED_AUDIO_CONTENT_TYPES.has(a.mimeType));
|
const everyAudio = renderingAttachments.every((a) => SUPPORTED_AUDIO_CONTENT_TYPES.has(a.mimeType));
|
||||||
return [everyPhoto, everyVideo, everyAudio];
|
const hasAnyPhoto = renderingAttachments.some((a) => SUPPORTED_PHOTO_CONTENT_TYPES.has(a.mimeType));
|
||||||
|
return [everyPhoto, everyVideo, everyAudio, hasAnyPhoto];
|
||||||
}, [renderingAttachments, isQuickGallery]);
|
}, [renderingAttachments, isQuickGallery]);
|
||||||
|
|
||||||
const hasAnySpoilerable = useMemo(() => {
|
const hasAnySpoilerable = useMemo(() => {
|
||||||
@ -471,6 +487,20 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
|
|||||||
return renderingAttachments.some((a) => !SUPPORTED_AUDIO_CONTENT_TYPES.has(a.mimeType));
|
return renderingAttachments.some((a) => !SUPPORTED_AUDIO_CONTENT_TYPES.has(a.mimeType));
|
||||||
}, [renderingAttachments]);
|
}, [renderingAttachments]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (shouldSendInHighQuality === renderingShouldSendInHighQuality) return;
|
||||||
|
if (timerRef.current) clearTimeout(timerRef.current);
|
||||||
|
timerRef.current = window.setTimeout(() => {
|
||||||
|
setRenderingShouldSendInHighQuality(shouldSendInHighQuality);
|
||||||
|
}, CLOSE_MENU_ANIMATION_DURATION);
|
||||||
|
return () => {
|
||||||
|
if (timerRef.current) {
|
||||||
|
clearTimeout(timerRef.current);
|
||||||
|
timerRef.current = undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [shouldSendInHighQuality, renderingShouldSendInHighQuality]);
|
||||||
|
|
||||||
if (!renderingAttachments) {
|
if (!renderingAttachments) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@ -536,16 +566,24 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
|
|||||||
{
|
{
|
||||||
!shouldForceAsFile && !shouldForceCompression && (isSendingCompressed ? (
|
!shouldForceAsFile && !shouldForceCompression && (isSendingCompressed ? (
|
||||||
|
|
||||||
<MenuItem icon="document" onClick={() => setShouldSendCompressed(false)}>
|
<MenuItem icon="document" onClick={handleToggleShouldCompress}>
|
||||||
{oldLang(isMultiple ? 'Attachment.SendAsFiles' : 'Attachment.SendAsFile')}
|
{oldLang(isMultiple ? 'Attachment.SendAsFiles' : 'Attachment.SendAsFile')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
) : (
|
) : (
|
||||||
|
|
||||||
<MenuItem icon="photo" onClick={() => setShouldSendCompressed(true)}>
|
<MenuItem icon="photo" onClick={handleToggleShouldCompress}>
|
||||||
{isMultiple ? 'Send All as Media' : 'Send as Media'}
|
{isMultiple ? 'Send All as Media' : 'Send as Media'}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
{isSendingCompressed && !editingMessage && hasAnyPhoto && (
|
||||||
|
<MenuItem
|
||||||
|
icon={renderingShouldSendInHighQuality ? 'sd-photo' : 'hd-photo'}
|
||||||
|
onClick={handleToggleQuality}
|
||||||
|
>
|
||||||
|
{lang(renderingShouldSendInHighQuality ? 'SendInStandardQuality' : 'SendInHighQuality')}
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
{isSendingCompressed && hasAnySpoilerable && Boolean(!editingMessage) && (
|
{isSendingCompressed && hasAnySpoilerable && Boolean(!editingMessage) && (
|
||||||
hasSpoiler ? (
|
hasSpoiler ? (
|
||||||
<MenuItem icon="spoiler-disable" onClick={handleDisableSpoilers}>
|
<MenuItem icon="spoiler-disable" onClick={handleDisableSpoilers}>
|
||||||
|
|||||||
@ -25,7 +25,7 @@ export type OwnProps = {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
withQuick?: boolean;
|
withQuick?: boolean;
|
||||||
onHide: NoneToVoidFunction;
|
onHide: NoneToVoidFunction;
|
||||||
onFileSelect: (files: File[], suggestCompression?: boolean) => void;
|
onFileSelect: (files: File[]) => void;
|
||||||
editingMessage?: ApiMessage | undefined;
|
editingMessage?: ApiMessage | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ const DropArea: FC<OwnProps> = ({
|
|||||||
isOpen, withQuick, onHide, onFileSelect, editingMessage,
|
isOpen, withQuick, onHide, onFileSelect, editingMessage,
|
||||||
}) => {
|
}) => {
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
const { showNotification } = getActions();
|
const { showNotification, updateAttachmentSettings } = getActions();
|
||||||
const hideTimeoutRef = useRef<number>();
|
const hideTimeoutRef = useRef<number>();
|
||||||
const prevWithQuick = usePreviousDeprecated(withQuick);
|
const prevWithQuick = usePreviousDeprecated(withQuick);
|
||||||
const { shouldRender, transitionClassNames } = useShowTransitionDeprecated(isOpen);
|
const { shouldRender, transitionClassNames } = useShowTransitionDeprecated(isOpen);
|
||||||
@ -78,7 +78,8 @@ const DropArea: FC<OwnProps> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
onHide();
|
onHide();
|
||||||
onFileSelect(files, withQuick ? false : undefined);
|
updateAttachmentSettings({ shouldCompress: withQuick ? false : undefined });
|
||||||
|
onFileSelect(files);
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleQuickFilesDrop = useLastCallback(async (e: React.DragEvent<HTMLDivElement>) => {
|
const handleQuickFilesDrop = useLastCallback(async (e: React.DragEvent<HTMLDivElement>) => {
|
||||||
@ -102,7 +103,8 @@ const DropArea: FC<OwnProps> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
onHide();
|
onHide();
|
||||||
onFileSelect(files, true);
|
updateAttachmentSettings({ shouldCompress: true });
|
||||||
|
onFileSelect(files);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,8 @@ import {
|
|||||||
} from '../../../../util/files';
|
} from '../../../../util/files';
|
||||||
import { scaleImage } from '../../../../util/imageResize';
|
import { scaleImage } from '../../../../util/imageResize';
|
||||||
|
|
||||||
const MAX_QUICK_IMG_SIZE = 1280; // px
|
const MAX_STANDARD_QUALITY_IMG_SIZE = 1280; // px
|
||||||
|
const MAX_HIGH_QUALITY_IMG_SIZE = 2560;
|
||||||
const MAX_THUMB_IMG_SIZE = 40; // px
|
const MAX_THUMB_IMG_SIZE = 40; // px
|
||||||
const MAX_ASPECT_RATIO = 20;
|
const MAX_ASPECT_RATIO = 20;
|
||||||
const FILE_EXT_REGEX = /\.[^/.]+$/;
|
const FILE_EXT_REGEX = /\.[^/.]+$/;
|
||||||
@ -28,22 +29,25 @@ export default async function buildAttachment(
|
|||||||
let audio;
|
let audio;
|
||||||
let previewBlobUrl;
|
let previewBlobUrl;
|
||||||
let shouldSendAsFile;
|
let shouldSendAsFile;
|
||||||
|
const shouldSendInHighQuality = options?.shouldSendInHighQuality;
|
||||||
|
|
||||||
if (SUPPORTED_PHOTO_CONTENT_TYPES.has(mimeType)) {
|
if (SUPPORTED_PHOTO_CONTENT_TYPES.has(mimeType)) {
|
||||||
const img = await preloadImage(blobUrl);
|
const img = await preloadImage(blobUrl);
|
||||||
const { width, height } = img;
|
const { width, height } = img;
|
||||||
shouldSendAsFile = !validateAspectRatio(width, height);
|
shouldSendAsFile = !validateAspectRatio(width, height);
|
||||||
|
|
||||||
const shouldShrink = Math.max(width, height) > MAX_QUICK_IMG_SIZE;
|
const maxQuickImgSize = shouldSendInHighQuality ? MAX_HIGH_QUALITY_IMG_SIZE : MAX_STANDARD_QUALITY_IMG_SIZE;
|
||||||
|
const shouldShrink = Math.max(width, height) > maxQuickImgSize;
|
||||||
const isGif = mimeType === GIF_MIME_TYPE;
|
const isGif = mimeType === GIF_MIME_TYPE;
|
||||||
|
|
||||||
if (!shouldSendAsFile) {
|
if (!shouldSendAsFile) {
|
||||||
if (!options?.compressedBlobUrl && !isGif && (shouldShrink || mimeType !== 'image/jpeg')) {
|
if (!options?.compressedBlobUrl && !isGif && (shouldShrink || mimeType !== 'image/jpeg')) {
|
||||||
const resizedUrl = await scaleImage(
|
const resizedUrl = await scaleImage(
|
||||||
blobUrl, shouldShrink ? MAX_QUICK_IMG_SIZE / Math.max(width, height) : 1, 'image/jpeg',
|
blobUrl, shouldShrink ? maxQuickImgSize / Math.max(width, height) : 1, 'image/jpeg',
|
||||||
);
|
);
|
||||||
URL.revokeObjectURL(blobUrl);
|
URL.revokeObjectURL(blobUrl);
|
||||||
return buildAttachment(filename, blob, {
|
return buildAttachment(filename, blob, {
|
||||||
|
...options,
|
||||||
compressedBlobUrl: resizedUrl,
|
compressedBlobUrl: resizedUrl,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -88,6 +92,7 @@ export default async function buildAttachment(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
blob,
|
||||||
blobUrl,
|
blobUrl,
|
||||||
filename,
|
filename,
|
||||||
mimeType,
|
mimeType,
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useState } from '../../../../lib/teact/teact';
|
import { useEffect, useState } from '../../../../lib/teact/teact';
|
||||||
import { getActions } from '../../../../global';
|
import { getActions } from '../../../../global';
|
||||||
|
|
||||||
import type { ApiAttachment, ApiMessage } from '../../../../api/types';
|
import type { ApiAttachment, ApiMessage } from '../../../../api/types';
|
||||||
@ -22,6 +22,7 @@ export default function useAttachmentModal({
|
|||||||
canSendDocuments,
|
canSendDocuments,
|
||||||
insertNextText,
|
insertNextText,
|
||||||
editedMessage,
|
editedMessage,
|
||||||
|
shouldSendInHighQuality,
|
||||||
}: {
|
}: {
|
||||||
attachments: ApiAttachment[];
|
attachments: ApiAttachment[];
|
||||||
fileSizeLimit: number;
|
fileSizeLimit: number;
|
||||||
@ -34,12 +35,12 @@ export default function useAttachmentModal({
|
|||||||
canSendDocuments?: boolean;
|
canSendDocuments?: boolean;
|
||||||
insertNextText: VoidFunction;
|
insertNextText: VoidFunction;
|
||||||
editedMessage: ApiMessage | undefined;
|
editedMessage: ApiMessage | undefined;
|
||||||
|
shouldSendInHighQuality?: boolean;
|
||||||
}) {
|
}) {
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
const { openLimitReachedModal, showAllowedMessageTypesNotification, showNotification } = getActions();
|
const { openLimitReachedModal, showAllowedMessageTypesNotification, showNotification } = getActions();
|
||||||
const [shouldForceAsFile, setShouldForceAsFile] = useState<boolean>(false);
|
const [shouldForceAsFile, setShouldForceAsFile] = useState<boolean>(false);
|
||||||
const [shouldForceCompression, setShouldForceCompression] = useState<boolean>(false);
|
const [shouldForceCompression, setShouldForceCompression] = useState<boolean>(false);
|
||||||
const [shouldSuggestCompression, setShouldSuggestCompression] = useState<boolean | undefined>(undefined);
|
|
||||||
|
|
||||||
const handleClearAttachments = useLastCallback(() => {
|
const handleClearAttachments = useLastCallback(() => {
|
||||||
setAttachments(MEMO_EMPTY_ARRAY);
|
setAttachments(MEMO_EMPTY_ARRAY);
|
||||||
@ -99,13 +100,14 @@ export default function useAttachmentModal({
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const newAttachments = await Promise.all(files.map((file) => (
|
const newAttachments = await Promise.all(files.map((file) => (
|
||||||
buildAttachment(file.name, file, { shouldSendAsSpoiler: isSpoiler || undefined })
|
buildAttachment(file.name, file,
|
||||||
|
{ shouldSendAsSpoiler: isSpoiler || undefined, shouldSendInHighQuality })
|
||||||
)));
|
)));
|
||||||
handleSetAttachments([...attachments, ...newAttachments]);
|
handleSetAttachments([...attachments, ...newAttachments]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleFileSelect = useLastCallback(async (files: File[], suggestCompression?: boolean) => {
|
const handleFileSelect = useLastCallback(async (files: File[]) => {
|
||||||
if (editedMessage) {
|
if (editedMessage) {
|
||||||
const newAttachment = await buildAttachment(files[0].name, files[0]);
|
const newAttachment = await buildAttachment(files[0].name, files[0]);
|
||||||
const canReplace = editedMessage && canReplaceMessageMedia(editedMessage, newAttachment);
|
const canReplace = editedMessage && canReplaceMessageMedia(editedMessage, newAttachment);
|
||||||
@ -120,14 +122,23 @@ export default function useAttachmentModal({
|
|||||||
handleSetAttachments([newAttachment]);
|
handleSetAttachments([newAttachment]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const newAttachments = await Promise.all(files.map((file) => buildAttachment(file.name, file)));
|
const newAttachments = await Promise.all(files.map((file) =>
|
||||||
|
buildAttachment(file.name, file, { shouldSendInHighQuality })));
|
||||||
handleSetAttachments(newAttachments);
|
handleSetAttachments(newAttachments);
|
||||||
}
|
}
|
||||||
setShouldSuggestCompression(suggestCompression);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const handleUpdateAttachmentsQuality = useLastCallback(async () => {
|
||||||
|
const newAttachments = await Promise.all(attachments.map((attachment) =>
|
||||||
|
buildAttachment(attachment.filename, attachment.blob, { shouldSendInHighQuality })));
|
||||||
|
handleSetAttachments(newAttachments);
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
handleUpdateAttachmentsQuality();
|
||||||
|
}, [shouldSendInHighQuality]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
shouldSuggestCompression,
|
|
||||||
handleAppendFiles,
|
handleAppendFiles,
|
||||||
handleFileSelect,
|
handleFileSelect,
|
||||||
onCaptionUpdate: setHtml,
|
onCaptionUpdate: setHtml,
|
||||||
|
|||||||
@ -529,17 +529,11 @@ addActionHandler('requestWave', (global, actions, payload): ActionReturnType =>
|
|||||||
});
|
});
|
||||||
|
|
||||||
addActionHandler('updateAttachmentSettings', (global, actions, payload): ActionReturnType => {
|
addActionHandler('updateAttachmentSettings', (global, actions, payload): ActionReturnType => {
|
||||||
const {
|
|
||||||
shouldCompress, shouldSendGrouped, isInvertedMedia, webPageMediaSize,
|
|
||||||
} = payload;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...global,
|
...global,
|
||||||
attachmentSettings: {
|
attachmentSettings: {
|
||||||
shouldCompress: shouldCompress ?? global.attachmentSettings.shouldCompress,
|
...global.attachmentSettings,
|
||||||
shouldSendGrouped: shouldSendGrouped ?? global.attachmentSettings.shouldSendGrouped,
|
...payload,
|
||||||
isInvertedMedia,
|
|
||||||
webPageMediaSize,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@ -180,6 +180,7 @@ export const INITIAL_GLOBAL_STATE: GlobalState = {
|
|||||||
shouldSendGrouped: true,
|
shouldSendGrouped: true,
|
||||||
isInvertedMedia: undefined,
|
isInvertedMedia: undefined,
|
||||||
webPageMediaSize: undefined,
|
webPageMediaSize: undefined,
|
||||||
|
shouldSendInHighQuality: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
scheduledMessages: {
|
scheduledMessages: {
|
||||||
|
|||||||
@ -2193,6 +2193,7 @@ export interface ActionPayloads {
|
|||||||
shouldSendGrouped?: boolean;
|
shouldSendGrouped?: boolean;
|
||||||
isInvertedMedia?: true;
|
isInvertedMedia?: true;
|
||||||
webPageMediaSize?: WebPageMediaSize;
|
webPageMediaSize?: WebPageMediaSize;
|
||||||
|
shouldSendInHighQuality?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
saveEffectInDraft: {
|
saveEffectInDraft: {
|
||||||
|
|||||||
@ -120,6 +120,7 @@ export type GlobalState = {
|
|||||||
shouldSendGrouped: boolean;
|
shouldSendGrouped: boolean;
|
||||||
isInvertedMedia?: true;
|
isInvertedMedia?: true;
|
||||||
webPageMediaSize?: WebPageMediaSize;
|
webPageMediaSize?: WebPageMediaSize;
|
||||||
|
shouldSendInHighQuality?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
attachMenu: {
|
attachMenu: {
|
||||||
|
|||||||
@ -140,166 +140,168 @@ $icons-map: (
|
|||||||
"grouped": "\f167",
|
"grouped": "\f167",
|
||||||
"hand-stop": "\f168",
|
"hand-stop": "\f168",
|
||||||
"hashtag": "\f169",
|
"hashtag": "\f169",
|
||||||
"heart-outline": "\f16a",
|
"hd-photo": "\f16a",
|
||||||
"heart": "\f16b",
|
"heart-outline": "\f16b",
|
||||||
"help": "\f16c",
|
"heart": "\f16c",
|
||||||
"info-filled": "\f16d",
|
"help": "\f16d",
|
||||||
"info": "\f16e",
|
"info-filled": "\f16e",
|
||||||
"install": "\f16f",
|
"info": "\f16f",
|
||||||
"italic": "\f170",
|
"install": "\f170",
|
||||||
"key": "\f171",
|
"italic": "\f171",
|
||||||
"keyboard": "\f172",
|
"key": "\f172",
|
||||||
"lamp": "\f173",
|
"keyboard": "\f173",
|
||||||
"language": "\f174",
|
"lamp": "\f174",
|
||||||
"large-pause": "\f175",
|
"language": "\f175",
|
||||||
"large-play": "\f176",
|
"large-pause": "\f176",
|
||||||
"link-badge": "\f177",
|
"large-play": "\f177",
|
||||||
"link-broken": "\f178",
|
"link-badge": "\f178",
|
||||||
"link": "\f179",
|
"link-broken": "\f179",
|
||||||
"location": "\f17a",
|
"link": "\f17a",
|
||||||
"lock-badge": "\f17b",
|
"location": "\f17b",
|
||||||
"lock": "\f17c",
|
"lock-badge": "\f17c",
|
||||||
"logout": "\f17d",
|
"lock": "\f17d",
|
||||||
"loop": "\f17e",
|
"logout": "\f17e",
|
||||||
"mention": "\f17f",
|
"loop": "\f17f",
|
||||||
"message-failed": "\f180",
|
"mention": "\f180",
|
||||||
"message-pending": "\f181",
|
"message-failed": "\f181",
|
||||||
"message-read": "\f182",
|
"message-pending": "\f182",
|
||||||
"message-succeeded": "\f183",
|
"message-read": "\f183",
|
||||||
"message": "\f184",
|
"message-succeeded": "\f184",
|
||||||
"microphone-alt": "\f185",
|
"message": "\f185",
|
||||||
"microphone": "\f186",
|
"microphone-alt": "\f186",
|
||||||
"monospace": "\f187",
|
"microphone": "\f187",
|
||||||
"more-circle": "\f188",
|
"monospace": "\f188",
|
||||||
"more": "\f189",
|
"more-circle": "\f189",
|
||||||
"move-caption-down": "\f18a",
|
"more": "\f18a",
|
||||||
"move-caption-up": "\f18b",
|
"move-caption-down": "\f18b",
|
||||||
"mute": "\f18c",
|
"move-caption-up": "\f18c",
|
||||||
"muted": "\f18d",
|
"mute": "\f18d",
|
||||||
"my-notes": "\f18e",
|
"muted": "\f18e",
|
||||||
"new-chat-filled": "\f18f",
|
"my-notes": "\f18f",
|
||||||
"next": "\f190",
|
"new-chat-filled": "\f190",
|
||||||
"nochannel": "\f191",
|
"next": "\f191",
|
||||||
"noise-suppression": "\f192",
|
"nochannel": "\f192",
|
||||||
"non-contacts": "\f193",
|
"noise-suppression": "\f193",
|
||||||
"one-filled": "\f194",
|
"non-contacts": "\f194",
|
||||||
"open-in-new-tab": "\f195",
|
"one-filled": "\f195",
|
||||||
"password-off": "\f196",
|
"open-in-new-tab": "\f196",
|
||||||
"pause": "\f197",
|
"password-off": "\f197",
|
||||||
"permissions": "\f198",
|
"pause": "\f198",
|
||||||
"phone-discard-outline": "\f199",
|
"permissions": "\f199",
|
||||||
"phone-discard": "\f19a",
|
"phone-discard-outline": "\f19a",
|
||||||
"phone": "\f19b",
|
"phone-discard": "\f19b",
|
||||||
"photo": "\f19c",
|
"phone": "\f19c",
|
||||||
"pin-badge": "\f19d",
|
"photo": "\f19d",
|
||||||
"pin-list": "\f19e",
|
"pin-badge": "\f19e",
|
||||||
"pin": "\f19f",
|
"pin-list": "\f19f",
|
||||||
"pinned-chat": "\f1a0",
|
"pin": "\f1a0",
|
||||||
"pinned-message": "\f1a1",
|
"pinned-chat": "\f1a1",
|
||||||
"pip": "\f1a2",
|
"pinned-message": "\f1a2",
|
||||||
"play-story": "\f1a3",
|
"pip": "\f1a3",
|
||||||
"play": "\f1a4",
|
"play-story": "\f1a4",
|
||||||
"poll": "\f1a5",
|
"play": "\f1a5",
|
||||||
"previous": "\f1a6",
|
"poll": "\f1a6",
|
||||||
"privacy-policy": "\f1a7",
|
"previous": "\f1a7",
|
||||||
"proof-of-ownership": "\f1a8",
|
"privacy-policy": "\f1a8",
|
||||||
"quote-text": "\f1a9",
|
"proof-of-ownership": "\f1a9",
|
||||||
"quote": "\f1aa",
|
"quote-text": "\f1aa",
|
||||||
"radial-badge": "\f1ab",
|
"quote": "\f1ab",
|
||||||
"readchats": "\f1ac",
|
"radial-badge": "\f1ac",
|
||||||
"recent": "\f1ad",
|
"readchats": "\f1ad",
|
||||||
"reload": "\f1ae",
|
"recent": "\f1ae",
|
||||||
"remove-quote": "\f1af",
|
"reload": "\f1af",
|
||||||
"remove": "\f1b0",
|
"remove-quote": "\f1b0",
|
||||||
"reopen-topic": "\f1b1",
|
"remove": "\f1b1",
|
||||||
"replace": "\f1b2",
|
"reopen-topic": "\f1b2",
|
||||||
"replies": "\f1b3",
|
"replace": "\f1b3",
|
||||||
"reply-filled": "\f1b4",
|
"replies": "\f1b4",
|
||||||
"reply": "\f1b5",
|
"reply-filled": "\f1b5",
|
||||||
"revenue-split": "\f1b6",
|
"reply": "\f1b6",
|
||||||
"revote": "\f1b7",
|
"revenue-split": "\f1b7",
|
||||||
"save-story": "\f1b8",
|
"revote": "\f1b8",
|
||||||
"saved-messages": "\f1b9",
|
"save-story": "\f1b9",
|
||||||
"schedule": "\f1ba",
|
"saved-messages": "\f1ba",
|
||||||
"search": "\f1bb",
|
"schedule": "\f1bb",
|
||||||
"select": "\f1bc",
|
"sd-photo": "\f1bc",
|
||||||
"sell-outline": "\f1bd",
|
"search": "\f1bd",
|
||||||
"sell": "\f1be",
|
"select": "\f1be",
|
||||||
"send-outline": "\f1bf",
|
"sell-outline": "\f1bf",
|
||||||
"send": "\f1c0",
|
"sell": "\f1c0",
|
||||||
"settings-filled": "\f1c1",
|
"send-outline": "\f1c1",
|
||||||
"settings": "\f1c2",
|
"send": "\f1c2",
|
||||||
"share-filled": "\f1c3",
|
"settings-filled": "\f1c3",
|
||||||
"share-screen-outlined": "\f1c4",
|
"settings": "\f1c4",
|
||||||
"share-screen-stop": "\f1c5",
|
"share-filled": "\f1c5",
|
||||||
"share-screen": "\f1c6",
|
"share-screen-outlined": "\f1c6",
|
||||||
"show-message": "\f1c7",
|
"share-screen-stop": "\f1c7",
|
||||||
"sidebar": "\f1c8",
|
"share-screen": "\f1c8",
|
||||||
"skip-next": "\f1c9",
|
"show-message": "\f1c9",
|
||||||
"skip-previous": "\f1ca",
|
"sidebar": "\f1ca",
|
||||||
"smallscreen": "\f1cb",
|
"skip-next": "\f1cb",
|
||||||
"smile": "\f1cc",
|
"skip-previous": "\f1cc",
|
||||||
"sort-by-date": "\f1cd",
|
"smallscreen": "\f1cd",
|
||||||
"sort-by-number": "\f1ce",
|
"smile": "\f1ce",
|
||||||
"sort-by-price": "\f1cf",
|
"sort-by-date": "\f1cf",
|
||||||
"sort": "\f1d0",
|
"sort-by-number": "\f1d0",
|
||||||
"speaker-muted-story": "\f1d1",
|
"sort-by-price": "\f1d1",
|
||||||
"speaker-outline": "\f1d2",
|
"sort": "\f1d2",
|
||||||
"speaker-story": "\f1d3",
|
"speaker-muted-story": "\f1d3",
|
||||||
"speaker": "\f1d4",
|
"speaker-outline": "\f1d4",
|
||||||
"spoiler-disable": "\f1d5",
|
"speaker-story": "\f1d5",
|
||||||
"spoiler": "\f1d6",
|
"speaker": "\f1d6",
|
||||||
"sport": "\f1d7",
|
"spoiler-disable": "\f1d7",
|
||||||
"star": "\f1d8",
|
"spoiler": "\f1d8",
|
||||||
"stars-lock": "\f1d9",
|
"sport": "\f1d9",
|
||||||
"stats": "\f1da",
|
"star": "\f1da",
|
||||||
"stealth-future": "\f1db",
|
"stars-lock": "\f1db",
|
||||||
"stealth-past": "\f1dc",
|
"stats": "\f1dc",
|
||||||
"stickers": "\f1dd",
|
"stealth-future": "\f1dd",
|
||||||
"stop-raising-hand": "\f1de",
|
"stealth-past": "\f1de",
|
||||||
"stop": "\f1df",
|
"stickers": "\f1df",
|
||||||
"story-caption": "\f1e0",
|
"stop-raising-hand": "\f1e0",
|
||||||
"story-expired": "\f1e1",
|
"stop": "\f1e1",
|
||||||
"story-priority": "\f1e2",
|
"story-caption": "\f1e2",
|
||||||
"story-reply": "\f1e3",
|
"story-expired": "\f1e3",
|
||||||
"strikethrough": "\f1e4",
|
"story-priority": "\f1e4",
|
||||||
"tag-add": "\f1e5",
|
"story-reply": "\f1e5",
|
||||||
"tag-crossed": "\f1e6",
|
"strikethrough": "\f1e6",
|
||||||
"tag-filter": "\f1e7",
|
"tag-add": "\f1e7",
|
||||||
"tag-name": "\f1e8",
|
"tag-crossed": "\f1e8",
|
||||||
"tag": "\f1e9",
|
"tag-filter": "\f1e9",
|
||||||
"timer": "\f1ea",
|
"tag-name": "\f1ea",
|
||||||
"toncoin": "\f1eb",
|
"tag": "\f1eb",
|
||||||
"trade": "\f1ec",
|
"timer": "\f1ec",
|
||||||
"transcribe": "\f1ed",
|
"toncoin": "\f1ed",
|
||||||
"truck": "\f1ee",
|
"trade": "\f1ee",
|
||||||
"unarchive": "\f1ef",
|
"transcribe": "\f1ef",
|
||||||
"underlined": "\f1f0",
|
"truck": "\f1f0",
|
||||||
"unique-profile": "\f1f1",
|
"unarchive": "\f1f1",
|
||||||
"unlist-outline": "\f1f2",
|
"underlined": "\f1f2",
|
||||||
"unlist": "\f1f3",
|
"unique-profile": "\f1f3",
|
||||||
"unlock-badge": "\f1f4",
|
"unlist-outline": "\f1f4",
|
||||||
"unlock": "\f1f5",
|
"unlist": "\f1f5",
|
||||||
"unmute": "\f1f6",
|
"unlock-badge": "\f1f6",
|
||||||
"unpin": "\f1f7",
|
"unlock": "\f1f7",
|
||||||
"unread": "\f1f8",
|
"unmute": "\f1f8",
|
||||||
"up": "\f1f9",
|
"unpin": "\f1f9",
|
||||||
"user-filled": "\f1fa",
|
"unread": "\f1fa",
|
||||||
"user-online": "\f1fb",
|
"up": "\f1fb",
|
||||||
"user": "\f1fc",
|
"user-filled": "\f1fc",
|
||||||
"video-outlined": "\f1fd",
|
"user-online": "\f1fd",
|
||||||
"video-stop": "\f1fe",
|
"user": "\f1fe",
|
||||||
"video": "\f1ff",
|
"video-outlined": "\f1ff",
|
||||||
"view-once": "\f200",
|
"video-stop": "\f200",
|
||||||
"voice-chat": "\f201",
|
"video": "\f201",
|
||||||
"volume-1": "\f202",
|
"view-once": "\f202",
|
||||||
"volume-2": "\f203",
|
"voice-chat": "\f203",
|
||||||
"volume-3": "\f204",
|
"volume-1": "\f204",
|
||||||
"web": "\f205",
|
"volume-2": "\f205",
|
||||||
"webapp": "\f206",
|
"volume-3": "\f206",
|
||||||
"word-wrap": "\f207",
|
"web": "\f207",
|
||||||
"zoom-in": "\f208",
|
"webapp": "\f208",
|
||||||
"zoom-out": "\f209",
|
"word-wrap": "\f209",
|
||||||
|
"zoom-in": "\f20a",
|
||||||
|
"zoom-out": "\f20b",
|
||||||
);
|
);
|
||||||
|
|
||||||
.icon-active-sessions::before {
|
.icon-active-sessions::before {
|
||||||
@ -617,6 +619,9 @@ $icons-map: (
|
|||||||
.icon-hashtag::before {
|
.icon-hashtag::before {
|
||||||
content: map.get($icons-map, "hashtag");
|
content: map.get($icons-map, "hashtag");
|
||||||
}
|
}
|
||||||
|
.icon-hd-photo::before {
|
||||||
|
content: map.get($icons-map, "hd-photo");
|
||||||
|
}
|
||||||
.icon-heart-outline::before {
|
.icon-heart-outline::before {
|
||||||
content: map.get($icons-map, "heart-outline");
|
content: map.get($icons-map, "heart-outline");
|
||||||
}
|
}
|
||||||
@ -860,6 +865,9 @@ $icons-map: (
|
|||||||
.icon-schedule::before {
|
.icon-schedule::before {
|
||||||
content: map.get($icons-map, "schedule");
|
content: map.get($icons-map, "schedule");
|
||||||
}
|
}
|
||||||
|
.icon-sd-photo::before {
|
||||||
|
content: map.get($icons-map, "sd-photo");
|
||||||
|
}
|
||||||
.icon-search::before {
|
.icon-search::before {
|
||||||
content: map.get($icons-map, "search");
|
content: map.get($icons-map, "search");
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@ -104,6 +104,7 @@ export type FontIconName =
|
|||||||
| 'grouped'
|
| 'grouped'
|
||||||
| 'hand-stop'
|
| 'hand-stop'
|
||||||
| 'hashtag'
|
| 'hashtag'
|
||||||
|
| 'hd-photo'
|
||||||
| 'heart-outline'
|
| 'heart-outline'
|
||||||
| 'heart'
|
| 'heart'
|
||||||
| 'help'
|
| 'help'
|
||||||
@ -185,6 +186,7 @@ export type FontIconName =
|
|||||||
| 'save-story'
|
| 'save-story'
|
||||||
| 'saved-messages'
|
| 'saved-messages'
|
||||||
| 'schedule'
|
| 'schedule'
|
||||||
|
| 'sd-photo'
|
||||||
| 'search'
|
| 'search'
|
||||||
| 'select'
|
| 'select'
|
||||||
| 'sell-outline'
|
| 'sell-outline'
|
||||||
|
|||||||
2
src/types/language.d.ts
vendored
2
src/types/language.d.ts
vendored
@ -1530,6 +1530,8 @@ export interface LangPair {
|
|||||||
'ValueGiftSortByNumber': undefined;
|
'ValueGiftSortByNumber': undefined;
|
||||||
'ResellGiftsNoFound': undefined;
|
'ResellGiftsNoFound': undefined;
|
||||||
'ResellGiftsClearFilters': undefined;
|
'ResellGiftsClearFilters': undefined;
|
||||||
|
'SendInStandardQuality': undefined;
|
||||||
|
'SendInHighQuality': undefined;
|
||||||
'MonoforumBadge': undefined;
|
'MonoforumBadge': undefined;
|
||||||
'MonoforumStatus': undefined;
|
'MonoforumStatus': undefined;
|
||||||
'MonoforumComposerPlaceholder': undefined;
|
'MonoforumComposerPlaceholder': undefined;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user