mirror of
https://github.com/nagisa77/OpenIsle.git
synced 2026-03-19 18:37:25 +08:00
feat: add optimistic reaction update
This commit is contained in:
@@ -128,10 +128,23 @@ export default {
|
|||||||
toast.error('请先登录')
|
toast.error('请先登录')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
const url = props.contentType === 'post'
|
||||||
|
? `${API_BASE_URL}/api/posts/${props.contentId}/reactions`
|
||||||
|
: `${API_BASE_URL}/api/comments/${props.contentId}/reactions`
|
||||||
|
|
||||||
|
// optimistic update
|
||||||
|
const existingIdx = reactions.value.findIndex(r => r.type === type && r.user === authState.username)
|
||||||
|
let tempReaction = null
|
||||||
|
let removedReaction = null
|
||||||
|
if (existingIdx > -1) {
|
||||||
|
removedReaction = reactions.value.splice(existingIdx, 1)[0]
|
||||||
|
} else {
|
||||||
|
tempReaction = { type, user: authState.username }
|
||||||
|
reactions.value.push(tempReaction)
|
||||||
|
}
|
||||||
|
emit('update:modelValue', reactions.value)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const url = props.contentType === 'post'
|
|
||||||
? `${API_BASE_URL}/api/posts/${props.contentId}/reactions`
|
|
||||||
: `${API_BASE_URL}/api/comments/${props.contentId}/reactions`
|
|
||||||
const res = await fetch(url, {
|
const res = await fetch(url, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
|
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
|
||||||
@@ -139,20 +152,40 @@ export default {
|
|||||||
})
|
})
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
if (res.status === 204) {
|
if (res.status === 204) {
|
||||||
const idx = reactions.value.findIndex(r => r.type === type && r.user === authState.username)
|
// removal already reflected
|
||||||
if (idx > -1) reactions.value.splice(idx, 1)
|
|
||||||
} else {
|
} else {
|
||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
reactions.value.push(data)
|
const idx = tempReaction ? reactions.value.indexOf(tempReaction) : -1
|
||||||
|
if (idx > -1) {
|
||||||
|
reactions.value.splice(idx, 1, data)
|
||||||
|
} else if (removedReaction) {
|
||||||
|
// server added back reaction even though we removed? restore data
|
||||||
|
reactions.value.push(data)
|
||||||
|
}
|
||||||
if (data.reward && data.reward > 0) {
|
if (data.reward && data.reward > 0) {
|
||||||
toast.success(`获得 ${data.reward} 经验值`)
|
toast.success(`获得 ${data.reward} 经验值`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
emit('update:modelValue', reactions.value)
|
emit('update:modelValue', reactions.value)
|
||||||
} else {
|
} else {
|
||||||
|
// revert optimistic update on failure
|
||||||
|
if (tempReaction) {
|
||||||
|
const idx = reactions.value.indexOf(tempReaction)
|
||||||
|
if (idx > -1) reactions.value.splice(idx, 1)
|
||||||
|
} else if (removedReaction) {
|
||||||
|
reactions.value.push(removedReaction)
|
||||||
|
}
|
||||||
|
emit('update:modelValue', reactions.value)
|
||||||
toast.error('操作失败')
|
toast.error('操作失败')
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
if (tempReaction) {
|
||||||
|
const idx = reactions.value.indexOf(tempReaction)
|
||||||
|
if (idx > -1) reactions.value.splice(idx, 1)
|
||||||
|
} else if (removedReaction) {
|
||||||
|
reactions.value.push(removedReaction)
|
||||||
|
}
|
||||||
|
emit('update:modelValue', reactions.value)
|
||||||
toast.error('操作失败')
|
toast.error('操作失败')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user