diff --git a/common/constants.js b/common/constants.js
index 1cc02fca..8fc1cb4e 100644
--- a/common/constants.js
+++ b/common/constants.js
@@ -14,7 +14,7 @@ export const sizes = {
export const system = {
white: "#ffffff",
- foreground: "#f7f7f7",
+ foreground: "#f8f8f8",
gray: "#e0e0e0",
border: "#d8d8d8",
darkGray: "#b2b2b2",
@@ -25,7 +25,7 @@ export const system = {
link: "#2935ff",
green: "#28a745",
yellow: " #FFC940",
- red: "#ff0000",
+ red: "#E05435",
slate: "#27292e",
moonstone: "#807d78",
wall: "#cfced3",
diff --git a/common/file-utilities.js b/common/file-utilities.js
index b2d0a9f0..6c1c04fb 100644
--- a/common/file-utilities.js
+++ b/common/file-utilities.js
@@ -1,3 +1,5 @@
+import { dispatchCustomEvent } from "~/common/custom-events";
+
export const upload = async ({ file, slate, context }) => {
let formData = new FormData();
const HEIC2ANY = require("heic2any");
@@ -93,9 +95,21 @@ export const upload = async ({ file, slate, context }) => {
body: JSON.stringify({ slate, data: { title: file.name, ...json.data } }),
});
- if (!addResponse || addResponse.error) {
- console.log(addResponse.error);
- alert("TODO: Adding an image to Slate went wrong.");
+ if (!addResponse) {
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: {
+ message:
+ "We're having trouble connecting right now. Please try again later",
+ },
+ },
+ });
+ } else if (addResponse.error) {
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: { alert: { decorator: addResponse.decorator } },
+ });
}
}
diff --git a/common/messages.js b/common/messages.js
index 6b268dc7..0581624f 100644
--- a/common/messages.js
+++ b/common/messages.js
@@ -1,9 +1,15 @@
export const error = {
//Slate Create
+ SERVER_FIND_USER_CREATE_SLATE: "There seems to be an issue with your account",
+ SERVER_FIND_USER_CREATE_SLATE_USER_NOT_FOUND: "Login to create a Slate!",
+ SERVER_EXISTING_SLATE:
+ "A Slate with that name already exists. Please try another",
+ SERVER_CREATE_SLATE: "There was an error when creating the Slate",
FIND_USER_CREATE_SLATE: "There seems to be an issue with your account",
FIND_USER_CREATE_SLATE_USER_NOT_FOUND: "Login to create a Slate!",
EXISTING_SLATE: "A Slate with that name already exists. Please try another",
CREATE_SLATE: "There was an error when creating the Slate",
+ SERVER_SLATE_LIMIT: "You've reached the limit for number of slates!",
//Slate Add URL
ADD_TO_SLATE_USER_NOT_FOUND: "Login to add a Slate URL",
@@ -11,54 +17,336 @@ export const error = {
"Sorry, we couldn't find that Slate! Please try another",
ADD_TO_SLATE_ERROR: "There was an error retriving this Slate",
+ //Slate Delete
+ DELETE_SLATE_BY_ID:
+ "Sorry, there was an error while trying to delete that slate. Please try again",
+ DELETE_SLATES_FOR_USER_ID:
+ "Sorry, we're having trouble deleting all your slates. Please try again later",
+ SERVER_DELETE_SLATE:
+ "We're having trouble deleting that at the moment. Please try again later",
+ SERVER_DELETE_SLATE_USER_NOT_FOUND: "Login to manage your slates!",
+ SERVER_DELETE_SLATE_SLATE_NOT_FOUND:
+ "We're having trouble deleting that at the moment. Please try again later",
+ SERVER_DELETE_SLATE:
+ "We're having trouble deleting that at the moment. Please try again later",
+
+ //Slate Get
+ GET_SLATE_BY_ID:
+ "We're having trouble retrieving information on that slate right now. Please try again later",
+ GET_SLATE_BY_NAME:
+ "We're having trouble retrieving information on that slate right now. Please try again later",
+ GET_SLATES_BY_USER_ID:
+ "We're having trouble retrieving that user's information. Please try again later",
+ SLATE_NOT_FOUND:
+ "We're having trouble retrieving that user's slates right now. Please try again",
+ SLATE_OWNER_NOT_FOUND:
+ "We're having trouble retrieving that slate's owner right now. Please try again",
+ SERVER_GET_SLATE_USER_NOT_FOUND:
+ "We're having trouble retrieving that slate's owner right now. Please try again",
+ SERVER_GET_SLATE:
+ "We're having trouble retrieving information on that slate right now. Please try again later",
+ SERVER_GET_SLATE_NOT_FOUND:
+ "We're having trouble retrieving information on that slate right now. Please try again later",
+
+ //Slate Update
+ UPDATE_SLATE_BY_ID:
+ "We ran into an issue while saving your slate. Please try again",
+ SERVER_ADD_TO_SLATE_USER_NOT_FOUND: "Login to upload files!",
+ SERVER_FIND_USER_UPDATE_SLATE_USER_NOT_FOUND: "Login to upload files!",
+ SERVER_ADD_TO_SLATE_SLATE_NOT_FOUND:
+ "We ran into issues while uploading that file. Please try again",
+ SERVER_ADD_TO_SLATE_ERROR:
+ "We ran into issues while uploading that file. Please try again",
+ SERVER_FIND_USER_UPDATE_SLATE:
+ "We ran into issues while uploading that file. Please try again",
+ SERVER_UPDATE_SLATE_NOT_FOUND:
+ "We ran into issues while locating that slate. Please try again",
+ SERVER_UPDATE_SLATE_MUST_PROVIDE_DATA:
+ "The input cannot be blank. Please check your input",
+ SERVER_UPDATE_SLATE_MUST_PROVIDE_NAME: "Please provide a slate name",
+ SERVER_UPDATE_SLATE:
+ "We're having trouble updating that slate right now. Please try again later",
+ V1_SERVER_UPLOAD_SLATE_NOT_FOUND:
+ "We're having trouble locating that slate right now. Please try again later",
+ V1_SERVER_API_KEY_NOT_FOUND:
+ "We can't seem to find your API key right now. Please try again later",
+ V1_SERVER_API_UPLOAD_ERROR:
+ "We're having trouble uploading that right now. Please try again later",
+ V1_SERVER_UPLOAD_SLATE_NOT_FOUND:
+ "We're having trouble locating that slate right now",
+ V1_SERVER_UPLOAD_TO_SLATE_ERROR:
+ "We're ran into issues while adding that to the slate. Please try again",
+ V1_GET_SLATE_NOT_FOUND:
+ "We're having trouble locating that slate right now. Please try again later",
+ V1_GET_SLATE_USER_NOT_FOUND:
+ "We're having trouble locating the owner of that slate right now. Please try again later",
+ V1_GET_SLATE_SLATE_NOT_FOUND:
+ "We're having trouble locating that slate right now. Please try again later",
+ V1_GET_SLATES_NOT_FOUND:
+ "We're having trouble locating those slates right now. Please try again later",
+
//Address Send
- SEND_FILECOIN: "That user doesn't seem to exist. Please try another",
+ SERVER_SEND_FILECOIN_USER_NOT_FOUND: "Sorry, we couldn't find that user!",
+ SERVER_SEND_FILECOIN_NO_ID:
+ "That user doesn't seem to exist. Please try another",
+ SERVER_SEND_FILECOIN_ACTION_FAILURE:
+ "There was an error sending the transaction. We're looking into it",
SEND_FILECOIN_USER_NOT_FOUND: "Sorry, we couldn't find that user!",
+ SEND_FILECOIN:
+ "There was an error sending the transaction. We're looking into it",
SEND_FILECOIN_ACTION_FAILURE:
"There was an error sending the transaction. We're looking into it",
+ //Address Create
+ CREATE_FILECOIN_ADDRESS:
+ "There was an error when creating the Filecoin address.",
+
//Data Upload
UPLOAD_PARSE_FAILURE:
"There was an error when parsing the upload. Please try again",
UPLOAD_NOT_IMAGE_TYPE:
"We are only accepting JPG and PNG files at this time. Try uploading a different file type!",
BUCKETS_PUSH_ISSUE: "There was an error uploading the data",
+ SERVER_UPLOAD_ERROR: "We're having issues uploading that file right now",
+ SERVER_API_KEY_MISSING:
+ "We can't seem to find your API key right now. Please try again later",
//Data CID Status
NO_CIDS_TO_CHECK: "There are no CIDs to check",
+ //Data Get
+ SERVER_GET_BUCKET_DATA:
+ "We ran into an issue fetching that data. Please try again later",
+
+ //Data Remove
+ SERVER_REMOVE_DATA_NO_CID: "We could not locate a file that matches that CID",
+ SERVER_REMOVE_DATA_NOT_ALLOWED: "You aren't authorized to remove that file",
+ SERVER_REMOVE_DATA_NO_LINK:
+ "We couldn't remove that data. Please try again later",
+
//Data Storage Deals
+ SERVER_STORAGE_DEAL_USER_NOT_FOUND: "Sorry, we couldn't find that user!",
+ SERVER_NO_CID: "IPFS CID is required",
+ SERVER_NO_IPFS: "There was a issue retriving data from IPFS",
+ SERVER_FILECOIN_STORAGE_DEAL_CID_ERROR:
+ "There was a issue making a storage deal",
+ SERVER_NO_JOB: "Sorry, this job doesn't exist!",
STORAGE_DEAL_USER_NOT_FOUND: "Sorry, we couldn't find that user!",
NO_CID: "IPFS CID is required",
NO_IPFS: "There was a issue retriving data from IPFS",
FILECOIN_STORAGE_DEAL_CID_ERROR: "There was a issue making a storage deal",
NO_JOB: "Sorry, this job doesn't exist!",
+ //Archive Deal
+ SERVER_REMOVE_DATA_NOT_ALLOWED: "You aren't authorized to archive that deal",
+ SERVER_BUCKET_ARCHIVE_DEAL_USER_NOT_FOUND:
+ "Please login first to archive a deal!",
+
+ //CID Status
+ SERVER_NO_CIDS_TO_CHECK: "No CIDs were entered, please check your input",
+
//Users Create
+ SERVER_EXISTING_USER_ALREADY:
+ "This username is already taken! Please try another one",
EXISTING_USER_ALREADY:
"This username is already taken! Please try another one",
INVALID_USERNAME: "Invalid username. Please include only letters and numbers",
+ SERVER_INVALID_USERNAME:
+ "Invalid username. Please include only letters and numbers",
INVALID_PASSWORD: "Password length must be more than 8 characters",
- USER_CREATE_USER_NOT_FOUND: "Sorry, we couldn't find that user!",
+ SERVER_INVALID_PASSWORD: "Password length must be more than 8 characters",
+ USER_CREATE_USER_NOT_FOUND:
+ "Sorry we weren't able to create your account. Please try again",
+ SERVER_USER_CREATE_USER_NOT_FOUND:
+ "Sorry we weren't able to create your account. Please try again",
+ CREATE_USER: "Sorry we weren't able to create your account. Please try again",
//Users Delete
USER_DELETE: "That user doesn't seem to exist. Please try another",
+ SERVER_USER_DELETE: "That user doesn't seem to exist. Please try another",
USER_DELETE_USER_NOT_FOUND: "Sorry, we couldn't find that user!",
+ SERVER_USER_DELETE_USER_NOT_FOUND: "Sorry, we couldn't find that user!",
+ DELETE_USER_BY_USERNAME:
+ "We're having trouble deleting your account right now",
+ SERVER_USER_DELETE: "We're having trouble deleting your account right now",
+ USER_NOT_FOUND: "We weren't able to locate that user",
+ SLATES_NOT_FOUND: "We weren't able to locate the slates for that user",
//Users Update
USER_UPDATE: "That user doesn't seem to exist. Please try another",
USER_UPDATE_USER_NOT_FOUND: "Sorry, we couldn't find that user!",
- INVALID_PASSWORD:
- "Short passwords are too easy to guess. Try one with more than 8 characters",
+ UPDATE_USER_BY_ID:
+ "We ran into an issue while updating your information. Please try again",
USER_UPDATE_SETTINGS_CONFIG: "Error when updating user settings",
- CREATE_FILECOIN_ADDRESS:
- "There was an error when creating the Filecoin address.",
+ SERVER_USER_UPDATE: "Please make sure you are signed in first",
+ SERVER_USER_UPDATE_USER_NOT_FOUND:
+ "We're having trouble locating your information. Please try again",
+
+ //Users Get
+ GET_USER_BY_ID:
+ "We weren't able to fetch information on that user. Please try again later",
+ GET_USER_BY_USERNAME:
+ "We weren't able to fetch information on that user. Please check your input",
+ USER_NOT_FOUND:
+ "We aren't able to locate that user at the moment. Please try again",
//Hydrate
- HYDRATE_FAILURE: "That user doesn't seem to exist. Please try another",
+ HYDRATE_FAILURE: "Please make sure you're logged in",
+ SERVER_HYDRATE_FAILURE: "Please make sure you're logged in",
+ SERVER_VIEWER_DATA_ERROR:
+ "We're havign trouble fetching your information right now. Please try again",
//Sign-in
SIGN_IN: "Your username/password can't be blank",
+ SERVER_SIGN_IN: "Your username/password can't be blank",
SIGN_IN_USER_NOT_FOUND: "Sorry, that user doesn't exist!",
+ SERVER_SIGN_IN_USER_NOT_FOUND: "Sorry, that user doesn't exist!",
SIGN_IN_AUTH: "Incorrect password",
+ SERVER_SIGN_IN_AUTH: "Incorrect password",
+
+ //Activity
+ CREATE_ACTIVITY:
+ "We're having issues posting that right now. Please try again",
+ DELETE_ACTIVITY_BY_ID: "We weren't able to delete that. Please try again",
+ GET_ACTIVITY_BY_ID:
+ "We weren't able to fetch that information. Please try again",
+ GET_ACTIVITY_FOR_SLATE_ID:
+ "We weren't able to fetch that information. Please try again",
+ GET_ACTIVITY_FOR_USER_ID:
+ "We weren't able to fetch that user's information. Please try again",
+
+ //Subscription Create
+ CREATE_SUBSCRIPTION:
+ "We weren't able to subscribe you. Please try again later",
+ SERVER_SUBSCRIBE: "Please login to subscribe",
+ SERVER_SUBSCRIBE_USER_NOT_FOUND:
+ "We're having trouble fetching your information. Please try again later",
+ SERVER_SUBSCRIBE_MUST_PROVIDE_SLATE_OR_USER:
+ "No user or slate was provided. Please check your input",
+ SERVER_SUBSCRIBE_CAN_NOT_SUBSCRIBE_TO_YOURSELF:
+ "You cannot subscribe to yourself",
+ SERVER_SUBSCRIBE_TARGET_USER_NOT_FOUND: "That user could not be found",
+ SERVER_SUBSCRIBE_TARGET_SLATE_NOT_FOUND: "That slate could not be found",
+ SERVER_SUBSCRIBE_SUBSCRIPTION_CHECK_ERROR:
+ "We weren't able to subscribe you. Please try again later",
+ SERVER_UNSUBSCRIBE_NOT_FOUND:
+ "We weren't able to unsubscribe you. Please try again",
+ SERVER_UNSUBSCRIBE_ERROR:
+ "We weren't able to unsubscribe you. Please try again",
+ SERVER_SUBSCRIBE_NOT_FOUND:
+ "We weren't able to subscribe you. Please try again",
+ SERVER_SUBSCRIBE_ERROR: "We weren't able to subscribe you. Please try again",
+
+ //Subscription Delete
+ DELETE_SUBSCRIPTION_BY_ID:
+ "We weren't able to unsubscribe you. Please try again later",
+
+ //Subscription Get
+ GET_SUBSCRIBERS_BY_USER_ID:
+ "We weren't able to retrieve that information. Please try again later",
+ GET_SUBSCRIPTION_BY_ID:
+ "We weren't able to retrieve that subscription information. Please try again later",
+ GET_SUBSCRIPTIONS_BY_USER_ID:
+ "We weren't able to retrieve that information. Please try again later",
+ GET_SUBSCRIPTIONS_TO_SLATE_ID:
+ "We weren't able to retrieve that information. Please try again later",
+ GET_SUBSCRIPTIONS_TO_USER_ID:
+ "We weren't able to retrieve that information. Please try again later",
+
+ //Trusted Create
+ CREATE_TRUSTED_RELATIONSHIP:
+ "We weren't able to add this user as trusted. Please try again later",
+ SERVER_TRUST: "Please make sure you are logged in",
+ SERVER_TRUSTED_RELATIONSHIP_USER_NOT_FOUND:
+ "We are having trouble retrieving your information right now",
+ SERVER_TRUSTED_RELATIONSHIP_MUST_PROVIDE_SOMEONE_TO_TRUST:
+ "No user was specified",
+ SERVER_TRUSTED_RELATIONSHIP_CAN_NOT_TRUST_YOURSELF:
+ "You cannot add yourself as trusted",
+ SERVER_TRUSTED_RELATIONSHIP_TARGET_USER_NOT_FOUND:
+ "We could not locate that user. Please try again later",
+ SERVER_TRUSTED_RELATIONSHIP_CHECK_ERROR:
+ "We're having trouble adding this person as your trusted right now",
+ SERVER_TRUSTED_RELATIONSHIP_INVERTED_CHECK_ERROR:
+ "You have already received a trust request from this person. Please accept it instead",
+ SERVER_DELETE_TRUSTED_RELATIONSHIP_NOT_FOUND:
+ "There is no trust relationshp to delete",
+ SERVER_DELETE_TRUSTED_RELATIONSHIP_ERROR:
+ "We're having trouble deleting this trust relationship right now",
+ SERVER_TRUSTED_RELATIONSHIP_NOT_FOUND:
+ "We're having trouble creating this trust relationship right now",
+ SERVER_TRUSTED_RELATIONSHIP_ERROR:
+ "We're having trouble creating this trust relationship right now",
+
+ //Trusted Delete
+ DELETE_TRUSTED_RELATIONSHIP_BY_ID:
+ "We weren't able to remove this user from your trusted. Please try again later",
+ SERVER_TRUST_DELETE: "Please login to manage your trusted",
+ SERVER_TRUST_DELETE_USER_NOT_FOUND:
+ "We weren't able to locate this user. Please try again later",
+ SERVER_TRUST_DELETE_MUST_PROVIDE_ID: "Please check your input",
+
+ //Trusted Get
+ GET_TRUSTED_RELATIONSHIP_BY_ID:
+ "We're having trouble retrieving that information right now. Please try again later",
+ GET_TRUSTED_RELATIONSHIP_BY_IDS:
+ "We're having trouble retrieving that information right now. Please try again later",
+ GET_TRUSTED_RELATIONSHIPS_BY_USER_ID:
+ "We're having trouble retrieving that information right now. Please try again later",
+
+ //Trusted Update
+ UPDATE_TRUSTED_RELATIONSHIP_BY_ID:
+ "We ran into an issue while updating that information. Please try again later",
+ SERVER_TRUST_UPDATE: "Please login to mange your trusted",
+ SERVER_TRUST_UPDATE_USER_NOT_FOUND:
+ "We weren't able to locate your information. Please try again later",
+ SERVER_TRUST_UPDATE_MUST_PROVIDE_SOMEONE_TO_TRUST:
+ "Please check your input. No user was provided",
+ SERVER_TRUST_UPDATE_CAN_NOT_TRUST_YOURSELF:
+ "You cannot add yourself as a trusted peer",
+ SERVER_TRUST_UPDATE_TARGET_USER_NOT_FOUND:
+ "We weren't able to locate that user. Please try again later",
+ SERVER_TRUST_UPDATE_CHECK_ERROR:
+ "This person is already among your trusted peers",
+
+ //API Key Create
+ CREATE_API_KEY_FOR_USER_ID:
+ "We're having trouble creating your API keys right now. Please try again",
+ SERVER_GENERATE_API_KEY_AUTH: "You aren't authorized to create that API key",
+ SERVER_GENERATE_API_KEY_USER_NOT_FOUND:
+ "We ran into issues finding your information while trying to generate that API key",
+ SERVER_GENERATE_API_KEY_TOO_MANY_KEYS:
+ "You have reached the limit for number of API keys",
+ SERVER_GENERATE_API_KEY_ERROR:
+ "We ran into issues while trying to generate that API key",
+
+ //API Key Delete
+ DELETE_API_KEY_BY_ID:
+ "We're having trouble deleting that API key right now. Please try again later",
+ DELETE_API_KEYS_FOR_USER_ID:
+ "We're having trouble deleting your API keys right now. Please try again later",
+ SERVER_DELETE_API_KEY_AUTH: "You aren't authorized to delete that API key",
+ SERVER_DELETE_API_KEY_USER_NOT_FOUND:
+ "No matching API key was found for that user",
+ SERVER_DELETE_API_KEY_NOT_FOUND:
+ "No matching API key was found for that user",
+ SERVER_DELETE_API_KEY_ERROR:
+ "We ran into an issue while trying to delete that API key. Please try again",
+
+ //API Key Get
+ GET_API_KEY_BY_KEY:
+ "We weren't able to fetch that API key. Please try again later",
+ GET_API_KEY: "We weren't able to fetch that API key. Please try again later",
+ GET_API_KEYS_BY_USER_ID:
+ "We're having trouble retrieving your API keys right now. Please try again",
+
+ //Query
+ SERVER_DEEPLINK:
+ "We ran into issues while trying to retrieve that information. Please try again",
+ SERVER_DEEPLINK_ERROR:
+ "We ran into issues while trying to retrieve that information. Please try again",
+ SERVER_SEARCH_NO_QUERY:
+ "No query was entered. Please enter a query and try again",
+
+ //Add url
};
diff --git a/components/core/Alert.js b/components/core/Alert.js
new file mode 100644
index 00000000..908dffda
--- /dev/null
+++ b/components/core/Alert.js
@@ -0,0 +1,124 @@
+import * as React from "react";
+import * as Strings from "~/common/strings";
+import * as Constants from "~/common/constants";
+
+import { error } from "~/common/messages";
+
+import { css } from "@emotion/react";
+
+const STYLES_ALERT = css`
+ box-sizing: border-box;
+ z-index: ${Constants.zindex.modal};
+ position: fixed;
+ top: 56px;
+ width: calc(100% - ${Constants.sizes.navigation}px);
+ min-height: 48px;
+ background-color: ${Constants.system.red};
+ color: ${Constants.system.white};
+ padding: 12px 48px;
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+
+ @media (max-width: ${Constants.sizes.mobile}px) {
+ width: calc(100% - 60px);
+ }
+`;
+
+export class Alert extends React.Component {
+ state = {
+ alert: null,
+ };
+
+ componentDidMount = () => {
+ window.addEventListener("create-alert", this._handleCreate);
+ window.addEventListener("click", this._handleDelete);
+ };
+
+ componentWillUnmount = () => {
+ window.removeEventListener("create-alert", this._handleCreate);
+ window.removeEventListener("click", this._handleDelete);
+ };
+
+ _handleCreate = (e) => {
+ this.setState({ alert: e.detail.alert });
+ };
+
+ _handleDelete = (e) => {
+ if (this.state.alert) {
+ this.setState({ alert: null });
+ }
+ };
+
+ render() {
+ if (!this.state.alert) {
+ return null;
+ }
+ return (
+
+ {this.state.alert.message
+ ? this.state.alert.message
+ : this.state.alert.decorator
+ ? error[this.state.alert.decorator] ||
+ "Whoops something went wrong! Please try again."
+ : "Whoops something went wrong! Please try again."}
+
+ );
+ }
+}
+
+export class Confirm extends React.Component {
+ state = {
+ alert: null,
+ };
+
+ componentDidMount = () => {
+ window.addEventListener("create-alert", this._handleCreate);
+ window.addEventListener("click", this._handleDelete);
+ };
+
+ componentWillUnmount = () => {
+ window.removeEventListener("create-alert", this._handleCreate);
+ window.removeEventListener("click", this._handleDelete);
+ };
+
+ _handleCreate = (e) => {
+ this.setState({ alert: e.detail.alert });
+ };
+
+ _handleDelete = (e) => {
+ if (this.state.alert) {
+ this.setState({ alert: null });
+ }
+ };
+
+ render() {
+ if (!this.state.alert) {
+ return null;
+ }
+ return (
+
+ {this.state.alert.message
+ ? this.state.alert.message
+ : this.state.alert.decorator
+ ? error[this.state.alert.decorator] ||
+ "Whoops something went wrong! Please try again."
+ : "Whoops something went wrong! Please try again."}
+
+ );
+ }
+}
diff --git a/components/core/Application.js b/components/core/Application.js
index 983ee4d5..ba0f502e 100644
--- a/components/core/Application.js
+++ b/components/core/Application.js
@@ -115,7 +115,17 @@ export default class ApplicationPage extends React.Component {
}
_handleOnlineStatus = async () => {
- window.alert(navigator.onLine ? "online" : "offline");
+ if (navigator.onLine) {
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: { alert: { message: "Back online!", status: "INFO" } },
+ });
+ } else {
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: { alert: { message: "Offline. Trying to reconnect" } },
+ });
+ }
this.setState({ online: navigator.onLine });
};
@@ -176,8 +186,7 @@ export default class ApplicationPage extends React.Component {
this.setState({ fileLoading: true });
- // TODO(jim):
- // Refactor later
+ // TODO(jim): Refactor later
const navigation = NavigationData.generate(this.state.viewer);
const next = this.state.history[this.state.currentIndex];
const current = NavigationData.getCurrentById(navigation, next.id);
@@ -213,7 +222,14 @@ export default class ApplicationPage extends React.Component {
}
if (!files.length) {
- alert("TODO: Files not supported error");
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: {
+ message: "File type not supported. Please try a different file",
+ },
+ },
+ });
this._handleRegisterFileLoading({ fileLoading: null });
return;
}
@@ -239,7 +255,14 @@ export default class ApplicationPage extends React.Component {
const response = await Actions.hydrateAuthenticatedUser();
if (!response || response.error) {
- alert("TODO: error fetching authenticated viewer");
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: {
+ message: "We encountered issues while refreshing. Please try again",
+ },
+ },
+ });
return null;
}
@@ -299,8 +322,7 @@ export default class ApplicationPage extends React.Component {
};
_handleDeleteYourself = async () => {
- // TODO(jim):
- // Put this somewhere better for messages.
+ // TODO(jim): Put this somewhere better for messages.
const message =
"Do you really want to delete your account? It will be permanently removed";
if (!window.confirm(message)) {
@@ -391,11 +413,17 @@ export default class ApplicationPage extends React.Component {
}
if (options.type === "ACTION") {
- return alert(JSON.stringify(options));
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: { alert: { message: JSON.stringify(options), status: "INFO" } },
+ });
}
if (options.type === "DOWNLOAD") {
- return alert(JSON.stringify(options));
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: { alert: { message: JSON.stringify(options), status: "INFO" } },
+ });
}
if (options.type === "SIDEBAR") {
@@ -405,7 +433,7 @@ export default class ApplicationPage extends React.Component {
});
}
- return alert(JSON.stringify(options));
+ return alert(JSON.stringify(options)); //TODO(martina): convert to alert?
};
_handleNavigateTo = (next, data = null) => {
diff --git a/components/core/ApplicationLayout.js b/components/core/ApplicationLayout.js
index 725a58b3..0ef5fba6 100644
--- a/components/core/ApplicationLayout.js
+++ b/components/core/ApplicationLayout.js
@@ -5,6 +5,7 @@ import * as SVG from "~/common/svg";
import { css } from "@emotion/react";
import { GlobalTooltip } from "~/components/system/components/fragments/GlobalTooltip";
import { Boundary } from "~/components/system/components/fragments/Boundary";
+import { Alert } from "~/components/core/Alert";
const STYLES_SCROLL = css`
overflow-y: scroll;
@@ -197,6 +198,7 @@ export default class ApplicationLayout extends React.Component {
+
{this.props.header}
- {/* //change this to allways allow uploads */}
+
)}
- {/* maybe send an alert if fails here */}
))
diff --git a/components/sidebars/SidebarCreatePaymentChannel.js b/components/sidebars/SidebarCreatePaymentChannel.js
index 63389589..a9a43b00 100644
--- a/components/sidebars/SidebarCreatePaymentChannel.js
+++ b/components/sidebars/SidebarCreatePaymentChannel.js
@@ -5,6 +5,7 @@ import * as SVG from "~/common/svg";
import * as System from "~/components/system";
import { css } from "@emotion/react";
+import { dispatchCustomEvent } from "~/common/custom-events";
const STYLES_FOCUS = css`
font-size: ${Constants.typescale.lvl1};
@@ -31,7 +32,12 @@ export default class SidebarCreatePaymentChannel extends React.Component {
state = { address: "", amount: "" };
_handleSubmit = () => {
- alert("TODO: Create a new payment channel");
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: { message: "Creating payment channel...", status: "INFO" },
+ },
+ });
this.props.onSubmit({});
};
diff --git a/components/sidebars/SidebarCreateSlate.js b/components/sidebars/SidebarCreateSlate.js
index 2ad3c3ca..30a116dd 100644
--- a/components/sidebars/SidebarCreateSlate.js
+++ b/components/sidebars/SidebarCreateSlate.js
@@ -4,6 +4,8 @@ import * as Constants from "~/common/constants";
import * as System from "~/components/system";
import * as Validations from "~/common/validations";
+import { dispatchCustomEvent } from "~/common/custom-events";
+
const SLATE_LIMIT = 20;
export default class SidebarCreateSlate extends React.Component {
@@ -14,14 +16,24 @@ export default class SidebarCreateSlate extends React.Component {
_handleSubmit = async () => {
if (this.props.viewer.slates.length >= SLATE_LIMIT) {
- alert("You have reached the limit of 20 Slates.");
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: { message: "You have reached the limit of 20 Slates!" },
+ },
+ });
return;
}
this.setState({ loading: true });
if (!Validations.slatename(this.state.name)) {
- alert("Please provide a name under 48 characters.");
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: { message: "Please provide a name under 48 characters." },
+ },
+ });
this.setState({ loading: false });
return;
}
@@ -31,10 +43,24 @@ export default class SidebarCreateSlate extends React.Component {
name: this.state.name,
});
- if (response && response.error) {
- alert(
- "Something went wrong while trying to create your new slate. Please try again."
- );
+ if (!response) {
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: {
+ message:
+ "We're having trouble connecting right now. Please try again later",
+ },
+ },
+ });
+ return;
+ }
+
+ if (response.error) {
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: { alert: { decorator: response.decorator } },
+ });
return;
}
diff --git a/components/sidebars/SidebarDeleteWalletAddress.js b/components/sidebars/SidebarDeleteWalletAddress.js
index 65447d6b..59569f03 100644
--- a/components/sidebars/SidebarDeleteWalletAddress.js
+++ b/components/sidebars/SidebarDeleteWalletAddress.js
@@ -5,10 +5,16 @@ import * as SVG from "~/common/svg";
import * as System from "~/components/system";
import { css } from "@emotion/react";
+import { dispatchCustomEvent } from "~/common/custom-events";
export default class SidebarDeleteWalletAddress extends React.Component {
_handleSubmit = () => {
- alert("TODO: Delete wallet address");
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: { message: "Deleting wallet address...", status: "INFO" },
+ },
+ });
this.props.onSubmit({});
};
diff --git a/components/sidebars/SidebarFilecoinArchive.js b/components/sidebars/SidebarFilecoinArchive.js
index a34b6af1..4fac2eb4 100644
--- a/components/sidebars/SidebarFilecoinArchive.js
+++ b/components/sidebars/SidebarFilecoinArchive.js
@@ -6,6 +6,7 @@ import * as SVG from "~/common/svg";
import * as System from "~/components/system";
import { css } from "@emotion/react";
+import { dispatchCustomEvent } from "~/common/custom-events";
export default class SidebarFilecoinArchive extends React.Component {
async componentDidMount() {}
@@ -13,7 +14,12 @@ export default class SidebarFilecoinArchive extends React.Component {
_handleMakeDeal = async () => {
const response = await Actions.archive();
console.log(response);
- alert("TODO: Still working on archiving issues.");
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: { message: "Deal archiving is still under development" },
+ },
+ });
};
_handleSubmit = async (e) => {
diff --git a/components/sidebars/SidebarSingleSlateSettings.js b/components/sidebars/SidebarSingleSlateSettings.js
index 7dbf66b3..1c8aa814 100644
--- a/components/sidebars/SidebarSingleSlateSettings.js
+++ b/components/sidebars/SidebarSingleSlateSettings.js
@@ -5,6 +5,7 @@ import * as System from "~/components/system";
import * as Strings from "~/common/strings";
import { css } from "@emotion/react";
+import { dispatchCustomEvent } from "~/common/custom-events";
const STYLES_GROUP = css`
display: flex;
@@ -56,12 +57,23 @@ export default class SidebarSingleSlateSettings extends React.Component {
});
if (!response) {
- alert("TODO: Server Error");
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: {
+ message:
+ "We're having trouble connecting right now. Please try again later",
+ },
+ },
+ });
return this.setState({ loading: false });
}
if (response.error) {
- alert(`TODO: ${response.decorator}`);
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: { alert: { decorator: response.decorator } },
+ });
return this.setState({ loading: false });
}
@@ -92,12 +104,23 @@ export default class SidebarSingleSlateSettings extends React.Component {
});
if (!response) {
- alert("TODO: Server Error");
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: {
+ message:
+ "We're having trouble connecting right now. Please try again later",
+ },
+ },
+ });
return this.setState({ loading: false });
}
if (response.error) {
- alert(`TODO: ${response.decorator}`);
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: { alert: { decorator: response.decorator } },
+ });
return this.setState({ loading: false });
}
diff --git a/components/sidebars/SidebarWalletSendFunds.js b/components/sidebars/SidebarWalletSendFunds.js
index 80ae0917..da36a75d 100644
--- a/components/sidebars/SidebarWalletSendFunds.js
+++ b/components/sidebars/SidebarWalletSendFunds.js
@@ -4,6 +4,7 @@ import * as Constants from "~/common/constants";
import * as System from "~/components/system";
import { css } from "@emotion/react";
+import { dispatchCustomEvent } from "~/common/custom-events";
const STYLES_FOCUS = css`
font-size: ${Constants.typescale.lvl1};
@@ -43,9 +44,15 @@ export default class SidebarWalletSendFunds extends React.Component {
const currentAddress = addresses[this.props.selected.address];
if (currentAddress.address === this.state.address) {
- alert(
- "TODO: Proper message for not allowing poeple to send funds to the same address."
- );
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: {
+ message:
+ "You cannot send funds from an address to itself. Please enter a different address",
+ },
+ },
+ });
this.setState({ loading: false });
return;
diff --git a/components/system/components/Typography.js b/components/system/components/Typography.js
index 8461c6c2..8288884b 100644
--- a/components/system/components/Typography.js
+++ b/components/system/components/Typography.js
@@ -4,6 +4,7 @@ import * as Actions from "~/common/actions";
import * as StringReplace from "~/vendor/react-string-replace";
import { css } from "@emotion/react";
+import { dispatchCustomEvent } from "~/common/custom-events";
const LINK_STYLES = `
font-family: ${Constants.font.text};
@@ -37,12 +38,38 @@ const onDeepLink = async (object) => {
deeplink: true,
});
- if (!response.data) {
- alert("TODO: Can not find deeplink");
+ if (!response) {
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: {
+ message:
+ "We're having trouble connecting right now. Please try again later",
+ },
+ },
+ });
+ return;
}
- if (!response.data.slate) {
- alert("TODO: Can not find deeplink");
+ if (response.error) {
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: { alert: { decorator: response.decorator } },
+ });
+ return;
+ }
+
+ if (!response.data || !response.data.slate) {
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: {
+ message:
+ "We encountered issues while locating that deeplink. Please try again later",
+ },
+ },
+ });
+ return;
}
return window.open(
@@ -64,7 +91,8 @@ export const ProcessedText = ({ text }) => {
css={STYLES_LINK}
key={match + i}
target="_blank"
- href={`/${match}`.toLowerCase()}>
+ href={`/${match}`.toLowerCase()}
+ >
@{match}
));
@@ -73,7 +101,8 @@ export const ProcessedText = ({ text }) => {
onDeepLink({ deeplink: match.toLowerCase() })}>
+ onClick={() => onDeepLink({ deeplink: match.toLowerCase() })}
+ >
#{match}
));
diff --git a/components/system/modules/CreateFilecoinStorageDeal.js b/components/system/modules/CreateFilecoinStorageDeal.js
index 6704b2a7..207c3307 100644
--- a/components/system/modules/CreateFilecoinStorageDeal.js
+++ b/components/system/modules/CreateFilecoinStorageDeal.js
@@ -6,6 +6,7 @@ import {
} from "~/components/system/components/Buttons";
import { css } from "@emotion/react";
+import { dispatchCustomEvent } from "~/common/custom-events";
const STYLES_CONTAINER = css`
font-family: ${Constants.font.text};
@@ -53,7 +54,16 @@ const STYLES_ITEM = css`
export class CreateFilecoinStorageDeal extends React.Component {
static defaultProps = {
- onSubmit: () => alert("onSubmit"),
+ onSubmit: () => {
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: {
+ message: "Filecoin storage deals are still under development",
+ },
+ },
+ });
+ },
};
state = { file: null };
@@ -63,7 +73,12 @@ export class CreateFilecoinStorageDeal extends React.Component {
let file = e.target.files[0];
if (!file) {
- alert("Something went wrong");
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: { message: "Something went wrong. Please try again" },
+ },
+ });
return;
}
diff --git a/pages/_/experiences/create-address.js b/pages/_/experiences/create-address.js
index 1e46c9dc..c3e1e706 100644
--- a/pages/_/experiences/create-address.js
+++ b/pages/_/experiences/create-address.js
@@ -5,6 +5,8 @@ import SystemPage from "~/components/system/SystemPage";
import ViewSourceLink from "~/components/system/ViewSourceLink";
import CodeBlock from "~/components/system/CodeBlock";
+import { dispatchCustomEvent } from "~/common/custom-events";
+
const EXAMPLE_CODE = `import * as React from "react";
import { CreateFilecoinAddress } from "slate-react-system";
import { createPow } from "@textile/powergate-client";
@@ -32,7 +34,13 @@ class Example extends React.Component {
export default class SystemPageCreateAddress extends React.Component {
_handleSubmit = ({ name, type, makeDefault }) => {
- alert(JSON.stringify({ name, type, makeDefault }));
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: { message: JSON.stringify({ name, type, makeDefault }) },
+ status: "INFO",
+ },
+ });
};
render() {
diff --git a/pages/_/experiences/filecoin-settings.js b/pages/_/experiences/filecoin-settings.js
index 95fddd7f..0802752a 100644
--- a/pages/_/experiences/filecoin-settings.js
+++ b/pages/_/experiences/filecoin-settings.js
@@ -5,6 +5,8 @@ import SystemPage from "~/components/system/SystemPage";
import ViewSourceLink from "~/components/system/ViewSourceLink";
import CodeBlock from "~/components/system/CodeBlock";
+import { dispatchCustomEvent } from "~/common/custom-events";
+
const addrsList = [
{
addr:
@@ -82,7 +84,11 @@ class Example extends React.Component {
export default class SystemPageFilecoinSettings extends React.Component {
_handleSave = async (storageConfig) => {
- alert("Saved");
+ // TODO(jim): Send setings data to server.
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: { alert: { message: "Saved!", status: "INFO" } },
+ });
};
render() {
diff --git a/pages/_/experiences/make-storage-deal.js b/pages/_/experiences/make-storage-deal.js
index c4824e3b..7de1cf58 100644
--- a/pages/_/experiences/make-storage-deal.js
+++ b/pages/_/experiences/make-storage-deal.js
@@ -5,6 +5,8 @@ import SystemPage from "~/components/system/SystemPage";
import ViewSourceLink from "~/components/system/ViewSourceLink";
import CodeBlock from "~/components/system/CodeBlock";
+import { dispatchCustomEvent } from "~/common/custom-events";
+
const EXAMPLE_CODE = `import * as React from "react";
import { CreateFilecoinStorageDeal } from "slate-react-system";
import { createPow } from "@textile/powergate-client";
@@ -58,7 +60,12 @@ class Example extends React.Component {
export default class SystemPageMakeStorageDeal extends React.Component {
_handleSubmit = async ({ file }) => {
// TODO(jim): Send file data to server.
- alert(file);
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: { message: "Storage deals are still under development" },
+ },
+ });
};
render() {
diff --git a/pages/_/experiences/send-address-filecoin.js b/pages/_/experiences/send-address-filecoin.js
index a8d621c6..766785fd 100644
--- a/pages/_/experiences/send-address-filecoin.js
+++ b/pages/_/experiences/send-address-filecoin.js
@@ -5,6 +5,8 @@ import SystemPage from "~/components/system/SystemPage";
import ViewSourceLink from "~/components/system/ViewSourceLink";
import CodeBlock from "~/components/system/CodeBlock";
+import { dispatchCustomEvent } from "~/common/custom-events";
+
const EXAMPLE_CODE = `import * as React from "react";
import { SendAddressFilecoin } from "slate-react-system";
import { createPow } from "@textile/powergate-client";
@@ -31,7 +33,15 @@ class Example extends React.Component {
export default class SystemPageSendAddressFilecoin extends React.Component {
_handleSubmit = ({ source, target, amount }) => {
- alert(JSON.stringify({ source, target, amount }));
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: {
+ message: JSON.stringify({ source, target, amount }),
+ status: "INFO",
+ },
+ },
+ });
};
render() {
diff --git a/pages/_/integration-page.js b/pages/_/integration-page.js
index 7d134623..e0362f70 100644
--- a/pages/_/integration-page.js
+++ b/pages/_/integration-page.js
@@ -4,6 +4,7 @@ import * as System from "~/components/system";
import * as Actions from "~/common/actions";
import { css } from "@emotion/react";
+import { dispatchCustomEvent } from "~/common/custom-events";
const STYLES_ITEM = css`
font-size: 12px;
@@ -53,11 +54,26 @@ export default class IntegrationPage extends React.Component {
_handleUpdate = async (e) => {
const response = await Actions.hydrateAuthenticatedUser();
- if (!response || response.error) {
- alert("TODO: error fetching authenticated viewer");
+ if (!response) {
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: {
+ message:
+ "We're having trouble connecting right now. Please try again later",
+ },
+ },
+ });
return null;
}
+ if (response.error) {
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: { alert: { decorator: response.decorator } },
+ });
+ }
+
const updates = {
viewer: response.data,
};
diff --git a/pages/api/addresses/send.js b/pages/api/addresses/send.js
index cecc0ad9..f9b66d82 100644
--- a/pages/api/addresses/send.js
+++ b/pages/api/addresses/send.js
@@ -7,7 +7,7 @@ export default async (req, res) => {
if (!id) {
return res
.status(500)
- .send({ decorator: "SERVER_SEND_FILECOIN", error: true });
+ .send({ decorator: "SERVER_SEND_FILECOIN_NO_ID", error: true });
}
const user = await Data.getUserById({
diff --git a/pages/api/users/delete.js b/pages/api/users/delete.js
index e8c919cf..aa7b1471 100644
--- a/pages/api/users/delete.js
+++ b/pages/api/users/delete.js
@@ -56,7 +56,7 @@ export default async (req, res) => {
if (!deleted) {
return res
- .status(200)
+ .status(500)
.send({ decorator: "SERVER_USER_DELETE", error: true });
}
diff --git a/scenes/SceneEditAccount.js b/scenes/SceneEditAccount.js
index 893ca885..0cf4c461 100644
--- a/scenes/SceneEditAccount.js
+++ b/scenes/SceneEditAccount.js
@@ -7,6 +7,7 @@ import * as Validations from "~/common/validations";
import * as FileUtilities from "~/common/file-utilities";
import { css } from "@emotion/react";
+import { dispatchCustomEvent } from "~/common/custom-events";
import ScenePage from "~/components/core/ScenePage";
import Avatar from "~/components/core/Avatar";
@@ -48,20 +49,35 @@ export default class SceneEditAccount extends React.Component {
let file = e.target.files[0];
if (!file) {
- alert("TODO: Something went wrong");
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: {
+ message: "Something went wrong with the upload. Please try again",
+ },
+ },
+ });
return;
}
// NOTE(jim): Only allow images for account avatar.
if (!file.type.startsWith("image/")) {
- alert("TODO: Error message for not an image.");
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: { message: "Upload failed. Only images and gifs are allowed" },
+ },
+ });
return;
}
const json = await FileUtilities.upload({ file });
if (json.error) {
- alert("TODO: Image already exists in bucket error message");
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: { alert: { decorator: json.decorator } },
+ });
this.setState({ changingAvatar: false });
return;
}
@@ -100,7 +116,14 @@ export default class SceneEditAccount extends React.Component {
this.setState({ changingUsername: true });
if (!Validations.username(this.state.username)) {
- alert("TODO: Not a valid username");
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: {
+ message: "Please include only letters and numbers in your username",
+ },
+ },
+ });
this.setState({ changingUsername: false });
return;
}
@@ -126,13 +149,21 @@ export default class SceneEditAccount extends React.Component {
_handleChangePassword = async (e) => {
this.setState({ changingPassword: true });
if (this.state.password !== this.state.confirm) {
- alert("TODO: Error message for non-matching passwords");
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: { alert: { message: "Passwords did not match" } },
+ });
this.setState({ changingPassword: false });
return;
}
if (!Validations.password(this.state.password)) {
- alert("TODO: Not a valid password");
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: { message: "Password length must be more than 8 characters" },
+ },
+ });
this.setState({ changingPassword: false });
return;
}
diff --git a/scenes/SceneProfile.js b/scenes/SceneProfile.js
index 1f0a6b85..37cfac8f 100644
--- a/scenes/SceneProfile.js
+++ b/scenes/SceneProfile.js
@@ -9,6 +9,7 @@ import {
ButtonPrimary,
ButtonSecondary,
} from "~/components/system/components/Buttons";
+import { dispatchCustomEvent } from "~/common/custom-events";
import ScenePage from "~/components/core/ScenePage";
import Profile from "~/components/core/Profile";
@@ -75,8 +76,24 @@ export default class SceneProfile extends React.Component {
_handleUpdate = async (e) => {
let response = await this.props.onRehydrate();
- if (!response || response.error) {
- alert("TODO: error fetching authenticated viewer");
+ if (!response) {
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: {
+ message:
+ "We're having trouble connecting right now. Please try again later",
+ },
+ },
+ });
+ return null;
+ }
+
+ if (response.error) {
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: { alert: { decorator: response.decorator } },
+ });
return null;
}
diff --git a/scenes/SceneSettingsDeveloper.js b/scenes/SceneSettingsDeveloper.js
index c69a1a28..d28e826f 100644
--- a/scenes/SceneSettingsDeveloper.js
+++ b/scenes/SceneSettingsDeveloper.js
@@ -5,6 +5,7 @@ import * as System from "~/components/system";
import * as SVG from "~/common/svg";
import { css } from "@emotion/react";
+import { dispatchCustomEvent } from "~/common/custom-events";
import ScenePage from "~/components/core/ScenePage";
import ScenePageHeader from "~/components/core/ScenePageHeader";
@@ -83,7 +84,8 @@ class Key extends React.Component {
onClick={this._handleToggleVisible}
style={{
marginRight: 8,
- }}>
+ }}
+ >
this._handleDelete(this.props.data.id)}
style={{
marginRight: 4,
- }}>
+ }}
+ >
@@ -192,9 +195,24 @@ export default class SceneSettingsDeveloper extends React.Component {
this.setState({ loading: true });
const response = await Actions.generateAPIKey();
- if (response && response.error) {
- // TODO(jim): Proper error message.
- alert(response.decorator);
+ if (!response) {
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: {
+ message:
+ "We're having trouble connecting right now. Please try again later",
+ },
+ },
+ });
+ return this.setState({ loading: false });
+ }
+
+ if (response.error) {
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: { alert: { decorator: response.decorator } },
+ });
return this.setState({ loading: false });
}
@@ -216,15 +234,26 @@ export default class SceneSettingsDeveloper extends React.Component {
}
const response = await Actions.deleteAPIKey({ id });
- if (response && response.error) {
- // TODO(jim): Proper error message.
- alert(response.decorator);
+ if (!response) {
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: {
+ message:
+ "We're having trouble connecting right now. Please try again later",
+ },
+ },
+ });
return this.setState({ loading: false });
}
- await this.props.onRehydrate();
-
- this.setState({ loading: false });
+ if (response.error) {
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: { alert: { decorator: response.decorator } },
+ });
+ return this.setState({ loading: false });
+ }
};
async componentDidMount() {
@@ -278,7 +307,8 @@ export default class SceneSettingsDeveloper extends React.Component {
+ loading={this.state.loading}
+ >
Generate
diff --git a/scenes/SceneSignIn.js b/scenes/SceneSignIn.js
index 932f7677..ccd9e248 100644
--- a/scenes/SceneSignIn.js
+++ b/scenes/SceneSignIn.js
@@ -7,6 +7,7 @@ import * as Strings from "~/common/strings";
import { css } from "@emotion/react";
import { Logo } from "~/common/logo";
+import { dispatchCustomEvent } from "~/common/custom-events";
import WebsitePrototypeHeader from "~/components/core/WebsitePrototypeHeader";
import WebsitePrototypeFooter from "~/components/core/WebsitePrototypeFooter";
@@ -123,15 +124,25 @@ export default class SceneSignIn extends React.Component {
await delay(100);
if (!Validations.username(this.state.username)) {
- alert(
- "Your username was invalid, only characters and numbers are allowed."
- );
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: {
+ message: "Only characters and numbers are allowed in usernames",
+ },
+ },
+ });
this.setState({ loading: false });
return;
}
if (!Validations.password(this.state.password)) {
- alert("Your password must be at least 8 characters.");
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: { message: "Your password must be at least 8 characters" },
+ },
+ });
this.setState({ loading: false });
return;
}
@@ -141,8 +152,25 @@ export default class SceneSignIn extends React.Component {
password: this.state.password,
});
- if (!response || response.error) {
- alert("We could not sign you into your account, try again later.");
+ if (!response) {
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: {
+ message:
+ "We could not sign you into your account, try again later.",
+ },
+ },
+ });
+ this.setState({ loading: false });
+ return;
+ }
+
+ if (response.error) {
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: { alert: { decorator: response.decorator } },
+ });
this.setState({ loading: false });
return;
}
diff --git a/scenes/SceneSlate.js b/scenes/SceneSlate.js
index 24f66216..32cd434e 100644
--- a/scenes/SceneSlate.js
+++ b/scenes/SceneSlate.js
@@ -182,12 +182,23 @@ export default class SceneSlate extends React.Component {
if (!response) {
this.setState({ loading: false, saving: "ERROR" });
- alert("TODO: Server Error");
+ System.dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: {
+ message:
+ "We're having trouble connecting right now. Please try again later",
+ },
+ },
+ });
}
if (response.error) {
this.setState({ loading: false, saving: "ERROR" });
- alert(`TODO: ${response.decorator}`);
+ System.dispatchCustomEvent({
+ name: "create-alert",
+ detail: { alert: { decorator: response.decorator } },
+ });
}
await this.props.onRehydrate();
@@ -297,7 +308,15 @@ export default class SceneSlate extends React.Component {
name: "state-global-carousel-loading",
detail: { loading: false },
});
- alert("TODO: Server Error");
+ System.dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: {
+ message:
+ "We're having trouble connecting right now. Please try again later",
+ },
+ },
+ });
}
if (response.error) {
@@ -305,7 +324,10 @@ export default class SceneSlate extends React.Component {
name: "state-global-carousel-loading",
detail: { loading: false },
});
- alert(`TODO: ${response.decorator}`);
+ System.dispatchCustomEvent({
+ name: "create-alert",
+ detail: { alert: { decorator: response.decorator } },
+ });
}
this._handleUpdateCarousel({
@@ -358,13 +380,36 @@ export default class SceneSlate extends React.Component {
deeplink: true,
});
- if (!response.data) {
- alert("Could not find Slate.");
+ if (!response || !response.data) {
+ System.dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: {
+ message:
+ "We're having trouble finding that slate right now. Please try again later",
+ },
+ },
+ });
return;
}
+ if (response.error) {
+ System.dispatchCustomEvent({
+ name: "create-alert",
+ detail: { alert: { decorator: response.decorator } },
+ });
+ }
+
if (!response.data.slate) {
- alert("Could not find Slate.");
+ System.dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: {
+ message:
+ "We're having trouble finding that slate right now. Please try again later",
+ },
+ },
+ });
return;
}
diff --git a/scenes/SceneWallet.js b/scenes/SceneWallet.js
index aba70818..88e2120c 100644
--- a/scenes/SceneWallet.js
+++ b/scenes/SceneWallet.js
@@ -5,6 +5,7 @@ import * as SVG from "~/common/svg";
import * as System from "~/components/system";
import { css } from "@emotion/react";
+import { dispatchCustomEvent } from "~/common/custom-events";
import Section from "~/components/core/Section";
import ScenePage from "~/components/core/ScenePage";
@@ -101,7 +102,10 @@ export default class SceneWallet extends React.Component {
_handleCopy = (text) => {
Strings.copyText(text);
- alert(`${text} Added to clipboard.`);
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: { alert: { message: "Copied to clipboard!", status: "INFO" } },
+ });
};
render() {