Auto-detect time format by nearest country
This commit is contained in:
parent
3b603ff4bf
commit
67dca172db
@ -132,13 +132,16 @@ function buildApiCountry(country: GramJs.help.Country, code?: GramJs.help.Countr
|
||||
}
|
||||
|
||||
export function buildApiCountryList(countries: GramJs.help.Country[]) {
|
||||
const listByCode = flatten(countries
|
||||
.filter((country) => !country.hidden)
|
||||
.map((country) => (
|
||||
country.countryCodes.map((code) => buildApiCountry(country, code))
|
||||
))).sort((a: ApiCountry, b: ApiCountry) => (
|
||||
a.name ? a.name.localeCompare(b.name!) : a.defaultName.localeCompare(b.defaultName)
|
||||
));
|
||||
const listByCode = flatten(
|
||||
countries
|
||||
.filter((country) => !country.hidden)
|
||||
.map((country) => (
|
||||
country.countryCodes.map((code) => buildApiCountry(country, code))
|
||||
)),
|
||||
)
|
||||
.sort((a: ApiCountry, b: ApiCountry) => (
|
||||
a.name ? a.name.localeCompare(b.name!) : a.defaultName.localeCompare(b.defaultName)
|
||||
));
|
||||
|
||||
const generalList = countries
|
||||
.filter((country) => !country.hidden)
|
||||
|
||||
@ -26,8 +26,7 @@ export {
|
||||
} from './messages';
|
||||
|
||||
export {
|
||||
fetchFullUser, fetchNearestCountry, fetchCountryList,
|
||||
fetchTopUsers, fetchContactList, fetchUsers,
|
||||
fetchFullUser, fetchNearestCountry, fetchTopUsers, fetchContactList, fetchUsers,
|
||||
addContact, updateContact, deleteUser, fetchProfilePhotos,
|
||||
} from './users';
|
||||
|
||||
@ -47,7 +46,7 @@ export {
|
||||
fetchAuthorizations, terminateAuthorization, terminateAllAuthorizations,
|
||||
fetchNotificationExceptions, fetchNotificationSettings, updateContactSignUpNotification, updateNotificationSettings,
|
||||
fetchLanguages, fetchLangPack, fetchPrivacySettings, setPrivacySettings, registerDevice, unregisterDevice,
|
||||
updateIsOnline, fetchContentSettings, updateContentSettings, fetchLangStrings,
|
||||
updateIsOnline, fetchContentSettings, updateContentSettings, fetchLangStrings, fetchCountryList,
|
||||
} from './settings';
|
||||
|
||||
export {
|
||||
|
||||
@ -4,11 +4,11 @@ import { Api as GramJs } from '../../../lib/gramjs';
|
||||
import {
|
||||
ApiChat, ApiLangString, ApiLanguage, ApiNotifyException, ApiUser, ApiWallpaper,
|
||||
} from '../../types';
|
||||
import { ApiPrivacyKey, InputPrivacyRules } from '../../../types';
|
||||
import { ApiPrivacyKey, InputPrivacyRules, LangCode } from '../../../types';
|
||||
|
||||
import { BLOCKED_LIST_LIMIT, DEFAULT_LANG_PACK, LANG_PACKS } from '../../../config';
|
||||
import {
|
||||
buildApiWallpaper, buildApiSession, buildPrivacyRules, buildApiNotifyException,
|
||||
buildApiWallpaper, buildApiSession, buildPrivacyRules, buildApiNotifyException, buildApiCountryList,
|
||||
} from '../apiBuilders/misc';
|
||||
|
||||
import { buildApiUser } from '../apiBuilders/users';
|
||||
@ -17,9 +17,9 @@ import { buildInputPrivacyKey, buildInputPeer, buildInputEntity } from '../gramj
|
||||
import { invokeRequest, uploadFile, getClient } from './client';
|
||||
import { omitVirtualClassFields } from '../apiBuilders/helpers';
|
||||
import { buildCollectionByKey } from '../../../util/iteratees';
|
||||
import localDb from '../localDb';
|
||||
import { getServerTime } from '../../../util/serverTime';
|
||||
import { buildApiPeerId, getApiChatIdFromMtpPeer } from '../apiBuilders/peers';
|
||||
import localDb from '../localDb';
|
||||
|
||||
const MAX_INT_32 = 2 ** 31 - 1;
|
||||
const BETA_LANG_CODES = ['ar', 'fa', 'id', 'ko', 'uz'];
|
||||
@ -447,3 +447,14 @@ function updateLocalDb(
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export async function fetchCountryList({ langCode = 'en' }: { langCode?: LangCode }) {
|
||||
const countryList = await invokeRequest(new GramJs.help.GetCountriesList({
|
||||
langCode,
|
||||
}));
|
||||
|
||||
if (!(countryList instanceof GramJs.help.CountriesList)) {
|
||||
return undefined;
|
||||
}
|
||||
return buildApiCountryList(countryList.countries);
|
||||
}
|
||||
|
||||
@ -3,7 +3,6 @@ import { Api as GramJs } from '../../../lib/gramjs';
|
||||
import {
|
||||
OnApiUpdate, ApiUser, ApiChat, ApiPhoto,
|
||||
} from '../../types';
|
||||
import { LangCode } from '../../../types';
|
||||
|
||||
import { PROFILE_PHOTOS_LIMIT } from '../../../config';
|
||||
import { invokeRequest } from './client';
|
||||
@ -18,7 +17,6 @@ import { buildApiChatFromPreview } from '../apiBuilders/chats';
|
||||
import { buildApiPhoto } from '../apiBuilders/common';
|
||||
import localDb from '../localDb';
|
||||
import { addPhotoToLocalDb } from '../helpers';
|
||||
import { buildApiCountryList } from '../apiBuilders/misc';
|
||||
import { buildApiPeerId } from '../apiBuilders/peers';
|
||||
|
||||
let onUpdate: OnApiUpdate;
|
||||
@ -62,17 +60,6 @@ export async function fetchNearestCountry() {
|
||||
return dcInfo?.country;
|
||||
}
|
||||
|
||||
export async function fetchCountryList({ langCode = 'en' }: { langCode?: LangCode }) {
|
||||
const countryList = await invokeRequest(new GramJs.help.GetCountriesList({
|
||||
langCode,
|
||||
}));
|
||||
|
||||
if (!(countryList instanceof GramJs.help.CountriesList)) {
|
||||
return undefined;
|
||||
}
|
||||
return buildApiCountryList(countryList.countries);
|
||||
}
|
||||
|
||||
export async function fetchTopUsers() {
|
||||
const topPeers = await invokeRequest(new GramJs.contacts.GetTopPeers({
|
||||
correspondents: true,
|
||||
|
||||
@ -132,10 +132,11 @@ const SettingsGeneral: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
setSettingOption({ messageTextSize: newSize });
|
||||
}, [setSettingOption]);
|
||||
|
||||
const handleTimeFormatChange = useCallback((value: string) => {
|
||||
setTimeFormat(value as TimeFormat, () => {
|
||||
setSettingOption({ timeFormat: value });
|
||||
});
|
||||
const handleTimeFormatChange = useCallback((newTimeFormat: string) => {
|
||||
setSettingOption({ timeFormat: newTimeFormat });
|
||||
setSettingOption({ wasTimeFormatSetManually: true });
|
||||
|
||||
setTimeFormat(newTimeFormat as TimeFormat);
|
||||
}, [setSettingOption]);
|
||||
|
||||
const handleStickerSetClick = useCallback((value: ApiSticker) => {
|
||||
|
||||
@ -48,7 +48,6 @@ import StickerSetModal from '../common/StickerSetModal.async';
|
||||
import './Main.scss';
|
||||
|
||||
type StateProps = {
|
||||
animationLevel: number;
|
||||
lastSyncTime?: number;
|
||||
isLeftColumnShown: boolean;
|
||||
isRightColumnShown: boolean;
|
||||
@ -61,14 +60,17 @@ type StateProps = {
|
||||
safeLinkModalUrl?: string;
|
||||
isHistoryCalendarOpen: boolean;
|
||||
shouldSkipHistoryAnimations?: boolean;
|
||||
language?: LangCode;
|
||||
openedStickerSetShortName?: string;
|
||||
isServiceChatReady?: boolean;
|
||||
animationLevel: number;
|
||||
language?: LangCode;
|
||||
wasTimeFormatSetManually?: boolean;
|
||||
};
|
||||
|
||||
type DispatchProps = Pick<GlobalActions, (
|
||||
'loadAnimatedEmojis' | 'loadNotificationSettings' | 'loadNotificationExceptions' | 'updateIsOnline' |
|
||||
'loadTopInlineBots' | 'loadEmojiKeywords' | 'openStickerSetShortName' | 'loadCountryList' | 'checkVersionNotification'
|
||||
'loadTopInlineBots' | 'loadEmojiKeywords' | 'openStickerSetShortName' |
|
||||
'loadCountryList' | 'ensureTimeFormat' | 'checkVersionNotification'
|
||||
)>;
|
||||
|
||||
const NOTIFICATION_INTERVAL = 1000;
|
||||
@ -84,7 +86,6 @@ const Main: FC<StateProps & DispatchProps> = ({
|
||||
isRightColumnShown,
|
||||
isMediaViewerOpen,
|
||||
isForwardModalOpen,
|
||||
animationLevel,
|
||||
hasNotifications,
|
||||
hasDialogs,
|
||||
audioMessage,
|
||||
@ -92,9 +93,11 @@ const Main: FC<StateProps & DispatchProps> = ({
|
||||
safeLinkModalUrl,
|
||||
isHistoryCalendarOpen,
|
||||
shouldSkipHistoryAnimations,
|
||||
language,
|
||||
openedStickerSetShortName,
|
||||
isServiceChatReady,
|
||||
animationLevel,
|
||||
language,
|
||||
wasTimeFormatSetManually,
|
||||
loadAnimatedEmojis,
|
||||
loadNotificationSettings,
|
||||
loadNotificationExceptions,
|
||||
@ -102,6 +105,7 @@ const Main: FC<StateProps & DispatchProps> = ({
|
||||
loadTopInlineBots,
|
||||
loadEmojiKeywords,
|
||||
loadCountryList,
|
||||
ensureTimeFormat,
|
||||
openStickerSetShortName,
|
||||
checkVersionNotification,
|
||||
}) => {
|
||||
@ -138,6 +142,12 @@ const Main: FC<StateProps & DispatchProps> = ({
|
||||
}
|
||||
}, [lastSyncTime, isServiceChatReady, checkVersionNotification]);
|
||||
|
||||
useEffect(() => {
|
||||
if (lastSyncTime && !wasTimeFormatSetManually) {
|
||||
ensureTimeFormat();
|
||||
}
|
||||
}, [lastSyncTime, wasTimeFormatSetManually, ensureTimeFormat]);
|
||||
|
||||
useEffect(() => {
|
||||
if (lastSyncTime && LOCATION_HASH.startsWith('#?tgaddr=')) {
|
||||
processDeepLink(decodeURIComponent(LOCATION_HASH.substr('#?tgaddr='.length)));
|
||||
@ -291,13 +301,13 @@ function updatePageTitle(nextTitle: string) {
|
||||
|
||||
export default memo(withGlobal(
|
||||
(global): StateProps => {
|
||||
const { settings: { byKey: { animationLevel, language, wasTimeFormatSetManually } } } = global;
|
||||
const { chatId: audioChatId, messageId: audioMessageId, origin } = global.audioPlayer;
|
||||
const audioMessage = audioChatId && audioMessageId
|
||||
? selectChatMessage(global, audioChatId, audioMessageId)
|
||||
: undefined;
|
||||
|
||||
return {
|
||||
animationLevel: global.settings.byKey.animationLevel,
|
||||
lastSyncTime: global.lastSyncTime,
|
||||
isLeftColumnShown: global.isLeftColumnShown,
|
||||
isRightColumnShown: selectIsRightColumnShown(global),
|
||||
@ -310,13 +320,16 @@ export default memo(withGlobal(
|
||||
safeLinkModalUrl: global.safeLinkModalUrl,
|
||||
isHistoryCalendarOpen: Boolean(global.historyCalendarSelectedAt),
|
||||
shouldSkipHistoryAnimations: global.shouldSkipHistoryAnimations,
|
||||
language: global.settings.byKey.language,
|
||||
openedStickerSetShortName: global.openedStickerSetShortName,
|
||||
isServiceChatReady: selectIsServiceChatReady(global),
|
||||
animationLevel,
|
||||
language,
|
||||
wasTimeFormatSetManually,
|
||||
};
|
||||
},
|
||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
||||
'loadAnimatedEmojis', 'loadNotificationSettings', 'loadNotificationExceptions', 'updateIsOnline',
|
||||
'loadTopInlineBots', 'loadEmojiKeywords', 'openStickerSetShortName', 'loadCountryList', 'checkVersionNotification',
|
||||
'loadTopInlineBots', 'loadEmojiKeywords', 'openStickerSetShortName', 'loadCountryList', 'ensureTimeFormat',
|
||||
'checkVersionNotification',
|
||||
]),
|
||||
)(Main));
|
||||
|
||||
@ -145,6 +145,9 @@ export const RE_MENTION_TEMPLATE = '(@[\\w\\d_-]+)';
|
||||
export const RE_TG_LINK = /^tg:(\/\/)?([?=&\d\w_-]+)?/gm;
|
||||
export const RE_TME_LINK = /^(?:https?:\/\/)?(?:t\.me\/)/gm;
|
||||
|
||||
// eslint-disable-next-line max-len
|
||||
export const COUNTRIES_WITH_12H_TIME_FORMAT = new Set(['AU', 'BD', 'CA', 'CO', 'EG', 'HN', 'IE', 'IN', 'JO', 'MX', 'MY', 'NI', 'NZ', 'PH', 'PK', 'SA', 'SV', 'US']);
|
||||
|
||||
// MTProto constants
|
||||
export const SERVICE_NOTIFICATIONS_USER_ID = '777000';
|
||||
export const REPLIES_USER_ID = '1271266957'; // TODO For Test connection ID must be equal to 708513
|
||||
|
||||
@ -149,6 +149,7 @@ export const INITIAL_STATE: GlobalState = {
|
||||
shouldLoopStickers: true,
|
||||
language: 'en',
|
||||
timeFormat: '24h',
|
||||
wasTimeFormatSetManually: false,
|
||||
},
|
||||
themes: {
|
||||
light: {
|
||||
|
||||
@ -500,7 +500,7 @@ export type ActionTypes = (
|
||||
'togglePreHistoryHidden' | 'updateChatDefaultBannedRights' | 'updateChatMemberBannedRights' | 'updateChatAdmin' |
|
||||
'acceptInviteConfirmation' |
|
||||
// users
|
||||
'loadFullUser' | 'openUserInfo' | 'loadNearestCountry' | 'loadCountryList' | 'loadTopUsers' | 'loadContactList' |
|
||||
'loadFullUser' | 'openUserInfo' | 'loadNearestCountry' | 'loadTopUsers' | 'loadContactList' |
|
||||
'loadCurrentUser' | 'updateProfile' | 'checkUsername' | 'addContact' | 'updateContact' |
|
||||
'deleteUser' | 'loadUser' | 'setUserSearchQuery' |
|
||||
// Channel / groups creation
|
||||
@ -523,11 +523,13 @@ export type ActionTypes = (
|
||||
// bots
|
||||
'clickInlineButton' | 'sendBotCommand' | 'loadTopInlineBots' | 'queryInlineBot' | 'sendInlineBotResult' |
|
||||
'resetInlineBot' | 'restartBot' | 'startBot' |
|
||||
// misc
|
||||
// media viewer & audio player
|
||||
'openMediaViewer' | 'closeMediaViewer' | 'openAudioPlayer' | 'setAudioPlayerVolume' | 'closeAudioPlayer' |
|
||||
// misc
|
||||
'openPollModal' | 'closePollModal' | 'loadWebPagePreview' | 'clearWebPagePreview' |
|
||||
'loadWallpapers' | 'uploadWallpaper' | 'setDeviceToken' | 'deleteDeviceToken' |
|
||||
'checkVersionNotification' | 'createServiceNotification' |
|
||||
'loadCountryList' | 'ensureTimeFormat' |
|
||||
// payment
|
||||
'openPaymentModal' | 'closePaymentModal' | 'addPaymentError' |
|
||||
'validateRequestedInfo' | 'setPaymentStep' | 'sendPaymentForm' | 'getPaymentForm' | 'getReceipt' |
|
||||
|
||||
@ -182,21 +182,6 @@ addReducer('loadNearestCountry', (global) => {
|
||||
})();
|
||||
});
|
||||
|
||||
addReducer('loadCountryList', (global, actions, payload = {}) => {
|
||||
let { langCode } = payload;
|
||||
if (!langCode) langCode = global.settings.byKey.language;
|
||||
|
||||
(async () => {
|
||||
const countryList = await callApi('fetchCountryList', { langCode });
|
||||
if (!countryList) return;
|
||||
|
||||
setGlobal({
|
||||
...getGlobal(),
|
||||
countryList,
|
||||
});
|
||||
})();
|
||||
});
|
||||
|
||||
addReducer('setDeviceToken', (global, actions, deviceToken) => {
|
||||
setGlobal({
|
||||
...global,
|
||||
|
||||
@ -6,9 +6,11 @@ import {
|
||||
UPLOADING_WALLPAPER_SLUG,
|
||||
} from '../../../types';
|
||||
|
||||
import { 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 { selectUser } from '../../selectors';
|
||||
import {
|
||||
addUsers, addBlockedContact, updateChats, updateUser, removeBlockedContact, replaceSettings, updateNotifySettings,
|
||||
@ -564,3 +566,39 @@ addReducer('updateContentSettings', (global, actions, payload) => {
|
||||
}
|
||||
})();
|
||||
});
|
||||
|
||||
addReducer('loadCountryList', (global, actions, payload = {}) => {
|
||||
let { langCode } = payload;
|
||||
if (!langCode) langCode = global.settings.byKey.language;
|
||||
|
||||
(async () => {
|
||||
const countryList = await callApi('fetchCountryList', { langCode });
|
||||
if (!countryList) return;
|
||||
|
||||
setGlobal({
|
||||
...getGlobal(),
|
||||
countryList,
|
||||
});
|
||||
})();
|
||||
});
|
||||
|
||||
addReducer('ensureTimeFormat', (global, actions) => {
|
||||
if (global.authNearestCountry) {
|
||||
const timeFormat = COUNTRIES_WITH_12H_TIME_FORMAT.has(global.authNearestCountry.toUpperCase()) ? '12h' : '24h';
|
||||
actions.setSettingOption({ timeFormat });
|
||||
setTimeFormat(timeFormat);
|
||||
}
|
||||
|
||||
(async () => {
|
||||
if (getGlobal().settings.byKey.wasTimeFormatSetManually) {
|
||||
return;
|
||||
}
|
||||
|
||||
const nearestCountryCode = await callApi('fetchNearestCountry');
|
||||
if (nearestCountryCode) {
|
||||
const timeFormat = COUNTRIES_WITH_12H_TIME_FORMAT.has(nearestCountryCode.toUpperCase()) ? '12h' : '24h';
|
||||
actions.setSettingOption({ timeFormat });
|
||||
setTimeFormat(timeFormat);
|
||||
}
|
||||
})();
|
||||
});
|
||||
|
||||
@ -70,6 +70,7 @@ export interface ISettings extends NotifySettings, Record<string, any> {
|
||||
isSensitiveEnabled?: boolean;
|
||||
canChangeSensitive?: boolean;
|
||||
timeFormat: TimeFormat;
|
||||
wasTimeFormatSetManually: boolean;
|
||||
}
|
||||
|
||||
export interface ApiPrivacySettings {
|
||||
|
||||
@ -139,22 +139,14 @@ export async function setLanguage(langCode: LangCode, callback?: NoneToVoidFunct
|
||||
runCallbacks();
|
||||
}
|
||||
|
||||
export function setTimeFormat(timeFormat: TimeFormat, callback?: NoneToVoidFunction) {
|
||||
export function setTimeFormat(timeFormat: TimeFormat) {
|
||||
if (timeFormat && timeFormat === currentTimeFormat) {
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
currentTimeFormat = timeFormat;
|
||||
getTranslation.timeFormat = timeFormat;
|
||||
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
|
||||
runCallbacks();
|
||||
}
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ export function getCountryCodesByIso(phoneCodeList: ApiCountryCode[], iso: strin
|
||||
return phoneCodeList.filter((country) => country.iso2 === iso);
|
||||
}
|
||||
|
||||
export function getCountryFromPhoneNumber(phoneCodeList: ApiCountryCode[], input: string = '') {
|
||||
export function getCountryFromPhoneNumber(phoneCodeList: ApiCountryCode[], input = '') {
|
||||
let phoneNumber = input.replace(/[^\d+]+/g, '');
|
||||
if (phoneNumber.startsWith('+')) {
|
||||
phoneNumber = phoneNumber.substr(1);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user