mirror of
https://github.com/danog/telegram-tt.git
synced 2025-01-22 21:31:22 +01:00
Compare versions for "Update Telegram" button; Various UI fixes (#2022)
This commit is contained in:
parent
bf4812f6cf
commit
6d0c4e4b66
@ -4,14 +4,15 @@
|
|||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "cross-env APP_ENV=development webpack serve --mode development",
|
"dev": "cross-env APP_ENV=development APP_VERSION=$(npm run print_version --silent) webpack serve --mode development",
|
||||||
"dev:mocked": "cross-env APP_ENV=test APP_MOCKED_CLIENT=1 webpack serve --mode development --port 1235",
|
"dev:mocked": "cross-env APP_ENV=test APP_MOCKED_CLIENT=1 webpack serve --mode development --port 1235",
|
||||||
"build:mocked": "cross-env APP_ENV=test APP_MOCKED_CLIENT=1 webpack --mode development",
|
"build:mocked": "cross-env APP_ENV=test APP_MOCKED_CLIENT=1 webpack --mode development",
|
||||||
"build:staging": "APP_ENV=staging APP_VERSION=$(npm run print_version --silent) webpack --mode development && ./deploy/copy_to_dist.sh",
|
"build:staging": "APP_ENV=staging APP_VERSION=$(npm run print_version --silent) webpack --mode development && ./deploy/copy_to_dist.sh",
|
||||||
"build:production": "npm i && APP_VERSION=$(npm run inc_version --silent) webpack && ./deploy/copy_to_dist.sh",
|
"build:production": "npm i && APP_VERSION=$(npm run inc_version --silent) webpack && ./deploy/copy_to_dist.sh",
|
||||||
"deploy:production": "npm run build:production && git add -A && git commit -a -m '[Build]' --no-verify && git push",
|
"deploy:production": "npm run build:production && git add -A && git commit -a -m '[Build]' --no-verify && git push",
|
||||||
"print_version": "node -p -e \"require('./package.json').version\"",
|
"update_version": "npm run print_version --silent > ./public/version.txt",
|
||||||
"inc_version": "echo $((`cat .patch-version` + 1)) > .patch-version && echo \"$(node -p -e \"require('./package.json').version.match(/^\\d+\\.\\d+/)[0]\").$(cat .patch-version)\"",
|
"print_version": "echo \"$(node -p -e \"require('./package.json').version.match(/^\\d+\\.\\d+/)[0]\").$(cat .patch-version)\"",
|
||||||
|
"inc_version": "echo $((`cat .patch-version` + 1)) > .patch-version && npm run update_version --silent && npm run print_version",
|
||||||
"telegraph:update_changelog": "node ./dev/telegraphChangelog.js",
|
"telegraph:update_changelog": "node ./dev/telegraphChangelog.js",
|
||||||
"check": "tsc && stylelint \"**/*.{css,scss}\" && eslint . --ext .ts,.tsx,.js --ignore-pattern src/lib/gramjs",
|
"check": "tsc && stylelint \"**/*.{css,scss}\" && eslint . --ext .ts,.tsx,.js --ignore-pattern src/lib/gramjs",
|
||||||
"check:fix": "npm run check -- --fix",
|
"check:fix": "npm run check -- --fix",
|
||||||
|
1
public/version.txt
Normal file
1
public/version.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
1.51.1
|
@ -32,6 +32,7 @@ type StateProps = {
|
|||||||
hasPasscode?: boolean;
|
hasPasscode?: boolean;
|
||||||
nextSettingsScreen?: SettingsScreens;
|
nextSettingsScreen?: SettingsScreens;
|
||||||
isChatOpen: boolean;
|
isChatOpen: boolean;
|
||||||
|
isUpdateAvailable?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ContentType {
|
enum ContentType {
|
||||||
@ -58,6 +59,7 @@ const LeftColumn: FC<StateProps> = ({
|
|||||||
hasPasscode,
|
hasPasscode,
|
||||||
nextSettingsScreen,
|
nextSettingsScreen,
|
||||||
isChatOpen,
|
isChatOpen,
|
||||||
|
isUpdateAvailable,
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
setGlobalSearchQuery,
|
setGlobalSearchQuery,
|
||||||
@ -440,6 +442,7 @@ const LeftColumn: FC<StateProps> = ({
|
|||||||
onScreenSelect={handleSettingsScreenSelect}
|
onScreenSelect={handleSettingsScreenSelect}
|
||||||
onReset={handleReset}
|
onReset={handleReset}
|
||||||
shouldSkipTransition={shouldSkipHistoryAnimations}
|
shouldSkipTransition={shouldSkipHistoryAnimations}
|
||||||
|
isUpdateAvailable={isUpdateAvailable}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -474,6 +477,7 @@ export default memo(withGlobal(
|
|||||||
settings: {
|
settings: {
|
||||||
nextScreen: nextSettingsScreen,
|
nextScreen: nextSettingsScreen,
|
||||||
},
|
},
|
||||||
|
isUpdateAvailable,
|
||||||
} = global;
|
} = global;
|
||||||
|
|
||||||
const isChatOpen = Boolean(selectCurrentChat(global)?.id);
|
const isChatOpen = Boolean(selectCurrentChat(global)?.id);
|
||||||
@ -488,6 +492,7 @@ export default memo(withGlobal(
|
|||||||
hasPasscode,
|
hasPasscode,
|
||||||
nextSettingsScreen,
|
nextSettingsScreen,
|
||||||
isChatOpen,
|
isChatOpen,
|
||||||
|
isUpdateAvailable,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
)(LeftColumn));
|
)(LeftColumn));
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
> span {
|
> span {
|
||||||
padding-left: 0.5rem;
|
padding-left: 0.5rem;
|
||||||
padding-right: 0.5rem;
|
padding-right: 0.5rem;
|
||||||
|
white-space: pre;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ import type { FolderEditDispatch } from '../../../hooks/reducers/useFoldersReduc
|
|||||||
|
|
||||||
import { IS_TOUCH_ENV } from '../../../util/environment';
|
import { IS_TOUCH_ENV } from '../../../util/environment';
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import useFlag from '../../../hooks/useFlag';
|
|
||||||
import useShowTransition from '../../../hooks/useShowTransition';
|
import useShowTransition from '../../../hooks/useShowTransition';
|
||||||
import useLang from '../../../hooks/useLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
|
|
||||||
@ -30,6 +29,7 @@ type OwnProps = {
|
|||||||
contactsFilter: string;
|
contactsFilter: string;
|
||||||
shouldSkipTransition?: boolean;
|
shouldSkipTransition?: boolean;
|
||||||
foldersDispatch: FolderEditDispatch;
|
foldersDispatch: FolderEditDispatch;
|
||||||
|
isUpdateAvailable?: boolean;
|
||||||
onSearchQuery: (query: string) => void;
|
onSearchQuery: (query: string) => void;
|
||||||
onContentChange: (content: LeftColumnContent) => void;
|
onContentChange: (content: LeftColumnContent) => void;
|
||||||
onScreenSelect: (screen: SettingsScreens) => void;
|
onScreenSelect: (screen: SettingsScreens) => void;
|
||||||
@ -38,7 +38,6 @@ type OwnProps = {
|
|||||||
|
|
||||||
const TRANSITION_RENDER_COUNT = Object.keys(LeftColumnContent).length / 2;
|
const TRANSITION_RENDER_COUNT = Object.keys(LeftColumnContent).length / 2;
|
||||||
const BUTTON_CLOSE_DELAY_MS = 250;
|
const BUTTON_CLOSE_DELAY_MS = 250;
|
||||||
const APP_OUTDATED_TIMEOUT = 3 * 24 * 60 * 60 * 1000; // 3 days
|
|
||||||
|
|
||||||
let closeTimeout: number | undefined;
|
let closeTimeout: number | undefined;
|
||||||
|
|
||||||
@ -49,6 +48,7 @@ const LeftMain: FC<OwnProps> = ({
|
|||||||
contactsFilter,
|
contactsFilter,
|
||||||
shouldSkipTransition,
|
shouldSkipTransition,
|
||||||
foldersDispatch,
|
foldersDispatch,
|
||||||
|
isUpdateAvailable,
|
||||||
onSearchQuery,
|
onSearchQuery,
|
||||||
onContentChange,
|
onContentChange,
|
||||||
onScreenSelect,
|
onScreenSelect,
|
||||||
@ -56,28 +56,13 @@ const LeftMain: FC<OwnProps> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const [isNewChatButtonShown, setIsNewChatButtonShown] = useState(IS_TOUCH_ENV);
|
const [isNewChatButtonShown, setIsNewChatButtonShown] = useState(IS_TOUCH_ENV);
|
||||||
|
|
||||||
|
const {
|
||||||
|
shouldRender: shouldRenderUpdateButton,
|
||||||
|
transitionClassNames: updateButtonClassNames,
|
||||||
|
} = useShowTransition(isUpdateAvailable);
|
||||||
|
|
||||||
const isMouseInside = useRef(false);
|
const isMouseInside = useRef(false);
|
||||||
|
|
||||||
const handleSelectSettings = useCallback(() => {
|
|
||||||
onContentChange(LeftColumnContent.Settings);
|
|
||||||
}, [onContentChange]);
|
|
||||||
|
|
||||||
const handleSelectContacts = useCallback(() => {
|
|
||||||
onContentChange(LeftColumnContent.Contacts);
|
|
||||||
}, [onContentChange]);
|
|
||||||
|
|
||||||
const handleSelectNewChannel = useCallback(() => {
|
|
||||||
onContentChange(LeftColumnContent.NewChannelStep1);
|
|
||||||
}, [onContentChange]);
|
|
||||||
|
|
||||||
const handleSelectNewGroup = useCallback(() => {
|
|
||||||
onContentChange(LeftColumnContent.NewGroupStep1);
|
|
||||||
}, [onContentChange]);
|
|
||||||
|
|
||||||
const handleSelectArchived = useCallback(() => {
|
|
||||||
onContentChange(LeftColumnContent.Archived);
|
|
||||||
}, [onContentChange]);
|
|
||||||
|
|
||||||
const handleMouseEnter = useCallback(() => {
|
const handleMouseEnter = useCallback(() => {
|
||||||
if (content !== LeftColumnContent.ChatList) {
|
if (content !== LeftColumnContent.ChatList) {
|
||||||
return;
|
return;
|
||||||
@ -101,6 +86,30 @@ const LeftMain: FC<OwnProps> = ({
|
|||||||
}, BUTTON_CLOSE_DELAY_MS);
|
}, BUTTON_CLOSE_DELAY_MS);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const handleSelectSettings = useCallback(() => {
|
||||||
|
onContentChange(LeftColumnContent.Settings);
|
||||||
|
}, [onContentChange]);
|
||||||
|
|
||||||
|
const handleSelectContacts = useCallback(() => {
|
||||||
|
onContentChange(LeftColumnContent.Contacts);
|
||||||
|
}, [onContentChange]);
|
||||||
|
|
||||||
|
const handleSelectArchived = useCallback(() => {
|
||||||
|
onContentChange(LeftColumnContent.Archived);
|
||||||
|
}, [onContentChange]);
|
||||||
|
|
||||||
|
const handleUpdateClick = useCallback(() => {
|
||||||
|
window.location.reload();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleSelectNewChannel = useCallback(() => {
|
||||||
|
onContentChange(LeftColumnContent.NewChannelStep1);
|
||||||
|
}, [onContentChange]);
|
||||||
|
|
||||||
|
const handleSelectNewGroup = useCallback(() => {
|
||||||
|
onContentChange(LeftColumnContent.NewGroupStep1);
|
||||||
|
}, [onContentChange]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let autoCloseTimeout: number | undefined;
|
let autoCloseTimeout: number | undefined;
|
||||||
if (content !== LeftColumnContent.ChatList) {
|
if (content !== LeftColumnContent.ChatList) {
|
||||||
@ -119,8 +128,6 @@ const LeftMain: FC<OwnProps> = ({
|
|||||||
};
|
};
|
||||||
}, [content]);
|
}, [content]);
|
||||||
|
|
||||||
const [shouldRenderUpdateButton, updateButtonClassNames, handleUpdateClick] = useAppOutdatedCheck();
|
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -186,24 +193,4 @@ const LeftMain: FC<OwnProps> = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
function useAppOutdatedCheck() {
|
|
||||||
const [isAppOutdated, markIsAppOutdated] = useFlag(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const timeout = window.setTimeout(markIsAppOutdated, APP_OUTDATED_TIMEOUT);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
clearTimeout(timeout);
|
|
||||||
};
|
|
||||||
}, [markIsAppOutdated]);
|
|
||||||
|
|
||||||
const { shouldRender, transitionClassNames } = useShowTransition(isAppOutdated);
|
|
||||||
|
|
||||||
const handleUpdateClick = () => {
|
|
||||||
window.location.reload();
|
|
||||||
};
|
|
||||||
|
|
||||||
return [shouldRender, transitionClassNames, handleUpdateClick] as const;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default memo(LeftMain);
|
export default memo(LeftMain);
|
||||||
|
@ -230,7 +230,7 @@ const ChatResults: FC<OwnProps & StateProps> = ({
|
|||||||
<div className="search-section">
|
<div className="search-section">
|
||||||
<h3 className="section-heading" dir={lang.isRtl ? 'auto' : undefined}>
|
<h3 className="section-heading" dir={lang.isRtl ? 'auto' : undefined}>
|
||||||
{localResults.length > LESS_LIST_ITEMS_AMOUNT && (
|
{localResults.length > LESS_LIST_ITEMS_AMOUNT && (
|
||||||
<Link onClick={handleClickShowMoreLocal}>
|
<Link className="Link" onClick={handleClickShowMoreLocal}>
|
||||||
{lang(shouldShowMoreLocal ? 'ChatList.Search.ShowLess' : 'ChatList.Search.ShowMore')}
|
{lang(shouldShowMoreLocal ? 'ChatList.Search.ShowLess' : 'ChatList.Search.ShowMore')}
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
@ -254,7 +254,7 @@ const ChatResults: FC<OwnProps & StateProps> = ({
|
|||||||
<div className="search-section">
|
<div className="search-section">
|
||||||
<h3 className="section-heading" dir={lang.isRtl ? 'auto' : undefined}>
|
<h3 className="section-heading" dir={lang.isRtl ? 'auto' : undefined}>
|
||||||
{globalResults.length > LESS_LIST_ITEMS_AMOUNT && (
|
{globalResults.length > LESS_LIST_ITEMS_AMOUNT && (
|
||||||
<Link onClick={handleClickShowMoreGlobal}>
|
<Link className="Link" onClick={handleClickShowMoreGlobal}>
|
||||||
{lang(shouldShowMoreGlobal ? 'ChatList.Search.ShowLess' : 'ChatList.Search.ShowMore')}
|
{lang(shouldShowMoreGlobal ? 'ChatList.Search.ShowLess' : 'ChatList.Search.ShowMore')}
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
|
@ -16,6 +16,7 @@ import useHistoryBack from '../../../../hooks/useHistoryBack';
|
|||||||
import { useFolderManagerForChatsCount } from '../../../../hooks/useFolderManager';
|
import { useFolderManagerForChatsCount } from '../../../../hooks/useFolderManager';
|
||||||
import { selectCurrentLimit } from '../../../../global/selectors/limits';
|
import { selectCurrentLimit } from '../../../../global/selectors/limits';
|
||||||
import { selectIsCurrentUserPremium } from '../../../../global/selectors';
|
import { selectIsCurrentUserPremium } from '../../../../global/selectors';
|
||||||
|
import renderText from '../../../common/helpers/renderText';
|
||||||
|
|
||||||
import ListItem from '../../../ui/ListItem';
|
import ListItem from '../../../ui/ListItem';
|
||||||
import Button from '../../../ui/Button';
|
import Button from '../../../ui/Button';
|
||||||
@ -277,7 +278,7 @@ const SettingsFoldersMain: FC<OwnProps & StateProps> = ({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span className="title">
|
<span className="title">
|
||||||
{folder.title}
|
{renderText(folder.title, ['emoji'])}
|
||||||
{isBlocked && <i className="icon-lock-badge settings-folders-blocked-icon" />}
|
{isBlocked && <i className="icon-lock-badge settings-folders-blocked-icon" />}
|
||||||
</span>
|
</span>
|
||||||
<span className="subtitle">{folder.subtitle}</span>
|
<span className="subtitle">{folder.subtitle}</span>
|
||||||
@ -307,7 +308,7 @@ const SettingsFoldersMain: FC<OwnProps & StateProps> = ({
|
|||||||
>
|
>
|
||||||
<div className="settings-folders-recommended-item">
|
<div className="settings-folders-recommended-item">
|
||||||
<div className="multiline-item">
|
<div className="multiline-item">
|
||||||
<span className="title">{folder.title}</span>
|
<span className="title">{renderText(folder.title, ['emoji'])}</span>
|
||||||
<span className="subtitle">{folder.description}</span>
|
<span className="subtitle">{folder.description}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ import useForceUpdate from '../../hooks/useForceUpdate';
|
|||||||
import { LOCATION_HASH } from '../../hooks/useHistoryBack';
|
import { LOCATION_HASH } from '../../hooks/useHistoryBack';
|
||||||
import useShowTransition from '../../hooks/useShowTransition';
|
import useShowTransition from '../../hooks/useShowTransition';
|
||||||
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
|
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
|
||||||
|
import useInterval from '../../hooks/useInterval';
|
||||||
|
|
||||||
import StickerSetModal from '../common/StickerSetModal.async';
|
import StickerSetModal from '../common/StickerSetModal.async';
|
||||||
import UnreadCount from '../common/UnreadCounter';
|
import UnreadCount from '../common/UnreadCounter';
|
||||||
@ -118,6 +119,7 @@ type StateProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const NOTIFICATION_INTERVAL = 1000;
|
const NOTIFICATION_INTERVAL = 1000;
|
||||||
|
const APP_OUTDATED_TIMEOUT_MS = 5 * 60 * 1000; // 5 min
|
||||||
|
|
||||||
let notificationInterval: number | undefined;
|
let notificationInterval: number | undefined;
|
||||||
|
|
||||||
@ -189,6 +191,7 @@ const Main: FC<StateProps> = ({
|
|||||||
loadCustomEmojis,
|
loadCustomEmojis,
|
||||||
closePaymentModal,
|
closePaymentModal,
|
||||||
clearReceipt,
|
clearReceipt,
|
||||||
|
checkAppVersion,
|
||||||
} = getActions();
|
} = getActions();
|
||||||
|
|
||||||
if (DEBUG && !DEBUG_isLogged) {
|
if (DEBUG && !DEBUG_isLogged) {
|
||||||
@ -203,6 +206,8 @@ const Main: FC<StateProps> = ({
|
|||||||
}
|
}
|
||||||
}, [connectionState, authState, sync]);
|
}, [connectionState, authState, sync]);
|
||||||
|
|
||||||
|
useInterval(checkAppVersion, APP_OUTDATED_TIMEOUT_MS, true);
|
||||||
|
|
||||||
// Initial API calls
|
// Initial API calls
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (lastSyncTime) {
|
if (lastSyncTime) {
|
||||||
@ -217,11 +222,12 @@ const Main: FC<StateProps> = ({
|
|||||||
loadAttachMenuBots();
|
loadAttachMenuBots();
|
||||||
loadContactList();
|
loadContactList();
|
||||||
loadPremiumGifts();
|
loadPremiumGifts();
|
||||||
|
checkAppVersion();
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
lastSyncTime, loadAnimatedEmojis, loadEmojiKeywords, loadNotificationExceptions, loadNotificationSettings,
|
lastSyncTime, loadAnimatedEmojis, loadEmojiKeywords, loadNotificationExceptions, loadNotificationSettings,
|
||||||
loadTopInlineBots, updateIsOnline, loadAvailableReactions, loadAppConfig, loadAttachMenuBots, loadContactList,
|
loadTopInlineBots, updateIsOnline, loadAvailableReactions, loadAppConfig, loadAttachMenuBots, loadContactList,
|
||||||
loadPremiumGifts,
|
loadPremiumGifts, checkAppVersion,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Language-based API calls
|
// Language-based API calls
|
||||||
|
@ -14,6 +14,7 @@ export const IS_PERF = process.env.APP_ENV === 'perf';
|
|||||||
export const IS_BETA = process.env.APP_ENV === 'staging';
|
export const IS_BETA = process.env.APP_ENV === 'staging';
|
||||||
|
|
||||||
export const BETA_CHANGELOG_URL = 'https://telegra.ph/WebZ-Beta-04-01';
|
export const BETA_CHANGELOG_URL = 'https://telegra.ph/WebZ-Beta-04-01';
|
||||||
|
export const APP_VERSION_URL_PATH = '/version.txt';
|
||||||
|
|
||||||
export const DEBUG_ALERT_MSG = 'Shoot!\nSomething went wrong, please see the error details in Dev Tools Console.';
|
export const DEBUG_ALERT_MSG = 'Shoot!\nSomething went wrong, please see the error details in Dev Tools Console.';
|
||||||
export const DEBUG_GRAMJS = false;
|
export const DEBUG_GRAMJS = false;
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
import { addActionHandler, setGlobal } from '../../index';
|
import { addActionHandler, getGlobal, setGlobal } from '../../index';
|
||||||
|
|
||||||
import type { ApiError } from '../../../api/types';
|
import type { ApiError } from '../../../api/types';
|
||||||
|
|
||||||
import { GLOBAL_STATE_CACHE_CUSTOM_EMOJI_LIMIT } from '../../../config';
|
import { APP_VERSION, APP_VERSION_URL_PATH, GLOBAL_STATE_CACHE_CUSTOM_EMOJI_LIMIT } from '../../../config';
|
||||||
import { IS_SINGLE_COLUMN_LAYOUT, IS_TABLET_COLUMN_LAYOUT } from '../../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT, IS_TABLET_COLUMN_LAYOUT } from '../../../util/environment';
|
||||||
import getReadableErrorText from '../../../util/getReadableErrorText';
|
import getReadableErrorText from '../../../util/getReadableErrorText';
|
||||||
import {
|
import { selectChatMessage, selectCurrentMessageList, selectIsTrustedBot } from '../../selectors';
|
||||||
selectChatMessage, selectCurrentMessageList, selectIsTrustedBot,
|
|
||||||
} from '../../selectors';
|
|
||||||
import generateIdFor from '../../../util/generateIdFor';
|
import generateIdFor from '../../../util/generateIdFor';
|
||||||
import { unique } from '../../../util/iteratees';
|
import { unique } from '../../../util/iteratees';
|
||||||
|
|
||||||
@ -405,3 +403,21 @@ addActionHandler('updateLastRenderedCustomEmojis', (global, actions, payload) =>
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addActionHandler('checkAppVersion', () => {
|
||||||
|
const APP_VERSION_REGEX = /^\d+\.\d+(\.\d+)?$/;
|
||||||
|
|
||||||
|
fetch(APP_VERSION_URL_PATH)
|
||||||
|
.then((response) => {
|
||||||
|
return response.text();
|
||||||
|
}).then((version) => {
|
||||||
|
version = version.trim();
|
||||||
|
|
||||||
|
if (APP_VERSION_REGEX.test(version) && version !== APP_VERSION) {
|
||||||
|
setGlobal({
|
||||||
|
...getGlobal(),
|
||||||
|
isUpdateAvailable: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -15,6 +15,7 @@ export const INITIAL_STATE: GlobalState = {
|
|||||||
newChatMembersProgress: NewChatMembersProgress.Closed,
|
newChatMembersProgress: NewChatMembersProgress.Closed,
|
||||||
uiReadyState: 0,
|
uiReadyState: 0,
|
||||||
serverTimeOffset: 0,
|
serverTimeOffset: 0,
|
||||||
|
isUpdateAvailable: false,
|
||||||
|
|
||||||
authRememberMe: true,
|
authRememberMe: true,
|
||||||
countryList: {
|
countryList: {
|
||||||
|
@ -147,6 +147,7 @@ export type GlobalState = {
|
|||||||
connectionState?: ApiUpdateConnectionStateType;
|
connectionState?: ApiUpdateConnectionStateType;
|
||||||
currentUserId?: string;
|
currentUserId?: string;
|
||||||
isSyncing?: boolean;
|
isSyncing?: boolean;
|
||||||
|
isUpdateAvailable?: boolean;
|
||||||
lastSyncTime?: number;
|
lastSyncTime?: number;
|
||||||
serverTimeOffset: number;
|
serverTimeOffset: number;
|
||||||
leftColumnWidth?: number;
|
leftColumnWidth?: number;
|
||||||
@ -690,6 +691,7 @@ export interface ActionPayloads {
|
|||||||
setInstallPrompt: { canInstall: boolean };
|
setInstallPrompt: { canInstall: boolean };
|
||||||
openLimitReachedModal: { limit: ApiLimitTypeWithModal };
|
openLimitReachedModal: { limit: ApiLimitTypeWithModal };
|
||||||
closeLimitReachedModal: never;
|
closeLimitReachedModal: never;
|
||||||
|
checkAppVersion: never;
|
||||||
|
|
||||||
// Accounts
|
// Accounts
|
||||||
reportPeer: {
|
reportPeer: {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user