embed colour, and filter table abstract functions
This commit is contained in:
parent
5a3b458f3e
commit
8864ac9cc0
@ -147,7 +147,7 @@ class SubscriptionSerializer_GET(DynamicModelSerializer):
|
||||
model = Subscription
|
||||
fields = (
|
||||
"id", "name", "url", "guild_id", "channels_count", "creation_datetime", "extra_notes",
|
||||
"filters", "article_title_mutators", "article_desc_mutators", "active"
|
||||
"filters", "article_title_mutators", "article_desc_mutators", "embed_colour", "active"
|
||||
)
|
||||
|
||||
|
||||
@ -160,7 +160,7 @@ class SubscriptionSerializer_POST(DynamicModelSerializer):
|
||||
model = Subscription
|
||||
fields = (
|
||||
"id", "name", "url", "guild_id", "channels_count", "creation_datetime", "extra_notes",
|
||||
"filters", "article_title_mutators", "article_desc_mutators", "active"
|
||||
"filters", "article_title_mutators", "article_desc_mutators", "embed_colour", "active"
|
||||
)
|
||||
|
||||
|
||||
|
@ -189,7 +189,7 @@ class Subscription_ListView(generics.ListCreateAPIView):
|
||||
filter_backends = [filters.SearchFilter, rest_filters.DjangoFilterBackend, filters.OrderingFilter]
|
||||
filterset_fields = [
|
||||
"id", "name", "url", "guild_id", "creation_datetime", "extra_notes", "filters",
|
||||
"article_title_mutators", "article_desc_mutators", "active"
|
||||
"article_title_mutators", "article_desc_mutators", "embed_colour", "active"
|
||||
]
|
||||
search_fields = ["name", "extra_notes"]
|
||||
ordering_fields = ["creation_datetime", "guild_id"]
|
||||
|
18
apps/home/migrations/0009_subscription_embed_colour.py
Normal file
18
apps/home/migrations/0009_subscription_embed_colour.py
Normal file
@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.0.4 on 2024-06-26 13:12
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('home', '0008_subscription_article_fetch_limit_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='subscription',
|
||||
name='embed_colour',
|
||||
field=models.CharField(default='3498db', max_length=6),
|
||||
),
|
||||
]
|
@ -224,6 +224,12 @@ class Subscription(models.Model):
|
||||
|
||||
reset_article_fetch_limit = models.BooleanField(default=False)
|
||||
|
||||
embed_colour = models.CharField(
|
||||
max_length=6,
|
||||
default="3498db",
|
||||
blank=True
|
||||
)
|
||||
|
||||
active = models.BooleanField(default=True)
|
||||
|
||||
class Meta:
|
||||
|
@ -30,6 +30,18 @@
|
||||
transition: border-radius .15s ease-in;
|
||||
}
|
||||
|
||||
/* widths */
|
||||
|
||||
.mw-10rem {
|
||||
max-width: 10rem;
|
||||
}
|
||||
|
||||
.col-switch-width {
|
||||
width: 3.5rem;
|
||||
min-width: 3.5rem;
|
||||
max-width: 3.5rem;
|
||||
}
|
||||
|
||||
/* tables */
|
||||
|
||||
.table {
|
||||
@ -43,4 +55,15 @@
|
||||
|
||||
.table.dataTable > tbody > tr.selected a {
|
||||
color: var(--bs-link-color) !important;
|
||||
}
|
||||
|
||||
/* Fuck ugly <td> height fix */
|
||||
td {
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
@-moz-document url-prefix() {
|
||||
.fix_height {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
@ -24,13 +24,17 @@ function initContentTable() {
|
||||
title: '<input type="checkbox" class="form-check-input table-select-all" />',
|
||||
data: null,
|
||||
orderable: false,
|
||||
className: "text-center col-1",
|
||||
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", visible: false },
|
||||
{
|
||||
title: "GUID",
|
||||
data: "guid",
|
||||
className: "text-truncate mw-10rem",
|
||||
},
|
||||
{
|
||||
title: "Name",
|
||||
data: "title",
|
||||
@ -60,9 +64,25 @@ function initContentTable() {
|
||||
data: "creation_datetime",
|
||||
className: "text-nowrap",
|
||||
render: function(data, type) {
|
||||
return `<small>${new Date(data).toISOString().replace('T', ' · ').replace(/\.\d+Z$/, '')}</small>`;
|
||||
// return new Date(data).toISOString().split("T")[0];
|
||||
let dateTime = new Date(data);
|
||||
let dateTimeString = formatDate(dateTime);
|
||||
return $(`
|
||||
<small data-bs-trigger="hover focus"
|
||||
data-bs-toggle="popover"
|
||||
data-bs-content="${dateTimeString}">
|
||||
${dateTime.toISOString().split("T")[0]}
|
||||
</small>
|
||||
`).popover()[0];
|
||||
}
|
||||
},
|
||||
{
|
||||
orderable: false,
|
||||
className: "p-0",
|
||||
render: function(data, type, row) {
|
||||
return `<div class="h-100" style="background-color: #${row.subscription.embed_colour}; width: .25rem;"> </div>`
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
@ -108,7 +128,10 @@ async function loadContent(guildId, page=1, pageSize=null) {
|
||||
try {
|
||||
const content = await getTrackedContent(guildId, null, page, pageSize);
|
||||
contentTable.rows.add(content.results).draw(false);
|
||||
handleContentPagination(page, pageSize, content.count, content.next, content.previous);
|
||||
|
||||
updateTablePagination("#contentPagination", page, pageSize, content.count, content.next, content.previous);
|
||||
updateTablePaginationInfo("#contentTablePageInfo", content.results.length, content.count);
|
||||
|
||||
$("#contentTable thead .table-select-all").prop("disabled", content.results.length === 0);
|
||||
}
|
||||
catch (err) {
|
||||
@ -121,60 +144,3 @@ $(document).on("selectedServerChange", async function() {
|
||||
const activeServer = getCurrentlyActiveServer();
|
||||
await loadContent(activeServer.guild_id);
|
||||
});
|
||||
|
||||
$("#contentTablePageSize").on("change", async function() {
|
||||
const page = 1; // reset to page 1 to ensure the page exists.
|
||||
const pageSize = $(this).val();
|
||||
|
||||
loadContent(getCurrentlyActiveServer().guild_id, page, pageSize);
|
||||
});
|
||||
|
||||
function handleContentPagination(currentPage, pageSize, totalItems, nextExists, prevExists) {
|
||||
|
||||
$("#contentPagination").attr("data-page", currentPage);
|
||||
|
||||
// Remove existing page-specific buttons
|
||||
$("#contentPagination .page-pick").remove();
|
||||
|
||||
// Determine states of 'previous page' and 'next page' buttons
|
||||
$("#contentPagination .page-prev").toggleClass("disabled", !prevExists).attr("tabindex", prevExists ? "" : "-1");
|
||||
$("#contentPagination .page-next").toggleClass("disabled", !nextExists).attr("tabindex", nextExists ? "" : "-1");
|
||||
|
||||
// Calculate amount of pages to account for
|
||||
const pages = Math.max(Math.ceil(totalItems / pageSize), 1);
|
||||
|
||||
// Create a button for each page
|
||||
for (let i = 1; i < pages + 1; i++) {
|
||||
let pageItem = $("<li>").addClass("page-item");
|
||||
let pageLink = $("<button>")
|
||||
.attr("type", "button")
|
||||
.attr("data-page", i)
|
||||
.addClass("page-link page-pick")
|
||||
.text(i)
|
||||
|
||||
pageItem.append(pageLink);
|
||||
|
||||
// Insert the new page button before the 'next page' button
|
||||
$("#contentPagination .pagination .page-next").parent().before(pageItem);
|
||||
}
|
||||
|
||||
// Disable the button for the current page
|
||||
$(`#contentPagination .pagination .page-pick[data-page="${currentPage}"]`).addClass("disabled").attr("tabindex", -1);
|
||||
}
|
||||
|
||||
$("#contentPagination .pagination").on("click", ".page-link", async function() {
|
||||
|
||||
let wantedPage;
|
||||
let currentPage = parseInt($("#contentPagination").attr("data-page"));
|
||||
|
||||
if ($(this).hasClass("page-prev"))
|
||||
wantedPage = currentPage - 1
|
||||
else if ($(this).hasClass("page-next"))
|
||||
wantedPage = currentPage + 1;
|
||||
else
|
||||
wantedPage = $(this).attr("data-page");
|
||||
|
||||
console.debug("moving to page: " + wantedPage);
|
||||
|
||||
await loadContent(getCurrentlyActiveServer().guild_id, wantedPage)
|
||||
});
|
@ -25,7 +25,7 @@ function initFiltersTable() {
|
||||
title: '<input type="checkbox" class="form-check-input table-select-all" />',
|
||||
data: null,
|
||||
orderable: false,
|
||||
className: "text-center col-1",
|
||||
className: "text-center col-switch-width",
|
||||
render: function() {
|
||||
return '<input type="checkbox" class="form-check-input table-select-row" />'
|
||||
}
|
||||
@ -39,23 +39,22 @@ function initFiltersTable() {
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "Keywords",
|
||||
data: "keywords",
|
||||
render: function(data, type) {
|
||||
if (!data) return "-";
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "Regex",
|
||||
data: "regex",
|
||||
render: function(data, type) {
|
||||
if (!data) return "-";
|
||||
return data;
|
||||
title: "Match",
|
||||
// data: "keywords",
|
||||
className: "text-start text-truncate",
|
||||
render: function(data, type, row) {
|
||||
return row.regex ? row.regex : row.keywords;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "Type",
|
||||
// data: "regex",
|
||||
render: function(data, type, row) {
|
||||
return row.regex ? "Regex" : "Keywords";
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "Control List",
|
||||
data: "whitelist",
|
||||
render: function(data) {
|
||||
return data ? "whitelist" : "blacklist";
|
||||
@ -180,20 +179,28 @@ $("#refreshFilterBtn").on("click", async function() {
|
||||
loadFilters(getCurrentlyActiveServer().guild_id);
|
||||
});
|
||||
|
||||
async function loadFilters(guildId) {
|
||||
async function loadFilters(guildId, page=1, pageSize=null) {
|
||||
|
||||
if (!guildId)
|
||||
return;
|
||||
|
||||
if (!pageSize)
|
||||
pageSize = $("#filtersTablePageSize").val();
|
||||
|
||||
$("#deleteSelectedFiltersBtn").prop("disabled", true);
|
||||
clearExistingFilterRows();
|
||||
|
||||
try {
|
||||
const filters = await getFilters(guildId);
|
||||
filtersTable.rows.add(filters.results).draw(false);
|
||||
|
||||
updateTablePagination("#filtersPagination", page, pageSize, filters.count, filters.next, filters.previous);
|
||||
updateTablePaginationInfo("#filtersTablePageInfo", filters.results.length, filters.count);
|
||||
|
||||
$("#filtersTable thead .table-select-all").prop("disabled", filters.results.length === 0);
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err)
|
||||
console.error(JSON.stringify(err, null, 4));
|
||||
showToast("danger", `Error Loading Filters: HTTP ${err.status}`, err.responseJSON.message, 15000);
|
||||
}
|
||||
|
@ -14,6 +14,15 @@ $(document).ready(async function() {
|
||||
await bindTablePagination("#subPagination", loadSubscriptions);
|
||||
await bindTablePaginationResizer("#subTablePageSize", loadSubscriptions);
|
||||
|
||||
// Bind pagination filtersTable
|
||||
await bindTablePagination("#filtersPagination", loadFilters);
|
||||
await bindTablePaginationResizer("#filtersTablePageSize", loadFilters);
|
||||
|
||||
// Bind pagination - contentTable
|
||||
await bindTablePagination("#contentPagination", loadContent);
|
||||
await bindTablePaginationResizer("#contentTablePageSize", loadContent);
|
||||
|
||||
|
||||
await loadSavedGuilds();
|
||||
await loadServerOptions();
|
||||
});
|
||||
@ -72,3 +81,47 @@ function determineSelectAllState(tableSelector, tableObject, deleteButtonSelecto
|
||||
|
||||
$(deleteButtonSelector).prop("disabled", !(checked || indeterminate) || !(allRowsCount > 0));
|
||||
}
|
||||
|
||||
function formatDate(date) {
|
||||
|
||||
// Array of weekday names
|
||||
const weekdays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
|
||||
|
||||
// Array of month names
|
||||
const months = [
|
||||
"January", "February", "March", "April", "May", "June",
|
||||
"July", "August", "September", "October", "November", "December"
|
||||
];
|
||||
|
||||
// Get individual components
|
||||
let hours = String(date.getHours()).padStart(2, '0');
|
||||
let minutes = String(date.getMinutes()).padStart(2, '0');
|
||||
let seconds = String(date.getSeconds()).padStart(2, '0');
|
||||
let dayOfWeek = weekdays[date.getDay()];
|
||||
let dayOfMonth = date.getDate();
|
||||
let month = months[date.getMonth()];
|
||||
let year = date.getFullYear();
|
||||
|
||||
// Format day with ordinal suffix
|
||||
let dayOfMonthSuffix;
|
||||
if (dayOfMonth % 10 === 1 && dayOfMonth !== 11) {
|
||||
dayOfMonthSuffix = dayOfMonth + "st";
|
||||
} else if (dayOfMonth % 10 === 2 && dayOfMonth !== 12) {
|
||||
dayOfMonthSuffix = dayOfMonth + "nd";
|
||||
} else if (dayOfMonth % 10 === 3 && dayOfMonth !== 13) {
|
||||
dayOfMonthSuffix = dayOfMonth + "rd";
|
||||
} else {
|
||||
dayOfMonthSuffix = dayOfMonth + "th";
|
||||
}
|
||||
|
||||
// `${hours}:${minutes}:${seconds} · `
|
||||
return `${dayOfWeek}, ${dayOfMonthSuffix} ${month}, ${year}`;
|
||||
}
|
||||
|
||||
function genHexString(len) {
|
||||
let output = '';
|
||||
for (let i = 0; i < len; ++i) {
|
||||
output += (Math.floor(Math.random() * 16)).toString(16);
|
||||
}
|
||||
return output;
|
||||
}
|
@ -17,7 +17,7 @@ function initSubscriptionTable() {
|
||||
{
|
||||
targets: 0,
|
||||
checkboxes: { selectRow: true }
|
||||
}
|
||||
},
|
||||
],
|
||||
columns: [
|
||||
{
|
||||
@ -25,7 +25,7 @@ function initSubscriptionTable() {
|
||||
title: '<input type="checkbox" class="form-check-input table-select-all" />',
|
||||
data: null,
|
||||
orderable: false,
|
||||
className: "text-center",
|
||||
className: "text-center col-switch-width",
|
||||
render: function() {
|
||||
return '<input type="checkbox" class="form-check-input table-select-row" />'
|
||||
}
|
||||
@ -51,7 +51,7 @@ function initSubscriptionTable() {
|
||||
title: "Channels",
|
||||
data: "channels_count",
|
||||
render: function(data) {
|
||||
return `<span class="badge badge-secondary">${data}</span>`;
|
||||
return `<span class="badge text-bg-secondary">${data}</span>`;
|
||||
}
|
||||
},
|
||||
// {
|
||||
@ -64,9 +64,17 @@ function initSubscriptionTable() {
|
||||
{
|
||||
title: "Created",
|
||||
data: "creation_datetime",
|
||||
className: "small",
|
||||
render: function(data, type) {
|
||||
return new Date(data).toISOString().split("T")[0];
|
||||
// return new Date(data).toISOString().split("T")[0];
|
||||
let dateTime = new Date(data);
|
||||
let dateTimeString = formatDate(dateTime);
|
||||
return $(`
|
||||
<small data-bs-trigger="hover focus"
|
||||
data-bs-toggle="popover"
|
||||
data-bs-content="${dateTimeString}">
|
||||
${dateTime.toISOString().split("T")[0]}
|
||||
</small>
|
||||
`).popover()[0];
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -77,7 +85,13 @@ function initSubscriptionTable() {
|
||||
render: function(data, type) {
|
||||
if (!data) return "";
|
||||
return $(`
|
||||
<i class="bi bi-chat-left-text" data-bs-trigger="hover focus" data-bs-toggle="popover" data-bs-title="Extra Notes" data-bs-content="${data}"></i>`).popover()[0];
|
||||
<i class="bi bi-chat-left-text"
|
||||
data-bs-trigger="hover focus"
|
||||
data-bs-toggle="popover"
|
||||
data-bs-title="Extra Notes"
|
||||
data-bs-content="${data}">
|
||||
</i>
|
||||
`).popover()[0];
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -88,6 +102,13 @@ function initSubscriptionTable() {
|
||||
render: function(data, type) {
|
||||
return `<input type="checkbox" class="sub-toggle-active form-check-input ms-0" ${data ? "checked" : ""} />`
|
||||
}
|
||||
},
|
||||
{
|
||||
orderable: false,
|
||||
className: "p-0",
|
||||
render: function(data, type, row) {
|
||||
return `<div class="h-100" style="background-color: #${row.embed_colour}; width: .25rem;"> </div>`
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
@ -124,6 +145,7 @@ $("#subTable").on("change", ".sub-toggle-active", async function () {
|
||||
title: sub.article_title_mutators.map(mutator => mutator.id),
|
||||
desc: sub.article_desc_mutators.map(mutator => mutator.id)
|
||||
},
|
||||
sub.embed_colour,
|
||||
active,
|
||||
handleErrorMsg=false
|
||||
);
|
||||
@ -167,8 +189,10 @@ async function showEditSubModal(subId) {
|
||||
$("#subTitleMutators").val("").change();
|
||||
$("#subDescMutators").val("").change();
|
||||
$("#subActive").prop("checked", true);
|
||||
$("#subImagePreview img").attr("src", "").hide();
|
||||
$("#subImagePreview small").show();
|
||||
// $("#subImagePreview img").attr("src", "").hide();
|
||||
// $("#subImagePreview small").show();
|
||||
|
||||
$("#subResetEmbedColour").click();
|
||||
}
|
||||
else {
|
||||
$("#subFormModal .form-create, #subAdvancedModal .form-create").hide();
|
||||
@ -195,6 +219,8 @@ async function showEditSubModal(subId) {
|
||||
|
||||
$("#subFilters").val("").change();
|
||||
$("#subFilters").val(subscription.filters).change();
|
||||
|
||||
subSetHexColour(`#${subscription.embed_colour}`);
|
||||
}
|
||||
|
||||
$("#subId").val(subId);
|
||||
@ -215,9 +241,10 @@ $("#subForm").on("submit", async function(event) {
|
||||
title: $("#subTitleMutators option:selected").toArray().map(mutator => parseInt(mutator.value)),
|
||||
desc: $("#subDescMutators option:selected").toArray().map(mutator => parseInt(mutator.value))
|
||||
}
|
||||
subEmbedColour = $("#subEmbedColour").val().split("#")[1];
|
||||
active = $("#subActive").prop("checked");
|
||||
|
||||
var subPrimaryKey = await saveSubscription(id, name, url, guildId, extraNotes, subFilters, subMutators, active);
|
||||
var subPrimaryKey = await saveSubscription(id, name, url, guildId, extraNotes, subFilters, subMutators, subEmbedColour, active);
|
||||
|
||||
if (!subPrimaryKey) {
|
||||
alert("prevented /subscriptions/false/subchannels");
|
||||
@ -236,7 +263,7 @@ $("#subForm").on("submit", async function(event) {
|
||||
$("#subFormModal").modal("hide");
|
||||
});
|
||||
|
||||
async function saveSubscription(id, name, url, guildId, extraNotes, filters, mutators, active, handleErrorMsg=true) {
|
||||
async function saveSubscription(id, name, url, guildId, extraNotes, filters, mutators, embedColour, active, handleErrorMsg=true) {
|
||||
var formData = new FormData();
|
||||
formData.append("name", name);
|
||||
formData.append("url", url);
|
||||
@ -245,6 +272,7 @@ async function saveSubscription(id, name, url, guildId, extraNotes, filters, mut
|
||||
filters.forEach(filter => formData.append("filters", filter));
|
||||
mutators.title.forEach(mutator => formData.append("article_title_mutators", mutator));
|
||||
mutators.desc.forEach(mutator => formData.append("article_desc_mutators", mutator));
|
||||
formData.append("embed_colour", embedColour);
|
||||
formData.append("active", active);
|
||||
|
||||
var response;
|
||||
@ -315,11 +343,14 @@ async function loadSubscriptions(guildId, page=1, pageSize=null) {
|
||||
console.debug("loading subs, " + subscriptions.results.length + " found");
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err)
|
||||
console.error(JSON.stringify(err, null, 4));
|
||||
showToast("danger", `Error Loading Subscriptions: HTTP ${err.status}`, err.responseJSON.message, 15000);
|
||||
}
|
||||
}
|
||||
|
||||
// #region Server Change Event Handler
|
||||
|
||||
$(document).on("selectedServerChange", async function() {
|
||||
|
||||
// Hide alerts
|
||||
@ -332,6 +363,9 @@ $(document).on("selectedServerChange", async function() {
|
||||
await loadMutatorOptions();
|
||||
})
|
||||
|
||||
// #endregion
|
||||
|
||||
|
||||
// Dev button (to be removed)
|
||||
// auto fills dummy data into form fields to quickly create test subs
|
||||
$("#devGenerateSub").on("click", function() {
|
||||
@ -375,6 +409,9 @@ $("#devGenerateSub").on("click", function() {
|
||||
showToast("info", "Generated", "Picked random sub data");
|
||||
});
|
||||
|
||||
|
||||
// #region Delete Subscription Buttons
|
||||
|
||||
// Delete button on the 'edit subscription' modal
|
||||
$("#deleteEditSub").on("click", async function() {
|
||||
const subId = $("#subId").val();
|
||||
@ -397,6 +434,12 @@ $("#deleteSelectedSubscriptionsBtn").on("click", async function() {
|
||||
await loadSubscriptions(getCurrentlyActiveServer().guild_id);
|
||||
})
|
||||
|
||||
// #endregion
|
||||
|
||||
|
||||
|
||||
// #region Load Modal Options
|
||||
|
||||
async function loadChannelOptions(guildId) {
|
||||
|
||||
// Disable input while options are loading
|
||||
@ -531,6 +574,10 @@ async function loadFilterOptions(guildId) {
|
||||
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
|
||||
// #region Bot Not in Server Alert
|
||||
function showServerJoinAlert() {
|
||||
const guildId = getCurrentlyActiveServer().guild_id;
|
||||
const inviteUrl = `https://discord.com/oauth2/authorize
|
||||
@ -542,11 +589,31 @@ function showServerJoinAlert() {
|
||||
$("#serverJoinAlert a.alert-link").attr("href", inviteUrl);
|
||||
$("#serverJoinAlert").show();
|
||||
}
|
||||
// #endregion
|
||||
|
||||
$("#subImage").on("change", function () {
|
||||
const [file] = $("#subImage")[0].files;
|
||||
if (file) {
|
||||
$("#subImagePreview small").hide();
|
||||
$("#subImagePreview img").attr("src", URL.createObjectURL(file)).show();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// #region Colour Controls
|
||||
$("#subEmbedColour").on("change", function() {
|
||||
$("#subEmbedColourText").val($(this).val());
|
||||
});
|
||||
|
||||
$("#subEmbedColourText").on("change", function() {
|
||||
$("#subEmbedColour").val($(this).val());
|
||||
});
|
||||
|
||||
function subSetHexColour(hexString) {
|
||||
$("#subEmbedColour").val(hexString);
|
||||
$("#subEmbedColourText").val(hexString);
|
||||
}
|
||||
|
||||
$(document).ready(() => {$("#subResetEmbedColour").click();});
|
||||
|
||||
$("#subResetEmbedColour").on("click", function() {
|
||||
subSetHexColour("#3498db");
|
||||
});
|
||||
|
||||
$("#subRandomEmbedColour").on("click", function() {
|
||||
subSetHexColour(`#${genHexString(6)}`);
|
||||
});
|
||||
// #endregion
|
@ -39,11 +39,6 @@
|
||||
<select name="subFilters" id="subFilters" class="select-2" multiple data-dropdownparent="#subFormModal" tabindex="4"></select>
|
||||
<div class="form-text">Filters to apply to this subscription's content.</div>
|
||||
</div>
|
||||
<!-- <div>
|
||||
<label for="subMutators" class="form-label">Article Mutators</label>
|
||||
<select name="subMutators" id="subMutators" class="select-2" multiple data-dropdownparent="#subFormModal" tabindex="6"></select>
|
||||
<div class="form-text">Apply mutators to subscription articles.</div>
|
||||
</div> -->
|
||||
<div class="form-switch mb-4 ps-0">
|
||||
<label for="subActive" class="form-check-label mb-2">Active</label>
|
||||
<br>
|
||||
@ -97,19 +92,37 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6 pe-lg-4 d-none">
|
||||
<label for="" class="form-label">Article Fetch Limit</label>
|
||||
<input type="number" id="subFetchLimit" class="form-control rounded-1" max="10" min="1">
|
||||
<div class="form-text">Limit the number of articles fetched every cycle.</div>
|
||||
<div class="mb-4">
|
||||
<label for="" class="form-label">Article Fetch Limit</label>
|
||||
<input type="number" id="subFetchLimit" class="form-control rounded-1" max="10" min="1">
|
||||
<div class="form-text">Limit the number of articles fetched every cycle.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6 ps-lg-4 d-none">
|
||||
<div class="form-switch ps-0">
|
||||
<div class="form-switch ps-0 mb-4">
|
||||
<label for="subResetFetchLimit" class="form-check-label mb-2">Max Fetch Limit after the First Cycle</label>
|
||||
<br>
|
||||
<input type="checkbox" id="subResetFetchLimit" name="subResetFetchLimit" class="form-check-input ms-0 mt-0" tabindex="6">
|
||||
<br>
|
||||
<div class="form-text">Sets the Fetch Limit to 10 after the first cycle. Helps with initial spam.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6 pe-lg-4">
|
||||
<div>
|
||||
<label for="subEmbedColour" class="form-label">Embed Colour</label>
|
||||
<div class="input-group">
|
||||
<input type="color" name="subEmbedColour" id="subEmbedColour" class="form-control-color input-group-text">
|
||||
<input type="text" name="subEmbedColourText" id="subEmbedColourText" class="form-control">
|
||||
<button type="button" id="subResetEmbedColour" class="btn btn-secondary" data-bs-toggle="tooltip" data-bs-title="Reset Colour">
|
||||
<i class="bi bi-arrow-clockwise"></i>
|
||||
</button>
|
||||
<button type="button" id="subRandomEmbedColour" class="btn btn-secondary" data-bs-toggle="tooltip" data-bs-title="Random Colour">
|
||||
<i class="bi bi-dice-5"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="form-text">Colour of each article's embed in Discord.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer px-4">
|
||||
|
@ -127,22 +127,47 @@
|
||||
<select name="subTablePageSize" id="subTablePageSize" class="select-2">
|
||||
<option value="10" selected>10 </option>
|
||||
<option value="25">25 </option>
|
||||
<option value="50">50 </option>
|
||||
<option value="100">100 </option>
|
||||
<!-- <option value="50">50 </option>
|
||||
<option value="100">100 </option> -->
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="filtersTabPane" class="tab-pane fade" role="tabpanel" aria-labelledby="filtersTab" tabindex="0">
|
||||
<div class="table-responsive mt-3">
|
||||
<div class="table-responsive my-3 px-3">
|
||||
<table id="filtersTable" class="table table-hover align-middle"></table>
|
||||
</div>
|
||||
<div class="table-controls d-flex mb-3 px-3">
|
||||
<nav id="filtersPagination">
|
||||
<ul class="pagination mb-0">
|
||||
<li class="page-item">
|
||||
<button type="button" class="page-link page-prev rounded-start-1">Previous</button>
|
||||
</li>
|
||||
<li class="page-item">
|
||||
<button type="button" class="page-link page-next rounded-end-1">Next</button>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<div id="filtersTablePageInfo" class="d-flex align-items-center mx-auto">
|
||||
showing <span class="pageinfo-showing"></span>
|
||||
of <span class="pageinfo-total"></span>
|
||||
</div>
|
||||
<div class="d-flex">
|
||||
<label for="filtersTablePageSize" class="form-label align-self-center mb-0 me-2">Per Page</label>
|
||||
<select name="filtersTablePageSize" id="filtersTablePageSize" class="select-2">
|
||||
<option value="10" selected>10 </option>
|
||||
<option value="25">25 </option>
|
||||
<!-- <option value="50">50 </option>
|
||||
<option value="100">100 </option> -->
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="contentTabPane" class="tab-pane fade" role="tabpanel" aria-labelledby="contentTab" tabindex="0">
|
||||
<div class="table-responsive my-3">
|
||||
<div class="table-responsive my-3 px-3">
|
||||
<table id="contentTable" class="table table-hover align-middle"></table>
|
||||
</div>
|
||||
<div class="table-controls d-flex mb-3">
|
||||
<div class="table-controls d-flex mb-3 px-3">
|
||||
<nav id="contentPagination">
|
||||
<ul class="pagination mb-0">
|
||||
<li class="page-item">
|
||||
@ -153,13 +178,17 @@
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<div class="d-flex ms-auto">
|
||||
<div id="contentTablePageInfo" class="d-flex align-items-center mx-auto">
|
||||
showing <span class="pageinfo-showing"></span>
|
||||
of <span class="pageinfo-total"></span>
|
||||
</div>
|
||||
<div class="d-flex">
|
||||
<label for="contentTablePageSize" class="form-label align-self-center mb-0 me-2">Per Page</label>
|
||||
<select name="contentTablePageSize" id="contentTablePageSize" class="select-2">
|
||||
<option value="10" selected>10 </option>
|
||||
<option value="25">25 </option>
|
||||
<option value="50">50 </option>
|
||||
<option value="100">100 </option>
|
||||
<!-- <option value="50">50 </option>
|
||||
<option value="100">100 </option> -->
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user