fedibird-fe/app/javascript/mastodon/actions/circles.js
noellabo a27fcf5e30 Add feature circle
Squashed commit of the following:

commit 7b2ba61c4841e23081552fb79270e4e430dd1fe0
Author: noellabo <noel.yoshiba@gmail.com>
Date:   Sat Sep 5 16:03:52 2020 +0900

    Add the ability to change to a new circle by replying to a circle

commit 7013a228c65c7bd147885de458b50095f3c24334
Author: noellabo <noel.yoshiba@gmail.com>
Date:   Sat Sep 5 16:10:57 2020 +0900

    fixup! add-limited-visibility-icon-to-status

commit 679aa8a7f9bef42ee5d0b326d9ae4925a1999939
Author: noellabo <noel.yoshiba@gmail.com>
Date:   Sat Sep 5 15:12:53 2020 +0900

    Fix 14666

commit b3addd8220d8bb3512ff345b32ca83c714dadd2a
Author: noellabo <noel.yoshiba@gmail.com>
Date:   Sat Sep 5 11:44:12 2020 +0900

    Add Japanese translation for circle

commit b7f4b773a0cd554084d5ad6a5923adb06b3acfc4
Author: noellabo <noel.yoshiba@gmail.com>
Date:   Sat Sep 5 11:40:12 2020 +0900

    Squashed commit of the following:

    commit b85a4685b27c49462288aba5f38723b91e936c4a
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Sat Sep 5 10:50:03 2020 +0900

        Changed to remove restrictions on privacy options and allow users to switch circles when replying

    commit 0a8c0140c73d7c5333e4f8017964adb5061a7cf1
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Sat Sep 5 09:33:07 2020 +0900

        Change limited visibility icon

    commit b64adf19788d828249408454ec6afa9beb3d4872
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Mon Aug 31 06:50:56 2020 +0900

        Fix a change to limited-visibility-bearcaps replies

    commit ed361405b5e38857a2f42b0515a599ddcdd412cf
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Thu Aug 27 15:53:18 2020 +0900

        Fix composer text when change visibility

    commit 4da3adddb6ffde43070d743e34c5b56e06579b30
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Sat Aug 22 22:34:23 2020 +0900

        Fix wrong circle_id when changing visibility

    commit 752d7fc2a3c9e34fab9993d767f83c6eae7ba55a
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Sun Aug 9 13:12:51 2020 +0900

        Add circle reply and redraft

    commit 5978bc04a24695edce6717bda89dcf6f861ef2c4
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Mon Jul 27 01:07:52 2020 +0900

        Fix remove unused props

    commit 7970f69676c24b4aa9385fee8b1635c46ba52fcd
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Sun Jul 26 21:17:07 2020 +0900

        Separate circle choice from privacy

    commit 36f6a684c0b0c895d4d0f1b9d09b05c91b104666
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Thu Jul 23 10:54:25 2020 +0900

        Add UI for posting to circles

    commit 7ef48003c1407275663dd603b124d292db2aa93a
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Fri Jul 24 12:55:10 2020 +0900

        Fix silent mention by circle

commit 7a1caed49333c3d3241301afb77639cdf1cabdc0
Author: noellabo <noel.yoshiba@gmail.com>
Date:   Sat Sep 5 11:38:10 2020 +0900

    Squashed commit of the following:

    commit dca71fab86c830932ca760b7d8b3f89cc25c453e
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Sat Sep 5 09:31:26 2020 +0900

        Revert "Add focus setting when opening the circle column"

        This reverts commit 3a93ac99312a13b68b7edc2b81313fb0ffb7bcdc.

    commit 0a1bc8307bb699c7eb3024072ce14a440df1fc87
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Sat Sep 5 09:31:11 2020 +0900

        Change limited visibility icon

    commit 9784f8b562f6592e9d9190ca29d2b2e870006d10
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Thu Aug 13 21:52:07 2020 +0900

        Add focus setting when opening the circle column

    commit a84f680c167fab9276550850c60f9108d251144e
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Thu Aug 13 15:55:27 2020 +0900

        Fix message

    commit e3f11c4adac57b6e6a15c981ed6f4721a1634212
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Mon Jul 27 01:01:23 2020 +0900

        Fix light-theme

    commit d7d96eda5b86d3e3f654ce79888e7cf5aa535db5
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Sun Jul 26 21:50:56 2020 +0900

        Fix circles loading in share page and followers search

    commit 10b821f7b8c0a87cea3df51f09deeadc2cb40b32
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Fri Jul 24 14:08:00 2020 +0900

        Refactor list items

    commit e020072915572ce409039ccf799d08f8d8b5b393
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Thu Jul 23 20:15:38 2020 +0900

        Fixed a bug that circle name change is not reflected in the list

    commit 735bc41161b4c09a8dafe2c0064096b3ca79f2a0
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Wed Jul 22 08:49:47 2020 +0900

        Add UI for managing circle members

    commit d7c3145b8fa84be0631bf7f41bb229f3e6d03ff1
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Wed Jul 22 07:34:52 2020 +0900

        Add the followers option to AccountSearchSercive

    commit 65e2b0c4299b72ede440b50089c1bd6afa6c9c05
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Wed Jul 22 07:05:56 2020 +0900

        Add CircleSerializer

