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 feature endpoints #1269

Merged
merged 41 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
6c933b2
feat: `createPoll`
totalimmersion Apr 18, 2023
46b2cbe
fix: fix create poll request
totalimmersion Apr 18, 2023
8714972
feat: create poll
totalimmersion Apr 19, 2023
cb1ead5
feat: create poll
totalimmersion Apr 19, 2023
7e4ede7
feat: getPoll and createPollOption
totalimmersion Apr 20, 2023
585c00b
feat: poll CRUD functions
totalimmersion Apr 21, 2023
eaf7fb5
feat: update poll and update poll option
totalimmersion Apr 21, 2023
2189f92
feat: add user_id for serverside call
totalimmersion Apr 25, 2023
192752b
feat: added voteOnPoll
totalimmersion Apr 27, 2023
6e0d5db
feat: changed poll request
totalimmersion Apr 27, 2023
2a1bbb5
feat: adding query votes method
totalimmersion May 4, 2023
d0c4dc9
wip
totalimmersion May 26, 2023
3c39cd8
Merge branch 'master' into feature/PBE-314_polls
totalimmersion May 26, 2023
f33a1eb
added voting_visibility
totalimmersion Jun 6, 2023
8a859e4
wip
totalimmersion Jun 15, 2023
7ecfd85
feat: poll improvement WIP
vishalnarkhede Sep 6, 2023
ced2291
wip: removeVote
totalimmersion Sep 15, 2023
06077e6
wip
totalimmersion Sep 15, 2023
07cd131
Merge branch 'master' into feature/PBE-314_polls
totalimmersion Sep 21, 2023
4c1819f
add polls channel config
totalimmersion Nov 7, 2023
f53694c
Merge branch 'master' into feature/PBE-314_polls
totalimmersion Nov 7, 2023
fd2cc54
Merge branch 'master' into feature/PBE-314_polls
totalimmersion Nov 21, 2023
ad455df
Merge branch 'master' into feature/PBE-314_polls
totalimmersion Mar 11, 2024
7fdb568
feat: getPoll optional user id
totalimmersion Mar 13, 2024
1366975
feat: changed query endpoints from get to post
totalimmersion Mar 14, 2024
1b87d06
Merge branch 'master' into feature/PBE-314_polls
totalimmersion Mar 14, 2024
5984d5e
fix: typescript and some methods
vishalnarkhede Mar 19, 2024
7c63393
refactor: drop poll from attachment
vishalnarkhede Mar 21, 2024
c189b33
Merge branch 'master' of github.com:GetStream/stream-chat-js into fea…
vishalnarkhede Mar 21, 2024
bffa361
Merge branch 'master' into feature/PBE-314_polls
kanat Mar 27, 2024
ae0bdd7
refactor: support prev/next pagination
kanat Mar 28, 2024
3ba598b
Merge branch 'master' into feature/PBE-314_polls
vishalnarkhede Apr 4, 2024
9c07921
refactor: polls endpoints
vishalnarkhede Apr 5, 2024
7f131bc
Merge branch 'feature/PBE-314_polls' of github.com:GetStream/stream-c…
vishalnarkhede Apr 5, 2024
3b70b11
refactor: cleanup around endpoint names
vishalnarkhede Apr 5, 2024
1bfedd8
refactor: change from comment to answer
vishalnarkhede Apr 9, 2024
006cc8c
refactor: add pollOptionType in generics
vishalnarkhede Apr 9, 2024
c29447a
refactor: lint fix
vishalnarkhede Apr 9, 2024
50f3c79
feat: (polls) support closePoll, add/fix missing fields (#1275)
kanat Apr 9, 2024
af41f70
refactor: lint fix
vishalnarkhede Apr 11, 2024
2896192
refactor: lint fixes
vishalnarkhede Apr 12, 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
40 changes: 40 additions & 0 deletions src/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import {
UserFilters,
UserResponse,
QueryChannelAPIResponse,
PollVoteData,
SendMessageOptions,
} from './types';
import { Role } from './permissions';
Expand Down Expand Up @@ -1158,6 +1159,20 @@ export class Channel<StreamChatGenerics extends ExtendableGenerics = DefaultGene
return await this.getClient().post<CreateCallResponse>(this._channelURL() + '/call', options);
}

/**
* Cast or cancel one or more votes on a poll
* @param pollId string The poll id
* @param votes PollVoteData[] The votes that will be casted (or canceled in case of an empty array)
* @returns {APIResponse & PollVoteResponse} The poll votes
*/
async vote(messageId: string, pollId: string, vote: PollVoteData) {
return await this.getClient().castPollVote(messageId, pollId, vote);
}

async removeVote(messageId: string, pollId: string, voteId: string) {
return await this.getClient().removePollVote(messageId, pollId, voteId);
}

/**
* on - Listen to events on this channel.
*
Expand Down Expand Up @@ -1401,6 +1416,31 @@ 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: 92 additions & 0 deletions src/channel_state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {
ReactionResponse,
UserResponse,
PendingMessageResponse,
PollVote,
PollResponse,
} from './types';
import { addToMessageList } from './utils';

Expand Down Expand Up @@ -486,6 +488,96 @@ 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