169 lines
4.7 KiB
TypeScript
169 lines
4.7 KiB
TypeScript
|
import { SagaIterator } from 'redux-saga';
|
||
|
import { select, put, takeEvery } from 'redux-saga/effects';
|
||
|
import { isValidAddressLabel } from 'libs/validators';
|
||
|
import { ADDRESS_BOOK_TABLE_ID } from 'components/AddressBookTable';
|
||
|
import { ACCOUNT_ADDRESS_ID } from 'components/BalanceSidebar/AccountAddress';
|
||
|
import {
|
||
|
TypeKeys,
|
||
|
ChangeAddressLabelEntry,
|
||
|
SaveAddressLabelEntry,
|
||
|
RemoveAddressLabelEntry,
|
||
|
setAddressLabelEntry,
|
||
|
setAddressLabel,
|
||
|
clearAddressLabel,
|
||
|
clearAddressLabelEntry
|
||
|
} from 'actions/addressBook';
|
||
|
import {
|
||
|
getAddressLabels,
|
||
|
getLabelAddresses,
|
||
|
getAddressLabelEntry,
|
||
|
getAddressLabelEntryFromAddress,
|
||
|
getNextAddressLabelId
|
||
|
} from 'selectors/addressBook';
|
||
|
import { showNotification } from 'actions/notifications';
|
||
|
|
||
|
export const ERROR_DURATION: number = 4000;
|
||
|
|
||
|
export function* handleChangeAddressLabelEntry(action: ChangeAddressLabelEntry): SagaIterator {
|
||
|
const {
|
||
|
id,
|
||
|
address: temporaryAddress,
|
||
|
label: temporaryLabel,
|
||
|
isEditing,
|
||
|
overrideValidation
|
||
|
} = action.payload;
|
||
|
const addresses = yield select(getAddressLabels);
|
||
|
const labels = yield select(getLabelAddresses);
|
||
|
const priorEntry = yield select(getAddressLabelEntry, id);
|
||
|
const { addressError, labelError } = isValidAddressLabel(
|
||
|
temporaryAddress,
|
||
|
temporaryLabel,
|
||
|
addresses,
|
||
|
labels
|
||
|
);
|
||
|
const updatedEntry = {
|
||
|
id,
|
||
|
address: addressError && !isEditing ? priorEntry.address || '' : temporaryAddress,
|
||
|
temporaryAddress,
|
||
|
addressError: isEditing || overrideValidation ? undefined : addressError,
|
||
|
label: labelError ? priorEntry.label || '' : temporaryLabel,
|
||
|
temporaryLabel,
|
||
|
labelError: overrideValidation ? undefined : labelError
|
||
|
};
|
||
|
|
||
|
return yield put(setAddressLabelEntry(updatedEntry));
|
||
|
}
|
||
|
|
||
|
export function* handleSaveAddressLabelEntry(action: SaveAddressLabelEntry): SagaIterator {
|
||
|
const id = action.payload;
|
||
|
const { address, addressError, label, labelError } = yield select(getAddressLabelEntry, id);
|
||
|
const nextId = yield select(getNextAddressLabelId);
|
||
|
const flashError = (error: string) => put(showNotification('danger', error, ERROR_DURATION));
|
||
|
|
||
|
if (addressError) {
|
||
|
return yield flashError(addressError);
|
||
|
}
|
||
|
|
||
|
if (labelError) {
|
||
|
return yield flashError(labelError);
|
||
|
}
|
||
|
|
||
|
yield put(clearAddressLabel(address));
|
||
|
yield put(
|
||
|
setAddressLabel({
|
||
|
address,
|
||
|
label
|
||
|
})
|
||
|
);
|
||
|
|
||
|
if (id === ADDRESS_BOOK_TABLE_ID) {
|
||
|
// When entering a new label, create a new entry.
|
||
|
yield put(
|
||
|
setAddressLabelEntry({
|
||
|
id: nextId,
|
||
|
address,
|
||
|
temporaryAddress: address,
|
||
|
addressError: undefined,
|
||
|
label,
|
||
|
temporaryLabel: label,
|
||
|
labelError: undefined
|
||
|
})
|
||
|
);
|
||
|
yield put(
|
||
|
setAddressLabelEntry({
|
||
|
id: ADDRESS_BOOK_TABLE_ID,
|
||
|
address: '',
|
||
|
temporaryAddress: '',
|
||
|
addressError: undefined,
|
||
|
label: '',
|
||
|
temporaryLabel: '',
|
||
|
labelError: undefined
|
||
|
})
|
||
|
);
|
||
|
} else if (id === ACCOUNT_ADDRESS_ID) {
|
||
|
const ownEntry = yield select(getAddressLabelEntryFromAddress, address);
|
||
|
|
||
|
yield put(
|
||
|
setAddressLabelEntry({
|
||
|
id: ownEntry ? ownEntry.id : nextId,
|
||
|
address,
|
||
|
temporaryAddress: address,
|
||
|
addressError: undefined,
|
||
|
label,
|
||
|
temporaryLabel: label,
|
||
|
labelError: undefined
|
||
|
})
|
||
|
);
|
||
|
yield put(
|
||
|
setAddressLabelEntry({
|
||
|
id: ACCOUNT_ADDRESS_ID,
|
||
|
address: '',
|
||
|
temporaryAddress: '',
|
||
|
addressError: undefined,
|
||
|
label: '',
|
||
|
temporaryLabel: '',
|
||
|
labelError: undefined
|
||
|
})
|
||
|
);
|
||
|
} else {
|
||
|
// When editing a label, overwrite the previous entry.
|
||
|
yield put(
|
||
|
setAddressLabelEntry({
|
||
|
id,
|
||
|
address,
|
||
|
temporaryAddress: address,
|
||
|
addressError: undefined,
|
||
|
label,
|
||
|
temporaryLabel: label,
|
||
|
labelError: undefined
|
||
|
})
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
export function* handleRemoveAddressLabelEntry(action: RemoveAddressLabelEntry): SagaIterator {
|
||
|
const id = action.payload;
|
||
|
const { id: entryId, address } = yield select(getAddressLabelEntry, id);
|
||
|
|
||
|
if (typeof entryId === 'undefined') {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
yield put(clearAddressLabel(address));
|
||
|
yield put(clearAddressLabelEntry(id));
|
||
|
|
||
|
if (id === ACCOUNT_ADDRESS_ID) {
|
||
|
const ownEntry = yield select(getAddressLabelEntryFromAddress, address);
|
||
|
|
||
|
if (ownEntry) {
|
||
|
yield put(clearAddressLabelEntry(ownEntry.id));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
export default function* addressBookSaga(): SagaIterator {
|
||
|
yield takeEvery(TypeKeys.CHANGE_ADDRESS_LABEL_ENTRY, handleChangeAddressLabelEntry);
|
||
|
yield takeEvery(TypeKeys.SAVE_ADDRESS_LABEL_ENTRY, handleSaveAddressLabelEntry);
|
||
|
yield takeEvery(TypeKeys.REMOVE_ADDRESS_LABEL_ENTRY, handleRemoveAddressLabelEntry);
|
||
|
}
|