Version 1.2.0 - Ajout des suggestions et de paramètres
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Frontend Deployment / deploy-frontend (push) Successful in 35s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	Frontend Deployment / deploy-frontend (push) Successful in 35s
				
			This commit is contained in:
		@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "chopin-frontend",
 | 
					  "name": "chopin-frontend",
 | 
				
			||||||
  "version": "1.1.0",
 | 
					  "version": "1.2.0",
 | 
				
			||||||
  "private": true,
 | 
					  "private": true,
 | 
				
			||||||
  "scripts": {
 | 
					  "scripts": {
 | 
				
			||||||
    "dev": "vite --host --port 8080",
 | 
					    "dev": "vite --host --port 8080",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,8 +31,6 @@ const router = useRouter();
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const userSettings = ref(null);
 | 
					const userSettings = ref(null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//FIXME: Set to dispatcher
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
<style scoped>
 | 
					<style scoped>
 | 
				
			||||||
.box {
 | 
					.box {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,8 +25,8 @@
 | 
				
			|||||||
                                </div>
 | 
					                                </div>
 | 
				
			||||||
                            </div>
 | 
					                            </div>
 | 
				
			||||||
                                <div class="server-actions">
 | 
					                                <div class="server-actions">
 | 
				
			||||||
                                    <Button v-if="gestion" @click="settings.open()"><Icon icon="fa-solid fa-gear"/>Gestion</Button>
 | 
					                                    <Button icon="fa-solid fa-gear" v-if="gestion" @click="settings.open()">Gestion</Button>
 | 
				
			||||||
                                    <Button :style="{width: gestion ? '' : '100%'}" @click="router.push(`/servers`)"><Icon icon="fa-solid fa-arrow-right"/>Changer de serveur</Button>
 | 
					                                    <Button icon="fa-solid fa-arrow-right" :style="{width: gestion ? '' : '100%'}" @click="router.push(`/servers`)">Changer de serveur</Button>
 | 
				
			||||||
                                </div>
 | 
					                                </div>
 | 
				
			||||||
                            </div>
 | 
					                            </div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -112,9 +112,6 @@ const playerOpen = ref(false);
 | 
				
			|||||||
const durationBar = ref(null);
 | 
					const durationBar = ref(null);
 | 
				
			||||||
const buffering = ref(false);
 | 
					const buffering = ref(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//TODO: Rework Animation Both Side
 | 
					 | 
				
			||||||
//FIXME: Animation weird 550px 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const playerMobile = ref(null);
 | 
					const playerMobile = ref(null);
 | 
				
			||||||
const playerMobileToggle = ref(null);
 | 
					const playerMobileToggle = ref(null);
 | 
				
			||||||
const playerHeight = ref(0);
 | 
					const playerHeight = ref(0);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,7 +12,7 @@
 | 
				
			|||||||
                </p>
 | 
					                </p>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <Button class="add-playlist" @click="openModal()"><Icon icon="fa-add"/> Ajouter une playlist</Button>
 | 
					        <Button icon="fa-add" class="add-playlist" @click="openModal()">Ajouter une playlist</Button>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <Modal icon="fa-list" title="Ajouter une Playlist" ref="modal">
 | 
					    <Modal icon="fa-list" title="Ajouter une Playlist" ref="modal">
 | 
				
			||||||
        <div class="p-modal-content">
 | 
					        <div class="p-modal-content">
 | 
				
			||||||
@@ -23,7 +23,7 @@
 | 
				
			|||||||
                <label>Importer depuis Youtube</label>
 | 
					                <label>Importer depuis Youtube</label>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            <Button :disabled="(!isYoutube && newPlaylistTitle.trim() === '') || (isYoutube && urlLink?.trim() === '')" @click="addPlaylist">Ajouter</Button>
 | 
					            <Button icon="fa-add" :disabled="(!isYoutube && newPlaylistTitle.trim() === '') || (isYoutube && urlLink?.trim() === '')" @click="addPlaylist">Ajouter</Button>
 | 
				
			||||||
            <p class="text-loading" v-if="isLoading"><Icon icon="fa-spinner" spin-pulse /> Création en cours...</p>
 | 
					            <p class="text-loading" v-if="isLoading"><Icon icon="fa-spinner" spin-pulse /> Création en cours...</p>
 | 
				
			||||||
            <p class="text-loading" v-if="error"><Error> {{ error }}</Error></p>
 | 
					            <p class="text-loading" v-if="error"><Error> {{ error }}</Error></p>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,11 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
    <div class="search">
 | 
					    <div class="search">
 | 
				
			||||||
        <Icon color="#FFFFFF" icon="fa-solid fa-magnifying-glass" style="width: 20px;" />
 | 
					        <Icon color="#FFFFFF" icon="fa-solid fa-magnifying-glass" style="width: 20px;" />
 | 
				
			||||||
        <input name="search" ref="searchBar" type="text" placeholder="Insérer votre recherche ici" v-model="searchQuery" />
 | 
					        <div class="search-bar">
 | 
				
			||||||
 | 
					        <input autocomplete="off" name="search" ref="searchBar" type="text" placeholder="Insérer votre recherche ici" v-model="searchQuery" />
 | 
				
			||||||
 | 
					        <Icon color="#FFFFFF" v-if="searchQuery.trim() !== ''" icon="fa-solid fa-xmark" class="clear-icon" @click="searchQuery = ''" />
 | 
				
			||||||
 | 
					        <SearchSuggestions v-if="searchQuery.trim() !== '' && suggestClose" :query="searchQuery" />
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
        <div class="search-actions">
 | 
					        <div class="search-actions">
 | 
				
			||||||
            <IconAction
 | 
					            <IconAction
 | 
				
			||||||
                icon="fa-solid fa-cloud-arrow-up"
 | 
					                icon="fa-solid fa-cloud-arrow-up"
 | 
				
			||||||
@@ -25,17 +29,24 @@ import { onBeforeUnmount, onMounted, ref } from 'vue';
 | 
				
			|||||||
import IconAction from '../UI/IconAction.vue';
 | 
					import IconAction from '../UI/IconAction.vue';
 | 
				
			||||||
import { IORequest } from '@/utils/IORequest';
 | 
					import { IORequest } from '@/utils/IORequest';
 | 
				
			||||||
import Events from '@/utils/Events';
 | 
					import Events from '@/utils/Events';
 | 
				
			||||||
 | 
					import SearchSuggestions from '@/components/Widget/View/Search/SearchSuggestions.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const searchBar = ref(null);
 | 
					const searchBar = ref(null);
 | 
				
			||||||
const searchQuery = ref('');
 | 
					const searchQuery = ref('');
 | 
				
			||||||
 | 
					const suggestClose = ref(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
onMounted(() => {
 | 
					onMounted(() => {
 | 
				
			||||||
    searchBar.value.addEventListener('change', find);
 | 
					    searchBar.value.addEventListener('change', () => {
 | 
				
			||||||
 | 
					        find();
 | 
				
			||||||
 | 
					        suggestClose.value = true;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    searchBar.value.addEventListener('keydown', (event) => {
 | 
				
			||||||
 | 
					        suggestClose.value = true;   
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//TODO: Faire un systême de suggestions.
 | 
					function find(queryByResult) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
function find() {
 | 
					 | 
				
			||||||
    // If on mobile close the keyboard
 | 
					    // If on mobile close the keyboard
 | 
				
			||||||
    if (window.innerWidth < 768) {
 | 
					    if (window.innerWidth < 768) {
 | 
				
			||||||
        searchBar.value.blur();
 | 
					        searchBar.value.blur();
 | 
				
			||||||
@@ -43,9 +54,15 @@ function find() {
 | 
				
			|||||||
    if (searchQuery.value.trim() === '') {
 | 
					    if (searchQuery.value.trim() === '') {
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if(queryByResult == "result") {
 | 
				
			||||||
 | 
					        Events.emit("SEARCH_RESULT_SENDED");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    Events.emit("SEARCH_STARTED");
 | 
					    Events.emit("SEARCH_STARTED");
 | 
				
			||||||
    IORequest("/SEARCH", (data) => {
 | 
					    IORequest("/SEARCH", (data) => {
 | 
				
			||||||
        Events.emit("SEARCH_RESULT", {data: data, query: searchQuery.value});
 | 
					        Events.emit("SEARCH_RESULT", {data: data, query: searchQuery.value});
 | 
				
			||||||
 | 
					        if(queryByResult == "result") {
 | 
				
			||||||
 | 
					        Events.emit("SEARCH_RESULT_SENDED");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }, searchQuery.value);
 | 
					    }, searchQuery.value);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -53,6 +70,13 @@ Events.on("VIEW_CLOSED", () => {
 | 
				
			|||||||
    searchQuery.value = '';
 | 
					    searchQuery.value = '';
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Events.on("SEARCH_RESULT_SELECTED", (result) => {
 | 
				
			||||||
 | 
					    searchQuery.value = result;
 | 
				
			||||||
 | 
					    suggestClose.value = false;
 | 
				
			||||||
 | 
					    Events.emit("SEARCH_RESULT_SENDED");
 | 
				
			||||||
 | 
					    find("result");
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
@@ -68,6 +92,19 @@ Events.on("VIEW_CLOSED", () => {
 | 
				
			|||||||
    box-shadow: 2px 2px 10px 0px rgba(0, 0, 0, 0.50);
 | 
					    box-shadow: 2px 2px 10px 0px rgba(0, 0, 0, 0.50);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.clear-icon {
 | 
				
			||||||
 | 
					    cursor: pointer;
 | 
				
			||||||
 | 
					    position: absolute;
 | 
				
			||||||
 | 
					    right: 10px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.search-bar {
 | 
				
			||||||
 | 
					    position: relative;
 | 
				
			||||||
 | 
					    flex: 1;
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    align-items: center;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.search input {
 | 
					.search input {
 | 
				
			||||||
    border: none;
 | 
					    border: none;
 | 
				
			||||||
    outline: none;
 | 
					    outline: none;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,8 +26,6 @@ const disableClass = computed(() => {
 | 
				
			|||||||
    return props.disabled ? props.colorLower ? 'disabled color-lower' : 'disabled' : '';
 | 
					    return props.disabled ? props.colorLower ? 'disabled color-lower' : 'disabled' : '';
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//TODO: Refactor every button component to use the icon prop
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
<style scoped>
 | 
					<style scoped>
 | 
				
			||||||
button {
 | 
					button {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -65,6 +65,7 @@ function open() {
 | 
				
			|||||||
    if (modal.value) {
 | 
					    if (modal.value) {
 | 
				
			||||||
        modal.value.style.display = 'flex';
 | 
					        modal.value.style.display = 'flex';
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    Events.emit('modal:open');
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
defineExpose({
 | 
					defineExpose({
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
<script setup lang="ts">
 | 
					<script setup>
 | 
				
			||||||
import IconAction from './IconAction.vue';
 | 
					import IconAction from './IconAction.vue';
 | 
				
			||||||
import { ref, onMounted, watch, onUnmounted } from 'vue';
 | 
					import { ref, onMounted, watch, onUnmounted } from 'vue';
 | 
				
			||||||
import { useSlots } from 'vue';
 | 
					import { useSlots } from 'vue';
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,11 @@
 | 
				
			|||||||
    <div class="subsonics-logo">
 | 
					    <div class="subsonics-logo">
 | 
				
			||||||
        <LogoDark class="img" v-if="globalStore.theme == 'light'"/>
 | 
					        <LogoDark class="img" v-if="globalStore.theme == 'light'"/>
 | 
				
			||||||
        <LogoLight class="img" v-else/>
 | 
					        <LogoLight class="img" v-else/>
 | 
				
			||||||
 | 
					        <div v-if="dev" class="text-p">
 | 
				
			||||||
            <h1>Subsonics</h1>
 | 
					            <h1>Subsonics</h1>
 | 
				
			||||||
 | 
					            <p>Developement</p>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <h1 v-if="!dev">Subsonics</h1>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
<script setup>
 | 
					<script setup>
 | 
				
			||||||
@@ -10,6 +14,8 @@ import LogoDark from '@/assets/LogoDark.vue';
 | 
				
			|||||||
import LogoLight from '@/assets/LogoLight.vue';
 | 
					import LogoLight from '@/assets/LogoLight.vue';
 | 
				
			||||||
import { useGlobalStore } from '@/stores/globalStore';
 | 
					import { useGlobalStore } from '@/stores/globalStore';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const dev = import.meta.env.DEV;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const globalStore = useGlobalStore();
 | 
					const globalStore = useGlobalStore();
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
<style scoped>
 | 
					<style scoped>
 | 
				
			||||||
@@ -27,6 +33,25 @@ const globalStore = useGlobalStore();
 | 
				
			|||||||
        justify-content: center;
 | 
					        justify-content: center;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .text-p {
 | 
				
			||||||
 | 
					        display: flex;
 | 
				
			||||||
 | 
					        align-items: flex-start;
 | 
				
			||||||
 | 
					        flex-direction: column;
 | 
				
			||||||
 | 
					        position: relative;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					      .text-p h1 {
 | 
				
			||||||
 | 
					        margin: 0 !important;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       .text-p p {
 | 
				
			||||||
 | 
					        margin: 0 !important;
 | 
				
			||||||
 | 
					        font-family: 'Gunship', sans-serif;
 | 
				
			||||||
 | 
					        position: absolute;
 | 
				
			||||||
 | 
					        bottom: -10px;
 | 
				
			||||||
 | 
					        font-size: 0.8em;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @media screen and (max-width: 768px),
 | 
					    @media screen and (max-width: 768px),
 | 
				
			||||||
            screen and (max-height: 607px) {
 | 
					            screen and (max-height: 607px) {
 | 
				
			||||||
        .img {
 | 
					        .img {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,9 +3,11 @@
 | 
				
			|||||||
        <ModalTree title="Utilisateurs" icon="fa-solid fa-users">
 | 
					        <ModalTree title="Utilisateurs" icon="fa-solid fa-users">
 | 
				
			||||||
            <GuildUsers :server="server"/>
 | 
					            <GuildUsers :server="server"/>
 | 
				
			||||||
        </ModalTree>
 | 
					        </ModalTree>
 | 
				
			||||||
 | 
					        <ModalTree v-if="userStore.userInfo.labels.includes('ADMIN') || userStore.userInfo.identity.id == server.owner" title="Sécurité" icon="fa-solid fa-shield-halved">
 | 
				
			||||||
 | 
					           <GuildSecurity :server="server"/>
 | 
				
			||||||
 | 
					        </ModalTree>
 | 
				
			||||||
        <ModalTree title="Statistiques" icon="fa-solid fa-chart-simple">
 | 
					        <ModalTree title="Statistiques" icon="fa-solid fa-chart-simple">
 | 
				
			||||||
            <GuildStats :server="server"/>
 | 
					            <GuildStats :server="server"/>
 | 
				
			||||||
 | 
					 | 
				
			||||||
        </ModalTree>
 | 
					        </ModalTree>
 | 
				
			||||||
    </Modal>
 | 
					    </Modal>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
@@ -15,13 +17,14 @@ import ModalTree from '@/components/UI/ModalTree.vue';
 | 
				
			|||||||
import { ref } from 'vue';
 | 
					import { ref } from 'vue';
 | 
				
			||||||
import GuildUsers from './Settings/GuildUsers.vue';
 | 
					import GuildUsers from './Settings/GuildUsers.vue';
 | 
				
			||||||
import GuildStats from './Settings/GuildStats.vue';
 | 
					import GuildStats from './Settings/GuildStats.vue';
 | 
				
			||||||
 | 
					import GuildSecurity from './Settings/GuildSecurity.vue';
 | 
				
			||||||
import Events from '@/utils/Events';
 | 
					import Events from '@/utils/Events';
 | 
				
			||||||
 | 
					import { useUserStore } from '@/stores/userStore';
 | 
				
			||||||
 | 
					const userStore = useUserStore();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const modal = ref(null);
 | 
					const modal = ref(null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//TODO: Ajouter la sécurité des roles pour empêcher l'utilisation publique du Bot
 | 
					 | 
				
			||||||
//TODO: Ajout de Log pour serveur
 | 
					//TODO: Ajout de Log pour serveur
 | 
				
			||||||
//TODO: Paramétérer une liste des channels autorisé !
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const props = defineProps({
 | 
					const props = defineProps({
 | 
				
			||||||
    server: {
 | 
					    server: {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										93
									
								
								src/components/Widget/Guild/Settings/GuildSecurity.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								src/components/Widget/Guild/Settings/GuildSecurity.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,93 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					    <div class="setting">
 | 
				
			||||||
 | 
					    <p class="text-secondary"><Icon icon="fa-solid fa-user-shield" /> Autoriser les utilisateurs avec un rôle spécifique</p>
 | 
				
			||||||
 | 
					    <Selector v-model="roleSelected" ref="roleSelector" v-if="roles.length > 0 && modalOpen">
 | 
				
			||||||
 | 
					      <Tag v-for="role in roles" :key="role.id" :value="role.id" :color="decimalToHex(role.color)">{{role.name.replace("@everyone", "Tout le monde (@everyone)")}}</Tag>
 | 
				
			||||||
 | 
					    </Selector>
 | 
				
			||||||
 | 
					    <Button @click="updateRole" icon="fa-solid fa-rotate">Mettre à jour</Button>
 | 
				
			||||||
 | 
					    <Success v-if="roleUpdated">Rôle mis à jour avec succès !</Success>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					<script setup>
 | 
				
			||||||
 | 
					import { onMounted, ref, watch } from 'vue';
 | 
				
			||||||
 | 
					import Selector from '@/components/UI/Selector.vue';
 | 
				
			||||||
 | 
					import { IORequest } from '@/utils/IORequest';
 | 
				
			||||||
 | 
					import Tag from '@/components/UI/Tag.vue';
 | 
				
			||||||
 | 
					import Events from '@/utils/Events';
 | 
				
			||||||
 | 
					import Button from '@/components/UI/Button.vue';
 | 
				
			||||||
 | 
					import Success from '@/components/UI/Success.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const roles = ref([])
 | 
				
			||||||
 | 
					const roleSelector = ref(null);
 | 
				
			||||||
 | 
					const roleUpdated = ref(false); 
 | 
				
			||||||
 | 
					const roleSelected = ref(null);
 | 
				
			||||||
 | 
					const modalOpen = ref(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const props = defineProps({
 | 
				
			||||||
 | 
					    server: {
 | 
				
			||||||
 | 
					        type: Object,
 | 
				
			||||||
 | 
					        required: true
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//TODO: FINISH IMPLEMENTATION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					onMounted(() => {
 | 
				
			||||||
 | 
					    actualizeRoles();
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Events.on("modal:open", () => {
 | 
				
			||||||
 | 
					    actualizeRoles();
 | 
				
			||||||
 | 
					    modalOpen.value = true;
 | 
				
			||||||
 | 
					    roleUpdated.value = false;
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Events.on("modal:close", () => {
 | 
				
			||||||
 | 
					    modalOpen.value = false;
 | 
				
			||||||
 | 
					    roleSelected.value = null;
 | 
				
			||||||
 | 
					    roleUpdated.value = false;
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function actualizeRoles() {
 | 
				
			||||||
 | 
					    IORequest("/OWNER/ROLES/GET", (data) => {
 | 
				
			||||||
 | 
					         roles.value = data;
 | 
				
			||||||
 | 
					        roleSelected.value = null;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function updateRole() {
 | 
				
			||||||
 | 
					    console.log(roleSelector.value?.firstSlot());   
 | 
				
			||||||
 | 
					    IORequest("/OWNER/ROLES/SET", (data) => {
 | 
				
			||||||
 | 
					        actualizeRoles();
 | 
				
			||||||
 | 
					        roleUpdated.value = true;
 | 
				
			||||||
 | 
					        setTimeout(() => {
 | 
				
			||||||
 | 
					            roleUpdated.value = false;
 | 
				
			||||||
 | 
					        }, 3000);
 | 
				
			||||||
 | 
					    }, roles.value.find(r => r.id === roleSelected.value) || null);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function decimalToHex(decimal) {
 | 
				
			||||||
 | 
					    if(decimal == 0) return "var(--quaternary)"; // Default color
 | 
				
			||||||
 | 
					    let hex = Number(decimal).toString(16);
 | 
				
			||||||
 | 
					    hex = "000000".substring(0, 6 - hex.length) + hex;
 | 
				
			||||||
 | 
					    return `#${hex}`;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					<style scoped>
 | 
				
			||||||
 | 
					.text-secondary {
 | 
				
			||||||
 | 
					    color: var(--text-secondary);
 | 
				
			||||||
 | 
					    font-size: 0.875rem;
 | 
				
			||||||
 | 
					    margin-bottom: 0.5rem;
 | 
				
			||||||
 | 
					    text-decoration: underline;
 | 
				
			||||||
 | 
					    margin: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.setting {
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    flex-direction: column;
 | 
				
			||||||
 | 
					    gap: 0.5rem;
 | 
				
			||||||
 | 
					    margin-top: 0.5rem;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
@@ -41,7 +41,7 @@
 | 
				
			|||||||
                <p class="selectorp" :value="playlist.playlistId" v-for="playlist in userStore.playlists" :key="playlist.playlistId"><Icon :icon="playlist.type === 'youtube' ? 'fa-brands fa-youtube' : 'fa-solid fa-music'" /> {{ playlist.title }}</p>
 | 
					                <p class="selectorp" :value="playlist.playlistId" v-for="playlist in userStore.playlists" :key="playlist.playlistId"><Icon :icon="playlist.type === 'youtube' ? 'fa-brands fa-youtube' : 'fa-solid fa-music'" /> {{ playlist.title }}</p>
 | 
				
			||||||
            </Selector>
 | 
					            </Selector>
 | 
				
			||||||
            <p v-else class="info-no">Vous n'avez pas encore de playlist. Créez-en une pour sauvegarder ce titre.</p>
 | 
					            <p v-else class="info-no">Vous n'avez pas encore de playlist. Créez-en une pour sauvegarder ce titre.</p>
 | 
				
			||||||
            <Button :disabled="userStore.playlists?.length === 0" @click="Events.emit('video:add', { video: nextList[selectedIndex], playlistId: playlistSelector.firstSlot().props.value }); saveModal.close()"><Icon icon="fa-solid fa-save" /> Sauvegarder</Button>
 | 
					            <Button :disabled="userStore.playlists?.length === 0" @click="Events.emit('video:add', { video: nextList[selectedIndex], playlistId: playlistSelector.firstSlot().props.value }); saveModal.close()" icon="fa-solid fa-save">Sauvegarder</Button>
 | 
				
			||||||
        </Modal>
 | 
					        </Modal>
 | 
				
			||||||
    </section>
 | 
					    </section>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,7 @@
 | 
				
			|||||||
                <p class="selectorp" :value="playlist.playlistId" v-for="playlist in userStore.playlists" :key="playlist.playlistId"><Icon :icon="playlist.type === 'youtube' ? 'fa-brands fa-youtube' : 'fa-solid fa-music'" /> {{ playlist.title }}</p>
 | 
					                <p class="selectorp" :value="playlist.playlistId" v-for="playlist in userStore.playlists" :key="playlist.playlistId"><Icon :icon="playlist.type === 'youtube' ? 'fa-brands fa-youtube' : 'fa-solid fa-music'" /> {{ playlist.title }}</p>
 | 
				
			||||||
            </Selector>
 | 
					            </Selector>
 | 
				
			||||||
            <p v-else class="info-no">Vous n'avez pas encore de playlist. Créez-en une pour sauvegarder ce titre.</p>
 | 
					            <p v-else class="info-no">Vous n'avez pas encore de playlist. Créez-en une pour sauvegarder ce titre.</p>
 | 
				
			||||||
            <Button :disabled="userStore.playlists?.length === 0" @click="Events.emit('video:add', { video: previousList[selectedIndex], playlistId: playlistSelector.firstSlot().props.value }); saveModal.close()"><Icon icon="fa-solid fa-save" /> Sauvegarder</Button>
 | 
					            <Button :disabled="userStore.playlists?.length === 0" @click="Events.emit('video:add', { video: previousList[selectedIndex], playlistId: playlistSelector.firstSlot().props.value }); saveModal.close()" icon="fa-solid fa-save">Sauvegarder</Button>
 | 
				
			||||||
        </Modal>
 | 
					        </Modal>
 | 
				
			||||||
    </section>
 | 
					    </section>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,8 @@
 | 
				
			|||||||
            <ServerOnlinePicture class="sop" :key="server.id" v-if="server.members.length > 0" :members="server.members"/>
 | 
					            <ServerOnlinePicture class="sop" :key="server.id" v-if="server.members.length > 0" :members="server.members"/>
 | 
				
			||||||
            <section>
 | 
					            <section>
 | 
				
			||||||
            <Error v-if="userStore.userInfo.labels.includes('BAN_' + server.id)">Banni</Error>
 | 
					            <Error v-if="userStore.userInfo.labels.includes('BAN_' + server.id)">Banni</Error>
 | 
				
			||||||
            <Button color-lower :disabled="userStore.userInfo.labels.includes('BAN_' + server.id)" class="btn" @click="access()"><Icon icon="fa-solid fa-right-to-bracket"/>Accéder</Button>
 | 
					            <Error v-else-if="server.restricted">Restreint</Error>
 | 
				
			||||||
 | 
					            <Button color-lower :disabled="userStore.userInfo.labels.includes('BAN_' + server.id) || server.restricted" class="btn" @click="access()"  icon="fa-solid fa-right-to-bracket">Accéder</Button>
 | 
				
			||||||
            </section>
 | 
					            </section>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
    </Box>
 | 
					    </Box>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -54,7 +54,7 @@ watch(showForm, (newValue) => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
    <p>Si vous rencontrez un problème, vous pouvez le signaler via ce formulaire. Vous pouvez être contacté en cas de besoin par Raphix pour plus d'informations.</p>
 | 
					    <p>Si vous rencontrez un problème, vous pouvez le signaler via ce formulaire. Vous pouvez être contacté en cas de besoin par Raphix pour plus d'informations.</p>
 | 
				
			||||||
    <Button v-if="!showForm" @click="showForm = !showForm" class="margin"><Icon icon="fa-solid fa-paper-plane" /> Faire un rapport de bug</Button>
 | 
					    <Button v-if="!showForm" @click="showForm = !showForm" class="margin" icon="fa-solid fa-paper-plane"> Faire un rapport de bug</Button>
 | 
				
			||||||
    <Success class="margin" v-if="sended">Votre rapport a été envoyé avec succès</Success>
 | 
					    <Success class="margin" v-if="sended">Votre rapport a été envoyé avec succès</Success>
 | 
				
			||||||
    <div v-if="showForm" class="report-content">
 | 
					    <div v-if="showForm" class="report-content">
 | 
				
			||||||
            <p>Catégorie</p>
 | 
					            <p>Catégorie</p>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
    <p class="privacy">Toutes les données récupérées sont à des fins <strong>strictement</strong> nécessaires au bon fonctionnement de l'application.</p>
 | 
					    <p class="privacy">Toutes les données récupérées sont à des fins <strong>strictement</strong> nécessaires au bon fonctionnement de l'application.</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <Button @click="openModal()"><Icon icon="fa-solid fa-trash"/> Supprimer mon compte</Button>
 | 
					    <Button @click="openModal()" icon="fa-solid fa-trash"> Supprimer mon compte</Button>
 | 
				
			||||||
    <Modal icon="fa-solid fa-trash" ref="deleteAccountModal" title="Supprimer mon compte">
 | 
					    <Modal icon="fa-solid fa-trash" ref="deleteAccountModal" title="Supprimer mon compte">
 | 
				
			||||||
        <p class="warning">
 | 
					        <p class="warning">
 | 
				
			||||||
            Êtes-vous sûr de vouloir supprimer votre compte ? <br/> 
 | 
					            Êtes-vous sûr de vouloir supprimer votre compte ? <br/> 
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,13 +10,13 @@
 | 
				
			|||||||
<Modal icon="fa-solid fa-video" title="Actions" ref="modal">
 | 
					<Modal icon="fa-solid fa-video" title="Actions" ref="modal">
 | 
				
			||||||
    <Video :video="video"/>
 | 
					    <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(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>
 | 
					    <Button icon="fa-solid fa-play" v-if="globalStore.currentChannel" @click="playSong(true)"> Lire maintenant</Button>
 | 
				
			||||||
    <div v-if="!globalStore.currentChannel" >
 | 
					    <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>
 | 
					        <p class="text-secondary">Connectez vous à un salon audio sur le serveur {{ globalStore.actualServer ? globalStore.actualServer.name : '' }}, pour lancer un titre</p>
 | 
				
			||||||
        <ActualChannel/>
 | 
					        <ActualChannel/>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <Button v-if="!props.delete && video.type != 'attachment'" @click="saveModal.open()"><Icon icon="fa-solid fa-save" /> Enregistrer dans une playlist</Button>
 | 
					    <Button v-if="!props.delete && video.type != 'attachment'" @click="saveModal.open()" icon="fa-solid fa-save"> Enregistrer dans une playlist</Button>
 | 
				
			||||||
    <Button v-if="props.delete" @click="Events.emit('video:delete', { video: props.video })"><Icon icon="fa-solid fa-trash" /> Supprimer</Button>
 | 
					    <Button v-if="props.delete" @click="Events.emit('video:delete', { video: props.video })" icon="fa-solid fa-trash"> Supprimer</Button>
 | 
				
			||||||
</Modal>
 | 
					</Modal>
 | 
				
			||||||
<Modal ref="saveModal" icon="fa-save" title="Sauvegarder dans une playlist">
 | 
					<Modal ref="saveModal" icon="fa-save" title="Sauvegarder dans une playlist">
 | 
				
			||||||
    <Video class="save-video" :video="video"/>
 | 
					    <Video class="save-video" :video="video"/>
 | 
				
			||||||
@@ -24,7 +24,7 @@
 | 
				
			|||||||
        <p class="selectorp" :value="playlist.playlistId" v-for="playlist in userStore.playlists" :key="playlist.playlistId"><Icon :icon="playlist.type === 'youtube' ? 'fa-brands fa-youtube' : 'fa-solid fa-music'" /> {{ playlist.title }}</p>
 | 
					        <p class="selectorp" :value="playlist.playlistId" v-for="playlist in userStore.playlists" :key="playlist.playlistId"><Icon :icon="playlist.type === 'youtube' ? 'fa-brands fa-youtube' : 'fa-solid fa-music'" /> {{ playlist.title }}</p>
 | 
				
			||||||
    </Selector>
 | 
					    </Selector>
 | 
				
			||||||
    <p v-else class="info-no">Vous n'avez pas encore de playlist. Créez-en une pour sauvegarder ce titre.</p>
 | 
					    <p v-else class="info-no">Vous n'avez pas encore de playlist. Créez-en une pour sauvegarder ce titre.</p>
 | 
				
			||||||
    <Button :disabled="userStore.playlists?.length === 0" @click="Events.emit('video:add', { video: props.video, playlistId: playlistSelector.firstSlot().props.value }); saveModal.close()"><Icon icon="fa-solid fa-save" /> Sauvegarder</Button>
 | 
					    <Button :disabled="userStore.playlists?.length === 0" @click="Events.emit('video:add', { video: props.video, playlistId: playlistSelector.firstSlot().props.value }); saveModal.close()" icon="fa-solid fa-save" > Sauvegarder</Button>
 | 
				
			||||||
</Modal>
 | 
					</Modal>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
<script setup>
 | 
					<script setup>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@
 | 
				
			|||||||
                <img v-if="results.thumbnail" class="search-playlist-thumbnail" :src="results.thumbnail" alt="Playlist Thumbnail" />
 | 
					                <img v-if="results.thumbnail" class="search-playlist-thumbnail" :src="results.thumbnail" alt="Playlist Thumbnail" />
 | 
				
			||||||
                <div v-else class="search-playlist-thumbnail"><div class="defaultIcon"><Icon icon="fa-music" /></div></div>
 | 
					                <div v-else class="search-playlist-thumbnail"><div class="defaultIcon"><Icon icon="fa-music" /></div></div>
 | 
				
			||||||
                <div class="search-playlist-info">
 | 
					                <div class="search-playlist-info">
 | 
				
			||||||
                    <p class="search-playlist-title">{{ results.title }} <Icon @click="openPlaylistPage()" class="link-icon" icon="fa-solid fa-link" /></p>
 | 
					                    <p class="search-playlist-title">{{ results.title }} <Icon v-if="results.url" @click="openPlaylistPage()" class="link-icon" icon="fa-solid fa-link" /></p>
 | 
				
			||||||
                    <p class="search-playlist-stats"><Tag color="var(--text-warning)">{{ results.songs.length }} titres</Tag><Tag v-if="results.views" color="var(--text-success)">{{ results.views }} vues</Tag ><Tag v-if="results.songs.length > 0">Durée : {{ results.readduration }}</Tag></p>
 | 
					                    <p class="search-playlist-stats"><Tag color="var(--text-warning)">{{ results.songs.length }} titres</Tag><Tag v-if="results.views" color="var(--text-success)">{{ results.views }} vues</Tag ><Tag v-if="results.songs.length > 0">Durée : {{ results.readduration }}</Tag></p>
 | 
				
			||||||
                    <div @click="openAuthorPage()" class="search-playlist-author-info">
 | 
					                    <div @click="openAuthorPage()" class="search-playlist-author-info">
 | 
				
			||||||
                        <img v-if="results.authorAvatar" :src="results.authorAvatar" alt="Author Thumbnail" class="search-playlist-author" />
 | 
					                        <img v-if="results.authorAvatar" :src="results.authorAvatar" alt="Author Thumbnail" class="search-playlist-author" />
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										116
									
								
								src/components/Widget/View/Search/SearchSuggestions.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								src/components/Widget/View/Search/SearchSuggestions.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,116 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					    <div ref="suggestions" class="search-suggestions">
 | 
				
			||||||
 | 
					        <ul>
 | 
				
			||||||
 | 
					            <li class="search-suggestion" v-for="result in results" :key="result.id" @click="selectResult(result[0])">
 | 
				
			||||||
 | 
					                {{ result[0] }}
 | 
				
			||||||
 | 
					                <Icon class="search-icon" icon="fa-solid fa-arrow-up-right-from-square" style="float: right;"/>
 | 
				
			||||||
 | 
					            </li>
 | 
				
			||||||
 | 
					        </ul>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script setup>
 | 
				
			||||||
 | 
					import { onMounted, ref, watch } from 'vue';
 | 
				
			||||||
 | 
					import Events from '@/utils/Events';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const props = defineProps({
 | 
				
			||||||
 | 
					    query: String
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const results = ref([]);
 | 
				
			||||||
 | 
					const suggestions = ref(null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					onMounted(() => {
 | 
				
			||||||
 | 
					    window.addEventListener('click', (event) => {
 | 
				
			||||||
 | 
					        if (suggestions.value && !suggestions.value.contains(event.target)) {
 | 
				
			||||||
 | 
					            results.value = [];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    window.addEventListener('keydown', (event) => {
 | 
				
			||||||
 | 
					        if (event.key === 'Escape') {
 | 
				
			||||||
 | 
					            results.value = [];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (event.key === 'Enter') {
 | 
				
			||||||
 | 
					            results.value = [];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					watch(() => props.query, (newQuery) => {
 | 
				
			||||||
 | 
					    if (newQuery) {
 | 
				
			||||||
 | 
					        fetchSuggest(newQuery)
 | 
				
			||||||
 | 
					            .then(data => {
 | 
				
			||||||
 | 
					                results.value = data[1];
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        results.value = [];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function fetchSuggest(query) {
 | 
				
			||||||
 | 
					  return new Promise((resolve, reject) => {
 | 
				
			||||||
 | 
					    const callbackName = "jsonp_callback_" + Math.random().toString(36).substr(2, 5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    window[callbackName] = function(data) {
 | 
				
			||||||
 | 
					      resolve(data);
 | 
				
			||||||
 | 
					      delete window[callbackName];
 | 
				
			||||||
 | 
					      script.remove();
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const script = document.createElement("script");
 | 
				
			||||||
 | 
					    script.src = `https://suggestqueries.google.com/complete/search?client=youtube&ds=yt&q=${encodeURIComponent(query)}&callback=${callbackName}`;
 | 
				
			||||||
 | 
					    script.onerror = reject;
 | 
				
			||||||
 | 
					    document.body.appendChild(script);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function selectResult(result) {
 | 
				
			||||||
 | 
					    Events.emit("SEARCH_RESULT_SELECTED", result);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Events.on("SEARCH_RESULT_SENDED", () => {
 | 
				
			||||||
 | 
					    results.value = [];
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style scoped>
 | 
				
			||||||
 | 
					.search-suggestions {
 | 
				
			||||||
 | 
					    position: absolute;
 | 
				
			||||||
 | 
					    background: var(--secondary);
 | 
				
			||||||
 | 
					    opacity: 0.95;
 | 
				
			||||||
 | 
					    z-index: 1000;
 | 
				
			||||||
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					    top: 40px;
 | 
				
			||||||
 | 
					    max-height: 30vh;
 | 
				
			||||||
 | 
					    overflow-y: auto;
 | 
				
			||||||
 | 
					    border-radius: 10px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.search-suggestions ul {
 | 
				
			||||||
 | 
					    list-style: none;
 | 
				
			||||||
 | 
					    padding: 0;
 | 
				
			||||||
 | 
					    margin: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.search-suggestions li {
 | 
				
			||||||
 | 
					    padding: 10px;
 | 
				
			||||||
 | 
					    cursor: pointer;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.search-icon {
 | 
				
			||||||
 | 
					    display: none;
 | 
				
			||||||
 | 
					    opacity: 0.5;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.search-suggestion:hover .search-icon {
 | 
				
			||||||
 | 
					    display: block !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.search-suggestions li:hover {
 | 
				
			||||||
 | 
					    background: var(--tertiary);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
@@ -4,7 +4,7 @@
 | 
				
			|||||||
            <h2><Icon icon="fa-folder"/> Mes fichiers</h2>
 | 
					            <h2><Icon icon="fa-folder"/> Mes fichiers</h2>
 | 
				
			||||||
            <Box box-class="area-container" padding="close" level="second">
 | 
					            <Box box-class="area-container" padding="close" level="second">
 | 
				
			||||||
                <div class="upload-area">
 | 
					                <div class="upload-area">
 | 
				
			||||||
                    <Button :color-lower="status === 'download'" :disabled="status === 'download'" class="upload-button" @click="uploadFile()"><Icon icon="fa-upload"/> Ajouter des fichiers</Button>
 | 
					                    <Button :color-lower="status === 'download'" :disabled="status === 'download'" class="upload-button" @click="uploadFile()" 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-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 === '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>
 | 
					                    <p v-else-if="status === 'toohigh'" class="upload-status" ref="uploadStatus"><Error>Le fichier est trop volumineux</Error></p>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,11 @@
 | 
				
			|||||||
<script setup>
 | 
					<script setup>
 | 
				
			||||||
import DefaultSplash from '@/components/UI/DefaultSplash.vue';
 | 
					import DefaultSplash from '@/components/UI/DefaultSplash.vue';
 | 
				
			||||||
import MusicAnimation from '@/components/UI/MusicAnimation.vue';
 | 
					import MusicAnimation from '@/components/UI/MusicAnimation.vue';
 | 
				
			||||||
 | 
					import { version } from '@/../package.json';
 | 
				
			||||||
const defaultMessage = "On s'accorde et on prépare le concert !";
 | 
					const defaultMessage = "On s'accorde et on prépare le concert !";
 | 
				
			||||||
const connectMsg = "Erreur de connexion au serveur : xhr poll error"
 | 
					const connectMsg = "Erreur de connexion au serveur : xhr poll error"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const props = defineProps({
 | 
					const props = defineProps({
 | 
				
			||||||
    interuptionMessage: {
 | 
					    interuptionMessage: {
 | 
				
			||||||
        type: String,
 | 
					        type: String,
 | 
				
			||||||
@@ -26,6 +27,7 @@ const props = defineProps({
 | 
				
			|||||||
            <p v-if="interuptionMessage" class="error"><Icon icon="fa-solid fa-circle-xmark"/> {{ interuptionMessage }}</p>
 | 
					            <p v-if="interuptionMessage" class="error"><Icon icon="fa-solid fa-circle-xmark"/> {{ interuptionMessage }}</p>
 | 
				
			||||||
            <p v-else>{{ defaultMessage }}</p>
 | 
					            <p v-else>{{ defaultMessage }}</p>
 | 
				
			||||||
            <MusicAnimation />
 | 
					            <MusicAnimation />
 | 
				
			||||||
 | 
					             <p class="version">Version : {{ version }} - Chopin</p>
 | 
				
			||||||
    </DefaultSplash>
 | 
					    </DefaultSplash>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
<style scoped>
 | 
					<style scoped>
 | 
				
			||||||
@@ -63,6 +65,12 @@ const props = defineProps({
 | 
				
			|||||||
    color: var(--text-secondary);
 | 
					    color: var(--text-secondary);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.version {
 | 
				
			||||||
 | 
					    font-size: 0.6em;
 | 
				
			||||||
 | 
					    margin-bottom: 0;
 | 
				
			||||||
 | 
					    color: var(--text-secondary);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 @media screen and (max-width: 768px),
 | 
					 @media screen and (max-width: 768px),
 | 
				
			||||||
            screen and (max-height: 607px) {
 | 
					            screen and (max-height: 607px) {
 | 
				
			||||||
        h1 {
 | 
					        h1 {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,7 @@
 | 
				
			|||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <br>
 | 
					        <br>
 | 
				
			||||||
        <router-link class="no-decoration" to="/">
 | 
					        <router-link class="no-decoration" to="/">
 | 
				
			||||||
            <Button><Icon icon="fa-solid fa-house"/> Revenir au concert</Button>
 | 
					            <Button icon="fa-solid fa-house"> Revenir au concert</Button>
 | 
				
			||||||
        </router-link>
 | 
					        </router-link>
 | 
				
			||||||
    </DefaultSplash>
 | 
					    </DefaultSplash>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -103,7 +103,7 @@ onMounted(() => {
 | 
				
			|||||||
        </Box>
 | 
					        </Box>
 | 
				
			||||||
        <br/>
 | 
					        <br/>
 | 
				
			||||||
        <router-link class="no-decoration" to="/">
 | 
					        <router-link class="no-decoration" to="/">
 | 
				
			||||||
            <Button><Icon icon="fa-solid fa-house"/> Revenir au concert</Button>
 | 
					            <Button icon="fa-solid fa-house"> Revenir au concert</Button>
 | 
				
			||||||
        </router-link>
 | 
					        </router-link>
 | 
				
			||||||
        <!-- Add more content here as needed -->
 | 
					        <!-- Add more content here as needed -->
 | 
				
			||||||
    </DefaultSplash>
 | 
					    </DefaultSplash>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -61,7 +61,7 @@ function inviteSubsonics() {
 | 
				
			|||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                    <Button :disabled="!hasLink" @click="inviteSubsonics()"><Icon icon="fa-solid fa-user-plus"/>Inviter Subsonics</Button>
 | 
					                    <Button :disabled="!hasLink" @click="inviteSubsonics()"  icon="fa-solid fa-user-plus">Inviter Subsonics</Button>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </Box>
 | 
					            </Box>
 | 
				
			||||||
            <Account class="full"/>
 | 
					            <Account class="full"/>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,7 +31,7 @@ onMounted(() => {
 | 
				
			|||||||
        </Box>
 | 
					        </Box>
 | 
				
			||||||
        <br>
 | 
					        <br>
 | 
				
			||||||
        <router-link class="no-decoration" to="/">
 | 
					        <router-link class="no-decoration" to="/">
 | 
				
			||||||
            <Button><Icon icon="fa-solid fa-house"/> Revenir au concert</Button>
 | 
					            <Button icon="fa-solid fa-house">Revenir au concert</Button>
 | 
				
			||||||
        </router-link>
 | 
					        </router-link>
 | 
				
			||||||
        <!-- Add more content here as needed -->
 | 
					        <!-- Add more content here as needed -->
 | 
				
			||||||
    </DefaultSplash>
 | 
					    </DefaultSplash>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user