init
This commit is contained in:
55
frontend/src/stores/auth.js
Normal file
55
frontend/src/stores/auth.js
Normal file
@@ -0,0 +1,55 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref, computed } from 'vue'
|
||||
import api from '../composables/useApi'
|
||||
|
||||
export const useAuthStore = defineStore('auth', () => {
|
||||
const token = ref(localStorage.getItem('token') || null)
|
||||
const user = ref(null)
|
||||
|
||||
const isAuthenticated = computed(() => !!token.value)
|
||||
|
||||
async function login(email, password) {
|
||||
const response = await api.post('/api/auth/login', { email, password })
|
||||
token.value = response.data.access_token
|
||||
localStorage.setItem('token', token.value)
|
||||
await fetchUser()
|
||||
}
|
||||
|
||||
async function register(username, email, password) {
|
||||
const response = await api.post('/api/auth/register', { username, email, password })
|
||||
token.value = response.data.access_token
|
||||
localStorage.setItem('token', token.value)
|
||||
await fetchUser()
|
||||
}
|
||||
|
||||
async function fetchUser() {
|
||||
if (!token.value) return
|
||||
try {
|
||||
const response = await api.get('/api/auth/me')
|
||||
user.value = response.data
|
||||
} catch (error) {
|
||||
logout()
|
||||
}
|
||||
}
|
||||
|
||||
function logout() {
|
||||
token.value = null
|
||||
user.value = null
|
||||
localStorage.removeItem('token')
|
||||
}
|
||||
|
||||
// Initialize
|
||||
if (token.value) {
|
||||
fetchUser()
|
||||
}
|
||||
|
||||
return {
|
||||
token,
|
||||
user,
|
||||
isAuthenticated,
|
||||
login,
|
||||
register,
|
||||
fetchUser,
|
||||
logout,
|
||||
}
|
||||
})
|
||||
71
frontend/src/stores/player.js
Normal file
71
frontend/src/stores/player.js
Normal file
@@ -0,0 +1,71 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
|
||||
export const usePlayerStore = defineStore('player', () => {
|
||||
const isPlaying = ref(false)
|
||||
const currentTrack = ref(null)
|
||||
const currentTrackUrl = ref(null)
|
||||
const position = ref(0)
|
||||
const duration = ref(0)
|
||||
const volume = ref(100)
|
||||
|
||||
function setPlayerState(state) {
|
||||
isPlaying.value = state.is_playing
|
||||
position.value = state.position
|
||||
if (state.current_track_id) {
|
||||
currentTrack.value = { id: state.current_track_id }
|
||||
}
|
||||
if (state.track_url) {
|
||||
currentTrackUrl.value = state.track_url
|
||||
}
|
||||
}
|
||||
|
||||
function setTrack(track, url) {
|
||||
currentTrack.value = track
|
||||
currentTrackUrl.value = url
|
||||
position.value = 0
|
||||
}
|
||||
|
||||
function setPosition(pos) {
|
||||
position.value = pos
|
||||
}
|
||||
|
||||
function setDuration(dur) {
|
||||
duration.value = dur
|
||||
}
|
||||
|
||||
function setVolume(vol) {
|
||||
volume.value = vol
|
||||
localStorage.setItem('volume', vol)
|
||||
}
|
||||
|
||||
function play() {
|
||||
isPlaying.value = true
|
||||
}
|
||||
|
||||
function pause() {
|
||||
isPlaying.value = false
|
||||
}
|
||||
|
||||
// Load saved volume
|
||||
const savedVolume = localStorage.getItem('volume')
|
||||
if (savedVolume) {
|
||||
volume.value = parseInt(savedVolume)
|
||||
}
|
||||
|
||||
return {
|
||||
isPlaying,
|
||||
currentTrack,
|
||||
currentTrackUrl,
|
||||
position,
|
||||
duration,
|
||||
volume,
|
||||
setPlayerState,
|
||||
setTrack,
|
||||
setPosition,
|
||||
setDuration,
|
||||
setVolume,
|
||||
play,
|
||||
pause,
|
||||
}
|
||||
})
|
||||
85
frontend/src/stores/room.js
Normal file
85
frontend/src/stores/room.js
Normal file
@@ -0,0 +1,85 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
import api from '../composables/useApi'
|
||||
|
||||
export const useRoomStore = defineStore('room', () => {
|
||||
const rooms = ref([])
|
||||
const currentRoom = ref(null)
|
||||
const participants = ref([])
|
||||
const queue = ref([])
|
||||
|
||||
async function fetchRooms() {
|
||||
const response = await api.get('/api/rooms')
|
||||
rooms.value = response.data
|
||||
}
|
||||
|
||||
async function fetchRoom(roomId) {
|
||||
const response = await api.get(`/api/rooms/${roomId}`)
|
||||
currentRoom.value = response.data
|
||||
participants.value = response.data.participants
|
||||
}
|
||||
|
||||
async function createRoom(name) {
|
||||
const response = await api.post('/api/rooms', { name })
|
||||
return response.data
|
||||
}
|
||||
|
||||
async function deleteRoom(roomId) {
|
||||
await api.delete(`/api/rooms/${roomId}`)
|
||||
rooms.value = rooms.value.filter(r => r.id !== roomId)
|
||||
}
|
||||
|
||||
async function joinRoom(roomId) {
|
||||
await api.post(`/api/rooms/${roomId}/join`)
|
||||
}
|
||||
|
||||
async function leaveRoom(roomId) {
|
||||
await api.post(`/api/rooms/${roomId}/leave`)
|
||||
}
|
||||
|
||||
async function fetchQueue(roomId) {
|
||||
const response = await api.get(`/api/rooms/${roomId}/queue`)
|
||||
queue.value = response.data
|
||||
}
|
||||
|
||||
async function addToQueue(roomId, trackId) {
|
||||
await api.post(`/api/rooms/${roomId}/queue`, { track_id: trackId })
|
||||
}
|
||||
|
||||
async function removeFromQueue(roomId, trackId) {
|
||||
await api.delete(`/api/rooms/${roomId}/queue/${trackId}`)
|
||||
}
|
||||
|
||||
function updateParticipants(newParticipants) {
|
||||
participants.value = newParticipants
|
||||
}
|
||||
|
||||
function addParticipant(user) {
|
||||
if (!participants.value.find(p => p.id === user.id)) {
|
||||
participants.value.push(user)
|
||||
}
|
||||
}
|
||||
|
||||
function removeParticipant(userId) {
|
||||
participants.value = participants.value.filter(p => p.id !== userId)
|
||||
}
|
||||
|
||||
return {
|
||||
rooms,
|
||||
currentRoom,
|
||||
participants,
|
||||
queue,
|
||||
fetchRooms,
|
||||
fetchRoom,
|
||||
createRoom,
|
||||
deleteRoom,
|
||||
joinRoom,
|
||||
leaveRoom,
|
||||
fetchQueue,
|
||||
addToQueue,
|
||||
removeFromQueue,
|
||||
updateParticipants,
|
||||
addParticipant,
|
||||
removeParticipant,
|
||||
}
|
||||
})
|
||||
50
frontend/src/stores/tracks.js
Normal file
50
frontend/src/stores/tracks.js
Normal file
@@ -0,0 +1,50 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
import api from '../composables/useApi'
|
||||
|
||||
export const useTracksStore = defineStore('tracks', () => {
|
||||
const tracks = ref([])
|
||||
const loading = ref(false)
|
||||
|
||||
async function fetchTracks() {
|
||||
loading.value = true
|
||||
try {
|
||||
const response = await api.get('/api/tracks')
|
||||
tracks.value = response.data
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function uploadTrack(file, title, artist) {
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
formData.append('title', title)
|
||||
formData.append('artist', artist)
|
||||
|
||||
const response = await api.post('/api/tracks/upload', formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
})
|
||||
tracks.value.unshift(response.data)
|
||||
return response.data
|
||||
}
|
||||
|
||||
async function deleteTrack(trackId) {
|
||||
await api.delete(`/api/tracks/${trackId}`)
|
||||
tracks.value = tracks.value.filter(t => t.id !== trackId)
|
||||
}
|
||||
|
||||
async function getTrackUrl(trackId) {
|
||||
const response = await api.get(`/api/tracks/${trackId}`)
|
||||
return response.data.url
|
||||
}
|
||||
|
||||
return {
|
||||
tracks,
|
||||
loading,
|
||||
fetchTracks,
|
||||
uploadTrack,
|
||||
deleteTrack,
|
||||
getTrackUrl,
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user