Skip to content

Commit 9f3820d

Browse files
committed
fix: correlate poll update votes
1 parent 8d66129 commit 9f3820d

3 files changed

Lines changed: 60 additions & 3 deletions

File tree

Sources/IMsgCore/MessagePolls.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,24 @@ extension MessagePollEvent {
309309
metadata: metadata
310310
)
311311
}
312+
313+
func resolvingPollReference(pollGUID: String?, originalGUID: String?) -> MessagePollEvent {
314+
if self.pollGUID == pollGUID, self.originalGUID == originalGUID {
315+
return self
316+
}
317+
return MessagePollEvent(
318+
kind: kind,
319+
pollGUID: pollGUID,
320+
question: question,
321+
options: options,
322+
vote: vote,
323+
votes: votes,
324+
originalGUID: originalGUID,
325+
creator: creator,
326+
participants: participants,
327+
metadata: metadata
328+
)
329+
}
312330
}
313331

314332
private struct PollFacts {

Sources/IMsgCore/MessageStore+Polls.swift

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,17 @@ extension MessageStore {
1515
}
1616
guard let pollGUID = candidateGUIDs.first else { return poll }
1717

18+
let sourcePollGUID = try sourcePollGUID(forAny: candidateGUIDs, db: db) ?? pollGUID
1819
let optionTexts = try pollOptionTextsByID(
19-
pollGUID: pollGUID,
20+
pollGUID: sourcePollGUID,
2021
db: db,
2122
cache: &cache
2223
)
23-
return poll.resolvingVoteOptionTexts(optionTexts)
24+
let resolvedPoll = poll.resolvingVoteOptionTexts(optionTexts)
25+
return resolvedPoll.resolvingPollReference(
26+
pollGUID: sourcePollGUID,
27+
originalGUID: sourcePollGUID
28+
)
2429
}
2530

2631
/// Ordered options of the poll identified by `guid`, decoded from its
@@ -109,4 +114,37 @@ extension MessageStore {
109114
}
110115
return options
111116
}
117+
118+
private func sourcePollGUID(forAny candidates: [String], db: Connection) throws -> String? {
119+
guard schema.hasReactionColumns else { return nil }
120+
for candidate in candidates {
121+
if let source = try sourcePollGUID(forUpdateRow: candidate, db: db) {
122+
return source
123+
}
124+
}
125+
return candidates.first
126+
}
127+
128+
private func sourcePollGUID(forUpdateRow guid: String, db: Connection) throws -> String? {
129+
let rows = try db.prepareRowIterator(
130+
"""
131+
SELECT associated_message_guid
132+
FROM message
133+
WHERE guid = ?
134+
AND associated_message_type = ?
135+
AND IFNULL(associated_message_guid, '') != ''
136+
LIMIT 1
137+
""",
138+
bindings: [guid, MessagePollDecoder.updateAssociatedMessageType]
139+
)
140+
guard
141+
let row = try rows.failableNext(),
142+
let associatedGUID = try row.get(Expression<String?>("associated_message_guid"))
143+
else {
144+
return nil
145+
}
146+
147+
let normalized = normalizeAssociatedGUID(associatedGUID)
148+
return normalized.isEmpty ? nil : normalized
149+
}
112150
}

Tests/IMsgCoreTests/MessagePollTests.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,8 @@ func messageStoreResolvesVoteOptionTextFromPollUpdateRows() throws {
549549
#expect(updateMessage.poll?.originalGUID == "original-poll-guid")
550550
#expect(updateMessage.poll?.options?.map(\.text) == ["A", "Custom choice"])
551551
#expect(voteMessage.poll?.kind == .vote)
552-
#expect(voteMessage.poll?.originalGUID == "updated-poll-guid")
552+
#expect(voteMessage.poll?.pollGUID == "original-poll-guid")
553+
#expect(voteMessage.poll?.originalGUID == "original-poll-guid")
553554
#expect(voteMessage.poll?.vote?.optionID == "choice-custom")
554555
#expect(voteMessage.poll?.vote?.optionText == "Custom choice")
555556
}

0 commit comments

Comments
 (0)