settings: Remove language_list_dbl_col from page_params.

The language_list_dbl_col parameter in the page_params
is used by only the web client frontend. The value is
calculated in the backend and then passed as a page_param
which is unnecessary considering that the whole process
is beneficial for the front_end only. Hence move the entire
calculation code to the frontend.

Fixes part of #18673.
This commit is contained in:
Gaurav Pandey 2021-06-16 02:07:07 +05:30 committed by Tim Abbott
parent 56d85fb833
commit 8fc3715ea8
8 changed files with 151 additions and 53 deletions

View File

@ -2,6 +2,8 @@
const {strict: assert} = require("assert");
const _ = require("lodash");
const {unmock_module, zrequire} = require("../zjsunit/namespace");
const {run_test} = require("../zjsunit/test");
const {page_params} = require("../zjsunit/zpage_params");
@ -23,7 +25,7 @@ page_params.translation_data = {
// `i18n.js` initializes FormatJS and is imported by
// `templates.js`.
unmock_module("../../static/js/i18n");
const {$t, $t_html} = zrequire("i18n");
const {$t, $t_html, get_language_list_columns} = zrequire("i18n");
run_test("$t", () => {
// Normally the id would be provided by babel-plugin-formatjs, but
@ -104,3 +106,78 @@ run_test("tr_tag", () => {
const html = require("../../static/templates/settings_tab.hbs")(args);
assert.ok(html.indexOf("Déclencheurs de notification") > 0);
});
run_test("language_list", () => {
page_params.language_list = [
{
code: "en",
locale: "en",
name: "English",
},
{
code: "en-gb",
locale: "en_GB",
name: "British English",
percent_translated: 99,
},
{
code: "id",
locale: "id",
name: "Bahasa Indonesia",
percent_translated: 32,
},
];
const successful_formatted_list = [
{
first: {
name: "English",
code: "en",
name_with_percent: "English",
selected: true,
},
second: {
name: "Bahasa Indonesia",
code: "id",
name_with_percent: "Bahasa Indonesia (32%)",
selected: false,
},
},
{
first: {
name: "British English",
code: "en-gb",
name_with_percent: "British English (99%)",
selected: false,
},
},
];
const formatted_list = get_language_list_columns("en");
function check_value_match(element, position) {
assert.equal(
formatted_list[element][position].name,
successful_formatted_list[element][position].name,
);
assert.equal(
formatted_list[element][position].code,
successful_formatted_list[element][position].code,
);
assert.equal(
formatted_list[element][position].name_with_percent,
successful_formatted_list[element][position].name_with_percent,
);
assert.equal(
formatted_list[element][position].selected,
successful_formatted_list[element][position].selected,
);
}
for (const element of _.range(0, formatted_list.length)) {
check_value_match(element, "first");
if (formatted_list[element].second) {
check_value_match(element, "second");
}
}
});

View File

@ -43,3 +43,68 @@ export function $t_html(descriptor, values) {
),
});
}
// This formats language data for the language selection modal in a
// 2-column format.
export function get_language_list_columns(default_language) {
const language_list = [];
// Only render languages with percentage translation >= 5%
for (const language of page_params.language_list) {
if (language.percent_translated === undefined || language.percent_translated >= 5) {
language_list.push({
code: language.code,
locale: language.locale,
name: language.name,
percent_translated: language.percent_translated,
});
}
}
const formatted_list = [];
const language_len = language_list.length;
const firsts_end = Math.floor(language_len / 2) + (language_len % 2);
const firsts = _.range(0, firsts_end);
const seconds = _.range(firsts_end, language_len);
const longest_zip = [];
// Create a zip (itertool.zip_longest in python)
for (const value of firsts) {
longest_zip.push([value, seconds[value]]);
}
for (const row of longest_zip) {
const item = {};
const zip_row = [
["first", row[0]],
["second", row[1]],
];
for (const zip_value of zip_row) {
if (zip_value[1] !== undefined) {
const lang = language_list[zip_value[1]];
const name = lang.name;
let name_with_percent = name;
if (lang.percent_translated !== undefined) {
name_with_percent = name + " (" + lang.percent_translated + "%)";
}
let selected = false;
if (default_language === lang.code || default_language === lang.locale) {
selected = true;
}
item[zip_value[0]] = {
name,
code: lang.code,
name_with_percent,
selected,
};
}
}
formatted_list.push(item);
}
return formatted_list;
}

View File

