gear_menu: Convert module to TypeScript.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg
2024-11-26 13:47:30 -08:00
committed by Tim Abbott
parent aa0dd44234
commit bb174e9b64
7 changed files with 103 additions and 15 deletions

View File

@@ -108,7 +108,7 @@ EXEMPT_FILES = make_set(
"web/src/feedback_widget.ts",
"web/src/fetch_status.ts",
"web/src/flatpickr.ts",
"web/src/gear_menu.js",
"web/src/gear_menu.ts",
"web/src/giphy.ts",
"web/src/giphy_state.ts",
"web/src/global.ts",

View File

@@ -1,5 +1,8 @@
import $ from "jquery";
import assert from "minimalistic-assert";
import type * as tippy from "tippy.js";
import WinChan from "winchan";
import {z} from "zod";
import render_navbar_gear_menu_popover from "../templates/popovers/navbar/navbar_gear_menu_popover.hbs";
@@ -84,7 +87,7 @@ The click handler uses "[data-overlay-trigger]" as
the selector and then calls browser_history.go_to_location.
*/
function render(instance) {
function render(instance: tippy.Instance): void {
const rendered_gear_menu = render_navbar_gear_menu_popover(
popover_menus_data.get_gear_menu_content_context(),
);
@@ -92,7 +95,7 @@ function render(instance) {
$("#gear-menu").addClass("active-navbar-menu");
}
export function initialize() {
export function initialize(): void {
popover_menus.register_popover_menu("#gear-menu", {
theme: "popover-menu",
placement: "bottom",
@@ -123,13 +126,32 @@ export function initialize() {
principal,
},
},
(err, r) => {
if (err) {
(err, raw_response) => {
if (err !== null) {
blueslip.warn(err);
return;
}
// https://github.com/davidben/webathena/blob/0be20d9b1d62c19b4f94f77e621bd8721e504446/app/scripts-src/request_ticket.js
const response_schema = z.discriminatedUnion("status", [
z.object({
status: z.literal("OK"),
session: z.unknown(),
}),
z.object({
status: z.literal("ERROR"),
code: z.string(),
message: z.string(),
}),
z.object({
status: z.literal("DENIED"),
code: z.string(),
message: z.string(),
}),
]);
const r = response_schema.parse(raw_response);
if (r.status !== "OK") {
blueslip.warn(r);
blueslip.warn(`Webathena: ${r.status}: ${r.message}`);
return;
}
@@ -158,7 +180,7 @@ export function initialize() {
});
$popper.on("change", "input[name='theme-select']", (e) => {
const theme_code = Number.parseInt($(e.currentTarget).attr("data-theme-code"), 10);
const theme_code = Number.parseInt($(e.currentTarget).attr("data-theme-code")!, 10);
requestAnimationFrame(() => {
theme.set_theme_for_spectator(theme_code);
});
@@ -168,12 +190,12 @@ export function initialize() {
onHidden(instance) {
$("#gear-menu").removeClass("active-navbar-menu");
instance.destroy();
popover_menus.popover_instances.gear_menu = undefined;
popover_menus.popover_instances.gear_menu = null;
},
});
}
export function toggle() {
export function toggle(): void {
if (popover_menus.is_gear_menu_popover_displayed()) {
popovers.hide_all();
return;
@@ -188,8 +210,10 @@ export function toggle() {
$("#gear-menu").trigger("click");
}
export function rerender() {
export function rerender(): void {
if (popover_menus.is_gear_menu_popover_displayed()) {
render(popover_menus.get_gear_menu_instance());
const instance = popover_menus.get_gear_menu_instance();
assert(instance !== null);
render(instance);
}
}

View File

@@ -20,7 +20,7 @@ import * as drafts_overlay_ui from "./drafts_overlay_ui.js";
import * as emoji from "./emoji.ts";
import * as emoji_picker from "./emoji_picker.ts";
import * as feedback_widget from "./feedback_widget.ts";
import * as gear_menu from "./gear_menu.js";
import * as gear_menu from "./gear_menu.ts";
import * as giphy from "./giphy.ts";
import * as hash_util from "./hash_util.ts";
import * as hashchange from "./hashchange.js";

View File

@@ -1,6 +1,6 @@
import $ from "jquery";
import * as gear_menu from "./gear_menu.js";
import * as gear_menu from "./gear_menu.ts";
import * as navbar_help_menu from "./navbar_help_menu.ts";
import * as personal_menu_popover from "./personal_menu_popover.ts";
import * as popover_menus from "./popover_menus.ts";

View File

@@ -19,7 +19,7 @@ import * as compose_state from "./compose_state.ts";
import {electron_bridge} from "./electron_bridge.ts";
import * as emoji from "./emoji.ts";
import * as emoji_picker from "./emoji_picker.ts";
import * as gear_menu from "./gear_menu.js";
import * as gear_menu from "./gear_menu.ts";
import * as giphy from "./giphy.ts";
import * as information_density from "./information_density.ts";
import * as left_sidebar_navigation_area from "./left_sidebar_navigation_area.ts";

64
web/src/types/winchan.d.ts vendored Normal file
View File

@@ -0,0 +1,64 @@
// Types for https://www.npmjs.com/package/winchan
/**
* Opens a window and initiates a cross-domain request. Call this from the
* "untrusted" or "client" site.
*
* @param options - Options for `open`
* @param responseCallback - Called when the request completes with a response
* or an error
*/
export function open(
options: {
/**
* URL of the "trusted" window
*/
url: string;
/**
* URL of the `relay.html` iframe (used for Internet Explorer support)
*/
relay_url: string;
/**
* Target name passed to `window.open`
*/
window_name?: string | undefined;
/**
* Comma-separated features passed to `window.open`
*/
window_features?: string | undefined;
/**
* Application-defined parameters for the request
*/
params?: unknown;
},
responseCallback: (err: string | null, response?: unknown) => void,
): {
/**
* Closes the window.
*/
close: () => void;
/**
* Tries to move the focus to the window.
*/
focus: () => void;
};
/**
* Listens for a request. Call this from the "trusted" site providing the
* window.
*
* @param requestCallback - Called to initiate the request
*/
export function onOpen(
requestCallback: (
origin: string,
params: unknown,
sendResponse: (response: unknown) => void,
) => void,
): {
/**
* Detaches the channel without sending a response yet. Call this before
* navigating to another page in a multi-page dialog.
*/
detach: () => void;
};

View File

@@ -43,7 +43,7 @@ import * as echo from "./echo.ts";
import * as emoji from "./emoji.ts";
import * as emoji_picker from "./emoji_picker.ts";
import * as emojisets from "./emojisets.ts";
import * as gear_menu from "./gear_menu.js";
import * as gear_menu from "./gear_menu.ts";
import * as giphy from "./giphy.ts";
import * as giphy_state from "./giphy_state.ts";
import * as hashchange from "./hashchange.js";