Reactions: Fix quick reactions, refetch configs (#2178)
Co-authored-by: undrfined <undrfined@gmail.com>
This commit is contained in:
parent
2a0ad055f1
commit
15e586d772
@ -22,7 +22,6 @@ interface GramJsAppConfig extends LimitsConfig {
|
||||
}>;
|
||||
emojies_send_dice: string[];
|
||||
groupcall_video_participants_max: number;
|
||||
reactions_default: string;
|
||||
reactions_uniq_max: number;
|
||||
chat_read_mark_size_threshold: number;
|
||||
chat_read_mark_expire_period: number;
|
||||
@ -66,7 +65,6 @@ export function buildAppConfig(json: GramJs.TypeJSONValue): ApiAppConfig {
|
||||
const appConfig = buildJson(json) as GramJsAppConfig;
|
||||
|
||||
return {
|
||||
defaultReaction: appConfig.reactions_default,
|
||||
emojiSounds: buildEmojiSounds(appConfig),
|
||||
seenByMaxChatMembers: appConfig.chat_read_mark_size_threshold,
|
||||
seenByExpiresAt: appConfig.chat_read_mark_expire_period,
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { Api as GramJs } from '../../../lib/gramjs';
|
||||
|
||||
import type {
|
||||
ApiConfig,
|
||||
ApiCountry, ApiSession, ApiUrlAuthResult, ApiWallpaper, ApiWebSession,
|
||||
} from '../../types';
|
||||
import type { ApiPrivacySettings, ApiPrivacyKey, PrivacyVisibility } from '../../../types';
|
||||
@ -221,3 +222,14 @@ export function buildApiUrlAuthResult(result: GramJs.TypeUrlAuthResult): ApiUrlA
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function buildApiConfig(config: GramJs.Config): ApiConfig {
|
||||
const defaultReaction = config.reactionsDefault
|
||||
&& 'emoticon' in config.reactionsDefault ? config.reactionsDefault.emoticon : undefined;
|
||||
return {
|
||||
expiresAt: config.expires,
|
||||
gifSearchUsername: config.gifSearchUsername,
|
||||
defaultReaction,
|
||||
maxGroupSize: config.chatSizeMax,
|
||||
};
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ export {
|
||||
fetchNotificationExceptions, fetchNotificationSettings, updateContactSignUpNotification, updateNotificationSettings,
|
||||
fetchLanguages, fetchLangPack, fetchPrivacySettings, setPrivacySettings, registerDevice, unregisterDevice,
|
||||
updateIsOnline, fetchContentSettings, updateContentSettings, fetchLangStrings, fetchCountryList, fetchAppConfig,
|
||||
fetchGlobalPrivacySettings, updateGlobalPrivacySettings, toggleUsername, reorderUsernames,
|
||||
fetchGlobalPrivacySettings, updateGlobalPrivacySettings, toggleUsername, reorderUsernames, fetchConfig,
|
||||
} from './settings';
|
||||
|
||||
export {
|
||||
|
||||
@ -3,6 +3,7 @@ import { Api as GramJs } from '../../../lib/gramjs';
|
||||
|
||||
import type {
|
||||
ApiAppConfig,
|
||||
ApiConfig,
|
||||
ApiError,
|
||||
ApiLangString,
|
||||
ApiLanguage,
|
||||
@ -14,6 +15,7 @@ import type { LANG_PACKS } from '../../../config';
|
||||
import { BLOCKED_LIST_LIMIT, DEFAULT_LANG_PACK } from '../../../config';
|
||||
import { ACCEPTABLE_USERNAME_ERRORS } from './management';
|
||||
import {
|
||||
buildApiConfig,
|
||||
buildApiCountryList,
|
||||
buildApiNotifyException,
|
||||
buildApiSession,
|
||||
@ -507,6 +509,13 @@ export async function fetchAppConfig(): Promise<ApiAppConfig | undefined> {
|
||||
return buildAppConfig(result);
|
||||
}
|
||||
|
||||
export async function fetchConfig(): Promise<ApiConfig | undefined> {
|
||||
const result = await invokeRequest(new GramJs.help.GetConfig());
|
||||
if (!result) return undefined;
|
||||
|
||||
return buildApiConfig(result);
|
||||
}
|
||||
|
||||
function updateLocalDb(
|
||||
result: (
|
||||
GramJs.account.PrivacyRules | GramJs.contacts.Blocked | GramJs.contacts.BlockedSlice |
|
||||
|
||||
@ -10,7 +10,7 @@ import {
|
||||
} from '../apiBuilders/symbols';
|
||||
import { buildInputStickerSet, buildInputDocument, buildInputStickerSetShortName } from '../gramjsBuilders';
|
||||
import { buildVideoFromDocument } from '../apiBuilders/messages';
|
||||
import { RECENT_STICKERS_LIMIT } from '../../../config';
|
||||
import { DEFAULT_GIF_SEARCH_BOT_USERNAME, RECENT_STICKERS_LIMIT } from '../../../config';
|
||||
|
||||
import localDb from '../localDb';
|
||||
|
||||
@ -301,15 +301,14 @@ export async function uninstallStickerSet({ stickerSetId, accessHash }: { sticke
|
||||
|
||||
let inputGifBot: GramJs.InputUser | undefined;
|
||||
|
||||
export async function searchGifs({ query, offset = '' }: { query: string; offset?: string }) {
|
||||
export async function searchGifs({
|
||||
query,
|
||||
offset = '',
|
||||
username = DEFAULT_GIF_SEARCH_BOT_USERNAME,
|
||||
}: { query: string; offset?: string; username?: string }) {
|
||||
if (!inputGifBot) {
|
||||
const config = await invokeRequest(new GramJs.help.GetConfig());
|
||||
if (!config) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const resolvedPeer = await invokeRequest(new GramJs.contacts.ResolveUsername({
|
||||
username: config.gifSearchUsername,
|
||||
username,
|
||||
}));
|
||||
if (!resolvedPeer || !(resolvedPeer.users[0] instanceof GramJs.User)) {
|
||||
return undefined;
|
||||
|
||||
@ -1031,6 +1031,7 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
|
||||
addEntitiesWithPhotosToLocalDb(entities);
|
||||
dispatchUserAndChatUpdates(entities);
|
||||
}
|
||||
onUpdate({ '@type': 'updateConfig' });
|
||||
} else if (DEBUG) {
|
||||
const params = typeof update === 'object' && 'className' in update ? update.className : update;
|
||||
log('UNEXPECTED UPDATE', params);
|
||||
|
||||
@ -162,7 +162,6 @@ export interface ApiCountryCode extends ApiCountry {
|
||||
}
|
||||
|
||||
export interface ApiAppConfig {
|
||||
defaultReaction: string;
|
||||
emojiSounds: Record<string, string>;
|
||||
seenByMaxChatMembers: number;
|
||||
seenByExpiresAt: number;
|
||||
@ -178,6 +177,13 @@ export interface ApiAppConfig {
|
||||
limits: Record<ApiLimitType, readonly [number, number]>;
|
||||
}
|
||||
|
||||
export interface ApiConfig {
|
||||
expiresAt: number;
|
||||
defaultReaction?: string;
|
||||
gifSearchUsername?: string;
|
||||
maxGroupSize: number;
|
||||
}
|
||||
|
||||
export interface GramJsEmojiInteraction {
|
||||
v: number;
|
||||
a: {
|
||||
|
||||
@ -375,6 +375,10 @@ export type ApiUpdateError = {
|
||||
error: ApiError;
|
||||
};
|
||||
|
||||
export type ApiUpdateConfig = {
|
||||
'@type': 'updateConfig';
|
||||
};
|
||||
|
||||
export type ApiUpdateResetContacts = {
|
||||
'@type': 'updateResetContactList';
|
||||
};
|
||||
@ -577,7 +581,7 @@ export type ApiUpdate = (
|
||||
ApiUpdatePendingJoinRequests | ApiUpdatePaymentVerificationNeeded | ApiUpdatePaymentStateCompleted |
|
||||
ApiUpdatePhoneCall | ApiUpdatePhoneCallSignalingData | ApiUpdatePhoneCallMediaState |
|
||||
ApiUpdatePhoneCallConnectionState | ApiUpdateBotMenuButton | ApiUpdateTranscribedAudio | ApiUpdateUserEmojiStatus |
|
||||
ApiUpdateMessageExtendedMedia
|
||||
ApiUpdateMessageExtendedMedia | ApiUpdateConfig
|
||||
);
|
||||
|
||||
export type OnApiUpdate = (update: ApiUpdate) => void;
|
||||
|
||||
@ -27,18 +27,17 @@ export type OwnProps = {
|
||||
type StateProps = {
|
||||
creationProgress?: ChatCreationProgress;
|
||||
creationError?: string;
|
||||
maxGroupSize?: number;
|
||||
};
|
||||
|
||||
// TODO @implement
|
||||
const MAX_USERS_FOR_LEGACY_CHAT = 199; // Accounting for current user
|
||||
|
||||
const NewChatStep2: FC<OwnProps & StateProps > = ({
|
||||
isChannel,
|
||||
isActive,
|
||||
memberIds,
|
||||
onReset,
|
||||
maxGroupSize,
|
||||
creationProgress,
|
||||
creationError,
|
||||
onReset,
|
||||
}) => {
|
||||
const {
|
||||
createGroupChat,
|
||||
@ -84,7 +83,7 @@ const NewChatStep2: FC<OwnProps & StateProps > = ({
|
||||
return;
|
||||
}
|
||||
|
||||
if (memberIds.length > MAX_USERS_FOR_LEGACY_CHAT) {
|
||||
if (maxGroupSize && memberIds.length >= maxGroupSize) {
|
||||
setError(chatTooManyUsersError);
|
||||
return;
|
||||
}
|
||||
@ -94,7 +93,7 @@ const NewChatStep2: FC<OwnProps & StateProps > = ({
|
||||
photo,
|
||||
memberIds,
|
||||
});
|
||||
}, [title, memberIds, createGroupChat, photo, chatTitleEmptyError, chatTooManyUsersError]);
|
||||
}, [title, memberIds, maxGroupSize, createGroupChat, photo]);
|
||||
|
||||
const handleCreateChannel = useCallback(() => {
|
||||
if (!title.length) {
|
||||
@ -204,6 +203,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
return {
|
||||
creationProgress,
|
||||
creationError,
|
||||
maxGroupSize: global.config?.maxGroupSize,
|
||||
};
|
||||
},
|
||||
)(NewChatStep2));
|
||||
|
||||
@ -63,12 +63,12 @@ const SettingsQuickReaction: FC<OwnProps & StateProps> = ({
|
||||
|
||||
export default memo(withGlobal<OwnProps>(
|
||||
(global) => {
|
||||
const { availableReactions, appConfig } = global;
|
||||
const { availableReactions, config } = global;
|
||||
const isPremium = selectIsCurrentUserPremium(global);
|
||||
|
||||
return {
|
||||
availableReactions,
|
||||
selectedReaction: appConfig?.defaultReaction,
|
||||
selectedReaction: config?.defaultReaction,
|
||||
isPremium,
|
||||
};
|
||||
},
|
||||
|
||||
@ -148,7 +148,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
addedSetIds: global.stickers.added.setIds,
|
||||
customEmojiSetIds: global.customEmojis.added.setIds,
|
||||
stickerSetsById: global.stickers.setsById,
|
||||
defaultReaction: global.appConfig?.defaultReaction,
|
||||
defaultReaction: global.config?.defaultReaction,
|
||||
};
|
||||
},
|
||||
)(SettingsStickers));
|
||||
|
||||
@ -186,6 +186,7 @@ const Main: FC<StateProps> = ({
|
||||
closeStickerSetModal,
|
||||
closeCustomEmojiSets,
|
||||
checkVersionNotification,
|
||||
loadConfig,
|
||||
loadAppConfig,
|
||||
loadAttachBots,
|
||||
loadContactList,
|
||||
@ -208,6 +209,7 @@ const Main: FC<StateProps> = ({
|
||||
useEffect(() => {
|
||||
if (lastSyncTime) {
|
||||
updateIsOnline(true);
|
||||
loadConfig();
|
||||
loadAppConfig();
|
||||
loadAvailableReactions();
|
||||
loadAnimatedEmojis();
|
||||
@ -223,7 +225,7 @@ const Main: FC<StateProps> = ({
|
||||
}, [
|
||||
lastSyncTime, loadAnimatedEmojis, loadEmojiKeywords, loadNotificationExceptions, loadNotificationSettings,
|
||||
loadTopInlineBots, updateIsOnline, loadAvailableReactions, loadAppConfig, loadAttachBots, loadContactList,
|
||||
loadPremiumGifts, checkAppVersion,
|
||||
loadPremiumGifts, checkAppVersion, loadConfig,
|
||||
]);
|
||||
|
||||
// Language-based API calls
|
||||
|
||||
@ -95,6 +95,8 @@ export const MACOS_DEFAULT_MESSAGE_TEXT_SIZE_PX = 15;
|
||||
|
||||
export const DRAFT_DEBOUNCE = 10000; // 10s
|
||||
export const SEND_MESSAGE_ACTION_INTERVAL = 3000; // 3s
|
||||
// 10000s from https://corefork.telegram.org/api/url-authorization#automatic-authorization
|
||||
export const APP_CONFIG_REFETCH_INTERVAL = 10000 * 1000;
|
||||
|
||||
export const EDITABLE_INPUT_ID = 'editable-message-text';
|
||||
export const EDITABLE_INPUT_MODAL_ID = 'editable-message-text-modal';
|
||||
@ -218,6 +220,7 @@ export const API_CHAT_TYPES = ['bots', 'channels', 'chats', 'users'] as const;
|
||||
export const SERVICE_NOTIFICATIONS_USER_ID = '777000';
|
||||
export const REPLIES_USER_ID = '1271266957'; // TODO For Test connection ID must be equal to 708513
|
||||
export const RESTRICTED_EMOJI_SET_ID = '7173162320003080';
|
||||
export const DEFAULT_GIF_SEARCH_BOT_USERNAME = 'gif';
|
||||
export const ALL_FOLDER_ID = 0;
|
||||
export const ARCHIVED_FOLDER_ID = 1;
|
||||
export const DELETED_COMMENTS_CHANNEL_ID = '-777';
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { addActionHandler, getGlobal, setGlobal } from '../../index';
|
||||
import { callApi } from '../../../api/gramjs';
|
||||
import * as mediaLoader from '../../../util/mediaLoader';
|
||||
import type { ApiAppConfig } from '../../../api/types';
|
||||
import { ApiMediaFormat } from '../../../api/types';
|
||||
import {
|
||||
selectChat,
|
||||
@ -180,12 +179,19 @@ addActionHandler('setDefaultReaction', async (global, actions, payload) => {
|
||||
return;
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
|
||||
if (!global.config) {
|
||||
actions.loadConfig(); // Refetch new config, if it is somehow not loaded
|
||||
return;
|
||||
}
|
||||
|
||||
setGlobal({
|
||||
...getGlobal(),
|
||||
appConfig: {
|
||||
...global.appConfig,
|
||||
...global,
|
||||
config: {
|
||||
...global.config,
|
||||
defaultReaction: reaction,
|
||||
} as ApiAppConfig,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -10,11 +10,13 @@ import {
|
||||
UPLOADING_WALLPAPER_SLUG,
|
||||
} from '../../../types';
|
||||
|
||||
import { COUNTRIES_WITH_12H_TIME_FORMAT } from '../../../config';
|
||||
import { APP_CONFIG_REFETCH_INTERVAL, COUNTRIES_WITH_12H_TIME_FORMAT } from '../../../config';
|
||||
import { callApi } from '../../../api/gramjs';
|
||||
import { buildCollectionByKey } from '../../../util/iteratees';
|
||||
import { subscribe, unsubscribe } from '../../../util/notifications';
|
||||
import { setTimeFormat } from '../../../util/langProvider';
|
||||
import requestActionTimeout from '../../../util/requestActionTimeout';
|
||||
import { getServerTime } from '../../../util/serverTime';
|
||||
import { selectChat, selectUser } from '../../selectors';
|
||||
import {
|
||||
addUsers, addBlockedContact, updateChats, updateUser, removeBlockedContact, replaceSettings, updateNotifySettings,
|
||||
@ -621,12 +623,27 @@ addActionHandler('loadAppConfig', async () => {
|
||||
const appConfig = await callApi('fetchAppConfig');
|
||||
if (!appConfig) return;
|
||||
|
||||
requestActionTimeout('loadAppConfig', APP_CONFIG_REFETCH_INTERVAL);
|
||||
|
||||
setGlobal({
|
||||
...getGlobal(),
|
||||
appConfig,
|
||||
});
|
||||
});
|
||||
|
||||
addActionHandler('loadConfig', async (global) => {
|
||||
const config = await callApi('fetchConfig');
|
||||
if (!config) return;
|
||||
|
||||
const timeout = config.expiresAt - getServerTime(global.serverTimeOffset);
|
||||
requestActionTimeout('loadConfig', timeout * 1000);
|
||||
|
||||
setGlobal({
|
||||
...getGlobal(),
|
||||
config,
|
||||
});
|
||||
});
|
||||
|
||||
addActionHandler('loadGlobalPrivacySettings', async () => {
|
||||
const globalSettings = await callApi('fetchGlobalPrivacySettings');
|
||||
if (!globalSettings) {
|
||||
|
||||
@ -516,7 +516,7 @@ addActionHandler('setGifSearchQuery', (global, actions, payload) => {
|
||||
|
||||
if (typeof query === 'string') {
|
||||
void searchThrottled(() => {
|
||||
searchGifs(query);
|
||||
searchGifs(query, global.config?.gifSearchUsername);
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -526,7 +526,7 @@ addActionHandler('searchMoreGifs', (global) => {
|
||||
|
||||
if (typeof query === 'string') {
|
||||
void searchThrottled(() => {
|
||||
searchGifs(query, offset);
|
||||
searchGifs(query, global.config?.gifSearchUsername, offset);
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -646,8 +646,8 @@ async function searchStickers(query: string, hash?: string) {
|
||||
));
|
||||
}
|
||||
|
||||
async function searchGifs(query: string, offset?: string) {
|
||||
const result = await callApi('searchGifs', { query, offset });
|
||||
async function searchGifs(query: string, botUsername?: string, offset?: string) {
|
||||
const result = await callApi('searchGifs', { query, offset, username: botUsername });
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -24,6 +24,10 @@ addActionHandler('apiUpdate', (global, actions, update) => {
|
||||
});
|
||||
break;
|
||||
|
||||
case 'updateConfig':
|
||||
actions.loadConfig();
|
||||
break;
|
||||
|
||||
case 'updateFavoriteStickers':
|
||||
actions.loadFavoriteStickers();
|
||||
break;
|
||||
|
||||
@ -952,7 +952,7 @@ export function selectDefaultReaction(global: GlobalState, chatId: string) {
|
||||
if (chatId === SERVICE_NOTIFICATIONS_USER_ID) return undefined;
|
||||
|
||||
const isPrivate = isUserId(chatId);
|
||||
const defaultReaction = global.appConfig?.defaultReaction;
|
||||
const defaultReaction = global.config?.defaultReaction;
|
||||
const { availableReactions } = global;
|
||||
if (!defaultReaction || !availableReactions?.some(
|
||||
(l) => l.reaction === defaultReaction && !l.isInactive,
|
||||
|
||||
@ -46,6 +46,7 @@ import type {
|
||||
ApiChatType,
|
||||
ApiReceipt,
|
||||
ApiPaymentCredentials,
|
||||
ApiConfig,
|
||||
} from '../api/types';
|
||||
import type {
|
||||
FocusDirection,
|
||||
@ -138,6 +139,7 @@ export type ApiLimitTypeWithModal = Exclude<ApiLimitType, (
|
||||
)>;
|
||||
|
||||
export type GlobalState = {
|
||||
config?: ApiConfig;
|
||||
appConfig?: ApiAppConfig;
|
||||
canInstall?: boolean;
|
||||
hasWebAuthTokenFailed?: boolean;
|
||||
@ -1198,6 +1200,8 @@ export interface ActionPayloads {
|
||||
skipLockOnUnload: never;
|
||||
|
||||
// Settings
|
||||
loadConfig: never;
|
||||
loadAppConfig: never;
|
||||
requestNextSettingsScreen: SettingsScreens;
|
||||
sortChatFolders: { folderIds: number[] };
|
||||
closeDeleteChatFolderModal: never;
|
||||
@ -1314,7 +1318,7 @@ export type NonTypedActionNames = (
|
||||
'updateWebNotificationSettings' | 'loadLanguages' | 'loadPrivacySettings' | 'setPrivacyVisibility' |
|
||||
'setPrivacySettings' | 'loadNotificationExceptions' | 'setThemeSettings' | 'updateIsOnline' |
|
||||
'loadContentSettings' | 'updateContentSettings' |
|
||||
'loadCountryList' | 'ensureTimeFormat' | 'loadAppConfig' |
|
||||
'loadCountryList' | 'ensureTimeFormat' |
|
||||
// stickers & GIFs
|
||||
'setStickerSearchQuery' | 'saveGif' | 'setGifSearchQuery' | 'searchMoreGifs' |
|
||||
'faveSticker' | 'unfaveSticker' | 'toggleStickerSet' |
|
||||
|
||||
12
src/util/requestActionTimeout.ts
Normal file
12
src/util/requestActionTimeout.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { getActions } from '../global';
|
||||
import type { GlobalActions } from '../global/types';
|
||||
|
||||
const callbacks = new Map<string, NodeJS.Timeout>();
|
||||
|
||||
export default function requestActionTimeout(action: keyof GlobalActions, timeout: number) {
|
||||
clearTimeout(callbacks.get(action));
|
||||
const timerId = setTimeout(() => {
|
||||
getActions()[action]();
|
||||
}, timeout);
|
||||
callbacks.set(action, timerId);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user