Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: polls rewrite #1373

Merged
merged 61 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
d4424ed
feat: extract PollAnswer type from PollVote type
MartinCupela Sep 18, 2024
b43297c
fix: populate missing generics for PollAnswer
MartinCupela Sep 18, 2024
75f2b60
fix: populate missing generics for QueryPollsResponse
MartinCupela Sep 18, 2024
9302884
refactor: simplify PollAnswer type
MartinCupela Sep 18, 2024
28edc51
feat: add client.queryPollAnswers method
MartinCupela Sep 18, 2024
dfa8f47
fix: remove channel and cid from PollResponse
MartinCupela Sep 19, 2024
a38f393
fix: fix poll types
MartinCupela Sep 20, 2024
fe845db
refactor: keep exports ordered in alphabetic order
MartinCupela Sep 20, 2024
7a523c6
fix: add missing StreamChatGenerics to poll types in client method de…
MartinCupela Sep 20, 2024
4151673
style: run lint
MartinCupela Sep 20, 2024
a03a0c7
feat: add Poll class
MartinCupela Sep 20, 2024
5f0df10
fix: remove paginator from index
MartinCupela Sep 20, 2024
c58d02b
feat: add Poll.queryPollAnswers & Poll.queryOptionVotes
MartinCupela Sep 20, 2024
7d0206a
fix: prevent recursion on poll.data getter
MartinCupela Sep 20, 2024
184cb80
fix: remove poll event handlers in channel state
MartinCupela Sep 20, 2024
aece207
feat: poll_manager initial impl
isekovanic Sep 20, 2024
1dfe2fe
style: fix lint issues
MartinCupela Sep 24, 2024
33cf859
feat: add maxVotedOptionIds, ownVotesByOptionId, ownAnswer to PollState
MartinCupela Sep 24, 2024
04efc24
style: fix lint issues
MartinCupela Sep 24, 2024
51ac4f6
fix: prevent executing poll event listener for other polls & subscrib…
MartinCupela Sep 24, 2024
33fd469
fix: remove previous own answers on vote changed
MartinCupela Sep 24, 2024
a3dacd0
fix: make sure own votes do not contain answers
MartinCupela Sep 24, 2024
9a53d6b
fix: reassign own votes on vote change
MartinCupela Sep 24, 2024
2c18517
fix: override own votes on poll.vote_changed event
MartinCupela Sep 24, 2024
6cb6cc3
fix: initiate ownAnswer in Poll state when initiating Poll instance
MartinCupela Sep 24, 2024
f6b8b6d
fix: minor issues and extract id from reactive state
isekovanic Sep 26, 2024
17a674f
fix: convert Poll methods to array functions
MartinCupela Sep 30, 2024
49b420f
Merge remote-tracking branch 'origin/feat/polls-rewrite' into feat/po…
MartinCupela Sep 30, 2024
25a8ee3
fix: do not use poll.data.id
MartinCupela Sep 30, 2024
eabf3e5
fix: on poll WS event update partially the state with PollEnrichData …
MartinCupela Sep 30, 2024
29e58f1
fix: vote switching bug
isekovanic Oct 7, 2024
843be7a
fix: latestAnswers breaking issue
isekovanic Oct 8, 2024
544c0eb
fix: add references to last added/updated and removed answer
isekovanic Oct 9, 2024
28f76ac
chore: revert no longer needed reactive state
isekovanic Oct 10, 2024
12e5d4f
feat: introduce poll cache to bring up poll state to a higher level
isekovanic Oct 14, 2024
9486184
fix: encapsulate poll cache
isekovanic Oct 14, 2024
850fb0c
fix: build failure
isekovanic Oct 15, 2024
3a69e15
fix: allow overwriting state in hydratePollCache
isekovanic Oct 16, 2024
162129c
fix: add missing updated_at property to PollVote type
MartinCupela Oct 21, 2024
21b8556
fix: make user_id optional in PollVote
MartinCupela Oct 21, 2024
4579394
style: fix linting issues
MartinCupela Oct 22, 2024
7774726
feat: store PollVote references in Poll state.ownVotesByOptionId
MartinCupela Oct 23, 2024
734757c
feat: remove oldest vote before casting new one on reaching max_votes…
MartinCupela Oct 23, 2024
0d62e10
refactor: remove ownVotes from Poll state
MartinCupela Oct 23, 2024
e87c750
test: start Poll tests
MartinCupela Oct 23, 2024
4bcb90d
chore: add initial poll_manager tests
isekovanic Oct 24, 2024
40b1f0d
chore: add tests for handling events
isekovanic Oct 24, 2024
d7a5696
chore: add missing event
isekovanic Oct 24, 2024
f0efbed
chore: add tests for handling subscriptions
isekovanic Oct 24, 2024
edd3f4d
fix: populate poll cache on queryPolls and getPoll too
isekovanic Oct 24, 2024
2deb62d
chore: add more poll_manager tests
isekovanic Oct 24, 2024
acb82cd
fix: lint issues
isekovanic Oct 24, 2024
c9aa7ea
fix: update Poll.ownVotesByOptionId on poll.vote_changed by merging i…
MartinCupela Oct 25, 2024
bfb3e05
test: add Poll tests
MartinCupela Oct 25, 2024
ec6dbee
Merge remote-tracking branch 'origin/feat/polls-rewrite' into feat/po…
MartinCupela Oct 25, 2024
4f8faec
style: fix lint issues
MartinCupela Oct 25, 2024
a2b7de1
Merge branch 'master' into feat/polls-rewrite
isekovanic Oct 28, 2024
7a506f3
chore: update from master and do PR remarks
isekovanic Oct 28, 2024
ec3f3bf
fix: lint issues
isekovanic Oct 30, 2024
b4082d8
fix: latest_answers resolution
isekovanic Oct 30, 2024
f1610eb
fix: linter errors
isekovanic Oct 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 2 additions & 25 deletions src/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1079,6 +1079,8 @@ export class Channel<StreamChatGenerics extends ExtendableGenerics = DefaultGene
}),
};

