fix image stuff and add delete tournament

This commit is contained in:
Luna 2025-09-24 04:36:54 +02:00
parent df72b7d8c6
commit ba98362502
7 changed files with 45 additions and 95 deletions

View file

@ -24,6 +24,8 @@ export const TABotTokenStore = createPersistedStore('TABotTokenTAUI', null);
export const TAServerUrl = createPersistedStore('TAServerUrl', "server.tournamentassistant.net");
export const TAServerAPIPort = createPersistedStore('TAServerAPIPort', "8678");
export const TAServerPort = createPersistedStore('TAServerPort', "8676");
export const TAServerPlayerPort = createPersistedStore('TAServerPlayerPort', "8675");

View file

@ -3,7 +3,7 @@
import { onMount, onDestroy } from 'svelte';
import Notification from '$lib/components/notifications/Popup.svelte';
import { discordAuthUrl } from '$lib/config.json';
import { discordDataStore, discordTokenStore, authTokenStore, TAServerPort, TAServerUrl, client, TAServerPlayerPort } from '$lib/stores';
import { discordDataStore, discordTokenStore, authTokenStore, TAServerPort, TAServerUrl, client, TAServerPlayerPort, TAServerAPIPort } from '$lib/stores';
import { TAClient, Response_ResponseType, Tournament } from 'moons-ta-client';
import { bufferToImageUrl } from '$lib/services/taImages';
import { v4 as uuidv4 } from "uuid";
@ -83,27 +83,13 @@
if (t.settings?.tournamentImage) {
// If the image is already a string URL
if (typeof t.settings.tournamentImage === 'string') {
imageUrl = t.settings.tournamentImage;
imageUrl = `https://${$TAServerUrl}:${$TAServerAPIPort}/api/file/${t.settings.tournamentImage}`;
}
// If the image is a Uint8Array
else if (typeof t.settings.tournamentImage === 'object') {
// Create and properly dispose of object URLs to prevent memory leaks
try {
imageUrl = bufferToImageUrl(t.settings.tournamentImage);
if (imageUrl.length < 150) {
imageUrl = "/talogo.png"
}
} catch (error) {
console.error('Failed to convert tournament image buffer to URL:', error);
// Fall back to default image
else {
imageUrl = "/talogo.png"
}
}
}
// Fetch authorized users for this tournament
// This initiates the API call immediately but doesn't block the map function
// const authorisedUsersPromise = await fetchTournamentAuthorisedUsers(t.guid);
return {
id: t.guid.substring(0, 8), // Short ID for display
@ -111,7 +97,6 @@
image: imageUrl,
guid: t.guid,
myPermissions: t.settings!.myPermissions
// authorisedUsers: authorisedUsersPromise // Wait for the promise to resolve
};
}));
@ -129,20 +114,6 @@
}
});
async function fetchTournamentAuthorisedUsers(tournamentGuid: string) {
// Get the authorised users for the tournament
let authorisedUsers = [];
try {
const response = await client.getAuthorizedUsers(tournamentGuid);
console.log("authUsers Found", response);
authorisedUsers = (response as any).details.getAuthorizedUsers.authorizedUsers;
return authorisedUsers;
} catch (error) {
console.error(`Failed to get authorized users for tournament ${tournamentGuid}:`, error);
return authorisedUsers;
}
}
function closeNotification() {
showLoginNotification = false;
}
@ -242,20 +213,6 @@
}
};
// Convert image to Uint8Array if an image was provided
if (newTournamentImage) {
try {
// old way of making an image empty in TA, changed in fileserver update
// tournament.settings!.tournamentImage = await convertImageToUint8Array(newTournamentImage);
// new way is just an empty string
tournament.settings!.tournamentImage = "";
console.log("Image converted successfully", tournament.settings!.tournamentImage.length, "bytes");
} catch (error) {
console.error("Failed to convert image:", error);
// Continue with default image
}
}
// Create the tournament
console.log("Creating tournament:", tournament);
const response = await client.createTournament(
@ -269,24 +226,17 @@
false,
true,
true,
);
console.log("Tournament created:", response);
const responseTournament = (response.details as any).tournament;
// Add the new tournament to the list (for immediate display)
let imageUrl = '/images/tournaments/default.jpg'; // Default fallback
if (imagePreviewUrl) {
imageUrl = imagePreviewUrl;
}
tournaments = [
...tournaments,
{
id: responseTournament.guid.substring(0, 8),
name: responseTournament.settings!.tournamentName,
image: imageUrl,
image: responseTournament.settings!.tournamentImage && responseTournament.settings!.tournamentImage.length > 2 ? `https://${$TAServerUrl}:${$TAServerAPIPort}/api/file/${responseTournament.settings.tournamentImage}` : '/talogo.png',
guid: responseTournament.guid,
myPermissions: responseTournament.settings!.myPermissions
// authorisedUsers: []
@ -364,6 +314,8 @@
<a href={`/tournaments/${tournament.guid}`} class="tournament-card-link">
<div class="tournament-card">
<div class="tournament-background" style="background-image: url({tournament.image})"></div>
<!-- svelte-ignore a11y-img-redundant-alt -->
<!-- <img src={tournament.image} alt="Tournament Image" class="tournament-background"> -->
<div class="tournament-content">
<div class="tournament-image">
<img src={tournament.image || "/talogo.png"} alt={tournament.name} />

View file

@ -1,5 +1,5 @@
<script lang="ts">
import { TABotTokenStore, TAServerPort, TAServerUrl, authTokenStore, discordDataStore, client } from "$lib/stores";
import { TABotTokenStore, TAServerPort, TAServerUrl, authTokenStore, discordDataStore, client, TAServerAPIPort } from "$lib/stores";
import { onMount, onDestroy } from "svelte";
//@ts-ignore
import { Match, Tournament, TAClient, Response_ResponseType, Map } from 'moons-ta-client';
@ -91,7 +91,7 @@
async function handleMapPoolCreated(event: CustomEvent<TAMapPool>) {
const newMapPool = event.detail;
let createMapPoolResponse = await client.addTournamentPool(tournamentGuid, newMapPool);
let createMapPoolResponse = await client.addTournamentPool(tournamentGuid, newMapPool.name, newMapPool.image, []);
if(createMapPoolResponse.type !== Response_ResponseType.Success) {
error = "Failed to create the new map pool! Please refresh this page!";
@ -166,16 +166,9 @@
// Get map pools from tournament data
tournament?.settings?.pools.map(async (pool) => {
let mapPoolImage;
try {
mapPoolImage = bufferToImageUrl(pool.image);
} catch (error) {
mapPoolImage = "/talogo.png"
}
mapPools = [...mapPools, {
name: pool.name,
image: mapPoolImage,
image: pool.image && pool.image.length > 2 ? `https://${$TAServerUrl}:${$TAServerAPIPort}/api/file/${pool.image}` : '/talogo.png',
guid: pool.guid,
color: generateRandomHexColor()
}];

View file

@ -1,5 +1,5 @@
<script lang="ts">
import { TABotTokenStore, TAServerPort, TAServerUrl, authTokenStore, discordDataStore, client } from "$lib/stores";
import { TABotTokenStore, TAServerPort, TAServerUrl, authTokenStore, discordDataStore, client, TAServerAPIPort } from "$lib/stores";
import { onMount, onDestroy } from "svelte";
//@ts-ignore
import { Match, Tournament, TAClient, Response_ResponseType, QualifierEvent, Map, Tournament_TournamentSettings } from 'moons-ta-client';
@ -82,7 +82,7 @@
const result = e.target?.result;
if (result instanceof ArrayBuffer) {
qualifierImageBuffer = new Uint8Array(result);
const blob = new Blob([qualifierImageBuffer], { type: file.type });
const blob = new Blob([result as ArrayBuffer], { type: file.type });
qualifierImagePreview = URL.createObjectURL(blob);
}
};
@ -95,7 +95,8 @@
const newQualifier: QualifierEvent = {
guid: uuidv4(),
name: newQualifierName,
image: qualifierImageBuffer || new Uint8Array(1),
// image: qualifierImageBuffer || new Uint8Array(1),
image: "",
qualifierMaps: [],
infoChannel: {
id: "",
@ -105,17 +106,9 @@
sort: 0
};
// TODO: Add API call to create qualifier
let createQualifierResponse = await client.createQualifierEvent(tournamentGuid, newQualifier);
let createQualifierResponse = await client.createQualifierEvent(tournamentGuid, newQualifier.name, newQualifier.infoChannel!.id, [], 0, 0, qualifierImageBuffer || new Uint8Array(1));
console.log("newQual", createQualifierResponse);
let qualifierImage;
try {
qualifierImage = bufferToImageUrl(qualifierImageBuffer || new Uint8Array(1));
} catch (error) {
qualifierImage = "/talogo.png"
}
qualifiers = [
...qualifiers,
{
@ -265,7 +258,7 @@
{#each qualifiers as qualifier, qualIndex}
<div class="qualifier-card">
<div class="qualifier-header">
<img class="qualifier-image" src={bufferToImageUrl(qualifier.image) || '/talogo.png'} alt="{qualifier.name}" />
<img class="qualifier-image" src={qualifier.image && qualifier.image.length > 2 ? `https://${$TAServerUrl}:${$TAServerAPIPort}/api/file/${qualifier.image}` : '/talogo.png'} alt="{qualifier.name}" />
<div class="qualifier-info">
<h4>{qualifier.name}</h4>
<p class="maps-count">{qualifier.qualifierMaps.length} maps</p>

View file

@ -2,7 +2,7 @@
import { onMount } from "svelte";
//@ts-ignore
import { TAClient, Response_ResponseType, Map, Tournament, QualifierEvent, GameplayModifiers_GameOptions, QualifierEvent_EventSettings, QualifierEvent_LeaderboardSort } from 'moons-ta-client';
import { TABotTokenStore, TAServerPort, TAServerUrl, authTokenStore, client } from "$lib/stores";
import { TABotTokenStore, TAServerAPIPort, TAServerPort, TAServerUrl, authTokenStore, client } from "$lib/stores";
import { bufferToImageUrl, convertImageToUint8Array, linkToUint8Array } from "$lib/services/taImages.js";
import SideMenu from "$lib/components/menus/SideMenuTournaments.svelte";
import Popup from "$lib/components/notifications/Popup.svelte";
@ -71,7 +71,7 @@
// Qualifier settings
let qualifierName: string = "";
let qualifierImage: Uint8Array | null = null;
let qualifierImage: Uint8Array = new Uint8Array([]);
let qualifierImagePreview: string | null = null;
let hideScoresFromPlayers: boolean = false;
let disableScoresaberSubmission: boolean = false;
@ -194,7 +194,9 @@
const result = e.target?.result;
if (result instanceof ArrayBuffer) {
qualifierImage = new Uint8Array(result);
const blob = new Blob([qualifierImage], { type: file.type });
console.log("result", result)
console.log("newQualImage", qualifierImage)
const blob = new Blob([result as ArrayBuffer], { type: file.type });
qualifierImagePreview = URL.createObjectURL(blob);
}
};
@ -207,7 +209,7 @@
if (!qualifier) return;
try {
const setImageResponse = await client.setQualifierImage(tournamentGuid, qualifierGuid, qualifierImage || qualifier.image);
const setImageResponse = await client.setQualifierImage(tournamentGuid, qualifierGuid, qualifierImage);
const setNameResponse = await client.setQualifierName(tournamentGuid, qualifierGuid, qualifierName);
const setFlagsResponse = await client.setQualifierFlags(tournamentGuid, qualifierGuid, qualifier.flags);
console.log("Qualifier Updated!", setImageResponse, setNameResponse, setFlagsResponse);
@ -310,9 +312,12 @@
enableDiscordScoreFeed = (qualifier.flags & QualifierEvent_EventSettings.EnableDiscordScoreFeed) === QualifierEvent_EventSettings.EnableDiscordScoreFeed;
hideScoresFromPlayers = (qualifier.flags & QualifierEvent_EventSettings.HideScoresFromPlayers) === QualifierEvent_EventSettings.HideScoresFromPlayers;
console.log("qualifier", qualifier)
// Set initial values
qualifierName = qualifier.name;
qualifierImagePreview = bufferToImageUrl(qualifier.image) || '/talogo.png';
qualifierImage = qualifier.image && qualifier.image.length > 2 ? await linkToUint8Array(`https://${$TAServerUrl}:${$TAServerAPIPort}/api/file/${qualifier.image}`) : new Uint8Array([]);
qualifierImagePreview = qualifier.image && qualifier.image.length > 2 ? `https://${$TAServerUrl}:${$TAServerAPIPort}/api/file/${qualifier.image}` : '/talogo.png';
// Load maps
const mapLevelIds = qualifier.qualifierMaps.map(map => map.gameplayParameters!.beatmap!.levelId);

View file

@ -1,5 +1,5 @@
<script lang="ts">
import { TABotTokenStore, TAServerPort, TAServerUrl, authTokenStore, discordDataStore, client } from "$lib/stores";
import { TABotTokenStore, TAServerPort, TAServerUrl, authTokenStore, discordDataStore, client, TAServerAPIPort } from "$lib/stores";
import { onMount, onDestroy } from "svelte";
import { bkAPIUrl } from '$lib/config.json';
import AddNewAuthorisedUser from "$lib/components/popups/AddNewAuthorisedUser.svelte";
@ -10,6 +10,7 @@
import InfoPopup from "$lib/components/notifications/InfoPopup.svelte";
import { bufferToImageUrl, convertImageToUint8Array, linkToUint8Array } from "$lib/services/taImages.js";
import Popup from "$lib/components/notifications/Popup.svelte";
import { goto } from "$app/navigation";
export let data;
@ -206,6 +207,12 @@
showSuccessfullySaved = true;
}
async function deleteTournament() {
await client.deleteTournament(tournamentGuid);
goto('/tournaments');
}
async function fetchTournamentData() {
if (!$authTokenStore) {
window.location.href = '/discordAuth';
@ -236,7 +243,7 @@
// Set initial values from tournament data
if (tournament) {
tournamentName = tournament.settings?.tournamentName || "";
tournamentImage = bufferToImageUrl(tournament.settings?.tournamentImage!) || tournamentImage;
tournamentImage = tournament.settings!.tournamentImage && tournament.settings!.tournamentImage.length > 2 ? `https://${$TAServerUrl}:${$TAServerAPIPort}/api/file/${tournament.settings!.tournamentImage}` : '/talogo.png';
enableMapPools = tournament.settings?.enablePools || false;
enableTeams = tournament.settings?.enableTeams || false;
showTournamentButton = tournament.settings?.showTournamentButton !== false;
@ -304,6 +311,10 @@
<span class="material-icons">refresh</span>
Refresh
</button>
<button class="action-button remove" on:click={deleteTournament}>
<span class="material-icons">delete</span>
Delete Tournament
</button>
</div>
</div>

View file

@ -1,5 +1,5 @@
<script lang="ts">
import { TABotTokenStore, TAServerPort, TAServerUrl, authTokenStore, discordDataStore, client } from "$lib/stores";
import { TABotTokenStore, TAServerPort, TAServerUrl, authTokenStore, discordDataStore, client, TAServerAPIPort } from "$lib/stores";
import { onMount, onDestroy } from "svelte";
//@ts-ignore
import { Match, Tournament, TAClient, Response_ResponseType } from 'moons-ta-client';
@ -101,7 +101,7 @@
if (result instanceof ArrayBuffer) {
teamImageBuffer = new Uint8Array(result);
// Create preview URL
const blob = new Blob([teamImageBuffer], { type: file.type });
const blob = new Blob([result as ArrayBuffer], { type: file.type });
teamImagePreview = URL.createObjectURL(blob);
}
};
@ -120,7 +120,7 @@
console.log(newTeam);
let createTeamResponse = await client.addTournamentTeam(tournamentGuid, newTeam);
let createTeamResponse = await client.addTournamentTeam(tournamentGuid, newTeam.name, newTeam.image);
if(createTeamResponse.type !== Response_ResponseType.Success) {
error = "Failed to create the new team! Please refresh this page!";
} else {
@ -189,15 +189,9 @@
// For demo purposes, we'll create some sample teams
// In a real app, this would come from the tournament data
tournament?.settings?.teams.map(async (team) => {
let teamImage;
try {
teamImage = bufferToImageUrl(team.image);
} catch (error) {
teamImage = "/talogo.png"
}
await teams.push({
name: team.name,
image: teamImage,
image: team.image && team.image.length > 2 ? `https://${$TAServerUrl}:${$TAServerAPIPort}/api/file/${team.image}` : '/talogo.png',
guid: team.guid,
color: generateRandomHexColor()
});