mirror of https://github.com/zulip/zulip.git
upload: Convert module to TypeScript.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
e74ed28f4f
commit
fba81d1cd5
|
@ -261,7 +261,7 @@ EXEMPT_FILES = make_set(
|
||||||
"web/src/unread.ts",
|
"web/src/unread.ts",
|
||||||
"web/src/unread_ops.ts",
|
"web/src/unread_ops.ts",
|
||||||
"web/src/unread_ui.ts",
|
"web/src/unread_ui.ts",
|
||||||
"web/src/upload.js",
|
"web/src/upload.ts",
|
||||||
"web/src/upload_widget.ts",
|
"web/src/upload_widget.ts",
|
||||||
"web/src/url-template.d.ts",
|
"web/src/url-template.d.ts",
|
||||||
"web/src/user_card_popover.js",
|
"web/src/user_card_popover.js",
|
||||||
|
|
|
@ -74,6 +74,7 @@ export const realm_schema = z.object({
|
||||||
PRONOUNS: z.object({id: z.number(), name: z.string()}),
|
PRONOUNS: z.object({id: z.number(), name: z.string()}),
|
||||||
}),
|
}),
|
||||||
max_avatar_file_size_mib: z.number(),
|
max_avatar_file_size_mib: z.number(),
|
||||||
|
max_file_upload_size_mib: z.number(),
|
||||||
max_icon_file_size_mib: z.number(),
|
max_icon_file_size_mib: z.number(),
|
||||||
max_logo_file_size_mib: z.number(),
|
max_logo_file_size_mib: z.number(),
|
||||||
max_message_length: z.number(),
|
max_message_length: z.number(),
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
|
import type {UppyFile} from "@uppy/core";
|
||||||
import {Uppy} from "@uppy/core";
|
import {Uppy} from "@uppy/core";
|
||||||
import XHRUpload from "@uppy/xhr-upload";
|
import XHRUpload from "@uppy/xhr-upload";
|
||||||
import $ from "jquery";
|
import $ from "jquery";
|
||||||
import assert from "minimalistic-assert";
|
import assert from "minimalistic-assert";
|
||||||
|
import {z} from "zod";
|
||||||
|
|
||||||
import render_upload_banner from "../templates/compose_banner/upload_banner.hbs";
|
import render_upload_banner from "../templates/compose_banner/upload_banner.hbs";
|
||||||
|
|
||||||
|
@ -18,27 +20,42 @@ import * as message_lists from "./message_lists";
|
||||||
import * as rows from "./rows";
|
import * as rows from "./rows";
|
||||||
import {realm} from "./state_data";
|
import {realm} from "./state_data";
|
||||||
|
|
||||||
let drag_drop_img = null;
|
let drag_drop_img: HTMLElement | null = null;
|
||||||
let compose_upload_object;
|
let compose_upload_object: Uppy;
|
||||||
const upload_objects_by_message_edit_row = new Map();
|
const upload_objects_by_message_edit_row = new Map<number, Uppy>();
|
||||||
|
|
||||||
export function compose_upload_cancel() {
|
export function compose_upload_cancel(): void {
|
||||||
compose_upload_object.cancelAll();
|
compose_upload_object.cancelAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function feature_check() {
|
export function feature_check(): XMLHttpRequestUpload {
|
||||||
// Show the upload button only if the browser supports it.
|
// Show the upload button only if the browser supports it.
|
||||||
return window.XMLHttpRequest && new window.XMLHttpRequest().upload;
|
return window.XMLHttpRequest && new window.XMLHttpRequest().upload;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get_translated_status(file) {
|
export function get_translated_status(file: File | UppyFile): string {
|
||||||
const status = $t({defaultMessage: "Uploading {filename}…"}, {filename: file.name});
|
const status = $t({defaultMessage: "Uploading {filename}…"}, {filename: file.name});
|
||||||
return "[" + status + "]()";
|
return "[" + status + "]()";
|
||||||
}
|
}
|
||||||
|
|
||||||
export const compose_config = {
|
type Config = ({mode: "compose"} | {mode: "edit"; row: number}) & {
|
||||||
|
textarea: () => JQuery<HTMLTextAreaElement>;
|
||||||
|
send_button: () => JQuery;
|
||||||
|
banner_container: () => JQuery;
|
||||||
|
upload_banner_identifier: (file_id: string) => string;
|
||||||
|
upload_banner: (file_id: string) => JQuery;
|
||||||
|
upload_banner_cancel_button: (file_id: string) => JQuery;
|
||||||
|
upload_banner_hide_button: (file_id: string) => JQuery;
|
||||||
|
upload_banner_message: (file_id: string) => JQuery;
|
||||||
|
file_input_identifier: () => string;
|
||||||
|
source: () => string;
|
||||||
|
drag_drop_container: () => JQuery;
|
||||||
|
markdown_preview_hide_button: () => JQuery;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const compose_config: Config = {
|
||||||
mode: "compose",
|
mode: "compose",
|
||||||
textarea: () => $("textarea#compose-textarea"),
|
textarea: () => $<HTMLTextAreaElement>("textarea#compose-textarea"),
|
||||||
send_button: () => $("#compose-send-button"),
|
send_button: () => $("#compose-send-button"),
|
||||||
banner_container: () => $("#compose_banners"),
|
banner_container: () => $("#compose_banners"),
|
||||||
upload_banner_identifier: (file_id) =>
|
upload_banner_identifier: (file_id) =>
|
||||||
|
@ -58,55 +75,58 @@ export const compose_config = {
|
||||||
),
|
),
|
||||||
upload_banner_message: (file_id) =>
|
upload_banner_message: (file_id) =>
|
||||||
$(`#compose_banners .upload_banner.file_${CSS.escape(file_id)} .upload_msg`),
|
$(`#compose_banners .upload_banner.file_${CSS.escape(file_id)} .upload_msg`),
|
||||||
file_input_identifier: () => "#compose .file_input",
|
file_input_identifier: () => "#compose input.file_input",
|
||||||
source: () => "compose-file-input",
|
source: () => "compose-file-input",
|
||||||
drag_drop_container: () => $("#compose"),
|
drag_drop_container: () => $("#compose"),
|
||||||
markdown_preview_hide_button: () => $("#compose .undo_markdown_preview"),
|
markdown_preview_hide_button: () => $("#compose .undo_markdown_preview"),
|
||||||
};
|
};
|
||||||
|
|
||||||
export function edit_config(row) {
|
export function edit_config(row: number): Config {
|
||||||
return {
|
return {
|
||||||
mode: "edit",
|
mode: "edit",
|
||||||
row,
|
row,
|
||||||
textarea: () => $(`#edit_form_${CSS.escape(row)} .message_edit_content`),
|
textarea: () =>
|
||||||
send_button: () => $(`#edit_form_${CSS.escape(row)}`).find(".message_edit_save"),
|
$<HTMLTextAreaElement>(
|
||||||
banner_container: () => $(`#edit_form_${CSS.escape(row)} .edit_form_banners`),
|
`#edit_form_${CSS.escape(`${row}`)} textarea.message_edit_content`,
|
||||||
|
),
|
||||||
|
send_button: () => $(`#edit_form_${CSS.escape(`${row}`)}`).find(".message_edit_save"),
|
||||||
|
banner_container: () => $(`#edit_form_${CSS.escape(`${row}`)} .edit_form_banners`),
|
||||||
upload_banner_identifier: (file_id) =>
|
upload_banner_identifier: (file_id) =>
|
||||||
`#edit_form_${CSS.escape(row)} .upload_banner.file_${CSS.escape(file_id)}`,
|
`#edit_form_${CSS.escape(`${row}`)} .upload_banner.file_${CSS.escape(file_id)}`,
|
||||||
upload_banner: (file_id) =>
|
upload_banner: (file_id) =>
|
||||||
$(`#edit_form_${CSS.escape(row)} .upload_banner.file_${CSS.escape(file_id)}`),
|
$(`#edit_form_${CSS.escape(`${row}`)} .upload_banner.file_${CSS.escape(file_id)}`),
|
||||||
upload_banner_cancel_button: (file_id) =>
|
upload_banner_cancel_button: (file_id) =>
|
||||||
$(
|
$(
|
||||||
`#edit_form_${CSS.escape(row)} .upload_banner.file_${CSS.escape(
|
`#edit_form_${CSS.escape(`${row}`)} .upload_banner.file_${CSS.escape(
|
||||||
file_id,
|
file_id,
|
||||||
)} .upload_banner_cancel_button`,
|
)} .upload_banner_cancel_button`,
|
||||||
),
|
),
|
||||||
upload_banner_hide_button: (file_id) =>
|
upload_banner_hide_button: (file_id) =>
|
||||||
$(
|
$(
|
||||||
`#edit_form_${CSS.escape(row)} .upload_banner.file_${CSS.escape(
|
`#edit_form_${CSS.escape(`${row}`)} .upload_banner.file_${CSS.escape(
|
||||||
file_id,
|
file_id,
|
||||||
)} .main-view-banner-close-button`,
|
)} .main-view-banner-close-button`,
|
||||||
),
|
),
|
||||||
upload_banner_message: (file_id) =>
|
upload_banner_message: (file_id) =>
|
||||||
$(
|
$(
|
||||||
`#edit_form_${CSS.escape(row)} .upload_banner.file_${CSS.escape(
|
`#edit_form_${CSS.escape(`${row}`)} .upload_banner.file_${CSS.escape(
|
||||||
file_id,
|
file_id,
|
||||||
)} .upload_msg`,
|
)} .upload_msg`,
|
||||||
),
|
),
|
||||||
file_input_identifier: () => `#edit_form_${CSS.escape(row)} .file_input`,
|
file_input_identifier: () => `#edit_form_${CSS.escape(`${row}`)} input.file_input`,
|
||||||
source: () => "message-edit-file-input",
|
source: () => "message-edit-file-input",
|
||||||
drag_drop_container() {
|
drag_drop_container() {
|
||||||
assert(message_lists.current !== undefined);
|
assert(message_lists.current !== undefined);
|
||||||
return $(
|
return $(
|
||||||
`#message-row-${message_lists.current.id}-${CSS.escape(row)} .message_edit_form`,
|
`#message-row-${message_lists.current.id}-${CSS.escape(`${row}`)} .message_edit_form`,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
markdown_preview_hide_button: () =>
|
markdown_preview_hide_button: () =>
|
||||||
$(`#edit_form_${CSS.escape(row)} .undo_markdown_preview`),
|
$(`#edit_form_${CSS.escape(`${row}`)} .undo_markdown_preview`),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hide_upload_banner(uppy, config, file_id) {
|
export function hide_upload_banner(uppy: Uppy, config: Config, file_id: string): void {
|
||||||
config.upload_banner(file_id).remove();
|
config.upload_banner(file_id).remove();
|
||||||
if (uppy.getFiles().length === 0) {
|
if (uppy.getFiles().length === 0) {
|
||||||
if (config.mode === "compose") {
|
if (config.mode === "compose") {
|
||||||
|
@ -118,12 +138,12 @@ export function hide_upload_banner(uppy, config, file_id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function add_upload_banner(
|
function add_upload_banner(
|
||||||
config,
|
config: Config,
|
||||||
banner_type,
|
banner_type: string,
|
||||||
banner_text,
|
banner_text: string,
|
||||||
file_id,
|
file_id: string,
|
||||||
is_upload_process_tracker = false,
|
is_upload_process_tracker = false,
|
||||||
) {
|
): void {
|
||||||
const new_banner_html = render_upload_banner({
|
const new_banner_html = render_upload_banner({
|
||||||
banner_type,
|
banner_type,
|
||||||
is_upload_process_tracker,
|
is_upload_process_tracker,
|
||||||
|
@ -137,10 +157,10 @@ function add_upload_banner(
|
||||||
}
|
}
|
||||||
|
|
||||||
export function show_error_message(
|
export function show_error_message(
|
||||||
config,
|
config: Config,
|
||||||
message = $t({defaultMessage: "An unknown error occurred."}),
|
message = $t({defaultMessage: "An unknown error occurred."}),
|
||||||
file_id = null,
|
file_id: string | null = null,
|
||||||
) {
|
): void {
|
||||||
if (file_id) {
|
if (file_id) {
|
||||||
$(`${config.upload_banner_identifier(file_id)} .moving_bar`).hide();
|
$(`${config.upload_banner_identifier(file_id)} .moving_bar`).hide();
|
||||||
config.upload_banner(file_id).removeClass("info").addClass("error");
|
config.upload_banner(file_id).removeClass("info").addClass("error");
|
||||||
|
@ -153,7 +173,7 @@ export function show_error_message(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function upload_files(uppy, config, files) {
|
export function upload_files(uppy: Uppy, config: Config, files: File[] | FileList): void {
|
||||||
if (files.length === 0) {
|
if (files.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -179,6 +199,7 @@ export async function upload_files(uppy, config, files) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
|
let file_id;
|
||||||
try {
|
try {
|
||||||
compose_ui.insert_syntax_and_focus(
|
compose_ui.insert_syntax_and_focus(
|
||||||
get_translated_status(file),
|
get_translated_status(file),
|
||||||
|
@ -187,7 +208,7 @@ export async function upload_files(uppy, config, files) {
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
compose_ui.autosize_textarea(config.textarea());
|
compose_ui.autosize_textarea(config.textarea());
|
||||||
file.id = uppy.addFile({
|
file_id = uppy.addFile({
|
||||||
source: config.source(),
|
source: config.source(),
|
||||||
name: file.name,
|
name: file.name,
|
||||||
type: file.type,
|
type: file.type,
|
||||||
|
@ -207,24 +228,24 @@ export async function upload_files(uppy, config, files) {
|
||||||
config,
|
config,
|
||||||
"info",
|
"info",
|
||||||
$t({defaultMessage: "Uploading {filename}…"}, {filename: file.name}),
|
$t({defaultMessage: "Uploading {filename}…"}, {filename: file.name}),
|
||||||
file.id,
|
file_id,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
config.upload_banner_cancel_button(file.id).one("click", () => {
|
config.upload_banner_cancel_button(file_id).one("click", () => {
|
||||||
compose_ui.replace_syntax(get_translated_status(file), "", config.textarea());
|
compose_ui.replace_syntax(get_translated_status(file), "", config.textarea());
|
||||||
compose_ui.autosize_textarea(config.textarea());
|
compose_ui.autosize_textarea(config.textarea());
|
||||||
config.textarea().trigger("focus");
|
config.textarea().trigger("focus");
|
||||||
|
|
||||||
uppy.removeFile(file.id);
|
uppy.removeFile(file_id);
|
||||||
hide_upload_banner(uppy, config, file.id);
|
hide_upload_banner(uppy, config, file_id);
|
||||||
});
|
});
|
||||||
config.upload_banner_hide_button(file.id).one("click", () => {
|
config.upload_banner_hide_button(file_id).one("click", () => {
|
||||||
hide_upload_banner(uppy, config, file.id);
|
hide_upload_banner(uppy, config, file_id);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setup_upload(config) {
|
export function setup_upload(config: Config): Uppy {
|
||||||
const uppy = new Uppy({
|
const uppy = new Uppy({
|
||||||
debug: false,
|
debug: false,
|
||||||
autoProceed: true,
|
autoProceed: true,
|
||||||
|
@ -267,14 +288,16 @@ export function setup_upload(config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uppy.on("upload-progress", (file, progress) => {
|
uppy.on("upload-progress", (file, progress) => {
|
||||||
|
assert(file !== undefined);
|
||||||
const percent_complete = (100 * progress.bytesUploaded) / progress.bytesTotal;
|
const percent_complete = (100 * progress.bytesUploaded) / progress.bytesTotal;
|
||||||
$(`${config.upload_banner_identifier(file.id)} .moving_bar`).css({
|
$(`${config.upload_banner_identifier(file.id)} .moving_bar`).css({
|
||||||
width: `${percent_complete}%`,
|
width: `${percent_complete}%`,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$(config.file_input_identifier()).on("change", (event) => {
|
$<HTMLInputElement>(config.file_input_identifier()).on("change", (event) => {
|
||||||
const files = event.target.files;
|
const files = event.target.files;
|
||||||
|
assert(files !== null);
|
||||||
upload_files(uppy, config, files);
|
upload_files(uppy, config, files);
|
||||||
config.textarea().trigger("focus");
|
config.textarea().trigger("focus");
|
||||||
event.target.value = "";
|
event.target.value = "";
|
||||||
|
@ -291,12 +314,18 @@ export function setup_upload(config) {
|
||||||
);
|
);
|
||||||
|
|
||||||
const $drag_drop_container = config.drag_drop_container();
|
const $drag_drop_container = config.drag_drop_container();
|
||||||
$drag_drop_container.on("dragover", (event) => event.preventDefault());
|
$drag_drop_container.on("dragover", (event) => {
|
||||||
$drag_drop_container.on("dragenter", (event) => event.preventDefault());
|
event.preventDefault();
|
||||||
|
});
|
||||||
|
$drag_drop_container.on("dragenter", (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
$drag_drop_container.on("drop", (event) => {
|
$drag_drop_container.on("drop", (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
assert(event.originalEvent !== undefined);
|
||||||
|
assert(event.originalEvent.dataTransfer !== null);
|
||||||
const files = event.originalEvent.dataTransfer.files;
|
const files = event.originalEvent.dataTransfer.files;
|
||||||
if (config.mode === "compose" && !compose_state.composing()) {
|
if (config.mode === "compose" && !compose_state.composing()) {
|
||||||
compose_reply.respond_to_message({
|
compose_reply.respond_to_message({
|
||||||
|
@ -308,17 +337,18 @@ export function setup_upload(config) {
|
||||||
});
|
});
|
||||||
|
|
||||||
$drag_drop_container.on("paste", (event) => {
|
$drag_drop_container.on("paste", (event) => {
|
||||||
const clipboard_data = event.clipboardData || event.originalEvent.clipboardData;
|
assert(event.originalEvent instanceof ClipboardEvent);
|
||||||
|
const clipboard_data = event.originalEvent.clipboardData;
|
||||||
if (!clipboard_data) {
|
if (!clipboard_data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const items = clipboard_data.items;
|
const items = clipboard_data.items;
|
||||||
const files = [];
|
const files = [];
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
if (item.kind !== "file") {
|
const file = item.getAsFile();
|
||||||
|
if (file === null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const file = item.getAsFile();
|
|
||||||
files.push(file);
|
files.push(file);
|
||||||
}
|
}
|
||||||
if (files.length === 0) {
|
if (files.length === 0) {
|
||||||
|
@ -338,7 +368,8 @@ export function setup_upload(config) {
|
||||||
});
|
});
|
||||||
|
|
||||||
uppy.on("upload-success", (file, response) => {
|
uppy.on("upload-success", (file, response) => {
|
||||||
const url = response.body.uri;
|
assert(file !== undefined);
|
||||||
|
const {uri: url} = z.object({uri: z.string().optional()}).parse(response.body);
|
||||||
if (url === undefined) {
|
if (url === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -376,7 +407,9 @@ export function setup_upload(config) {
|
||||||
// TODO: Ideally, we'd be using the `.error()` hook or
|
// TODO: Ideally, we'd be using the `.error()` hook or
|
||||||
// something, not parsing error message strings.
|
// something, not parsing error message strings.
|
||||||
const infoList = uppy.getState().info;
|
const infoList = uppy.getState().info;
|
||||||
|
assert(infoList !== undefined);
|
||||||
const info = infoList.at(-1);
|
const info = infoList.at(-1);
|
||||||
|
assert(info !== undefined);
|
||||||
if (info.type === "error" && info.message === "No Internet connection") {
|
if (info.type === "error" && info.message === "No Internet connection") {
|
||||||
// server_events already handles the case of no internet.
|
// server_events already handles the case of no internet.
|
||||||
return;
|
return;
|
||||||
|
@ -397,11 +430,17 @@ export function setup_upload(config) {
|
||||||
});
|
});
|
||||||
|
|
||||||
uppy.on("upload-error", (file, _error, response) => {
|
uppy.on("upload-error", (file, _error, response) => {
|
||||||
|
assert(file !== undefined);
|
||||||
// The files with failed upload should be removed since uppy doesn't allow files in the store
|
// The files with failed upload should be removed since uppy doesn't allow files in the store
|
||||||
// to be re-uploaded again.
|
// to be re-uploaded again.
|
||||||
uppy.removeFile(file.id);
|
uppy.removeFile(file.id);
|
||||||
|
|
||||||
const message = response ? response.body.msg : undefined;
|
let parsed;
|
||||||
|
const message =
|
||||||
|
response !== undefined &&
|
||||||
|
(parsed = z.object({msg: z.string()}).safeParse(response.body)).success
|
||||||
|
? parsed.data.msg
|
||||||
|
: undefined;
|
||||||
// Hide the upload status banner on error so only the error banner shows
|
// Hide the upload status banner on error so only the error banner shows
|
||||||
hide_upload_banner(uppy, config, file.id);
|
hide_upload_banner(uppy, config, file.id);
|
||||||
show_error_message(config, message, file.id);
|
show_error_message(config, message, file.id);
|
||||||
|
@ -410,6 +449,7 @@ export function setup_upload(config) {
|
||||||
});
|
});
|
||||||
|
|
||||||
uppy.on("restriction-failed", (file) => {
|
uppy.on("restriction-failed", (file) => {
|
||||||
|
assert(file !== undefined);
|
||||||
compose_ui.replace_syntax(get_translated_status(file), "", config.textarea());
|
compose_ui.replace_syntax(get_translated_status(file), "", config.textarea());
|
||||||
compose_ui.autosize_textarea(config.textarea());
|
compose_ui.autosize_textarea(config.textarea());
|
||||||
});
|
});
|
||||||
|
@ -417,7 +457,7 @@ export function setup_upload(config) {
|
||||||
return uppy;
|
return uppy;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function deactivate_upload(config) {
|
export function deactivate_upload(config: Config): void {
|
||||||
// Remove event listeners added for handling uploads.
|
// Remove event listeners added for handling uploads.
|
||||||
$(config.file_input_identifier()).off("change");
|
$(config.file_input_identifier()).off("change");
|
||||||
config.banner_container().off("click");
|
config.banner_container().off("click");
|
||||||
|
@ -451,7 +491,7 @@ export function deactivate_upload(config) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initialize() {
|
export function initialize(): void {
|
||||||
compose_upload_object = setup_upload(compose_config);
|
compose_upload_object = setup_upload(compose_config);
|
||||||
|
|
||||||
$(".app, #navbar-fixed-container").on("dragstart", (event) => {
|
$(".app, #navbar-fixed-container").on("dragstart", (event) => {
|
||||||
|
@ -463,10 +503,14 @@ export function initialize() {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Allow the app panel to receive drag/drop events.
|
// Allow the app panel to receive drag/drop events.
|
||||||
$(".app, #navbar-fixed-container").on("dragover", (event) => event.preventDefault());
|
$(".app, #navbar-fixed-container").on("dragover", (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
// TODO: Do something visual to hint that drag/drop will work.
|
// TODO: Do something visual to hint that drag/drop will work.
|
||||||
$(".app, #navbar-fixed-container").on("dragenter", (event) => event.preventDefault());
|
$(".app, #navbar-fixed-container").on("dragenter", (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
$(".app, #navbar-fixed-container").on("drop", (event) => {
|
$(".app, #navbar-fixed-container").on("drop", (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
@ -477,6 +521,8 @@ export function initialize() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const $drag_drop_edit_containers = $(".message_edit_form form");
|
const $drag_drop_edit_containers = $(".message_edit_form form");
|
||||||
|
assert(event.originalEvent !== undefined);
|
||||||
|
assert(event.originalEvent.dataTransfer !== null);
|
||||||
const files = event.originalEvent.dataTransfer.files;
|
const files = event.originalEvent.dataTransfer.files;
|
||||||
const $last_drag_drop_edit_container = $drag_drop_edit_containers.last();
|
const $last_drag_drop_edit_container = $drag_drop_edit_containers.last();
|
||||||
|
|
||||||
|
@ -496,6 +542,7 @@ export function initialize() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const edit_upload_object = upload_objects_by_message_edit_row.get(row_id);
|
const edit_upload_object = upload_objects_by_message_edit_row.get(row_id);
|
||||||
|
assert(edit_upload_object !== undefined);
|
||||||
|
|
||||||
upload_files(edit_upload_object, edit_config(row_id), files);
|
upload_files(edit_upload_object, edit_config(row_id), files);
|
||||||
} else if (message_lists.current?.selected_message()) {
|
} else if (message_lists.current?.selected_message()) {
|
|
@ -10,8 +10,8 @@ const blueslip_stacktrace = zrequire("blueslip_stacktrace");
|
||||||
run_test("clean_path", () => {
|
run_test("clean_path", () => {
|
||||||
// Local file
|
// Local file
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
blueslip_stacktrace.clean_path("webpack:///web/src/upload.js"),
|
blueslip_stacktrace.clean_path("webpack:///web/src/upload.ts"),
|
||||||
"/web/src/upload.js",
|
"/web/src/upload.ts",
|
||||||
);
|
);
|
||||||
|
|
||||||
// Third party library (jQuery)
|
// Third party library (jQuery)
|
||||||
|
@ -36,9 +36,9 @@ run_test("clean_function_name", () => {
|
||||||
|
|
||||||
// Local file
|
// Local file
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
blueslip_stacktrace.clean_function_name("Object../web/src/upload.js.exports.options"),
|
blueslip_stacktrace.clean_function_name("Object../web/src/upload.ts.exports.options"),
|
||||||
{
|
{
|
||||||
scope: "Object../web/src/upload.js.exports.",
|
scope: "Object../web/src/upload.ts.exports.",
|
||||||
name: "options",
|
name: "options",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -7,6 +7,13 @@ const {run_test, noop} = require("./lib/test");
|
||||||
const $ = require("./lib/zjquery");
|
const $ = require("./lib/zjquery");
|
||||||
const {realm} = require("./lib/zpage_params");
|
const {realm} = require("./lib/zpage_params");
|
||||||
|
|
||||||
|
class ClipboardEvent {
|
||||||
|
constructor({clipboardData}) {
|
||||||
|
this.clipboardData = clipboardData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_global("ClipboardEvent", ClipboardEvent);
|
||||||
|
|
||||||
set_global("navigator", {
|
set_global("navigator", {
|
||||||
userAgent: "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)",
|
userAgent: "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)",
|
||||||
});
|
});
|
||||||
|
@ -60,7 +67,7 @@ test("config", () => {
|
||||||
upload.compose_config.upload_banner_hide_button("id_2"),
|
upload.compose_config.upload_banner_hide_button("id_2"),
|
||||||
$("#compose_banners .upload_banner.file_id_2 .main-view-banner-close-button"),
|
$("#compose_banners .upload_banner.file_id_2 .main-view-banner-close-button"),
|
||||||
);
|
);
|
||||||
assert.equal(upload.compose_config.file_input_identifier(), "#compose .file_input");
|
assert.equal(upload.compose_config.file_input_identifier(), "#compose input.file_input");
|
||||||
assert.equal(upload.compose_config.source(), "compose-file-input");
|
assert.equal(upload.compose_config.source(), "compose-file-input");
|
||||||
assert.equal(upload.compose_config.drag_drop_container(), $("#compose"));
|
assert.equal(upload.compose_config.drag_drop_container(), $("#compose"));
|
||||||
assert.equal(
|
assert.equal(
|
||||||
|
@ -70,7 +77,7 @@ test("config", () => {
|
||||||
|
|
||||||
assert.equal(
|
assert.equal(
|
||||||
upload.edit_config(1).textarea(),
|
upload.edit_config(1).textarea(),
|
||||||
$(`#edit_form_${CSS.escape(1)} .message_edit_content`),
|
$(`#edit_form_${CSS.escape(1)} textarea.message_edit_content`),
|
||||||
);
|
);
|
||||||
|
|
||||||
$(`#edit_form_${CSS.escape(2)}`).set_find_results(
|
$(`#edit_form_${CSS.escape(2)}`).set_find_results(
|
||||||
|
@ -117,7 +124,7 @@ test("config", () => {
|
||||||
|
|
||||||
assert.equal(
|
assert.equal(
|
||||||
upload.edit_config(123).file_input_identifier(),
|
upload.edit_config(123).file_input_identifier(),
|
||||||
`#edit_form_${CSS.escape(123)} .file_input`,
|
`#edit_form_${CSS.escape(123)} input.file_input`,
|
||||||
);
|
);
|
||||||
assert.equal(upload.edit_config(123).source(), "message-edit-file-input");
|
assert.equal(upload.edit_config(123).source(), "message-edit-file-input");
|
||||||
assert.equal(
|
assert.equal(
|
||||||
|
@ -343,7 +350,7 @@ test("uppy_config", () => {
|
||||||
test("file_input", ({override_rewire}) => {
|
test("file_input", ({override_rewire}) => {
|
||||||
upload.setup_upload(upload.compose_config);
|
upload.setup_upload(upload.compose_config);
|
||||||
|
|
||||||
const change_handler = $("#compose .file_input").get_on_handler("change");
|
const change_handler = $("#compose input.file_input").get_on_handler("change");
|
||||||
const files = ["file1", "file2"];
|
const files = ["file1", "file2"];
|
||||||
const event = {
|
const event = {
|
||||||
target: {
|
target: {
|
||||||
|
@ -417,7 +424,7 @@ test("copy_paste", ({override, override_rewire}) => {
|
||||||
const paste_handler = $("#compose").get_on_handler("paste");
|
const paste_handler = $("#compose").get_on_handler("paste");
|
||||||
let get_as_file_called = false;
|
let get_as_file_called = false;
|
||||||
let event = {
|
let event = {
|
||||||
originalEvent: {
|
originalEvent: new ClipboardEvent({
|
||||||
clipboardData: {
|
clipboardData: {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
|
@ -428,10 +435,11 @@ test("copy_paste", ({override, override_rewire}) => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
kind: "notfile",
|
kind: "notfile",
|
||||||
|
getAsFile: () => null,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
}),
|
||||||
preventDefault() {},
|
preventDefault() {},
|
||||||
};
|
};
|
||||||
let upload_files_called = false;
|
let upload_files_called = false;
|
||||||
|
@ -449,7 +457,7 @@ test("copy_paste", ({override, override_rewire}) => {
|
||||||
assert.ok(compose_actions_start_called);
|
assert.ok(compose_actions_start_called);
|
||||||
upload_files_called = false;
|
upload_files_called = false;
|
||||||
event = {
|
event = {
|
||||||
originalEvent: {},
|
originalEvent: new ClipboardEvent({}),
|
||||||
};
|
};
|
||||||
paste_handler(event);
|
paste_handler(event);
|
||||||
assert.equal(upload_files_called, false);
|
assert.equal(upload_files_called, false);
|
||||||
|
@ -585,7 +593,7 @@ test("uppy_events", ({override_rewire, mock_template}) => {
|
||||||
assert.ok(compose_ui_replace_syntax_called);
|
assert.ok(compose_ui_replace_syntax_called);
|
||||||
|
|
||||||
compose_ui_replace_syntax_called = false;
|
compose_ui_replace_syntax_called = false;
|
||||||
on_upload_error_callback(file, null, null);
|
on_upload_error_callback(file, null, undefined);
|
||||||
assert.ok(compose_ui_replace_syntax_called);
|
assert.ok(compose_ui_replace_syntax_called);
|
||||||
|
|
||||||
$("#compose_banners .upload_banner .upload_msg").text("");
|
$("#compose_banners .upload_banner .upload_msg").text("");
|
||||||
|
|
Loading…
Reference in New Issue