about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/javascript/mastodon/features/list_editor/components/edit_list_form.js70
-rw-r--r--app/javascript/mastodon/features/list_editor/index.js7
-rw-r--r--app/javascript/mastodon/reducers/list_editor.js11
-rw-r--r--app/javascript/styles/mastodon/components.scss2
4 files changed, 83 insertions, 7 deletions
diff --git a/app/javascript/mastodon/features/list_editor/components/edit_list_form.js b/app/javascript/mastodon/features/list_editor/components/edit_list_form.js
new file mode 100644
index 000000000..3dc59c12e
--- /dev/null
+++ b/app/javascript/mastodon/features/list_editor/components/edit_list_form.js
@@ -0,0 +1,70 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import PropTypes from 'prop-types';
+import { changeListEditorTitle, submitListEditor } from '../../../actions/lists';
+import IconButton from '../../../components/icon_button';
+import { defineMessages, injectIntl } from 'react-intl';
+
+const messages = defineMessages({
+  title: { id: 'lists.edit.submit', defaultMessage: 'Change title' },
+});
+
+const mapStateToProps = state => ({
+  value: state.getIn(['listEditor', 'title']),
+  disabled: !state.getIn(['listEditor', 'isChanged']),
+});
+
+const mapDispatchToProps = dispatch => ({
+  onChange: value => dispatch(changeListEditorTitle(value)),
+  onSubmit: () => dispatch(submitListEditor(false)),
+});
+
+export default @connect(mapStateToProps, mapDispatchToProps)
+@injectIntl
+class ListForm extends React.PureComponent {
+
+  static propTypes = {
+    value: PropTypes.string.isRequired,
+    disabled: PropTypes.bool,
+    intl: PropTypes.object.isRequired,
+    onChange: PropTypes.func.isRequired,
+    onSubmit: PropTypes.func.isRequired,
+  };
+
+  handleChange = e => {
+    this.props.onChange(e.target.value);
+  }
+
+  handleSubmit = e => {
+    e.preventDefault();
+    this.props.onSubmit();
+  }
+
+  handleClick = () => {
+    this.props.onSubmit();
+  }
+
+  render () {
+    const { value, disabled, intl } = this.props;
+
+    const title = intl.formatMessage(messages.title);
+
+    return (
+      <form className='column-inline-form' onSubmit={this.handleSubmit}>
+        <input
+          className='setting-text'
+          value={value}
+          onChange={this.handleChange}
+        />
+
+        <IconButton
+          disabled={disabled}
+          icon='check'
+          title={title}
+          onClick={this.handleClick}
+        />
+      </form>
+    );
+  }
+
+}
diff --git a/app/javascript/mastodon/features/list_editor/index.js b/app/javascript/mastodon/features/list_editor/index.js
index aab0cdd0c..48466604a 100644
--- a/app/javascript/mastodon/features/list_editor/index.js
+++ b/app/javascript/mastodon/features/list_editor/index.js
@@ -7,11 +7,11 @@ import { injectIntl } from 'react-intl';
 import { setupListEditor, clearListSuggestions, resetListEditor } from '../../actions/lists';
 import Account from './components/account';
 import Search from './components/search';
+import EditListForm from './components/edit_list_form';
 import Motion from '../ui/util/optional_motion';
 import spring from 'react-motion/lib/spring';
 
 const mapStateToProps = state => ({
-  title: state.getIn(['listEditor', 'title']),
   accountIds: state.getIn(['listEditor', 'accounts', 'items']),
   searchAccountIds: state.getIn(['listEditor', 'suggestions', 'items']),
 });
@@ -33,7 +33,6 @@ class ListEditor extends ImmutablePureComponent {
     onInitialize: PropTypes.func.isRequired,
     onClear: PropTypes.func.isRequired,
     onReset: PropTypes.func.isRequired,
-    title: PropTypes.string.isRequired,
     accountIds: ImmutablePropTypes.list.isRequired,
     searchAccountIds: ImmutablePropTypes.list.isRequired,
   };
@@ -49,12 +48,12 @@ class ListEditor extends ImmutablePureComponent {
   }
 
   render () {
-    const { title, accountIds, searchAccountIds, onClear } = this.props;
+    const { accountIds, searchAccountIds, onClear } = this.props;
     const showSearch = searchAccountIds.size > 0;
 
     return (
       <div className='modal-root__modal list-editor'>
-        <h4>{title}</h4>
+        <EditListForm />
 
         <Search />
 
diff --git a/app/javascript/mastodon/reducers/list_editor.js b/app/javascript/mastodon/reducers/list_editor.js
index 02a0dabb1..91e524dd5 100644
--- a/app/javascript/mastodon/reducers/list_editor.js
+++ b/app/javascript/mastodon/reducers/list_editor.js
@@ -22,6 +22,7 @@ import {
 const initialState = ImmutableMap({
   listId: null,
   isSubmitting: false,
+  isChanged: false,
   title: '',
 
   accounts: ImmutableMap({
@@ -47,10 +48,16 @@ export default function listEditorReducer(state = initialState, action) {
       map.set('isSubmitting', false);
     });
   case LIST_EDITOR_TITLE_CHANGE:
-    return state.set('title', action.value);
+    return state.withMutations(map => {
+      map.set('title', action.value);
+      map.set('isChanged', true);
+    });
   case LIST_CREATE_REQUEST:
   case LIST_UPDATE_REQUEST:
-    return state.set('isSubmitting', true);
+    return state.withMutations(map => {
+      map.set('isSubmitting', true);
+      map.set('isChanged', false);
+    });
   case LIST_CREATE_FAIL:
   case LIST_UPDATE_FAIL:
     return state.set('isSubmitting', false);
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index 02bbd345a..8533e4eb5 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -5163,7 +5163,7 @@ noscript {
 
   .icon-button {
     flex: 0 0 auto;
-    margin-left: 5px;
+    margin: 0 5px;
   }
 }