rewrite generating and loading servers
This commit is contained in:
parent
9bcb99dd30
commit
edf047f148
@ -2,22 +2,19 @@
|
||||
|
||||
from rest_framework.permissions import BasePermission
|
||||
|
||||
from apps.home.models import r_Server
|
||||
from apps.authentication.models import ServerMember
|
||||
|
||||
class UserHasDiscordPermissions(BasePermission):
|
||||
|
||||
class HasServerAccess(BasePermission):
|
||||
"""
|
||||
Permission to ensure that the user is permitted to make
|
||||
changes on behalf of the server they are representing.
|
||||
An object permission class, the object must have a 'server' attribute.
|
||||
"""
|
||||
|
||||
message = "You lack administrator access to this server"
|
||||
|
||||
def has_object_permission(self, request, view, obj):
|
||||
if not hasattr(obj, "server"):
|
||||
raise Exception(f"obj '{obj}' must have attr 'server'")
|
||||
|
||||
|
||||
# class SubscriptionServerMember(BasePermission):
|
||||
# """
|
||||
# Permission for each subscription that omits the sub if
|
||||
# the request user isn't a member of it's server.
|
||||
# """
|
||||
|
||||
# def has_object_permission(self, request, view, obj):
|
||||
|
||||
# return obj.server in request.user.servers
|
||||
return ServerMember.objects.filter(user=request.user, server=obj.server).exists()
|
||||
|
@ -259,14 +259,7 @@ class TrackedContentSerializer_POST(DynamicModelSerializer):
|
||||
fields = ("id", "guid", "title", "url", "subscription", "channel_id", "message_id", "blocked", "creation_datetime")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# rewrite
|
||||
|
||||
class DiscordServerIdSerializer(serializers.Serializer):
|
||||
server_id = serializers.IntegerField()
|
||||
|
||||
#region rewrite
|
||||
|
||||
class r_ServerSerializer(DynamicModelSerializer):
|
||||
class Meta:
|
||||
|
@ -23,7 +23,6 @@ from .views import (
|
||||
UniqueContentRule_DetailView,
|
||||
|
||||
#rewrite
|
||||
CreateDiscordServerView,
|
||||
r_Server_ListView,
|
||||
r_Server_DetailView,
|
||||
r_ContentFilter_ListView,
|
||||
@ -90,8 +89,6 @@ urlpatterns = [
|
||||
|
||||
#region rewrite
|
||||
|
||||
path("discord-servers/", CreateDiscordServerView.as_view()),
|
||||
|
||||
path("r_servers/", include([
|
||||
path("", r_Server_ListView.as_view()),
|
||||
path("<int:pk>/", r_Server_DetailView.as_view())
|
||||
|
@ -47,7 +47,6 @@ from .serializers import (
|
||||
UniqueContentRuleSerializer,
|
||||
|
||||
#rewrite
|
||||
DiscordServerIdSerializer,
|
||||
r_ServerSerializer,
|
||||
r_ContentFilterSerializer,
|
||||
r_MessageMutatorSerializer,
|
||||
@ -56,6 +55,7 @@ from .serializers import (
|
||||
r_ContentSerializer,
|
||||
r_UniqueContentRuleSerializer
|
||||
)
|
||||
from .permissions import HasServerAccess
|
||||
from .errors import NotAMemberError
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -712,74 +712,7 @@ class DeletableDetailView(generics.RetrieveDestroyAPIView):
|
||||
parser_classes = [MultiPartParser, FormParser]
|
||||
|
||||
|
||||
class CreateDiscordServerView(generics.CreateAPIView):
|
||||
serializer_class = DiscordServerIdSerializer
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
serializer = self.serializer_class(data=request.data)
|
||||
if not serializer.is_valid():
|
||||
return Response()
|
||||
|
||||
server_id = serializer.validated_data["server_id"]
|
||||
response = requests.get(
|
||||
url=f"{settings.DISCORD_API_URL}/guilds/{server_id}",
|
||||
headers={"Authorization": f"Bot {settings.BOT_TOKEN}"}
|
||||
)
|
||||
raw = response.json()
|
||||
if not response.status_code == 200:
|
||||
return Response(
|
||||
status=response.status_code,
|
||||
data=raw
|
||||
)
|
||||
|
||||
server = r_Server.objects.filter(id=server_id)
|
||||
|
||||
if server.exists():
|
||||
return self.create_member_for_server(server.first(), request.user)
|
||||
else:
|
||||
return self.create_server(raw, request.user)
|
||||
|
||||
|
||||
def create_member_for_server(self, server: r_Server, user: DiscordUser) -> Response:
|
||||
response = requests.get(
|
||||
url=f"{settings.DISCORD_API_URL}/users/@me/guilds/{server.id}/member", # TODO: continue here
|
||||
headers={"Authorization": f"Bearer {user.access_token}"} # the scope of the token doesnt cover membership, so
|
||||
) # this needs to be updated against the bot from the
|
||||
raw = response.json() # discord developers dashboard.
|
||||
if response.status_code != 200:
|
||||
if raw.get("code") == 0:
|
||||
log.warning("Failed to get member data, does the oauth url contain the correct permissions?")
|
||||
|
||||
return Response(
|
||||
status=response.status_code,
|
||||
data=raw
|
||||
)
|
||||
|
||||
# TODO: might need to a case where this member already exists
|
||||
ServerMember.objects.get_or_create(
|
||||
server=server,
|
||||
user=user,
|
||||
nick=raw.get("nick"),
|
||||
permissions=raw["permissions"]
|
||||
)
|
||||
|
||||
return Response(
|
||||
status=200,
|
||||
data={"message": "success"}
|
||||
)
|
||||
|
||||
def create_server(self, raw: dict, user: DiscordUser) -> Response:
|
||||
server = r_Server.objects.create(
|
||||
id=raw["id"],
|
||||
name=raw["name"],
|
||||
icon_hash=raw["icon"],
|
||||
owner_id=raw["owner_id"]
|
||||
)
|
||||
|
||||
return self.create_member_for_server(server, user)
|
||||
|
||||
|
||||
class r_Server_ListView(ListCreateView): # maybe change to ListView only later, and create through secure backend means?
|
||||
class r_Server_ListView(ListView):
|
||||
filterset_fields = []
|
||||
search_fields = []
|
||||
ordering_fields = []
|
||||
@ -789,7 +722,7 @@ class r_Server_ListView(ListCreateView): # maybe change to ListView only later,
|
||||
return r_Server.objects.all()
|
||||
|
||||
|
||||
class r_Server_DetailView(ChangableDetailView): # maybe change to ListView only later, and create through secure backend means?
|
||||
class r_Server_DetailView(DetailView):
|
||||
serializer_class = r_ServerSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
|
@ -75,34 +75,79 @@ class GuildSettingsAdmin(admin.ModelAdmin):
|
||||
|
||||
@admin.register(r_Server)
|
||||
class r_ServerAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
list_display = ["id", "name", "icon_hash", "active"]
|
||||
|
||||
|
||||
@admin.register(r_ContentFilter)
|
||||
class r_ContentFilterAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
list_display = [
|
||||
"id",
|
||||
"server",
|
||||
"name",
|
||||
"match",
|
||||
"matching_algorithm",
|
||||
"is_insensitive",
|
||||
"is_whitelist"
|
||||
]
|
||||
|
||||
|
||||
@admin.register(r_MessageMutator)
|
||||
class r_MessageMutatorAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
list_display = [
|
||||
"id",
|
||||
"name",
|
||||
"value"
|
||||
]
|
||||
|
||||
|
||||
@admin.register(r_MessageStyle)
|
||||
class r_MessageStyleAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
list_display = [
|
||||
"id",
|
||||
"server",
|
||||
"is_embed",
|
||||
"is_hyperlinked",
|
||||
"show_author",
|
||||
"show_timestamp",
|
||||
"show_images",
|
||||
"fetch_images",
|
||||
"title_mutator",
|
||||
"description_mutator"
|
||||
]
|
||||
|
||||
|
||||
@admin.register(r_Subscription)
|
||||
class r_Subscription(admin.ModelAdmin):
|
||||
pass
|
||||
list_display = [
|
||||
"id",
|
||||
"server",
|
||||
"name",
|
||||
"url",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"extra_notes",
|
||||
"active",
|
||||
"message_style"
|
||||
]
|
||||
|
||||
|
||||
@admin.register(r_Content)
|
||||
class r_ContentAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
list_display = [
|
||||
"id",
|
||||
"subscription",
|
||||
"item_id",
|
||||
"item_guid",
|
||||
"item_url",
|
||||
"item_title",
|
||||
"item_content_hash"
|
||||
]
|
||||
|
||||
|
||||
@admin.register(r_UniqueContentRule)
|
||||
class r_UniqueContentRule(admin.ModelAdmin):
|
||||
pass
|
||||
list_display = [
|
||||
"id",
|
||||
"name",
|
||||
"value"
|
||||
]
|
||||
|
@ -7,6 +7,5 @@ from .views import IndexView, GuildsView
|
||||
|
||||
urlpatterns = [
|
||||
path("", login_required(IndexView.as_view()), name="index"),
|
||||
|
||||
path("user-guilds", GuildsView.as_view(), name="user-guilds")
|
||||
path("generate-servers/", GuildsView.as_view(), name="generate-servers")
|
||||
]
|
||||
|
@ -183,3 +183,13 @@ async function getUniqueContentRule(ruleId) {
|
||||
return await ajaxRequest(`/api/unique-content-rule/${ruleId}/`, "GET");
|
||||
}
|
||||
|
||||
|
||||
//#region rewrite
|
||||
|
||||
async function generateServers() {
|
||||
return ajaxRequest("/generate-servers/", "GET");
|
||||
}
|
||||
|
||||
async function getServers() {
|
||||
return ajaxRequest("/api/r_servers/", "GET");
|
||||
}
|
@ -5,8 +5,7 @@ $(document).ready(async function() {
|
||||
|
||||
$("#subscriptionsTab").click();
|
||||
|
||||
await loadSavedGuilds();
|
||||
await loadServerOptions();
|
||||
await loadServers();
|
||||
});
|
||||
|
||||
$(document).on("selectedServerChange", function() {
|
||||
@ -189,4 +188,25 @@ function arrayToHtmlList(array, bold=false) {
|
||||
});
|
||||
|
||||
return $ul;
|
||||
}
|
||||
|
||||
function logError(error) {
|
||||
if (error instanceof Error) {
|
||||
// Logs typical error properties like message and stack
|
||||
console.error({
|
||||
message: error.message,
|
||||
stack: error.stack,
|
||||
name: error.name,
|
||||
});
|
||||
} else if (typeof error === 'object' && error !== null) {
|
||||
// Try to stringify if it's an object
|
||||
try {
|
||||
console.error(JSON.stringify(error, null, 2));
|
||||
} catch (stringifyError) {
|
||||
console.error('Could not stringify the error:', error);
|
||||
}
|
||||
} else {
|
||||
// Fallback for any other types (string, number, etc.)
|
||||
console.error('Error:', error);
|
||||
}
|
||||
}
|
@ -1,263 +1,178 @@
|
||||
|
||||
// #region Loaded Servers
|
||||
|
||||
var loadedServers = {};
|
||||
var _loadedServers = []
|
||||
var selectedServer = null;
|
||||
|
||||
// Returns the currently active server, or null if none are active.
|
||||
function getCurrentlyActiveServer() {
|
||||
const activeServerAndId = Object.entries(loadedServers).find(([id, server]) => server.currentlyActive);
|
||||
if (activeServerAndId === undefined)
|
||||
return null;
|
||||
function getLoadedServer(options) {
|
||||
let servers = _loadedServers.filter(item => {
|
||||
|
||||
var [id, activeServer] = activeServerAndId;
|
||||
activeServer.id = id;
|
||||
|
||||
return activeServer;
|
||||
}
|
||||
|
||||
// Returns the requested server from the provided snowflake id
|
||||
function getServerFromSnowflake(guildId) {
|
||||
const serverAndId = Object.entries(loadedServers).find(([id, server]) => server.guild_id == guildId);
|
||||
if (serverAndId === undefined)
|
||||
return null;
|
||||
|
||||
var [id, server] = serverAndId;
|
||||
server.id = id;
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
function addToLoadedServers(server, selectNew=true) {
|
||||
// Remove the 'id' property and add the 'currentlyActive' property
|
||||
({id, ...rest} = server, server = {...rest, currentlyActive: false})
|
||||
|
||||
// Save the server as loaded
|
||||
loadedServers[id] = server;
|
||||
|
||||
// Display the loaded server
|
||||
addServerTemplate(id, sanitise(server.guild_id), sanitise(server.name), sanitise(server.icon), sanitise(server.permissions), sanitise(server.owner));
|
||||
|
||||
// Select the newly added server
|
||||
if (selectNew) {
|
||||
selectServer(id);
|
||||
}
|
||||
}
|
||||
|
||||
function removeFromLoadedServers(serverPrimaryKey) {
|
||||
delete loadedServers[serverPrimaryKey];
|
||||
removeServerTemplate(serverPrimaryKey);
|
||||
|
||||
$("#backToSelectServer").click();
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region Server Back Btn
|
||||
|
||||
$("#backToSelectServer").on("click", function() {
|
||||
$("#noSelectedServer").show();
|
||||
$("#selectedServerContainer").hide();
|
||||
});
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region Server Modal
|
||||
|
||||
$("#serverOptionsRefreshBtn").on("click", async function() {
|
||||
await loadServerOptions();
|
||||
});
|
||||
|
||||
// Load server options into the 'Add Server' dropdown
|
||||
async function loadServerOptions() {
|
||||
|
||||
// Disable controls while loading
|
||||
$("#serverOptions").prop("disabled", true);
|
||||
$("#serverOptionsRefreshBtn").prop("disabled", true).find("i.bi").addClass("spinning-360");
|
||||
|
||||
// Remove existing options
|
||||
$("#serverOptions option").each(function() {
|
||||
if ($(this).val()) {
|
||||
$(this).remove();
|
||||
for (let key in options) {
|
||||
if (item[key] !== options[key]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
// Deselect any selected option
|
||||
$("#serverOptions").val(null).trigger("change");
|
||||
return servers || [];
|
||||
}
|
||||
|
||||
// Fetch and append the server options
|
||||
try {
|
||||
const servers = await loadGuilds();
|
||||
servers.forEach(server => {
|
||||
$("#serverOptions").append($("<option>", {
|
||||
value: server.id,
|
||||
text: sanitise(server.name),
|
||||
"data-icon": sanitise(server.icon),
|
||||
"data-permissions": sanitise(server.permissions),
|
||||
"data-isowner": sanitise(server.owner)
|
||||
}));
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
console.error(JSON.stringify(error, null, 4));
|
||||
showToast("danger", `Error Loading Guilds: HTTP ${error.status}`, error.responseJSON.message, 15000);
|
||||
}
|
||||
finally {
|
||||
// Re-enable controls
|
||||
$("#serverOptions").prop("disabled", false);
|
||||
$("#serverOptionsRefreshBtn").prop("disabled", false).find("i.bi").removeClass("spinning-360");
|
||||
function getServerFromSnowflake(id) {
|
||||
server = getLoadedServer({id: id});
|
||||
if (!server.length) {
|
||||
throw new Error("No Server with that ID");
|
||||
}
|
||||
|
||||
return server[0];
|
||||
}
|
||||
|
||||
function addToLoadedServers(serverData, autoSelect=false) {
|
||||
_loadedServers.push(serverData);
|
||||
createSelectButton(serverData);
|
||||
|
||||
if (autoSelect) {
|
||||
selectServer(serverData["id"]);
|
||||
}
|
||||
}
|
||||
|
||||
function removeFromLoadedServers(id) {
|
||||
_loadedServers = _loadedServers.filter(item => item.id !== id);
|
||||
removeSelectButton(id)
|
||||
|
||||
if (selectedServer.id === id) {
|
||||
selectedServer(null);
|
||||
}
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region Server Sidebar
|
||||
// #region UI Buttons
|
||||
|
||||
// Load any existing 'saved guilds' from the database
|
||||
async function loadSavedGuilds() {
|
||||
try {
|
||||
const response = await getSavedGuilds(currentUserId);
|
||||
function createSelectButton(serverData) {
|
||||
// server details
|
||||
let id = serverData["id"];
|
||||
let name = serverData["name"];
|
||||
let iconHash = serverData["icon"];
|
||||
|
||||
response.forEach(server => {
|
||||
|
||||
// 'Register' the server, by storing it for later and
|
||||
// displaying it on the server list sidebar
|
||||
addToLoadedServers(server, false);
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
alert("Error loading saved guilds: " + error);
|
||||
}
|
||||
}
|
||||
|
||||
// Create an element for the added server and show it
|
||||
function addServerTemplate(serverPrimaryKey, serverGuildId, serverName, serverIconHash, serverPermissions, serverIsOwner) {
|
||||
let template = $($("#serverItemTemplate").html());
|
||||
let imageUrl = `https://cdn.discordapp.com/icons/${serverGuildId}/${serverIconHash}.webp?size=80`;
|
||||
let imageUrl = `https://cdn.discordapp.com/icons/${id}/${iconHash}.webp?size=80`;
|
||||
let altText = name.split(' ').map(word => word.charAt(0)).join(''); // initials of server name, used if iconUrl is 404
|
||||
|
||||
template.find("img").attr("src", imageUrl);
|
||||
template.find(".js-guildId").text(serverGuildId);
|
||||
template.find(".js-guildName").text(serverName);
|
||||
template.attr("data-id", serverPrimaryKey);
|
||||
template.attr("data-guild-id", serverGuildId);
|
||||
template.find("img").attr("src", imageUrl).attr("alt", altText);
|
||||
template.find(".js-guildName").text(name);
|
||||
template.find(".js-guildId").text(id);
|
||||
template.attr("data-id", id);
|
||||
|
||||
// Bind the button for selecting this server
|
||||
template.find(".server-item-selector").off("click").on("click", function() {
|
||||
$(".server-item-selector").removeClass("active");
|
||||
$(this).addClass("active");
|
||||
selectServer(serverPrimaryKey);
|
||||
selectServer(id);
|
||||
});
|
||||
|
||||
|
||||
$("#serverList").prepend(template);
|
||||
}
|
||||
|
||||
function removeServerTemplate(serverPrimaryKey) {
|
||||
$(`#serverList .server-item[data-id=${serverPrimaryKey}]`).remove();
|
||||
function removeSelectButton(id) {
|
||||
$(`#serverList .server-item[data-id=${id}]`).remove();
|
||||
}
|
||||
|
||||
// Open 'Add Server' Form Modal
|
||||
$("#newServerBtn").on("click", function() {
|
||||
newServerModal();
|
||||
$("#backToSelectServer").on("click", function() {
|
||||
$("#noSelectedServer").show();
|
||||
$("#selectedServerContainer").hide();
|
||||
selectServer = null;
|
||||
});
|
||||
|
||||
function newServerModal() {
|
||||
$("#serverFormModal").modal("show");
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region New Server
|
||||
// #region Server Selection
|
||||
|
||||
// Submit 'Add Server' Form
|
||||
$("#serverForm").on("submit", async function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
var selectedOption = $("#serverOptions option:selected");
|
||||
serverName = selectedOption.text();
|
||||
serverGuildId = selectedOption.val();
|
||||
serverIconHash = selectedOption.attr("data-icon");
|
||||
serverPermissions = selectedOption.attr("data-permissions");
|
||||
serverIsOwner = selectedOption.attr("data-isowner");
|
||||
|
||||
var serverPrimaryKey = await registerNewServer(serverName, serverGuildId, serverIconHash, serverPermissions, serverIsOwner);
|
||||
if (serverPrimaryKey)
|
||||
addToLoadedServers(await getSavedGuild(serverPrimaryKey));
|
||||
|
||||
$("#serverFormModal").modal("hide");
|
||||
});
|
||||
|
||||
// Add a new 'saved guild' based on the info provided
|
||||
// returns `response.id` if successful, else false
|
||||
async function registerNewServer(serverName, serverGuildId, serverIconHash, serverPermissions, serverIsOwner) {
|
||||
var formData = new FormData();
|
||||
formData.append("name", serverName);
|
||||
formData.append("guild_id", serverGuildId);
|
||||
formData.append("icon", serverIconHash);
|
||||
formData.append("added_by", currentUserId);
|
||||
formData.append("permissions", serverPermissions);
|
||||
formData.append("owner", serverIsOwner === "true");
|
||||
|
||||
try { response = await newSavedGuild(formData); }
|
||||
catch (err) {
|
||||
if (err.status === 409)
|
||||
showToast("warning", "Server Conflict", `Can't add ${sanitise(serverName)} because it already exists.`, 10000);
|
||||
else
|
||||
console.error(JSON.stringify(err, null, 4));
|
||||
|
||||
return false;
|
||||
function selectServer(id) {
|
||||
let server = getServerFromSnowflake(id);
|
||||
if (!server) {
|
||||
$("#noSelectedServer").show();
|
||||
$("#selectedServerContainer").hide();
|
||||
selectServer = null;
|
||||
return;
|
||||
}
|
||||
debugger
|
||||
|
||||
return response.id;
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region Select Server
|
||||
|
||||
function selectServer(primaryKey) {
|
||||
var server = loadedServers[primaryKey];
|
||||
|
||||
// Change appearance of selected vs none-selected items
|
||||
$("#serverList .server-item").removeClass("active")
|
||||
$(`#serverList .server-item[data-id=${primaryKey}]`).addClass("active")
|
||||
$("#serverList .server-item").removeClass("active");
|
||||
$(`#serverList .server-item[data-id=${id}]`).addClass("active");
|
||||
|
||||
// Display details of the selected server
|
||||
$("#selectedServerContainer .selected-server-name").text(sanitise(server.name));
|
||||
$("#selectedServerContainer .selected-server-id").text(sanitise(server.guild_id));
|
||||
$("#selectedServerContainer .selected-server-icon").attr("src", `https://cdn.discordapp.com/icons/${server.guild_id}/${server.icon}.webp?size=80`);
|
||||
|
||||
// Disable all loaded servers
|
||||
$.each(loadedServers, function(serverPrimaryKey, server) {
|
||||
server.currentlyActive = false;
|
||||
});
|
||||
|
||||
// Activate current selected server
|
||||
loadedServers[primaryKey].currentlyActive = true;
|
||||
// Global variable
|
||||
selectedServer = server;
|
||||
|
||||
// Update UI
|
||||
$("#noSelectedServer").hide();
|
||||
$("#selectedServerContainer").show().css("display", "flex");
|
||||
|
||||
// Announce change to any listeners
|
||||
$(document).trigger("selectedServerChange");
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region Delete Server Btn
|
||||
// #region Resolve Strings
|
||||
|
||||
function resolveServerStrings() {
|
||||
// Server icon
|
||||
$(".resolve-to-server-icon").attr(
|
||||
"src",
|
||||
`https://cdn.discordapp.com/icons/${selectedServer.id}/${selectedServer.icon}.webp?size=80`
|
||||
);
|
||||
|
||||
// Server names
|
||||
$(".resolve-to-server-name").text(selectedServer.name);
|
||||
|
||||
// Server Guild Ids
|
||||
$(".resolve-to-server-id").text(selectedServer.id);
|
||||
|
||||
// Bot Invite links
|
||||
$(".resolve-to-invite-link").attr("href", `https://discord.com/oauth2/authorize
|
||||
?client_id=${discordClientId}
|
||||
&permissions=2147534848
|
||||
&scope=bot+applications.commands
|
||||
&guild_id=${selectedServer.id}
|
||||
&disable_guild_select=true`);
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region Change Listener
|
||||
|
||||
$(document).on("selectedServerChange", function() {
|
||||
resolveServerStrings();
|
||||
$("#serverJoinAlert").hide();
|
||||
});
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region Load Servers
|
||||
|
||||
async function loadServers() {
|
||||
try {
|
||||
let response = await generateServers();
|
||||
response.forEach(server => {
|
||||
addToLoadedServers(server, false);
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
logError(error);
|
||||
}
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region Server Deletion
|
||||
|
||||
$("#deleteSelectedServerBtn").on("click", async function() {
|
||||
const notes = [
|
||||
"No Subscriptions, Filters or Tracked Content will be deleted.",
|
||||
"No data will be deleted for other users.",
|
||||
"The server will no longer appear on your sidebar.",
|
||||
"You can re-add the server",
|
||||
"All Subscriptions, Filters and Tracked Content will be available when/if you re-add the server."
|
||||
];
|
||||
const notesString = arrayToHtmlList(notes).prop("outerHTML");
|
||||
|
||||
await confirmationModal(
|
||||
"Close this server?",
|
||||
`This is a safe, non-permanent action:<br><br>${notesString}`,
|
||||
"Delete Server Data?",
|
||||
"All related items will be erased, are you sure? (Only the owner can confirm)",
|
||||
"warning",
|
||||
deleteSelectedServer,
|
||||
null
|
||||
@ -265,51 +180,7 @@ $("#deleteSelectedServerBtn").on("click", async function() {
|
||||
});
|
||||
|
||||
async function deleteSelectedServer() {
|
||||
var activeServer = getCurrentlyActiveServer();
|
||||
|
||||
if (!activeServer) {
|
||||
showToast("danger", "Error Deleting Server", "You must select a server to delete.");
|
||||
return;
|
||||
}
|
||||
|
||||
console.debug(`Deleting ${activeServer.id}: ${JSON.stringify(activeServer, null, 4)}`)
|
||||
|
||||
try {
|
||||
await deleteSavedGuild(activeServer.id);
|
||||
removeFromLoadedServers(activeServer.id);
|
||||
}
|
||||
catch (error) {
|
||||
alert(error)
|
||||
alert(JSON.stringify(error, null, 4))
|
||||
}
|
||||
};
|
||||
|
||||
// #endregion
|
||||
|
||||
$(document).on("selectedServerChange", function() {
|
||||
resolveServerStrings();
|
||||
$("#serverJoinAlert").hide();
|
||||
})
|
||||
|
||||
// #region Resolve Strings
|
||||
|
||||
function resolveServerStrings() {
|
||||
const server = getCurrentlyActiveServer();
|
||||
|
||||
// Server names
|
||||
$(".resolve-to-server-name").text(sanitise(server.name));
|
||||
|
||||
// Server Guild Ids
|
||||
$(".resolve-to-server-id").text(sanitise(server.guild_id))
|
||||
|
||||
// Bot Invite links
|
||||
$(".resolve-to-invite-link").attr("href", `https://discord.com/oauth2/authorize
|
||||
?client_id=${discordClientId}
|
||||
&permissions=2147534848
|
||||
&scope=bot+applications.commands
|
||||
&guild_id=${sanitise(server.guild_id)}
|
||||
&disable_guild_select=true`);
|
||||
|
||||
alert("not implemented");
|
||||
}
|
||||
|
||||
// #endregion
|
||||
// #endregion
|
@ -1,34 +0,0 @@
|
||||
|
||||
<div id="serverFormModal" class="modal fade" data-bs-backdrop="static" tabindex="-1">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content rounded-1">
|
||||
<form id="serverForm" class="mb-0" novalidate>
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title ms-2">
|
||||
Add Server
|
||||
</h5>
|
||||
</div>
|
||||
<div class="modal-body p-4">
|
||||
<div class="d-flex flex-nowrap mb-3">
|
||||
<div class="flex-fill">
|
||||
<select name="serverOptions" id="serverOptions" class="select-2 rounded-1" data-dropdownparent="#serverFormModal">
|
||||
<option value="">-- Select a Server --</option>
|
||||
</select>
|
||||
</div>
|
||||
<button type="button" id="serverOptionsRefreshBtn" class="btn btn-secondary rounded-1 ms-3">
|
||||
<i class="bi bi-arrow-clockwise d-block"></i>
|
||||
</button>
|
||||
</div>
|
||||
<p class="mb-0 form-text">
|
||||
<b>Not seeing your server?</b>
|
||||
Ensure that you are authenticated as either the owner or an administrator of the server you wish to add.
|
||||
</p>
|
||||
</div>
|
||||
<div class="modal-footer px-4">
|
||||
<button type="submit" class="btn btn-primary rounded-1 me-0">Submit</button>
|
||||
<button type="button" class="btn btn-secondary rounded-1 ms-3" data-bs-dismiss="modal">Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -14,12 +14,6 @@
|
||||
<div class="d-flex flex-nowrap h-100">
|
||||
<div class="server-sidebar d-flex flex-column bg-body-tertiary py-3 border-end">
|
||||
<ul id="serverList" class="nav nav-pills nav-flush flex-column mb-auto text-center px-lg-2 px-1 flex-nowrap overflow-y-auto">
|
||||
<li class="nav-item">
|
||||
<button type="button" id="newServerBtn" class="btn btn-outline-primary rounded-1 mt-2 w-100 d-flex justify-content-center align-items-center">
|
||||
<i class="bi bi-plus-lg fs-5 d-lg-none d-inline"></i>
|
||||
<span class="small d-lg-inline d-none">Add Server</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="flex-grow-1 container-fluid bg-body overflow-y-auto" style="min-width: 0;">
|
||||
@ -45,7 +39,7 @@
|
||||
<div class="col-12 bg-body-tertiary border-bottom p-3 py-sm-4">
|
||||
<div class="row">
|
||||
<div class="col-sm-7 col-md-6 d-flex align-items-center">
|
||||
<img alt="Server Icon" class="rounded-3 selected-server-icon d-none d-sm-block">
|
||||
<img alt="Server Icon" class="resolve-to-server-icon rounded-3 d-none d-sm-block">
|
||||
<div class="ms-sm-3" style="min-width: 0">
|
||||
<h3 class="mb-0 resolve-to-server-name text-truncate"></h3>
|
||||
<h5 class="mb-0 resolve-to-server-id text-truncate text-body-secondary text-monospace"></h5>
|
||||
@ -112,7 +106,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% include "home/includes/servermodal.html" %}
|
||||
{% include "home/includes/submodal.html" %}
|
||||
{% include "home/includes/filtermodal.html" %}
|
||||
{% include "home/includes/deletemodal.html" %}
|
||||
|
Loading…
x
Reference in New Issue
Block a user