mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2025-02-17 08:31:23 -05:00
finished draft of intermediary refactor of addtostudio modal redux code, container-presentation code simplified
This commit is contained in:
parent
6a32edb2fe
commit
bc7b31e924
5 changed files with 118 additions and 175 deletions
|
@ -1,18 +1,3 @@
|
|||
// NOTE: next questions:
|
||||
// * what is the lifecycle of the getStudios etc. requests? Are they guaranteed to be there
|
||||
// on page load? Are they ever updated, e.g. after you join one?
|
||||
|
||||
// design decisions:
|
||||
// * we should treat "waiting" to mean, user has requested the modal to be closed;
|
||||
// that is, if you click ok and it's waiting for responses, then you click x,
|
||||
// it closes and sets waiting to false?
|
||||
// then in the checkForOutstandingUpdates function, we close the window
|
||||
// iff waiting is true.
|
||||
// that avoids the situation where you close the window while a request is
|
||||
// outstanding, then reopen it only to have it instantly close on you.
|
||||
// * keep the okay button, it sets up an overall spinner until everything is resolved
|
||||
// * but you can totally close the window regardless
|
||||
|
||||
// sample data:
|
||||
// this.studios = [{name: 'Funny games', id: 1}, {name: 'Silly ideas', id: 2}];
|
||||
// studios data is like:
|
||||
|
@ -30,10 +15,6 @@ const bindAll = require('lodash.bindall');
|
|||
const truncate = require('lodash.truncate');
|
||||
const PropTypes = require('prop-types');
|
||||
const React = require('react');
|
||||
const FormattedMessage = require('react-intl').FormattedMessage;
|
||||
const injectIntl = require('react-intl').injectIntl;
|
||||
const intlShape = require('react-intl').intlShape;
|
||||
const Modal = require('../base/modal.jsx');
|
||||
const log = require('../../../lib/log.js');
|
||||
|
||||
const Form = require('../../forms/form.jsx');
|
||||
|
@ -42,8 +23,8 @@ const Select = require('../../forms/select.jsx');
|
|||
const Spinner = require('../../spinner/spinner.jsx');
|
||||
const TextArea = require('../../forms/textarea.jsx');
|
||||
const FlexRow = require('../../flex-row/flex-row.jsx');
|
||||
const AddToStudioModalPresentation = require('presentation.jsx');
|
||||
const RequestStatus = require('').intlShape;
|
||||
const AddToStudioModalPresentation = require('./presentation.jsx');
|
||||
const previewActions = require('../../../redux/preview.js');
|
||||
|
||||
require('../../forms/button.scss');
|
||||
require('./modal.scss');
|
||||
|
@ -51,126 +32,61 @@ require('./modal.scss');
|
|||
class AddToStudioModal extends React.Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
bindAll(this, [ // NOTE: will need to add and bind callback fn to handle addind and removing studios
|
||||
'handleToggle',
|
||||
'handleRequestClose',
|
||||
bindAll(this, [
|
||||
'handleSubmit'
|
||||
]);
|
||||
|
||||
// NOTE: need to:
|
||||
// construct hash of inclusion status by id, populate it.
|
||||
// replace curatedStudios with list of studios ordered by
|
||||
// membership/stats/name. use that for rendering.
|
||||
this.state = {
|
||||
waitingToClose: false,
|
||||
studioState: {},
|
||||
waitingToClose: false
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.updateStudioState(this.props.projectStudios, this.props.curatedStudios);
|
||||
componentWillUpdate (prevProps) {
|
||||
checkIfFinishedUpdating();
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
this.updateStudioState(nextProps.projectStudios, nextProps.curatedStudios);
|
||||
hasOutstandingUpdates () {
|
||||
return (studios.some(studio => (studio.hasRequestOutstanding === true)));
|
||||
}
|
||||
|
||||
updateStudioState(projectStudios, curatedStudios) {
|
||||
// can't just use the spread operator here, because we may have
|
||||
// project studios removed from the list.
|
||||
// NOTE: This isn't handling the removal of a studio from the list well.
|
||||
|
||||
// can't build it from scratch, because needs transitional state
|
||||
let studioState = Object.assign({}, this.state.studioState);
|
||||
|
||||
// remove all states that are not in transition
|
||||
for (let id in studioState) {
|
||||
if (studioState[id] === AddToStudioModalPresentation.State.IN
|
||||
|| studioState[id] === AddToStudioModalPresentation.State.OUT) {
|
||||
delete studioState[id];
|
||||
}
|
||||
}
|
||||
// for all studios with no state, either because they weren't transitional
|
||||
// or they're new, start them with state OUT
|
||||
curatedStudios.forEach((curatedStudio) => {
|
||||
if (!(curatedStudio.id in studioState)) {
|
||||
studioState[curatedStudio.id] = AddToStudioModalPresentation.State.OUT
|
||||
}
|
||||
});
|
||||
// nests which all states to in for studios this project is in
|
||||
projectStudios.forEach((joinedStudio) => {
|
||||
studioState[joinedStudio.id] = AddToStudioModalPresentation.State.IN
|
||||
});
|
||||
// NOTE: do I really need this assign? I took it out
|
||||
this.setState({studioState: studioState});
|
||||
}
|
||||
|
||||
handleToggle(studioId) {
|
||||
if (studioId in this.state.studioState) {
|
||||
const studioState = this.state.studioState[studioId];
|
||||
// ignore clicks on studio buttons that are still waiting for response
|
||||
if (studioState === AddToStudioModalPresentation.State.IN) {
|
||||
this.props.onToggleStudio(studioId, false)
|
||||
} elseif (studioState === AddToStudioModalPresentation.State.OUT) {
|
||||
this.props.onToggleStudio(studioId, true)
|
||||
}
|
||||
} else {
|
||||
// NOTE: error
|
||||
checkIfFinishedUpdating () {
|
||||
if (waitingToClose === true && hasOutstandingUpdates() === false) {
|
||||
this.setState({waitingToClose: false}, () => {
|
||||
this.props.onRequestClose();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// we need to separately handle
|
||||
// server responses to our update requests,
|
||||
// and after each one, check to see if there are no outstanding updates
|
||||
// queued.
|
||||
checkForOutstandingUpdates () {
|
||||
const updateQueued = this.state.updateQueued;
|
||||
if (Object.keys(updateQueued).length == 0) {
|
||||
setTimeout(function() {
|
||||
this.setState({waitingToClose: false}, () => {
|
||||
this.handleRequestClose();
|
||||
});
|
||||
}.bind(this), 3000);
|
||||
}
|
||||
}
|
||||
|
||||
handleRequestClose () {
|
||||
// NOTE that we do NOT clear joined, so we don't lose
|
||||
// user's work from a stray click outside the modal...
|
||||
// but maybe this should be different?
|
||||
this.baseModal.handleRequestClose();
|
||||
}
|
||||
handleSubmit (formData) {
|
||||
// NOTE:For this approach to work, we need to separately handle
|
||||
// server responses to our update requests,
|
||||
// and after each one, check to see if there are no outstanding updates
|
||||
// queued.
|
||||
this.setState({waitingToClose: true}, () => {
|
||||
this.checkForOutstandingUpdates();
|
||||
this.checkIfFinishedUpdating();
|
||||
});
|
||||
}
|
||||
|
||||
render () {
|
||||
const {
|
||||
curatedStudios,
|
||||
isOpen,
|
||||
studios,
|
||||
onToggleStudio,
|
||||
onRequestClose
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<AddToStudioModalPresentation
|
||||
studios={curatedStudios}
|
||||
studioState={this.state.studioState}
|
||||
studios={studios}
|
||||
isOpen={isOpen}
|
||||
onToggleStudio={handleToggle}
|
||||
onToggleStudio={onToggleStudio}
|
||||
onSubmit={handleSubmit}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
AddToStudioModal.propTypes = {
|
||||
projectStudios: PropTypes.arrayOf(PropTypes.object),
|
||||
curatedStudios: PropTypes.arrayOf(PropTypes.object),
|
||||
studioRequests: PropTypes.object,
|
||||
isOpen: PropTypes.bool,
|
||||
studios: PropTypes.arrayOf(PropTypes.object),
|
||||
onToggleStudio: PropTypes.func,
|
||||
onRequestClose: PropTypes.func
|
||||
};
|
||||
|
||||
module.exports = AddToStudioModalPresentation;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
const keyMirror = require('keymirror');
|
||||
const bindAll = require('lodash.bindall');
|
||||
const truncate = require('lodash.truncate');
|
||||
const PropTypes = require('prop-types');
|
||||
|
@ -19,39 +18,24 @@ const FlexRow = require('../../flex-row/flex-row.jsx');
|
|||
require('../../forms/button.scss');
|
||||
require('./modal.scss');
|
||||
|
||||
module.exports.State = keyMirror({
|
||||
IN: null,
|
||||
OUT: null,
|
||||
JOINING: null,
|
||||
LEAVING: null
|
||||
});
|
||||
|
||||
class AddToStudioModalPresentation extends React.Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
bindAll(this, [ // NOTE: will need to add and bind callback fn to handle addind and removing studios
|
||||
'handleRequestClose',
|
||||
bindAll(this, [
|
||||
'handleSubmit'
|
||||
]);
|
||||
|
||||
// NOTE: need to:
|
||||
// construct hash of inclusion status by id, populate it.
|
||||
// replace curatedStudios with list of studios ordered by
|
||||
// membership/stats/name. use that for rendering.
|
||||
this.state = {
|
||||
waitingToClose: false,
|
||||
studios: props.studios
|
||||
};
|
||||
}
|
||||
|
||||
handleRequestClose () {
|
||||
this.baseModal.handleRequestClose();
|
||||
}
|
||||
handleSubmit (formData) {
|
||||
this.props.handleSubmit(formData);
|
||||
this.props.onSubmit(formData);
|
||||
}
|
||||
|
||||
render () {
|
||||
// NOTE: how does intl get injected?
|
||||
const {
|
||||
intl,
|
||||
studios,
|
||||
|
@ -68,29 +52,24 @@ class AddToStudioModalPresentation extends React.Component {
|
|||
src="/svgs/modal/add.svg"
|
||||
/>
|
||||
const studioButtons = studios.map((studio, index) => {
|
||||
const thisStudioState = studioState[studio.id];
|
||||
return (
|
||||
<div className={"studio-selector-button " +
|
||||
(thisStudioState === module.exports.State.JOINING ||
|
||||
thisStudioState === module.exports.State.LEAVING) ?
|
||||
"studio-selector-button-waiting" :
|
||||
(thisStudioState === module.exports.State.IN ? "studio-selector-button-selected" : ""))}
|
||||
(studio.hasRequestOutstanding ? "studio-selector-button-waiting" :
|
||||
(studio.includesProject ? "studio-selector-button-selected" : ""))}
|
||||
key={studio.id}
|
||||
onClick={() => this.props.onToggleStudio(studio.id)}
|
||||
>
|
||||
<div className={"studio-selector-button-text " +
|
||||
(thisStudioState === module.exports.State.OUT ?
|
||||
"studio-selector-button-text-unselected" :
|
||||
".studio-selector-button-text-selected")}>
|
||||
(studio.includesProject ? "studio-selector-button-text-selected" :
|
||||
"studio-selector-button-text-unselected")}>
|
||||
{truncate(studio.title, {'length': 20, 'separator': /[,:\.;]*\s+/})}
|
||||
</div>
|
||||
<div className={"studio-status-icon " +
|
||||
(thisStudioState === module.exports.State.OUT ? "studio-status-icon-unselected" : "")}
|
||||
(studio.includesProject ? "" : "studio-status-icon-unselected")}
|
||||
>
|
||||
{(thisStudioState === module.exports.State.JOINING ||
|
||||
thisStudioState === module.exports.State.LEAVING) ?
|
||||
{(studio.hasRequestOutstanding ?
|
||||
(<Spinner type="smooth" />) :
|
||||
(thisStudioState === module.exports.State.IN ? checkmark : plus)}
|
||||
(studio.includesProject ? checkmark : plus))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -100,9 +79,6 @@ class AddToStudioModalPresentation extends React.Component {
|
|||
<Modal
|
||||
className="mod-addToStudio"
|
||||
contentLabel={contentLabel}
|
||||
ref={component => { // bind to base modal, to pass handleRequestClose through
|
||||
this.baseModal = component;
|
||||
}}
|
||||
onRequestClose={this.props.onRequestClose}
|
||||
isOpen={isOpen}
|
||||
>
|
||||
|
@ -131,7 +107,7 @@ class AddToStudioModalPresentation extends React.Component {
|
|||
<FlexRow className="action-buttons">
|
||||
<Button
|
||||
className="action-button close-button white"
|
||||
onClick={this.handleRequestClose}
|
||||
onClick={this.props.onRequestClose}
|
||||
key="closeButton"
|
||||
name="closeButton"
|
||||
type="button"
|
||||
|
@ -177,7 +153,8 @@ AddToStudioModalPresentation.propTypes = {
|
|||
intl: intlShape,
|
||||
studios: PropTypes.arrayOf(PropTypes.object),
|
||||
onAddToStudio: PropTypes.func,
|
||||
onRequestClose: PropTypes.func
|
||||
onRequestClose: PropTypes.func,
|
||||
onSubmit: PropTypes.func
|
||||
};
|
||||
|
||||
module.exports = injectIntl(AddToStudioModalPresentation);
|
||||
|
|
|
@ -31,7 +31,7 @@ module.exports.getInitialState = () => ({
|
|||
original: {},
|
||||
parent: {},
|
||||
projectStudios: [],
|
||||
curatedStudios: [],
|
||||
curatedStudios: []
|
||||
});
|
||||
|
||||
module.exports.previewReducer = (state, action) => {
|
||||
|
@ -64,6 +64,17 @@ module.exports.previewReducer = (state, action) => {
|
|||
return Object.assign({}, state, {
|
||||
curatedStudios: action.items
|
||||
});
|
||||
case 'ADD_TO_PROJECT_STUDIOS':
|
||||
return Object.assign({}, state, {
|
||||
// NOTE: move this to calling fn, make this add object passed to me
|
||||
projectStudios: state.projectStudios.concat({id: action.studioId})
|
||||
});
|
||||
case 'REMOVE_FROM_PROJECT_STUDIOS':
|
||||
return Object.assign({}, state, {
|
||||
projectStudios: state.projectStudios.filter(studio => (
|
||||
studio.id !== action.studioId
|
||||
))
|
||||
});
|
||||
case 'SET_COMMENTS':
|
||||
return Object.assign({}, state, {
|
||||
comments: action.items
|
||||
|
@ -137,7 +148,15 @@ module.exports.setCuratedStudios = items => ({
|
|||
items: items
|
||||
});
|
||||
|
||||
// NOTE: unclear to me what kind of Delta to do to what data when add and leave commands come back
|
||||
module.exports.addToProjectStudios = studioId => ({
|
||||
type: 'ADD_TO_PROJECT_STUDIOS',
|
||||
studioId: studioId
|
||||
});
|
||||
|
||||
module.exports.removeFromProjectStudios = studioId => ({
|
||||
type: 'REMOVE_FROM_PROJECT_STUDIOS',
|
||||
studioId: studioId
|
||||
});
|
||||
|
||||
module.exports.setFetchStatus = (type, status) => ({
|
||||
type: 'SET_FETCH_STATUS',
|
||||
|
@ -405,6 +424,7 @@ module.exports.getCuratedStudios = (username, token) => (dispatch => {
|
|||
});
|
||||
|
||||
module.exports.addToStudio = (studioId, projectId, token) => (dispatch => {
|
||||
dispatch(module.exports.setStudioFetchStatus(studioId, module.exports.Status.FETCHING));
|
||||
api({
|
||||
uri: `/studios/${studioId}/project/${projectId}`,
|
||||
authentication: token,
|
||||
|
@ -419,11 +439,15 @@ module.exports.addToStudio = (studioId, projectId, token) => (dispatch => {
|
|||
return;
|
||||
}
|
||||
dispatch(module.exports.setStudioFetchStatus(studioId, module.exports.Status.FETCHED));
|
||||
// NOTE: is there a way here to update or refresh the project studio list?
|
||||
// action: add studio to list
|
||||
// NOTE: what is the content of the body in the response to this request?
|
||||
// should we pass the rich object to addToProjectStudios ?
|
||||
dispatch(module.exports.addToProjectStudios(studioId));
|
||||
});
|
||||
});
|
||||
|
||||
module.exports.leaveStudio = (studioId, projectId, token) => (dispatch => {
|
||||
dispatch(module.exports.setStudioFetchStatus(studioId, module.exports.Status.FETCHING));
|
||||
api({
|
||||
uri: `/studios/${studioId}/project/${projectId}`,
|
||||
authentication: token,
|
||||
|
@ -438,7 +462,7 @@ module.exports.leaveStudio = (studioId, projectId, token) => (dispatch => {
|
|||
return;
|
||||
}
|
||||
dispatch(module.exports.setStudioFetchStatus(studioId, module.exports.Status.FETCHED));
|
||||
// NOTE: is there a way here to update or refresh the project studio list?
|
||||
dispatch(module.exports.removeFromProjectStudios(studioId));
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -221,7 +221,6 @@ class PreviewPresentation extends React.Component {
|
|||
sessionStatus,
|
||||
projectStudios,
|
||||
curatedStudios,
|
||||
studioRequests,
|
||||
onToggleStudio,
|
||||
user,
|
||||
onFavoriteClicked,
|
||||
|
@ -474,9 +473,7 @@ class PreviewPresentation extends React.Component {
|
|||
<AddToStudioModal
|
||||
isOpen={this.state.addToStudioOpen}
|
||||
key="add-to-studio-modal"
|
||||
projectStudios={projectStudios}
|
||||
curatedStudios={this.mockedMyStudios}
|
||||
studioRequests={studioRequests}
|
||||
studios={curatedStudios}
|
||||
onToggleStudio={onToggleStudio}
|
||||
onRequestClose={this.handleAddToStudioClose}
|
||||
/>
|
||||
|
@ -592,7 +589,6 @@ PreviewPresentation.propTypes = {
|
|||
sessionStatus: PropTypes.string.isRequired,
|
||||
projectStudios: PropTypes.arrayOf(PropTypes.object),
|
||||
curatedStudios: PropTypes.arrayOf(PropTypes.object),
|
||||
studioRequests: PropTypes.object,
|
||||
onToggleStudio: PropTypes.func,
|
||||
user: PropTypes.shape({
|
||||
id: PropTypes.number,
|
||||
|
|
|
@ -23,6 +23,7 @@ class Preview extends React.Component {
|
|||
super(props);
|
||||
bindAll(this, [
|
||||
'addEventListeners',
|
||||
'handleToggleStudio',
|
||||
'handleFavoriteToggle',
|
||||
'handleLoveToggle',
|
||||
'handlePermissions',
|
||||
|
@ -127,19 +128,12 @@ class Preview extends React.Component {
|
|||
}
|
||||
}
|
||||
handleToggleStudio (studioId, isAdd) {
|
||||
if (isAdd === true) {
|
||||
this.props.addToStudio(
|
||||
studioId,
|
||||
this.props.projectInfo.id,
|
||||
this.props.user.token
|
||||
);
|
||||
} else {
|
||||
this.props.leaveStudio(
|
||||
studioId,
|
||||
this.props.projectInfo.id,
|
||||
this.props.user.token
|
||||
);
|
||||
}
|
||||
this.props.toggleStudio(
|
||||
isAdd,
|
||||
studioId,
|
||||
this.props.projectInfo.id,
|
||||
this.props.user.token
|
||||
);
|
||||
}
|
||||
handleFavoriteToggle () {
|
||||
this.props.setFavedStatus(
|
||||
|
@ -218,7 +212,6 @@ class Preview extends React.Component {
|
|||
sessionStatus={this.props.sessionStatus}
|
||||
projectStudios={this.props.projectStudios}
|
||||
curatedStudios={this.props.curatedStudios}
|
||||
studioRequests={this.props.studioRequests}
|
||||
onToggleStudio={this.handleToggleStudio}
|
||||
user={this.props.user}
|
||||
onFavoriteClicked={this.handleFavoriteToggle}
|
||||
|
@ -249,6 +242,7 @@ Preview.propTypes = {
|
|||
getRemixes: PropTypes.func.isRequired,
|
||||
getProjectStudios: PropTypes.func.isRequired,
|
||||
getCuratedStudios: PropTypes.func.isRequired,
|
||||
toggleStudio: PropTypes.func.isRequired,
|
||||
loved: PropTypes.bool,
|
||||
original: projectShape,
|
||||
parent: projectShape,
|
||||
|
@ -262,7 +256,6 @@ Preview.propTypes = {
|
|||
setPlayer: PropTypes.func.isRequired,
|
||||
projectStudios: PropTypes.arrayOf(PropTypes.object),
|
||||
curatedStudios: PropTypes.arrayOf(PropTypes.object),
|
||||
studioRequests: PropTypes.object,
|
||||
updateProject: PropTypes.func.isRequired,
|
||||
user: PropTypes.shape({
|
||||
id: PropTypes.number,
|
||||
|
@ -281,6 +274,42 @@ Preview.defaultProps = {
|
|||
user: {}
|
||||
};
|
||||
|
||||
// Build consolidated curatedStudios object from all studio info.
|
||||
// We add data to curatedStudios so it knows which of the studios the
|
||||
// project belongs to, and the status of requests to join/leave studios.
|
||||
function consolidateStudiosInfo (curatedStudios, projectStudios, studioRequests) {
|
||||
let studios = [];
|
||||
let projectStudiosFoundInCurated = {}; // temp, for time complexity
|
||||
|
||||
// copy curated studios, updating any that are also in other data structures
|
||||
curatedStudios.forEach((curatedStudio) => {
|
||||
let studioCopy = Object.assign({}, curatedStudio,
|
||||
{includesProject: false, hasRequestOutstanding: false});
|
||||
projectStudios.forEach((projectStudio) => {
|
||||
if (curatedStudio.id === projectStudio.id) {
|
||||
studioCopy.includesProject = true;
|
||||
projectStudiosFoundInCurated[projectStudio.id] = true;
|
||||
}
|
||||
});
|
||||
// set studio state to leaving or joining if it's being fetched
|
||||
if (studioCopy.id in status.studioRequests) {
|
||||
const request = status.studioRequests[studioId];
|
||||
studioCopy.hasRequestOutstanding = (request === preview.Status.FETCHING);
|
||||
}
|
||||
studios.push(studioCopy);
|
||||
});
|
||||
// if there are any other studios this project is in that are NOT in the list
|
||||
// of studios this user curates, like public studios, add to front of list
|
||||
projectStudios.forEach((projectStudio) => {
|
||||
if (!(projectStudio.id in projectStudiosFoundInCurated)) {
|
||||
studios.unshift(Object.assign({}, projectStudio,
|
||||
{includesProject: true, hasRequestOutstanding: false}
|
||||
));
|
||||
}
|
||||
});
|
||||
return studios;
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
projectInfo: state.preview.projectInfo,
|
||||
comments: state.preview.comments,
|
||||
|
@ -291,8 +320,8 @@ const mapStateToProps = state => ({
|
|||
remixes: state.preview.remixes,
|
||||
sessionStatus: state.session.status,
|
||||
projectStudios: state.preview.projectStudios,
|
||||
curatedStudios: state.preview.curatedStudios,
|
||||
studioRequests: state.preview.status.studioRequests,
|
||||
curatedStudios: consolidateStudiosInfo(state.preview.curatedStudios,
|
||||
state.preview.projectStudios, state.preview.status.studioRequests),
|
||||
user: state.session.session.user,
|
||||
playerMode: state.scratchGui.mode.isPlayerOnly,
|
||||
fullScreen: state.scratchGui.mode.isFullScreen
|
||||
|
@ -318,11 +347,12 @@ const mapDispatchToProps = dispatch => ({
|
|||
getCuratedStudios: (username, token) => {
|
||||
dispatch(previewActions.getCuratedStudios(username, token));
|
||||
},
|
||||
addToStudio: (studioId, id, token) => {
|
||||
dispatch(previewActions.addToStudio(studioId, id, token));
|
||||
},
|
||||
leaveStudio: (studioId, id, token) => {
|
||||
dispatch(previewActions.leaveStudio(studioId, id, token));
|
||||
toggleStudio: (isAdd, studioId, id, token) => {
|
||||
if (isAdd === true) {
|
||||
dispatch(previewActions.addToStudio(studioId, id, token));
|
||||
} else {
|
||||
dispatch(previewActions.leaveStudio(studioId, id, token));
|
||||
}
|
||||
},
|
||||
getFavedStatus: (id, username, token) => {
|
||||
dispatch(previewActions.getFavedStatus(id, username, token));
|
||||
|
|
Loading…
Reference in a new issue