Media Viewer: Allow to hide caption by tap on mobile (#1196)
This commit is contained in:
parent
c6550ca3e4
commit
2c7c23715c
@ -8,7 +8,7 @@ import {
|
|||||||
} from '../../api/types';
|
} from '../../api/types';
|
||||||
import { ISettings } from '../../types';
|
import { ISettings } from '../../types';
|
||||||
|
|
||||||
import { IS_MOBILE_SCREEN } from '../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
||||||
import { formatMediaDateTime, formatMediaDuration, formatPastTimeShort } from '../../util/dateFormat';
|
import { formatMediaDateTime, formatMediaDuration, formatPastTimeShort } from '../../util/dateFormat';
|
||||||
import {
|
import {
|
||||||
getMediaDuration,
|
getMediaDuration,
|
||||||
@ -65,8 +65,8 @@ interface ISeekMethods {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const AVG_VOICE_DURATION = 30;
|
const AVG_VOICE_DURATION = 30;
|
||||||
const MIN_SPIKES = IS_MOBILE_SCREEN ? 20 : 25;
|
const MIN_SPIKES = IS_SINGLE_COLUMN_LAYOUT ? 20 : 25;
|
||||||
const MAX_SPIKES = IS_MOBILE_SCREEN ? 50 : 75;
|
const MAX_SPIKES = IS_SINGLE_COLUMN_LAYOUT ? 50 : 75;
|
||||||
// This is needed for browsers requiring user interaction before playing.
|
// This is needed for browsers requiring user interaction before playing.
|
||||||
const PRELOAD = true;
|
const PRELOAD = true;
|
||||||
|
|
||||||
@ -286,7 +286,7 @@ const Audio: FC<OwnProps & StateProps> = ({
|
|||||||
)}
|
)}
|
||||||
<Button
|
<Button
|
||||||
round
|
round
|
||||||
ripple={!IS_MOBILE_SCREEN}
|
ripple={!IS_SINGLE_COLUMN_LAYOUT}
|
||||||
size={renderingFor ? 'smaller' : 'tiny'}
|
size={renderingFor ? 'smaller' : 'tiny'}
|
||||||
className={buttonClassNames.join(' ')}
|
className={buttonClassNames.join(' ')}
|
||||||
ariaLabel={isPlaying ? 'Pause audio' : 'Play audio'}
|
ariaLabel={isPlaying ? 'Pause audio' : 'Play audio'}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import buildClassName from '../../util/buildClassName';
|
|||||||
import {
|
import {
|
||||||
formatMonthAndYear, formatHumanDate, formatTime,
|
formatMonthAndYear, formatHumanDate, formatTime,
|
||||||
} from '../../util/dateFormat';
|
} from '../../util/dateFormat';
|
||||||
import { IS_MOBILE_SCREEN } from '../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
||||||
import useLang, { LangFn } from '../../hooks/useLang';
|
import useLang, { LangFn } from '../../hooks/useLang';
|
||||||
|
|
||||||
import Modal from '../ui/Modal';
|
import Modal from '../ui/Modal';
|
||||||
@ -183,7 +183,7 @@ const CalendarModal: FC<OwnProps> = ({
|
|||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<h4>
|
<h4>
|
||||||
{formatMonthAndYear(lang, selectedDate, IS_MOBILE_SCREEN)}
|
{formatMonthAndYear(lang, selectedDate, IS_SINGLE_COLUMN_LAYOUT)}
|
||||||
</h4>
|
</h4>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import React, {
|
|||||||
} from '../../lib/teact/teact';
|
} from '../../lib/teact/teact';
|
||||||
|
|
||||||
import { MIN_PASSWORD_LENGTH } from '../../config';
|
import { MIN_PASSWORD_LENGTH } from '../../config';
|
||||||
import { IS_TOUCH_ENV, IS_MOBILE_SCREEN } from '../../util/environment';
|
import { IS_TOUCH_ENV, IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
||||||
import buildClassName from '../../util/buildClassName';
|
import buildClassName from '../../util/buildClassName';
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ type OwnProps = {
|
|||||||
onSubmit: (password: string) => void;
|
onSubmit: (password: string) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const FOCUS_DELAY_TIMEOUT_MS = IS_MOBILE_SCREEN ? 550 : 400;
|
const FOCUS_DELAY_TIMEOUT_MS = IS_SINGLE_COLUMN_LAYOUT ? 550 : 400;
|
||||||
|
|
||||||
const PasswordForm: FC<OwnProps> = ({
|
const PasswordForm: FC<OwnProps> = ({
|
||||||
isLoading = false,
|
isLoading = false,
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import React, {
|
|||||||
} from '../../lib/teact/teact';
|
} from '../../lib/teact/teact';
|
||||||
|
|
||||||
import { STICKER_SIZE_AUTH, STICKER_SIZE_AUTH_MOBILE, STICKER_SIZE_TWO_FA } from '../../config';
|
import { STICKER_SIZE_AUTH, STICKER_SIZE_AUTH_MOBILE, STICKER_SIZE_TWO_FA } from '../../config';
|
||||||
import { IS_MOBILE_SCREEN } from '../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
||||||
import getAnimationData from './helpers/animatedAssets';
|
import getAnimationData from './helpers/animatedAssets';
|
||||||
|
|
||||||
import AnimatedSticker from './AnimatedSticker';
|
import AnimatedSticker from './AnimatedSticker';
|
||||||
@ -19,7 +19,7 @@ const PEEK_MONKEY_SHOW_DELAY = 2000;
|
|||||||
const SEGMENT_COVER_EYES: [number, number] = [0, 50];
|
const SEGMENT_COVER_EYES: [number, number] = [0, 50];
|
||||||
const SEGMENT_UNCOVER_EYE: [number, number] = [0, 20];
|
const SEGMENT_UNCOVER_EYE: [number, number] = [0, 20];
|
||||||
const SEGMENT_COVER_EYE: [number, number] = [20, 0];
|
const SEGMENT_COVER_EYE: [number, number] = [20, 0];
|
||||||
const STICKER_SIZE = IS_MOBILE_SCREEN ? STICKER_SIZE_AUTH_MOBILE : STICKER_SIZE_AUTH;
|
const STICKER_SIZE = IS_SINGLE_COLUMN_LAYOUT ? STICKER_SIZE_AUTH_MOBILE : STICKER_SIZE_AUTH;
|
||||||
|
|
||||||
const PasswordMonkey: FC<OwnProps> = ({ isPasswordVisible, isBig }) => {
|
const PasswordMonkey: FC<OwnProps> = ({ isPasswordVisible, isBig }) => {
|
||||||
const [closeMonkeyData, setCloseMonkeyData] = useState<Record<string, any>>();
|
const [closeMonkeyData, setCloseMonkeyData] = useState<Record<string, any>>();
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import React, {
|
|||||||
} from '../../lib/teact/teact';
|
} from '../../lib/teact/teact';
|
||||||
|
|
||||||
import { STICKER_SIZE_AUTH, STICKER_SIZE_AUTH_MOBILE, STICKER_SIZE_TWO_FA } from '../../config';
|
import { STICKER_SIZE_AUTH, STICKER_SIZE_AUTH_MOBILE, STICKER_SIZE_TWO_FA } from '../../config';
|
||||||
import { IS_MOBILE_SCREEN } from '../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
||||||
import getAnimationData from './helpers/animatedAssets';
|
import getAnimationData from './helpers/animatedAssets';
|
||||||
|
|
||||||
import AnimatedSticker from './AnimatedSticker';
|
import AnimatedSticker from './AnimatedSticker';
|
||||||
@ -20,7 +20,7 @@ type OwnProps = {
|
|||||||
|
|
||||||
const TRACKING_START_FRAME = 15;
|
const TRACKING_START_FRAME = 15;
|
||||||
const TRACKING_END_FRAME = 180;
|
const TRACKING_END_FRAME = 180;
|
||||||
const STICKER_SIZE = IS_MOBILE_SCREEN ? STICKER_SIZE_AUTH_MOBILE : STICKER_SIZE_AUTH;
|
const STICKER_SIZE = IS_SINGLE_COLUMN_LAYOUT ? STICKER_SIZE_AUTH_MOBILE : STICKER_SIZE_AUTH;
|
||||||
|
|
||||||
const TrackingMonkey: FC<OwnProps> = ({
|
const TrackingMonkey: FC<OwnProps> = ({
|
||||||
code,
|
code,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { ApiPhoto, ApiVideo, ApiSticker } from '../../../api/types';
|
import { ApiPhoto, ApiVideo, ApiSticker } from '../../../api/types';
|
||||||
import { getPhotoInlineDimensions, getVideoDimensions, IDimensions } from '../../../modules/helpers';
|
import { getPhotoInlineDimensions, getVideoDimensions, IDimensions } from '../../../modules/helpers';
|
||||||
import windowSize from '../../../util/windowSize';
|
import windowSize from '../../../util/windowSize';
|
||||||
import { IS_MOBILE_SCREEN } from '../../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
|
||||||
import { STICKER_SIZE_INLINE_DESKTOP_FACTOR, STICKER_SIZE_INLINE_MOBILE_FACTOR } from '../../../config';
|
import { STICKER_SIZE_INLINE_DESKTOP_FACTOR, STICKER_SIZE_INLINE_MOBILE_FACTOR } from '../../../config';
|
||||||
|
|
||||||
export const MEDIA_VIEWER_MEDIA_QUERY = '(max-height: 640px)';
|
export const MEDIA_VIEWER_MEDIA_QUERY = '(max-height: 640px)';
|
||||||
@ -17,7 +17,7 @@ let cachedMaxWidth: number | undefined;
|
|||||||
|
|
||||||
function getMaxMessageWidthRem(fromOwnMessage: boolean) {
|
function getMaxMessageWidthRem(fromOwnMessage: boolean) {
|
||||||
const regularMaxWidth = fromOwnMessage ? 30 : 29;
|
const regularMaxWidth = fromOwnMessage ? 30 : 29;
|
||||||
if (!IS_MOBILE_SCREEN) {
|
if (!IS_SINGLE_COLUMN_LAYOUT) {
|
||||||
return regularMaxWidth;
|
return regularMaxWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +154,11 @@ export function getStickerDimensions(sticker: ApiSticker): IDimensions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const aspectRatio = (height && width) && height / width;
|
const aspectRatio = (height && width) && height / width;
|
||||||
const baseWidth = (IS_MOBILE_SCREEN ? STICKER_SIZE_INLINE_MOBILE_FACTOR : STICKER_SIZE_INLINE_DESKTOP_FACTOR) * REM;
|
const baseWidth = REM * (
|
||||||
|
IS_SINGLE_COLUMN_LAYOUT
|
||||||
|
? STICKER_SIZE_INLINE_MOBILE_FACTOR
|
||||||
|
: STICKER_SIZE_INLINE_DESKTOP_FACTOR
|
||||||
|
);
|
||||||
const calculatedHeight = aspectRatio ? baseWidth * aspectRatio : baseWidth;
|
const calculatedHeight = aspectRatio ? baseWidth * aspectRatio : baseWidth;
|
||||||
|
|
||||||
if (aspectRatio && calculatedHeight > baseWidth) {
|
if (aspectRatio && calculatedHeight > baseWidth) {
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { withGlobal } from '../../lib/teact/teactn';
|
|||||||
import { GlobalActions } from '../../global/types';
|
import { GlobalActions } from '../../global/types';
|
||||||
import { LeftColumnContent, SettingsScreens } from '../../types';
|
import { LeftColumnContent, SettingsScreens } from '../../types';
|
||||||
|
|
||||||
import { IS_MOBILE_SCREEN } from '../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
||||||
import captureEscKeyListener from '../../util/captureEscKeyListener';
|
import captureEscKeyListener from '../../util/captureEscKeyListener';
|
||||||
import { pick } from '../../util/iteratees';
|
import { pick } from '../../util/iteratees';
|
||||||
|
|
||||||
@ -240,7 +240,7 @@ const LeftColumn: FC<StateProps & DispatchProps> = ({
|
|||||||
return (
|
return (
|
||||||
<Transition
|
<Transition
|
||||||
id="LeftColumn"
|
id="LeftColumn"
|
||||||
name={IS_MOBILE_SCREEN ? 'slide-layers' : 'push-slide'}
|
name={IS_SINGLE_COLUMN_LAYOUT ? 'slide-layers' : 'push-slide'}
|
||||||
renderCount={RENDER_COUNT}
|
renderCount={RENDER_COUNT}
|
||||||
activeKey={contentType}
|
activeKey={contentType}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import {
|
|||||||
} from '../../../api/types';
|
} from '../../../api/types';
|
||||||
|
|
||||||
import { ANIMATION_END_DELAY } from '../../../config';
|
import { ANIMATION_END_DELAY } from '../../../config';
|
||||||
import { IS_MOBILE_SCREEN } from '../../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
|
||||||
import {
|
import {
|
||||||
getChatTitle,
|
getChatTitle,
|
||||||
isChatPrivate,
|
isChatPrivate,
|
||||||
@ -241,7 +241,7 @@ const Chat: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
const className = buildClassName(
|
const className = buildClassName(
|
||||||
'Chat chat-item-clickable',
|
'Chat chat-item-clickable',
|
||||||
isChatPrivate(chatId) ? 'private' : 'group',
|
isChatPrivate(chatId) ? 'private' : 'group',
|
||||||
isSelected && !IS_MOBILE_SCREEN && 'selected',
|
isSelected && !IS_SINGLE_COLUMN_LAYOUT && 'selected',
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -249,7 +249,7 @@ const Chat: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
ref={ref}
|
ref={ref}
|
||||||
className={className}
|
className={className}
|
||||||
style={style}
|
style={style}
|
||||||
ripple={!IS_MOBILE_SCREEN}
|
ripple={!IS_SINGLE_COLUMN_LAYOUT}
|
||||||
contextActions={contextActions}
|
contextActions={contextActions}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { withGlobal } from '../../../lib/teact/teactn';
|
|||||||
import { GlobalActions } from '../../../global/types';
|
import { GlobalActions } from '../../../global/types';
|
||||||
import { ApiUser } from '../../../api/types';
|
import { ApiUser } from '../../../api/types';
|
||||||
|
|
||||||
import { IS_MOBILE_SCREEN } from '../../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
|
||||||
import { throttle } from '../../../util/schedulers';
|
import { throttle } from '../../../util/schedulers';
|
||||||
import searchWords from '../../../util/searchWords';
|
import searchWords from '../../../util/searchWords';
|
||||||
import { pick } from '../../../util/iteratees';
|
import { pick } from '../../../util/iteratees';
|
||||||
@ -77,7 +77,7 @@ const ContactList: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
key={id}
|
key={id}
|
||||||
className="chat-item-clickable"
|
className="chat-item-clickable"
|
||||||
onClick={() => handleClick(id)}
|
onClick={() => handleClick(id)}
|
||||||
ripple={!IS_MOBILE_SCREEN}
|
ripple={!IS_SINGLE_COLUMN_LAYOUT}
|
||||||
>
|
>
|
||||||
<PrivateChatInfo userId={id} forceShowSelf avatarSize="large" />
|
<PrivateChatInfo userId={id} forceShowSelf avatarSize="large" />
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import { LeftColumnContent, ISettings } from '../../../types';
|
|||||||
import { ApiChat } from '../../../api/types';
|
import { ApiChat } from '../../../api/types';
|
||||||
|
|
||||||
import { APP_NAME, APP_VERSION, FEEDBACK_URL } from '../../../config';
|
import { APP_NAME, APP_VERSION, FEEDBACK_URL } from '../../../config';
|
||||||
import { IS_MOBILE_SCREEN } from '../../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import { pick } from '../../../util/iteratees';
|
import { pick } from '../../../util/iteratees';
|
||||||
import { isChatArchived } from '../../../modules/helpers';
|
import { isChatArchived } from '../../../modules/helpers';
|
||||||
@ -109,7 +109,7 @@ const LeftMainHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
return ({ onTrigger, isOpen }) => (
|
return ({ onTrigger, isOpen }) => (
|
||||||
<Button
|
<Button
|
||||||
round
|
round
|
||||||
ripple={hasMenu && !IS_MOBILE_SCREEN}
|
ripple={hasMenu && !IS_SINGLE_COLUMN_LAYOUT}
|
||||||
size="smaller"
|
size="smaller"
|
||||||
color="translucent"
|
color="translucent"
|
||||||
className={isOpen ? 'active' : ''}
|
className={isOpen ? 'active' : ''}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import React, {
|
|||||||
|
|
||||||
import { LeftColumnContent } from '../../../types';
|
import { LeftColumnContent } from '../../../types';
|
||||||
|
|
||||||
import { IS_MOBILE_SCREEN } from '../../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
|
||||||
|
|
||||||
import Transition from '../../ui/Transition';
|
import Transition from '../../ui/Transition';
|
||||||
import NewChatStep1 from './NewChatStep1';
|
import NewChatStep1 from './NewChatStep1';
|
||||||
@ -36,7 +36,7 @@ const NewChat: FC<OwnProps> = ({
|
|||||||
return (
|
return (
|
||||||
<Transition
|
<Transition
|
||||||
id="NewChat"
|
id="NewChat"
|
||||||
name={IS_MOBILE_SCREEN ? 'slide-layers' : 'push-slide'}
|
name={IS_SINGLE_COLUMN_LAYOUT ? 'slide-layers' : 'push-slide'}
|
||||||
renderCount={RENDER_COUNT}
|
renderCount={RENDER_COUNT}
|
||||||
activeKey={content}
|
activeKey={content}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import {
|
|||||||
ApiChat, ApiUser, ApiMessage, ApiMessageOutgoingStatus,
|
ApiChat, ApiUser, ApiMessage, ApiMessageOutgoingStatus,
|
||||||
} from '../../../api/types';
|
} from '../../../api/types';
|
||||||
|
|
||||||
import { IS_MOBILE_SCREEN } from '../../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
|
||||||
import {
|
import {
|
||||||
getChatTitle,
|
getChatTitle,
|
||||||
getPrivateChatUserId,
|
getPrivateChatUserId,
|
||||||
@ -76,7 +76,7 @@ const ChatMessage: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
return (
|
return (
|
||||||
<ListItem
|
<ListItem
|
||||||
className="ChatMessage chat-item-clickable"
|
className="ChatMessage chat-item-clickable"
|
||||||
ripple={!IS_MOBILE_SCREEN}
|
ripple={!IS_SINGLE_COLUMN_LAYOUT}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
buttonRef={buttonRef}
|
buttonRef={buttonRef}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import { ApiUser, ApiChat, ApiMessage } from '../../../api/types';
|
|||||||
import { GlobalActions } from '../../../global/types';
|
import { GlobalActions } from '../../../global/types';
|
||||||
import { LoadMoreDirection } from '../../../types';
|
import { LoadMoreDirection } from '../../../types';
|
||||||
|
|
||||||
import { IS_MOBILE_SCREEN } from '../../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
|
||||||
import searchWords from '../../../util/searchWords';
|
import searchWords from '../../../util/searchWords';
|
||||||
import { unique, pick } from '../../../util/iteratees';
|
import { unique, pick } from '../../../util/iteratees';
|
||||||
import { getUserFullName, getMessageSummaryText, sortChatIds } from '../../../modules/helpers';
|
import { getUserFullName, getMessageSummaryText, sortChatIds } from '../../../modules/helpers';
|
||||||
@ -88,7 +88,7 @@ const ChatResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
addRecentlyFoundChatId({ id });
|
addRecentlyFoundChatId({ id });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IS_MOBILE_SCREEN) {
|
if (!IS_SINGLE_COLUMN_LAYOUT) {
|
||||||
onReset();
|
onReset();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import React, { FC, memo, useCallback } from '../../../lib/teact/teact';
|
|||||||
|
|
||||||
import { SettingsScreens } from '../../../types';
|
import { SettingsScreens } from '../../../types';
|
||||||
|
|
||||||
import { IS_MOBILE_SCREEN } from '../../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
|
||||||
import useFoldersReducer from '../../../hooks/reducers/useFoldersReducer';
|
import useFoldersReducer from '../../../hooks/reducers/useFoldersReducer';
|
||||||
import useTwoFaReducer from '../../../hooks/reducers/useTwoFaReducer';
|
import useTwoFaReducer from '../../../hooks/reducers/useTwoFaReducer';
|
||||||
|
|
||||||
@ -213,7 +213,7 @@ const Settings: FC<OwnProps> = ({
|
|||||||
return (
|
return (
|
||||||
<Transition
|
<Transition
|
||||||
id="Settings"
|
id="Settings"
|
||||||
name={IS_MOBILE_SCREEN ? 'slide-layers' : 'push-slide'}
|
name={IS_SINGLE_COLUMN_LAYOUT ? 'slide-layers' : 'push-slide'}
|
||||||
activeKey={currentScreen}
|
activeKey={currentScreen}
|
||||||
renderCount={TRANSITION_RENDER_COUNT}
|
renderCount={TRANSITION_RENDER_COUNT}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { withGlobal } from '../../../lib/teact/teactn';
|
|||||||
import { GlobalActions } from '../../../global/types';
|
import { GlobalActions } from '../../../global/types';
|
||||||
import { SettingsScreens } from '../../../types';
|
import { SettingsScreens } from '../../../types';
|
||||||
|
|
||||||
import { IS_MOBILE_SCREEN } from '../../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
|
||||||
import { pick } from '../../../util/iteratees';
|
import { pick } from '../../../util/iteratees';
|
||||||
import useLang from '../../../hooks/useLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ const SettingsHeader: FC<OwnProps & DispatchProps> = ({
|
|||||||
return ({ onTrigger, isOpen }) => (
|
return ({ onTrigger, isOpen }) => (
|
||||||
<Button
|
<Button
|
||||||
round
|
round
|
||||||
ripple={!IS_MOBILE_SCREEN}
|
ripple={!IS_SINGLE_COLUMN_LAYOUT}
|
||||||
size="smaller"
|
size="smaller"
|
||||||
color="translucent"
|
color="translucent"
|
||||||
className={isOpen ? 'active' : ''}
|
className={isOpen ? 'active' : ''}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { withGlobal } from '../../../../lib/teact/teactn';
|
|||||||
|
|
||||||
import { ApiSticker } from '../../../../api/types';
|
import { ApiSticker } from '../../../../api/types';
|
||||||
|
|
||||||
import { IS_MOBILE_SCREEN, IS_TOUCH_ENV } from '../../../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT, IS_TOUCH_ENV } from '../../../../util/environment';
|
||||||
import { selectAnimatedEmoji } from '../../../../modules/selectors';
|
import { selectAnimatedEmoji } from '../../../../modules/selectors';
|
||||||
import useLang from '../../../../hooks/useLang';
|
import useLang from '../../../../hooks/useLang';
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ type StateProps = {
|
|||||||
codeLength: number;
|
codeLength: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
const FOCUS_DELAY_TIMEOUT_MS = IS_MOBILE_SCREEN ? 550 : 400;
|
const FOCUS_DELAY_TIMEOUT_MS = IS_SINGLE_COLUMN_LAYOUT ? 550 : 400;
|
||||||
|
|
||||||
const SettingsTwoFaEmailCode: FC<OwnProps & StateProps> = ({
|
const SettingsTwoFaEmailCode: FC<OwnProps & StateProps> = ({
|
||||||
animatedEmoji,
|
animatedEmoji,
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { withGlobal } from '../../../../lib/teact/teactn';
|
|||||||
|
|
||||||
import { ApiSticker } from '../../../../api/types';
|
import { ApiSticker } from '../../../../api/types';
|
||||||
|
|
||||||
import { IS_MOBILE_SCREEN, IS_TOUCH_ENV } from '../../../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT, IS_TOUCH_ENV } from '../../../../util/environment';
|
||||||
import { selectAnimatedEmoji } from '../../../../modules/selectors';
|
import { selectAnimatedEmoji } from '../../../../modules/selectors';
|
||||||
import useFlag from '../../../../hooks/useFlag';
|
import useFlag from '../../../../hooks/useFlag';
|
||||||
import useLang from '../../../../hooks/useLang';
|
import useLang from '../../../../hooks/useLang';
|
||||||
@ -31,7 +31,7 @@ type StateProps = {
|
|||||||
animatedEmoji: ApiSticker;
|
animatedEmoji: ApiSticker;
|
||||||
};
|
};
|
||||||
|
|
||||||
const FOCUS_DELAY_TIMEOUT_MS = IS_MOBILE_SCREEN ? 550 : 400;
|
const FOCUS_DELAY_TIMEOUT_MS = IS_SINGLE_COLUMN_LAYOUT ? 550 : 400;
|
||||||
|
|
||||||
const SettingsTwoFaSkippableForm: FC<OwnProps & StateProps> = ({
|
const SettingsTwoFaSkippableForm: FC<OwnProps & StateProps> = ({
|
||||||
animatedEmoji,
|
animatedEmoji,
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { withGlobal } from '../../lib/teact/teactn';
|
|||||||
import { GlobalActions } from '../../global/types';
|
import { GlobalActions } from '../../global/types';
|
||||||
import { ApiChat, MAIN_THREAD_ID } from '../../api/types';
|
import { ApiChat, MAIN_THREAD_ID } from '../../api/types';
|
||||||
|
|
||||||
import { IS_MOBILE_SCREEN } from '../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
||||||
import {
|
import {
|
||||||
getCanPostInChat, getChatTitle, isChatPrivate, sortChatIds,
|
getCanPostInChat, getChatTitle, isChatPrivate, sortChatIds,
|
||||||
} from '../../modules/helpers';
|
} from '../../modules/helpers';
|
||||||
@ -65,7 +65,7 @@ const ForwardPicker: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
if (!IS_MOBILE_SCREEN) {
|
if (!IS_SINGLE_COLUMN_LAYOUT) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
if (inputRef.current) {
|
if (inputRef.current) {
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import {
|
|||||||
import { MediaViewerOrigin } from '../../types';
|
import { MediaViewerOrigin } from '../../types';
|
||||||
|
|
||||||
import { ANIMATION_END_DELAY } from '../../config';
|
import { ANIMATION_END_DELAY } from '../../config';
|
||||||
import { IS_IOS, IS_MOBILE_SCREEN, IS_TOUCH_ENV } from '../../util/environment';
|
import { IS_IOS, IS_SINGLE_COLUMN_LAYOUT, IS_TOUCH_ENV } from '../../util/environment';
|
||||||
import {
|
import {
|
||||||
AVATAR_FULL_DIMENSIONS,
|
AVATAR_FULL_DIMENSIONS,
|
||||||
MEDIA_VIEWER_MEDIA_QUERY,
|
MEDIA_VIEWER_MEDIA_QUERY,
|
||||||
@ -126,6 +126,7 @@ const MediaViewer: FC<StateProps & DispatchProps> = ({
|
|||||||
const [isZoomed, setIsZoomed] = useState<boolean>(false);
|
const [isZoomed, setIsZoomed] = useState<boolean>(false);
|
||||||
const [zoomLevel, setZoomLevel] = useState<number>(1);
|
const [zoomLevel, setZoomLevel] = useState<number>(1);
|
||||||
const [panDelta, setPanDelta] = useState({ x: 0, y: 0 });
|
const [panDelta, setPanDelta] = useState({ x: 0, y: 0 });
|
||||||
|
const [isFooterHidden, setIsFooterHidden] = useState<boolean>(false);
|
||||||
|
|
||||||
const messageIds = useMemo(() => {
|
const messageIds = useMemo(() => {
|
||||||
return isWebPagePhoto && messageId
|
return isWebPagePhoto && messageId
|
||||||
@ -189,7 +190,7 @@ const MediaViewer: FC<StateProps & DispatchProps> = ({
|
|||||||
const videoDimensions = isVideo ? getVideoDimensions(getMessageVideo(message!)!) : undefined;
|
const videoDimensions = isVideo ? getVideoDimensions(getMessageVideo(message!)!) : undefined;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!IS_MOBILE_SCREEN) {
|
if (!IS_SINGLE_COLUMN_LAYOUT) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,7 +374,7 @@ const MediaViewer: FC<StateProps & DispatchProps> = ({
|
|||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
excludedClosestSelector: `.backdrop, .navigation, .media-viewer-head, .media-viewer-footer${!shouldCloseOnVideo ? ', .VideoPlayer' : ''}`,
|
excludedClosestSelector: `.backdrop, .navigation, .media-viewer-head, .media-viewer-footer${!shouldCloseOnVideo ? ', .VideoPlayer' : ''}`,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
if (!isZoomed) {
|
if (!isZoomed && !IS_TOUCH_ENV) {
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -382,17 +383,23 @@ const MediaViewer: FC<StateProps & DispatchProps> = ({
|
|||||||
selectPreviousMedia();
|
selectPreviousMedia();
|
||||||
} else if (direction === SwipeDirection.Left) {
|
} else if (direction === SwipeDirection.Left) {
|
||||||
selectNextMedia();
|
selectNextMedia();
|
||||||
} else {
|
} else if (!(e.target && (e.target as HTMLElement).closest('.MediaViewerFooter'))) {
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
} : undefined,
|
} : undefined,
|
||||||
});
|
});
|
||||||
}, [close, isGif, isZoomed, selectNextMedia, selectPreviousMedia, canPanZoomWrap]);
|
}, [close, isFooterHidden, isGif, isPhoto, isZoomed, selectNextMedia, selectPreviousMedia]);
|
||||||
|
|
||||||
const handlePan = useCallback((x: number, y: number) => {
|
const handlePan = useCallback((x: number, y: number) => {
|
||||||
setPanDelta({ x, y });
|
setPanDelta({ x, y });
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const handleToggleFooterVisibility = useCallback(() => {
|
||||||
|
if (IS_TOUCH_ENV && (isPhoto || isGif)) {
|
||||||
|
setIsFooterHidden(!isFooterHidden);
|
||||||
|
}
|
||||||
|
}, [isFooterHidden, isGif, isPhoto]);
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
function renderSlide(isActive: boolean) {
|
function renderSlide(isActive: boolean) {
|
||||||
@ -402,7 +409,7 @@ const MediaViewer: FC<StateProps & DispatchProps> = ({
|
|||||||
{renderPhoto(
|
{renderPhoto(
|
||||||
fullMediaData || blobUrlPreview,
|
fullMediaData || blobUrlPreview,
|
||||||
calculateMediaViewerDimensions(AVATAR_FULL_DIMENSIONS, false),
|
calculateMediaViewerDimensions(AVATAR_FULL_DIMENSIONS, false),
|
||||||
!IS_MOBILE_SCREEN && !isZoomed,
|
!IS_SINGLE_COLUMN_LAYOUT && !isZoomed,
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -411,11 +418,15 @@ const MediaViewer: FC<StateProps & DispatchProps> = ({
|
|||||||
const hasFooter = Boolean(textParts);
|
const hasFooter = Boolean(textParts);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={messageId} className={`media-viewer-content ${hasFooter ? 'has-footer' : ''}`}>
|
<div
|
||||||
|
key={messageId}
|
||||||
|
className={`media-viewer-content ${hasFooter ? 'has-footer' : ''}`}
|
||||||
|
onClick={handleToggleFooterVisibility}
|
||||||
|
>
|
||||||
{isPhoto && renderPhoto(
|
{isPhoto && renderPhoto(
|
||||||
localBlobUrl || fullMediaData || blobUrlPreview || blobUrlPictogram,
|
localBlobUrl || fullMediaData || blobUrlPreview || blobUrlPictogram,
|
||||||
message && calculateMediaViewerDimensions(photoDimensions!, hasFooter),
|
message && calculateMediaViewerDimensions(photoDimensions!, hasFooter),
|
||||||
!IS_MOBILE_SCREEN && !isZoomed,
|
!IS_SINGLE_COLUMN_LAYOUT && !isZoomed,
|
||||||
)}
|
)}
|
||||||
{isVideo && (
|
{isVideo && (
|
||||||
<VideoPlayer
|
<VideoPlayer
|
||||||
@ -435,7 +446,8 @@ const MediaViewer: FC<StateProps & DispatchProps> = ({
|
|||||||
<MediaViewerFooter
|
<MediaViewerFooter
|
||||||
text={textParts}
|
text={textParts}
|
||||||
onClick={handleFooterClick}
|
onClick={handleFooterClick}
|
||||||
isHideable={isVideo}
|
isHidden={isFooterHidden && (!isVideo || isGif)}
|
||||||
|
isForVideo={isVideo && !isGif}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -465,7 +477,7 @@ const MediaViewer: FC<StateProps & DispatchProps> = ({
|
|||||||
{() => (
|
{() => (
|
||||||
<>
|
<>
|
||||||
<div className="media-viewer-head" dir={lang.isRtl ? 'rtl' : undefined}>
|
<div className="media-viewer-head" dir={lang.isRtl ? 'rtl' : undefined}>
|
||||||
{IS_MOBILE_SCREEN && (
|
{IS_SINGLE_COLUMN_LAYOUT && (
|
||||||
<Button
|
<Button
|
||||||
className="media-viewer-close"
|
className="media-viewer-close"
|
||||||
round
|
round
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import React, { FC, useMemo } from '../../lib/teact/teact';
|
|||||||
|
|
||||||
import { ApiMessage } from '../../api/types';
|
import { ApiMessage } from '../../api/types';
|
||||||
|
|
||||||
import { IS_MOBILE_SCREEN } from '../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
||||||
import { getMessageMediaHash } from '../../modules/helpers';
|
import { getMessageMediaHash } from '../../modules/helpers';
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ const MediaViewerActions: FC<OwnProps> = ({
|
|||||||
);
|
);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if (IS_MOBILE_SCREEN) {
|
if (IS_SINGLE_COLUMN_LAYOUT) {
|
||||||
return (
|
return (
|
||||||
<div className="MediaViewerActions-mobile">
|
<div className="MediaViewerActions-mobile">
|
||||||
<DropdownMenu
|
<DropdownMenu
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
padding-bottom: 4.5rem;
|
padding-bottom: 4.5rem;
|
||||||
background: linear-gradient(to top, #000 0%, rgba(0, 0, 0, 0) 100%);
|
background: linear-gradient(to top, #000 0%, rgba(0, 0, 0, 0) 100%);
|
||||||
|
|
||||||
&.hideable {
|
&.is-for-video {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
|
||||||
@ -44,6 +44,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.is-hidden {
|
||||||
|
.media-viewer-footer-content {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.media-text {
|
.media-text {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
import React, { FC, useEffect, useState } from '../../lib/teact/teact';
|
import React, { FC, useEffect, useState } from '../../lib/teact/teact';
|
||||||
|
|
||||||
import { throttle } from '../../util/schedulers';
|
import { throttle } from '../../util/schedulers';
|
||||||
import { TextPart } from '../common/helpers/renderMessageText';
|
import { TextPart } from '../common/helpers/renderMessageText';
|
||||||
|
import buildClassName from '../../util/buildClassName';
|
||||||
import { REM } from '../common/helpers/mediaDimensions';
|
import { REM } from '../common/helpers/mediaDimensions';
|
||||||
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
||||||
|
|
||||||
import './MediaViewerFooter.scss';
|
import './MediaViewerFooter.scss';
|
||||||
|
|
||||||
@ -10,10 +13,13 @@ const RESIZE_THROTTLE_MS = 500;
|
|||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
text: TextPart | TextPart[];
|
text: TextPart | TextPart[];
|
||||||
onClick: () => void;
|
onClick: () => void;
|
||||||
isHideable: boolean;
|
isHidden?: boolean;
|
||||||
|
isForVideo: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const MediaViewerFooter: FC<OwnProps> = ({ text = '', isHideable, onClick }) => {
|
const MediaViewerFooter: FC<OwnProps> = ({
|
||||||
|
text = '', isHidden, isForVideo, onClick,
|
||||||
|
}) => {
|
||||||
const [isMultiline, setIsMultiline] = useState(false);
|
const [isMultiline, setIsMultiline] = useState(false);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const footerContent = document.querySelector('.MediaViewerFooter .media-text') as HTMLDivElement | null;
|
const footerContent = document.querySelector('.MediaViewerFooter .media-text') as HTMLDivElement | null;
|
||||||
@ -42,10 +48,16 @@ const MediaViewerFooter: FC<OwnProps> = ({ text = '', isHideable, onClick }) =>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const classNames = buildClassName(
|
||||||
|
'MediaViewerFooter',
|
||||||
|
isForVideo && 'is-for-video',
|
||||||
|
isHidden && 'is-hidden',
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`MediaViewerFooter ${isHideable ? 'hideable' : ''}`} onClick={stopEvent}>
|
<div className={classNames} onClick={stopEvent}>
|
||||||
{text && (
|
{text && (
|
||||||
<div className="media-viewer-footer-content" onClick={onClick}>
|
<div className="media-viewer-footer-content" onClick={!IS_SINGLE_COLUMN_LAYOUT ? onClick : undefined}>
|
||||||
<p className={`media-text custom-scroll ${isMultiline ? 'multiline' : ''}`} dir="auto">{text}</p>
|
<p className={`media-text custom-scroll ${isMultiline ? 'multiline' : ''}`} dir="auto">{text}</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import React, {
|
|||||||
|
|
||||||
import { IDimensions } from '../../modules/helpers';
|
import { IDimensions } from '../../modules/helpers';
|
||||||
|
|
||||||
import { IS_IOS, IS_MOBILE_SCREEN, IS_TOUCH_ENV } from '../../util/environment';
|
import { IS_IOS, IS_SINGLE_COLUMN_LAYOUT, IS_TOUCH_ENV } from '../../util/environment';
|
||||||
import useShowTransition from '../../hooks/useShowTransition';
|
import useShowTransition from '../../hooks/useShowTransition';
|
||||||
import useBuffering from '../../hooks/useBuffering';
|
import useBuffering from '../../hooks/useBuffering';
|
||||||
import useFullscreenStatus from '../../hooks/useFullscreen';
|
import useFullscreenStatus from '../../hooks/useFullscreen';
|
||||||
@ -144,7 +144,7 @@ const VideoPlayer: FC<OwnProps> = ({
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="VideoPlayer"
|
className="VideoPlayer"
|
||||||
onClick={!isGif && IS_MOBILE_SCREEN ? toggleControls : undefined}
|
onClick={!isGif && IS_SINGLE_COLUMN_LAYOUT ? toggleControls : undefined}
|
||||||
onMouseOver={!isGif ? handleMouseOver : undefined}
|
onMouseOver={!isGif ? handleMouseOver : undefined}
|
||||||
onMouseOut={!isGif ? handleMouseOut : undefined}
|
onMouseOut={!isGif ? handleMouseOut : undefined}
|
||||||
>
|
>
|
||||||
@ -164,7 +164,7 @@ const VideoPlayer: FC<OwnProps> = ({
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
style={videoStyle}
|
style={videoStyle}
|
||||||
onEnded={handleEnded}
|
onEnded={handleEnded}
|
||||||
onClick={togglePlayState}
|
onClick={!IS_SINGLE_COLUMN_LAYOUT ? togglePlayState : undefined}
|
||||||
onDoubleClick={handleFullscreenChange}
|
onDoubleClick={handleFullscreenChange}
|
||||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||||
{...bufferingHandlers}
|
{...bufferingHandlers}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import React, { FC, useState, useEffect } from '../../lib/teact/teact';
|
import React, { FC, useState, useEffect } from '../../lib/teact/teact';
|
||||||
|
|
||||||
import { IS_MOBILE_SCREEN } from '../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
||||||
import { formatMediaDuration } from '../../util/dateFormat';
|
import { formatMediaDuration } from '../../util/dateFormat';
|
||||||
import formatFileSize from './helpers/formatFileSize';
|
import formatFileSize from './helpers/formatFileSize';
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
@ -58,7 +58,7 @@ const VideoPlayerControls: FC<IProps> = ({
|
|||||||
let timeout: number | undefined;
|
let timeout: number | undefined;
|
||||||
|
|
||||||
if (!isForceVisible) {
|
if (!isForceVisible) {
|
||||||
if (IS_MOBILE_SCREEN) {
|
if (IS_SINGLE_COLUMN_LAYOUT) {
|
||||||
setVisibility(false);
|
setVisibility(false);
|
||||||
} else {
|
} else {
|
||||||
timeout = window.setTimeout(() => {
|
timeout = window.setTimeout(() => {
|
||||||
@ -96,7 +96,7 @@ const VideoPlayerControls: FC<IProps> = ({
|
|||||||
<Button
|
<Button
|
||||||
ariaLabel={lang('AccActionPlay')}
|
ariaLabel={lang('AccActionPlay')}
|
||||||
size="tiny"
|
size="tiny"
|
||||||
ripple={!IS_MOBILE_SCREEN}
|
ripple={!IS_SINGLE_COLUMN_LAYOUT}
|
||||||
color="translucent-white"
|
color="translucent-white"
|
||||||
className="play"
|
className="play"
|
||||||
onClick={onPlayPause}
|
onClick={onPlayPause}
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import React, {
|
|||||||
FC, memo, useCallback, useEffect, useRef, useState,
|
FC, memo, useCallback, useEffect, useRef, useState,
|
||||||
} from '../../lib/teact/teact';
|
} from '../../lib/teact/teact';
|
||||||
|
|
||||||
import { IS_MOBILE_SCREEN } from '../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
||||||
import buildClassName from '../../util/buildClassName';
|
import buildClassName from '../../util/buildClassName';
|
||||||
import usePrevious from '../../hooks/usePrevious';
|
import usePrevious from '../../hooks/usePrevious';
|
||||||
import useShowTransition from '../../hooks/useShowTransition';
|
import useShowTransition from '../../hooks/useShowTransition';
|
||||||
@ -82,7 +82,7 @@ const ZoomControls: FC<OwnProps> = ({ isShown, onChangeZoom }) => {
|
|||||||
color="translucent-white"
|
color="translucent-white"
|
||||||
ariaLabel={lang('ZoomOut')}
|
ariaLabel={lang('ZoomOut')}
|
||||||
className="zoom-out"
|
className="zoom-out"
|
||||||
ripple={!IS_MOBILE_SCREEN}
|
ripple={!IS_SINGLE_COLUMN_LAYOUT}
|
||||||
onClick={handleZoomOut}
|
onClick={handleZoomOut}
|
||||||
>
|
>
|
||||||
<i className="icon-zoom-out" />
|
<i className="icon-zoom-out" />
|
||||||
@ -93,7 +93,7 @@ const ZoomControls: FC<OwnProps> = ({ isShown, onChangeZoom }) => {
|
|||||||
color="translucent-white"
|
color="translucent-white"
|
||||||
ariaLabel="Zoom In"
|
ariaLabel="Zoom In"
|
||||||
className="zoom-in"
|
className="zoom-in"
|
||||||
ripple={!IS_MOBILE_SCREEN}
|
ripple={!IS_SINGLE_COLUMN_LAYOUT}
|
||||||
onClick={handleZoomIn}
|
onClick={handleZoomIn}
|
||||||
>
|
>
|
||||||
<i className="icon-zoom-in" />
|
<i className="icon-zoom-in" />
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import {
|
|||||||
ApiAudio, ApiChat, ApiMessage, ApiUser,
|
ApiAudio, ApiChat, ApiMessage, ApiUser,
|
||||||
} from '../../api/types';
|
} from '../../api/types';
|
||||||
|
|
||||||
import { IS_MOBILE_SCREEN } from '../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
||||||
import * as mediaLoader from '../../util/mediaLoader';
|
import * as mediaLoader from '../../util/mediaLoader';
|
||||||
import {
|
import {
|
||||||
getMediaDuration, getMessageAudio, getMessageKey, getMessageMediaHash, getSenderTitle,
|
getMediaDuration, getMessageAudio, getMessageKey, getMessageMediaHash, getSenderTitle,
|
||||||
@ -67,7 +67,7 @@ const AudioPlayer: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
<div className={buildClassName('AudioPlayer', className)} dir={lang.isRtl ? 'rtl' : undefined}>
|
<div className={buildClassName('AudioPlayer', className)} dir={lang.isRtl ? 'rtl' : undefined}>
|
||||||
<Button
|
<Button
|
||||||
round
|
round
|
||||||
ripple={!IS_MOBILE_SCREEN}
|
ripple={!IS_SINGLE_COLUMN_LAYOUT}
|
||||||
color="translucent"
|
color="translucent"
|
||||||
size="smaller"
|
size="smaller"
|
||||||
className={buildClassName('toggle-play', isPlaying ? 'pause' : 'play')}
|
className={buildClassName('toggle-play', isPlaying ? 'pause' : 'play')}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import { GlobalActions, MessageListType } from '../../global/types';
|
|||||||
import { MAIN_THREAD_ID } from '../../api/types';
|
import { MAIN_THREAD_ID } from '../../api/types';
|
||||||
import { IAnchorPosition } from '../../types';
|
import { IAnchorPosition } from '../../types';
|
||||||
|
|
||||||
import { IS_MOBILE_SCREEN } from '../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
||||||
import { pick } from '../../util/iteratees';
|
import { pick } from '../../util/iteratees';
|
||||||
import { isChatChannel, isChatSuperGroup } from '../../modules/helpers';
|
import { isChatChannel, isChatSuperGroup } from '../../modules/helpers';
|
||||||
import {
|
import {
|
||||||
@ -94,7 +94,7 @@ const HeaderActions: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
const handleSearchClick = useCallback(() => {
|
const handleSearchClick = useCallback(() => {
|
||||||
openLocalTextSearch();
|
openLocalTextSearch();
|
||||||
|
|
||||||
if (IS_MOBILE_SCREEN) {
|
if (IS_SINGLE_COLUMN_LAYOUT) {
|
||||||
// iOS requires synchronous focus on user event.
|
// iOS requires synchronous focus on user event.
|
||||||
const searchInput = document.querySelector<HTMLInputElement>('#MobileSearch input')!;
|
const searchInput = document.querySelector<HTMLInputElement>('#MobileSearch input')!;
|
||||||
searchInput.focus();
|
searchInput.focus();
|
||||||
@ -112,7 +112,7 @@ const HeaderActions: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="HeaderActions">
|
<div className="HeaderActions">
|
||||||
{!IS_MOBILE_SCREEN && canSubscribe && (
|
{!IS_SINGLE_COLUMN_LAYOUT && canSubscribe && (
|
||||||
<Button
|
<Button
|
||||||
size="tiny"
|
size="tiny"
|
||||||
ripple
|
ripple
|
||||||
@ -122,7 +122,7 @@ const HeaderActions: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
{lang(isChannel ? 'Subscribe' : 'Join Group')}
|
{lang(isChannel ? 'Subscribe' : 'Join Group')}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{!IS_MOBILE_SCREEN && canStartBot && (
|
{!IS_SINGLE_COLUMN_LAYOUT && canStartBot && (
|
||||||
<Button
|
<Button
|
||||||
size="tiny"
|
size="tiny"
|
||||||
ripple
|
ripple
|
||||||
@ -132,7 +132,7 @@ const HeaderActions: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
{lang('Start')}
|
{lang('Start')}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{!IS_MOBILE_SCREEN && canSearch && (
|
{!IS_SINGLE_COLUMN_LAYOUT && canSearch && (
|
||||||
<Button
|
<Button
|
||||||
round
|
round
|
||||||
ripple={isRightColumnShown}
|
ripple={isRightColumnShown}
|
||||||
@ -144,12 +144,12 @@ const HeaderActions: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
<i className="icon-search" />
|
<i className="icon-search" />
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{(IS_MOBILE_SCREEN || !canSubscribe) && (
|
{(IS_SINGLE_COLUMN_LAYOUT || !canSubscribe) && (
|
||||||
<Button
|
<Button
|
||||||
ref={menuButtonRef}
|
ref={menuButtonRef}
|
||||||
className={isMenuOpen ? 'active' : ''}
|
className={isMenuOpen ? 'active' : ''}
|
||||||
round
|
round
|
||||||
ripple={!IS_MOBILE_SCREEN}
|
ripple={!IS_SINGLE_COLUMN_LAYOUT}
|
||||||
size="smaller"
|
size="smaller"
|
||||||
color="translucent"
|
color="translucent"
|
||||||
disabled={noMenu}
|
disabled={noMenu}
|
||||||
@ -207,8 +207,8 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
const canLeave = isMainThread && !canSubscribe;
|
const canLeave = isMainThread && !canSubscribe;
|
||||||
|
|
||||||
const noMenu = !(
|
const noMenu = !(
|
||||||
(IS_MOBILE_SCREEN && canSubscribe)
|
(IS_SINGLE_COLUMN_LAYOUT && canSubscribe)
|
||||||
|| (IS_MOBILE_SCREEN && canSearch)
|
|| (IS_SINGLE_COLUMN_LAYOUT && canSearch)
|
||||||
|| canMute
|
|| canMute
|
||||||
|| canSelect
|
|| canSelect
|
||||||
|| canLeave
|
|| canLeave
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import { GlobalActions } from '../../global/types';
|
|||||||
import { ApiChat } from '../../api/types';
|
import { ApiChat } from '../../api/types';
|
||||||
import { IAnchorPosition } from '../../types';
|
import { IAnchorPosition } from '../../types';
|
||||||
|
|
||||||
import { IS_MOBILE_SCREEN } from '../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
||||||
import { disableScrolling, enableScrolling } from '../../util/scrollLock';
|
import { disableScrolling, enableScrolling } from '../../util/scrollLock';
|
||||||
import { selectChat } from '../../modules/selectors';
|
import { selectChat } from '../../modules/selectors';
|
||||||
import { pick } from '../../util/iteratees';
|
import { pick } from '../../util/iteratees';
|
||||||
@ -127,7 +127,7 @@ const HeaderMenuContainer: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
style={`left: ${x}px;top: ${y}px;`}
|
style={`left: ${x}px;top: ${y}px;`}
|
||||||
onClose={closeMenu}
|
onClose={closeMenu}
|
||||||
>
|
>
|
||||||
{IS_MOBILE_SCREEN && canSubscribe && (
|
{IS_SINGLE_COLUMN_LAYOUT && canSubscribe && (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
icon={isChannel ? 'channel' : 'group'}
|
icon={isChannel ? 'channel' : 'group'}
|
||||||
onClick={handleSubscribe}
|
onClick={handleSubscribe}
|
||||||
@ -135,7 +135,7 @@ const HeaderMenuContainer: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
{lang(isChannel ? 'Subscribe' : 'Join Group')}
|
{lang(isChannel ? 'Subscribe' : 'Join Group')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
{IS_MOBILE_SCREEN && canSearch && (
|
{IS_SINGLE_COLUMN_LAYOUT && canSearch && (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
icon="search"
|
icon="search"
|
||||||
onClick={handleSearch}
|
onClick={handleSearch}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import { GlobalActions, MessageListType } from '../../global/types';
|
|||||||
import { LoadMoreDirection } from '../../types';
|
import { LoadMoreDirection } from '../../types';
|
||||||
|
|
||||||
import { ANIMATION_END_DELAY, MESSAGE_LIST_SLICE, SCHEDULED_WHEN_ONLINE } from '../../config';
|
import { ANIMATION_END_DELAY, MESSAGE_LIST_SLICE, SCHEDULED_WHEN_ONLINE } from '../../config';
|
||||||
import { IS_ANDROID, IS_MOBILE_SCREEN } from '../../util/environment';
|
import { IS_ANDROID, IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
||||||
import {
|
import {
|
||||||
selectChatMessages,
|
selectChatMessages,
|
||||||
selectIsViewportNewest,
|
selectIsViewportNewest,
|
||||||
@ -102,7 +102,7 @@ const UNREAD_DIVIDER_TOP = 10;
|
|||||||
const UNREAD_DIVIDER_TOP_WITH_TOOLS = 60;
|
const UNREAD_DIVIDER_TOP_WITH_TOOLS = 60;
|
||||||
const SCROLL_DEBOUNCE = 200;
|
const SCROLL_DEBOUNCE = 200;
|
||||||
const INTERSECTION_THROTTLE_FOR_MEDIA = IS_ANDROID ? 1000 : 350;
|
const INTERSECTION_THROTTLE_FOR_MEDIA = IS_ANDROID ? 1000 : 350;
|
||||||
const INTERSECTION_MARGIN_FOR_MEDIA = IS_MOBILE_SCREEN ? 300 : 500;
|
const INTERSECTION_MARGIN_FOR_MEDIA = IS_SINGLE_COLUMN_LAYOUT ? 300 : 500;
|
||||||
const FOCUSING_DURATION = 1000;
|
const FOCUSING_DURATION = 1000;
|
||||||
const BOTTOM_FOCUS_MARGIN = 20;
|
const BOTTOM_FOCUS_MARGIN = 20;
|
||||||
const SELECT_MODE_ANIMATION_DURATION = 200;
|
const SELECT_MODE_ANIMATION_DURATION = 200;
|
||||||
|
|||||||
@ -19,7 +19,7 @@ import {
|
|||||||
DARK_THEME_BG_COLOR,
|
DARK_THEME_BG_COLOR,
|
||||||
LIGHT_THEME_BG_COLOR,
|
LIGHT_THEME_BG_COLOR,
|
||||||
} from '../../config';
|
} from '../../config';
|
||||||
import { IS_MOBILE_SCREEN, IS_TOUCH_ENV, MASK_IMAGE_DISABLED } from '../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT, IS_TOUCH_ENV, MASK_IMAGE_DISABLED } from '../../util/environment';
|
||||||
import { DropAreaState } from './composer/DropArea';
|
import { DropAreaState } from './composer/DropArea';
|
||||||
import {
|
import {
|
||||||
selectChat,
|
selectChat,
|
||||||
@ -76,7 +76,7 @@ type StateProps = {
|
|||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'openChat' | 'unpinAllMessages' | 'loadUser'>;
|
type DispatchProps = Pick<GlobalActions, 'openChat' | 'unpinAllMessages' | 'loadUser'>;
|
||||||
|
|
||||||
const CLOSE_ANIMATION_DURATION = IS_MOBILE_SCREEN ? 450 + ANIMATION_END_DELAY : undefined;
|
const CLOSE_ANIMATION_DURATION = IS_SINGLE_COLUMN_LAYOUT ? 450 + ANIMATION_END_DELAY : undefined;
|
||||||
|
|
||||||
function canBeQuicklyUploaded(item: DataTransferItem) {
|
function canBeQuicklyUploaded(item: DataTransferItem) {
|
||||||
return item.kind === 'file' && item.type && CONTENT_TYPES_FOR_QUICK_UPLOAD.includes(item.type);
|
return item.kind === 'file' && item.type && CONTENT_TYPES_FOR_QUICK_UPLOAD.includes(item.type);
|
||||||
@ -308,7 +308,7 @@ const MiddleColumn: FC<StateProps & DispatchProps> = ({
|
|||||||
canPost={renderingCanPost}
|
canPost={renderingCanPost}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{IS_MOBILE_SCREEN && <MobileSearch isActive={Boolean(isMobileSearchActive)} />}
|
{IS_SINGLE_COLUMN_LAYOUT && <MobileSearch isActive={Boolean(isMobileSearchActive)} />}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{chatId && (
|
{chatId && (
|
||||||
@ -341,7 +341,7 @@ export default memo(withGlobal(
|
|||||||
patternColor,
|
patternColor,
|
||||||
isRightColumnShown: selectIsRightColumnShown(global),
|
isRightColumnShown: selectIsRightColumnShown(global),
|
||||||
isBackgroundBlurred,
|
isBackgroundBlurred,
|
||||||
isMobileSearchActive: Boolean(IS_MOBILE_SCREEN && selectCurrentTextSearch(global)),
|
isMobileSearchActive: Boolean(IS_SINGLE_COLUMN_LAYOUT && selectCurrentTextSearch(global)),
|
||||||
isSelectModeActive: selectIsInSelectMode(global),
|
isSelectModeActive: selectIsInSelectMode(global),
|
||||||
animationLevel: global.settings.byKey.animationLevel,
|
animationLevel: global.settings.byKey.animationLevel,
|
||||||
};
|
};
|
||||||
@ -365,7 +365,7 @@ export default memo(withGlobal(
|
|||||||
threadId,
|
threadId,
|
||||||
messageListType,
|
messageListType,
|
||||||
isPrivate: isChatPrivate(chatId),
|
isPrivate: isChatPrivate(chatId),
|
||||||
canPost: !isPinnedMessageList && (!chat || canPost) && (!isBotNotStarted || IS_MOBILE_SCREEN),
|
canPost: !isPinnedMessageList && (!chat || canPost) && (!isBotNotStarted || IS_SINGLE_COLUMN_LAYOUT),
|
||||||
isPinnedMessageList,
|
isPinnedMessageList,
|
||||||
messageSendingRestrictionReason: chat && getMessageSendingRestrictionReason(chat),
|
messageSendingRestrictionReason: chat && getMessageSendingRestrictionReason(chat),
|
||||||
hasPinnedOrAudioMessage: (
|
hasPinnedOrAudioMessage: (
|
||||||
|
|||||||
@ -21,7 +21,7 @@ import {
|
|||||||
SAFE_SCREEN_WIDTH_FOR_STATIC_RIGHT_COLUMN,
|
SAFE_SCREEN_WIDTH_FOR_STATIC_RIGHT_COLUMN,
|
||||||
SAFE_SCREEN_WIDTH_FOR_CHAT_INFO,
|
SAFE_SCREEN_WIDTH_FOR_CHAT_INFO,
|
||||||
} from '../../config';
|
} from '../../config';
|
||||||
import { IS_MOBILE_SCREEN } from '../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
||||||
import {
|
import {
|
||||||
isChatPrivate,
|
isChatPrivate,
|
||||||
isChatArchived,
|
isChatArchived,
|
||||||
@ -184,14 +184,14 @@ const MiddleHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
}, [openChat, chatId]);
|
}, [openChat, chatId]);
|
||||||
|
|
||||||
const handleBackClick = useCallback(() => {
|
const handleBackClick = useCallback(() => {
|
||||||
if (IS_MOBILE_SCREEN) {
|
if (IS_SINGLE_COLUMN_LAYOUT) {
|
||||||
const messageInput = document.getElementById(EDITABLE_INPUT_ID);
|
const messageInput = document.getElementById(EDITABLE_INPUT_ID);
|
||||||
if (messageInput) {
|
if (messageInput) {
|
||||||
messageInput.blur();
|
messageInput.blur();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (threadId === MAIN_THREAD_ID && messageListType === 'thread') {
|
if (threadId === MAIN_THREAD_ID && messageListType === 'thread') {
|
||||||
if (IS_MOBILE_SCREEN) {
|
if (IS_SINGLE_COLUMN_LAYOUT) {
|
||||||
openChat({ id: undefined });
|
openChat({ id: undefined });
|
||||||
} else {
|
} else {
|
||||||
toggleLeftColumn();
|
toggleLeftColumn();
|
||||||
|
|||||||
@ -19,7 +19,7 @@ import {
|
|||||||
import { LangCode } from '../../../types';
|
import { LangCode } from '../../../types';
|
||||||
|
|
||||||
import { EDITABLE_INPUT_ID, SCHEDULED_WHEN_ONLINE } from '../../../config';
|
import { EDITABLE_INPUT_ID, SCHEDULED_WHEN_ONLINE } from '../../../config';
|
||||||
import { IS_VOICE_RECORDING_SUPPORTED, IS_MOBILE_SCREEN, IS_EMOJI_SUPPORTED } from '../../../util/environment';
|
import { IS_VOICE_RECORDING_SUPPORTED, IS_SINGLE_COLUMN_LAYOUT, IS_EMOJI_SUPPORTED } from '../../../util/environment';
|
||||||
import {
|
import {
|
||||||
selectChat,
|
selectChat,
|
||||||
selectIsChatWithBot,
|
selectIsChatWithBot,
|
||||||
@ -337,7 +337,7 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
|
|
||||||
setHtml(`${htmlRef.current!}${newHtml}`);
|
setHtml(`${htmlRef.current!}${newHtml}`);
|
||||||
|
|
||||||
if (!IS_MOBILE_SCREEN) {
|
if (!IS_SINGLE_COLUMN_LAYOUT) {
|
||||||
// If selection is outside of input, set cursor at the end of input
|
// If selection is outside of input, set cursor at the end of input
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
focusEditableElement(messageInput);
|
focusEditableElement(messageInput);
|
||||||
@ -368,7 +368,7 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
closeMentionTooltip();
|
closeMentionTooltip();
|
||||||
closeEmojiTooltip();
|
closeEmojiTooltip();
|
||||||
|
|
||||||
if (IS_MOBILE_SCREEN) {
|
if (IS_SINGLE_COLUMN_LAYOUT) {
|
||||||
// @perf
|
// @perf
|
||||||
setTimeout(() => closeSymbolMenu(), SENDING_ANIMATION_DURATION);
|
setTimeout(() => closeSymbolMenu(), SENDING_ANIMATION_DURATION);
|
||||||
} else {
|
} else {
|
||||||
@ -582,7 +582,7 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
const handleSymbolMenuOpen = useCallback(() => {
|
const handleSymbolMenuOpen = useCallback(() => {
|
||||||
const messageInput = document.getElementById(EDITABLE_INPUT_ID)!;
|
const messageInput = document.getElementById(EDITABLE_INPUT_ID)!;
|
||||||
|
|
||||||
if (!IS_MOBILE_SCREEN || messageInput !== document.activeElement) {
|
if (!IS_SINGLE_COLUMN_LAYOUT || messageInput !== document.activeElement) {
|
||||||
openSymbolMenu();
|
openSymbolMenu();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -598,7 +598,7 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
}, [openChat, chatId, threadId]);
|
}, [openChat, chatId, threadId]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isRightColumnShown && IS_MOBILE_SCREEN) {
|
if (isRightColumnShown && IS_SINGLE_COLUMN_LAYOUT) {
|
||||||
closeSymbolMenu();
|
closeSymbolMenu();
|
||||||
}
|
}
|
||||||
}, [isRightColumnShown, closeSymbolMenu]);
|
}, [isRightColumnShown, closeSymbolMenu]);
|
||||||
@ -751,7 +751,7 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
disabled={!allowedAttachmentOptions.canAttachEmbedLinks}
|
disabled={!allowedAttachmentOptions.canAttachEmbedLinks}
|
||||||
/>
|
/>
|
||||||
<div className="message-input-wrapper">
|
<div className="message-input-wrapper">
|
||||||
{IS_MOBILE_SCREEN ? (
|
{IS_SINGLE_COLUMN_LAYOUT ? (
|
||||||
<Button
|
<Button
|
||||||
className={symbolMenuButtonClassName}
|
className={symbolMenuButtonClassName}
|
||||||
round
|
round
|
||||||
@ -782,7 +782,7 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
activeVoiceRecording && window.innerWidth <= SCREEN_WIDTH_TO_HIDE_PLACEHOLDER ? '' : lang('Message')
|
activeVoiceRecording && window.innerWidth <= SCREEN_WIDTH_TO_HIDE_PLACEHOLDER ? '' : lang('Message')
|
||||||
}
|
}
|
||||||
shouldSetFocus={isSymbolMenuOpen}
|
shouldSetFocus={isSymbolMenuOpen}
|
||||||
shouldSupressFocus={IS_MOBILE_SCREEN && isSymbolMenuOpen}
|
shouldSupressFocus={IS_SINGLE_COLUMN_LAYOUT && isSymbolMenuOpen}
|
||||||
shouldSupressTextFormatter={isEmojiTooltipOpen || isMentionTooltipOpen}
|
shouldSupressTextFormatter={isEmojiTooltipOpen || isMentionTooltipOpen}
|
||||||
onUpdate={setHtml}
|
onUpdate={setHtml}
|
||||||
onSend={onSend}
|
onSend={onSend}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import React, { FC, memo, useRef } from '../../../lib/teact/teact';
|
import React, { FC, memo, useRef } from '../../../lib/teact/teact';
|
||||||
|
|
||||||
import { IS_MOBILE_SCREEN } from '../../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import windowSize from '../../../util/windowSize';
|
import windowSize from '../../../util/windowSize';
|
||||||
import { ObserveFn, useOnIntersect } from '../../../hooks/useIntersectionObserver';
|
import { ObserveFn, useOnIntersect } from '../../../hooks/useIntersectionObserver';
|
||||||
@ -35,7 +35,7 @@ const EmojiCategory: FC<OwnProps> = ({
|
|||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
const emojisPerRow = IS_MOBILE_SCREEN
|
const emojisPerRow = IS_SINGLE_COLUMN_LAYOUT
|
||||||
? Math.floor((windowSize.get().width - MOBILE_CONTAINER_PADDING) / (EMOJI_SIZE + EMOJI_MARGIN))
|
? Math.floor((windowSize.get().width - MOBILE_CONTAINER_PADDING) / (EMOJI_SIZE + EMOJI_MARGIN))
|
||||||
: EMOJIS_PER_ROW_ON_DESKTOP;
|
: EMOJIS_PER_ROW_ON_DESKTOP;
|
||||||
const height = Math.ceil(category.emojis.length / emojisPerRow) * (EMOJI_SIZE + EMOJI_MARGIN);
|
const height = Math.ceil(category.emojis.length / emojisPerRow) * (EMOJI_SIZE + EMOJI_MARGIN);
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import { GlobalState } from '../../../global/types';
|
|||||||
|
|
||||||
import { MENU_TRANSITION_DURATION } from '../../../config';
|
import { MENU_TRANSITION_DURATION } from '../../../config';
|
||||||
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
|
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
|
||||||
import { IS_MOBILE_SCREEN } from '../../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
|
||||||
import {
|
import {
|
||||||
EmojiModule,
|
EmojiModule,
|
||||||
EmojiRawData,
|
EmojiRawData,
|
||||||
@ -99,7 +99,7 @@ const EmojiPicker: FC<OwnProps & StateProps> = ({
|
|||||||
setActiveCategoryIndex(intersectingWithIndexes[Math.floor(intersectingWithIndexes.length / 2)].index);
|
setActiveCategoryIndex(intersectingWithIndexes[Math.floor(intersectingWithIndexes.length / 2)].index);
|
||||||
});
|
});
|
||||||
|
|
||||||
useHorizontalScroll(headerRef.current, !IS_MOBILE_SCREEN);
|
useHorizontalScroll(headerRef.current, !IS_SINGLE_COLUMN_LAYOUT);
|
||||||
|
|
||||||
// Scroll header when active set updates
|
// Scroll header when active set updates
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import focusEditableElement from '../../../util/focusEditableElement';
|
|||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import { pick } from '../../../util/iteratees';
|
import { pick } from '../../../util/iteratees';
|
||||||
import {
|
import {
|
||||||
IS_ANDROID, IS_IOS, IS_MOBILE_SCREEN, IS_TOUCH_ENV,
|
IS_ANDROID, IS_IOS, IS_SINGLE_COLUMN_LAYOUT, IS_TOUCH_ENV,
|
||||||
} from '../../../util/environment';
|
} from '../../../util/environment';
|
||||||
import captureKeyboardListeners from '../../../util/captureKeyboardListeners';
|
import captureKeyboardListeners from '../../../util/captureKeyboardListeners';
|
||||||
import useLayoutEffectWithPrevDeps from '../../../hooks/useLayoutEffectWithPrevDeps';
|
import useLayoutEffectWithPrevDeps from '../../../hooks/useLayoutEffectWithPrevDeps';
|
||||||
@ -52,7 +52,7 @@ type StateProps = {
|
|||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'editLastMessage' | 'replyToNextMessage'>;
|
type DispatchProps = Pick<GlobalActions, 'editLastMessage' | 'replyToNextMessage'>;
|
||||||
|
|
||||||
const MAX_INPUT_HEIGHT = IS_MOBILE_SCREEN ? 256 : 416;
|
const MAX_INPUT_HEIGHT = IS_SINGLE_COLUMN_LAYOUT ? 256 : 416;
|
||||||
const TAB_INDEX_PRIORITY_TIMEOUT = 2000;
|
const TAB_INDEX_PRIORITY_TIMEOUT = 2000;
|
||||||
const TEXT_FORMATTER_SAFE_AREA_PX = 90;
|
const TEXT_FORMATTER_SAFE_AREA_PX = 90;
|
||||||
// For some reason Safari inserts `<br>` after user removes text from input
|
// For some reason Safari inserts `<br>` after user removes text from input
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { StickerSetOrRecent } from '../../../types';
|
|||||||
import { ObserveFn, useOnIntersect } from '../../../hooks/useIntersectionObserver';
|
import { ObserveFn, useOnIntersect } from '../../../hooks/useIntersectionObserver';
|
||||||
|
|
||||||
import { STICKER_SIZE_PICKER } from '../../../config';
|
import { STICKER_SIZE_PICKER } from '../../../config';
|
||||||
import { IS_MOBILE_SCREEN } from '../../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
|
||||||
import windowSize from '../../../util/windowSize';
|
import windowSize from '../../../util/windowSize';
|
||||||
import StickerButton from '../../common/StickerButton';
|
import StickerButton from '../../common/StickerButton';
|
||||||
import useShowTransition from '../../../hooks/useShowTransition';
|
import useShowTransition from '../../../hooks/useShowTransition';
|
||||||
@ -22,7 +22,7 @@ type OwnProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const STICKERS_PER_ROW_ON_DESKTOP = 5;
|
const STICKERS_PER_ROW_ON_DESKTOP = 5;
|
||||||
const STICKER_MARGIN = IS_MOBILE_SCREEN ? 8 : 16;
|
const STICKER_MARGIN = IS_SINGLE_COLUMN_LAYOUT ? 8 : 16;
|
||||||
const MOBILE_CONTAINER_PADDING = 8;
|
const MOBILE_CONTAINER_PADDING = 8;
|
||||||
|
|
||||||
const StickerSet: FC<OwnProps> = ({
|
const StickerSet: FC<OwnProps> = ({
|
||||||
@ -41,7 +41,7 @@ const StickerSet: FC<OwnProps> = ({
|
|||||||
|
|
||||||
const { transitionClassNames } = useShowTransition(shouldRender, undefined, undefined, 'slow');
|
const { transitionClassNames } = useShowTransition(shouldRender, undefined, undefined, 'slow');
|
||||||
|
|
||||||
const stickersPerRow = IS_MOBILE_SCREEN
|
const stickersPerRow = IS_SINGLE_COLUMN_LAYOUT
|
||||||
? Math.floor((windowSize.get().width - MOBILE_CONTAINER_PADDING) / (STICKER_SIZE_PICKER + STICKER_MARGIN))
|
? Math.floor((windowSize.get().width - MOBILE_CONTAINER_PADDING) / (STICKER_SIZE_PICKER + STICKER_MARGIN))
|
||||||
: STICKERS_PER_ROW_ON_DESKTOP;
|
: STICKERS_PER_ROW_ON_DESKTOP;
|
||||||
const height = Math.ceil(stickerSet.count / stickersPerRow) * (STICKER_SIZE_PICKER + STICKER_MARGIN);
|
const height = Math.ceil(stickerSet.count / stickersPerRow) * (STICKER_SIZE_PICKER + STICKER_MARGIN);
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import React, {
|
|||||||
import { ApiSticker, ApiVideo } from '../../../api/types';
|
import { ApiSticker, ApiVideo } from '../../../api/types';
|
||||||
|
|
||||||
import { IAllowedAttachmentOptions } from '../../../modules/helpers';
|
import { IAllowedAttachmentOptions } from '../../../modules/helpers';
|
||||||
import { IS_MOBILE_SCREEN, IS_TOUCH_ENV } from '../../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT, IS_TOUCH_ENV } from '../../../util/environment';
|
||||||
import { fastRaf } from '../../../util/schedulers';
|
import { fastRaf } from '../../../util/schedulers';
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import useShowTransition from '../../../hooks/useShowTransition';
|
import useShowTransition from '../../../hooks/useShowTransition';
|
||||||
@ -49,7 +49,7 @@ const SymbolMenu: FC<OwnProps> = ({
|
|||||||
const [activeTab, setActiveTab] = useState<number>(0);
|
const [activeTab, setActiveTab] = useState<number>(0);
|
||||||
const [recentEmojis, setRecentEmojis] = useState<string[]>([]);
|
const [recentEmojis, setRecentEmojis] = useState<string[]>([]);
|
||||||
|
|
||||||
const [handleMouseEnter, handleMouseLeave] = useMouseInside(isOpen, onClose, undefined, IS_MOBILE_SCREEN);
|
const [handleMouseEnter, handleMouseLeave] = useMouseInside(isOpen, onClose, undefined, IS_SINGLE_COLUMN_LAYOUT);
|
||||||
const { shouldRender, transitionClassNames } = useShowTransition(isOpen, onClose, false, false);
|
const { shouldRender, transitionClassNames } = useShowTransition(isOpen, onClose, false, false);
|
||||||
|
|
||||||
if (!isActivated && isOpen) {
|
if (!isActivated && isOpen) {
|
||||||
@ -61,7 +61,7 @@ const SymbolMenu: FC<OwnProps> = ({
|
|||||||
}, [onLoad]);
|
}, [onLoad]);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
if (!IS_MOBILE_SCREEN) {
|
if (!IS_SINGLE_COLUMN_LAYOUT) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,7 +158,7 @@ const SymbolMenu: FC<OwnProps> = ({
|
|||||||
</Transition>
|
</Transition>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{IS_MOBILE_SCREEN && (
|
{IS_SINGLE_COLUMN_LAYOUT && (
|
||||||
<Button
|
<Button
|
||||||
round
|
round
|
||||||
faded
|
faded
|
||||||
@ -180,7 +180,7 @@ const SymbolMenu: FC<OwnProps> = ({
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
if (IS_MOBILE_SCREEN) {
|
if (IS_SINGLE_COLUMN_LAYOUT) {
|
||||||
if (!shouldRender) {
|
if (!shouldRender) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import {
|
|||||||
} from '../../../../lib/teact/teact';
|
} from '../../../../lib/teact/teact';
|
||||||
|
|
||||||
import { EDITABLE_INPUT_ID } from '../../../../config';
|
import { EDITABLE_INPUT_ID } from '../../../../config';
|
||||||
import { IS_MOBILE_SCREEN } from '../../../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../../util/environment';
|
||||||
import {
|
import {
|
||||||
EmojiData, EmojiModule, EmojiRawData, uncompressEmoji,
|
EmojiData, EmojiModule, EmojiRawData, uncompressEmoji,
|
||||||
} from '../../../../util/emoji';
|
} from '../../../../util/emoji';
|
||||||
@ -154,7 +154,7 @@ export default function useEmojiTooltip(
|
|||||||
if (atIndex !== -1) {
|
if (atIndex !== -1) {
|
||||||
onUpdateHtml(`${html.substr(0, atIndex)}${textEmoji}`);
|
onUpdateHtml(`${html.substr(0, atIndex)}${textEmoji}`);
|
||||||
const messageInput = document.getElementById(inputId)!;
|
const messageInput = document.getElementById(inputId)!;
|
||||||
if (!IS_MOBILE_SCREEN) {
|
if (!IS_SINGLE_COLUMN_LAYOUT) {
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
focusEditableElement(messageInput, true);
|
focusEditableElement(messageInput, true);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { ApiMessageEntityTypes, ApiChatMember, ApiUser } from '../../../../api/t
|
|||||||
import { EDITABLE_INPUT_ID } from '../../../../config';
|
import { EDITABLE_INPUT_ID } from '../../../../config';
|
||||||
import { getUserFirstOrLastName } from '../../../../modules/helpers';
|
import { getUserFirstOrLastName } from '../../../../modules/helpers';
|
||||||
import searchUserName from '../helpers/searchUserName';
|
import searchUserName from '../helpers/searchUserName';
|
||||||
import { IS_MOBILE_SCREEN } from '../../../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../../util/environment';
|
||||||
import focusEditableElement from '../../../../util/focusEditableElement';
|
import focusEditableElement from '../../../../util/focusEditableElement';
|
||||||
import useFlag from '../../../../hooks/useFlag';
|
import useFlag from '../../../../hooks/useFlag';
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ export default function useMentionTooltip(
|
|||||||
if (atIndex !== -1) {
|
if (atIndex !== -1) {
|
||||||
onUpdateHtml(`${html.substr(0, atIndex)}${insertedHtml} `);
|
onUpdateHtml(`${html.substr(0, atIndex)}${insertedHtml} `);
|
||||||
const messageInput = document.getElementById(inputId)!;
|
const messageInput = document.getElementById(inputId)!;
|
||||||
if (!IS_MOBILE_SCREEN) {
|
if (!IS_SINGLE_COLUMN_LAYOUT) {
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
focusEditableElement(messageInput, forceFocus);
|
focusEditableElement(messageInput, forceFocus);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { ApiMessage } from '../../../../api/types';
|
import { ApiMessage } from '../../../../api/types';
|
||||||
|
|
||||||
import { IS_CANVAS_FILTER_SUPPORTED, IS_MOBILE_SCREEN } from '../../../../util/environment';
|
import { IS_CANVAS_FILTER_SUPPORTED, IS_SINGLE_COLUMN_LAYOUT } from '../../../../util/environment';
|
||||||
import { getMessageMediaThumbDataUri } from '../../../../modules/helpers';
|
import { getMessageMediaThumbDataUri } from '../../../../modules/helpers';
|
||||||
import useCanvasBlur from '../../../../hooks/useCanvasBlur';
|
import useCanvasBlur from '../../../../hooks/useCanvasBlur';
|
||||||
|
|
||||||
@ -8,6 +8,6 @@ export default function useBlurredMediaThumbRef(message: ApiMessage, fullMediaDa
|
|||||||
return useCanvasBlur(
|
return useCanvasBlur(
|
||||||
getMessageMediaThumbDataUri(message),
|
getMessageMediaThumbDataUri(message),
|
||||||
Boolean(fullMediaData),
|
Boolean(fullMediaData),
|
||||||
IS_MOBILE_SCREEN && !IS_CANVAS_FILTER_SUPPORTED,
|
IS_SINGLE_COLUMN_LAYOUT && !IS_CANVAS_FILTER_SUPPORTED,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { withGlobal } from '../../lib/teact/teactn';
|
|||||||
import { GlobalActions } from '../../global/types';
|
import { GlobalActions } from '../../global/types';
|
||||||
import { ManagementScreens, ProfileState } from '../../types';
|
import { ManagementScreens, ProfileState } from '../../types';
|
||||||
|
|
||||||
import { IS_MOBILE_SCREEN } from '../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
||||||
import { debounce } from '../../util/schedulers';
|
import { debounce } from '../../util/schedulers';
|
||||||
import { pick } from '../../util/iteratees';
|
import { pick } from '../../util/iteratees';
|
||||||
import buildClassName from '../../util/buildClassName';
|
import buildClassName from '../../util/buildClassName';
|
||||||
@ -270,7 +270,7 @@ const RightHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const isBackButton = (
|
const isBackButton = (
|
||||||
IS_MOBILE_SCREEN
|
IS_SINGLE_COLUMN_LAYOUT
|
||||||
|| contentKey === HeaderContent.SharedMedia
|
|| contentKey === HeaderContent.SharedMedia
|
||||||
|| contentKey === HeaderContent.MemberList
|
|| contentKey === HeaderContent.MemberList
|
||||||
|| isManagement
|
|| isManagement
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import React, {
|
|||||||
import { withGlobal } from '../../lib/teact/teactn';
|
import { withGlobal } from '../../lib/teact/teactn';
|
||||||
|
|
||||||
import { ANIMATION_END_DELAY } from '../../config';
|
import { ANIMATION_END_DELAY } from '../../config';
|
||||||
import { IS_MOBILE_SCREEN } from '../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
||||||
import useForceUpdate from '../../hooks/useForceUpdate';
|
import useForceUpdate from '../../hooks/useForceUpdate';
|
||||||
import usePrevious from '../../hooks/usePrevious';
|
import usePrevious from '../../hooks/usePrevious';
|
||||||
import buildClassName from '../../util/buildClassName';
|
import buildClassName from '../../util/buildClassName';
|
||||||
@ -44,7 +44,7 @@ const ANIMATION_DURATION = {
|
|||||||
'zoom-fade': 150,
|
'zoom-fade': 150,
|
||||||
'scroll-slide': 500,
|
'scroll-slide': 500,
|
||||||
fade: 150,
|
fade: 150,
|
||||||
'slide-layers': IS_MOBILE_SCREEN ? 450 : 300,
|
'slide-layers': IS_SINGLE_COLUMN_LAYOUT ? 450 : 300,
|
||||||
'push-slide': 300,
|
'push-slide': 300,
|
||||||
reveal: 350,
|
reveal: 350,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import {
|
|||||||
LEGACY_SESSION_KEY,
|
LEGACY_SESSION_KEY,
|
||||||
MIN_SCREEN_WIDTH_FOR_STATIC_RIGHT_COLUMN, GLOBAL_STATE_CACHE_USER_LIST_LIMIT, SESSION_USER_KEY,
|
MIN_SCREEN_WIDTH_FOR_STATIC_RIGHT_COLUMN, GLOBAL_STATE_CACHE_USER_LIST_LIMIT, SESSION_USER_KEY,
|
||||||
} from '../config';
|
} from '../config';
|
||||||
import { IS_MOBILE_SCREEN } from '../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../util/environment';
|
||||||
import { pick } from '../util/iteratees';
|
import { pick } from '../util/iteratees';
|
||||||
import { INITIAL_STATE } from './initial';
|
import { INITIAL_STATE } from './initial';
|
||||||
import { selectCurrentMessageList } from '../modules/selectors';
|
import { selectCurrentMessageList } from '../modules/selectors';
|
||||||
@ -205,7 +205,7 @@ function reduceMessages(global: GlobalState): GlobalState['messages'] {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
byChatId,
|
byChatId,
|
||||||
messageLists: !currentMessageList || IS_MOBILE_SCREEN ? undefined : [{
|
messageLists: !currentMessageList || IS_SINGLE_COLUMN_LAYOUT ? undefined : [{
|
||||||
...currentMessageList,
|
...currentMessageList,
|
||||||
threadId: MAIN_THREAD_ID,
|
threadId: MAIN_THREAD_ID,
|
||||||
type: 'thread',
|
type: 'thread',
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { RefObject } from 'react';
|
|||||||
import { useState, useEffect, useCallback } from '../lib/teact/teact';
|
import { useState, useEffect, useCallback } from '../lib/teact/teact';
|
||||||
|
|
||||||
import { IAnchorPosition } from '../types';
|
import { IAnchorPosition } from '../types';
|
||||||
import { IS_TOUCH_ENV, IS_MOBILE_SCREEN } from '../util/environment';
|
import { IS_TOUCH_ENV, IS_SINGLE_COLUMN_LAYOUT } from '../util/environment';
|
||||||
|
|
||||||
const LONG_TAP_DURATION_MS = 250;
|
const LONG_TAP_DURATION_MS = 250;
|
||||||
const SELECTION_ANIMATION_DURATION_MS = 200;
|
const SELECTION_ANIMATION_DURATION_MS = 200;
|
||||||
@ -10,7 +10,7 @@ const SELECTION_ANIMATION_DURATION_MS = 200;
|
|||||||
let contextMenuCounter = 0;
|
let contextMenuCounter = 0;
|
||||||
|
|
||||||
function checkIsDisabledForMobile() {
|
function checkIsDisabledForMobile() {
|
||||||
return IS_MOBILE_SCREEN
|
return IS_SINGLE_COLUMN_LAYOUT
|
||||||
&& window.document.body.classList.contains('enable-symbol-menu-transforms');
|
&& window.document.body.classList.contains('enable-symbol-menu-transforms');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import Worker from 'worker-loader!./rlottie.worker';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
DPR,
|
DPR,
|
||||||
IS_MOBILE_SCREEN,
|
IS_SINGLE_COLUMN_LAYOUT,
|
||||||
IS_SAFARI,
|
IS_SAFARI,
|
||||||
} from '../../util/environment';
|
} from '../../util/environment';
|
||||||
import WorkerConnector from '../../util/WorkerConnector';
|
import WorkerConnector from '../../util/WorkerConnector';
|
||||||
@ -22,7 +22,7 @@ type Chunks = (Frames | undefined)[];
|
|||||||
// TODO Consider removing chunks
|
// TODO Consider removing chunks
|
||||||
const CHUNK_SIZE = 1;
|
const CHUNK_SIZE = 1;
|
||||||
const MAX_WORKERS = 4;
|
const MAX_WORKERS = 4;
|
||||||
const HIGH_PRIORITY_QUALITY = IS_MOBILE_SCREEN ? 0.75 : 1;
|
const HIGH_PRIORITY_QUALITY = IS_SINGLE_COLUMN_LAYOUT ? 0.75 : 1;
|
||||||
const LOW_PRIORITY_QUALITY = 0.75;
|
const LOW_PRIORITY_QUALITY = 0.75;
|
||||||
const HIGH_PRIORITY_MAX_FPS = 60;
|
const HIGH_PRIORITY_MAX_FPS = 60;
|
||||||
const LOW_PRIORITY_MAX_FPS = 30;
|
const LOW_PRIORITY_MAX_FPS = 30;
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { addReducer } from '../../../lib/teact/teactn';
|
|||||||
|
|
||||||
import { GlobalState } from '../../../global/types';
|
import { GlobalState } from '../../../global/types';
|
||||||
|
|
||||||
import { IS_MOBILE_SCREEN } from '../../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
|
||||||
import getReadableErrorText from '../../../util/getReadableErrorText';
|
import getReadableErrorText from '../../../util/getReadableErrorText';
|
||||||
import { selectCurrentMessageList } from '../../selectors';
|
import { selectCurrentMessageList } from '../../selectors';
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ addReducer('closeManagement', (global): GlobalState | undefined => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
addReducer('openChat', (global, actions, payload) => {
|
addReducer('openChat', (global, actions, payload) => {
|
||||||
if (!IS_MOBILE_SCREEN) {
|
if (!IS_SINGLE_COLUMN_LAYOUT) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { GlobalState } from '../../global/types';
|
import { GlobalState } from '../../global/types';
|
||||||
import { RightColumnContent } from '../../types';
|
import { RightColumnContent } from '../../types';
|
||||||
|
|
||||||
import { IS_MOBILE_SCREEN, SYSTEM_THEME } from '../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT, SYSTEM_THEME } from '../../util/environment';
|
||||||
import { selectCurrentMessageList, selectIsPollResultsOpen } from './messages';
|
import { selectCurrentMessageList, selectIsPollResultsOpen } from './messages';
|
||||||
import { selectCurrentTextSearch } from './localSearch';
|
import { selectCurrentTextSearch } from './localSearch';
|
||||||
import { selectCurrentStickerSearch, selectCurrentGifSearch } from './symbols';
|
import { selectCurrentStickerSearch, selectCurrentGifSearch } from './symbols';
|
||||||
@ -20,7 +20,7 @@ export function selectRightColumnContentKey(global: GlobalState) {
|
|||||||
} = global;
|
} = global;
|
||||||
|
|
||||||
const isPollResults = selectIsPollResultsOpen(global);
|
const isPollResults = selectIsPollResultsOpen(global);
|
||||||
const isSearch = Boolean(!IS_MOBILE_SCREEN && selectCurrentTextSearch(global));
|
const isSearch = Boolean(!IS_SINGLE_COLUMN_LAYOUT && selectCurrentTextSearch(global));
|
||||||
const isManagement = selectCurrentManagement(global);
|
const isManagement = selectCurrentManagement(global);
|
||||||
const stickerSearch = selectCurrentStickerSearch(global);
|
const stickerSearch = selectCurrentStickerSearch(global);
|
||||||
const isStickerSearch = stickerSearch.query !== undefined;
|
const isStickerSearch = stickerSearch.query !== undefined;
|
||||||
|
|||||||
@ -35,7 +35,7 @@ export const IS_SAFARI = /^((?!chrome|android).)*safari/i.test(navigator.userAge
|
|||||||
|
|
||||||
export const IS_TOUCH_ENV = window.matchMedia('(pointer: coarse)').matches;
|
export const IS_TOUCH_ENV = window.matchMedia('(pointer: coarse)').matches;
|
||||||
// Keep in mind the landscape orientation
|
// Keep in mind the landscape orientation
|
||||||
export const IS_MOBILE_SCREEN = window.innerWidth <= MOBILE_SCREEN_MAX_WIDTH || (
|
export const IS_SINGLE_COLUMN_LAYOUT = window.innerWidth <= MOBILE_SCREEN_MAX_WIDTH || (
|
||||||
window.innerWidth <= MOBILE_SCREEN_LANDSCAPE_MAX_WIDTH && window.innerHeight <= MOBILE_SCREEN_LANDSCAPE_MAX_HEIGHT
|
window.innerWidth <= MOBILE_SCREEN_LANDSCAPE_MAX_WIDTH && window.innerHeight <= MOBILE_SCREEN_LANDSCAPE_MAX_HEIGHT
|
||||||
);
|
);
|
||||||
export const IS_VOICE_RECORDING_SUPPORTED = (navigator.mediaDevices && 'getUserMedia' in navigator.mediaDevices && (
|
export const IS_VOICE_RECORDING_SUPPORTED = (navigator.mediaDevices && 'getUserMedia' in navigator.mediaDevices && (
|
||||||
|
|||||||
@ -4,21 +4,21 @@ import {
|
|||||||
MOBILE_SCREEN_LANDSCAPE_MAX_WIDTH,
|
MOBILE_SCREEN_LANDSCAPE_MAX_WIDTH,
|
||||||
MOBILE_SCREEN_MAX_WIDTH,
|
MOBILE_SCREEN_MAX_WIDTH,
|
||||||
} from '../config';
|
} from '../config';
|
||||||
import { IS_IOS, IS_MOBILE_SCREEN } from './environment';
|
import { IS_IOS, IS_SINGLE_COLUMN_LAYOUT } from './environment';
|
||||||
|
|
||||||
type IDimensions = {
|
type IDimensions = {
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
const IS_LANDSCAPE = IS_MOBILE_SCREEN && isLandscape();
|
const IS_LANDSCAPE = IS_SINGLE_COLUMN_LAYOUT && isLandscape();
|
||||||
|
|
||||||
let windowSize = updateSizes();
|
let windowSize = updateSizes();
|
||||||
|
|
||||||
const handleResize = throttle(() => {
|
const handleResize = throttle(() => {
|
||||||
windowSize = updateSizes();
|
windowSize = updateSizes();
|
||||||
|
|
||||||
if ((isMobileScreen() !== IS_MOBILE_SCREEN) || (IS_MOBILE_SCREEN && IS_LANDSCAPE !== isLandscape())) {
|
if ((isMobileScreen() !== IS_SINGLE_COLUMN_LAYOUT) || (IS_SINGLE_COLUMN_LAYOUT && IS_LANDSCAPE !== isLandscape())) {
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
}
|
}
|
||||||
}, 250, true);
|
}, 250, true);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user