Merge branch 'account-notes' into 'develop'
Account notes See merge request soapbox-pub/soapbox-fe!1053
This commit is contained in:
commit
92ac0e6a0d
|
@ -0,0 +1,67 @@
|
||||||
|
import api from '../api';
|
||||||
|
|
||||||
|
import { openModal, closeModal } from './modals';
|
||||||
|
|
||||||
|
export const ACCOUNT_NOTE_SUBMIT_REQUEST = 'ACCOUNT_NOTE_SUBMIT_REQUEST';
|
||||||
|
export const ACCOUNT_NOTE_SUBMIT_SUCCESS = 'ACCOUNT_NOTE_SUBMIT_SUCCESS';
|
||||||
|
export const ACCOUNT_NOTE_SUBMIT_FAIL = 'ACCOUNT_NOTE_SUBMIT_FAIL';
|
||||||
|
|
||||||
|
export const ACCOUNT_NOTE_INIT_MODAL = 'ACCOUNT_NOTE_INIT_MODAL';
|
||||||
|
|
||||||
|
export const ACCOUNT_NOTE_CHANGE_COMMENT = 'ACCOUNT_NOTE_CHANGE_COMMENT';
|
||||||
|
|
||||||
|
export function submitAccountNote() {
|
||||||
|
return (dispatch, getState) => {
|
||||||
|
dispatch(submitAccountNoteRequest());
|
||||||
|
|
||||||
|
const id = getState().getIn(['account_notes', 'edit', 'account_id']);
|
||||||
|
|
||||||
|
api(getState).post(`/api/v1/accounts/${id}/note`, {
|
||||||
|
comment: getState().getIn(['account_notes', 'edit', 'comment']),
|
||||||
|
}).then(response => {
|
||||||
|
dispatch(closeModal());
|
||||||
|
dispatch(submitAccountNoteSuccess(response.data));
|
||||||
|
}).catch(error => dispatch(submitAccountNoteFail(error)));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function submitAccountNoteRequest() {
|
||||||
|
return {
|
||||||
|
type: ACCOUNT_NOTE_SUBMIT_REQUEST,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function submitAccountNoteSuccess(relationship) {
|
||||||
|
return {
|
||||||
|
type: ACCOUNT_NOTE_SUBMIT_SUCCESS,
|
||||||
|
relationship,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function submitAccountNoteFail(error) {
|
||||||
|
return {
|
||||||
|
type: ACCOUNT_NOTE_SUBMIT_FAIL,
|
||||||
|
error,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function initAccountNoteModal(account) {
|
||||||
|
return (dispatch, getState) => {
|
||||||
|
const comment = getState().getIn(['relationships', account.get('id'), 'note']);
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: ACCOUNT_NOTE_INIT_MODAL,
|
||||||
|
account,
|
||||||
|
comment,
|
||||||
|
});
|
||||||
|
|
||||||
|
dispatch(openModal('ACCOUNT_NOTE'));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function changeAccountNoteComment(comment) {
|
||||||
|
return {
|
||||||
|
type: ACCOUNT_NOTE_CHANGE_COMMENT,
|
||||||
|
comment,
|
||||||
|
};
|
||||||
|
}
|
|
@ -62,6 +62,8 @@ const messages = defineMessages({
|
||||||
mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' },
|
mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' },
|
||||||
endorse: { id: 'account.endorse', defaultMessage: 'Feature on profile' },
|
endorse: { id: 'account.endorse', defaultMessage: 'Feature on profile' },
|
||||||
unendorse: { id: 'account.unendorse', defaultMessage: 'Don\'t feature on profile' },
|
unendorse: { id: 'account.unendorse', defaultMessage: 'Don\'t feature on profile' },
|
||||||
|
createNote: { id: 'account.create_note', defaultMessage: 'Create a note' },
|
||||||
|
editNote: { id: 'account.edit_note', defaultMessage: 'Edit note' },
|
||||||
admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
|
admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
|
||||||
add_or_remove_from_list: { id: 'account.add_or_remove_from_list', defaultMessage: 'Add or Remove from lists' },
|
add_or_remove_from_list: { id: 'account.add_or_remove_from_list', defaultMessage: 'Add or Remove from lists' },
|
||||||
deactivateUser: { id: 'admin.users.actions.deactivate_user', defaultMessage: 'Deactivate @{name}' },
|
deactivateUser: { id: 'admin.users.actions.deactivate_user', defaultMessage: 'Deactivate @{name}' },
|
||||||
|
@ -268,6 +270,14 @@ class Header extends ImmutablePureComponent {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (features.notes) {
|
||||||
|
menu.push({
|
||||||
|
text: intl.formatMessage(account.getIn(['relationship', 'note']) ? messages.editNote : messages.createNote),
|
||||||
|
action: this.props.onShowNote,
|
||||||
|
icon: require('@tabler/icons/icons/note.svg'),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (account.getIn(['relationship', 'following'])) {
|
if (account.getIn(['relationship', 'following'])) {
|
||||||
if (account.getIn(['relationship', 'showing_reblogs'])) {
|
if (account.getIn(['relationship', 'showing_reblogs'])) {
|
||||||
menu.push({
|
menu.push({
|
||||||
|
|
|
@ -131,6 +131,10 @@ export default class Header extends ImmutablePureComponent {
|
||||||
this.props.onUnsuggestUser(this.props.account);
|
this.props.onUnsuggestUser(this.props.account);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleShowNote = () => {
|
||||||
|
this.props.onShowNote(this.props.account);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { account, identity_proofs } = this.props;
|
const { account, identity_proofs } = this.props;
|
||||||
const moved = (account) ? account.get('moved') : false;
|
const moved = (account) ? account.get('moved') : false;
|
||||||
|
@ -165,6 +169,7 @@ export default class Header extends ImmutablePureComponent {
|
||||||
onDemoteToUser={this.handleDemoteToUser}
|
onDemoteToUser={this.handleDemoteToUser}
|
||||||
onSuggestUser={this.handleSuggestUser}
|
onSuggestUser={this.handleSuggestUser}
|
||||||
onUnsuggestUser={this.handleUnsuggestUser}
|
onUnsuggestUser={this.handleUnsuggestUser}
|
||||||
|
onShowNote={this.handleShowNote}
|
||||||
username={this.props.username}
|
username={this.props.username}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,21 +3,7 @@ import React from 'react';
|
||||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import {
|
import { initAccountNoteModal } from 'soapbox/actions/account_notes';
|
||||||
verifyUser,
|
|
||||||
unverifyUser,
|
|
||||||
promoteToAdmin,
|
|
||||||
promoteToModerator,
|
|
||||||
demoteToUser,
|
|
||||||
suggestUsers,
|
|
||||||
unsuggestUsers,
|
|
||||||
} from 'soapbox/actions/admin';
|
|
||||||
import { launchChat } from 'soapbox/actions/chats';
|
|
||||||
import { deactivateUserModal, deleteUserModal } from 'soapbox/actions/moderation';
|
|
||||||
import { getSettings } from 'soapbox/actions/settings';
|
|
||||||
import snackbar from 'soapbox/actions/snackbar';
|
|
||||||
import { isAdmin } from 'soapbox/utils/accounts';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
followAccount,
|
followAccount,
|
||||||
unfollowAccount,
|
unfollowAccount,
|
||||||
|
@ -28,16 +14,31 @@ import {
|
||||||
unpinAccount,
|
unpinAccount,
|
||||||
subscribeAccount,
|
subscribeAccount,
|
||||||
unsubscribeAccount,
|
unsubscribeAccount,
|
||||||
} from '../../../actions/accounts';
|
} from 'soapbox/actions/accounts';
|
||||||
|
import {
|
||||||
|
verifyUser,
|
||||||
|
unverifyUser,
|
||||||
|
promoteToAdmin,
|
||||||
|
promoteToModerator,
|
||||||
|
demoteToUser,
|
||||||
|
suggestUsers,
|
||||||
|
unsuggestUsers,
|
||||||
|
} from 'soapbox/actions/admin';
|
||||||
|
import { launchChat } from 'soapbox/actions/chats';
|
||||||
import {
|
import {
|
||||||
mentionCompose,
|
mentionCompose,
|
||||||
directCompose,
|
directCompose,
|
||||||
} from '../../../actions/compose';
|
} from 'soapbox/actions/compose';
|
||||||
import { blockDomain, unblockDomain } from '../../../actions/domain_blocks';
|
import { blockDomain, unblockDomain } from 'soapbox/actions/domain_blocks';
|
||||||
import { openModal } from '../../../actions/modals';
|
import { openModal } from 'soapbox/actions/modals';
|
||||||
import { initMuteModal } from '../../../actions/mutes';
|
import { deactivateUserModal, deleteUserModal } from 'soapbox/actions/moderation';
|
||||||
import { initReport } from '../../../actions/reports';
|
import { initMuteModal } from 'soapbox/actions/mutes';
|
||||||
import { makeGetAccount } from '../../../selectors';
|
import { initReport } from 'soapbox/actions/reports';
|
||||||
|
import { getSettings } from 'soapbox/actions/settings';
|
||||||
|
import snackbar from 'soapbox/actions/snackbar';
|
||||||
|
import { makeGetAccount } from 'soapbox/selectors';
|
||||||
|
import { isAdmin } from 'soapbox/utils/accounts';
|
||||||
|
|
||||||
import Header from '../components/header';
|
import Header from '../components/header';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
|
@ -246,6 +247,10 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||||
.then(() => dispatch(snackbar.success(message)))
|
.then(() => dispatch(snackbar.success(message)))
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onShowNote(account) {
|
||||||
|
dispatch(initAccountNoteModal(account));
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default injectIntl(connect(makeMapStateToProps, mapDispatchToProps)(Header));
|
export default injectIntl(connect(makeMapStateToProps, mapDispatchToProps)(Header));
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React from 'react';
|
||||||
|
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import { changeAccountNoteComment, submitAccountNote } from 'soapbox/actions/account_notes';
|
||||||
|
import { closeModal } from 'soapbox/actions/modals';
|
||||||
|
import Button from 'soapbox/components/button';
|
||||||
|
import Icon from 'soapbox/components/icon';
|
||||||
|
import { makeGetAccount } from 'soapbox/selectors';
|
||||||
|
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
close: { id: 'lightbox.close', defaultMessage: 'Close' },
|
||||||
|
placeholder: { id: 'account_note.placeholder', defaultMessage: 'No comment provided' },
|
||||||
|
save: { id: 'account_note.save', defaultMessage: 'Save' },
|
||||||
|
});
|
||||||
|
|
||||||
|
const makeMapStateToProps = () => {
|
||||||
|
const getAccount = makeGetAccount();
|
||||||
|
|
||||||
|
const mapStateToProps = state => ({
|
||||||
|
isSubmitting: state.getIn(['account_notes', 'edit', 'isSubmitting']),
|
||||||
|
account: getAccount(state, state.getIn(['account_notes', 'edit', 'account_id'])),
|
||||||
|
comment: state.getIn(['account_notes', 'edit', 'comment']),
|
||||||
|
});
|
||||||
|
|
||||||
|
return mapStateToProps;
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => {
|
||||||
|
return {
|
||||||
|
onConfirm() {
|
||||||
|
dispatch(submitAccountNote());
|
||||||
|
},
|
||||||
|
|
||||||
|
onClose() {
|
||||||
|
dispatch(closeModal());
|
||||||
|
},
|
||||||
|
|
||||||
|
onCommentChange(comment) {
|
||||||
|
dispatch(changeAccountNoteComment(comment));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default @connect(makeMapStateToProps, mapDispatchToProps)
|
||||||
|
@injectIntl
|
||||||
|
class AccountNoteModal extends React.PureComponent {
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
isSubmitting: PropTypes.bool,
|
||||||
|
account: PropTypes.object.isRequired,
|
||||||
|
onClose: PropTypes.func.isRequired,
|
||||||
|
onConfirm: PropTypes.func.isRequired,
|
||||||
|
onCommentChange: PropTypes.func.isRequired,
|
||||||
|
comment: PropTypes.string,
|
||||||
|
intl: PropTypes.object.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
handleCommentChange = e => {
|
||||||
|
this.props.onCommentChange(e.target.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSubmit = () => {
|
||||||
|
this.props.onConfirm();
|
||||||
|
}
|
||||||
|
|
||||||
|
handleKeyDown = e => {
|
||||||
|
if (e.keyCode === 13 && (e.ctrlKey || e.metaKey)) {
|
||||||
|
this.handleSubmit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { account, isSubmitting, comment, onClose, intl } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='modal-root__modal account-note-modal'>
|
||||||
|
<div className='account-note-modal__header'>
|
||||||
|
<Icon src={require('@tabler/icons/icons/note.svg')} />
|
||||||
|
<FormattedMessage id='account_note.target' defaultMessage='Note for @{target}' values={{ target: account.get('acct') }} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='account-note-modal__container'>
|
||||||
|
<p><FormattedMessage id='account_note.hint' defaultMessage='You can keep notes about this user for yourself (this will not be shared with them):' /></p>
|
||||||
|
|
||||||
|
<textarea
|
||||||
|
className='setting-text light'
|
||||||
|
placeholder={intl.formatMessage(messages.placeholder)}
|
||||||
|
value={comment}
|
||||||
|
onChange={this.handleCommentChange}
|
||||||
|
onKeyDown={this.handleKeyDown}
|
||||||
|
disabled={isSubmitting}
|
||||||
|
autoFocus
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className='account-note-modal__action-bar'>
|
||||||
|
<Button onClick={onClose} className='account-note-modal__cancel-button'>
|
||||||
|
<FormattedMessage id='confirmation_modal.cancel' defaultMessage='Cancel' />
|
||||||
|
</Button>
|
||||||
|
<Button text={intl.formatMessage(messages.save)} onClick={this.handleSubmit} disabled={isSubmitting} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -27,6 +27,7 @@ import {
|
||||||
ReblogsModal,
|
ReblogsModal,
|
||||||
MentionsModal,
|
MentionsModal,
|
||||||
BirthdaysModal,
|
BirthdaysModal,
|
||||||
|
AccountNoteModal,
|
||||||
} from '../../../features/ui/util/async-components';
|
} from '../../../features/ui/util/async-components';
|
||||||
import BundleContainer from '../containers/bundle_container';
|
import BundleContainer from '../containers/bundle_container';
|
||||||
|
|
||||||
|
@ -59,6 +60,7 @@ const MODAL_COMPONENTS = {
|
||||||
'REACTIONS': ReactionsModal,
|
'REACTIONS': ReactionsModal,
|
||||||
'MENTIONS': MentionsModal,
|
'MENTIONS': MentionsModal,
|
||||||
'BIRTHDAYS': BirthdaysModal,
|
'BIRTHDAYS': BirthdaysModal,
|
||||||
|
'ACCOUNT_NOTE': AccountNoteModal,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class ModalRoot extends React.PureComponent {
|
export default class ModalRoot extends React.PureComponent {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import { initAccountNoteModal } from 'soapbox/actions/account_notes';
|
||||||
import Badge from 'soapbox/components/badge';
|
import Badge from 'soapbox/components/badge';
|
||||||
import Icon from 'soapbox/components/icon';
|
import Icon from 'soapbox/components/icon';
|
||||||
import VerificationBadge from 'soapbox/components/verification_badge';
|
import VerificationBadge from 'soapbox/components/verification_badge';
|
||||||
|
@ -48,6 +49,7 @@ class ProfileInfoPanel extends ImmutablePureComponent {
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
username: PropTypes.string,
|
username: PropTypes.string,
|
||||||
displayFqn: PropTypes.bool,
|
displayFqn: PropTypes.bool,
|
||||||
|
onShowNote: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
getStaffBadge = () => {
|
getStaffBadge = () => {
|
||||||
|
@ -115,6 +117,13 @@ class ProfileInfoPanel extends ImmutablePureComponent {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleShowNote = e => {
|
||||||
|
const { account, onShowNote } = this.props;
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
onShowNote(account);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { account, displayFqn, intl, identity_proofs, username } = this.props;
|
const { account, displayFqn, intl, identity_proofs, username } = this.props;
|
||||||
|
|
||||||
|
@ -187,6 +196,13 @@ class ProfileInfoPanel extends ImmutablePureComponent {
|
||||||
|
|
||||||
{this.getBirthday()}
|
{this.getBirthday()}
|
||||||
|
|
||||||
|
{!!account.getIn(['relationship', 'note']) && (
|
||||||
|
<a href='#' className='profile-info-panel-content__note' onClick={this.handleShowNote}>
|
||||||
|
<Icon src={require('@tabler/icons/icons/note.svg')} />
|
||||||
|
<FormattedMessage id='account.show_note' defaultMessage='Show note' />
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
|
||||||
<ProfileStats
|
<ProfileStats
|
||||||
className='profile-info-panel-content__stats'
|
className='profile-info-panel-content__stats'
|
||||||
account={account}
|
account={account}
|
||||||
|
@ -250,8 +266,14 @@ const mapStateToProps = (state, { account }) => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
onShowNote(account) {
|
||||||
|
dispatch(initAccountNoteModal(account));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export default injectIntl(
|
export default injectIntl(
|
||||||
connect(mapStateToProps, null, null, {
|
connect(mapStateToProps, mapDispatchToProps, null, {
|
||||||
forwardRef: true,
|
forwardRef: true,
|
||||||
},
|
},
|
||||||
)(ProfileInfoPanel));
|
)(ProfileInfoPanel));
|
||||||
|
|
|
@ -218,6 +218,10 @@ export function BirthdaysModal() {
|
||||||
return import(/* webpackChunkName: "features/ui" */'../components/birthdays_modal');
|
return import(/* webpackChunkName: "features/ui" */'../components/birthdays_modal');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function AccountNoteModal() {
|
||||||
|
return import(/* webpackChunkName: "features/ui" */'../components/account_note_modal');
|
||||||
|
}
|
||||||
|
|
||||||
export function ListEditor() {
|
export function ListEditor() {
|
||||||
return import(/* webpackChunkName: "features/list_editor" */'../../list_editor');
|
return import(/* webpackChunkName: "features/list_editor" */'../../list_editor');
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
import { Map as ImmutableMap } from 'immutable';
|
||||||
|
|
||||||
|
import {
|
||||||
|
ACCOUNT_NOTE_INIT_MODAL,
|
||||||
|
ACCOUNT_NOTE_CHANGE_COMMENT,
|
||||||
|
ACCOUNT_NOTE_SUBMIT_REQUEST,
|
||||||
|
ACCOUNT_NOTE_SUBMIT_FAIL,
|
||||||
|
ACCOUNT_NOTE_SUBMIT_SUCCESS,
|
||||||
|
} from '../actions/account_notes';
|
||||||
|
|
||||||
|
const initialState = ImmutableMap({
|
||||||
|
edit: ImmutableMap({
|
||||||
|
isSubmitting: false,
|
||||||
|
account: null,
|
||||||
|
comment: null,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default function account_notes(state = initialState, action) {
|
||||||
|
switch (action.type) {
|
||||||
|
case ACCOUNT_NOTE_INIT_MODAL:
|
||||||
|
return state.withMutations((state) => {
|
||||||
|
state.setIn(['edit', 'isSubmitting'], false);
|
||||||
|
state.setIn(['edit', 'account_id'], action.account.get('id'));
|
||||||
|
state.setIn(['edit', 'comment'], action.comment);
|
||||||
|
});
|
||||||
|
case ACCOUNT_NOTE_CHANGE_COMMENT:
|
||||||
|
return state.setIn(['edit', 'comment'], action.comment);
|
||||||
|
case ACCOUNT_NOTE_SUBMIT_REQUEST:
|
||||||
|
return state.setIn(['edit', 'isSubmitting'], true);
|
||||||
|
case ACCOUNT_NOTE_SUBMIT_FAIL:
|
||||||
|
case ACCOUNT_NOTE_SUBMIT_SUCCESS:
|
||||||
|
return state.setIn(['edit', 'isSubmitting'], false);
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ import { combineReducers } from 'redux-immutable';
|
||||||
|
|
||||||
import { AUTH_LOGGED_OUT } from 'soapbox/actions/auth';
|
import { AUTH_LOGGED_OUT } from 'soapbox/actions/auth';
|
||||||
|
|
||||||
|
import account_notes from './account_notes';
|
||||||
import accounts from './accounts';
|
import accounts from './accounts';
|
||||||
import accounts_counters from './accounts_counters';
|
import accounts_counters from './accounts_counters';
|
||||||
import accounts_meta from './accounts_meta';
|
import accounts_meta from './accounts_meta';
|
||||||
|
@ -66,6 +67,7 @@ const appReducer = combineReducers({
|
||||||
user_lists,
|
user_lists,
|
||||||
domain_lists,
|
domain_lists,
|
||||||
status_lists,
|
status_lists,
|
||||||
|
account_notes,
|
||||||
accounts,
|
accounts,
|
||||||
accounts_counters,
|
accounts_counters,
|
||||||
statuses,
|
statuses,
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { get } from 'lodash';
|
||||||
|
|
||||||
import { STREAMING_FOLLOW_RELATIONSHIPS_UPDATE } from 'soapbox/actions/streaming';
|
import { STREAMING_FOLLOW_RELATIONSHIPS_UPDATE } from 'soapbox/actions/streaming';
|
||||||
|
|
||||||
|
import { ACCOUNT_NOTE_SUBMIT_SUCCESS } from '../actions/account_notes';
|
||||||
import {
|
import {
|
||||||
ACCOUNT_FOLLOW_SUCCESS,
|
ACCOUNT_FOLLOW_SUCCESS,
|
||||||
ACCOUNT_FOLLOW_REQUEST,
|
ACCOUNT_FOLLOW_REQUEST,
|
||||||
|
@ -106,6 +107,7 @@ export default function relationships(state = initialState, action) {
|
||||||
case ACCOUNT_UNSUBSCRIBE_SUCCESS:
|
case ACCOUNT_UNSUBSCRIBE_SUCCESS:
|
||||||
case ACCOUNT_PIN_SUCCESS:
|
case ACCOUNT_PIN_SUCCESS:
|
||||||
case ACCOUNT_UNPIN_SUCCESS:
|
case ACCOUNT_UNPIN_SUCCESS:
|
||||||
|
case ACCOUNT_NOTE_SUBMIT_SUCCESS:
|
||||||
return normalizeRelationship(state, action.relationship);
|
return normalizeRelationship(state, action.relationship);
|
||||||
case RELATIONSHIPS_FETCH_SUCCESS:
|
case RELATIONSHIPS_FETCH_SUCCESS:
|
||||||
return normalizeRelationships(state, action.relationships);
|
return normalizeRelationships(state, action.relationships);
|
||||||
|
|
|
@ -89,6 +89,10 @@ export const getFeatures = createSelector([instance => instance], instance => {
|
||||||
birthdays: v.software === PLEROMA && gte(v.version, '2.4.50'),
|
birthdays: v.software === PLEROMA && gte(v.version, '2.4.50'),
|
||||||
ethereumLogin: v.software === MITRA,
|
ethereumLogin: v.software === MITRA,
|
||||||
accountMoving: v.software === PLEROMA && gte(v.version, '2.4.50'),
|
accountMoving: v.software === PLEROMA && gte(v.version, '2.4.50'),
|
||||||
|
notes: any([
|
||||||
|
v.software === MASTODON && gte(v.compatVersion, '3.2.0'),
|
||||||
|
v.software === PLEROMA && gte(v.version, '2.4.50'),
|
||||||
|
]),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,9 @@
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
|
||||||
@media screen and (max-width: 600px) { padding: 30px 2px; }
|
@media screen and (max-width: 600px) {
|
||||||
|
padding: 30px 2px;
|
||||||
|
}
|
||||||
|
|
||||||
.svg-icon {
|
.svg-icon {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
|
@ -342,7 +344,8 @@
|
||||||
.mute-modal,
|
.mute-modal,
|
||||||
.reactions-modal,
|
.reactions-modal,
|
||||||
.reblogs-modal,
|
.reblogs-modal,
|
||||||
.mentions-modal {
|
.mentions-modal,
|
||||||
|
.account-note-modal {
|
||||||
position: relative;
|
position: relative;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
@ -411,7 +414,8 @@
|
||||||
|
|
||||||
.boost-modal__action-bar,
|
.boost-modal__action-bar,
|
||||||
.confirmation-modal__action-bar,
|
.confirmation-modal__action-bar,
|
||||||
.mute-modal__action-bar {
|
.mute-modal__action-bar,
|
||||||
|
.account-note-modal__action-bar {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
@ -464,7 +468,8 @@
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
.report-modal {
|
.report-modal,
|
||||||
|
.account-note-modal {
|
||||||
width: 90vw;
|
width: 90vw;
|
||||||
max-width: 700px;
|
max-width: 700px;
|
||||||
}
|
}
|
||||||
|
@ -521,27 +526,6 @@
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.setting-text {
|
|
||||||
display: block;
|
|
||||||
box-sizing: border-box;
|
|
||||||
width: 100%;
|
|
||||||
margin: 0;
|
|
||||||
color: var(--primary-text-color);
|
|
||||||
background: var(--background-color);
|
|
||||||
padding: 10px;
|
|
||||||
font-family: inherit;
|
|
||||||
font-size: 14px;
|
|
||||||
resize: vertical;
|
|
||||||
outline: 0;
|
|
||||||
border: 1px solid var(--background-color);
|
|
||||||
border-radius: 4px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
border: 1px solid var(--background-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.setting-toggle {
|
.setting-toggle {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
margin-bottom: 24px;
|
margin-bottom: 24px;
|
||||||
|
@ -574,7 +558,9 @@
|
||||||
max-height: 300px;
|
max-height: 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions-modal__item-label { font-weight: 500; }
|
.actions-modal__item-label {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
@ -582,12 +568,18 @@
|
||||||
max-height: calc(100vh - 147px);
|
max-height: calc(100vh - 147px);
|
||||||
|
|
||||||
// NOTE - not sure what this is yet, leaving alone for now until I find out.
|
// NOTE - not sure what this is yet, leaving alone for now until I find out.
|
||||||
&.with-status { max-height: calc(80vh - 75px); }
|
&.with-status {
|
||||||
|
max-height: calc(80vh - 75px);
|
||||||
|
}
|
||||||
|
|
||||||
li:empty { margin: 0; }
|
li:empty {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
li:not(:empty) {
|
li:not(:empty) {
|
||||||
&:first-of-type { margin: 10px 0 0; }
|
&:first-of-type {
|
||||||
|
margin: 10px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -654,10 +646,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.confirmation-modal__action-bar,
|
.confirmation-modal__action-bar,
|
||||||
.mute-modal__action-bar {
|
.mute-modal__action-bar,
|
||||||
|
.account-note-modal__action-bar {
|
||||||
.confirmation-modal__secondary-button,
|
.confirmation-modal__secondary-button,
|
||||||
.confirmation-modal__cancel-button,
|
.confirmation-modal__cancel-button,
|
||||||
.mute-modal__cancel-button {
|
.mute-modal__cancel-button,
|
||||||
|
.account-note-modal__cancel-button {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
color: var(--highlight-text-color);
|
color: var(--highlight-text-color);
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
@ -726,7 +720,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-layout {
|
.modal-layout {
|
||||||
background: var(--brand-color--med) url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 234.80078 31.757813" width="234.80078" height="31.757812"><path d="M19.599609 0c-1.05 0-2.10039.375-2.90039 1.125L0 16.925781v14.832031h234.80078V17.025391l-16.5-15.900391c-1.6-1.5-4.20078-1.5-5.80078 0l-13.80078 13.099609c-1.6 1.5-4.19883 1.5-5.79883 0L179.09961 1.125c-1.6-1.5-4.19883-1.5-5.79883 0L159.5 14.224609c-1.6 1.5-4.20078 1.5-5.80078 0L139.90039 1.125c-1.6-1.5-4.20078-1.5-5.80078 0l-13.79883 13.099609c-1.6 1.5-4.20078 1.5-5.80078 0L100.69922 1.125c-1.600001-1.5-4.198829-1.5-5.798829 0l-13.59961 13.099609c-1.6 1.5-4.200781 1.5-5.800781 0L61.699219 1.125c-1.6-1.5-4.198828-1.5-5.798828 0L42.099609 14.224609c-1.6 1.5-4.198828 1.5-5.798828 0L22.5 1.125C21.7.375 20.649609 0 19.599609 0z" fill="#{hex-color(var(--background-color))}"/></svg>') repeat-x bottom fixed;
|
background: var(--brand-color--med)
|
||||||
|
url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 234.80078 31.757813" width="234.80078" height="31.757812"><path d="M19.599609 0c-1.05 0-2.10039.375-2.90039 1.125L0 16.925781v14.832031h234.80078V17.025391l-16.5-15.900391c-1.6-1.5-4.20078-1.5-5.80078 0l-13.80078 13.099609c-1.6 1.5-4.19883 1.5-5.79883 0L179.09961 1.125c-1.6-1.5-4.19883-1.5-5.79883 0L159.5 14.224609c-1.6 1.5-4.20078 1.5-5.80078 0L139.90039 1.125c-1.6-1.5-4.20078-1.5-5.80078 0l-13.79883 13.099609c-1.6 1.5-4.20078 1.5-5.80078 0L100.69922 1.125c-1.600001-1.5-4.198829-1.5-5.798829 0l-13.59961 13.099609c-1.6 1.5-4.200781 1.5-5.800781 0L61.699219 1.125c-1.6-1.5-4.198828-1.5-5.798828 0L42.099609 14.224609c-1.6 1.5-4.198828 1.5-5.798828 0L22.5 1.125C21.7.375 20.649609 0 19.599609 0z" fill="#{hex-color(var(--background-color))}"/></svg>')
|
||||||
|
repeat-x bottom fixed;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
|
@ -1068,7 +1064,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.confirmation-modal,
|
.confirmation-modal,
|
||||||
.mute-modal {
|
.mute-modal,
|
||||||
|
.account-note-modal {
|
||||||
&__header {
|
&__header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -1090,3 +1087,35 @@
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.report-modal__comment,
|
||||||
|
.account-note-modal__container {
|
||||||
|
.setting-text {
|
||||||
|
display: block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
color: var(--primary-text-color);
|
||||||
|
background: var(--background-color);
|
||||||
|
padding: 10px;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: 14px;
|
||||||
|
resize: vertical;
|
||||||
|
outline: 0;
|
||||||
|
border: 1px solid var(--background-color);
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
border: 1px solid var(--background-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-note-modal {
|
||||||
|
.setting-text {
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
resize: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -23,7 +23,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&__join-date,
|
&__join-date,
|
||||||
&__birthday {
|
&__birthday,
|
||||||
|
&__note {
|
||||||
display: flex;
|
display: flex;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: var(--primary-text-color--faint);
|
color: var(--primary-text-color--faint);
|
||||||
|
@ -39,6 +40,15 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__note {
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&__stats {
|
&__stats {
|
||||||
margin: 15px 0;
|
margin: 15px 0;
|
||||||
|
|
||||||
|
@ -163,10 +173,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile-info-panel__name-content::before {
|
.profile-info-panel__name-content::before {
|
||||||
content: '[';
|
content: "[";
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile-info-panel__name-content::after {
|
.profile-info-panel__name-content::after {
|
||||||
content: ']';
|
content: "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue