256 lines
8.6 KiB
JavaScript

var contentTable;
contentOptions = null;
channelResolveInterval = null;
async function initContentTable() {
contentOptions = await getTrackedContentOptions();
await initTable("#contentTabPane", "contentTable", loadContent, null, deleteSelectedContent, contentOptions);
contentTable = $("#contentTable").DataTable({
info: false,
paging: false,
ordering: false,
searching: false,
autoWidth: false,
order: [],
select: {
style: "multi+shift",
selector: 'th:first-child input[type="checkbox"]'
},
columnDefs: [
{ orderable: false, targets: "no-sort" },
{
targets: 0,
checkboxes: { selectRow: true }
}
],
columns: [
{
// Select row checkbox column
title: '<input type="checkbox" class="form-check-input table-select-all" />',
data: null,
orderable: false,
className: "text-center col-switch-width",
render: function() {
return '<input type="checkbox" class="form-check-input table-select-row" />'
}
},
{ data: "id", visible: false },
{
title: "GUID",
data: "guid",
className: "text-truncate mw-10rem",
},
{
title: "Name",
data: "title",
className: "text-truncate",
render: function(data, type, row) {
const title = sanitise(data);
const url = sanitise(row.url);
return `<a href="${url}" class="btn btn-link text-start text-decoration-none" target="_blank">${title}</a>`
}
},
{
title: "Subscription",
data: "subscription.name",
className: "text-nowrap",
render: function(data, type, row) {
const subName = sanitise(data);
return `<button type="button" onclick="goToSubscription(${row.subscription.id})" class="btn btn-link text-start text-decoration-none">${subName}</button>`
}
},
{
title: "Blocked",
data: "blocked",
className: "text-center col-1",
render: function(data) {
return data ? `<i class="bi bi-check-lg text-success"></i>` : ""
}
},
{
title: "Channel",
data: "channel_id",
className: "text-start",
render: function(data, type, row) {
const channelId = sanitise(data);
const messageId = sanitise(row.message_id);
return `<div class="resolve-channel-name text-center" data-channel-id="${channelId}" data-msg-id="${messageId}">
<div class="spinner-border spinner-border-sm" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</div>`;
}
},
{
title: "Created",
data: "creation_datetime",
className: "text-nowrap",
render: function(data, type) {
let dateTime = new Date(data);
return $(`
<span data-bs-trigger="hover focus"
data-bs-html="true"
data-bs-custom-class="text-center"
data-bs-toggle="popover"
data-bs-content="${formatStringDate(dateTime, "%a, %D %B, %Y<br>%H:%M:%S")}">
${formatStringDate(dateTime, "%D, %b %Y")}
</span>
`).popover()[0];
}
},
{
orderable: false,
className: "p-0",
render: function(data, type, row) {
const embedColour = sanitise(row.subscription.embed_colour);
return `<div class="h-100" style="background-color: #${embedColour}; width: .25rem;">&nbsp;</div>`
}
}
]
});
bindTableCheckboxes("#contentTable", contentTable, "#contentTabPane .table-del-btn");
contentTable.on("draw", function() {
restartResolveChannelNamesTask();
});
}
// #region Resolve Channels
function restartResolveChannelNamesTask() {
clearInterval(channelResolveInterval);
startResolveChannelNamesTask();
}
function startResolveChannelNamesTask() {
const guildId = getCurrentlyActiveServer().guild_id;
channelResolveInterval = setInterval(function() {
if (resolveChannelNames(guildId))
clearInterval(channelResolveInterval);
}, 50)
}
function resolveChannelNames(guildId) {
if (!discordChannels.length) {
return false
}
$(".resolve-channel-name").each(function() {
const channelId = $(this).data("channel-id");
const messageId = $(this).data("msg-id");
console.log(channelId + " " + messageId);
const channel = discordChannels.find(channel => channel.value === channelId);
if (channel) {
const href = `https://discord.com/channels/${guildId}/${channelId}/${messageId}/`;
$(this).replaceWith(
$("<a>").text(channel.text)
.attr("href", href)
.attr("target", "_blank")
.addClass("btn btn-link text-start text-decoration-none text-nowrap")
);
}
});
return true;
}
// #endregion
async function goToSubscription(subId) {
$("#subscriptionsTab").click();
await showEditSubModal(subId);
}
// #region Delete Content
async function deleteSelectedContent() {
const rows = contentTable.rows(".selected").data().toArray();
const names = rows.map(row => { return row.title });
const namesString = arrayToHtmlList(names, true).prop("outerHTML");
const isMany = names.length > 1;
await confirmationModal(
`Delete ${isMany ? "Many Tracked Contents" : "a Tracked Content"}`,
`Do you wish to permanently delete ${isMany ? "these" : "this"} <b>${names.length}</b> Tracked Content${isMany ? "s" : ""}?<br><br>${namesString}`,
"danger",
async () => {
rows.forEach(async row => { await deleteTrackedContent(row.id) });
showToast(
"danger",
`Deleted ${names.length} Content${isMany ? "s" : ""}`,
`${arrayToHtmlList(names, false).prop("outerHTML")}`,
12000
);
// Multi-deletion can take time, this timeout ensures the refresh is accurate
setTimeout(async () => {
await loadContent(getCurrentlyActiveServer().guild_id);
}, 600);
},
null
);
}
// #endregion
function clearExistingContentRows() {
$("#contentTable thead .table-select-all").prop("checked", false).prop("indeterminate", false);
contentTable.clear().draw(false);
}
$("#contentTabPane").on("click", ".table-refresh-btn", async function() {
await loadContent(getCurrentlyActiveServer().guild_id);
});
// #region Load Content
async function loadContent(guildId) {
if (!guildId)
return;
setTableFilter("contentTable", "subscription__guild_id", guildId);
ensureTablePagination("contentTable");
$("#contentTabPane .table-del-btn").prop("disabled", true);
clearExistingContentRows();
try {
var content = await getTrackedContent(tableFilters["contentTable"], tableSorts["contentTable"]);
contentTable.rows.add(content.results).draw(false);
}
catch (err) {
console.error(err);
showToast("danger", `Error loading Tracked Content: HTTP ${err.status}`, err, 15000);
return;
}
updateTableContainer(
"contentTabPane",
tableFilters["contentTable"]["page"],
tableFilters["contentTable"]["page_size"],
content.results.length,
content.count,
content.next,
content.previous
);
$("#contentTable thead .table-select-all").prop("disabled", content.results.length === 0);
console.debug(`loaded filters, ${content.results.length} found`)
}
$(document).on("selectedServerChange", async function() {
const activeServer = getCurrentlyActiveServer();
await loadContent(activeServer.guild_id);
});
// #endregion