Main Menu: Support "Install App" action (#1901)
This commit is contained in:
parent
05ca268f6b
commit
e7781e10c9
@ -29,6 +29,7 @@ import { isChatArchived } from '../../../global/helpers';
|
|||||||
import useLang from '../../../hooks/useLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
import useConnectionStatus from '../../../hooks/useConnectionStatus';
|
import useConnectionStatus from '../../../hooks/useConnectionStatus';
|
||||||
import { useHotkeys } from '../../../hooks/useHotkeys';
|
import { useHotkeys } from '../../../hooks/useHotkeys';
|
||||||
|
import { getPromptInstall } from '../../../util/installPrompt';
|
||||||
|
|
||||||
import DropdownMenu from '../../ui/DropdownMenu';
|
import DropdownMenu from '../../ui/DropdownMenu';
|
||||||
import MenuItem from '../../ui/MenuItem';
|
import MenuItem from '../../ui/MenuItem';
|
||||||
@ -67,7 +68,7 @@ type StateProps =
|
|||||||
areChatsLoaded?: boolean;
|
areChatsLoaded?: boolean;
|
||||||
hasPasscode?: boolean;
|
hasPasscode?: boolean;
|
||||||
}
|
}
|
||||||
& Pick<GlobalState, 'connectionState' | 'isSyncing'>;
|
& Pick<GlobalState, 'connectionState' | 'isSyncing' | 'canInstall'>;
|
||||||
|
|
||||||
const PRODUCTION_HOSTNAME = 'web.telegram.org';
|
const PRODUCTION_HOSTNAME = 'web.telegram.org';
|
||||||
const LEGACY_VERSION_URL = 'https://web.telegram.org/?legacy=1';
|
const LEGACY_VERSION_URL = 'https://web.telegram.org/?legacy=1';
|
||||||
@ -96,6 +97,7 @@ const LeftMainHeader: FC<OwnProps & StateProps> = ({
|
|||||||
isConnectionStatusMinimized,
|
isConnectionStatusMinimized,
|
||||||
areChatsLoaded,
|
areChatsLoaded,
|
||||||
hasPasscode,
|
hasPasscode,
|
||||||
|
canInstall,
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
openChat,
|
openChat,
|
||||||
@ -345,6 +347,15 @@ const LeftMainHeader: FC<OwnProps & StateProps> = ({
|
|||||||
</MenuItem>
|
</MenuItem>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
{canInstall && (
|
||||||
|
<MenuItem
|
||||||
|
icon="install"
|
||||||
|
onClick={getPromptInstall()}
|
||||||
|
>
|
||||||
|
Install App
|
||||||
|
<span className="menu-item-badge">{lang('New')}</span>
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
<SearchInput
|
<SearchInput
|
||||||
inputId="telegram-search-input"
|
inputId="telegram-search-input"
|
||||||
@ -436,6 +447,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
isConnectionStatusMinimized,
|
isConnectionStatusMinimized,
|
||||||
areChatsLoaded: Boolean(global.chats.listIds.active),
|
areChatsLoaded: Boolean(global.chats.listIds.active),
|
||||||
hasPasscode: Boolean(global.passcode.hasPasscode),
|
hasPasscode: Boolean(global.passcode.hasPasscode),
|
||||||
|
canInstall: Boolean(global.canInstall),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
)(LeftMainHeader));
|
)(LeftMainHeader));
|
||||||
|
|||||||
@ -47,6 +47,14 @@ addActionHandler('init', (global) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addActionHandler('setInstallPrompt', (global, actions, payload) => {
|
||||||
|
const { canInstall } = payload;
|
||||||
|
return {
|
||||||
|
...global,
|
||||||
|
canInstall,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
addActionHandler('setIsUiReady', (global, actions, payload) => {
|
addActionHandler('setIsUiReady', (global, actions, payload) => {
|
||||||
const { uiReadyState } = payload!;
|
const { uiReadyState } = payload!;
|
||||||
|
|
||||||
|
|||||||
@ -121,6 +121,7 @@ export interface ServiceNotification {
|
|||||||
|
|
||||||
export type GlobalState = {
|
export type GlobalState = {
|
||||||
appConfig?: ApiAppConfig;
|
appConfig?: ApiAppConfig;
|
||||||
|
canInstall?: boolean;
|
||||||
isChatInfoShown: boolean;
|
isChatInfoShown: boolean;
|
||||||
isStatisticsShown?: boolean;
|
isStatisticsShown?: boolean;
|
||||||
isLeftColumnShown: boolean;
|
isLeftColumnShown: boolean;
|
||||||
@ -599,6 +600,9 @@ export interface ActionPayloads {
|
|||||||
signOut: { forceInitApi?: boolean } | undefined;
|
signOut: { forceInitApi?: boolean } | undefined;
|
||||||
apiUpdate: ApiUpdate;
|
apiUpdate: ApiUpdate;
|
||||||
|
|
||||||
|
// Misc
|
||||||
|
setInstallPrompt: { canInstall: boolean };
|
||||||
|
|
||||||
// Accounts
|
// Accounts
|
||||||
reportPeer: {
|
reportPeer: {
|
||||||
chatId?: string;
|
chatId?: string;
|
||||||
|
|||||||
@ -6,6 +6,8 @@ import TeactDOM from './lib/teact/teact-dom';
|
|||||||
|
|
||||||
import { getActions, getGlobal } from './global';
|
import { getActions, getGlobal } from './global';
|
||||||
import updateWebmanifest from './util/updateWebmanifest';
|
import updateWebmanifest from './util/updateWebmanifest';
|
||||||
|
import { setupBeforeInstallPrompt } from './util/installPrompt';
|
||||||
|
import { IS_INSTALL_PROMPT_SUPPORTED } from './util/environment';
|
||||||
import './global/init';
|
import './global/init';
|
||||||
|
|
||||||
import { DEBUG } from './config';
|
import { DEBUG } from './config';
|
||||||
@ -19,6 +21,9 @@ if (DEBUG) {
|
|||||||
console.log('>>> INIT');
|
console.log('>>> INIT');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IS_INSTALL_PROMPT_SUPPORTED) {
|
||||||
|
setupBeforeInstallPrompt();
|
||||||
|
}
|
||||||
getActions().init();
|
getActions().init();
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
|
|||||||
@ -91,6 +91,7 @@ export const IS_BACKDROP_BLUR_SUPPORTED = !IS_TEST && (
|
|||||||
);
|
);
|
||||||
export const IS_COMPACT_MENU = !IS_TOUCH_ENV;
|
export const IS_COMPACT_MENU = !IS_TOUCH_ENV;
|
||||||
export const IS_SCROLL_PATCH_NEEDED = !IS_MAC_OS && !IS_IOS && !IS_ANDROID;
|
export const IS_SCROLL_PATCH_NEEDED = !IS_MAC_OS && !IS_IOS && !IS_ANDROID;
|
||||||
|
export const IS_INSTALL_PROMPT_SUPPORTED = 'onbeforeinstallprompt' in window;
|
||||||
|
|
||||||
// Smaller area reduces scroll jumps caused by `patchChromiumScroll`
|
// Smaller area reduces scroll jumps caused by `patchChromiumScroll`
|
||||||
export const MESSAGE_LIST_SENSITIVE_AREA = IS_SCROLL_PATCH_NEEDED ? 300 : 750;
|
export const MESSAGE_LIST_SENSITIVE_AREA = IS_SCROLL_PATCH_NEEDED ? 300 : 750;
|
||||||
|
|||||||
21
src/util/installPrompt.ts
Normal file
21
src/util/installPrompt.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { getActions } from '../global';
|
||||||
|
|
||||||
|
let promptInstall: () => Promise<void>;
|
||||||
|
|
||||||
|
export function setupBeforeInstallPrompt() {
|
||||||
|
window.addEventListener('beforeinstallprompt', (e: any) => {
|
||||||
|
promptInstall = async () => {
|
||||||
|
e.prompt();
|
||||||
|
const userChoice = await e.userChoice;
|
||||||
|
const isInstalled = userChoice.outcome === 'accepted';
|
||||||
|
|
||||||
|
if (!isInstalled) return;
|
||||||
|
getActions().setInstallPrompt({ canInstall: false });
|
||||||
|
};
|
||||||
|
getActions().setInstallPrompt({ canInstall: true });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPromptInstall() {
|
||||||
|
return promptInstall;
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user