Compare versions for "Update Telegram" button; Various UI fixes (#2022)

This commit is contained in:
Alexander Zinchuk 2022-09-12 11:05:53 +02:00
parent bf4812f6cf
commit 6d0c4e4b66
12 changed files with 79 additions and 57 deletions

View File

@ -4,14 +4,15 @@
"description": "",
"main": "index.js",
"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",
"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: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",
"print_version": "node -p -e \"require('./package.json').version\"",
"inc_version": "echo $((`cat .patch-version` + 1)) > .patch-version && echo \"$(node -p -e \"require('./package.json').version.match(/^\\d+\\.\\d+/)[0]\").$(cat .patch-version)\"",
"update_version": "npm run print_version --silent > ./public/version.txt",
"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",
"check": "tsc && stylelint \"**/*.{css,scss}\" && eslint . --ext .ts,.tsx,.js --ignore-pattern src/lib/gramjs",
"check:fix": "npm run check -- --fix",

1
public/version.txt Normal file
View File

@ -0,0 +1 @@
1.51.1

View File

@ -32,6 +32,7 @@ type StateProps = {
hasPasscode?: boolean;
nextSettingsScreen?: SettingsScreens;
isChatOpen: boolean;
isUpdateAvailable?: boolean;
};
enum ContentType {
@ -58,6 +59,7 @@ const LeftColumn: FC<StateProps> = ({
hasPasscode,
nextSettingsScreen,
isChatOpen,
isUpdateAvailable,
}) => {
const {
setGlobalSearchQuery,
@ -440,6 +442,7 @@ const LeftColumn: FC<StateProps> = ({
onScreenSelect={handleSettingsScreenSelect}
onReset={handleReset}
shouldSkipTransition={shouldSkipHistoryAnimations}
isUpdateAvailable={isUpdateAvailable}
/>
);
}
@ -474,6 +477,7 @@ export default memo(withGlobal(
settings: {
nextScreen: nextSettingsScreen,
},
isUpdateAvailable,
} = global;
const isChatOpen = Boolean(selectCurrentChat(global)?.id);
@ -488,6 +492,7 @@ export default memo(withGlobal(
hasPasscode,
nextSettingsScreen,
isChatOpen,
isUpdateAvailable,
};
},
)(LeftColumn));

View File

@ -43,6 +43,7 @@
> span {
padding-left: 0.5rem;
padding-right: 0.5rem;
white-space: pre;
}
}

View File

@ -9,7 +9,6 @@ import type { FolderEditDispatch } from '../../../hooks/reducers/useFoldersReduc
import { IS_TOUCH_ENV } from '../../../util/environment';
import buildClassName from '../../../util/buildClassName';
import useFlag from '../../../hooks/useFlag';
import useShowTransition from '../../../hooks/useShowTransition';
import useLang from '../../../hooks/useLang';
@ -30,6 +29,7 @@ type OwnProps = {
contactsFilter: string;
shouldSkipTransition?: boolean;
foldersDispatch: FolderEditDispatch;
isUpdateAvailable?: boolean;
onSearchQuery: (query: string) => void;
onContentChange: (content: LeftColumnContent) => void;
onScreenSelect: (screen: SettingsScreens) => void;
@ -38,7 +38,6 @@ type OwnProps = {
const TRANSITION_RENDER_COUNT = Object.keys(LeftColumnContent).length / 2;
const BUTTON_CLOSE_DELAY_MS = 250;
const APP_OUTDATED_TIMEOUT = 3 * 24 * 60 * 60 * 1000; // 3 days
let closeTimeout: number | undefined;
@ -49,6 +48,7 @@ const LeftMain: FC<OwnProps> = ({
contactsFilter,
shouldSkipTransition,
foldersDispatch,
isUpdateAvailable,
onSearchQuery,
onContentChange,
onScreenSelect,
@ -56,28 +56,13 @@ const LeftMain: FC<OwnProps> = ({
}) => {
const [isNewChatButtonShown, setIsNewChatButtonShown] = useState(IS_TOUCH_ENV);
const {
shouldRender: shouldRenderUpdateButton,
transitionClassNames: updateButtonClassNames,
} = useShowTransition(isUpdateAvailable);
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(() => {
if (content !== LeftColumnContent.ChatList) {
return;
@ -101,6 +86,30 @@ const LeftMain: FC<OwnProps> = ({
}, 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(() => {
let autoCloseTimeout: number | undefined;
if (content !== LeftColumnContent.ChatList) {
@ -119,8 +128,6 @@ const LeftMain: FC<OwnProps> = ({
};
}, [content]);
const [shouldRenderUpdateButton, updateButtonClassNames, handleUpdateClick] = useAppOutdatedCheck();
const lang = useLang();
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);

View File

@ -230,7 +230,7 @@ const ChatResults: FC<OwnProps & StateProps> = ({
<div className="search-section">
<h3 className="section-heading" dir={lang.isRtl ? 'auto' : undefined}>
{localResults.length > LESS_LIST_ITEMS_AMOUNT && (
<Link onClick={handleClickShowMoreLocal}>
<Link className="Link" onClick={handleClickShowMoreLocal}>
{lang(shouldShowMoreLocal ? 'ChatList.Search.ShowLess' : 'ChatList.Search.ShowMore')}
</Link>
)}
@ -254,7 +254,7 @@ const ChatResults: FC<OwnProps & StateProps> = ({
<div className="search-section">
<h3 className="section-heading" dir={lang.isRtl ? 'auto' : undefined}>
{globalResults.length > LESS_LIST_ITEMS_AMOUNT && (
<Link onClick={handleClickShowMoreGlobal}>
<Link className="Link" onClick={handleClickShowMoreGlobal}>
{lang(shouldShowMoreGlobal ? 'ChatList.Search.ShowLess' : 'ChatList.Search.ShowMore')}
</Link>
)}

View File

@ -16,6 +16,7 @@ import useHistoryBack from '../../../../hooks/useHistoryBack';
import { useFolderManagerForChatsCount } from '../../../../hooks/useFolderManager';
import { selectCurrentLimit } from '../../../../global/selectors/limits';
import { selectIsCurrentUserPremium } from '../../../../global/selectors';
import renderText from '../../../common/helpers/renderText';
import ListItem from '../../../ui/ListItem';
import Button from '../../../ui/Button';
@ -277,7 +278,7 @@ const SettingsFoldersMain: FC<OwnProps & StateProps> = ({
}}
>
<span className="title">
{folder.title}
{renderText(folder.title, ['emoji'])}
{isBlocked && <i className="icon-lock-badge settings-folders-blocked-icon" />}
</span>
<span className="subtitle">{folder.subtitle}</span>
@ -307,7 +308,7 @@ const SettingsFoldersMain: FC<OwnProps & StateProps> = ({
>
<div className="settings-folders-recommended-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>
</div>

View File

@ -39,6 +39,7 @@ import useForceUpdate from '../../hooks/useForceUpdate';
import { LOCATION_HASH } from '../../hooks/useHistoryBack';
import useShowTransition from '../../hooks/useShowTransition';
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
import useInterval from '../../hooks/useInterval';
import StickerSetModal from '../common/StickerSetModal.async';
import UnreadCount from '../common/UnreadCounter';
@ -118,6 +119,7 @@ type StateProps = {
};
const NOTIFICATION_INTERVAL = 1000;
const APP_OUTDATED_TIMEOUT_MS = 5 * 60 * 1000; // 5 min
let notificationInterval: number | undefined;
@ -189,6 +191,7 @@ const Main: FC<StateProps> = ({
loadCustomEmojis,
closePaymentModal,
clearReceipt,
checkAppVersion,
} = getActions();
if (DEBUG && !DEBUG_isLogged) {
@ -203,6 +206,8 @@ const Main: FC<StateProps> = ({
}
}, [connectionState, authState, sync]);
useInterval(checkAppVersion, APP_OUTDATED_TIMEOUT_MS, true);
// Initial API calls
useEffect(() => {
if (lastSyncTime) {
@ -217,11 +222,12 @@ const Main: FC<StateProps> = ({
loadAttachMenuBots();
loadContactList();
loadPremiumGifts();
checkAppVersion();
}
}, [
lastSyncTime, loadAnimatedEmojis, loadEmojiKeywords, loadNotificationExceptions, loadNotificationSettings,
loadTopInlineBots, updateIsOnline, loadAvailableReactions, loadAppConfig, loadAttachMenuBots, loadContactList,
loadPremiumGifts,
loadPremiumGifts, checkAppVersion,
]);
// Language-based API calls

View File

@ -14,6 +14,7 @@ export const IS_PERF = process.env.APP_ENV === 'perf';
export const IS_BETA = process.env.APP_ENV === 'staging';
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_GRAMJS = false;

View File

@ -1,13 +1,11 @@
import { addActionHandler, setGlobal } from '../../index';
import { addActionHandler, getGlobal, setGlobal } from '../../index';
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 getReadableErrorText from '../../../util/getReadableErrorText';
import {
selectChatMessage, selectCurrentMessageList, selectIsTrustedBot,
} from '../../selectors';
import { selectChatMessage, selectCurrentMessageList, selectIsTrustedBot } from '../../selectors';
import generateIdFor from '../../../util/generateIdFor';
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,
});
}
});
});

View File

@ -15,6 +15,7 @@ export const INITIAL_STATE: GlobalState = {
newChatMembersProgress: NewChatMembersProgress.Closed,
uiReadyState: 0,
serverTimeOffset: 0,
isUpdateAvailable: false,
authRememberMe: true,
countryList: {

View File

@ -147,6 +147,7 @@ export type GlobalState = {
connectionState?: ApiUpdateConnectionStateType;
currentUserId?: string;
isSyncing?: boolean;
isUpdateAvailable?: boolean;
lastSyncTime?: number;
serverTimeOffset: number;
leftColumnWidth?: number;
@ -690,6 +691,7 @@ export interface ActionPayloads {
setInstallPrompt: { canInstall: boolean };
openLimitReachedModal: { limit: ApiLimitTypeWithModal };
closeLimitReachedModal: never;
checkAppVersion: never;
// Accounts
reportPeer: {