opus-submitter/polylan_submitter/src/stores/noita.ts

185 lines
4.7 KiB
TypeScript

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,
}
})