Skip to content

Commit

Permalink
feat(polls-history): control polls through local storage
Browse files Browse the repository at this point in the history
  • Loading branch information
Calinteodor committed Jul 26, 2024
1 parent 2514617 commit 60b4581
Show file tree
Hide file tree
Showing 20 changed files with 313 additions and 100 deletions.
1 change: 1 addition & 0 deletions lang/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,7 @@
"submit": "Submit"
},
"by": "By {{ name }}",
"closeButton": "Close poll",
"create": {
"addOption": "Add option",
"answerPlaceholder": "Option {{index}}",
Expand Down
1 change: 1 addition & 0 deletions react/features/app/middlewares.any.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import '../notifications/middleware';
import '../overlay/middleware';
import '../participants-pane/middleware';
import '../polls/middleware';
import '../polls-history/middleware';
import '../reactions/middleware';
import '../recent-list/middleware';
import '../recording/middleware';
Expand Down
1 change: 1 addition & 0 deletions react/features/app/reducers.any.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import '../notifications/reducer';
import '../overlay/reducer';
import '../participants-pane/reducer';
import '../polls/reducer';
import '../polls-history/reducer';
import '../reactions/reducer';
import '../recent-list/reducer';
import '../recording/reducer';
Expand Down
2 changes: 2 additions & 0 deletions react/features/app/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import { INotificationsState } from '../notifications/reducer';
import { IOverlayState } from '../overlay/reducer';
import { IParticipantsPaneState } from '../participants-pane/reducer';
import { IPollsState } from '../polls/reducer';
import { IPollsHistoryState } from '../polls-history/reducer';
import { IPowerMonitorState } from '../power-monitor/reducer';
import { IPrejoinState } from '../prejoin/reducer';
import { IReactionsState } from '../reactions/reducer';
Expand Down Expand Up @@ -149,6 +150,7 @@ export interface IReduxState {
'features/overlay': IOverlayState;
'features/participants-pane': IParticipantsPaneState;
'features/polls': IPollsState;
'features/polls-history': IPollsHistoryState;
'features/power-monitor': IPowerMonitorState;
'features/prejoin': IPrejoinState;
'features/reactions': IReactionsState;
Expand Down
8 changes: 0 additions & 8 deletions react/features/base/conference/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,6 @@ import { IJitsiConference } from './reducer';
*/
export const getConferenceState = (state: IReduxState) => state['features/base/conference'];

/**
* Is the conference joined or not.
*
* @param {IReduxState} state - Global state.
* @returns {boolean}
*/
export const getIsConferenceJoined = (state: IReduxState) => Boolean(getConferenceState(state).conference);

/**
* Attach a set of local tracks to a conference.
*
Expand Down
23 changes: 23 additions & 0 deletions react/features/polls-history/actionTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* The type of the action which signals that we need to remove poll from the history(local storage).
*
* {
* type: REMOVE_POLL_FROM_HISTORY,
* meetingId: string,
* pollId: string,
* poll: IPoll
* }
*/
export const REMOVE_POLL_FROM_HISTORY = 'REMOVE_POLL_FROM_HISTORY';

/**
* The type of the action triggered when the poll is saved in history(local storage).
*
* {
* type: SAVE_POLL_IN_HISTORY,
* poll: Poll,
* pollId: string,
* saved: boolean
* }
*/
export const SAVE_POLL_IN_HISTORY = 'SAVE_POLL_IN_HISTORY';
47 changes: 47 additions & 0 deletions react/features/polls-history/actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { IPoll } from '../polls/types';

import { REMOVE_POLL_FROM_HISTORY, SAVE_POLL_IN_HISTORY } from './actionTypes';

/**
* Action to signal saving a poll in history(local storage).
*
* @param {string} meetingId - The id of the meeting in which polls get to be saved.
* @param {string} pollId - The id of the poll that gets to be saved.
* @param {IPoll} poll - The Poll object that gets to be saved.
* @returns {{
* type: SAVE_POLL_IN_HISTORY,
* meetingId: string,
* pollId: string,
* poll: IPoll
* }}
*/
export function savePollInHistory(meetingId: string | undefined, pollId: string, poll: IPoll) {
return {
type: SAVE_POLL_IN_HISTORY,
meetingId,
pollId,
poll
};
}

/**
* Action to signal that existing poll needs to be deleted from history(local storage).
*
* @param {string} meetingId - The id of the meeting in which poll gets to be removed.
* @param {string} pollId - The id of the poll that gets to be removed.
* @param {IPoll} poll - The incoming IPoll object.
* @returns {{
* type: REMOVE_POLL_FROM_HISTORY,
* meetingId: string,
* pollId: string,
* poll: IPoll
* }}
*/
export const removePollFromHistory = (meetingId: string | undefined, pollId: string, poll: IPoll) => {
return {
type: REMOVE_POLL_FROM_HISTORY,
meetingId,
pollId,
poll
};
};
46 changes: 46 additions & 0 deletions react/features/polls-history/middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { CONFERENCE_JOINED } from '../base/conference/actionTypes';
import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
import { REMOVE_POLL, SAVE_POLL } from '../polls/actionTypes';
import { savePoll } from '../polls/actions';

import { removePollFromHistory, savePollInHistory } from './actions';

MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
const result = next(action);
const { room: meetingId } = getState()['features/base/conference'];

switch (action.type) {

case CONFERENCE_JOINED: {
const state = getState();
const pollsHistory = meetingId && state['features/polls-history'].polls?.[meetingId];

if (!pollsHistory) {
return null;
}

for (const key in pollsHistory) {
if (pollsHistory.hasOwnProperty(key) && pollsHistory[key].saved) {
dispatch(savePoll(key, pollsHistory[key]));
}
}
break;
}

case REMOVE_POLL: {
const { poll, pollId } = action;

dispatch(removePollFromHistory(meetingId, pollId, poll));
break;
}

case SAVE_POLL: {
const { poll, pollId } = action;

dispatch(savePollInHistory(meetingId, pollId, poll));
break;
}
}

return result;
});
52 changes: 52 additions & 0 deletions react/features/polls-history/reducer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import PersistenceRegistry from '../base/redux/PersistenceRegistry';
import ReducerRegistry from '../base/redux/ReducerRegistry';
import { IPoll } from '../polls/types';

