More translations

This commit is contained in:
morethanwords 2021-03-26 21:49:29 +04:00
parent bb1ea43c9b
commit b0d742932e
10 changed files with 142 additions and 67 deletions

View File

@ -23,6 +23,7 @@ import Scrollable, { ScrollableX } from "./scrollable";
import { wrapDocument, wrapPhoto, wrapVideo } from "./wrappers";
import useHeavyAnimationCheck, { getHeavyAnimationPromise } from "../hooks/useHeavyAnimationCheck";
import { isSafari } from "../helpers/userAgent";
import { LangPackKey, i18n } from "../lib/langPack";
//const testScroll = false;
@ -83,7 +84,7 @@ export default class AppSearchSuper {
public goingHard: Partial<{[type in MyInputMessagesFilter]: {scrollTop: number, scrollHeight: number}}> = {};
constructor(public types: {inputFilter: SearchSuperType, name: string}[], public scrollable: Scrollable, public searchGroups?: {[group in SearchGroupType]: SearchGroup}, public asChatList = false, public groupByMonth = true) {
constructor(public types: {inputFilter: SearchSuperType, name: LangPackKey, type: string}[], public scrollable: Scrollable, public searchGroups?: {[group in SearchGroupType]: SearchGroup}, public asChatList = false, public groupByMonth = true) {
this.container = document.createElement('div');
this.container.classList.add('search-super');
@ -104,7 +105,7 @@ export default class AppSearchSuper {
const span = document.createElement('span');
const i = document.createElement('i');
span.innerText = type.name;
span.append(i18n(type.name));
span.append(i);
menuTab.append(span);
@ -119,10 +120,10 @@ export default class AppSearchSuper {
for(const type of types) {
const container = document.createElement('div');
container.classList.add('search-super-container-' + type.name.toLowerCase()/* , 'scrollable', 'scrollable-y' */);
container.classList.add('search-super-container-' + type.type/* , 'scrollable', 'scrollable-y' */);
const content = document.createElement('div');
content.classList.add('search-super-content-' + type.name.toLowerCase()/* , 'scrollable', 'scrollable-y' */);
content.classList.add('search-super-content-' + type.type/* , 'scrollable', 'scrollable-y' */);
//content.style.overflowY = 'hidden';
/* container.style.overflow = 'visible';

View File

@ -190,14 +190,14 @@ export default class ChatTopbar {
verify: () => mediaSizes.isMobile
}, */ {
icon: 'mute',
text: 'Mute',
text: 'ChatList.Context.Mute',
onClick: () => {
this.appMessagesManager.mutePeer(this.peerId);
},
verify: () => this.chat.type === 'chat' && rootScope.myId !== this.peerId && !this.appNotificationsManager.isPeerLocalMuted(this.peerId, false)
}, {
icon: 'unmute',
text: 'Unmute',
text: 'ChatList.Context.Unmute',
onClick: () => {
this.appMessagesManager.mutePeer(this.peerId);
},

View File

@ -61,6 +61,7 @@ export enum InputState {
export type InputFieldOptions = {
placeholder?: LangPackKey,
label?: LangPackKey,
labelOptions?: any[],
name?: string,
maxLength?: number,
showLengthOn?: number,
@ -147,7 +148,7 @@ class InputField {
if(label) {
this.label = document.createElement('label');
this.label.append(i18n(label));
this.label.append(i18n(label, options.labelOptions));
this.container.append(this.label);
}
@ -168,11 +169,11 @@ class InputField {
if(isError || diff <= showLengthOn) {
labelEl.innerHTML = '';
labelEl.append(i18n(label), ` (${maxLength - inputLength})`);
labelEl.append(i18n(label, options.labelOptions), ` (${maxLength - inputLength})`);
if(!showingLength) showingLength = true;
} else if((wasError && !isError) || showingLength) {
labelEl.innerHTML = '';
labelEl.append(i18n(label));
labelEl.append(i18n(label, options.labelOptions));
showingLength = false;
}
};
@ -242,8 +243,8 @@ class InputField {
public setState(state: InputState, label?: LangPackKey) {
if(label) {
this.label.innerHTML = '';
this.label.append(i18n(label));
this.label.textContent = '';
this.label.append(i18n(label, this.options.labelOptions));
}
this.input.classList.toggle('error', !!(state & InputState.Error));

View File

@ -9,6 +9,7 @@ import Scrollable from "../scrollable";
import { toast } from "../toast";
import SendContextMenu from "../chat/sendContextMenu";
import { MessageEntity } from "../../layer";
import I18n, { _i18n, i18n } from "../../lib/langPack";
const MAX_LENGTH_QUESTION = 255;
const MAX_LENGTH_OPTION = 100;
@ -26,19 +27,26 @@ export default class PopupCreatePoll extends PopupElement {
private correctAnswers: Uint8Array[];
private quizSolutionField: InputField;
private optionInputFields: InputField[];
constructor(private chat: Chat) {
super('popup-create-poll popup-new-media', null, {closable: true, withConfirm: 'CREATE', body: true});
super('popup-create-poll popup-new-media', null, {closable: true, withConfirm: 'NewPoll.Create', body: true});
this.title.innerText = 'New Poll';
_i18n(this.title, 'NewPoll');
this.questionInputField = new InputField({
placeholder: 'Ask a Question',
label: 'Ask a Question',
placeholder: 'AskAQuestion',
label: 'AskAQuestion',
name: 'question',
maxLength: MAX_LENGTH_QUESTION
});
this.questionInputField.input.addEventListener('input', () => {
this.handleChange();
});
this.optionInputFields = [];
if(this.chat.type !== 'scheduled') {
const sendMenu = new SendContextMenu({
onSilentClick: () => {
@ -64,7 +72,7 @@ export default class PopupCreatePoll extends PopupElement {
const hr = document.createElement('hr');
const d = document.createElement('div');
d.classList.add('caption');
d.innerText = 'Options';
_i18n(d, 'PollOptions');
this.questions = document.createElement('form');
this.questions.classList.add('poll-create-questions');
@ -74,11 +82,11 @@ export default class PopupCreatePoll extends PopupElement {
const settingsCaption = document.createElement('div');
settingsCaption.classList.add('caption');
settingsCaption.innerText = 'Settings';
_i18n(settingsCaption, 'Settings');
if(!this.chat.appPeersManager.isBroadcast(this.chat.peerId)) {
this.anonymousCheckboxField = new CheckboxField({
text: 'Anonymous Voting',
text: 'NewPoll.Anonymous',
name: 'anonymous'
});
this.anonymousCheckboxField.input.checked = true;
@ -86,11 +94,11 @@ export default class PopupCreatePoll extends PopupElement {
}
this.multipleCheckboxField = new CheckboxField({
text: 'Multiple Answers',
text: 'NewPoll.MultipleChoice',
name: 'multiple'
});
this.quizCheckboxField = new CheckboxField({
text: 'Quiz Mode',
text: 'NewPoll.Quiz',
name: 'quiz'
});
@ -106,9 +114,15 @@ export default class PopupCreatePoll extends PopupElement {
el.classList.toggle('radio-field', checked);
});
if(!checked) {
this.correctAnswers = undefined;
this.quizSolutionField.setValueSilently('');
}
quizElements.forEach(el => el.classList.toggle('hide', !checked));
this.multipleCheckboxField.input.toggleAttribute('disabled', checked);
this.handleChange();
});
dd.append(this.multipleCheckboxField.label, this.quizCheckboxField.label);
@ -117,7 +131,7 @@ export default class PopupCreatePoll extends PopupElement {
const quizSolutionCaption = document.createElement('div');
quizSolutionCaption.classList.add('caption');
quizSolutionCaption.innerText = 'Explanation';
_i18n(quizSolutionCaption, 'AccDescrQuizExplanation');
const quizHr = document.createElement('hr');
@ -125,15 +139,19 @@ export default class PopupCreatePoll extends PopupElement {
quizSolutionContainer.classList.add('poll-create-questions');
this.quizSolutionField = new InputField({
placeholder: 'Add a Comment (Optional)',
label: 'Add a Comment (Optional)',
placeholder: 'NewPoll.Explanation.Placeholder',
label: 'NewPoll.Explanation.Placeholder',
name: 'solution',
maxLength: MAX_LENGTH_SOLUTION
});
this.questionInputField.input.addEventListener('input', () => {
this.handleChange();
});
const quizSolutionSubtitle = document.createElement('div');
quizSolutionSubtitle.classList.add('subtitle');
quizSolutionSubtitle.innerText = 'Users will see this comment after choosing a wrong answer, good for educational purposes.';
_i18n(quizSolutionSubtitle, 'AddAnExplanationInfo');
quizSolutionContainer.append(this.quizSolutionField.container, quizSolutionSubtitle);
@ -151,6 +169,8 @@ export default class PopupCreatePoll extends PopupElement {
this.onEscape = () => {
return !this.getFilledAnswers().length;
};
this.handleChange();
}
private getFilledAnswers() {
@ -166,44 +186,52 @@ export default class PopupCreatePoll extends PopupElement {
this.send();
};
public send(force = false) {
private validate() {
const question = this.questionInputField.value;
if(!question) {
toast('Please enter a question.');
return;
return false;
}
if(question.length > MAX_LENGTH_QUESTION) {
toast('Question is too long.');
return;
return false;
}
if(this.quizCheckboxField.input.checked && !this.correctAnswers?.length) {
toast('Please choose the correct answer.');
return;
return false;
}
const answers = this.getFilledAnswers();
if(answers.length < 2) {
toast('Please enter at least two options.');
return;
return false;
}
const tooLongOption = answers.find(a => a.length > MAX_LENGTH_OPTION);
if(tooLongOption) {
toast('Option is too long.');
return;
return false;
}
const quizSolutionEntities: MessageEntity[] = [];
const quizSolution = getRichValue(this.quizSolutionField.input, quizSolutionEntities) || undefined;
if(quizSolution?.length > MAX_LENGTH_SOLUTION) {
toast('Explanation is too long.');
return;
return false;
}
return true;
}
private handleChange() {
const valid = this.validate();
this.btnConfirm.toggleAttribute('disabled', !valid);
}
public send(force = false) {
const question = this.questionInputField.value;
const answers = this.getFilledAnswers();
const quizSolutionEntities: MessageEntity[] = [];
const quizSolution = getRichValue(this.quizSolutionField.input, quizSolutionEntities) || undefined;
if(this.chat.type === 'scheduled' && !force) {
this.chat.input.scheduleSending(() => {
this.send(true);
@ -280,24 +308,39 @@ export default class PopupCreatePoll extends PopupElement {
if(isLast && !isEmpty && this.questions.childElementCount < 10) {
this.appendMoreField();
}
this.handleChange();
};
onDeleteClick = (e: MouseEvent) => {
const target = e.target as HTMLSpanElement;
findUpTag(target, 'LABEL').remove();
const label = findUpTag(target, 'LABEL');
const idx = whichChild(label);
Array.from(this.questions.children).forEach((el, idx) => {
const label = el.querySelector('label') as HTMLLabelElement;
label.innerText = 'Option ' + (idx + 1);
if(this.correctAnswers && this.correctAnswers[0][0] === idx) {
this.correctAnswers = undefined;
}
label.remove();
this.optionInputFields.splice(idx, 1);
this.optionInputFields.forEach((inputField, idx) => {
inputField.options.labelOptions.length = 0;
inputField.options.labelOptions.push(idx + 1);
const i18nElement = I18n.weakMap.get(inputField.label.firstElementChild as HTMLElement);
i18nElement.update();
});
this.handleChange();
};
private appendMoreField() {
const tempId = this.tempId++;
const idx = this.questions.childElementCount + 1;
const questionField = new InputField({
placeholder: 'Add an Option',
label: 'Option ' + idx,
placeholder: 'NewPoll.OptionsAddOption',
label: 'NewPoll.OptionLabel',
labelOptions: [idx],
name: 'question-' + tempId,
maxLength: MAX_LENGTH_OPTION
});
@ -319,6 +362,7 @@ export default class PopupCreatePoll extends PopupElement {
if(checked) {
const idx = whichChild(radioField.label);
this.correctAnswers = [new Uint8Array([idx])];
this.handleChange();
}
});
@ -332,5 +376,7 @@ export default class PopupCreatePoll extends PopupElement {
this.scrollable.scrollIntoViewNew(this.questions.lastElementChild as HTMLElement, 'center');
//this.scrollable.scrollTo(this.scrollable.scrollHeight, 'top', true, true);
this.optionInputFields.push(questionField);
}
}
}

View File

@ -181,22 +181,28 @@ export class AppSidebarLeft extends SidebarSlider {
const searchSuper = this.searchSuper = new AppSearchSuper([{
inputFilter: 'inputMessagesFilterEmpty',
name: 'Chats'
name: 'FilterChats',
type: 'chats'
}, {
inputFilter: 'inputMessagesFilterPhotoVideo',
name: 'Media'
name: 'SharedMediaTab2',
type: 'media'
}, {
inputFilter: 'inputMessagesFilterUrl',
name: 'Links'
name: 'SharedLinksTab2',
type: 'links'
}, {
inputFilter: 'inputMessagesFilterDocument',
name: 'Files'
name: 'SharedFilesTab2',
type: 'files'
}, {
inputFilter: 'inputMessagesFilterMusic',
name: 'Music'
name: 'SharedMusicTab2',
type: 'music'
}, {
inputFilter: 'inputMessagesFilterVoice',
name: 'Voice'
name: 'SharedVoiceTab2',
type: 'voice'
}], scrollable, this.searchGroups, true);
searchContainer.prepend(searchSuper.nav.parentElement.parentElement);

View File

@ -49,9 +49,6 @@ export default class AppChatFoldersTab extends SliderSuperTab {
else if(pFlags.groups) k = 'FilterAllGroups';
else if(pFlags.broadcasts) k = 'FilterAllChannels';
else if(pFlags.bots) k = 'FilterAllBots';
else if(pFlags.exclude_muted) k = 'FilterAllUnmuted';
else if(pFlags.exclude_read) k = 'FilterAllUnread';
else if(pFlags.exclude_archived) k = 'FilterAllUnarchived';
d.push(i18n(k));
} else {
const folder = appMessagesManager.dialogsStorage.getFolder(filter.id);

View File

@ -194,16 +194,20 @@ export default class AppSharedMediaTab implements SliderTab {
this.searchSuper = new AppSearchSuper([{
inputFilter: 'inputMessagesFilterPhotoVideo',
name: 'Media'
name: 'SharedMediaTab2',
type: 'media'
}, {
inputFilter: 'inputMessagesFilterDocument',
name: 'Files'
name: 'SharedFilesTab2',
type: 'files'
}, {
inputFilter: 'inputMessagesFilterUrl',
name: 'Links'
name: 'SharedLinksTab2',
type: 'links'
}, {
inputFilter: 'inputMessagesFilterMusic',
name: 'Music'
name: 'SharedMusicTab2',
type: 'music'
}], this.scroll/* , undefined, undefined, false */);
this.profileContentEl.append(this.searchSuper.container);

View File

@ -10,9 +10,6 @@ const lang = {
"FilterAllNonContacts": "All Non-Contacts",
"FilterAllChannels": "All Channels",
"FilterAllBots": "All Bots",
"FilterAllUnmuted": "All Unmuted",
"FilterAllUnread": "All Unread",
"FilterAllUnarchived": "All Unarchived",
"WordDelimiter": ", ",
"WordDelimiterLast": " and ",
"EditProfile.FirstNameLabel": "Name",
@ -48,6 +45,8 @@ const lang = {
"Notifications.Sound": "Notification Sound",
"Notifications.MessagePreview": "Message preview",
"NewPrivateChat": "New Private Chat",
"NewPoll.OptionLabel": "Option %d",
"NewPoll.Create": "CREATE",
"Message.Context.Selection.Copy": "Copy selected",
"Message.Context.Selection.Clear": "Clear selection",
"Message.Context.Selection.Delete": "Delete selected",
@ -222,6 +221,19 @@ const lang = {
"Caption": "Caption",
"Message": "Message",
"Poll": "Poll",
"SharedFilesTab2": "Files",
"SharedMediaTab2": "Media",
//"SharedMediaTabFull2": "Shared Media",
//"SharedGroupsTab2": "Groups",
"SharedLinksTab2": "Links",
"SharedMusicTab2": "Music",
"SharedVoiceTab2": "Voice",
//"SharedGIFsTab2": "GIFs",
"NewPoll": "New Poll",
"PollOptions": "Poll options",
"AskAQuestion": "Ask a Question",
"AddAnExplanationInfo": "Users will see this text after choosing the wrong answer, good for educational purposes.",
"AccDescrQuizExplanation": "Explanation",
// * macos
"AccountSettings.Filters": "Chat Folders",
@ -332,6 +344,11 @@ const lang = {
"Message.Context.Select": "Select",
"Message.Context.Pin": "Pin",
"Message.Context.Unpin": "Unpin",
"NewPoll.Anonymous": "Anonymous Voting",
"NewPoll.Explanation.Placeholder": "Add a Comment (Optional)",
"NewPoll.OptionsAddOption": "Add an Option",
"NewPoll.MultipleChoice": "Multiple Answers",
"NewPoll.Quiz": "Quiz Mode",
};
export default lang;

View File

@ -2665,11 +2665,10 @@ export class AppMessagesManager {
// this.log('message action:', action);
if((action as MessageAction.messageActionCustomAction).message) {
const richText = RichTextProcessor.wrapRichText((action as MessageAction.messageActionCustomAction).message, {noLinebreaks: true});
if(plain) {
return richText;
return RichTextProcessor.wrapPlainText(message.message);
} else {
element.innerHTML = richText;
element.innerHTML = RichTextProcessor.wrapRichText((action as MessageAction.messageActionCustomAction).message, {noLinebreaks: true});
return element;
}
} else {
@ -2723,7 +2722,7 @@ export class AppMessagesManager {
args.push(getNameDivHTML(message.fromId, plain));
}
args.push(plain ? action.title : RichTextProcessor.wrapEmojiText(action.title));
args.push(plain ? action.title : htmlToDocumentFragment(RichTextProcessor.wrapEmojiText(action.title)));
break;
}

View File

@ -452,6 +452,10 @@
&__filled {
background-color: #0089ff;
&:not(.progress-line__loaded) {
z-index: 1;
}
}
&__loaded {