commit a639e1803abf5590068846dbe98bc5edfaa2ad82
Author: noellabo <noel.yoshiba@gmail.com>
Date:   Sat Sep 5 11:37:30 2020 +0900

    Squashed commit of the following:

    commit 9cb3fb9d980e3ee066083076f508c5ab1447176a
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Sat Sep 5 07:15:19 2020 +0900

        Move the link to the mention list to the menu

    commit b32dd87b43f4e09b8e2c437f1fb5d3ebd6221215
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Sat Sep 5 00:56:12 2020 +0900

        Change limited visibility icon

    commit 8db0d024119d1c2cef8de849f2501496a166a2dd
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Tue Sep 1 01:42:13 2020 +0900

        Fix to disallow getting the list of mentions in limited replies

    commit 490a9d65a59a3dd0d86e81f6780e879dc4313dff
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Fri Jul 24 11:36:24 2020 +0900

        Add column to list mentioned accounts of limited status

    commit 62a423ac2729c16f26fafe111f257bc373218df2
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Thu Jul 23 13:30:17 2020 +0900

        Fix visibility compatibility more

    commit a5cfa54b259054f41e89037f299fa928a2361818
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Mon Jul 20 05:39:49 2020 +0900

        Fix visibility compatibility

    commit 7900ca5650c77565b86ddc594a221dfa3b5321b4
    Author: noellabo <noel.yoshiba@gmail.com>
    Date:   Mon Jul 20 02:01:27 2020 +0900

        Add limited visibility icon to status

commit 66b83965ef068e9ee8c940249c68bcbde15731fe
Author: Eugen Rochko <eugen@zeonfederated.com>
Date:   Wed Aug 26 03:16:47 2020 +0200

    Add conversation-based forwarding for limited visibility statuses through bearcaps

commit 561abc65e0ace89318b3952047025b8d98515fbb
Author: Eugen Rochko <eugen@zeonfederated.com>
Date:   Sun Jul 19 02:05:16 2020 +0200

    Add REST API for managing and posting to circles

    Circles are the conceptual opposite of lists. A list is a subdivision
    of your follows, a circle is a subdivision of your followers. Posting
    to a circle means making content available to only some of your
    followers. Circles have been internally supported in Mastodon for
    the purposes of federation since #8950, this adds the REST API
    necessary for making use of them in Mastodon itsef.
2022-05-11 00:48:02 +09:00

372 lines
11 KiB
JavaScript

