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 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
|
An object permission class, the object must have a 'server' attribute.
|
||||||
changes on behalf of the server they are representing.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
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'")
|
||||||
|
|
||||||
|
return ServerMember.objects.filter(user=request.user, server=obj.server).exists()
|
||||||
# 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
|
|
||||||
|
@ -259,14 +259,7 @@ class TrackedContentSerializer_POST(DynamicModelSerializer):
|
|||||||
fields = ("id", "guid", "title", "url", "subscription", "channel_id", "message_id", "blocked", "creation_datetime")
|
fields = ("id", "guid", "title", "url", "subscription", "channel_id", "message_id", "blocked", "creation_datetime")
|
||||||
|
|
||||||
|
|
||||||
|
#region rewrite
|
||||||
|
|
||||||
|
|
||||||
# rewrite
|
|
||||||
|
|
||||||
class DiscordServerIdSerializer(serializers.Serializer):
|
|
||||||
server_id = serializers.IntegerField()
|
|
||||||
|
|
||||||
|
|
||||||
class r_ServerSerializer(DynamicModelSerializer):
|
class r_ServerSerializer(DynamicModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -23,7 +23,6 @@ from .views import (
|
|||||||
UniqueContentRule_DetailView,
|
UniqueContentRule_DetailView,
|
||||||
|
|
||||||
#rewrite
|
#rewrite
|
||||||
CreateDiscordServerView,
|
|
||||||
r_Server_ListView,
|
r_Server_ListView,
|
||||||
r_Server_DetailView,
|
r_Server_DetailView,
|
||||||
r_ContentFilter_ListView,
|
r_ContentFilter_ListView,
|
||||||
@ -90,8 +89,6 @@ urlpatterns = [
|
|||||||
|
|
||||||
#region rewrite
|
#region rewrite
|
||||||
|
|
||||||
path("discord-servers/", CreateDiscordServerView.as_view()),
|
|
||||||
|
|
||||||
path("r_servers/", include([
|
path("r_servers/", include([
|
||||||
path("", r_Server_ListView.as_view()),
|
path("", r_Server_ListView.as_view()),
|
||||||
path("<int:pk>/", r_Server_DetailView.as_view())
|
path("<int:pk>/", r_Server_DetailView.as_view())
|
||||||
|
@ -47,7 +47,6 @@ from .serializers import (
|
|||||||
UniqueContentRuleSerializer,
|
UniqueContentRuleSerializer,
|
||||||
|
|
||||||
#rewrite
|
#rewrite
|
||||||
DiscordServerIdSerializer,
|
|
||||||
r_ServerSerializer,
|
r_ServerSerializer,
|
||||||
r_ContentFilterSerializer,
|
r_ContentFilterSerializer,
|
||||||
r_MessageMutatorSerializer,
|
r_MessageMutatorSerializer,
|
||||||
@ -56,6 +55,7 @@ from .serializers import (
|
|||||||
r_ContentSerializer,
|
r_ContentSerializer,
|
||||||
r_UniqueContentRuleSerializer
|
r_UniqueContentRuleSerializer
|
||||||
)
|
)
|
||||||
|
from .permissions import HasServerAccess
|
||||||
from .errors import NotAMemberError
|
from .errors import NotAMemberError
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -712,74 +712,7 @@ class DeletableDetailView(generics.RetrieveDestroyAPIView):
|
|||||||
parser_classes = [MultiPartParser, FormParser]
|
parser_classes = [MultiPartParser, FormParser]
|
||||||
|
|
||||||
|
|
||||||
class CreateDiscordServerView(generics.CreateAPIView):
|
class r_Server_ListView(ListView):
|
||||||
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?
|
|
||||||
filterset_fields = []
|
filterset_fields = []
|
||||||
search_fields = []
|
search_fields = []
|
||||||
ordering_fields = []
|
ordering_fields = []
|
||||||
@ -789,7 +722,7 @@ class r_Server_ListView(ListCreateView): # maybe change to ListView only later,
|
|||||||
return r_Server.objects.all()
|
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
|
serializer_class = r_ServerSerializer
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
|
@ -75,34 +75,79 @@ class GuildSettingsAdmin(admin.ModelAdmin):
|
|||||||
|
|
||||||
@admin.register(r_Server)
|
@admin.register(r_Server)
|
||||||
class r_ServerAdmin(admin.ModelAdmin):
|
class r_ServerAdmin(admin.ModelAdmin):
|
||||||
pass
|
list_display = ["id", "name", "icon_hash", "active"]
|
||||||
|
|
||||||
|
|
||||||
@admin.register(r_ContentFilter)
|
@admin.register(r_ContentFilter)
|
||||||
class r_ContentFilterAdmin(admin.ModelAdmin):
|
class r_ContentFilterAdmin(admin.ModelAdmin):
|
||||||
pass
|
list_display = [
|
||||||
|
"id",
|
||||||
|
"server",
|
||||||
|
"name",
|
||||||
|
"match",
|
||||||
|
"matching_algorithm",
|
||||||
|
"is_insensitive",
|
||||||
|
"is_whitelist"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
@admin.register(r_MessageMutator)
|
@admin.register(r_MessageMutator)
|
||||||
class r_MessageMutatorAdmin(admin.ModelAdmin):
|
class r_MessageMutatorAdmin(admin.ModelAdmin):
|
||||||
pass
|
list_display = [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"value"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
@admin.register(r_MessageStyle)
|
@admin.register(r_MessageStyle)
|
||||||
class r_MessageStyleAdmin(admin.ModelAdmin):
|
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)
|
@admin.register(r_Subscription)
|
||||||
class r_Subscription(admin.ModelAdmin):
|
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)
|
@admin.register(r_Content)
|
||||||
class r_ContentAdmin(admin.ModelAdmin):
|
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)
|
@admin.register(r_UniqueContentRule)
|
||||||
class r_UniqueContentRule(admin.ModelAdmin):
|
class r_UniqueContentRule(admin.ModelAdmin):
|
||||||
pass
|
list_display = [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"value"
|
||||||
|
]
|
||||||
|
@ -7,6 +7,5 @@ from .views import IndexView, GuildsView
|
|||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("", login_required(IndexView.as_view()), name="index"),
|
path("", login_required(IndexView.as_view()), name="index"),
|
||||||
|
path("generate-servers/", GuildsView.as_view(), name="generate-servers")
|
||||||
path("user-guilds", GuildsView.as_view(), name="user-guilds")
|
|
||||||
]
|
]
|
||||||
|
@ -183,3 +183,13 @@ async function getUniqueContentRule(ruleId) {
|
|||||||
return await ajaxRequest(`/api/unique-content-rule/${ruleId}/`, "GET");
|
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();
|
$("#subscriptionsTab").click();
|
||||||
|
|
||||||
await loadSavedGuilds();
|
await loadServers();
|
||||||
await loadServerOptions();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).on("selectedServerChange", function() {
|
$(document).on("selectedServerChange", function() {
|
||||||
@ -189,4 +188,25 @@ function arrayToHtmlList(array, bold=false) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return $ul;
|
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
|
// #region Loaded Servers
|
||||||
|
|
||||||
var loadedServers = {};
|
var _loadedServers = []
|
||||||
|
var selectedServer = null;
|
||||||
|
|
||||||
// Returns the currently active server, or null if none are active.
|
function getLoadedServer(options) {
|
||||||
function getCurrentlyActiveServer() {
|
let servers = _loadedServers.filter(item => {
|
||||||
const activeServerAndId = Object.entries(loadedServers).find(([id, server]) => server.currentlyActive);
|
|
||||||
if (activeServerAndId === undefined)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var [id, activeServer] = activeServerAndId;
|
for (let key in options) {
|
||||||
activeServer.id = id;
|
if (item[key] !== options[key]) {
|
||||||
|
return false
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Deselect any selected option
|
return servers || [];
|
||||||
$("#serverOptions").val(null).trigger("change");
|
}
|
||||||
|
|
||||||
// Fetch and append the server options
|
function getServerFromSnowflake(id) {
|
||||||
try {
|
server = getLoadedServer({id: id});
|
||||||
const servers = await loadGuilds();
|
if (!server.length) {
|
||||||
servers.forEach(server => {
|
throw new Error("No Server with that ID");
|
||||||
$("#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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
// #endregion
|
||||||
|
|
||||||
// #region Server Sidebar
|
// #region UI Buttons
|
||||||
|
|
||||||
// Load any existing 'saved guilds' from the database
|
function createSelectButton(serverData) {
|
||||||
async function loadSavedGuilds() {
|
// server details
|
||||||
try {
|
let id = serverData["id"];
|
||||||
const response = await getSavedGuilds(currentUserId);
|
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 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("img").attr("src", imageUrl).attr("alt", altText);
|
||||||
template.find(".js-guildId").text(serverGuildId);
|
template.find(".js-guildName").text(name);
|
||||||
template.find(".js-guildName").text(serverName);
|
template.find(".js-guildId").text(id);
|
||||||
template.attr("data-id", serverPrimaryKey);
|
template.attr("data-id", id);
|
||||||
template.attr("data-guild-id", serverGuildId);
|
|
||||||
|
|
||||||
// Bind the button for selecting this server
|
// Bind the button for selecting this server
|
||||||
template.find(".server-item-selector").off("click").on("click", function() {
|
template.find(".server-item-selector").off("click").on("click", function() {
|
||||||
$(".server-item-selector").removeClass("active");
|
$(".server-item-selector").removeClass("active");
|
||||||
$(this).addClass("active");
|
$(this).addClass("active");
|
||||||
selectServer(serverPrimaryKey);
|
selectServer(id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
$("#serverList").prepend(template);
|
$("#serverList").prepend(template);
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeServerTemplate(serverPrimaryKey) {
|
function removeSelectButton(id) {
|
||||||
$(`#serverList .server-item[data-id=${serverPrimaryKey}]`).remove();
|
$(`#serverList .server-item[data-id=${id}]`).remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open 'Add Server' Form Modal
|
$("#backToSelectServer").on("click", function() {
|
||||||
$("#newServerBtn").on("click", function() {
|
$("#noSelectedServer").show();
|
||||||
newServerModal();
|
$("#selectedServerContainer").hide();
|
||||||
|
selectServer = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
function newServerModal() {
|
|
||||||
$("#serverFormModal").modal("show");
|
|
||||||
}
|
|
||||||
|
|
||||||
// #endregion
|
// #endregion
|
||||||
|
|
||||||
// #region New Server
|
// #region Server Selection
|
||||||
|
|
||||||
// Submit 'Add Server' Form
|
function selectServer(id) {
|
||||||
$("#serverForm").on("submit", async function(event) {
|
let server = getServerFromSnowflake(id);
|
||||||
event.preventDefault();
|
if (!server) {
|
||||||
|
$("#noSelectedServer").show();
|
||||||
var selectedOption = $("#serverOptions option:selected");
|
$("#selectedServerContainer").hide();
|
||||||
serverName = selectedOption.text();
|
selectServer = null;
|
||||||
serverGuildId = selectedOption.val();
|
return;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
debugger
|
||||||
|
|
||||||
return response.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// #endregion
|
|
||||||
|
|
||||||
// #region Select Server
|
|
||||||
|
|
||||||
function selectServer(primaryKey) {
|
|
||||||
var server = loadedServers[primaryKey];
|
|
||||||
|
|
||||||
// Change appearance of selected vs none-selected items
|
// Change appearance of selected vs none-selected items
|
||||||
$("#serverList .server-item").removeClass("active")
|
$("#serverList .server-item").removeClass("active");
|
||||||
$(`#serverList .server-item[data-id=${primaryKey}]`).addClass("active")
|
$(`#serverList .server-item[data-id=${id}]`).addClass("active");
|
||||||
|
|
||||||
// Display details of the selected server
|
// Global variable
|
||||||
$("#selectedServerContainer .selected-server-name").text(sanitise(server.name));
|
selectedServer = server;
|
||||||
$("#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;
|
|
||||||
|
|
||||||
|
// Update UI
|
||||||
$("#noSelectedServer").hide();
|
$("#noSelectedServer").hide();
|
||||||
$("#selectedServerContainer").show().css("display", "flex");
|
$("#selectedServerContainer").show().css("display", "flex");
|
||||||
|
|
||||||
|
// Announce change to any listeners
|
||||||
$(document).trigger("selectedServerChange");
|
$(document).trigger("selectedServerChange");
|
||||||
}
|
}
|
||||||
|
|
||||||
// #endregion
|
// #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() {
|
$("#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(
|
await confirmationModal(
|
||||||
"Close this server?",
|
"Delete Server Data?",
|
||||||
`This is a safe, non-permanent action:<br><br>${notesString}`,
|
"All related items will be erased, are you sure? (Only the owner can confirm)",
|
||||||
"warning",
|
"warning",
|
||||||
deleteSelectedServer,
|
deleteSelectedServer,
|
||||||
null
|
null
|
||||||
@ -265,51 +180,7 @@ $("#deleteSelectedServerBtn").on("click", async function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
async function deleteSelectedServer() {
|
async function deleteSelectedServer() {
|
||||||
var activeServer = getCurrentlyActiveServer();
|
alert("not implemented");
|
||||||
|
|
||||||
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`);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// #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="d-flex flex-nowrap h-100">
|
||||||
<div class="server-sidebar d-flex flex-column bg-body-tertiary py-3 border-end">
|
<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">
|
<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>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-grow-1 container-fluid bg-body overflow-y-auto" style="min-width: 0;">
|
<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="col-12 bg-body-tertiary border-bottom p-3 py-sm-4">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-7 col-md-6 d-flex align-items-center">
|
<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">
|
<div class="ms-sm-3" style="min-width: 0">
|
||||||
<h3 class="mb-0 resolve-to-server-name text-truncate"></h3>
|
<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>
|
<h5 class="mb-0 resolve-to-server-id text-truncate text-body-secondary text-monospace"></h5>
|
||||||
@ -112,7 +106,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% include "home/includes/servermodal.html" %}
|
|
||||||
{% include "home/includes/submodal.html" %}
|
{% include "home/includes/submodal.html" %}
|
||||||
{% include "home/includes/filtermodal.html" %}
|
{% include "home/includes/filtermodal.html" %}
|
||||||
{% include "home/includes/deletemodal.html" %}
|
{% include "home/includes/deletemodal.html" %}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user