最終更新 4 weeks ago

nuno revised this gist 4 weeks ago. Go to revision

1 file changed, 93 insertions

gistfile1.txt(file created)

@@ -0,0 +1,93 @@
1 + async function handleSwitchAfterReclaim(btn: ButtonInteraction): Promise<void> {
2 + const parts = btn.customId.split(":");
3 + const userKey = parts[1];
4 + const charName = parts[2];
5 + const prevVoteType = (parts[3] ?? "yes") as "yes" | "no";
6 +
7 + const chars = JSON.parse(
8 + fs.readFileSync(path.join(__dirname, "../../data/characters.json"), "utf8")
9 + );
10 +
11 + let resolvedChar: any = null;
12 + let borrowedFrom: string | null = null;
13 +
14 + // Try own char first
15 + const ownEntry = chars[userKey]?.characters?.find((c: any) => c.name === charName);
16 + if (ownEntry) {
17 + setActiveCharacter(userKey, charName);
18 + clearSessionBorrowForUser(userKey);
19 + resolvedChar = ownEntry;
20 + } else {
21 + // Try shared char
22 + for (const [ownerKey, data] of Object.entries(chars) as [string, any][]) {
23 + const char = data.characters?.find(
24 + (c: any) => c.name === charName && c.sharedWith?.includes(userKey)
25 + );
26 + if (char) {
27 + setPersistentPreference(userKey, ownerKey, charName);
28 + clearSessionBorrowForUser(userKey);
29 + resolvedChar = char;
30 + borrowedFrom = ownerKey;
31 + break;
32 + }
33 + }
34 + }
35 +
36 + if (!resolvedChar) {
37 + await btn.reply({ content: `❌ Could not switch to **${charName}**.`, ephemeral: true });
38 + return;
39 + }
40 +
41 + // Re-add to poll with previous vote type
42 + const slot = [...polls.keys()][0];
43 + const state = slot !== undefined ? polls.get(slot) : null;
44 +
45 + if (state && !state.locked && state.confirmed === null) {
46 + const { char } = getEffectiveCharacter(userKey);
47 + const now = nowFormatted();
48 + const publicMsg = resolveMessage("public", prevVoteType, 1, userKey, null, null);
49 + const voteEntry = {
50 + userKey,
51 + displayName: charName,
52 + characterName: char?.name ?? charName,
53 + characterClass: char?.class ?? resolvedChar.class,
54 + characterLevel: char?.level ?? resolvedChar.level,
55 + characterNation: char?.nation ?? resolvedChar.nation,
56 + borrowedFrom: borrowedFrom ?? undefined,
57 + discordId: btn.user.id,
58 + votedAt: now,
59 + publicMessage: publicMsg ?? undefined,
60 + };
61 +
62 + // Find and reuse existing vote ID — avoids duplicate entries
63 + let existingVoteId: string | null = null;
64 + for (const [id, entry] of [...state.yes.entries(), ...state.no.entries()]) {
65 + if (entry.userKey === userKey) {
66 + if (!existingVoteId) existingVoteId = id;
67 + state.yes.delete(id);
68 + state.no.delete(id);
69 + }
70 + }
71 + const voteId = existingVoteId ?? btn.user.id;
72 +
73 + if (prevVoteType === "yes") {
74 + state.yes.set(voteId, voteEntry);
75 + } else {
76 + state.no.set(voteId, voteEntry);
77 + }
78 +
79 + console.log(`[switch_reclaim] cleaning up for userKey=${userKey}`);
80 + console.log(`[switch_reclaim] yes keys:`, [...state.yes.entries()].map(([id, e]) => `${id}:${e.userKey}`));
81 + console.log(`[switch_reclaim] no keys:`, [...state.no.entries()].map(([id, e]) => `${id}:${e.userKey}`));
82 +
83 + const channel = await btn.client.channels.fetch(cfg("pollChannelId")) as TextChannel;
84 + await updatePollMessage(channel, slot!);
85 + }
86 +
87 + const charDisplay = resolvedChar ? format.char(resolvedChar) : charName;
88 + const borrowNote = borrowedFrom ? ` *(shared by ${borrowedFrom})*` : "";
89 + await btn.reply({
90 + content: `🔄 ${charDisplay}${borrowNote}${state ? ` — re-added to poll as **${prevVoteType}**.` : ""}`,
91 + ephemeral: true,
92 + });
93 + }
Newer Older