import { REMOVE_POLL_FROM_HISTORY, SAVE_POLL_IN_HISTORY } from './actionTypes';

const INITIAL_STATE = {
polls: {}
};

export interface IPollsHistoryState {
polls: {
[meetingId: string]: {
[pollId: string]: IPoll;
};
};
}

const STORE_NAME = 'features/polls-history';

PersistenceRegistry.register(STORE_NAME, INITIAL_STATE);

ReducerRegistry.register<IPollsHistoryState>(STORE_NAME, (state = INITIAL_STATE, action): IPollsHistoryState => {
switch (action.type) {

case REMOVE_POLL_FROM_HISTORY: {
if (Object.keys(state.polls[action.meetingId] ?? {})?.length === 1) {
delete state.polls[action.meetingId];
} else {
delete state.polls[action.meetingId]?.[action.pollId];
}

return state;
}

case SAVE_POLL_IN_HISTORY: {
return {
...state,
polls: {
...state.polls,
[action.meetingId]: {
...state.polls[action.meetingId],
[action.pollId]: action.poll
}
}
};
}

default:
return state;
}
});
9 changes: 5 additions & 4 deletions react/features/polls/actionTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const CHANGE_VOTE = 'CHANGE_VOTE';

/**
* The type of the action which signals that we need to clear all polls from the state.
* For example we are moving to another conference.
* For example, we are moving to another conference.
*
* {
* type: CLEAR_POLLS
Expand Down Expand Up @@ -65,14 +65,15 @@ export const RECEIVE_ANSWER = 'RECEIVE_ANSWER';
export const REGISTER_VOTE = 'REGISTER_VOTE';

/**
* The type of the action which retracts a vote.
* The type of the action which signals that we need to remove poll.
*
* {
* type: RETRACT_VOTE,
* type: REMOVE_POLL,
* pollId: string,
* poll: IPoll
* }
*/
export const RETRACT_VOTE = 'RETRACT_VOTE';
export const REMOVE_POLL = 'REMOVE_POLL';

/**
* The type of the action triggered when the poll tab in chat pane is closed
Expand Down
Loading

0 comments on commit 60b4581

Please sign in to comment.