Localization: Add more translations (#1112)
This commit is contained in:
parent
01933bfcb1
commit
d0dac76c8b
@ -94,7 +94,7 @@ const DeleteMessageModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
<p>{lang('lng_delete_for_me_chat_hint')}</p>
|
<p>{lang('lng_delete_for_me_chat_hint')}</p>
|
||||||
)}
|
)}
|
||||||
{willDeleteForAll && (
|
{willDeleteForAll && (
|
||||||
<p>{lang('lng_delete_for_everyone_hint')}</p>
|
<p>{lang('lng_delete_for_everyone_hint', 1, 'i')}</p>
|
||||||
)}
|
)}
|
||||||
{canDeleteForAll && (
|
{canDeleteForAll && (
|
||||||
<Button color="danger" className="confirm-dialog-button" isText onClick={handleDeleteMessageForAll}>
|
<Button color="danger" className="confirm-dialog-button" isText onClick={handleDeleteMessageForAll}>
|
||||||
|
|||||||
@ -65,24 +65,16 @@ const PinMessageModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
function renderModalHeader() {
|
|
||||||
return (
|
|
||||||
<div className="modal-header">
|
|
||||||
<h3 className="modal-title">{lang('PinMessageAlertTitle')}</h3>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderMessage() {
|
function renderMessage() {
|
||||||
if (isChannel) {
|
if (isChannel) {
|
||||||
return <p>{lang('PinMessageAlertChannel')}</p>;
|
return lang('PinMessageAlertChannel');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isGroup || isSuperGroup) {
|
if (isGroup || isSuperGroup) {
|
||||||
return <p>{lang('PinMessageAlert')}</p>;
|
return lang('PinMessageAlert');
|
||||||
}
|
}
|
||||||
|
|
||||||
return <p>{lang('PinMessageAlertChat')}</p>;
|
return lang('PinMessageAlertChat');
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -90,15 +82,17 @@ const PinMessageModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
className="pin"
|
className="pin"
|
||||||
header={renderModalHeader()}
|
title={lang('PinMessageAlertTitle')}
|
||||||
>
|
>
|
||||||
{renderMessage()}
|
<p>{renderMessage()}</p>
|
||||||
<Button className="confirm-dialog-button" isText onClick={handlePinMessage}>
|
<Button className="confirm-dialog-button" isText onClick={handlePinMessage}>
|
||||||
{lang('DialogPin')}
|
{lang('DialogPin')}
|
||||||
</Button>
|
</Button>
|
||||||
{canPinForAll && (
|
{canPinForAll && (
|
||||||
<Button className="confirm-dialog-button" isText onClick={handlePinMessageForAll}>
|
<Button className="confirm-dialog-button" isText onClick={handlePinMessageForAll}>
|
||||||
{contactName ? `Pin for me and ${contactName}` : 'Pin and notify all memebers'}
|
{contactName
|
||||||
|
? lang('Conversation.PinMessagesFor', contactName)
|
||||||
|
: lang('Conversation.PinMessageAlert.PinAndNotifyMembers')}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
<Button className="confirm-dialog-button" isText onClick={onClose}>{lang('Cancel')}</Button>
|
<Button className="confirm-dialog-button" isText onClick={onClose}>{lang('Cancel')}</Button>
|
||||||
|
|||||||
@ -78,7 +78,7 @@ const StickerSetModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
hasCloseButton
|
hasCloseButton
|
||||||
title={stickerSet ? stickerSet.title : 'Sticker Set'}
|
title={stickerSet ? stickerSet.title : lang('AccDescrStickerSet')}
|
||||||
>
|
>
|
||||||
{stickerSet && stickerSet.stickers ? (
|
{stickerSet && stickerSet.stickers ? (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
import React, { FC, memo } from '../../lib/teact/teact';
|
import React, { FC, memo } from '../../lib/teact/teact';
|
||||||
import { withGlobal } from '../../lib/teact/teactn';
|
|
||||||
|
|
||||||
import { selectPinnedIds } from '../../modules/selectors';
|
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
|
|
||||||
import Modal from '../ui/Modal';
|
import Modal from '../ui/Modal';
|
||||||
@ -10,42 +8,26 @@ import Button from '../ui/Button';
|
|||||||
export type OwnProps = {
|
export type OwnProps = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
chatId?: number;
|
chatId?: number;
|
||||||
|
pinnedMessagesCount?: number;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
onUnpin: () => void;
|
onUnpin: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
type StateProps = {
|
const UnpinAllMessagesModal: FC<OwnProps> = ({
|
||||||
pinnedMessagesCount: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
const UnpinAllMessagesModal: FC<OwnProps & StateProps> = ({
|
|
||||||
isOpen,
|
isOpen,
|
||||||
pinnedMessagesCount,
|
pinnedMessagesCount = 0,
|
||||||
onClose,
|
onClose,
|
||||||
onUnpin,
|
onUnpin,
|
||||||
}) => {
|
}) => {
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
function renderModalHeader() {
|
|
||||||
return (
|
|
||||||
<div className="modal-header">
|
|
||||||
<h3 className="modal-title">{lang('UnpinAllMessages')}</h3>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderMessage() {
|
|
||||||
return <p>Do you want to unpin all {pinnedMessagesCount} messages in this chat?</p>;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
className="unpin-all"
|
className="unpin-all"
|
||||||
header={renderModalHeader()}
|
title={lang('Chat.PanelUnpinAllMessages')}
|
||||||
>
|
>
|
||||||
{renderMessage()}
|
<p>{lang('Chat.UnpinAllMessagesConfirmation', pinnedMessagesCount, 'i')}</p>
|
||||||
<Button className="confirm-dialog-button" isText onClick={onUnpin}>
|
<Button className="confirm-dialog-button" isText onClick={onUnpin}>
|
||||||
{lang('DialogUnpin')}
|
{lang('DialogUnpin')}
|
||||||
</Button>
|
</Button>
|
||||||
@ -54,12 +36,4 @@ const UnpinAllMessagesModal: FC<OwnProps & StateProps> = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(withGlobal<OwnProps>(
|
export default memo(UnpinAllMessagesModal);
|
||||||
(global, { chatId }): StateProps => {
|
|
||||||
const pinnedIds = chatId ? selectPinnedIds(global, chatId) : [];
|
|
||||||
|
|
||||||
return {
|
|
||||||
pinnedMessagesCount: pinnedIds ? pinnedIds.length : 0,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
)(UnpinAllMessagesModal));
|
|
||||||
|
|||||||
@ -78,7 +78,7 @@ const DeleteSelectedMessagesModal: FC<OwnProps & StateProps & DispatchProps> = (
|
|||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
onEnter={canDeleteForAll ? undefined : handleDeleteMessageForSelf}
|
onEnter={canDeleteForAll ? undefined : handleDeleteMessageForSelf}
|
||||||
className="delete"
|
className="delete"
|
||||||
title="Delete Messages?"
|
title={lang('Conversation.DeleteManyMessages')}
|
||||||
>
|
>
|
||||||
<p>{lang('AreYouSureDeleteFewMessages')}</p>
|
<p>{lang('AreYouSureDeleteFewMessages')}</p>
|
||||||
{willDeleteForCurrentUserOnly && (
|
{willDeleteForCurrentUserOnly && (
|
||||||
@ -89,12 +89,13 @@ const DeleteSelectedMessagesModal: FC<OwnProps & StateProps & DispatchProps> = (
|
|||||||
)}
|
)}
|
||||||
{canDeleteForAll && (
|
{canDeleteForAll && (
|
||||||
<Button color="danger" className="confirm-dialog-button" isText onClick={handleDeleteMessageForAll}>
|
<Button color="danger" className="confirm-dialog-button" isText onClick={handleDeleteMessageForAll}>
|
||||||
Delete for {contactName ? 'me and ' : 'Everyone'}
|
{contactName
|
||||||
{contactName && renderText(contactName)}
|
? lang('ChatList.DeleteForEveryone', renderText(contactName))
|
||||||
|
: lang('Conversation.DeleteMessagesForEveryone')}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
<Button color="danger" className="confirm-dialog-button" isText onClick={handleDeleteMessageForSelf}>
|
<Button color="danger" className="confirm-dialog-button" isText onClick={handleDeleteMessageForSelf}>
|
||||||
Delete{canDeleteForAll ? ' just for me' : ''}
|
{lang(canDeleteForAll ? 'ChatList.DeleteForCurrentUser' : 'Delete')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button className="confirm-dialog-button" isText onClick={onClose}>{lang('Cancel')}</Button>
|
<Button className="confirm-dialog-button" isText onClick={onClose}>{lang('Cancel')}</Button>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|||||||
@ -58,6 +58,7 @@ type StateProps = {
|
|||||||
canPost?: boolean;
|
canPost?: boolean;
|
||||||
messageSendingRestrictionReason?: string;
|
messageSendingRestrictionReason?: string;
|
||||||
hasPinnedOrAudioMessage?: boolean;
|
hasPinnedOrAudioMessage?: boolean;
|
||||||
|
pinnedMessagesCount?: number;
|
||||||
customBackground?: string;
|
customBackground?: string;
|
||||||
patternColor?: string;
|
patternColor?: string;
|
||||||
isCustomBackgroundColor?: boolean;
|
isCustomBackgroundColor?: boolean;
|
||||||
@ -85,6 +86,7 @@ const MiddleColumn: FC<StateProps & DispatchProps> = ({
|
|||||||
canPost,
|
canPost,
|
||||||
messageSendingRestrictionReason,
|
messageSendingRestrictionReason,
|
||||||
hasPinnedOrAudioMessage,
|
hasPinnedOrAudioMessage,
|
||||||
|
pinnedMessagesCount,
|
||||||
customBackground,
|
customBackground,
|
||||||
patternColor,
|
patternColor,
|
||||||
isCustomBackgroundColor,
|
isCustomBackgroundColor,
|
||||||
@ -261,7 +263,7 @@ const MiddleColumn: FC<StateProps & DispatchProps> = ({
|
|||||||
onClick={handleOpenUnpinModal}
|
onClick={handleOpenUnpinModal}
|
||||||
>
|
>
|
||||||
<i className="icon-unpin" />
|
<i className="icon-unpin" />
|
||||||
<span>{lang('Chat.PanelHidePinnedMessages')}</span>
|
<span>{lang('Chat.Pinned.UnpinAll', pinnedMessagesCount, 'i')}</span>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -296,6 +298,7 @@ const MiddleColumn: FC<StateProps & DispatchProps> = ({
|
|||||||
<UnpinAllMessagesModal
|
<UnpinAllMessagesModal
|
||||||
isOpen={isUnpinModalOpen}
|
isOpen={isUnpinModalOpen}
|
||||||
chatId={chatId}
|
chatId={chatId}
|
||||||
|
pinnedMessagesCount={pinnedMessagesCount}
|
||||||
onClose={closeUnpinModal}
|
onClose={closeUnpinModal}
|
||||||
onUnpin={handleUnpinAllMessages}
|
onUnpin={handleUnpinAllMessages}
|
||||||
/>
|
/>
|
||||||
@ -350,6 +353,7 @@ export default memo(withGlobal(
|
|||||||
|| Boolean(pinnedIds && pinnedIds.length)
|
|| Boolean(pinnedIds && pinnedIds.length)
|
||||||
|| Boolean(audioChatId && audioMessageId)
|
|| Boolean(audioChatId && audioMessageId)
|
||||||
),
|
),
|
||||||
|
pinnedMessagesCount: pinnedIds ? pinnedIds.length : 0,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
(setGlobal, actions): DispatchProps => pick(actions, [
|
||||||
|
|||||||
@ -149,11 +149,11 @@ const AttachmentModal: FC<OwnProps> = ({
|
|||||||
|
|
||||||
let title = '';
|
let title = '';
|
||||||
if (areAllPhotos) {
|
if (areAllPhotos) {
|
||||||
title = renderingAttachments.length === 1 ? 'Send Photo' : `Send ${renderingAttachments.length} Photos`;
|
title = lang('PreviewSender.SendPhoto', renderingAttachments.length, 'i');
|
||||||
} else if (areAllVideos) {
|
} else if (areAllVideos) {
|
||||||
title = renderingAttachments.length === 1 ? 'Send Video' : `Send ${renderingAttachments.length} Videos`;
|
title = lang('PreviewSender.SendVideo', renderingAttachments.length, 'i');
|
||||||
} else {
|
} else {
|
||||||
title = renderingAttachments.length === 1 ? 'Send File' : `Send ${renderingAttachments.length} Files`;
|
title = lang('PreviewSender.SendFile', renderingAttachments.length, 'i');
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderHeader() {
|
function renderHeader() {
|
||||||
|
|||||||
@ -46,6 +46,8 @@ const PollModal: FC<OwnProps> = ({ isOpen, onSend, onClear }) => {
|
|||||||
const [correctOption, setCorrectOption] = useState<string>();
|
const [correctOption, setCorrectOption] = useState<string>();
|
||||||
const [hasErrors, setHasErrors] = useState<boolean>(false);
|
const [hasErrors, setHasErrors] = useState<boolean>(false);
|
||||||
|
|
||||||
|
const lang = useLang();
|
||||||
|
|
||||||
const focusInput = useCallback((ref: RefObject<HTMLInputElement>) => {
|
const focusInput = useCallback((ref: RefObject<HTMLInputElement>) => {
|
||||||
if (isOpen && ref.current) {
|
if (isOpen && ref.current) {
|
||||||
ref.current.focus();
|
ref.current.focus();
|
||||||
@ -206,21 +208,19 @@ const PollModal: FC<OwnProps> = ({ isOpen, onSend, onClear }) => {
|
|||||||
|
|
||||||
const getQuestionError = useCallback(() => {
|
const getQuestionError = useCallback(() => {
|
||||||
if (hasErrors && !question.trim().length) {
|
if (hasErrors && !question.trim().length) {
|
||||||
return 'Please enter the question';
|
return lang('lng_polls_choose_question');
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}, [hasErrors, question]);
|
}, [hasErrors, lang, question]);
|
||||||
|
|
||||||
const getOptionsError = useCallback((index: number) => {
|
const getOptionsError = useCallback((index: number) => {
|
||||||
const optionsTrimmed = options.map((o) => o.trim()).filter((o) => o.length);
|
const optionsTrimmed = options.map((o) => o.trim()).filter((o) => o.length);
|
||||||
if (hasErrors && optionsTrimmed.length < 2 && !options[index].trim().length) {
|
if (hasErrors && optionsTrimmed.length < 2 && !options[index].trim().length) {
|
||||||
return 'Please enter at least two options';
|
return lang('lng_polls_choose_answers');
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}, [hasErrors, options]);
|
}, [hasErrors, lang, options]);
|
||||||
|
|
||||||
const lang = useLang();
|
|
||||||
|
|
||||||
function renderHeader() {
|
function renderHeader() {
|
||||||
return (
|
return (
|
||||||
@ -246,8 +246,8 @@ const PollModal: FC<OwnProps> = ({ isOpen, onSend, onClear }) => {
|
|||||||
<div className="option-wrapper">
|
<div className="option-wrapper">
|
||||||
<InputText
|
<InputText
|
||||||
label={index !== options.length - 1 || options.length === MAX_OPTIONS_COUNT
|
label={index !== options.length - 1 || options.length === MAX_OPTIONS_COUNT
|
||||||
? `Option ${index + 1}`
|
? lang('OptionHint')
|
||||||
: 'Add an Option'}
|
: lang('CreatePoll.AddOption')}
|
||||||
error={getOptionsError(index)}
|
error={getOptionsError(index)}
|
||||||
value={option}
|
value={option}
|
||||||
onChange={(e) => updateOption(index, e.currentTarget.value)}
|
onChange={(e) => updateOption(index, e.currentTarget.value)}
|
||||||
@ -259,7 +259,7 @@ const PollModal: FC<OwnProps> = ({ isOpen, onSend, onClear }) => {
|
|||||||
round
|
round
|
||||||
color="translucent"
|
color="translucent"
|
||||||
size="smaller"
|
size="smaller"
|
||||||
ariaLabel="Remove option"
|
ariaLabel={lang('Delete')}
|
||||||
onClick={() => removeOption(index)}
|
onClick={() => removeOption(index)}
|
||||||
>
|
>
|
||||||
<i className="icon-close" />
|
<i className="icon-close" />
|
||||||
@ -278,9 +278,7 @@ const PollModal: FC<OwnProps> = ({ isOpen, onSend, onClear }) => {
|
|||||||
const optionsTrimmed = options.map((o) => o.trim()).filter((o) => o.length);
|
const optionsTrimmed = options.map((o) => o.trim()).filter((o) => o.length);
|
||||||
|
|
||||||
return isQuizMode && (!correctOption || !optionsTrimmed[Number(correctOption)]) && (
|
return isQuizMode && (!correctOption || !optionsTrimmed[Number(correctOption)]) && (
|
||||||
<p className="error">
|
<p className="error">{lang('lng_polls_choose_correct')}</p>
|
||||||
Please choose the correct answer
|
|
||||||
</p>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,9 +339,7 @@ const PollModal: FC<OwnProps> = ({ isOpen, onSend, onClear }) => {
|
|||||||
contentEditable
|
contentEditable
|
||||||
onChange={(e) => setSolution(e.currentTarget.innerHTML)}
|
onChange={(e) => setSolution(e.currentTarget.innerHTML)}
|
||||||
/>
|
/>
|
||||||
<div className="note">
|
<div className="note">{lang('CreatePoll.ExplanationInfo')}</div>
|
||||||
Users will see this comment after choosing a wrong answer, good for educational purposes.
|
|
||||||
</div>
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -167,12 +167,12 @@ const Invoice: FC<OwnProps & StateProps & GlobalStateProps & DispatchProps> = ({
|
|||||||
onClose={handleErrorModalClose}
|
onClose={handleErrorModalClose}
|
||||||
>
|
>
|
||||||
<h4>{error.description || 'Error'}</h4>
|
<h4>{error.description || 'Error'}</h4>
|
||||||
{error.description || 'Error'}
|
<p>{error.description || 'Error'}</p>
|
||||||
<Button
|
<Button
|
||||||
isText
|
isText
|
||||||
onClick={clearPaymentError}
|
onClick={clearPaymentError}
|
||||||
>
|
>
|
||||||
OK
|
{lang('OK')}
|
||||||
</Button>
|
</Button>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
@ -287,11 +287,11 @@ const Invoice: FC<OwnProps & StateProps & GlobalStateProps & DispatchProps> = ({
|
|||||||
const buttonText = useMemo(() => {
|
const buttonText = useMemo(() => {
|
||||||
switch (step) {
|
switch (step) {
|
||||||
case PaymentStep.Checkout:
|
case PaymentStep.Checkout:
|
||||||
return `Pay ${currencySign}${(totalPrice / 100).toFixed(2)}`;
|
return lang('Checkout.PayPrice', `${currencySign}${(totalPrice / 100).toFixed(2)}`);
|
||||||
default:
|
default:
|
||||||
return 'Next Step';
|
return lang('Next');
|
||||||
}
|
}
|
||||||
}, [step, totalPrice, currencySign]);
|
}, [step, lang, currencySign, totalPrice]);
|
||||||
|
|
||||||
if (isProviderError) {
|
if (isProviderError) {
|
||||||
return (
|
return (
|
||||||
@ -300,13 +300,15 @@ const Invoice: FC<OwnProps & StateProps & GlobalStateProps & DispatchProps> = ({
|
|||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
>
|
>
|
||||||
Sorry, Telegram T doesn't support payments with this provider yet.
|
<p>
|
||||||
Please use one of our mobile apps to do this.
|
Sorry, Telegram T doesn't support payments with this provider yet. <br />
|
||||||
|
Please use one of our mobile apps to do this.
|
||||||
|
</p>
|
||||||
<Button
|
<Button
|
||||||
isText
|
isText
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
>
|
>
|
||||||
OK
|
{lang('OK')}
|
||||||
</Button>
|
</Button>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
@ -329,7 +331,7 @@ const Invoice: FC<OwnProps & StateProps & GlobalStateProps & DispatchProps> = ({
|
|||||||
>
|
>
|
||||||
<i className="icon-close" />
|
<i className="icon-close" />
|
||||||
</Button>
|
</Button>
|
||||||
<h3>{ modalHeader }</h3>
|
<h3>{modalHeader}</h3>
|
||||||
</div>
|
</div>
|
||||||
{step !== undefined ? (
|
{step !== undefined ? (
|
||||||
<Transition name="slide" activeKey={step}>
|
<Transition name="slide" activeKey={step}>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user