Clean up vote count & pin expiry parsing
This commit is contained in:
parent
c68f334581
commit
ffae2627d3
@ -318,7 +318,10 @@ extension ConversationViewController: MessageActionsDelegate {
|
||||
let sentTimestamp = Date.ows_millisecondTimestamp()
|
||||
|
||||
if let _pinMessage = pinMessage as? OutgoingPinMessage {
|
||||
let expiresAtMs: UInt64? = _pinMessage.pinDurationSeconds > 0 ? Date.ows_millisecondTimestamp() + UInt64(_pinMessage.pinDurationSeconds * 1000) : nil
|
||||
var expiresAtMs: UInt64?
|
||||
if _pinMessage.pinDurationSeconds > 0 {
|
||||
expiresAtMs = Date.ows_millisecondTimestamp() + UInt64(_pinMessage.pinDurationSeconds) * 1000
|
||||
}
|
||||
|
||||
pinnedMessageManager.applyPinMessageChangeToLocalState(
|
||||
targetTimestamp: _pinMessage.targetMessageTimestamp,
|
||||
|
||||
@ -254,6 +254,9 @@ extension BackupArchive {
|
||||
/// A poll vote recipient id was not found
|
||||
case pollVoteAuthorSignalRecipientIdMissing
|
||||
|
||||
/// A poll vote count was not a valid Int32 value
|
||||
case pollVoteCountInvalid
|
||||
|
||||
/// Author Aci for end poll message was invalid
|
||||
case endPollUpdateInvalidAuthorAci
|
||||
|
||||
@ -381,6 +384,7 @@ extension BackupArchive {
|
||||
.invalidPollVoteRecordDatabaseRow,
|
||||
.pollMessageMissingQuestionBody,
|
||||
.pollVoteAuthorSignalRecipientIdMissing,
|
||||
.pollVoteCountInvalid,
|
||||
.endPollUpdateInvalidAuthorAci,
|
||||
.pollEndMissingQuestion,
|
||||
.pollEndMissingPersistableData,
|
||||
@ -455,6 +459,7 @@ extension BackupArchive {
|
||||
.invalidPollVoteRecordDatabaseRow,
|
||||
.pollMessageMissingQuestionBody,
|
||||
.pollVoteAuthorSignalRecipientIdMissing,
|
||||
.pollVoteCountInvalid,
|
||||
.endPollUpdateInvalidAuthorAci,
|
||||
.pollEndMissingQuestion,
|
||||
.pollEndMissingPersistableData,
|
||||
@ -838,6 +843,9 @@ extension BackupArchive {
|
||||
/// We expect all authors to have an associated latest vote count, but there wasn't
|
||||
case noPollVoteCountForAuthor
|
||||
|
||||
/// Vote count was not a valid Int32 value
|
||||
case invalidPollVoteCount
|
||||
|
||||
/// The pin message author had an invalid non-contact Address
|
||||
case pinMessageAuthorNotContact
|
||||
|
||||
@ -1009,6 +1017,7 @@ extension BackupArchive {
|
||||
.pollVoteAuthorNotContact,
|
||||
.pollVoteCountRepeated,
|
||||
.noPollVoteCountForAuthor,
|
||||
.invalidPollVoteCount,
|
||||
.pinMessageAuthorNotContact,
|
||||
.invalidNumberOfPinnedMessages,
|
||||
.sentTimestampOverflowedLocalType,
|
||||
@ -1124,6 +1133,7 @@ extension BackupArchive {
|
||||
.pollVoteAuthorNotContact,
|
||||
.pollVoteCountRepeated,
|
||||
.noPollVoteCountForAuthor,
|
||||
.invalidPollVoteCount,
|
||||
.pinMessageAuthorNotContact,
|
||||
.invalidNumberOfPinnedMessages,
|
||||
.sentTimestampOverflowedLocalType,
|
||||
|
||||
@ -59,8 +59,12 @@ class BackupArchivePollArchiver: BackupArchiveProtoStreamWriter {
|
||||
return .messageFailure([.archiveFrameError(.pollVoteAuthorSignalRecipientIdMissing, BackupArchive.InteractionUniqueId(interaction: message))])
|
||||
}
|
||||
|
||||
guard vote.voteCount >= 0 else {
|
||||
return .messageFailure([.archiveFrameError(.pollVoteCountInvalid, BackupArchive.InteractionUniqueId(interaction: message))])
|
||||
}
|
||||
|
||||
pollVoteProto.voterID = voterId.value
|
||||
pollVoteProto.voteCount = vote.voteCount
|
||||
pollVoteProto.voteCount = UInt32(vote.voteCount)
|
||||
pollOptionProto.votes.append(pollVoteProto)
|
||||
}
|
||||
pollProto.options.append(pollOptionProto)
|
||||
|
||||
@ -2160,7 +2160,16 @@ class BackupArchiveTSMessageContentsArchiver: BackupArchiveProtoStreamWriter {
|
||||
)]
|
||||
continue
|
||||
}
|
||||
votes.append(BackupsPollVote(voteAuthorId: voteAuthorId, voteCount: voteProto.voteCount))
|
||||
|
||||
guard voteProto.voteCount <= Int32.max else {
|
||||
partialErrors += [.restoreFrameError(
|
||||
.invalidProtoData(.invalidPollVoteCount),
|
||||
chatItemId,
|
||||
)]
|
||||
continue
|
||||
}
|
||||
|
||||
votes.append(BackupsPollVote(voteAuthorId: voteAuthorId, voteCount: Int32(voteProto.voteCount)))
|
||||
}
|
||||
options.append(BackupsPollOption(text: optionProto.option, votes: votes))
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ public class OutgoingPinMessage: TransientOutgoingMessage {
|
||||
guard let pinDurationSeconds = coder.decodeObject(of: NSNumber.self, forKey: "pinDurationSeconds") else {
|
||||
return nil
|
||||
}
|
||||
self.pinDurationSeconds = pinDurationSeconds.uint32Value
|
||||
self.pinDurationSeconds = pinDurationSeconds.int32Value
|
||||
guard
|
||||
let targetMessageAuthorAciBinary = coder.decodeObject(of: NSData.self, forKey: "targetMessageAuthorAciBinary") as Data?,
|
||||
let targetMessageAuthorAci = try? Aci.parseFrom(serviceIdBinary: targetMessageAuthorAciBinary)
|
||||
@ -62,14 +62,14 @@ public class OutgoingPinMessage: TransientOutgoingMessage {
|
||||
|
||||
public let targetMessageTimestamp: UInt64
|
||||
public let targetMessageAuthorAci: Aci
|
||||
public let pinDurationSeconds: UInt32
|
||||
public let pinDurationSeconds: Int32
|
||||
private let pinDurationForever: Bool
|
||||
|
||||
public init(
|
||||
thread: TSThread,
|
||||
targetMessageTimestamp: UInt64,
|
||||
targetMessageAuthorAciBinary: Aci,
|
||||
pinDurationSeconds: UInt32,
|
||||
pinDurationSeconds: Int32,
|
||||
pinDurationForever: Bool,
|
||||
messageExpiresInSeconds: UInt32,
|
||||
tx: DBReadTransaction,
|
||||
@ -123,7 +123,7 @@ public class OutgoingPinMessage: TransientOutgoingMessage {
|
||||
pinMessageBuilder.setTargetAuthorAciBinary(targetMessageAuthorAci.serviceIdBinary)
|
||||
|
||||
if pinDurationSeconds > 0 {
|
||||
pinMessageBuilder.setPinDurationSeconds(pinDurationSeconds)
|
||||
pinMessageBuilder.setPinDurationSeconds(UInt32(pinDurationSeconds))
|
||||
} else if pinDurationForever {
|
||||
pinMessageBuilder.setPinDurationForever(pinDurationForever)
|
||||
}
|
||||
@ -138,7 +138,11 @@ public class OutgoingPinMessage: TransientOutgoingMessage {
|
||||
override public func updateWithSendSuccess(tx: DBWriteTransaction) {
|
||||
let pinnedMessageManager = DependenciesBridge.shared.pinnedMessageManager
|
||||
|
||||
let expiresAtMs: UInt64? = pinDurationSeconds > 0 ? Date.ows_millisecondTimestamp() + UInt64(pinDurationSeconds * 1000) : nil
|
||||
var expiresAtMs: UInt64?
|
||||
if pinDurationSeconds > 0 {
|
||||
let pinDurationMilliseconds = UInt64(pinDurationSeconds) * 1000
|
||||
expiresAtMs = Date.ows_millisecondTimestamp() + pinDurationMilliseconds
|
||||
}
|
||||
|
||||
pinnedMessageManager.applyPinMessageChangeToLocalState(
|
||||
targetTimestamp: targetMessageTimestamp,
|
||||
|
||||
@ -71,7 +71,7 @@ public class PinnedMessageManager {
|
||||
throw OWSAssertionError("Invalid timestamp.")
|
||||
}
|
||||
|
||||
guard pinMessageProto.pinDurationSeconds < Int32.max else {
|
||||
guard pinMessageProto.pinDurationSeconds <= Int32.max else {
|
||||
throw OWSAssertionError("Invalid timestamp.")
|
||||
}
|
||||
}
|
||||
@ -416,9 +416,9 @@ public class PinnedMessageManager {
|
||||
return nil
|
||||
}
|
||||
|
||||
var pinDurationSeconds: UInt32?
|
||||
var pinDurationSeconds: Int32?
|
||||
if let expiresAt {
|
||||
pinDurationSeconds = UInt32(expiresAt)
|
||||
pinDurationSeconds = Int32(expiresAt)
|
||||
}
|
||||
|
||||
return OutgoingPinMessage(
|
||||
|
||||
@ -24,7 +24,7 @@ public class OutgoingPollVoteMessage: TransientOutgoingMessage {
|
||||
guard let voteCount = coder.decodeObject(of: NSNumber.self, forKey: "voteCount") else {
|
||||
return nil
|
||||
}
|
||||
self.voteCount = voteCount.uint32Value
|
||||
self.voteCount = voteCount.int32Value
|
||||
guard let voteOptionIndexes = coder.decodeArrayOfObjects(ofClass: NSNumber.self, forKey: "voteOptionIndexes") else {
|
||||
return nil
|
||||
}
|
||||
@ -63,14 +63,14 @@ public class OutgoingPollVoteMessage: TransientOutgoingMessage {
|
||||
let targetPollTimestamp: UInt64
|
||||
let targetPollAuthorAci: Aci
|
||||
let voteOptionIndexes: [UInt32]
|
||||
let voteCount: UInt32
|
||||
let voteCount: Int32
|
||||
|
||||
public init(
|
||||
thread: TSThread,
|
||||
targetPollTimestamp: UInt64,
|
||||
targetPollAuthorAci: Aci,
|
||||
voteOptionIndexes: [UInt32],
|
||||
voteCount: UInt32,
|
||||
voteCount: Int32,
|
||||
tx: DBReadTransaction,
|
||||
) {
|
||||
self.targetPollTimestamp = targetPollTimestamp
|
||||
@ -110,7 +110,7 @@ public class OutgoingPollVoteMessage: TransientOutgoingMessage {
|
||||
|
||||
pollVoteBuilder.setOptionIndexes(voteOptionIndexes)
|
||||
|
||||
pollVoteBuilder.setVoteCount(voteCount)
|
||||
pollVoteBuilder.setVoteCount(UInt32(clamping: voteCount))
|
||||
|
||||
dataMessageBuilder.setPollVote(
|
||||
pollVoteBuilder.buildInfallibly(),
|
||||
@ -179,7 +179,7 @@ public class OutgoingPollVoteMessage: TransientOutgoingMessage {
|
||||
}
|
||||
|
||||
try PollStore().revertVoteCount(
|
||||
voteCount: Int32(voteCount),
|
||||
voteCount: voteCount,
|
||||
interactionId: interactionId,
|
||||
voteAuthorId: localRecipientId,
|
||||
transaction: tx,
|
||||
|
||||
@ -318,7 +318,7 @@ public class PollMessageManager {
|
||||
targetPollTimestamp: UInt64,
|
||||
targetPollAuthorAci: Aci,
|
||||
optionIndexes: [OWSPoll.OptionIndex],
|
||||
voteCount: UInt32,
|
||||
voteCount: Int32,
|
||||
threadUniqueId: String,
|
||||
tx: DBWriteTransaction,
|
||||
) throws {
|
||||
@ -353,7 +353,7 @@ public class PollMessageManager {
|
||||
interactionId: interactionId,
|
||||
optionsVoted: optionIndexes,
|
||||
voteAuthorId: localAuthorRecipientId,
|
||||
voteCount: voteCount,
|
||||
voteCount: UInt32(clamping: voteCount),
|
||||
transaction: tx,
|
||||
)
|
||||
|
||||
@ -442,7 +442,7 @@ public class PollMessageManager {
|
||||
targetPollTimestamp: pollInteraction.timestamp,
|
||||
targetPollAuthorAci: authorAci,
|
||||
voteOptionIndexes: optionIndexVotes,
|
||||
voteCount: UInt32(newHighestVoteCount),
|
||||
voteCount: newHighestVoteCount,
|
||||
tx: tx,
|
||||
)
|
||||
}
|
||||
@ -454,7 +454,7 @@ public struct BackupsPollData {
|
||||
public struct BackupsPollOption {
|
||||
public struct BackupsPollVote {
|
||||
let voteAuthorId: SignalRecipient.RowId
|
||||
let voteCount: UInt32
|
||||
let voteCount: Int32
|
||||
}
|
||||
|
||||
let text: String
|
||||
@ -527,7 +527,7 @@ extension PollMessageManager {
|
||||
var partialErrors = [BackupArchive.RestoreFrameError<BackupArchive.ChatItemId>]()
|
||||
|
||||
var votesByAuthorId: [Int64: [OWSPoll.OptionIndex]] = [:]
|
||||
var voteCountByAuthorId: [Int64: UInt32] = [:]
|
||||
var voteCountByAuthorId: [Int64: Int32] = [:]
|
||||
|
||||
for (index, optionData) in pollBackupData.options.enumerated() {
|
||||
for vote in optionData.votes {
|
||||
@ -560,7 +560,7 @@ extension PollMessageManager {
|
||||
interactionId: interactionId,
|
||||
optionsVoted: optionIndices,
|
||||
voteAuthorId: voteAuthorId,
|
||||
voteCount: voteCount,
|
||||
voteCount: UInt32(clamping: voteCount),
|
||||
transaction: tx,
|
||||
)
|
||||
} catch {
|
||||
|
||||
@ -384,13 +384,20 @@ public class PollStore {
|
||||
}
|
||||
|
||||
// Include pending here so we don't reuse an already-sent but not-yet-delivered vote count.
|
||||
let newHighestVoteCount = try highestVoteCount(
|
||||
|
||||
let highestVoteCount = try highestVoteCount(
|
||||
pollId: pollId,
|
||||
voteAuthorId: localRecipientId,
|
||||
includePending: true,
|
||||
transaction: transaction,
|
||||
) + 1
|
||||
)
|
||||
|
||||
guard highestVoteCount < Int32.max else {
|
||||
Logger.error("Failed to apply pending vote, highestVoteCount is too large")
|
||||
return nil
|
||||
}
|
||||
|
||||
let newHighestVoteCount = highestVoteCount + 1
|
||||
guard
|
||||
let optionId = try voteOptionIds(
|
||||
from: [optionIndex],
|
||||
@ -569,7 +576,7 @@ extension PollStore {
|
||||
var votes: [BackupsPollData.BackupsPollOption.BackupsPollVote] = []
|
||||
for voteRow in optionIdToVotes[optionId] ?? [] {
|
||||
if voteRow.voteState == .vote {
|
||||
votes.append(BackupsPollData.BackupsPollOption.BackupsPollVote(voteAuthorId: voteRow.voteAuthorId, voteCount: UInt32(voteRow.voteCount)))
|
||||
votes.append(BackupsPollData.BackupsPollOption.BackupsPollVote(voteAuthorId: voteRow.voteAuthorId, voteCount: voteRow.voteCount))
|
||||
}
|
||||
}
|
||||
optionData.append(BackupsPollData.BackupsPollOption(text: optionRow.option, votes: votes))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user