Add reaction deck remove api

This commit is contained in:
KMY 2023-05-26 18:53:55 +09:00
parent 1cf9bb24d7
commit c4efa4d986
6 changed files with 76 additions and 12 deletions

View file

@ -4,10 +4,10 @@ class Api::V1::ReactionDeckController < Api::BaseController
include RoutingHelper
before_action -> { doorkeeper_authorize! :read, :'read:lists' }, only: [:index]
before_action -> { doorkeeper_authorize! :write, :'write:lists' }, only: [:create]
before_action -> { doorkeeper_authorize! :write, :'write:lists' }, only: [:create, :remove]
before_action :require_user!
before_action :set_deck, only: [:index, :create]
before_action :set_deck, only: [:index, :create, :remove]
rescue_from ArgumentError do |e|
render json: { error: e.to_s }, status: 422
@ -50,6 +50,14 @@ class Api::V1::ReactionDeckController < Api::BaseController
render json: remove_metas(deck)
end
def remove
deck = @deck.filter { |item| deck_params['emojis'].none? { |d| d['id'] == item['id'] } }
current_user.settings['reaction_deck'] = deck.to_json
current_user.save!
render json: remove_metas(deck)
end
private
def set_deck

View file

@ -8,6 +8,10 @@ export const REACTION_DECK_UPDATE_REQUEST = 'REACTION_DECK_UPDATE_REQUEST';
export const REACTION_DECK_UPDATE_SUCCESS = 'REACTION_DECK_UPDATE_SUCCESS';
export const REACTION_DECK_UPDATE_FAIL = 'REACTION_DECK_UPDATE_FAIL';
export const REACTION_DECK_REMOVE_REQUEST = 'REACTION_DECK_REMOVE_REQUEST';
export const REACTION_DECK_REMOVE_SUCCESS = 'REACTION_DECK_REMOVE_SUCCESS';
export const REACTION_DECK_REMOVE_FAIL = 'REACTION_DECK_REMOVE_FAIL';
export function fetchReactionDeck() {
return (dispatch, getState) => {
dispatch(fetchReactionDeckRequest());
@ -77,3 +81,38 @@ export function updateReactionDeckFail(error) {
skipLoading: true,
};
}
export function removeReactionDeck(id) {
return (dispatch, getState) => {
dispatch(removeReactionDeckRequest());
api(getState).post('/api/v1/remove_reaction_deck', { emojis: [{ id }] }).then(response => {
dispatch(removeReactionDeckSuccess(response.data));
}).catch(error => {
dispatch(removeReactionDeckFail(error));
});
};
}
export function removeReactionDeckRequest() {
return {
type: REACTION_DECK_REMOVE_REQUEST,
skipLoading: true,
};
}
export function removeReactionDeckSuccess(emojis) {
return {
type: REACTION_DECK_REMOVE_SUCCESS,
emojis,
skipLoading: true,
};
}
export function removeReactionDeckFail(error) {
return {
type: REACTION_DECK_REMOVE_FAIL,
error,
skipLoading: true,
};
}

View file

@ -1,17 +1,22 @@
import PropTypes from 'prop-types';
import { injectIntl } from 'react-intl';
import { defineMessages, injectIntl } from 'react-intl';
import { List as ImmutableList, Map as ImmutableMap } from 'immutable';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { connect } from 'react-redux';
import { updateReactionDeck } from 'mastodon/actions/reaction_deck';
import { updateReactionDeck, removeReactionDeck } from 'mastodon/actions/reaction_deck';
import Button from 'mastodon/components/button';
import EmojiPickerDropdownContainer from 'mastodon/features/compose/containers/emoji_picker_dropdown_container';
import emojify from 'mastodon/features/emoji/emoji';
import { autoPlayGif } from 'mastodon/initial_state';
const messages = defineMessages({
remove: { id: 'reaction_deck.remove', defaultMessage: 'Remove' },
});
const MapStateToProps = (state, { emojiId, emojiMap }) => ({
emoji: (state.get('reaction_deck', ImmutableList()).toArray().find(em => em.get('id') === emojiId) || ImmutableMap({ emoji: { shortcode: '' } })).get('name'),
emojiMap,
@ -19,6 +24,7 @@ const MapStateToProps = (state, { emojiId, emojiMap }) => ({
const mapDispatchToProps = (dispatch, { emojiId }) => ({
onChange: (emoji) => dispatch(updateReactionDeck(emojiId, emoji)),
onRemove: () => dispatch(removeReactionDeck(emojiId)),
});
class ReactionEmoji extends ImmutablePureComponent {
@ -27,6 +33,7 @@ class ReactionEmoji extends ImmutablePureComponent {
emoji: PropTypes.string,
emojiMap: ImmutablePropTypes.map.isRequired,
onChange: PropTypes.func.isRequired,
onRemove: PropTypes.func.isRequired,
};
static defaultProps = {
@ -34,7 +41,7 @@ class ReactionEmoji extends ImmutablePureComponent {
};
render () {
const { emojiMap, emoji, onChange } = this.props;
const { intl, emojiMap, emoji, onChange, onRemove } = this.props;
let content = null;
@ -61,11 +68,16 @@ class ReactionEmoji extends ImmutablePureComponent {
return (
<div className='reaction_deck__emoji'>
<div className='reaction_deck__emoji__wrapper'>
<div className='reaction_deck__emoji__wrapper__content'>
<EmojiPickerDropdownContainer onPickEmoji={onChange} />
<div>
{content}
</div>
</div>
<div className='reaction_deck__emoji__wrapper__options'>
<Button secondary text={intl.formatMessage(messages.remove)} onClick={onRemove} />
</div>
</div>
</div>
);
}

View file

@ -1,11 +1,11 @@
import { List as ImmutableList, fromJS as ConvertToImmutable } from 'immutable';
import { REACTION_DECK_FETCH_SUCCESS, REACTION_DECK_UPDATE_SUCCESS } from '../actions/reaction_deck';
import { REACTION_DECK_FETCH_SUCCESS, REACTION_DECK_UPDATE_SUCCESS, REACTION_DECK_REMOVE_SUCCESS } from '../actions/reaction_deck';
const initialState = ImmutableList([]);
export default function reaction_deck(state = initialState, action) {
if(action.type === REACTION_DECK_FETCH_SUCCESS || action.type === REACTION_DECK_UPDATE_SUCCESS) {
if(action.type === REACTION_DECK_FETCH_SUCCESS || action.type === REACTION_DECK_UPDATE_SUCCESS || action.type === REACTION_DECK_REMOVE_SUCCESS) {
state = ConvertToImmutable(action.emojis);
}

View file

@ -7547,8 +7547,7 @@ noscript {
.reaction_deck__emoji {
&__wrapper {
display: flex;
margin: 8px 4px;
margin: 8px 16px 8px 4px;
height: 32px;
.emojione {
@ -7561,6 +7560,11 @@ noscript {
margin-right: 24px;
padding: 0;
}
&__content {
display: flex;
flex: 1;
}
}
}

View file

@ -55,6 +55,7 @@ namespace :api, format: false do
resources :custom_emojis, only: [:index]
resources :reaction_deck, only: [:index, :create]
post :remove_reaction_deck, to: 'reaction_deck#remove'
resources :suggestions, only: [:index, :destroy]
resources :scheduled_statuses, only: [:index, :show, :update, :destroy]
resources :preferences, only: [:index]