2020-09-12 15:49:20 +02:00
|
|
|
import {createErrorModal, createModal} from "../../ui/elements/Modal";
|
2021-01-10 17:36:57 +01:00
|
|
|
import {LogCategory, logError} from "../../log";
|
2020-09-12 15:49:20 +02:00
|
|
|
import {ConnectionHandler} from "../../ConnectionHandler";
|
|
|
|
import {base64_encode_ab} from "../../utils/buffers";
|
|
|
|
import {ClientEntry} from "../../tree/Client";
|
2021-03-14 19:39:08 +01:00
|
|
|
import moment from "moment";
|
2021-01-10 17:36:57 +01:00
|
|
|
import {tr} from "tc-shared/i18n/localize";
|
2021-04-24 14:52:08 +02:00
|
|
|
import {promptYesNo} from "tc-shared/ui/modal/yes-no/Controller";
|
2020-03-30 13:44:18 +02:00
|
|
|
|
|
|
|
const avatar_to_uid = (id: string) => {
|
|
|
|
const buffer = new Uint8Array(id.length / 2);
|
2020-09-12 15:49:20 +02:00
|
|
|
for (let index = 0; index < id.length; index += 2) {
|
2020-03-30 13:44:18 +02:00
|
|
|
const upper_nibble = id.charCodeAt(index) - 97;
|
|
|
|
const lower_nibble = id.charCodeAt(index + 1) - 97;
|
|
|
|
buffer[index / 2] = (upper_nibble << 4) | lower_nibble;
|
|
|
|
}
|
|
|
|
return base64_encode_ab(buffer);
|
|
|
|
};
|
|
|
|
|
|
|
|
export const human_file_size = (size: number) => {
|
2020-09-12 15:49:20 +02:00
|
|
|
if (size < 1000)
|
2020-03-30 13:44:18 +02:00
|
|
|
return size + "B";
|
|
|
|
const exp = Math.floor(Math.log2(size) / 10);
|
|
|
|
return (size / Math.pow(1024, exp)).toFixed(2) + 'KMGTPE'.charAt(exp - 1) + "iB";
|
|
|
|
};
|
|
|
|
|
|
|
|
export function spawnAvatarList(client: ConnectionHandler) {
|
|
|
|
const modal = createModal({
|
|
|
|
header: tr("Avatars"),
|
|
|
|
footer: undefined,
|
|
|
|
body: () => {
|
2021-04-19 13:27:09 +02:00
|
|
|
return $("#tmpl_avatar_list").renderTag({});
|
2020-03-30 13:44:18 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
let callback_download: () => any;
|
|
|
|
let callback_delete: () => any;
|
|
|
|
|
|
|
|
const button_download = modal.htmlTag.find(".button-download");
|
|
|
|
const button_delete = modal.htmlTag.find(".button-delete");
|
|
|
|
const container_list = modal.htmlTag.find(".container-list .list-entries-container");
|
|
|
|
const list_entries = container_list.find(".list-entries");
|
|
|
|
const container_info = modal.htmlTag.find(".container-info");
|
|
|
|
const overlay_no_user = container_info.find(".disabled-overlay").show();
|
|
|
|
|
|
|
|
const set_selected_avatar = (unique_id: string, avatar_id: string, size: number) => {
|
|
|
|
button_download.prop("disabled", true);
|
|
|
|
callback_download = undefined;
|
2020-09-12 15:49:20 +02:00
|
|
|
if (!unique_id) {
|
2020-03-30 13:44:18 +02:00
|
|
|
overlay_no_user.show();
|
|
|
|
return;
|
2019-03-25 20:04:04 +01:00
|
|
|
}
|
|
|
|
|
2020-03-30 13:44:18 +02:00
|
|
|
const tag_username = container_info.find(".property-username");
|
|
|
|
const tag_unique_id = container_info.find(".property-unique-id");
|
|
|
|
const tag_avatar_id = container_info.find(".property-avatar-id");
|
|
|
|
const container_avatar = container_info.find(".container-image");
|
|
|
|
const tag_image_bytes = container_info.find(".property-image-size");
|
|
|
|
const tag_image_width = container_info.find(".property-image-width").val(tr("loading..."));
|
|
|
|
const tag_image_height = container_info.find(".property-image-height").val(tr("loading..."));
|
|
|
|
const tag_image_type = container_info.find(".property-image-type").val(tr("loading..."));
|
|
|
|
|
|
|
|
tag_username.val("unknown");
|
|
|
|
tag_unique_id.val(unique_id);
|
|
|
|
tag_avatar_id.val(avatar_id);
|
|
|
|
tag_image_bytes.val(size);
|
|
|
|
|
2020-07-12 16:31:57 +02:00
|
|
|
/* FIXME!
|
2020-03-30 13:44:18 +02:00
|
|
|
container_avatar.empty().append(client.fileManager.avatars.generate_tag(avatar_id, undefined, {
|
|
|
|
callback_image: image => {
|
|
|
|
tag_image_width.val(image[0].naturalWidth + 'px');
|
|
|
|
tag_image_height.val(image[0].naturalHeight + 'px');
|
|
|
|
},
|
|
|
|
callback_avatar: avatar => {
|
|
|
|
tag_image_type.val(media_image_type(avatar.type));
|
|
|
|
button_download.prop("disabled", false);
|
|
|
|
|
|
|
|
callback_download = () => {
|
|
|
|
const element = $.spawn("a")
|
|
|
|
.text("download")
|
|
|
|
.attr("href", avatar.url)
|
|
|
|
.attr("download", "avatar-" + unique_id + "." + media_image_type(avatar.type, true))
|
|
|
|
.css("display", "none")
|
|
|
|
.appendTo($("body"));
|
|
|
|
element[0].click();
|
|
|
|
element.remove();
|
|
|
|
};
|
2019-03-25 20:04:04 +01:00
|
|
|
}
|
2020-03-30 13:44:18 +02:00
|
|
|
}));
|
2020-07-12 16:31:57 +02:00
|
|
|
*/
|
2019-03-25 20:04:04 +01:00
|
|
|
|
2020-03-30 13:44:18 +02:00
|
|
|
callback_delete = () => {
|
2021-04-24 14:52:08 +02:00
|
|
|
promptYesNo({
|
|
|
|
title: tr("Are you sure?"),
|
|
|
|
question: tr("Do you really want to delete this avatar?"),
|
|
|
|
}).then(result => {
|
2020-09-12 15:49:20 +02:00
|
|
|
if (result) {
|
2020-03-30 13:44:18 +02:00
|
|
|
createErrorModal(tr("Not implemented"), tr("Avatar delete hasn't implemented yet")).open();
|
|
|
|
//TODO Implement avatar delete
|
2019-03-25 20:04:04 +01:00
|
|
|
}
|
2020-03-30 13:44:18 +02:00
|
|
|
});
|
|
|
|
};
|
|
|
|
overlay_no_user.hide();
|
|
|
|
};
|
|
|
|
set_selected_avatar(undefined, undefined, 0);
|
|
|
|
|
|
|
|
const update_avatar_list = () => {
|
|
|
|
const template_entry = $("#tmpl_avatar_list-list_entry");
|
|
|
|
list_entries.empty();
|
|
|
|
|
|
|
|
client.fileManager.requestFileList("/").then(files => {
|
2020-09-12 15:49:20 +02:00
|
|
|
const username_resolve: { [unique_id: string]: ((name: string) => any)[] } = {};
|
|
|
|
for (const entry of files) {
|
2020-03-30 13:44:18 +02:00
|
|
|
const avatar_id = entry.name.substr('avatar_'.length);
|
|
|
|
const unique_id = avatar_to_uid(avatar_id);
|
|
|
|
|
|
|
|
const tag = template_entry.renderTag({
|
|
|
|
username: 'loading',
|
|
|
|
unique_id: unique_id,
|
|
|
|
size: human_file_size(entry.size),
|
|
|
|
timestamp: moment(entry.datetime * 1000).format('YY-MM-DD HH:mm')
|
|
|
|
});
|
2019-03-25 20:04:04 +01:00
|
|
|
|
2020-03-30 13:44:18 +02:00
|
|
|
(username_resolve[unique_id] || (username_resolve[unique_id] = [])).push(name => {
|
|
|
|
const tag_username = tag.find(".column-username").empty();
|
2020-09-12 15:49:20 +02:00
|
|
|
if (name) {
|
2020-03-30 13:44:18 +02:00
|
|
|
tag_username.append(ClientEntry.chatTag(0, name, unique_id, false));
|
|
|
|
} else {
|
|
|
|
tag_username.text("unknown");
|
2019-03-25 20:04:04 +01:00
|
|
|
}
|
|
|
|
});
|
2020-03-30 13:44:18 +02:00
|
|
|
list_entries.append(tag);
|
2019-03-25 20:04:04 +01:00
|
|
|
|
2020-03-30 13:44:18 +02:00
|
|
|
tag.on('click', () => {
|
|
|
|
list_entries.find('.selected').removeClass('selected');
|
|
|
|
tag.addClass('selected');
|
2019-03-25 20:04:04 +01:00
|
|
|
|
2020-03-30 13:44:18 +02:00
|
|
|
set_selected_avatar(unique_id, avatar_id, entry.size);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-09-12 15:49:20 +02:00
|
|
|
if (container_list.hasScrollBar())
|
2020-03-30 13:44:18 +02:00
|
|
|
container_list.addClass("scrollbar");
|
|
|
|
|
2020-09-07 12:42:00 +02:00
|
|
|
client.serverConnection.command_helper.getInfoFromUniqueId(...Object.keys(username_resolve)).then(result => {
|
2020-09-12 15:49:20 +02:00
|
|
|
for (const info of result) {
|
2020-09-07 12:42:00 +02:00
|
|
|
username_resolve[info.clientUniqueId].forEach(e => e(info.clientNickname));
|
|
|
|
delete username_resolve[info.clientUniqueId];
|
2020-03-30 13:44:18 +02:00
|
|
|
}
|
2020-09-12 15:49:20 +02:00
|
|
|
for (const uid of Object.keys(username_resolve)) {
|
2020-03-30 13:44:18 +02:00
|
|
|
(username_resolve[uid] || []).forEach(e => e(undefined));
|
|
|
|
}
|
2019-03-25 20:04:04 +01:00
|
|
|
}).catch(error => {
|
2021-01-10 17:36:57 +01:00
|
|
|
logError(LogCategory.GENERAL, tr("Failed to fetch usernames from avatar names. Error: %o"), error);
|
2020-03-30 13:44:18 +02:00
|
|
|
createErrorModal(tr("Failed to fetch usernames"), tr("Failed to fetch usernames related to their avatar names"), undefined).open();
|
|
|
|
})
|
|
|
|
}).catch(error => {
|
|
|
|
//TODO: Display no perms error
|
2021-01-10 17:36:57 +01:00
|
|
|
logError(LogCategory.GENERAL, tr("Failed to receive avatar list. Error: %o"), error);
|
2020-03-30 13:44:18 +02:00
|
|
|
createErrorModal(tr("Failed to list avatars"), tr("Failed to receive avatar list."), undefined).open();
|
|
|
|
});
|
|
|
|
};
|
2019-03-25 20:04:04 +01:00
|
|
|
|
2020-09-12 15:49:20 +02:00
|
|
|
button_download.on('click', () => (callback_download || (() => {
|
|
|
|
}))());
|
|
|
|
button_delete.on('click', () => (callback_delete || (() => {
|
|
|
|
}))());
|
2020-03-30 13:44:18 +02:00
|
|
|
setTimeout(() => update_avatar_list(), 250);
|
|
|
|
modal.open();
|
2019-03-25 20:04:04 +01:00
|
|
|
}
|