this.getClient().polls.hydratePollCache(messageSet.messages, true);

const areCapabilitiesChanged =
[...(state.channel.own_capabilities || [])].sort().join() !==
[...(Array.isArray(this.data?.own_capabilities) ? (this.data?.own_capabilities as string[]) : [])].sort().join();
Expand Down Expand Up @@ -1462,31 +1464,6 @@ export class Channel<StreamChatGenerics extends ExtendableGenerics = DefaultGene
};
}
break;
case 'poll.updated':
if (event.poll) {
channelState.updatePoll(event.poll, event.message?.id || '');
}
break;
case 'poll.vote_casted':
if (event.poll_vote && event.poll) {
channelState.addPollVote(event.poll_vote, event.poll, event.message?.id || '');
}
break;
case 'poll.vote_changed':
if (event.poll_vote && event.poll) {
channelState.updatePollVote(event.poll_vote, event.poll, event.message?.id || '');
}
break;
case 'poll.vote_removed':
if (event.poll_vote && event.poll) {
channelState.removePollVote(event.poll_vote, event.poll, event.message?.id || '');
}
break;
case 'poll.closed':
if (event.message) {
channelState.addMessageSorted(event.message, false, false);
}
break;
case 'reaction.new':
if (event.message && event.reaction) {
event.message = channelState.addReaction(event.reaction, event.message);
Expand Down
92 changes: 0 additions & 92 deletions src/channel_state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import {
MessageSet,
MessageSetType,
PendingMessageResponse,
PollResponse,
PollVote,
ReactionResponse,
UserResponse,
} from './types';
Expand Down Expand Up @@ -493,96 +491,6 @@ export class ChannelState<StreamChatGenerics extends ExtendableGenerics = Defaul
return { removed: result.length < msgArray.length, result };
};

// this handles the case when vote on poll is changed
updatePollVote = (
pollVote: PollVote<StreamChatGenerics>,
poll: PollResponse<StreamChatGenerics>,
messageId: string,
) => {
const message = this.findMessage(messageId);
if (!message) return;

if (message.poll_id !== pollVote.poll_id) return;

const updatedPoll = { ...poll };
let ownVotes = [...(message.poll?.own_votes || [])];

if (pollVote.user_id === this._channel.getClient().userID) {
if (pollVote.option_id && poll.enforce_unique_vote) {
// remove all previous votes where option_id is not empty
ownVotes = ownVotes.filter((vote) => !vote.option_id);
} else if (pollVote.answer_text) {
// remove all previous votes where option_id is empty
ownVotes = ownVotes.filter((vote) => vote.answer_text);
}

ownVotes.push(pollVote);
}

updatedPoll.own_votes = ownVotes as PollVote<StreamChatGenerics>[];
const newMessage = { ...message, poll: updatedPoll };

this.addMessageSorted((newMessage as unknown) as MessageResponse<StreamChatGenerics>, false, false);
};

addPollVote = (pollVote: PollVote<StreamChatGenerics>, poll: PollResponse<StreamChatGenerics>, messageId: string) => {
const message = this.findMessage(messageId);
if (!message) return;

if (message.poll_id !== pollVote.poll_id) return;

const updatedPoll = { ...poll };
const ownVotes = [...(message.poll?.own_votes || [])];

if (pollVote.user_id === this._channel.getClient().userID) {
ownVotes.push(pollVote);
}

updatedPoll.own_votes = ownVotes as PollVote<StreamChatGenerics>[];
const newMessage = { ...message, poll: updatedPoll };

this.addMessageSorted((newMessage as unknown) as MessageResponse<StreamChatGenerics>, false, false);
};

removePollVote = (
pollVote: PollVote<StreamChatGenerics>,
poll: PollResponse<StreamChatGenerics>,
messageId: string,
) => {
const message = this.findMessage(messageId);
if (!message) return;

if (message.poll_id !== pollVote.poll_id) return;

const updatedPoll = { ...poll };
const ownVotes = [...(message.poll?.own_votes || [])];
if (pollVote.user_id === this._channel.getClient().userID) {
const index = ownVotes.findIndex((vote) => vote.option_id === pollVote.option_id);
if (index > -1) {
ownVotes.splice(index, 1);
}
}

updatedPoll.own_votes = ownVotes as PollVote<StreamChatGenerics>[];

const newMessage = { ...message, poll: updatedPoll };
this.addMessageSorted((newMessage as unknown) as MessageResponse<StreamChatGenerics>, false, false);
};

updatePoll = (poll: PollResponse<StreamChatGenerics>, messageId: string) => {
const message = this.findMessage(messageId);
if (!message) return;

const updatedPoll = {
...poll,
own_votes: [...(message.poll?.own_votes || [])],
};

const newMessage = { ...message, poll: updatedPoll };

this.addMessageSorted((newMessage as unknown) as MessageResponse<StreamChatGenerics>, false, false);
};

/**
* Updates the message.user property with updated user object, for messages.
*
Expand Down
Loading
Loading