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-history): control polls inside local storage #14915

Merged
merged 1 commit into from
Jul 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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'];

/**
Calinteodor marked this conversation as resolved.
Show resolved Hide resolved
* 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