Version 1.1.0 - Modification et ajout de fonctionnalités
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Frontend Deployment / deploy-frontend (push) Successful in 34s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	Frontend Deployment / deploy-frontend (push) Successful in 34s
				
			This commit is contained in:
		@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "chopin-frontend",
 | 
			
		||||
  "version": "1.0.3",
 | 
			
		||||
  "version": "1.1.0",
 | 
			
		||||
  "private": true,
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "dev": "vite --host --port 8080",
 | 
			
		||||
 
 | 
			
		||||
@@ -54,6 +54,7 @@ import GuildHeaderUsers from '../Widget/Guild/GuildHeaderUsers.vue';
 | 
			
		||||
import GuildSettings from '../Widget/Guild/GuildSettings.vue';
 | 
			
		||||
import { useUserStore } from '@/stores/userStore';
 | 
			
		||||
import { useGlobalStore } from '@/stores/globalStore';
 | 
			
		||||
import Events from '@/utils/Events';
 | 
			
		||||
 | 
			
		||||
const userStore = useUserStore();
 | 
			
		||||
 | 
			
		||||
@@ -109,8 +110,13 @@ function updateServerInfo() {
 | 
			
		||||
        console.log("Server info updated");
 | 
			
		||||
        events.emit("GUILD_JOINED", data);
 | 
			
		||||
    })
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Events.on("GUILD_LIST_UPDATE", (guilds) => {
 | 
			
		||||
    server.value = guilds.find(g => g.id === globalStore.lastGuild);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
<style scoped>
 | 
			
		||||
 
 | 
			
		||||
@@ -151,7 +151,6 @@ function onDragEnd(event) {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
    gap: 10px;
 | 
			
		||||
    padding-right: 5px;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: 100%;
 | 
			
		||||
    overflow-y: auto;
 | 
			
		||||
@@ -192,6 +191,7 @@ function onDragEnd(event) {
 | 
			
		||||
    gap: 10px;
 | 
			
		||||
    margin-top: 2.5px;
 | 
			
		||||
    margin-bottom: 2.5px;
 | 
			
		||||
    padding-right: 5px;
 | 
			
		||||
}
 | 
			
		||||
.allSpace {
 | 
			
		||||
    flex: 1;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
<template>
 | 
			
		||||
<Video :video="video" ref="videoContainer">
 | 
			
		||||
    <div ref="controls" class="controls">
 | 
			
		||||
        <span v-if="globalStore.currentChannel" title="Ajouter à la liste de lecture" @click="disableAction(); playSong(false)" class="control-icon"><AddList /></span>
 | 
			
		||||
        <span v-if="globalStore.currentChannel" title="Lire maintenant" @click="disableAction(); playSong(true)" class="control-icon"><Icon icon="fa-play" /></span>
 | 
			
		||||
        <span title="Ajouter à la liste de lecture" @click="disableAction(); playSong(false)" :class="{'control-icon': globalStore.currentChannel, 'control-icon-disable': !globalStore.currentChannel}"><AddList /></span>
 | 
			
		||||
        <span title="Lire maintenant" @click="disableAction(); playSong(true)" :class="{'control-icon': globalStore.currentChannel, 'control-icon-disable': !globalStore.currentChannel}"><Icon icon="fa-play" /></span>
 | 
			
		||||
        <span v-if="!props.delete && video.type != 'attachment'" title="Enregistrer dans une playlist" @click="disableAction(); saveModal.open()" class="control-icon"><Icon icon="fa-save" /></span>
 | 
			
		||||
        <span v-if="props.delete" title="Supprimer" @click="disableAction(); Events.emit('video:delete', { video: props.video })" class="control-icon"><Icon icon="fa-trash" /></span>
 | 
			
		||||
    </div>
 | 
			
		||||
@@ -11,7 +11,7 @@
 | 
			
		||||
    <Video :video="video"/>
 | 
			
		||||
    <Button v-if="globalStore.currentChannel" @click="playSong(false)"><AddList /> Ajouter à la liste de lecture</Button>
 | 
			
		||||
    <Button v-if="globalStore.currentChannel" @click="playSong(true)"><Icon icon="fa-solid fa-play"/> Lire maintenant</Button>
 | 
			
		||||
    <div v-else>
 | 
			
		||||
    <div v-if="!globalStore.currentChannel" >
 | 
			
		||||
        <p class="text-secondary">Connectez vous à un salon audio sur le serveur {{ globalStore.actualServer ? globalStore.actualServer.name : '' }}, pour lancer un titre</p>
 | 
			
		||||
        <ActualChannel/>
 | 
			
		||||
    </div>
 | 
			
		||||
@@ -64,6 +64,7 @@ const props = defineProps({
 | 
			
		||||
let nativeVideo = {}
 | 
			
		||||
 | 
			
		||||
function disableAction() {
 | 
			
		||||
    if(!globalStore.currentChannel) return;
 | 
			
		||||
    controls.value.style.display = "none";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -74,7 +75,7 @@ let activePointerId = null;
 | 
			
		||||
const SLIDE_THRESHOLD = 10; // ajuster si besoin
 | 
			
		||||
 | 
			
		||||
function playSong(now) {
 | 
			
		||||
    
 | 
			
		||||
    if(!globalStore.currentChannel) return;
 | 
			
		||||
    IORequest("/SEARCH/PLAY", (data) => {
 | 
			
		||||
        modal.value.close();    
 | 
			
		||||
    }, {song: nativeVideo, now: now})
 | 
			
		||||
@@ -118,9 +119,12 @@ onMounted(() => {
 | 
			
		||||
            if (activePointerId != null) videoContainer.value.releasePointerCapture(activePointerId);
 | 
			
		||||
        } catch (e) { /* ignore */ }
 | 
			
		||||
        if(!videoContainer.value) return
 | 
			
		||||
        try {
 | 
			
		||||
        videoContainer.value.removeEventListener('pointermove', onPointerMove);
 | 
			
		||||
        videoContainer.value.removeEventListener('pointerup', onPointerUp);
 | 
			
		||||
        videoContainer.value.removeEventListener('pointercancel', onPointerCancel);
 | 
			
		||||
        } catch (e) { console.log(videoContainer.value) }
 | 
			
		||||
  
 | 
			
		||||
        activePointerId = null;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
@@ -149,10 +153,16 @@ onMounted(() => {
 | 
			
		||||
        isSliding = false;
 | 
			
		||||
        activePointerId = ev.pointerId;
 | 
			
		||||
        if(!videoContainer.value) return
 | 
			
		||||
        try {
 | 
			
		||||
            thumbnailContainer.value = videoContainer.value.getThumbnailContainer();
 | 
			
		||||
            videoContainer.value = videoContainer.value.getVideoContainer();
 | 
			
		||||
        } catch (e) { }
 | 
			
		||||
        try { videoContainer.value.setPointerCapture(activePointerId); } catch (e) { /* ignore */ }
 | 
			
		||||
        try {
 | 
			
		||||
             videoContainer.value.addEventListener('pointermove', onPointerMove);
 | 
			
		||||
            videoContainer.value.addEventListener('pointerup', onPointerUp);
 | 
			
		||||
            videoContainer.value.addEventListener('pointercancel', onPointerCancel);
 | 
			
		||||
        } catch (e) { console.log(videoContainer.value) }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    videoContainer.value.addEventListener('pointerdown', onPointerDown);
 | 
			
		||||
@@ -218,6 +228,20 @@ onMounted(() => {
 | 
			
		||||
    opacity: 0.8;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.control-icon-disable {
 | 
			
		||||
    font-size: 1.2em;
 | 
			
		||||
    background-color: var(--text-inverse);
 | 
			
		||||
    color: var(--secondary);
 | 
			
		||||
    border-radius: 100%;
 | 
			
		||||
    width: 40px;
 | 
			
		||||
    height: 40px;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    justify-content: center;
 | 
			
		||||
    opacity: 0.8;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.video:hover .controls {
 | 
			
		||||
    opacity: 1;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,6 @@
 | 
			
		||||
<template>
 | 
			
		||||
 <div class="default">
 | 
			
		||||
  <!-- <Carousel v-show="!loading" class="child"> -->
 | 
			
		||||
    <Changelog/>
 | 
			
		||||
    <!-- <History/>
 | 
			
		||||
    <Advice/>
 | 
			
		||||
  </Carousel> -->
 | 
			
		||||
  <p v-show="loading" class="loading">
 | 
			
		||||
    <Icon icon="fa-spinner fa-solid" spin-pulse/> Chargement en cours
 | 
			
		||||
  </p>
 | 
			
		||||
@@ -47,18 +43,13 @@ p {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.default  {
 | 
			
		||||
    display: grid;
 | 
			
		||||
    grid-template-rows: 1fr;
 | 
			
		||||
    grid-template-columns: 1fr;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    gap: 5px;
 | 
			
		||||
    flex: 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media screen and (max-width: 768px),
 | 
			
		||||
       screen and (max-height: 607px) {
 | 
			
		||||
    .default {
 | 
			
		||||
        grid-template-rows: 1fr;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.child {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
    <section class="changelog">
 | 
			
		||||
    <Welcome/>
 | 
			
		||||
    <h2 class="changelog-title">📝 Changelog</h2>
 | 
			
		||||
    <div class="changelog-overflow" v-if="changelog" >
 | 
			
		||||
    <div v-if="changelog" class="changelog-overflow">
 | 
			
		||||
        <div class="changelog-container" v-html="changelog" ></div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="textSecond" v-else-if="!error"><Icon icon="fa-spinner fa-solid" spin-pulse/> Chargement en cours</div>
 | 
			
		||||
@@ -39,6 +39,8 @@ function loadChangelog() {
 | 
			
		||||
            data = data.replaceAll("-*", "</span>");
 | 
			
		||||
            data = data.replaceAll("*_", "<span class='underline'>");
 | 
			
		||||
            data = data.replaceAll("_*", "</span>");
 | 
			
		||||
            data = data.replaceAll('/#', "<span class='changelog-tags'>");
 | 
			
		||||
            data = data.replaceAll('#/', "</span>");
 | 
			
		||||
 | 
			
		||||
            changelog.value = data;
 | 
			
		||||
        } else {
 | 
			
		||||
@@ -102,12 +104,13 @@ function loadChangelog() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.changelog-container {
 | 
			
		||||
    display: grid;
 | 
			
		||||
    grid-template-columns: 1fr;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
    gap: 15px;
 | 
			
		||||
    overflow-y: auto;
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    flex: 1;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    grid-template-rows: auto;
 | 
			
		||||
    gap: 20px;
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.changelog {
 | 
			
		||||
@@ -119,7 +122,10 @@ function loadChangelog() {
 | 
			
		||||
 | 
			
		||||
.changelog-overflow {
 | 
			
		||||
    overflow-y: auto;
 | 
			
		||||
    position: relative;
 | 
			
		||||
    max-height: 100%;
 | 
			
		||||
    flex: 1;
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.tags {
 | 
			
		||||
@@ -225,20 +231,57 @@ function loadChangelog() {
 | 
			
		||||
    white-space: nowrap; /* Prevent line breaks */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media screen and (max-width: 768px),
 | 
			
		||||
       screen and (max-height: 607px) {
 | 
			
		||||
    .changelog-container {
 | 
			
		||||
        grid-template-columns: 1fr !important;
 | 
			
		||||
    }
 | 
			
		||||
.changelog-overflow {
 | 
			
		||||
  position: relative;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    .changelog-container ul {
 | 
			
		||||
        padding: 0
 | 
			
		||||
     
 | 
			
		||||
        display: flex;
 | 
			
		||||
        flex-direction: column;
 | 
			
		||||
        gap: 10px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .changelog-tags {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: row;
 | 
			
		||||
    gap: 5px;
 | 
			
		||||
    background-color: var(--quaternary);
 | 
			
		||||
    padding: 5px;
 | 
			
		||||
    border-radius: 10px;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
@media screen and (max-width: 768px),
 | 
			
		||||
       screen and (max-height: 607px) {
 | 
			
		||||
    
 | 
			
		||||
        .changelog-container ul {
 | 
			
		||||
             padding: 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    .changelog-version ul li::before {
 | 
			
		||||
        display: none;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    .welcome-container {
 | 
			
		||||
        flex-direction: column;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        gap: 10px;
 | 
			
		||||
        width: 100%;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .welcome-actions {
 | 
			
		||||
        flex-direction: column;
 | 
			
		||||
        width: 100%;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .changelog-tags {
 | 
			
		||||
         flex-direction: column;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
 
 | 
			
		||||
@@ -126,6 +126,7 @@ const props = defineProps({
 | 
			
		||||
 | 
			
		||||
function openAuthorPage() {
 | 
			
		||||
    if (!props.results.authorId) return;
 | 
			
		||||
    if(!props.results.author) return;
 | 
			
		||||
    window.open(props.results.authorId, '_blank');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
            <h2><Icon icon="fa-folder"/> Mes fichiers</h2>
 | 
			
		||||
            <Box box-class="area-container" padding="close" level="second">
 | 
			
		||||
                <div class="upload-area">
 | 
			
		||||
                    <Button :color-lower="status === 'download'" :disabled="status === 'download'" class="upload-button" @click="uploadFile()"><Icon icon="fa-upload"/> Ajouter un fichier</Button>
 | 
			
		||||
                    <Button :color-lower="status === 'download'" :disabled="status === 'download'" class="upload-button" @click="uploadFile()"><Icon icon="fa-upload"/> Ajouter des fichiers</Button>
 | 
			
		||||
                    <p v-if="status === 'download'" class="upload-file-name" ref="uploadStatus"><Icon icon='fa-spinner' spin-pulse/> Téléchargement en cours...</p>
 | 
			
		||||
                    <p v-else-if="status === 'error'" class="upload-status" ref="uploadStatus"><Error>Erreur lors du téléchargement</Error></p>
 | 
			
		||||
                    <p v-else-if="status === 'toohigh'" class="upload-status" ref="uploadStatus"><Error>Le fichier est trop volumineux</Error></p>
 | 
			
		||||
@@ -14,15 +14,17 @@
 | 
			
		||||
                <p class="text-secondary infosup"><Icon icon="fa-circle-info"/> Ce système n'est pas un stockage permanent de données car il dépend du CDN de Discord. Vos fichiers peuvent exprirer à tout moment.</p>
 | 
			
		||||
            </Box>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div v-if="myFiles && myFiles.length > 0" class="uploaded-files">
 | 
			
		||||
        <div  v-if="myFiles && myFiles.length > 0" class="uploaded-files-container">
 | 
			
		||||
        <div class="uploaded-files">
 | 
			
		||||
            <span v-for="file in myFiles" :key="file.id"><VideoComposable  :video="file" delete/></span>
 | 
			
		||||
        </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <p v-else-if="isLoading" class="none"><Icon icon="fa-spinner" spin-pulse/> Chargement des fichiers...</p>
 | 
			
		||||
        <p v-else class="none"><Icon icon="fa-circle-xmark"/> Aucun fichier enregistré</p>
 | 
			
		||||
        <Modal icon="fa-upload" title="Uploader un fichier" ref="uploadModal">
 | 
			
		||||
            <p>Etes-vous sûr de vouloir uploader ce fichier ?</p>
 | 
			
		||||
            <p class="text-secondary">Ce fichier sera stocké sur le CDN de Discord et sera à jamais accessible. Ne diffusez rien de sensible.</p>
 | 
			
		||||
            <p v-if="fileSelected" class="upload-modal-name"><Icon icon="fa-file"/> {{ fileSelected.name }}</p>
 | 
			
		||||
            <p>Etes-vous sûr de vouloir uploader ces fichiers ?</p>
 | 
			
		||||
            <p class="text-secondary">Ces fichiers seront stockés sur le CDN de Discord et seront à jamais accessibles. Ne diffusez rien de sensible.</p>
 | 
			
		||||
            <p v-if="fileSelected.length > 0" v-for="value in fileSelected" class="upload-modal-name"><Icon icon="fa-file"/> {{ value.name }}</p>
 | 
			
		||||
            <div class="upload-actions">
 | 
			
		||||
                <Button @click="closeModal()">Annuler</Button>
 | 
			
		||||
                <Button @click="confirmUpload()">Confirmer</Button>
 | 
			
		||||
@@ -41,7 +43,7 @@ import { IORequest } from '@/utils/IORequest';
 | 
			
		||||
import { onMounted, onUnmounted, ref } from 'vue';
 | 
			
		||||
import Events from '@/utils/Events';
 | 
			
		||||
 | 
			
		||||
const fileSelected = ref(null);
 | 
			
		||||
const fileSelected = ref([]);
 | 
			
		||||
const status = ref(false);
 | 
			
		||||
const uploadModal = ref(null);
 | 
			
		||||
const myFiles = ref([]);
 | 
			
		||||
@@ -66,53 +68,68 @@ function uploadFile() {
 | 
			
		||||
    const input = document.createElement('input');
 | 
			
		||||
    input.type = 'file';
 | 
			
		||||
    input.accept = '.mp3,.wav,.ogg'; // Accept audio files
 | 
			
		||||
    input.multiple = true;
 | 
			
		||||
    input.onchange = (event) => {
 | 
			
		||||
        const file = event.target.files[0];
 | 
			
		||||
        if (file) {
 | 
			
		||||
            fileSelected.value = file;
 | 
			
		||||
            // Here you would typically handle the file upload to the server
 | 
			
		||||
            console.log(`File selected: ${file.name}`);
 | 
			
		||||
            // Reset the input for future uploads
 | 
			
		||||
       const files = Array.from(event.target.files);
 | 
			
		||||
       if (files.length > 0) {
 | 
			
		||||
            fileSelected.value = files;
 | 
			
		||||
            console.log(`Files selected:`, files.map(f => f.name));
 | 
			
		||||
            input.value = '';
 | 
			
		||||
            // destroy input
 | 
			
		||||
            input.remove();
 | 
			
		||||
            uploadModal.value.open();
 | 
			
		||||
        } else {
 | 
			
		||||
            fileSelected.value = null;
 | 
			
		||||
            fileSelected.value = [];
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    input.click();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function confirmUpload() {
 | 
			
		||||
    console.log(`Uploading file: ${fileSelected.value.name}`);
 | 
			
		||||
async function confirmUpload() {
 | 
			
		||||
    if (fileSelected.value.length === 0) return;
 | 
			
		||||
    status.value = 'download';
 | 
			
		||||
    uploadModal.value.close();
 | 
			
		||||
    if(fileSelected.value) {
 | 
			
		||||
        // Send the file to the server
 | 
			
		||||
        const reader = new FileReader();
 | 
			
		||||
        reader.onload = () => {
 | 
			
		||||
            const fileBuffer = reader.result;
 | 
			
		||||
            // If it's higher than 300mb
 | 
			
		||||
 | 
			
		||||
    let errorOccurred = false;
 | 
			
		||||
 | 
			
		||||
    for (const file of fileSelected.value) {
 | 
			
		||||
        try {
 | 
			
		||||
            const fileBuffer = await readFileAsArrayBuffer(file);
 | 
			
		||||
 | 
			
		||||
            if (fileBuffer.byteLength > 300 * 1024 * 1024) {
 | 
			
		||||
                status.value = 'toohigh';
 | 
			
		||||
                console.error('File is too large');
 | 
			
		||||
                return;
 | 
			
		||||
                errorOccurred = true;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            await new Promise(resolve => {
 | 
			
		||||
                IORequest('/UPLOAD/FILE', (response) => {
 | 
			
		||||
                if(!response) {
 | 
			
		||||
                    status.value = 'error';
 | 
			
		||||
                } else if(response === "TOOHIGH") {
 | 
			
		||||
                    status.value = 'toohigh';
 | 
			
		||||
                } else {
 | 
			
		||||
                    status.value = 'success';
 | 
			
		||||
                    if (!response || response === "TOOHIGH") {
 | 
			
		||||
                        errorOccurred = true;
 | 
			
		||||
                        status.value = (response === "TOOHIGH") ? 'toohigh' : 'error';
 | 
			
		||||
                    }
 | 
			
		||||
                    resolve();
 | 
			
		||||
                }, { name: file.name, file: fileBuffer });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        } catch (err) {
 | 
			
		||||
            console.error("Erreur upload fichier:", file.name, err);
 | 
			
		||||
            errorOccurred = true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    status.value = errorOccurred ? status.value : 'success';
 | 
			
		||||
    refreshUploadedFiles();
 | 
			
		||||
            }, {name: fileSelected.value.name, file: fileBuffer})
 | 
			
		||||
            fileSelected.value = null;
 | 
			
		||||
        };
 | 
			
		||||
        reader.readAsArrayBuffer(fileSelected.value);
 | 
			
		||||
    }
 | 
			
		||||
    fileSelected.value = [];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Petite fonction utilitaire pour transformer FileReader en promesse
 | 
			
		||||
function readFileAsArrayBuffer(file) {
 | 
			
		||||
    return new Promise((resolve, reject) => {
 | 
			
		||||
        const reader = new FileReader();
 | 
			
		||||
        reader.onload = () => resolve(reader.result);
 | 
			
		||||
        reader.onerror = reject;
 | 
			
		||||
        reader.readAsArrayBuffer(file);
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -149,6 +166,17 @@ function refreshUploadedFiles() {
 | 
			
		||||
    display: grid;
 | 
			
		||||
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
 | 
			
		||||
    gap: 10px;
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.uploaded-files-container {
 | 
			
		||||
    position: relative;
 | 
			
		||||
    flex: 1;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: 100%;
 | 
			
		||||
    overflow-y: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.none {
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@ import { IOListener, IORequest } from '@/utils/IORequest';
 | 
			
		||||
import { useUserStore } from '@/stores/userStore';
 | 
			
		||||
import { useGlobalStore } from '@/stores/globalStore';
 | 
			
		||||
import events from '@/utils/Events.js';
 | 
			
		||||
import Events from '@/utils/Events.js';
 | 
			
		||||
 | 
			
		||||
    const router = useRouter();
 | 
			
		||||
    const interuptionMessage = ref(null);
 | 
			
		||||
@@ -43,6 +44,7 @@ import events from '@/utils/Events.js';
 | 
			
		||||
        IORequest("/GUILD/LIST", (response) => {
 | 
			
		||||
            if(response) {
 | 
			
		||||
                userStore.userInfo.guilds = response;
 | 
			
		||||
                Events.emit("GUILD_LIST_UPDATE", response);
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
    })
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user