Left Menu: Add Telegram Features, Report Bug and app info items
This commit is contained in:
parent
47edc22f9a
commit
2499a4ca95
@ -7,7 +7,7 @@
|
|||||||
"dev": "cross-env APP_ENV=development webpack-dev-server -d",
|
"dev": "cross-env APP_ENV=development webpack-dev-server -d",
|
||||||
"build": "webpack -p",
|
"build": "webpack -p",
|
||||||
"build:staging": "rm -rf dist/ && APP_ENV=staging npm run build && ./deploy/copy_to_dist.sh",
|
"build:staging": "rm -rf dist/ && APP_ENV=staging npm run build && ./deploy/copy_to_dist.sh",
|
||||||
"build:production": "rm -rf dist/ && APP_ENV=production npm run build -- --env.noSourceMap && ./deploy/copy_to_dist.sh",
|
"build:production": "rm -rf dist/ && APP_INFO=\"Telegram WebZ alpha $(git rev-parse --short HEAD)\" APP_ENV=production npm run build -- --env.noSourceMap && ./deploy/copy_to_dist.sh",
|
||||||
"deploy:contest": "./deploy/contest.sh",
|
"deploy:contest": "./deploy/contest.sh",
|
||||||
"perf:serve": "APP_ENV=perf parcel src/index-perf.html",
|
"perf:serve": "APP_ENV=perf parcel src/index-perf.html",
|
||||||
"lint": "eslint . --ext .ts,.tsx",
|
"lint": "eslint . --ext .ts,.tsx",
|
||||||
|
|||||||
BIN
src/assets/fonts/icomoon.woff
Executable file → Normal file
BIN
src/assets/fonts/icomoon.woff
Executable file → Normal file
Binary file not shown.
Binary file not shown.
@ -57,6 +57,10 @@
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.Menu .bubble {
|
||||||
|
min-width: 17rem;
|
||||||
|
}
|
||||||
|
|
||||||
// @optimization
|
// @optimization
|
||||||
@include while-transition() {
|
@include while-transition() {
|
||||||
.Menu .bubble {
|
.Menu .bubble {
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import { GlobalActions } from '../../../global/types';
|
|||||||
import { LeftColumnContent, ISettings } from '../../../types';
|
import { LeftColumnContent, ISettings } from '../../../types';
|
||||||
import { ApiChat } from '../../../api/types';
|
import { ApiChat } from '../../../api/types';
|
||||||
|
|
||||||
|
import { APP_INFO, FEEDBACK_URL } from '../../../config';
|
||||||
import { IS_MOBILE_SCREEN } from '../../../util/environment';
|
import { IS_MOBILE_SCREEN } from '../../../util/environment';
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import { pick } from '../../../util/iteratees';
|
import { pick } from '../../../util/iteratees';
|
||||||
@ -45,8 +46,9 @@ type StateProps = {
|
|||||||
chatsById?: Record<number, ApiChat>;
|
chatsById?: Record<number, ApiChat>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions,
|
type DispatchProps = Pick<GlobalActions, (
|
||||||
'openChat'| 'openSupportChat' | 'setGlobalSearchDate' | 'setGlobalSearchChatId' | 'setSettingOption'>;
|
'openChat' | 'openTipsChat' | 'setGlobalSearchDate' | 'setGlobalSearchChatId' | 'setSettingOption'
|
||||||
|
)>;
|
||||||
|
|
||||||
const ANIMATION_LEVEL_OPTIONS = [0, 1, 2];
|
const ANIMATION_LEVEL_OPTIONS = [0, 1, 2];
|
||||||
|
|
||||||
@ -68,7 +70,7 @@ const LeftMainHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
animationLevel,
|
animationLevel,
|
||||||
chatsById,
|
chatsById,
|
||||||
openChat,
|
openChat,
|
||||||
openSupportChat,
|
openTipsChat,
|
||||||
setGlobalSearchDate,
|
setGlobalSearchDate,
|
||||||
setSettingOption,
|
setSettingOption,
|
||||||
}) => {
|
}) => {
|
||||||
@ -144,9 +146,11 @@ const LeftMainHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
const isSearchFocused = Boolean(globalSearchChatId)
|
const isSearchFocused = (
|
||||||
|| content === LeftColumnContent.GlobalSearch
|
Boolean(globalSearchChatId)
|
||||||
|| content === LeftColumnContent.Contacts;
|
|| content === LeftColumnContent.GlobalSearch
|
||||||
|
|| content === LeftColumnContent.Contacts
|
||||||
|
);
|
||||||
|
|
||||||
const searchInputPlaceholder = content === LeftColumnContent.Contacts
|
const searchInputPlaceholder = content === LeftColumnContent.Contacts
|
||||||
? lang('SearchFriends')
|
? lang('SearchFriends')
|
||||||
@ -157,6 +161,7 @@ const LeftMainHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
<div id="LeftMainHeader" className="left-header">
|
<div id="LeftMainHeader" className="left-header">
|
||||||
<DropdownMenu
|
<DropdownMenu
|
||||||
trigger={MainButton}
|
trigger={MainButton}
|
||||||
|
footer={APP_INFO}
|
||||||
>
|
>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
icon="saved-messages"
|
icon="saved-messages"
|
||||||
@ -209,9 +214,15 @@ const LeftMainHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
icon="help"
|
icon="help"
|
||||||
onClick={openSupportChat}
|
onClick={openTipsChat}
|
||||||
>
|
>
|
||||||
{lang('BotHelp')}
|
Telegram Features
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem
|
||||||
|
icon="bug"
|
||||||
|
href={FEEDBACK_URL}
|
||||||
|
>
|
||||||
|
Report Bug
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
<SearchInput
|
<SearchInput
|
||||||
@ -273,7 +284,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
(setGlobal, actions): DispatchProps => pick(actions, [
|
||||||
'openChat',
|
'openChat',
|
||||||
'openSupportChat',
|
'openTipsChat',
|
||||||
'setGlobalSearchDate',
|
'setGlobalSearchDate',
|
||||||
'setGlobalSearchChatId',
|
'setGlobalSearchChatId',
|
||||||
'setSettingOption',
|
'setSettingOption',
|
||||||
|
|||||||
@ -9,17 +9,18 @@ type OwnProps = {
|
|||||||
trigger: FC<{ onTrigger: () => void; isOpen?: boolean }>;
|
trigger: FC<{ onTrigger: () => void; isOpen?: boolean }>;
|
||||||
positionX?: 'left' | 'right';
|
positionX?: 'left' | 'right';
|
||||||
positionY?: 'top' | 'bottom';
|
positionY?: 'top' | 'bottom';
|
||||||
|
footer?: string;
|
||||||
children: any;
|
children: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
const DropdownMenu: FC<OwnProps> = (props) => {
|
const DropdownMenu: FC<OwnProps> = ({
|
||||||
const {
|
trigger,
|
||||||
trigger,
|
className,
|
||||||
className,
|
children,
|
||||||
children,
|
positionX = 'left',
|
||||||
positionX = 'left',
|
positionY = 'top',
|
||||||
positionY = 'top',
|
footer,
|
||||||
} = props;
|
}) => {
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const menuRef = useRef<HTMLDivElement>(null);
|
const menuRef = useRef<HTMLDivElement>(null);
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
@ -64,6 +65,7 @@ const DropdownMenu: FC<OwnProps> = (props) => {
|
|||||||
className={className || ''}
|
className={className || ''}
|
||||||
positionX={positionX}
|
positionX={positionX}
|
||||||
positionY={positionY}
|
positionY={positionY}
|
||||||
|
footer={footer}
|
||||||
autoClose
|
autoClose
|
||||||
onClose={handleClose}
|
onClose={handleClose}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.bubble {
|
.bubble {
|
||||||
|
overflow: hidden;
|
||||||
display: block;
|
display: block;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
padding: 0.5rem 0;
|
padding: 0.5rem 0;
|
||||||
@ -63,5 +64,17 @@
|
|||||||
&.right {
|
&.right {
|
||||||
right: var(--offset-x);
|
right: var(--offset-x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.with-footer {
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
padding: 0.5rem 0;
|
||||||
|
background: #F4F4F5;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
font-size: 0.8125rem;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,6 +20,7 @@ type OwnProps = {
|
|||||||
positionX?: 'left' | 'right';
|
positionX?: 'left' | 'right';
|
||||||
positionY?: 'top' | 'bottom';
|
positionY?: 'top' | 'bottom';
|
||||||
autoClose?: boolean;
|
autoClose?: boolean;
|
||||||
|
footer?: string;
|
||||||
noCloseOnBackdrop?: boolean;
|
noCloseOnBackdrop?: boolean;
|
||||||
onKeyDown?: (e: React.KeyboardEvent<any>) => void;
|
onKeyDown?: (e: React.KeyboardEvent<any>) => void;
|
||||||
onCloseAnimationEnd?: () => void;
|
onCloseAnimationEnd?: () => void;
|
||||||
@ -41,6 +42,7 @@ const Menu: FC<OwnProps> = ({
|
|||||||
positionX = 'left',
|
positionX = 'left',
|
||||||
positionY = 'top',
|
positionY = 'top',
|
||||||
autoClose = false,
|
autoClose = false,
|
||||||
|
footer,
|
||||||
noCloseOnBackdrop = false,
|
noCloseOnBackdrop = false,
|
||||||
onCloseAnimationEnd,
|
onCloseAnimationEnd,
|
||||||
onClose,
|
onClose,
|
||||||
@ -72,6 +74,14 @@ const Menu: FC<OwnProps> = ({
|
|||||||
noCloseOnBackdrop ? undefined : onClose,
|
noCloseOnBackdrop ? undefined : onClose,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const bubbleClassName = buildClassName(
|
||||||
|
'bubble menu-container custom-scroll',
|
||||||
|
positionY,
|
||||||
|
positionX,
|
||||||
|
footer && 'with-footer',
|
||||||
|
transitionClassNames,
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={buildClassName('Menu no-selection', className)}
|
className={buildClassName('Menu no-selection', className)}
|
||||||
@ -87,12 +97,13 @@ const Menu: FC<OwnProps> = ({
|
|||||||
)}
|
)}
|
||||||
<div
|
<div
|
||||||
ref={menuRef}
|
ref={menuRef}
|
||||||
className={buildClassName('bubble menu-container custom-scroll', positionY, positionX, transitionClassNames)}
|
className={bubbleClassName}
|
||||||
// @ts-ignore teact feature
|
// @ts-ignore teact feature
|
||||||
style={`transform-origin: ${positionY} ${positionX}`}
|
style={`transform-origin: ${positionY} ${positionX}`}
|
||||||
onClick={autoClose ? onClose : undefined}
|
onClick={autoClose ? onClose : undefined}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
{footer && <div className="footer">{footer}</div>}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
&:hover, &:focus {
|
&:hover, &:focus {
|
||||||
background-color: var(--color-chat-hover);
|
background-color: var(--color-chat-hover);
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
i {
|
i {
|
||||||
|
|||||||
@ -82,6 +82,8 @@ const MenuItem: FC<OwnProps> = (props) => {
|
|||||||
download={download}
|
download={download}
|
||||||
aria-label={ariaLabel}
|
aria-label={ariaLabel}
|
||||||
title={ariaLabel}
|
title={ariaLabel}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
>
|
>
|
||||||
{content}
|
{content}
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
export const APP_INFO = process.env.APP_INFO || 'Telegram T';
|
||||||
|
|
||||||
export const DEBUG = (
|
export const DEBUG = (
|
||||||
process.env.APP_ENV !== 'production' && process.env.APP_ENV !== 'perf' && process.env.APP_ENV !== 'test'
|
process.env.APP_ENV !== 'production' && process.env.APP_ENV !== 'perf' && process.env.APP_ENV !== 'test'
|
||||||
);
|
);
|
||||||
@ -115,3 +117,5 @@ export const MAX_ACTIVE_PINNED_CHATS = 5;
|
|||||||
export const SCHEDULED_WHEN_ONLINE = 0x7FFFFFFE;
|
export const SCHEDULED_WHEN_ONLINE = 0x7FFFFFFE;
|
||||||
export const DEFAULT_LANG_PACK = 'android';
|
export const DEFAULT_LANG_PACK = 'android';
|
||||||
export const LANG_PACKS = ['android', 'ios'];
|
export const LANG_PACKS = ['android', 'ios'];
|
||||||
|
export const TIPS_USERNAME = 'TelegramTips';
|
||||||
|
export const FEEDBACK_URL = 'https://bugs.telegram.org/?tag_ids=41&sort=time';
|
||||||
|
|||||||
@ -385,7 +385,8 @@ export type ActionTypes = (
|
|||||||
'setAuthPhoneNumber' | 'setAuthCode' | 'setAuthPassword' | 'signUp' | 'returnToAuthPhoneNumber' | 'signOut' |
|
'setAuthPhoneNumber' | 'setAuthCode' | 'setAuthPassword' | 'signUp' | 'returnToAuthPhoneNumber' | 'signOut' |
|
||||||
'setAuthRememberMe' | 'clearAuthError' | 'uploadProfilePhoto' | 'gotToAuthQrCode' | 'clearCache' |
|
'setAuthRememberMe' | 'clearAuthError' | 'uploadProfilePhoto' | 'gotToAuthQrCode' | 'clearCache' |
|
||||||
// chats
|
// chats
|
||||||
'preloadTopChatMessages' | 'loadChats' | 'loadMoreChats' | 'openChat' | 'openChatWithInfo' | 'openSupportChat' |
|
'preloadTopChatMessages' | 'loadChats' | 'loadMoreChats' | 'openChat' | 'openChatWithInfo' |
|
||||||
|
'openSupportChat' | 'openTipsChat' |
|
||||||
'loadFullChat' | 'loadSuperGroupOnlines' | 'loadTopChats' | 'requestChatUpdate' | 'updateChatMutedState' |
|
'loadFullChat' | 'loadSuperGroupOnlines' | 'loadTopChats' | 'requestChatUpdate' | 'updateChatMutedState' |
|
||||||
'joinChannel' | 'leaveChannel' | 'deleteChannel' | 'toggleChatPinned' | 'toggleChatArchived' | 'toggleChatUnread' |
|
'joinChannel' | 'leaveChannel' | 'deleteChannel' | 'toggleChatPinned' | 'toggleChatArchived' | 'toggleChatUnread' |
|
||||||
'loadChatFolders' | 'loadRecommendedChatFolders' | 'editChatFolder' | 'addChatFolder' | 'deleteChatFolder' |
|
'loadChatFolders' | 'loadRecommendedChatFolders' | 'editChatFolder' | 'addChatFolder' | 'deleteChatFolder' |
|
||||||
|
|||||||
@ -13,8 +13,9 @@ import {
|
|||||||
TOP_CHAT_MESSAGES_PRELOAD_LIMIT,
|
TOP_CHAT_MESSAGES_PRELOAD_LIMIT,
|
||||||
CHAT_LIST_LOAD_SLICE,
|
CHAT_LIST_LOAD_SLICE,
|
||||||
RE_TME_LINK,
|
RE_TME_LINK,
|
||||||
|
TIPS_USERNAME,
|
||||||
} from '../../../config';
|
} from '../../../config';
|
||||||
|
import { IS_TOUCH_ENV } from '../../../util/environment';
|
||||||
import { callApi } from '../../../api/gramjs';
|
import { callApi } from '../../../api/gramjs';
|
||||||
import {
|
import {
|
||||||
addChats,
|
addChats,
|
||||||
@ -43,7 +44,6 @@ import { debounce, pause, throttle } from '../../../util/schedulers';
|
|||||||
import {
|
import {
|
||||||
isChatSummaryOnly, isChatArchived, prepareChatList, isChatBasicGroup,
|
isChatSummaryOnly, isChatArchived, prepareChatList, isChatBasicGroup,
|
||||||
} from '../../helpers';
|
} from '../../helpers';
|
||||||
import { IS_TOUCH_ENV } from '../../../util/environment';
|
|
||||||
|
|
||||||
const TOP_CHATS_PRELOAD_PAUSE = 200;
|
const TOP_CHATS_PRELOAD_PAUSE = 200;
|
||||||
// We expect this ID does not exist
|
// We expect this ID does not exist
|
||||||
@ -136,6 +136,10 @@ addReducer('openSupportChat', (global, actions) => {
|
|||||||
})();
|
})();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addReducer('openTipsChat', (global, actions) => {
|
||||||
|
actions.openChatByUsername({ username: TIPS_USERNAME });
|
||||||
|
});
|
||||||
|
|
||||||
addReducer('loadMoreChats', (global, actions, payload) => {
|
addReducer('loadMoreChats', (global, actions, payload) => {
|
||||||
const { listType = 'active' } = payload!;
|
const { listType = 'active' } = payload!;
|
||||||
const listIds = global.chats.listIds[listType as ('active' | 'archived')];
|
const listIds = global.chats.listIds[listType as ('active' | 'archived')];
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -22,6 +22,9 @@
|
|||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-bug:before {
|
||||||
|
content: "\e97d";
|
||||||
|
}
|
||||||
.icon-darkmode:before {
|
.icon-darkmode:before {
|
||||||
content: "\e979";
|
content: "\e979";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -103,6 +103,7 @@ module.exports = (env = {}, argv = {}) => {
|
|||||||
ignoreOrder: true,
|
ignoreOrder: true,
|
||||||
}),
|
}),
|
||||||
new EnvironmentPlugin({
|
new EnvironmentPlugin({
|
||||||
|
APP_INFO: 'Telegram T',
|
||||||
APP_ENV: 'production',
|
APP_ENV: 'production',
|
||||||
TELEGRAM_T_API_ID: '',
|
TELEGRAM_T_API_ID: '',
|
||||||
TELEGRAM_T_API_HASH: '',
|
TELEGRAM_T_API_HASH: '',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user