mirror of https://github.com/zulip/zulip.git
gear_menu: Allow spectators to select their default language.
Set the default_language as cookie and reload the page so that the spectator can immediately see the language change in effect. We can reload the page forcefully for spectators since there is no chance of any work being lost. It is possible that the spectator may lose the selected message on doing so. This requires a new dependency, to be able to set cookies from frontend JavaScript. Fixes #21961
This commit is contained in:
parent
085443c722
commit
59e676b1f5
|
@ -303,8 +303,10 @@ async function test_alert_words_section(page: Page): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function change_language(page: Page, language_data_code: string): Promise<void> {
|
async function change_language(page: Page, language_data_code: string): Promise<void> {
|
||||||
await page.waitForSelector("#user-display-settings .setting_default_language", {visible: true});
|
await page.waitForSelector("#user-display-settings .language_selection_button", {
|
||||||
await page.click("#user-display-settings .setting_default_language");
|
visible: true,
|
||||||
|
});
|
||||||
|
await page.click("#user-display-settings .language_selection_button");
|
||||||
await common.wait_for_micromodal_to_open(page);
|
await common.wait_for_micromodal_to_open(page);
|
||||||
const language_selector = `a[data-code="${CSS.escape(language_data_code)}"]`;
|
const language_selector = `a[data-code="${CSS.escape(language_data_code)}"]`;
|
||||||
await page.click(language_selector);
|
await page.click(language_selector);
|
||||||
|
@ -317,10 +319,12 @@ async function check_language_setting_status(page: Page): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function assert_language_changed_to_chinese(page: Page): Promise<void> {
|
async function assert_language_changed_to_chinese(page: Page): Promise<void> {
|
||||||
await page.waitForSelector("#user-display-settings .setting_default_language", {visible: true});
|
await page.waitForSelector("#user-display-settings .language_selection_button", {
|
||||||
|
visible: true,
|
||||||
|
});
|
||||||
const default_language = await common.get_text_from_selector(
|
const default_language = await common.get_text_from_selector(
|
||||||
page,
|
page,
|
||||||
"#user-display-settings .setting_default_language",
|
"#user-display-settings .language_selection_button",
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
default_language,
|
default_language,
|
||||||
|
@ -346,7 +350,9 @@ async function test_default_language_setting(page: Page): Promise<void> {
|
||||||
// Check that the saved indicator appears
|
// Check that the saved indicator appears
|
||||||
await check_language_setting_status(page);
|
await check_language_setting_status(page);
|
||||||
await page.click(".reload_link");
|
await page.click(".reload_link");
|
||||||
await page.waitForSelector("#user-display-settings .setting_default_language", {visible: true});
|
await page.waitForSelector("#user-display-settings .language_selection_button", {
|
||||||
|
visible: true,
|
||||||
|
});
|
||||||
await assert_language_changed_to_chinese(page);
|
await assert_language_changed_to_chinese(page);
|
||||||
await test_i18n_language_precedence(page);
|
await test_i18n_language_precedence(page);
|
||||||
await page.waitForSelector(display_settings_section, {visible: true});
|
await page.waitForSelector(display_settings_section, {visible: true});
|
||||||
|
@ -363,7 +369,9 @@ async function test_default_language_setting(page: Page): Promise<void> {
|
||||||
await page.waitForSelector("#user-display-settings .lang-time-settings-status", {
|
await page.waitForSelector("#user-display-settings .lang-time-settings-status", {
|
||||||
visible: true,
|
visible: true,
|
||||||
});
|
});
|
||||||
await page.waitForSelector("#user-display-settings .setting_default_language", {visible: true});
|
await page.waitForSelector("#user-display-settings .language_selection_button", {
|
||||||
|
visible: true,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function test_notifications_section(page: Page): Promise<void> {
|
async function test_notifications_section(page: Page): Promise<void> {
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
"jquery": "^3.4.1",
|
"jquery": "^3.4.1",
|
||||||
"jquery-caret-plugin": "^1.5.2",
|
"jquery-caret-plugin": "^1.5.2",
|
||||||
"jquery-validation": "^1.19.0",
|
"jquery-validation": "^1.19.0",
|
||||||
|
"js-cookie": "^3.0.1",
|
||||||
"katex": "^0.15.3",
|
"katex": "^0.15.3",
|
||||||
"lodash": "^4.17.19",
|
"lodash": "^4.17.19",
|
||||||
"micromodal": "^0.4.6",
|
"micromodal": "^0.4.6",
|
||||||
|
|
|
@ -37,6 +37,7 @@ import * as reactions from "./reactions";
|
||||||
import * as recent_topics_ui from "./recent_topics_ui";
|
import * as recent_topics_ui from "./recent_topics_ui";
|
||||||
import * as rows from "./rows";
|
import * as rows from "./rows";
|
||||||
import * as server_events from "./server_events";
|
import * as server_events from "./server_events";
|
||||||
|
import * as settings_display from "./settings_display";
|
||||||
import * as settings_panel_menu from "./settings_panel_menu";
|
import * as settings_panel_menu from "./settings_panel_menu";
|
||||||
import * as settings_toggle from "./settings_toggle";
|
import * as settings_toggle from "./settings_toggle";
|
||||||
import * as spectators from "./spectators";
|
import * as spectators from "./spectators";
|
||||||
|
@ -671,6 +672,10 @@ export function initialize() {
|
||||||
popovers.hide_all();
|
popovers.hide_all();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$("body").on("click", ".reload_link", () => {
|
||||||
|
window.location.reload();
|
||||||
|
});
|
||||||
|
|
||||||
// COMPOSE
|
// COMPOSE
|
||||||
|
|
||||||
$("body").on("click", "#compose-send-status .compose-send-status-close", () => {
|
$("body").on("click", "#compose-send-status .compose-send-status-close", () => {
|
||||||
|
@ -863,6 +868,12 @@ export function initialize() {
|
||||||
|
|
||||||
// GEAR MENU
|
// GEAR MENU
|
||||||
|
|
||||||
|
$("body").on("click", ".change-language-spectator, .language_selection_widget button", (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
settings_display.launch_default_language_setting_modal();
|
||||||
|
});
|
||||||
|
|
||||||
$("body").on("click", "#gear-menu .dark-theme", (e) => {
|
$("body").on("click", "#gear-menu .dark-theme", (e) => {
|
||||||
// Allow propagation to close gear menu.
|
// Allow propagation to close gear menu.
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
|
@ -573,6 +573,7 @@ export const display_settings_labels = {
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
escape_navigates_to_default_view: $t({defaultMessage: "Escape key navigates to default view"}),
|
escape_navigates_to_default_view: $t({defaultMessage: "Escape key navigates to default view"}),
|
||||||
|
default_language_settings_label: $t({defaultMessage: "Language"}),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const notification_settings_labels = {
|
export const notification_settings_labels = {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import $ from "jquery";
|
import $ from "jquery";
|
||||||
|
import Cookies from "js-cookie"; // eslint-disable-line import/no-unresolved
|
||||||
|
|
||||||
import render_dialog_default_language from "../templates/default_language_modal.hbs";
|
import render_dialog_default_language from "../templates/default_language_modal.hbs";
|
||||||
|
|
||||||
|
@ -8,6 +9,7 @@ import * as emojisets from "./emojisets";
|
||||||
import {$t_html, get_language_list_columns, get_language_name} from "./i18n";
|
import {$t_html, get_language_list_columns, get_language_name} from "./i18n";
|
||||||
import * as loading from "./loading";
|
import * as loading from "./loading";
|
||||||
import * as overlays from "./overlays";
|
import * as overlays from "./overlays";
|
||||||
|
import {page_params} from "./page_params";
|
||||||
import * as settings_org from "./settings_org";
|
import * as settings_org from "./settings_org";
|
||||||
import * as settings_ui from "./settings_ui";
|
import * as settings_ui from "./settings_ui";
|
||||||
import * as ui_report from "./ui_report";
|
import * as ui_report from "./ui_report";
|
||||||
|
@ -42,8 +44,22 @@ function change_display_setting(data, $status_el, success_msg_html, sticky) {
|
||||||
settings_ui.do_settings_change(channel.patch, "/json/settings", data, $status_el, opts);
|
settings_ui.do_settings_change(channel.patch, "/json/settings", data, $status_el, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
function default_language_modal_post_render($container) {
|
function spectator_default_language_modal_post_render() {
|
||||||
$("#user_default_language_modal")
|
$("#language_selection_modal")
|
||||||
|
.find(".language")
|
||||||
|
.on("click", (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
dialog_widget.close_modal();
|
||||||
|
|
||||||
|
const $link = $(e.target).closest("a[data-code]");
|
||||||
|
Cookies.set(page_params.language_cookie_name, $link.attr("data-code"));
|
||||||
|
window.location.reload();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function user_default_language_modal_post_render() {
|
||||||
|
$("#language_selection_modal")
|
||||||
.find(".language")
|
.find(".language")
|
||||||
.on("click", (e) => {
|
.on("click", (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -55,11 +71,13 @@ function default_language_modal_post_render($container) {
|
||||||
const data = {default_language: setting_value};
|
const data = {default_language: setting_value};
|
||||||
|
|
||||||
const new_language = $link.attr("data-name");
|
const new_language = $link.attr("data-name");
|
||||||
$container.find(".default_language_name").text(new_language);
|
$(
|
||||||
|
"#user-display-settings .language_selection_widget .language_selection_button span",
|
||||||
|
).text(new_language);
|
||||||
|
|
||||||
change_display_setting(
|
change_display_setting(
|
||||||
data,
|
data,
|
||||||
$container.find(".lang-time-settings-status"),
|
$("#settings_content").find(".lang-time-settings-status"),
|
||||||
$t_html(
|
$t_html(
|
||||||
{
|
{
|
||||||
defaultMessage:
|
defaultMessage:
|
||||||
|
@ -72,7 +90,15 @@ function default_language_modal_post_render($container) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function launch_default_language_setting_modal($container) {
|
function default_language_modal_post_render() {
|
||||||
|
if (page_params.is_spectator) {
|
||||||
|
spectator_default_language_modal_post_render();
|
||||||
|
} else {
|
||||||
|
user_default_language_modal_post_render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function launch_default_language_setting_modal() {
|
||||||
const html_body = render_dialog_default_language({
|
const html_body = render_dialog_default_language({
|
||||||
language_list: get_language_list_columns(user_settings.default_language),
|
language_list: get_language_list_columns(user_settings.default_language),
|
||||||
});
|
});
|
||||||
|
@ -81,11 +107,11 @@ export function launch_default_language_setting_modal($container) {
|
||||||
html_heading: $t_html({defaultMessage: "Select default language"}),
|
html_heading: $t_html({defaultMessage: "Select default language"}),
|
||||||
html_body,
|
html_body,
|
||||||
html_submit_button: $t_html({defaultMessage: "Close"}),
|
html_submit_button: $t_html({defaultMessage: "Close"}),
|
||||||
id: "user_default_language_modal",
|
id: "language_selection_modal",
|
||||||
close_on_submit: true,
|
close_on_submit: true,
|
||||||
focus_submit_on_open: true,
|
focus_submit_on_open: true,
|
||||||
single_footer_button: true,
|
single_footer_button: true,
|
||||||
post_render: () => default_language_modal_post_render($container),
|
post_render: default_language_modal_post_render,
|
||||||
on_click: () => {},
|
on_click: () => {},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -147,16 +173,6 @@ export function set_up(settings_panel) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$container.find(".setting_default_language").on("click", (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
launch_default_language_setting_modal($container);
|
|
||||||
});
|
|
||||||
|
|
||||||
$("body").on("click", ".reload_link", () => {
|
|
||||||
window.location.reload();
|
|
||||||
});
|
|
||||||
|
|
||||||
$container.find(".setting_emojiset_choice").on("click", function () {
|
$container.find(".setting_emojiset_choice").on("click", function () {
|
||||||
const data = {emojiset: $(this).val()};
|
const data = {emojiset: $(this).val()};
|
||||||
const current_emojiset = settings_object.emojiset;
|
const current_emojiset = settings_object.emojiset;
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 651 B |
|
@ -395,11 +395,7 @@ td .button {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
#user-display-settings .setting_default_language {
|
#language_selection_modal {
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#user_default_language_modal {
|
|
||||||
table {
|
table {
|
||||||
width: 90%;
|
width: 90%;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
|
@ -573,7 +569,8 @@ input[type="checkbox"] {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#user-display-settings .setting_default_language {
|
.language_selection_widget .language_selection_button {
|
||||||
|
text-decoration: none;
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2167,6 +2167,12 @@ div.focused_table {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#gear-menu .zulip-icon-language {
|
||||||
|
position: relative;
|
||||||
|
top: 2.5px;
|
||||||
|
left: -0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
.nav .dropdown-menu a,
|
.nav .dropdown-menu a,
|
||||||
.typeahead.dropdown-menu a {
|
.typeahead.dropdown-menu a {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
|
|
|
@ -32,6 +32,11 @@
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
|
<li role="presentation" class="only-visible-for-spectators">
|
||||||
|
<a class="change-language-spectator" role="menuitem">
|
||||||
|
<i class="zulip-icon zulip-icon-language" aria-hidden="true"></i> {{t 'Select language' }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<li role="presentation" class="only-visible-for-spectators">
|
<li role="presentation" class="only-visible-for-spectators">
|
||||||
<a class="dark-theme" role="menuitem">
|
<a class="dark-theme" role="menuitem">
|
||||||
<i class="fa fa-moon-o" aria-hidden="true"></i> {{t 'Switch to dark theme' }}
|
<i class="fa fa-moon-o" aria-hidden="true"></i> {{t 'Switch to dark theme' }}
|
||||||
|
|
|
@ -11,13 +11,10 @@
|
||||||
{{> settings_save_discard_widget section_name="lang-time-settings" show_only_indicator=(not for_realm_settings) }}
|
{{> settings_save_discard_widget section_name="lang-time-settings" show_only_indicator=(not for_realm_settings) }}
|
||||||
</div>
|
</div>
|
||||||
{{#unless for_realm_settings}}
|
{{#unless for_realm_settings}}
|
||||||
<div class="input-group">
|
{{> language_selection_widget
|
||||||
<label class="inline-block title">{{t "Language" }}</label>
|
section_name="default_language_name"
|
||||||
<button type="button" class="setting_default_language button btn-link rounded small inline-block">
|
setting_value=default_language_name
|
||||||
<span class="default_language_name">{{default_language_name}}</span>
|
section_title=settings_label.default_language_settings_label }}
|
||||||
<i class="fa fa-pencil"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
|
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
<div class="input-group language_selection_widget">
|
||||||
|
<label class="inline-block title">{{section_title}}</label>
|
||||||
|
<button type="button" class="language_selection_button button btn-link rounded small inline-block" data-section="{{section_name}}">
|
||||||
|
<span class="{{section_name}}">{{setting_value}}</span>
|
||||||
|
<i class="fa fa-pencil"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
|
@ -48,4 +48,4 @@ API_FEATURE_LEVEL = 132
|
||||||
# historical commits sharing the same major version, in which case a
|
# historical commits sharing the same major version, in which case a
|
||||||
# minor version bump suffices.
|
# minor version bump suffices.
|
||||||
|
|
||||||
PROVISION_VERSION = "190.0"
|
PROVISION_VERSION = "190.1"
|
||||||
|
|
|
@ -6582,6 +6582,11 @@ jquery@^3.4.1:
|
||||||
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.0.tgz#c72a09f15c1bdce142f49dbf1170bdf8adac2470"
|
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.0.tgz#c72a09f15c1bdce142f49dbf1170bdf8adac2470"
|
||||||
integrity sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==
|
integrity sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==
|
||||||
|
|
||||||
|
js-cookie@^3.0.1:
|
||||||
|
version "3.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-3.0.1.tgz#9e39b4c6c2f56563708d7d31f6f5f21873a92414"
|
||||||
|
integrity sha512-+0rgsUXZu4ncpPxRL+lNEptWMOWl9etvPHc/koSRp6MPwpRYAhmk0dUG00J4bxVV3r9uUzfo24wW0knS07SKSw==
|
||||||
|
|
||||||
js-tokens@^4.0.0:
|
js-tokens@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||||
|
|
Loading…
Reference in New Issue