@ -7,7 +7,7 @@ import render_settings_tab from "../templates/settings_tab.hbs";
import * as admin from "./admin";
import * as blueslip from "./blueslip";
import * as common from "./common";
import {$t, $t_html} from "./i18n";
import {$t, $t_html, get_language_list_columns} from "./i18n";
import * as overlays from "./overlays";
import {page_params} from "./page_params";
import * as people from "./people";
@ -113,6 +113,7 @@ export function build_page() {
user_can_change_avatar: settings_data.user_can_change_avatar(),
user_role_text: people.get_user_type(page_params.user_id),
default_language_name: settings_display.default_language_name,
language_list_dbl_col: get_language_list_columns(page_params.default_language),
});
$(".settings-box").html(rendered_settings_tab);

View File

@ -21,23 +21,23 @@
</p>
<div>
<table>
{{#each page_params.language_list_dbl_col}}
{{#each language_list}}
<tr>
<td>
<a class="language" data-code="{{this.first.code}}" data-name="{{this.first.name}}">
{{#if this.first.selected}}
<b>{{this.first.percent}}</b>
<b>{{this.first.name_with_percent}}</b>
{{else}}
{{this.first.percent}}
{{this.first.name_with_percent}}
{{/if}}
</a>
</td>
<td>
<a class="language" data-code="{{this.second.code}}" data-name="{{this.second.name}}">
{{#if this.second.selected}}
<b>{{this.second.percent}}</b>
<b>{{this.second.name_with_percent}}</b>
{{else}}
{{this.second.percent}}
{{this.second.name_with_percent}}
{{/if}}
</a>
</td>

View File

@ -14,7 +14,7 @@
</button>
</div>
{{> ../default_language_modal guidelines_link="https://zulip.readthedocs.io/en/latest/translating/translating.html"}}
{{> ../default_language_modal language_list=language_list_dbl_col guidelines_link="https://zulip.readthedocs.io/en/latest/translating/translating.html"}}
</div>
<div id="user-display-settings">

View File

@ -14,7 +14,6 @@ from zerver.lib.events import do_events_register
from zerver.lib.i18n import (
get_and_set_request_language,
get_language_list,
get_language_list_for_templates,
get_language_translation_data,
)
from zerver.lib.users import compute_show_invites_and_add_streams
@ -196,7 +195,6 @@ def build_page_params_for_home_page_load(
# Only show marketing email settings if on Zulip Cloud
corporate_enabled=settings.CORPORATE_ENABLED,
## Misc. extra data.
language_list_dbl_col=get_language_list_for_templates(register_ret["default_language"]),
language_list=get_language_list(),
needs_tutorial=needs_tutorial,
first_in_realm=first_in_realm,

View File

@ -1,10 +1,8 @@
# See https://zulip.readthedocs.io/en/latest/translating/internationalization.html
import logging
import operator
import os
from functools import lru_cache
from itertools import zip_longest
from typing import Any, Dict, List, Optional
import orjson
@ -21,46 +19,6 @@ def get_language_list() -> List[Dict[str, Any]]:
return languages["name_map"]
def get_language_list_for_templates(default_language: str) -> List[Dict[str, Dict[str, str]]]:
language_list = [
lang
for lang in get_language_list()
if "percent_translated" not in lang or lang["percent_translated"] >= 5.0
]
formatted_list = []
lang_len = len(language_list)
firsts_end = (lang_len // 2) + operator.mod(lang_len, 2)
firsts = list(range(0, firsts_end))
seconds = list(range(firsts_end, lang_len))
assert len(firsts) + len(seconds) == lang_len
for row in zip_longest(firsts, seconds):
item = {}
for position, ind in zip(["first", "second"], row):
if ind is None:
continue
lang = language_list[ind]
percent = name = lang["name"]
if "percent_translated" in lang:
percent = "{} ({}%)".format(name, lang["percent_translated"])
selected = False
if default_language in (lang["code"], lang["locale"]):
selected = True
item[position] = {
"name": name,
"code": lang["code"],
"percent": percent,
"selected": selected,
}
formatted_list.append(item)
return formatted_list
def get_language_name(code: str) -> str:
for lang in get_language_list():
if code in (lang["code"], lang["locale"]):

View File

@ -106,7 +106,6 @@ class HomeTest(ZulipTestCase):
"is_spectator",
"jitsi_server_url",
"language_list",
"language_list_dbl_col",
"last_event_id",
"left_side_userlist",
"login_page",