Merge branch 'bugfix/122' into 'develop'
Composer: Don't force scope change after settings save, fixes #122 Closes #122 See merge request soapbox-pub/soapbox-fe!76
This commit is contained in:
commit
7e1457bb8d
|
@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [Unreleased patch]
|
||||||
|
### Fixed
|
||||||
|
- Composer: Forcing the scope to default after settings save.
|
||||||
|
|
||||||
## [1.0.0] - 2020-06-15
|
## [1.0.0] - 2020-06-15
|
||||||
### Added
|
### Added
|
||||||
- Emoji reactions.
|
- Emoji reactions.
|
||||||
|
@ -43,5 +49,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
### Added
|
### Added
|
||||||
- Initial beta release.
|
- Initial beta release.
|
||||||
|
|
||||||
|
[Unreleased]: https://gitlab.com/soapbox-pub/soapbox-fe/-/compare/v1.0.0...develop
|
||||||
|
[Unreleased patch]: https://gitlab.com/soapbox-pub/soapbox-fe/-/compare/v1.0.0...stable/1.0.x
|
||||||
[1.0.0]: https://gitlab.com/soapbox-pub/soapbox-fe/-/compare/v0.9.0...v1.0.0
|
[1.0.0]: https://gitlab.com/soapbox-pub/soapbox-fe/-/compare/v0.9.0...v1.0.0
|
||||||
[0.9.0]: https://gitlab.com/soapbox-pub/soapbox-fe/-/tags/v0.9.0
|
[0.9.0]: https://gitlab.com/soapbox-pub/soapbox-fe/-/tags/v0.9.0
|
||||||
|
|
|
@ -7,6 +7,7 @@ export const ME_FETCH_FAIL = 'ME_FETCH_FAIL';
|
||||||
export const ME_FETCH_SKIP = 'ME_FETCH_SKIP';
|
export const ME_FETCH_SKIP = 'ME_FETCH_SKIP';
|
||||||
|
|
||||||
export const ME_PATCH_REQUEST = 'ME_PATCH_REQUEST';
|
export const ME_PATCH_REQUEST = 'ME_PATCH_REQUEST';
|
||||||
|
export const ME_PATCH_SUCCESS = 'ME_PATCH_SUCCESS';
|
||||||
export const ME_PATCH_FAIL = 'ME_PATCH_FAIL';
|
export const ME_PATCH_FAIL = 'ME_PATCH_FAIL';
|
||||||
|
|
||||||
const hasToken = getState => getState().hasIn(['auth', 'user', 'access_token']);
|
const hasToken = getState => getState().hasIn(['auth', 'user', 'access_token']);
|
||||||
|
@ -35,7 +36,7 @@ export function patchMe(params) {
|
||||||
return api(getState)
|
return api(getState)
|
||||||
.patch('/api/v1/accounts/update_credentials', params)
|
.patch('/api/v1/accounts/update_credentials', params)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
dispatch(fetchMeSuccess(response.data));
|
dispatch(patchMeSuccess(response.data));
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
dispatch(patchMeFail(error));
|
dispatch(patchMeFail(error));
|
||||||
});
|
});
|
||||||
|
@ -72,6 +73,16 @@ export function patchMeRequest() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function patchMeSuccess(me) {
|
||||||
|
return (dispatch, getState) => {
|
||||||
|
dispatch(importFetchedAccount(me));
|
||||||
|
dispatch({
|
||||||
|
type: ME_PATCH_SUCCESS,
|
||||||
|
me,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function patchMeFail(error) {
|
export function patchMeFail(error) {
|
||||||
return {
|
return {
|
||||||
type: ME_PATCH_FAIL,
|
type: ME_PATCH_FAIL,
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
import reducer from '../compose';
|
import reducer from '../compose';
|
||||||
|
import { Map as ImmutableMap } from 'immutable';
|
||||||
|
import { COMPOSE_REPLY } from 'soapbox/actions/compose';
|
||||||
|
import { ME_FETCH_SUCCESS, ME_PATCH_SUCCESS } from 'soapbox/actions/me';
|
||||||
|
import { SETTING_CHANGE } from 'soapbox/actions/settings';
|
||||||
|
|
||||||
describe('compose reducer', () => {
|
describe('compose reducer', () => {
|
||||||
it('should return the initial state', () => {
|
it('returns the initial state by default', () => {
|
||||||
expect(reducer(undefined, {}).toJS()).toMatchObject({
|
expect(reducer(undefined, {}).toJS()).toMatchObject({
|
||||||
mounted: 0,
|
mounted: 0,
|
||||||
sensitive: false,
|
sensitive: false,
|
||||||
|
@ -27,4 +31,100 @@ describe('compose reducer', () => {
|
||||||
tagHistory: [],
|
tagHistory: [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('uses \'public\' scope as default', () => {
|
||||||
|
const action = {
|
||||||
|
type: COMPOSE_REPLY,
|
||||||
|
status: ImmutableMap(),
|
||||||
|
account: ImmutableMap(),
|
||||||
|
};
|
||||||
|
expect(reducer(undefined, action).toJS()).toMatchObject({ privacy: 'public' });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('uses \'direct\' scope when replying to a DM', () => {
|
||||||
|
const state = ImmutableMap({ default_privacy: 'public' });
|
||||||
|
const action = {
|
||||||
|
type: COMPOSE_REPLY,
|
||||||
|
status: ImmutableMap({ visibility: 'direct' }),
|
||||||
|
account: ImmutableMap(),
|
||||||
|
};
|
||||||
|
expect(reducer(state, action).toJS()).toMatchObject({ privacy: 'direct' });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('uses \'private\' scope when replying to a private post', () => {
|
||||||
|
const state = ImmutableMap({ default_privacy: 'public' });
|
||||||
|
const action = {
|
||||||
|
type: COMPOSE_REPLY,
|
||||||
|
status: ImmutableMap({ visibility: 'private' }),
|
||||||
|
account: ImmutableMap(),
|
||||||
|
};
|
||||||
|
expect(reducer(state, action).toJS()).toMatchObject({ privacy: 'private' });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('uses \'unlisted\' scope when replying to an unlisted post', () => {
|
||||||
|
const state = ImmutableMap({ default_privacy: 'public' });
|
||||||
|
const action = {
|
||||||
|
type: COMPOSE_REPLY,
|
||||||
|
status: ImmutableMap({ visibility: 'unlisted' }),
|
||||||
|
account: ImmutableMap(),
|
||||||
|
};
|
||||||
|
expect(reducer(state, action).toJS()).toMatchObject({ privacy: 'unlisted' });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('uses \'private\' scope when set as preference and replying to a public post', () => {
|
||||||
|
const state = ImmutableMap({ default_privacy: 'private' });
|
||||||
|
const action = {
|
||||||
|
type: COMPOSE_REPLY,
|
||||||
|
status: ImmutableMap({ visibility: 'public' }),
|
||||||
|
account: ImmutableMap(),
|
||||||
|
};
|
||||||
|
expect(reducer(state, action).toJS()).toMatchObject({ privacy: 'private' });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('uses \'unlisted\' scope when set as preference and replying to a public post', () => {
|
||||||
|
const state = ImmutableMap({ default_privacy: 'unlisted' });
|
||||||
|
const action = {
|
||||||
|
type: COMPOSE_REPLY,
|
||||||
|
status: ImmutableMap({ visibility: 'public' }),
|
||||||
|
account: ImmutableMap(),
|
||||||
|
};
|
||||||
|
expect(reducer(state, action).toJS()).toMatchObject({ privacy: 'unlisted' });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sets preferred scope on user login', () => {
|
||||||
|
const state = ImmutableMap({ default_privacy: 'public' });
|
||||||
|
const action = {
|
||||||
|
type: ME_FETCH_SUCCESS,
|
||||||
|
me: { pleroma: { settings_store: { soapbox_fe: { defaultPrivacy: 'unlisted' } } } },
|
||||||
|
};
|
||||||
|
expect(reducer(state, action).toJS()).toMatchObject({
|
||||||
|
default_privacy: 'unlisted',
|
||||||
|
privacy: 'unlisted',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sets preferred scope on settings change', () => {
|
||||||
|
const state = ImmutableMap({ default_privacy: 'public' });
|
||||||
|
const action = {
|
||||||
|
type: SETTING_CHANGE,
|
||||||
|
path: ['defaultPrivacy'],
|
||||||
|
value: 'unlisted',
|
||||||
|
};
|
||||||
|
expect(reducer(state, action).toJS()).toMatchObject({
|
||||||
|
default_privacy: 'unlisted',
|
||||||
|
privacy: 'unlisted',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sets default scope on settings save (but retains current scope)', () => {
|
||||||
|
const state = ImmutableMap({ default_privacy: 'public', privacy: 'public' });
|
||||||
|
const action = {
|
||||||
|
type: ME_PATCH_SUCCESS,
|
||||||
|
me: { pleroma: { settings_store: { soapbox_fe: { defaultPrivacy: 'unlisted' } } } },
|
||||||
|
};
|
||||||
|
expect(reducer(state, action).toJS()).toMatchObject({
|
||||||
|
default_privacy: 'unlisted',
|
||||||
|
privacy: 'public',
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -39,7 +39,7 @@ import {
|
||||||
import { TIMELINE_DELETE } from '../actions/timelines';
|
import { TIMELINE_DELETE } from '../actions/timelines';
|
||||||
import { STORE_HYDRATE } from '../actions/store';
|
import { STORE_HYDRATE } from '../actions/store';
|
||||||
import { REDRAFT } from '../actions/statuses';
|
import { REDRAFT } from '../actions/statuses';
|
||||||
import { ME_FETCH_SUCCESS } from '../actions/me';
|
import { ME_FETCH_SUCCESS, ME_PATCH_SUCCESS } from '../actions/me';
|
||||||
import { SETTING_CHANGE, FE_NAME } from '../actions/settings';
|
import { SETTING_CHANGE, FE_NAME } from '../actions/settings';
|
||||||
import { Map as ImmutableMap, List as ImmutableList, OrderedSet as ImmutableOrderedSet, fromJS } from 'immutable';
|
import { Map as ImmutableMap, List as ImmutableList, OrderedSet as ImmutableOrderedSet, fromJS } from 'immutable';
|
||||||
import uuid from '../uuid';
|
import uuid from '../uuid';
|
||||||
|
@ -199,6 +199,7 @@ const expandMentions = status => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function compose(state = initialState, action) {
|
export default function compose(state = initialState, action) {
|
||||||
|
let me, defaultPrivacy;
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
case STORE_HYDRATE:
|
case STORE_HYDRATE:
|
||||||
return hydrate(state, action.state.get('compose'));
|
return hydrate(state, action.state.get('compose'));
|
||||||
|
@ -249,7 +250,7 @@ export default function compose(state = initialState, action) {
|
||||||
map.set('caretPosition', null);
|
map.set('caretPosition', null);
|
||||||
map.set('idempotencyKey', uuid());
|
map.set('idempotencyKey', uuid());
|
||||||
|
|
||||||
if (action.status.get('spoiler_text').length > 0) {
|
if (action.status.get('spoiler_text', '').length > 0) {
|
||||||
map.set('spoiler', true);
|
map.set('spoiler', true);
|
||||||
map.set('spoiler_text', action.status.get('spoiler_text'));
|
map.set('spoiler_text', action.status.get('spoiler_text'));
|
||||||
} else {
|
} else {
|
||||||
|
@ -361,10 +362,15 @@ export default function compose(state = initialState, action) {
|
||||||
case COMPOSE_POLL_SETTINGS_CHANGE:
|
case COMPOSE_POLL_SETTINGS_CHANGE:
|
||||||
return state.update('poll', poll => poll.set('expires_in', action.expiresIn).set('multiple', action.isMultiple));
|
return state.update('poll', poll => poll.set('expires_in', action.expiresIn).set('multiple', action.isMultiple));
|
||||||
case ME_FETCH_SUCCESS:
|
case ME_FETCH_SUCCESS:
|
||||||
const me = fromJS(action.me);
|
me = fromJS(action.me);
|
||||||
const defaultPrivacy = me.getIn(['pleroma', 'settings_store', FE_NAME, 'defaultPrivacy']);
|
defaultPrivacy = me.getIn(['pleroma', 'settings_store', FE_NAME, 'defaultPrivacy']);
|
||||||
if (!defaultPrivacy) return state;
|
if (!defaultPrivacy) return state;
|
||||||
return state.set('default_privacy', defaultPrivacy).set('privacy', defaultPrivacy);
|
return state.set('default_privacy', defaultPrivacy).set('privacy', defaultPrivacy);
|
||||||
|
case ME_PATCH_SUCCESS:
|
||||||
|
me = fromJS(action.me);
|
||||||
|
defaultPrivacy = me.getIn(['pleroma', 'settings_store', FE_NAME, 'defaultPrivacy']);
|
||||||
|
if (!defaultPrivacy) return state;
|
||||||
|
return state.set('default_privacy', defaultPrivacy);
|
||||||
case SETTING_CHANGE:
|
case SETTING_CHANGE:
|
||||||
const pathString = action.path.join(',');
|
const pathString = action.path.join(',');
|
||||||
if (pathString === 'defaultPrivacy')
|
if (pathString === 'defaultPrivacy')
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
import { ME_FETCH_SUCCESS, ME_FETCH_FAIL, ME_FETCH_SKIP } from '../actions/me';
|
import {
|
||||||
|
ME_FETCH_SUCCESS,
|
||||||
|
ME_FETCH_FAIL,
|
||||||
|
ME_FETCH_SKIP,
|
||||||
|
ME_PATCH_SUCCESS,
|
||||||
|
} from '../actions/me';
|
||||||
import { AUTH_LOGGED_OUT } from '../actions/auth';
|
import { AUTH_LOGGED_OUT } from '../actions/auth';
|
||||||
|
|
||||||
const initialState = null;
|
const initialState = null;
|
||||||
|
@ -6,6 +11,7 @@ const initialState = null;
|
||||||
export default function me(state = initialState, action) {
|
export default function me(state = initialState, action) {
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
case ME_FETCH_SUCCESS:
|
case ME_FETCH_SUCCESS:
|
||||||
|
case ME_PATCH_SUCCESS:
|
||||||
return action.me.id;
|
return action.me.id;
|
||||||
case ME_FETCH_FAIL:
|
case ME_FETCH_FAIL:
|
||||||
case ME_FETCH_SKIP:
|
case ME_FETCH_SKIP:
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { STORE_HYDRATE } from '../actions/store';
|
import { STORE_HYDRATE } from '../actions/store';
|
||||||
import { ME_FETCH_SUCCESS } from 'soapbox/actions/me';
|
import { ME_FETCH_SUCCESS, ME_PATCH_SUCCESS } from 'soapbox/actions/me';
|
||||||
import { Map as ImmutableMap, fromJS } from 'immutable';
|
import { Map as ImmutableMap, fromJS } from 'immutable';
|
||||||
|
|
||||||
const initialState = ImmutableMap();
|
const initialState = ImmutableMap();
|
||||||
|
@ -11,6 +11,7 @@ export default function meta(state = initialState, action) {
|
||||||
case STORE_HYDRATE:
|
case STORE_HYDRATE:
|
||||||
return state.merge(action.state.get('meta'));
|
return state.merge(action.state.get('meta'));
|
||||||
case ME_FETCH_SUCCESS:
|
case ME_FETCH_SUCCESS:
|
||||||
|
case ME_PATCH_SUCCESS:
|
||||||
const me = fromJS(action.me);
|
const me = fromJS(action.me);
|
||||||
if (me.has('pleroma')) {
|
if (me.has('pleroma')) {
|
||||||
const pleroPrefs = me.get('pleroma').delete('settings_store');
|
const pleroPrefs = me.get('pleroma').delete('settings_store');
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { NOTIFICATIONS_FILTER_SET } from '../actions/notifications';
|
||||||
import { STORE_HYDRATE } from '../actions/store';
|
import { STORE_HYDRATE } from '../actions/store';
|
||||||
import { EMOJI_USE } from '../actions/emojis';
|
import { EMOJI_USE } from '../actions/emojis';
|
||||||
import { LIST_DELETE_SUCCESS, LIST_FETCH_FAIL } from '../actions/lists';
|
import { LIST_DELETE_SUCCESS, LIST_FETCH_FAIL } from '../actions/lists';
|
||||||
import { ME_FETCH_SUCCESS } from 'soapbox/actions/me';
|
import { ME_FETCH_SUCCESS, ME_PATCH_SUCCESS } from 'soapbox/actions/me';
|
||||||
import { Map as ImmutableMap, fromJS } from 'immutable';
|
import { Map as ImmutableMap, fromJS } from 'immutable';
|
||||||
import uuid from '../uuid';
|
import uuid from '../uuid';
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ export default function settings(state = initialState, action) {
|
||||||
case STORE_HYDRATE:
|
case STORE_HYDRATE:
|
||||||
return hydrate(state, action.state.get('settings'));
|
return hydrate(state, action.state.get('settings'));
|
||||||
case ME_FETCH_SUCCESS:
|
case ME_FETCH_SUCCESS:
|
||||||
|
case ME_PATCH_SUCCESS:
|
||||||
const me = fromJS(action.me);
|
const me = fromJS(action.me);
|
||||||
const fePrefs = me.getIn(['pleroma', 'settings_store', FE_NAME]);
|
const fePrefs = me.getIn(['pleroma', 'settings_store', FE_NAME]);
|
||||||
return state.merge(fePrefs);
|
return state.merge(fePrefs);
|
||||||
|
|
Loading…
Reference in New Issue