CI and images / lint (push) Successful in 3s
CI and images / extension-version (push) Successful in 3s
CI and images / frontend-build (push) Successful in 18s
CI and images / backend-lint-and-test (push) Successful in 32s
CI and images / integration (push) Successful in 2m22s
CI and images / sign-extension (push) Successful in 3s
CI and images / build-agent (push) Successful in 6s
CI and images / build-web (push) Successful in 1m38s
CI and images / smoke-web (push) Successful in 59s
CI and images / promote (push) Skipped
The linked drop's images and the piece's variants join the teaser's rail,
after its own images, each with a corner badge. The meta line counts them
apart ("+N from Discord"), so a Patreon card never reads as though the creator
posted Discord's files there. The text of each referenced post sits under
the teaser's body.
If FC made the link, the card says so, names the matching working name and
offers Undo. If a person accepted it, it offers Unlink and makes no claim
about FC. Both dismiss the pair. The kept row then stops the next sweep from
linking it straight back.
The announcement settings card gets the two windows: how close a drop must be
before its own card is left out of the feed, and how far to reach for
variants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVjrnpQjRgHdvq95rASoiR
110 lines
3.4 KiB
JavaScript
110 lines
3.4 KiB
JavaScript
import { defineStore } from 'pinia'
|
|
import { ref } from 'vue'
|
|
|
|
import { useApi } from '../composables/useApi.js'
|
|
import { useAsyncAction } from '../composables/useAsyncAction.js'
|
|
import { toast } from '../utils/toast.js'
|
|
|
|
// Backs the announcement review queue (#388 E5): "this Patreon post announced
|
|
// that Discord drop". A wrongly-asserted link tells the operator two different
|
|
// pieces are one, which is worse than no link at all — so what reaches this
|
|
// queue is everything FC is NOT sure enough about to act on by itself.
|
|
//
|
|
// A pair the creator's own working name identifies, where that name is on
|
|
// these two posts and nowhere else in their library, is linked without asking
|
|
// (`auto`). Mirrors seriesSuggestions (FC-6.3) in shape.
|
|
export const usePostAssociationsStore = defineStore('postAssociations', () => {
|
|
const api = useApi()
|
|
const proposals = ref([])
|
|
const enabled = ref(true)
|
|
const auto = ref(true)
|
|
const threshold = ref(0.6)
|
|
const windowHours = ref(24)
|
|
// #4402 — what a link shows once made. See PostAssociationsCard.
|
|
const foldHours = ref(24)
|
|
const familyDays = ref(60)
|
|
const { loading, error, run } = useAsyncAction({ errorAs: 'message' })
|
|
|
|
async function load () {
|
|
await run(async () => {
|
|
const body = await api.get('/api/posts/associations')
|
|
proposals.value = body.items || []
|
|
})
|
|
}
|
|
|
|
async function loadSettings () {
|
|
const s = await api.get('/api/settings/import')
|
|
enabled.value = s.discord_link_enabled
|
|
auto.value = s.discord_link_auto
|
|
threshold.value = s.discord_link_threshold
|
|
windowHours.value = s.discord_link_window_hours
|
|
foldHours.value = s.discord_link_fold_hours
|
|
familyDays.value = s.discord_family_window_days
|
|
}
|
|
|
|
async function saveSettings (patch) {
|
|
await api.patch('/api/settings/import', { body: patch })
|
|
}
|
|
|
|
async function setEnabled (v) {
|
|
enabled.value = v
|
|
await saveSettings({ discord_link_enabled: v })
|
|
}
|
|
|
|
async function setAuto (v) {
|
|
auto.value = v
|
|
await saveSettings({ discord_link_auto: v })
|
|
}
|
|
|
|
async function setThreshold (v) {
|
|
threshold.value = v
|
|
await saveSettings({ discord_link_threshold: v })
|
|
}
|
|
|
|
async function setWindowHours (v) {
|
|
windowHours.value = v
|
|
await saveSettings({ discord_link_window_hours: v })
|
|
}
|
|
|
|
async function setFoldHours (v) {
|
|
foldHours.value = v
|
|
await saveSettings({ discord_link_fold_hours: v })
|
|
}
|
|
|
|
async function setFamilyDays (v) {
|
|
familyDays.value = v
|
|
await saveSettings({ discord_family_window_days: v })
|
|
}
|
|
|
|
async function accept (id) {
|
|
try {
|
|
await api.post(`/api/posts/associations/${id}/accept`, {})
|
|
proposals.value = proposals.value.filter(p => p.id !== id)
|
|
toast({ text: 'Linked', type: 'success' })
|
|
} catch (e) {
|
|
toast({ text: `Link failed: ${e.message}`, type: 'error' })
|
|
}
|
|
}
|
|
|
|
async function dismiss (id) {
|
|
try {
|
|
await api.post(`/api/posts/associations/${id}/dismiss`, {})
|
|
proposals.value = proposals.value.filter(p => p.id !== id)
|
|
} catch (e) {
|
|
toast({ text: `Dismiss failed: ${e.message}`, type: 'error' })
|
|
}
|
|
}
|
|
|
|
async function rescan () {
|
|
await api.post('/api/posts/associations/rescan', {})
|
|
await load()
|
|
}
|
|
|
|
return {
|
|
proposals, enabled, auto, threshold, windowHours, foldHours, familyDays,
|
|
loading, error,
|
|
load, loadSettings, setEnabled, setAuto, setThreshold, setWindowHours,
|
|
setFoldHours, setFamilyDays, accept, dismiss, rescan
|
|
}
|
|
})
|