diff --git a/src/app/components/modules/Settings.jsx b/src/app/components/modules/Settings.jsx
index 967b8e8d4..f4464d365 100644
--- a/src/app/components/modules/Settings.jsx
+++ b/src/app/components/modules/Settings.jsx
@@ -1,193 +1,10 @@
import React from 'react';
import { connect } from 'react-redux';
import tt from 'counterpart';
-import * as userActions from 'app/redux/UserReducer';
-import * as transactionActions from 'app/redux/TransactionReducer';
import * as appActions from 'app/redux/AppReducer';
import o2j from 'shared/clash/object2json';
-import LoadingIndicator from 'app/components/elements/LoadingIndicator';
-import reactForm from 'app/utils/ReactForm';
-import UserList from 'app/components/elements/UserList';
-import Dropzone from 'react-dropzone';
class Settings extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- errorMessage: '',
- successMessage: '',
- progress: {},
- };
- this.initForm(props);
- }
-
- initForm(props) {
- reactForm({
- instance: this,
- name: 'accountSettings',
- fields: [
- 'profile_image',
- 'cover_image',
- 'name',
- 'about',
- 'location',
- 'website',
- ],
- initialValues: props.profile,
- validation: values => ({
- profile_image:
- values.profile_image &&
- !/^https?:\/\//.test(values.profile_image)
- ? tt('settings_jsx.invalid_url')
- : null,
- cover_image:
- values.cover_image &&
- !/^https?:\/\//.test(values.cover_image)
- ? tt('settings_jsx.invalid_url')
- : null,
- name:
- values.name && values.name.length > 20
- ? tt('settings_jsx.name_is_too_long')
- : values.name && /^\s*@/.test(values.name)
- ? tt('settings_jsx.name_must_not_begin_with')
- : null,
- about:
- values.about && values.about.length > 160
- ? tt('settings_jsx.about_is_too_long')
- : null,
- location:
- values.location && values.location.length > 30
- ? tt('settings_jsx.location_is_too_long')
- : null,
- website:
- values.website && values.website.length > 100
- ? tt('settings_jsx.website_url_is_too_long')
- : values.website && !/^https?:\/\//.test(values.website)
- ? tt('settings_jsx.invalid_url')
- : null,
- }),
- });
- this.handleSubmitForm = this.state.accountSettings.handleSubmit(args =>
- this.handleSubmit(args)
- );
- }
-
- onDrop = (acceptedFiles, rejectedFiles) => {
- if (!acceptedFiles.length) {
- if (rejectedFiles.length) {
- this.setState({
- progress: { error: 'Please insert only image files.' },
- });
- console.log('onDrop Rejected files: ', rejectedFiles);
- }
- return;
- }
- const file = acceptedFiles[0];
- this.upload(file, file.name);
- };
-
- onOpenClick = imageName => {
- this.setState({
- imageInProgress: imageName,
- });
- this.dropzone.open();
- };
-
- upload = (file, name = '') => {
- const { uploadImage } = this.props;
- this.setState({
- progress: { message: tt('settings_jsx.uploading_image') + '...' },
- });
- uploadImage(file, progress => {
- if (progress.url) {
- this.setState({ progress: {} });
- const { url } = progress;
- const image_md = `${url}`;
- let field;
- if (this.state.imageInProgress === 'profile_image') {
- field = this.state.profile_image;
- } else if (this.state.imageInProgress === 'cover_image') {
- field = this.state.cover_image;
- } else {
- return;
- }
- field.props.onChange(image_md);
- } else {
- this.setState({ progress });
- }
- setTimeout(() => {
- this.setState({ progress: {} });
- }, 4000); // clear message
- });
- };
-
- handleSubmit = ({ updateInitialValues }) => {
- let { metaData } = this.props;
- if (!metaData) metaData = {};
- if (!metaData.profile) metaData.profile = {};
- delete metaData.user_image; // old field... cleanup
-
- const {
- profile_image,
- cover_image,
- name,
- about,
- location,
- website,
- } = this.state;
-
- // Update relevant fields
- metaData.profile.profile_image = profile_image.value;
- metaData.profile.cover_image = cover_image.value;
- metaData.profile.name = name.value;
- metaData.profile.about = about.value;
- metaData.profile.location = location.value;
- metaData.profile.website = website.value;
-
- // Remove empty keys
- if (!metaData.profile.profile_image)
- delete metaData.profile.profile_image;
- if (!metaData.profile.cover_image) delete metaData.profile.cover_image;
- if (!metaData.profile.name) delete metaData.profile.name;
- if (!metaData.profile.about) delete metaData.profile.about;
- if (!metaData.profile.location) delete metaData.profile.location;
- if (!metaData.profile.website) delete metaData.profile.website;
-
- const { account, updateAccount } = this.props;
- this.setState({ loading: true });
- updateAccount({
- json_metadata: JSON.stringify(metaData),
- account: account.name,
- memo_key: account.memo_key,
- errorCallback: e => {
- if (e === 'Canceled') {
- this.setState({
- loading: false,
- errorMessage: '',
- });
- } else {
- console.log('updateAccount ERROR', e);
- this.setState({
- loading: false,
- changed: false,
- errorMessage: tt('g.server_returned_error'),
- });
- }
- },
- successCallback: () => {
- this.setState({
- loading: false,
- changed: false,
- errorMessage: '',
- successMessage: tt('settings_jsx.saved'),
- });
- // remove successMessage after a while
- setTimeout(() => this.setState({ successMessage: '' }), 4000);
- updateInitialValues();
- },
- });
- };
-
handleLanguageChange = event => {
const locale = event.target.value;
const userPreferences = { ...this.props.user_preferences, locale };
@@ -195,187 +12,29 @@ class Settings extends React.Component {
};
render() {
- const { state, props } = this;
-
- const { submitting, valid, touched } = this.state.accountSettings;
- const disabled = state.loading || submitting || !valid || !touched;
-
- const {
- profile_image,
- cover_image,
- name,
- about,
- location,
- website,
- progress,
- } = this.state;
-
- const { account, user_preferences } = this.props;
-
+ const { user_preferences } = this.props;
return (
{tt('settings_jsx.preferences')}
-
+ {tt('g.choose_language')}
+
-
-
-
-
);
}
@@ -384,44 +43,16 @@ class Settings extends React.Component {
export default connect(
// mapStateToProps
(state, ownProps) => {
- const { accountname } = ownProps.routeParams;
- const account = state.global.getIn(['accounts', accountname]).toJS();
- const current_user = state.user.get('current');
- let metaData = account
- ? o2j.ifStringParseJSON(account.json_metadata)
- : {};
- if (typeof metaData === 'string')
- metaData = o2j.ifStringParseJSON(metaData); // issue #1237
- const profile = metaData && metaData.profile ? metaData.profile : {};
const user_preferences = state.app.get('user_preferences').toJS();
-
return {
- account,
- metaData,
- accountname,
- profile,
user_preferences,
...ownProps,
};
},
// mapDispatchToProps
dispatch => ({
- changeLanguage: language => {
- dispatch(userActions.changeLanguage(language));
- },
setUserPreferences: payload => {
dispatch(appActions.setUserPreferences(payload));
},
- uploadImage: (file, progress) =>
- dispatch(userActions.uploadImage({ file, progress })),
- updateAccount: ({ successCallback, errorCallback, ...operation }) => {
- const options = {
- type: 'account_update',
- operation,
- successCallback,
- errorCallback,
- };
- dispatch(transactionActions.broadcastOperation(options));
- },
})
)(Settings);
diff --git a/src/app/redux/UserReducer.js b/src/app/redux/UserReducer.js
index cd81e6bb7..a2da35bba 100644
--- a/src/app/redux/UserReducer.js
+++ b/src/app/redux/UserReducer.js
@@ -405,11 +405,6 @@ export const loadSavingsWithdraw = payload => ({
payload,
});
-export const uploadImage = payload => ({
- type: UPLOAD_IMAGE,
- payload,
-});
-
export const showSidePanel = () => ({
type: SHOW_SIDE_PANEL,
});
diff --git a/src/app/redux/UserSaga.js b/src/app/redux/UserSaga.js
index f43bca3a0..013539517 100644
--- a/src/app/redux/UserSaga.js
+++ b/src/app/redux/UserSaga.js
@@ -34,7 +34,6 @@ export const userWatches = [
takeLatest(userActions.LOGOUT, logout),
takeLatest(userActions.LOGIN_ERROR, loginError),
takeLatest(userActions.LOAD_SAVINGS_WITHDRAW, loadSavingsWithdraw),
- takeLatest(userActions.UPLOAD_IMAGE, uploadImage),
takeLatest(userActions.ACCEPT_TERMS, function*() {
try {
yield call(acceptTos);
@@ -585,129 +584,3 @@ function* lookupPreviousOwnerAuthority({ payload: {} }) {
// console.log('UserSage ---> previous_owner_authority', previous_owner_authority.toJS())
yield put(userActions.setUser({ previous_owner_authority }));
}
-
-function* uploadImage({
- payload: { file, dataUrl, filename = 'image.txt', progress },
-}) {
- const _progress = progress;
- progress = msg => {
- // console.log('Upload image progress', msg)
- _progress(msg);
- };
-
- const stateUser = yield select(state => state.user);
- const username = stateUser.getIn(['current', 'username']);
- const keychainLogin = isLoggedInWithKeychain();
- const hasPosting = stateUser.getIn([
- 'current',
- 'private_keys',
- 'posting_private',
- ]);
- const hasActive = stateUser.getIn([
- 'current',
- 'private_keys',
- 'active_private',
- ]);
-
- if (!username) {
- progress({ error: 'Please login first.' });
- return;
- }
-
- if (!(keychainLogin || hasPosting || hasActive)) {
- // we still allow upload with the posting key, but it will prompt for active to update either way
- // (due to current blockchain rules)
- progress({ error: 'Login with your active key' });
- return;
- }
-
- if (!file && !dataUrl) {
- console.error('uploadImage required: file or dataUrl');
- return;
- }
-
- let data, dataBs64;
- if (file) {
- // drag and drop
- const reader = new FileReader();
- data = yield new Promise(resolve => {
- reader.addEventListener('load', () => {
- const result = new Buffer(reader.result, 'binary');
- resolve(result);
- });
- reader.readAsBinaryString(file);
- });
- } else {
- // recover from preview
- const commaIdx = dataUrl.indexOf(',');
- dataBs64 = dataUrl.substring(commaIdx + 1);
- data = new Buffer(dataBs64, 'base64');
- }
-
- // The challenge needs to be prefixed with a constant (both on the server and checked on the client) to make sure the server can't easily make the client sign a transaction doing something else.
- const prefix = new Buffer('ImageSigningChallenge');
- const buf = Buffer.concat([prefix, data]);
- const bufSha = hash.sha256(buf);
-
- const formData = new FormData();
- if (file) {
- formData.append('file', file);
- } else {
- // formData.append('file', file, filename) <- Failed to add filename=xxx to Content-Disposition
- // Can't easily make this look like a file so this relies on the server supporting: filename and filebinary
- formData.append('filename', filename);
- formData.append('filebase64', dataBs64);
- }
-
- let sig;
- if (keychainLogin) {
- const response = yield new Promise(resolve => {
- window.steem_keychain.requestSignBuffer(
- username,
- JSON.stringify(buf),
- 'Posting',
- response => {
- resolve(response);
- }
- );
- });
- if (response.success) {
- sig = response.result;
- } else {
- progress({ error: response.message });
- return;
- }
- } else {
- sig = Signature.signBufferSha256(
- bufSha,
- hasPosting ? hasPosting : hasActive
- ).toHex();
- }
- const postUrl = `${$STM_Config.upload_image}/${username}/${sig}`;
-
- const xhr = new XMLHttpRequest();
- xhr.open('POST', postUrl);
- xhr.onload = function() {
- console.log(xhr.status, xhr.responseText);
- const res = JSON.parse(xhr.responseText);
- const { error } = res;
- if (error) {
- progress({ error: 'Error: ' + error });
- return;
- }
- const { url } = res;
- progress({ url });
- };
- xhr.onerror = function(error) {
- console.error(filename, error);
- progress({ error: 'Unable to contact the server.' });
- };
- xhr.upload.onprogress = function(event) {
- if (event.lengthComputable) {
- const percent = Math.round((event.loaded / event.total) * 100);
- progress({ message: `Uploading ${percent}%` });
- // console.log('Upload', percent)
- }
- };
- xhr.send(formData);
-}