import api from '../api';
import { importFetchedAccounts } from './importer';
import { showAlertForError } from './alerts';
export const CIRCLE_FETCH_REQUEST = 'CIRCLE_FETCH_REQUEST';
export const CIRCLE_FETCH_SUCCESS = 'CIRCLE_FETCH_SUCCESS';
export const CIRCLE_FETCH_FAIL = 'CIRCLE_FETCH_FAIL';
export const CIRCLES_FETCH_REQUEST = 'CIRCLES_FETCH_REQUEST';
export const CIRCLES_FETCH_SUCCESS = 'CIRCLES_FETCH_SUCCESS';
export const CIRCLES_FETCH_FAIL = 'CIRCLES_FETCH_FAIL';
export const CIRCLE_EDITOR_TITLE_CHANGE = 'CIRCLE_EDITOR_TITLE_CHANGE';
export const CIRCLE_EDITOR_RESET = 'CIRCLE_EDITOR_RESET';
export const CIRCLE_EDITOR_SETUP = 'CIRCLE_EDITOR_SETUP';
export const CIRCLE_CREATE_REQUEST = 'CIRCLE_CREATE_REQUEST';
export const CIRCLE_CREATE_SUCCESS = 'CIRCLE_CREATE_SUCCESS';
export const CIRCLE_CREATE_FAIL = 'CIRCLE_CREATE_FAIL';
export const CIRCLE_UPDATE_REQUEST = 'CIRCLE_UPDATE_REQUEST';
export const CIRCLE_UPDATE_SUCCESS = 'CIRCLE_UPDATE_SUCCESS';
export const CIRCLE_UPDATE_FAIL = 'CIRCLE_UPDATE_FAIL';
export const CIRCLE_DELETE_REQUEST = 'CIRCLE_DELETE_REQUEST';
export const CIRCLE_DELETE_SUCCESS = 'CIRCLE_DELETE_SUCCESS';
export const CIRCLE_DELETE_FAIL = 'CIRCLE_DELETE_FAIL';
export const CIRCLE_ACCOUNTS_FETCH_REQUEST = 'CIRCLE_ACCOUNTS_FETCH_REQUEST';
export const CIRCLE_ACCOUNTS_FETCH_SUCCESS = 'CIRCLE_ACCOUNTS_FETCH_SUCCESS';
export const CIRCLE_ACCOUNTS_FETCH_FAIL = 'CIRCLE_ACCOUNTS_FETCH_FAIL';
export const CIRCLE_EDITOR_SUGGESTIONS_CHANGE = 'CIRCLE_EDITOR_SUGGESTIONS_CHANGE';
export const CIRCLE_EDITOR_SUGGESTIONS_READY = 'CIRCLE_EDITOR_SUGGESTIONS_READY';
export const CIRCLE_EDITOR_SUGGESTIONS_CLEAR = 'CIRCLE_EDITOR_SUGGESTIONS_CLEAR';
export const CIRCLE_EDITOR_ADD_REQUEST = 'CIRCLE_EDITOR_ADD_REQUEST';
export const CIRCLE_EDITOR_ADD_SUCCESS = 'CIRCLE_EDITOR_ADD_SUCCESS';
export const CIRCLE_EDITOR_ADD_FAIL = 'CIRCLE_EDITOR_ADD_FAIL';
export const CIRCLE_EDITOR_REMOVE_REQUEST = 'CIRCLE_EDITOR_REMOVE_REQUEST';
export const CIRCLE_EDITOR_REMOVE_SUCCESS = 'CIRCLE_EDITOR_REMOVE_SUCCESS';
export const CIRCLE_EDITOR_REMOVE_FAIL = 'CIRCLE_EDITOR_REMOVE_FAIL';
export const CIRCLE_ADDER_RESET = 'CIRCLE_ADDER_RESET';
export const CIRCLE_ADDER_SETUP = 'CIRCLE_ADDER_SETUP';
export const CIRCLE_ADDER_CIRCLES_FETCH_REQUEST = 'CIRCLE_ADDER_CIRCLES_FETCH_REQUEST';
export const CIRCLE_ADDER_CIRCLES_FETCH_SUCCESS = 'CIRCLE_ADDER_CIRCLES_FETCH_SUCCESS';
export const CIRCLE_ADDER_CIRCLES_FETCH_FAIL = 'CIRCLE_ADDER_CIRCLES_FETCH_FAIL';
export const fetchCircle = id => (dispatch, getState) => {
if (getState().getIn(['circles', id])) {
return;
}
dispatch(fetchCircleRequest(id));
api(getState).get(`/api/v1/circles/${id}`)
.then(({ data }) => dispatch(fetchCircleSuccess(data)))
.catch(err => dispatch(fetchCircleFail(id, err)));
};
export const fetchCircleRequest = id => ({
type: CIRCLE_FETCH_REQUEST,
id,
});
export const fetchCircleSuccess = circle => ({
type: CIRCLE_FETCH_SUCCESS,
circle,
});
export const fetchCircleFail = (id, error) => ({
type: CIRCLE_FETCH_FAIL,
id,
error,
});
export const fetchCircles = () => (dispatch, getState) => {
dispatch(fetchCirclesRequest());
api(getState).get('/api/v1/circles')
.then(({ data }) => dispatch(fetchCirclesSuccess(data)))
.catch(err => dispatch(fetchCirclesFail(err)));
};
export const fetchCirclesRequest = () => ({
type: CIRCLES_FETCH_REQUEST,
});
export const fetchCirclesSuccess = circles => ({
type: CIRCLES_FETCH_SUCCESS,
circles,
});
export const fetchCirclesFail = error => ({
type: CIRCLES_FETCH_FAIL,
error,
});
export const submitCircleEditor = shouldReset => (dispatch, getState) => {
const circleId = getState().getIn(['circleEditor', 'circleId']);
const title = getState().getIn(['circleEditor', 'title']);
if (circleId === null) {
dispatch(createCircle(title, shouldReset));
} else {
dispatch(updateCircle(circleId, title, shouldReset));
}
};
export const setupCircleEditor = circleId => (dispatch, getState) => {
dispatch({
type: CIRCLE_EDITOR_SETUP,
circle: getState().getIn(['circles', circleId]),
});
dispatch(fetchCircleAccounts(circleId));
};
export const changeCircleEditorTitle = value => ({
type: CIRCLE_EDITOR_TITLE_CHANGE,
value,
});
export const createCircle = (title, shouldReset) => (dispatch, getState) => {
dispatch(createCircleRequest());
api(getState).post('/api/v1/circles', { title }).then(({ data }) => {
dispatch(createCircleSuccess(data));
if (shouldReset) {
dispatch(resetCircleEditor());
}
}).catch(err => dispatch(createCircleFail(err)));
};
export const createCircleRequest = () => ({
type: CIRCLE_CREATE_REQUEST,
});
export const createCircleSuccess = circle => ({
type: CIRCLE_CREATE_SUCCESS,
circle,
});
export const createCircleFail = error => ({
type: CIRCLE_CREATE_FAIL,
error,
});
export const updateCircle = (id, title, shouldReset) => (dispatch, getState) => {
dispatch(updateCircleRequest(id));
api(getState).put(`/api/v1/circles/${id}`, { title }).then(({ data }) => {
dispatch(updateCircleSuccess(data));
if (shouldReset) {
dispatch(resetCircleEditor());
}
}).catch(err => dispatch(updateCircleFail(id, err)));
};
export const updateCircleRequest = id => ({
type: CIRCLE_UPDATE_REQUEST,
id,
});
export const updateCircleSuccess = circle => ({
type: CIRCLE_UPDATE_SUCCESS,
circle,
});
export const updateCircleFail = (id, error) => ({
type: CIRCLE_UPDATE_FAIL,
id,
error,
});
export const resetCircleEditor = () => ({
type: CIRCLE_EDITOR_RESET,
});
export const deleteCircle = id => (dispatch, getState) => {
dispatch(deleteCircleRequest(id));
api(getState).delete(`/api/v1/circles/${id}`)
.then(() => dispatch(deleteCircleSuccess(id)))
.catch(err => dispatch(deleteCircleFail(id, err)));
};
export const deleteCircleRequest = id => ({
type: CIRCLE_DELETE_REQUEST,
id,
});
export const deleteCircleSuccess = id => ({
type: CIRCLE_DELETE_SUCCESS,
id,
});
export const deleteCircleFail = (id, error) => ({
type: CIRCLE_DELETE_FAIL,
id,
error,
});
export const fetchCircleAccounts = circleId => (dispatch, getState) => {
dispatch(fetchCircleAccountsRequest(circleId));
api(getState).get(`/api/v1/circles/${circleId}/accounts`, { params: { limit: 0 } }).then(({ data }) => {
dispatch(importFetchedAccounts(data));
dispatch(fetchCircleAccountsSuccess(circleId, data));
}).catch(err => dispatch(fetchCircleAccountsFail(circleId, err)));
};
export const fetchCircleAccountsRequest = id => ({
type: CIRCLE_ACCOUNTS_FETCH_REQUEST,
id,
});
export const fetchCircleAccountsSuccess = (id, accounts, next) => ({
type: CIRCLE_ACCOUNTS_FETCH_SUCCESS,
id,
accounts,
next,
});
export const fetchCircleAccountsFail = (id, error) => ({
type: CIRCLE_ACCOUNTS_FETCH_FAIL,
id,
error,
});
export const fetchCircleSuggestions = q => (dispatch, getState) => {
const params = {
q,
resolve: false,
limit: 4,
followers: true,
};
api(getState).get('/api/v1/accounts/search', { params }).then(({ data }) => {
dispatch(importFetchedAccounts(data));
dispatch(fetchCircleSuggestionsReady(q, data));
}).catch(error => dispatch(showAlertForError(error)));
};
export const fetchCircleSuggestionsReady = (query, accounts) => ({
type: CIRCLE_EDITOR_SUGGESTIONS_READY,
query,
accounts,
});
export const clearCircleSuggestions = () => ({
type: CIRCLE_EDITOR_SUGGESTIONS_CLEAR,
});
export const changeCircleSuggestions = value => ({
type: CIRCLE_EDITOR_SUGGESTIONS_CHANGE,
value,
});
export const addToCircleEditor = accountId => (dispatch, getState) => {
dispatch(addToCircle(getState().getIn(['circleEditor', 'circleId']), accountId));
};
export const addToCircle = (circleId, accountId) => (dispatch, getState) => {
dispatch(addToCircleRequest(circleId, accountId));
api(getState).post(`/api/v1/circles/${circleId}/accounts`, { account_ids: [accountId] })
.then(() => dispatch(addToCircleSuccess(circleId, accountId)))
.catch(err => dispatch(addToCircleFail(circleId, accountId, err)));
};
export const addToCircleRequest = (circleId, accountId) => ({
type: CIRCLE_EDITOR_ADD_REQUEST,
circleId,
accountId,
});
export const addToCircleSuccess = (circleId, accountId) => ({
type: CIRCLE_EDITOR_ADD_SUCCESS,
circleId,
accountId,
});
export const addToCircleFail = (circleId, accountId, error) => ({
type: CIRCLE_EDITOR_ADD_FAIL,
circleId,
accountId,
error,
});
export const removeFromCircleEditor = accountId => (dispatch, getState) => {
dispatch(removeFromCircle(getState().getIn(['circleEditor', 'circleId']), accountId));
};
export const removeFromCircle = (circleId, accountId) => (dispatch, getState) => {
dispatch(removeFromCircleRequest(circleId, accountId));
api(getState).delete(`/api/v1/circles/${circleId}/accounts`, { params: { account_ids: [accountId] } })
.then(() => dispatch(removeFromCircleSuccess(circleId, accountId)))
.catch(err => dispatch(removeFromCircleFail(circleId, accountId, err)));
};
export const removeFromCircleRequest = (circleId, accountId) => ({
type: CIRCLE_EDITOR_REMOVE_REQUEST,
circleId,
accountId,
});
export const removeFromCircleSuccess = (circleId, accountId) => ({
type: CIRCLE_EDITOR_REMOVE_SUCCESS,
circleId,
accountId,
});
export const removeFromCircleFail = (circleId, accountId, error) => ({
type: CIRCLE_EDITOR_REMOVE_FAIL,
circleId,
accountId,
error,
});
export const resetCircleAdder = () => ({
type: CIRCLE_ADDER_RESET,
});
export const setupCircleAdder = accountId => (dispatch, getState) => {
dispatch({
type: CIRCLE_ADDER_SETUP,
account: getState().getIn(['accounts', accountId]),
});
dispatch(fetchCircles());
dispatch(fetchAccountCircles(accountId));
};
export const fetchAccountCircles = accountId => (dispatch, getState) => {
dispatch(fetchAccountCirclesRequest(accountId));
api(getState).get(`/api/v1/accounts/${accountId}/circles`)
.then(({ data }) => dispatch(fetchAccountCirclesSuccess(accountId, data)))
.catch(err => dispatch(fetchAccountCirclesFail(accountId, err)));
};
export const fetchAccountCirclesRequest = id => ({
type:CIRCLE_ADDER_CIRCLES_FETCH_REQUEST,
id,
});
export const fetchAccountCirclesSuccess = (id, circles) => ({
type: CIRCLE_ADDER_CIRCLES_FETCH_SUCCESS,
id,
circles,
});
export const fetchAccountCirclesFail = (id, err) => ({
type: CIRCLE_ADDER_CIRCLES_FETCH_FAIL,
id,
err,
});
export const addToCircleAdder = circleId => (dispatch, getState) => {
dispatch(addToCircle(circleId, getState().getIn(['circleAdder', 'accountId'])));
};
export const removeFromCircleAdder = circleId => (dispatch, getState) => {
dispatch(removeFromCircle(circleId, getState().getIn(['circleAdder', 'accountId'])));
};