feat(noita): stores
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
|
||||
export interface Objective {
|
||||
objectiv_id: string
|
||||
display_string: string
|
||||
first_seen_at: string | null
|
||||
count: number
|
||||
max_count: number
|
||||
seed: string | null
|
||||
points_per_objectiv: number
|
||||
total_points: number
|
||||
}
|
||||
|
||||
interface UserInfo {
|
||||
username: string
|
||||
rank: number | null
|
||||
score: number
|
||||
runsSubmitted: number
|
||||
deathsCount: number
|
||||
isStaff: boolean
|
||||
}
|
||||
|
||||
interface LeaderboardEntry {
|
||||
rank: number
|
||||
username: string
|
||||
total_score: number
|
||||
objectives_count: number
|
||||
deaths_count: number
|
||||
is_staff: boolean
|
||||
}
|
||||
|
||||
export const useNoitaStore = defineStore('noita', () => {
|
||||
// State
|
||||
const userInfo = ref<UserInfo>({
|
||||
username: 'Player',
|
||||
rank: null,
|
||||
score: 0,
|
||||
runsSubmitted: 0,
|
||||
deathsCount: 0,
|
||||
isStaff: false,
|
||||
})
|
||||
const objectives = ref<Objective[]>([])
|
||||
const leaderboard = ref<LeaderboardEntry[]>([])
|
||||
const isLoadingLeaderboard = ref(false)
|
||||
const isUploading = ref(false)
|
||||
const error = ref<string>('')
|
||||
|
||||
// Actions
|
||||
const fetchUserResults = async () => {
|
||||
try {
|
||||
const response = await fetch('/api/noita/results')
|
||||
if (!response.ok) throw new Error('Failed to fetch results')
|
||||
|
||||
const results = await response.json()
|
||||
userInfo.value.score = results.total_score
|
||||
userInfo.value.deathsCount = results.deaths_count
|
||||
userInfo.value.runsSubmitted = results.objectives.length
|
||||
objectives.value = results.objectives
|
||||
} catch (err) {
|
||||
error.value = 'Failed to fetch user results'
|
||||
console.error('Error fetching results:', err)
|
||||
}
|
||||
}
|
||||
|
||||
const fetchLeaderboard = async () => {
|
||||
isLoadingLeaderboard.value = true
|
||||
try {
|
||||
const response = await fetch('/api/noita/leaderboard')
|
||||
if (!response.ok) throw new Error('Failed to fetch leaderboard')
|
||||
|
||||
const data = await response.json()
|
||||
leaderboard.value = data.leaderboard
|
||||
|
||||
// Find current user's rank
|
||||
const userRank = leaderboard.value.find(
|
||||
(entry) => entry.username === userInfo.value.username
|
||||
)
|
||||
|
||||
if (userRank) {
|
||||
userInfo.value.rank = userRank.rank
|
||||
userInfo.value.score = userRank.total_score
|
||||
userInfo.value.deathsCount = userRank.deaths_count
|
||||
}
|
||||
} catch (err) {
|
||||
error.value = 'Failed to fetch leaderboard'
|
||||
console.error('Error fetching leaderboard:', err)
|
||||
} finally {
|
||||
isLoadingLeaderboard.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const loadUserData = async () => {
|
||||
try {
|
||||
const response = await fetch('/api/user')
|
||||
if (response.ok) {
|
||||
const user = await response.json()
|
||||
if (user.is_authenticated) {
|
||||
userInfo.value.username = user.username
|
||||
userInfo.value.isStaff = user.is_staff || false
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error fetching user info:', err)
|
||||
}
|
||||
|
||||
await Promise.all([fetchUserResults(), fetchLeaderboard()])
|
||||
}
|
||||
|
||||
const submitRun = async (files: File[]) => {
|
||||
if (files.length === 0) return
|
||||
|
||||
isUploading.value = true
|
||||
try {
|
||||
for (const file of files) {
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
|
||||
const response = await fetch('/api/noita/submit', {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json()
|
||||
throw new Error(errorData.detail || 'Unknown error')
|
||||
}
|
||||
|
||||
const result = await response.json()
|
||||
console.log('Submission successful:', result)
|
||||
}
|
||||
|
||||
// Refresh objectives, score, and rank after successful submission
|
||||
await Promise.all([fetchUserResults(), fetchLeaderboard()])
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : 'Unknown error'
|
||||
error.value = `Error submitting run: ${errorMessage}`
|
||||
throw err
|
||||
} finally {
|
||||
isUploading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const clearCache = async () => {
|
||||
try {
|
||||
const response = await fetch('/api/cache/clear', {
|
||||
method: 'POST',
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json()
|
||||
throw new Error(errorData.detail || 'Unknown error')
|
||||
}
|
||||
|
||||
await Promise.all([fetchUserResults(), fetchLeaderboard()])
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : 'Unknown error'
|
||||
error.value = `Error clearing cache: ${errorMessage}`
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
const refreshData = async () => {
|
||||
await Promise.all([fetchUserResults(), fetchLeaderboard()])
|
||||
}
|
||||
|
||||
return {
|
||||
// State
|
||||
userInfo,
|
||||
objectives,
|
||||
leaderboard,
|
||||
isLoadingLeaderboard,
|
||||
isUploading,
|
||||
error,
|
||||
|
||||
// Actions
|
||||
fetchUserResults,
|
||||
fetchLeaderboard,
|
||||
loadUserData,
|
||||
submitRun,
|
||||
clearCache,
|
||||
refreshData,
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user