mirror of
https://github.com/sky-systems/sky_phone.git
synced 2026-08-29 01:08:59 +00:00
176 lines
5.6 KiB
TypeScript
176 lines
5.6 KiB
TypeScript
import { defineStore } from 'pinia'
|
|
|
|
import type {
|
|
FlareBootstrap,
|
|
FlareMatch,
|
|
FlareMessage,
|
|
FlareOutgoingMessage,
|
|
FlareProfile,
|
|
FlareProfileDraft,
|
|
} from '@/types/flare'
|
|
import { nuiCall } from '@/utils/nui'
|
|
|
|
function hasValidProfilePhotos(
|
|
photoMediaIds: unknown,
|
|
): photoMediaIds is number[] {
|
|
return (
|
|
Array.isArray(photoMediaIds) &&
|
|
photoMediaIds.length >= 1 &&
|
|
photoMediaIds.length <= 6 &&
|
|
new Set(photoMediaIds).size === photoMediaIds.length &&
|
|
photoMediaIds.every((mediaId) => Number.isInteger(mediaId) && mediaId > 0)
|
|
)
|
|
}
|
|
|
|
export const useFlareStore = defineStore('flare', {
|
|
state: () => ({
|
|
activeMatchId: '' as string,
|
|
error: '' as string,
|
|
loading: false,
|
|
likes: [] as FlareBootstrap['likes'],
|
|
matches: [] as FlareMatch[],
|
|
messages: [] as FlareMessage[],
|
|
profile: null as FlareBootstrap['profile'],
|
|
sending: false,
|
|
suggestions: [] as FlareProfile[],
|
|
}),
|
|
actions: {
|
|
async bootstrap(): Promise<boolean> {
|
|
this.loading = true
|
|
const response = await nuiCall<FlareBootstrap>('flare:bootstrap')
|
|
this.loading = false
|
|
this.error = response.success ? '' : (response.error ?? 'default')
|
|
if (response.success && response.data) {
|
|
this.applyBootstrap(response.data)
|
|
}
|
|
return response.success
|
|
},
|
|
async loadThread(matchId: string): Promise<boolean> {
|
|
this.activeMatchId = matchId
|
|
const response = await nuiCall<{ messages: FlareMessage[] }>(
|
|
'flare:thread',
|
|
{ matchId },
|
|
)
|
|
this.error = response.success ? '' : (response.error ?? 'default')
|
|
if (response.success) {
|
|
this.messages = response.data?.messages ?? []
|
|
const match = this.matches.find((item) => item.id === matchId)
|
|
if (match) match.unread = 0
|
|
}
|
|
return response.success
|
|
},
|
|
async deleteProfile(): Promise<boolean> {
|
|
const response = await nuiCall('flare:delete-profile')
|
|
this.error = response.success ? '' : (response.error ?? 'default')
|
|
if (response.success) this.reset()
|
|
return response.success
|
|
},
|
|
async saveProfile(draft: FlareProfileDraft): Promise<boolean> {
|
|
if (!hasValidProfilePhotos(draft.photoMediaIds)) {
|
|
this.error = 'invalid_profile_photos'
|
|
return false
|
|
}
|
|
const response = await nuiCall<FlareBootstrap>(
|
|
'flare:save-profile',
|
|
draft,
|
|
)
|
|
this.error = response.success ? '' : (response.error ?? 'default')
|
|
if (response.success && response.data) {
|
|
this.applyBootstrap(response.data)
|
|
}
|
|
return response.success
|
|
},
|
|
async send(
|
|
matchId: string,
|
|
outgoing: FlareOutgoingMessage,
|
|
): Promise<boolean> {
|
|
this.sending = true
|
|
const response = await nuiCall<FlareMessage>('flare:send', {
|
|
matchId,
|
|
...outgoing,
|
|
})
|
|
this.sending = false
|
|
this.error = response.success ? '' : (response.error ?? 'default')
|
|
if (response.success && response.data) {
|
|
this.messages.push(response.data)
|
|
const match = this.matches.find((item) => item.id === matchId)
|
|
if (match) {
|
|
match.lastMessage = response.data.body
|
|
match.lastMessageAt = response.data.createdAt
|
|
match.lastMessageType = response.data.messageType
|
|
}
|
|
}
|
|
return response.success
|
|
},
|
|
async swipe(
|
|
targetId: number,
|
|
choice: 'like' | 'pass' | 'superlike',
|
|
): Promise<FlareMatch | null> {
|
|
const response = await nuiCall<{ match: FlareMatch | null }>(
|
|
'flare:swipe',
|
|
{ choice, targetId },
|
|
)
|
|
this.error = response.success ? '' : (response.error ?? 'default')
|
|
if (!response.success) return null
|
|
this.suggestions = this.suggestions.filter(
|
|
(profile) => profile.id !== targetId,
|
|
)
|
|
this.likes = this.likes.filter((profile) => profile.id !== targetId)
|
|
const match = response.data?.match ?? null
|
|
if (match) {
|
|
this.matches = [
|
|
match,
|
|
...this.matches.filter((item) => item.id !== match.id),
|
|
]
|
|
}
|
|
return match
|
|
},
|
|
async rewind(): Promise<boolean> {
|
|
const response = await nuiCall<FlareBootstrap>('flare:rewind')
|
|
this.error = response.success ? '' : (response.error ?? 'default')
|
|
if (response.success && response.data) this.applyBootstrap(response.data)
|
|
return response.success
|
|
},
|
|
async setDiscovery(enabled: boolean): Promise<boolean> {
|
|
const response = await nuiCall<FlareBootstrap>('flare:set-discovery', {
|
|
enabled,
|
|
})
|
|
this.error = response.success ? '' : (response.error ?? 'default')
|
|
if (response.success && response.data) this.applyBootstrap(response.data)
|
|
return response.success
|
|
},
|
|
async unmatch(matchId: string): Promise<boolean> {
|
|
const response = await nuiCall<{ matches: FlareMatch[] }>(
|
|
'flare:unmatch',
|
|
{
|
|
matchId,
|
|
},
|
|
)
|
|
this.error = response.success ? '' : (response.error ?? 'default')
|
|
if (response.success) {
|
|
this.matches = response.data?.matches ?? []
|
|
this.messages = []
|
|
if (this.activeMatchId === matchId) this.activeMatchId = ''
|
|
}
|
|
return response.success
|
|
},
|
|
reset(error = ''): void {
|
|
this.activeMatchId = ''
|
|
this.error = error
|
|
this.loading = false
|
|
this.likes = []
|
|
this.matches = []
|
|
this.messages = []
|
|
this.profile = null
|
|
this.sending = false
|
|
this.suggestions = []
|
|
},
|
|
applyBootstrap(data: FlareBootstrap): void {
|
|
this.profile = data.profile
|
|
this.likes = data.likes
|
|
this.matches = data.matches
|
|
this.suggestions = data.suggestions
|
|
},
|
|
},
|
|
})
|