256 lines
8.6 KiB
JavaScript
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;"> </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
|