switched alerts to Alert component

This commit is contained in:
Martina 2020-09-11 15:25:33 -07:00
parent 1503277783
commit b05f42fcbb
25 changed files with 594 additions and 98 deletions

View File

@ -1,3 +1,5 @@
import { dispatchCustomEvent } from "~/common/custom-events";
export const upload = async ({ file, slate, context }) => { export const upload = async ({ file, slate, context }) => {
let formData = new FormData(); let formData = new FormData();
const HEIC2ANY = require("heic2any"); 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 } }), body: JSON.stringify({ slate, data: { title: file.name, ...json.data } }),
}); });
if (!addResponse || addResponse.error) { if (!addResponse) {
console.log(addResponse.error); dispatchCustomEvent({
alert("TODO: Adding an image to Slate went wrong."); 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 } },
});
} }
} }

View File

@ -73,3 +73,52 @@ export class Alert extends React.Component {
); );
} }
} }
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 (
<div
css={STYLES_ALERT}
style={
this.state.alert.status === "INFO"
? { backgroundColor: Constants.system.brand }
: null
}
>
{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."}
</div>
);
}
}

View File

@ -115,7 +115,17 @@ export default class ApplicationPage extends React.Component {
} }
_handleOnlineStatus = async () => { _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 }); this.setState({ online: navigator.onLine });
}; };
@ -176,8 +186,7 @@ export default class ApplicationPage extends React.Component {
this.setState({ fileLoading: true }); this.setState({ fileLoading: true });
// TODO(jim): // TODO(jim): Refactor later
// Refactor later
const navigation = NavigationData.generate(this.state.viewer); const navigation = NavigationData.generate(this.state.viewer);
const next = this.state.history[this.state.currentIndex]; const next = this.state.history[this.state.currentIndex];
const current = NavigationData.getCurrentById(navigation, next.id); const current = NavigationData.getCurrentById(navigation, next.id);
@ -213,7 +222,14 @@ export default class ApplicationPage extends React.Component {
} }
if (!files.length) { 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 }); this._handleRegisterFileLoading({ fileLoading: null });
return; return;
} }
@ -239,7 +255,14 @@ export default class ApplicationPage extends React.Component {
const response = await Actions.hydrateAuthenticatedUser(); const response = await Actions.hydrateAuthenticatedUser();
if (!response || response.error) { 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; return null;
} }
@ -299,8 +322,7 @@ export default class ApplicationPage extends React.Component {
}; };
_handleDeleteYourself = async () => { _handleDeleteYourself = async () => {
// TODO(jim): // TODO(jim): Put this somewhere better for messages.
// Put this somewhere better for messages.
const message = const message =
"Do you really want to delete your account? It will be permanently removed"; "Do you really want to delete your account? It will be permanently removed";
if (!window.confirm(message)) { if (!window.confirm(message)) {
@ -391,11 +413,17 @@ export default class ApplicationPage extends React.Component {
} }
if (options.type === "ACTION") { 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") { 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") { 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) => { _handleNavigateTo = (next, data = null) => {

View File

@ -235,8 +235,22 @@ export default class DataView extends React.Component {
body: JSON.stringify({ slate, data: { title: data.name, ...data } }), body: JSON.stringify({ slate, data: { title: data.name, ...data } }),
}); });
if (!addResponse || addResponse.error) { if (!addResponse) {
alert("We could not add this object to your slate."); dispatchCustomEvent({
name: "create-alert",
detail: {
alert: {
message:
"We're having trouble connecting right now. Please try again later",
},
},
});
return null;
} else if (addResponse.error) {
dispatchCustomEvent({
name: "create-alert",
detail: { alert: { decorator: addResponse.decorator } },
});
return null; return null;
} }
@ -279,7 +293,15 @@ export default class DataView extends React.Component {
detail: { loading: false }, detail: { loading: false },
}); });
alert("We failed to remove the object from your Slate."); dispatchCustomEvent({
name: "create-alert",
detail: {
alert: {
message:
"We're having trouble connecting right now and weren't able to delete that. Please try again later",
},
},
});
return null; return null;
} }
@ -289,7 +311,14 @@ export default class DataView extends React.Component {
detail: { loading: false }, detail: { loading: false },
}); });
alert("We failed to remove the object from your Slate."); dispatchCustomEvent({
name: "create-alert",
detail: {
alert: {
decorator: response.decorator,
},
},
});
return null; return null;
} }
@ -354,13 +383,24 @@ export default class DataView extends React.Component {
if (!response) { if (!response) {
this._handleLoading({ cid }); this._handleLoading({ cid });
alert("TODO: Broken response error"); dispatchCustomEvent({
name: "create-alert",
detail: {
alert: {
message:
"We're having trouble connecting right now. Please try again later",
},
},
});
return null; return null;
} }
if (response.error) { if (response.error) {
this._handleLoading({ cid }); this._handleLoading({ cid });
alert("TODO: Bucket delete error"); dispatchCustomEvent({
name: "create-alert",
detail: { alert: { decorator: response.decorator } },
});
return null; return null;
} }

View File

@ -6,6 +6,7 @@ import * as Actions from "~/common/actions";
import { Responsive, WidthProvider } from "react-grid-layout"; import { Responsive, WidthProvider } from "react-grid-layout";
import { css } from "@emotion/react"; import { css } from "@emotion/react";
import { LoaderSpinner } from "~/components/system/components/Loaders"; import { LoaderSpinner } from "~/components/system/components/Loaders";
import { dispatchCustomEvent } from "~/common/custom-events";
import SlateMediaObjectPreview from "~/components/core/SlateMediaObjectPreview"; import SlateMediaObjectPreview from "~/components/core/SlateMediaObjectPreview";
import CircleButtonGray from "~/components/core/CircleButtonGray"; import CircleButtonGray from "~/components/core/CircleButtonGray";
@ -164,12 +165,35 @@ export default class Slate extends React.Component {
}); });
if (!response.data) { if (!response.data) {
alert("Could not find Slate."); dispatchCustomEvent({
name: "create-alert",
detail: {
alert: {
message:
"We're having trouble connecting right now and could not locate that slate. Please try again later",
},
},
});
return;
}
if (response.error) {
dispatchCustomEvent({
name: "create-alert",
detail: { alert: { decorator: response.decorator } },
});
return; return;
} }
if (!response.data.slate) { if (!response.data.slate) {
alert("Could not find Slate."); dispatchCustomEvent({
name: "create-alert",
detail: {
alert: {
message: "We could not locate that slate. Please try again later",
},
},
});
return; return;
} }

View File

@ -73,15 +73,25 @@ export default class SidebarAddFileToBucket extends React.Component {
let file = e.target.files[i]; let file = e.target.files[i];
if (!file) { if (!file) {
alert("We could not find any files to upload."); dispatchCustomEvent({
name: "create-alert",
detail: {
alert: { message: "We could not find any files to upload." },
},
});
continue; continue;
} }
const isAllowed = Validations.isFileTypeAllowed(file.type); const isAllowed = Validations.isFileTypeAllowed(file.type);
if (!isAllowed) { if (!isAllowed) {
alert( dispatchCustomEvent({
`We currently do not accept ${file.type} yet but may in the future.` name: "create-alert",
); detail: {
alert: {
message: `We currently do not accept ${file.type} yet but may in the future!`,
},
},
});
continue; continue;
} }
@ -94,7 +104,12 @@ export default class SidebarAddFileToBucket extends React.Component {
} }
if (!files.length) { if (!files.length) {
alert("We could not find any files to upload."); dispatchCustomEvent({
name: "create-alert",
detail: {
alert: { message: "We could not find any files to upload." },
},
});
// return this.props.onRegisterFileLoading({ fileLoading: null }); // return this.props.onRegisterFileLoading({ fileLoading: null });
} }
@ -113,16 +128,23 @@ export default class SidebarAddFileToBucket extends React.Component {
}); });
if (!response) { if (!response) {
alert( dispatchCustomEvent({
"Something went wrong with saving your new file. Please refresh your browser." name: "create-alert",
); detail: {
alert: {
message:
"Something went wrong while saving your new file. Please refresh your browser.",
},
},
});
continue; continue;
} }
if (response.error) { if (response.error) {
alert( dispatchCustomEvent({
"Something went wrong with saving your new file. Please refresh your browser." name: "create-alert",
); detail: { alert: { decorator: response.decorator } },
});
continue; continue;
} }
} }
@ -188,7 +210,7 @@ export default class SidebarAddFileToBucket extends React.Component {
)} )}
. .
</System.P> </System.P>
{/* //change this to allways allow uploads */}
<System.ButtonPrimary <System.ButtonPrimary
full full
type="label" type="label"
@ -228,7 +250,6 @@ export default class SidebarAddFileToBucket extends React.Component {
style={{ width: "20px", height: "20px", margin: "2px" }} style={{ width: "20px", height: "20px", margin: "2px" }}
/> />
)} )}
{/* maybe send an alert if fails here */}
</div> </div>
</div> </div>
)) ))

View File

@ -5,6 +5,7 @@ import * as SVG from "~/common/svg";
import * as System from "~/components/system"; import * as System from "~/components/system";
import { css } from "@emotion/react"; import { css } from "@emotion/react";
import { dispatchCustomEvent } from "~/common/custom-events";
const STYLES_FOCUS = css` const STYLES_FOCUS = css`
font-size: ${Constants.typescale.lvl1}; font-size: ${Constants.typescale.lvl1};
@ -31,7 +32,12 @@ export default class SidebarCreatePaymentChannel extends React.Component {
state = { address: "", amount: "" }; state = { address: "", amount: "" };
_handleSubmit = () => { _handleSubmit = () => {
alert("TODO: Create a new payment channel"); dispatchCustomEvent({
name: "create-alert",
detail: {
alert: { message: "Creating payment channel...", status: "INFO" },
},
});
this.props.onSubmit({}); this.props.onSubmit({});
}; };

View File

@ -4,6 +4,8 @@ import * as Constants from "~/common/constants";
import * as System from "~/components/system"; import * as System from "~/components/system";
import * as Validations from "~/common/validations"; import * as Validations from "~/common/validations";
import { dispatchCustomEvent } from "~/common/custom-events";
const SLATE_LIMIT = 20; const SLATE_LIMIT = 20;
export default class SidebarCreateSlate extends React.Component { export default class SidebarCreateSlate extends React.Component {
@ -14,14 +16,24 @@ export default class SidebarCreateSlate extends React.Component {
_handleSubmit = async () => { _handleSubmit = async () => {
if (this.props.viewer.slates.length >= SLATE_LIMIT) { 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; return;
} }
this.setState({ loading: true }); this.setState({ loading: true });
if (!Validations.slatename(this.state.name)) { 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 }); this.setState({ loading: false });
return; return;
} }
@ -31,10 +43,24 @@ export default class SidebarCreateSlate extends React.Component {
name: this.state.name, name: this.state.name,
}); });
if (response && response.error) { if (!response) {
alert( dispatchCustomEvent({
"Something went wrong while trying to create your new slate. Please try again." 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; return;
} }

View File

@ -5,10 +5,16 @@ import * as SVG from "~/common/svg";
import * as System from "~/components/system"; import * as System from "~/components/system";
import { css } from "@emotion/react"; import { css } from "@emotion/react";
import { dispatchCustomEvent } from "~/common/custom-events";
export default class SidebarDeleteWalletAddress extends React.Component { export default class SidebarDeleteWalletAddress extends React.Component {
_handleSubmit = () => { _handleSubmit = () => {
alert("TODO: Delete wallet address"); dispatchCustomEvent({
name: "create-alert",
detail: {
alert: { message: "Deleting wallet address...", status: "INFO" },
},
});
this.props.onSubmit({}); this.props.onSubmit({});
}; };

View File

@ -6,6 +6,7 @@ import * as SVG from "~/common/svg";
import * as System from "~/components/system"; import * as System from "~/components/system";
import { css } from "@emotion/react"; import { css } from "@emotion/react";
import { dispatchCustomEvent } from "~/common/custom-events";
export default class SidebarFilecoinArchive extends React.Component { export default class SidebarFilecoinArchive extends React.Component {
async componentDidMount() {} async componentDidMount() {}
@ -13,7 +14,12 @@ export default class SidebarFilecoinArchive extends React.Component {
_handleMakeDeal = async () => { _handleMakeDeal = async () => {
const response = await Actions.archive(); const response = await Actions.archive();
console.log(response); 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) => { _handleSubmit = async (e) => {

View File

@ -5,6 +5,7 @@ import * as System from "~/components/system";
import * as Strings from "~/common/strings"; import * as Strings from "~/common/strings";
import { css } from "@emotion/react"; import { css } from "@emotion/react";
import { dispatchCustomEvent } from "~/common/custom-events";
const STYLES_GROUP = css` const STYLES_GROUP = css`
display: flex; display: flex;
@ -56,12 +57,23 @@ export default class SidebarSingleSlateSettings extends React.Component {
}); });
if (!response) { 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 }); return this.setState({ loading: false });
} }
if (response.error) { if (response.error) {
alert(`TODO: ${response.decorator}`); dispatchCustomEvent({
name: "create-alert",
detail: { alert: { decorator: response.decorator } },
});
return this.setState({ loading: false }); return this.setState({ loading: false });
} }
@ -92,12 +104,23 @@ export default class SidebarSingleSlateSettings extends React.Component {
}); });
if (!response) { 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 }); return this.setState({ loading: false });
} }
if (response.error) { if (response.error) {
alert(`TODO: ${response.decorator}`); dispatchCustomEvent({
name: "create-alert",
detail: { alert: { decorator: response.decorator } },
});
return this.setState({ loading: false }); return this.setState({ loading: false });
} }

View File

@ -4,6 +4,7 @@ import * as Constants from "~/common/constants";
import * as System from "~/components/system"; import * as System from "~/components/system";
import { css } from "@emotion/react"; import { css } from "@emotion/react";
import { dispatchCustomEvent } from "~/common/custom-events";
const STYLES_FOCUS = css` const STYLES_FOCUS = css`
font-size: ${Constants.typescale.lvl1}; font-size: ${Constants.typescale.lvl1};
@ -43,9 +44,15 @@ export default class SidebarWalletSendFunds extends React.Component {
const currentAddress = addresses[this.props.selected.address]; const currentAddress = addresses[this.props.selected.address];
if (currentAddress.address === this.state.address) { if (currentAddress.address === this.state.address) {
alert( dispatchCustomEvent({
"TODO: Proper message for not allowing poeple to send funds to the same address." name: "create-alert",
); detail: {
alert: {
message:
"You cannot send funds from an address to itself. Please enter a different address",
},
},
});
this.setState({ loading: false }); this.setState({ loading: false });
return; return;

View File

@ -4,6 +4,7 @@ import * as Actions from "~/common/actions";
import * as StringReplace from "~/vendor/react-string-replace"; import * as StringReplace from "~/vendor/react-string-replace";
import { css } from "@emotion/react"; import { css } from "@emotion/react";
import { dispatchCustomEvent } from "~/common/custom-events";
const LINK_STYLES = ` const LINK_STYLES = `
font-family: ${Constants.font.text}; font-family: ${Constants.font.text};
@ -37,12 +38,38 @@ const onDeepLink = async (object) => {
deeplink: true, deeplink: true,
}); });
if (!response.data) { if (!response) {
alert("TODO: Can not find deeplink"); dispatchCustomEvent({
name: "create-alert",
detail: {
alert: {
message:
"We're having trouble connecting right now. Please try again later",
},
},
});
return;
} }
if (!response.data.slate) { if (response.error) {
alert("TODO: Can not find deeplink"); 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( return window.open(
@ -64,7 +91,8 @@ export const ProcessedText = ({ text }) => {
css={STYLES_LINK} css={STYLES_LINK}
key={match + i} key={match + i}
target="_blank" target="_blank"
href={`/${match}`.toLowerCase()}> href={`/${match}`.toLowerCase()}
>
@{match} @{match}
</a> </a>
)); ));
@ -73,7 +101,8 @@ export const ProcessedText = ({ text }) => {
<span <span
css={STYLES_LINK} css={STYLES_LINK}
key={match + i} key={match + i}
onClick={() => onDeepLink({ deeplink: match.toLowerCase() })}> onClick={() => onDeepLink({ deeplink: match.toLowerCase() })}
>
#{match} #{match}
</span> </span>
)); ));

View File

@ -6,6 +6,7 @@ import {
} from "~/components/system/components/Buttons"; } from "~/components/system/components/Buttons";
import { css } from "@emotion/react"; import { css } from "@emotion/react";
import { dispatchCustomEvent } from "~/common/custom-events";
const STYLES_CONTAINER = css` const STYLES_CONTAINER = css`
font-family: ${Constants.font.text}; font-family: ${Constants.font.text};
@ -53,7 +54,16 @@ const STYLES_ITEM = css`
export class CreateFilecoinStorageDeal extends React.Component { export class CreateFilecoinStorageDeal extends React.Component {
static defaultProps = { static defaultProps = {
onSubmit: () => alert("onSubmit"), onSubmit: () => {
dispatchCustomEvent({
name: "create-alert",
detail: {
alert: {
message: "Filecoin storage deals are still under development",
},
},
});
},
}; };
state = { file: null }; state = { file: null };
@ -63,7 +73,12 @@ export class CreateFilecoinStorageDeal extends React.Component {
let file = e.target.files[0]; let file = e.target.files[0];
if (!file) { if (!file) {
alert("Something went wrong"); dispatchCustomEvent({
name: "create-alert",
detail: {
alert: { message: "Something went wrong. Please try again" },
},
});
return; return;
} }

View File

@ -5,6 +5,8 @@ import SystemPage from "~/components/system/SystemPage";
import ViewSourceLink from "~/components/system/ViewSourceLink"; import ViewSourceLink from "~/components/system/ViewSourceLink";
import CodeBlock from "~/components/system/CodeBlock"; import CodeBlock from "~/components/system/CodeBlock";
import { dispatchCustomEvent } from "~/common/custom-events";
const EXAMPLE_CODE = `import * as React from "react"; const EXAMPLE_CODE = `import * as React from "react";
import { CreateFilecoinAddress } from "slate-react-system"; import { CreateFilecoinAddress } from "slate-react-system";
import { createPow } from "@textile/powergate-client"; import { createPow } from "@textile/powergate-client";
@ -32,7 +34,13 @@ class Example extends React.Component {
export default class SystemPageCreateAddress extends React.Component { export default class SystemPageCreateAddress extends React.Component {
_handleSubmit = ({ name, type, makeDefault }) => { _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() { render() {

View File

@ -5,6 +5,8 @@ import SystemPage from "~/components/system/SystemPage";
import ViewSourceLink from "~/components/system/ViewSourceLink"; import ViewSourceLink from "~/components/system/ViewSourceLink";
import CodeBlock from "~/components/system/CodeBlock"; import CodeBlock from "~/components/system/CodeBlock";
import { dispatchCustomEvent } from "~/common/custom-events";
const addrsList = [ const addrsList = [
{ {
addr: addr:
@ -82,7 +84,11 @@ class Example extends React.Component {
export default class SystemPageFilecoinSettings extends React.Component { export default class SystemPageFilecoinSettings extends React.Component {
_handleSave = async (storageConfig) => { _handleSave = async (storageConfig) => {
alert("Saved"); // TODO(jim): Send setings data to server.
dispatchCustomEvent({
name: "create-alert",
detail: { alert: { message: "Saved!", status: "INFO" } },
});
}; };
render() { render() {

View File

@ -5,6 +5,8 @@ import SystemPage from "~/components/system/SystemPage";
import ViewSourceLink from "~/components/system/ViewSourceLink"; import ViewSourceLink from "~/components/system/ViewSourceLink";
import CodeBlock from "~/components/system/CodeBlock"; import CodeBlock from "~/components/system/CodeBlock";
import { dispatchCustomEvent } from "~/common/custom-events";
const EXAMPLE_CODE = `import * as React from "react"; const EXAMPLE_CODE = `import * as React from "react";
import { CreateFilecoinStorageDeal } from "slate-react-system"; import { CreateFilecoinStorageDeal } from "slate-react-system";
import { createPow } from "@textile/powergate-client"; import { createPow } from "@textile/powergate-client";
@ -58,7 +60,12 @@ class Example extends React.Component {
export default class SystemPageMakeStorageDeal extends React.Component { export default class SystemPageMakeStorageDeal extends React.Component {
_handleSubmit = async ({ file }) => { _handleSubmit = async ({ file }) => {
// TODO(jim): Send file data to server. // TODO(jim): Send file data to server.
alert(file); dispatchCustomEvent({
name: "create-alert",
detail: {
alert: { message: "Storage deals are still under development" },
},
});
}; };
render() { render() {

View File

@ -5,6 +5,8 @@ import SystemPage from "~/components/system/SystemPage";
import ViewSourceLink from "~/components/system/ViewSourceLink"; import ViewSourceLink from "~/components/system/ViewSourceLink";
import CodeBlock from "~/components/system/CodeBlock"; import CodeBlock from "~/components/system/CodeBlock";
import { dispatchCustomEvent } from "~/common/custom-events";
const EXAMPLE_CODE = `import * as React from "react"; const EXAMPLE_CODE = `import * as React from "react";
import { SendAddressFilecoin } from "slate-react-system"; import { SendAddressFilecoin } from "slate-react-system";
import { createPow } from "@textile/powergate-client"; import { createPow } from "@textile/powergate-client";
@ -31,7 +33,15 @@ class Example extends React.Component {
export default class SystemPageSendAddressFilecoin extends React.Component { export default class SystemPageSendAddressFilecoin extends React.Component {
_handleSubmit = ({ source, target, amount }) => { _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() { render() {

View File

@ -4,6 +4,7 @@ import * as System from "~/components/system";
import * as Actions from "~/common/actions"; import * as Actions from "~/common/actions";
import { css } from "@emotion/react"; import { css } from "@emotion/react";
import { dispatchCustomEvent } from "~/common/custom-events";
const STYLES_ITEM = css` const STYLES_ITEM = css`
font-size: 12px; font-size: 12px;
@ -53,11 +54,26 @@ export default class IntegrationPage extends React.Component {
_handleUpdate = async (e) => { _handleUpdate = async (e) => {
const response = await Actions.hydrateAuthenticatedUser(); const response = await Actions.hydrateAuthenticatedUser();
if (!response || response.error) { if (!response) {
alert("TODO: error fetching authenticated viewer"); dispatchCustomEvent({
name: "create-alert",
detail: {
alert: {
message:
"We're having trouble connecting right now. Please try again later",
},
},
});
return null; return null;
} }
if (response.error) {
dispatchCustomEvent({
name: "create-alert",
detail: { alert: { decorator: response.decorator } },
});
}
const updates = { const updates = {
viewer: response.data, viewer: response.data,
}; };

View File

@ -7,6 +7,7 @@ import * as Validations from "~/common/validations";
import * as FileUtilities from "~/common/file-utilities"; import * as FileUtilities from "~/common/file-utilities";
import { css } from "@emotion/react"; import { css } from "@emotion/react";
import { dispatchCustomEvent } from "~/common/custom-events";
import ScenePage from "~/components/core/ScenePage"; import ScenePage from "~/components/core/ScenePage";
import Avatar from "~/components/core/Avatar"; import Avatar from "~/components/core/Avatar";
@ -48,20 +49,35 @@ export default class SceneEditAccount extends React.Component {
let file = e.target.files[0]; let file = e.target.files[0];
if (!file) { if (!file) {
alert("TODO: Something went wrong"); dispatchCustomEvent({
name: "create-alert",
detail: {
alert: {
message: "Something went wrong with the upload. Please try again",
},
},
});
return; return;
} }
// NOTE(jim): Only allow images for account avatar. // NOTE(jim): Only allow images for account avatar.
if (!file.type.startsWith("image/")) { 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; return;
} }
const json = await FileUtilities.upload({ file }); const json = await FileUtilities.upload({ file });
if (json.error) { 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 }); this.setState({ changingAvatar: false });
return; return;
} }
@ -100,7 +116,14 @@ export default class SceneEditAccount extends React.Component {
this.setState({ changingUsername: true }); this.setState({ changingUsername: true });
if (!Validations.username(this.state.username)) { 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 }); this.setState({ changingUsername: false });
return; return;
} }
@ -126,13 +149,21 @@ export default class SceneEditAccount extends React.Component {
_handleChangePassword = async (e) => { _handleChangePassword = async (e) => {
this.setState({ changingPassword: true }); this.setState({ changingPassword: true });
if (this.state.password !== this.state.confirm) { 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 }); this.setState({ changingPassword: false });
return; return;
} }
if (!Validations.password(this.state.password)) { 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 }); this.setState({ changingPassword: false });
return; return;
} }

View File

@ -9,6 +9,7 @@ import {
ButtonPrimary, ButtonPrimary,
ButtonSecondary, ButtonSecondary,
} from "~/components/system/components/Buttons"; } from "~/components/system/components/Buttons";
import { dispatchCustomEvent } from "~/common/custom-events";
import ScenePage from "~/components/core/ScenePage"; import ScenePage from "~/components/core/ScenePage";
import Profile from "~/components/core/Profile"; import Profile from "~/components/core/Profile";
@ -75,8 +76,24 @@ export default class SceneProfile extends React.Component {
_handleUpdate = async (e) => { _handleUpdate = async (e) => {
let response = await this.props.onRehydrate(); let response = await this.props.onRehydrate();
if (!response || response.error) { if (!response) {
alert("TODO: error fetching authenticated viewer"); 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; return null;
} }

View File

@ -5,6 +5,7 @@ import * as System from "~/components/system";
import * as SVG from "~/common/svg"; import * as SVG from "~/common/svg";
import { css } from "@emotion/react"; import { css } from "@emotion/react";
import { dispatchCustomEvent } from "~/common/custom-events";
import ScenePage from "~/components/core/ScenePage"; import ScenePage from "~/components/core/ScenePage";
import ScenePageHeader from "~/components/core/ScenePageHeader"; import ScenePageHeader from "~/components/core/ScenePageHeader";
@ -83,7 +84,8 @@ class Key extends React.Component {
onClick={this._handleToggleVisible} onClick={this._handleToggleVisible}
style={{ style={{
marginRight: 8, marginRight: 8,
}}> }}
>
<SVG.Privacy height="16px" /> <SVG.Privacy height="16px" />
</span> </span>
<span <span
@ -91,7 +93,8 @@ class Key extends React.Component {
onClick={() => this._handleDelete(this.props.data.id)} onClick={() => this._handleDelete(this.props.data.id)}
style={{ style={{
marginRight: 4, marginRight: 4,
}}> }}
>
<SVG.Dismiss height="16px" /> <SVG.Dismiss height="16px" />
</span> </span>
</div> </div>
@ -192,9 +195,24 @@ export default class SceneSettingsDeveloper extends React.Component {
this.setState({ loading: true }); this.setState({ loading: true });
const response = await Actions.generateAPIKey(); const response = await Actions.generateAPIKey();
if (response && response.error) { if (!response) {
// TODO(jim): Proper error message. dispatchCustomEvent({
alert(response.decorator); 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 }); return this.setState({ loading: false });
} }
@ -216,15 +234,26 @@ export default class SceneSettingsDeveloper extends React.Component {
} }
const response = await Actions.deleteAPIKey({ id }); const response = await Actions.deleteAPIKey({ id });
if (response && response.error) { if (!response) {
// TODO(jim): Proper error message. dispatchCustomEvent({
alert(response.decorator); name: "create-alert",
detail: {
alert: {
message:
"We're having trouble connecting right now. Please try again later",
},
},
});
return this.setState({ loading: false }); return this.setState({ loading: false });
} }
await this.props.onRehydrate(); if (response.error) {
dispatchCustomEvent({
this.setState({ loading: false }); name: "create-alert",
detail: { alert: { decorator: response.decorator } },
});
return this.setState({ loading: false });
}
}; };
async componentDidMount() { async componentDidMount() {
@ -278,7 +307,8 @@ export default class SceneSettingsDeveloper extends React.Component {
<div style={{ marginTop: 24 }}> <div style={{ marginTop: 24 }}>
<System.ButtonPrimary <System.ButtonPrimary
onClick={this._handleSave} onClick={this._handleSave}
loading={this.state.loading}> loading={this.state.loading}
>
Generate Generate
</System.ButtonPrimary> </System.ButtonPrimary>
</div> </div>

View File

@ -7,6 +7,7 @@ import * as Strings from "~/common/strings";
import { css } from "@emotion/react"; import { css } from "@emotion/react";
import { Logo } from "~/common/logo"; import { Logo } from "~/common/logo";
import { dispatchCustomEvent } from "~/common/custom-events";
import WebsitePrototypeHeader from "~/components/core/WebsitePrototypeHeader"; import WebsitePrototypeHeader from "~/components/core/WebsitePrototypeHeader";
import WebsitePrototypeFooter from "~/components/core/WebsitePrototypeFooter"; import WebsitePrototypeFooter from "~/components/core/WebsitePrototypeFooter";
@ -123,15 +124,25 @@ export default class SceneSignIn extends React.Component {
await delay(100); await delay(100);
if (!Validations.username(this.state.username)) { if (!Validations.username(this.state.username)) {
alert( dispatchCustomEvent({
"Your username was invalid, only characters and numbers are allowed." name: "create-alert",
); detail: {
alert: {
message: "Only characters and numbers are allowed in usernames",
},
},
});
this.setState({ loading: false }); this.setState({ loading: false });
return; return;
} }
if (!Validations.password(this.state.password)) { 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 }); this.setState({ loading: false });
return; return;
} }
@ -141,8 +152,25 @@ export default class SceneSignIn extends React.Component {
password: this.state.password, password: this.state.password,
}); });
if (!response || response.error) { if (!response) {
alert("We could not sign you into your account, try again later."); 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 }); this.setState({ loading: false });
return; return;
} }

View File

@ -182,12 +182,23 @@ export default class SceneSlate extends React.Component {
if (!response) { if (!response) {
this.setState({ loading: false, saving: "ERROR" }); 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) { if (response.error) {
this.setState({ loading: false, saving: "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(); await this.props.onRehydrate();
@ -297,7 +308,15 @@ export default class SceneSlate extends React.Component {
name: "state-global-carousel-loading", name: "state-global-carousel-loading",
detail: { loading: false }, 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) { if (response.error) {
@ -305,7 +324,10 @@ export default class SceneSlate extends React.Component {
name: "state-global-carousel-loading", name: "state-global-carousel-loading",
detail: { loading: false }, detail: { loading: false },
}); });
alert(`TODO: ${response.decorator}`); System.dispatchCustomEvent({
name: "create-alert",
detail: { alert: { decorator: response.decorator } },
});
} }
this._handleUpdateCarousel({ this._handleUpdateCarousel({
@ -358,13 +380,36 @@ export default class SceneSlate extends React.Component {
deeplink: true, deeplink: true,
}); });
if (!response.data) { if (!response || !response.data) {
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; return;
} }
if (response.error) {
System.dispatchCustomEvent({
name: "create-alert",
detail: { alert: { decorator: response.decorator } },
});
}
if (!response.data.slate) { 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; return;
} }

View File

@ -5,6 +5,7 @@ import * as SVG from "~/common/svg";
import * as System from "~/components/system"; import * as System from "~/components/system";
import { css } from "@emotion/react"; import { css } from "@emotion/react";
import { dispatchCustomEvent } from "~/common/custom-events";
import Section from "~/components/core/Section"; import Section from "~/components/core/Section";
import ScenePage from "~/components/core/ScenePage"; import ScenePage from "~/components/core/ScenePage";
@ -101,7 +102,10 @@ export default class SceneWallet extends React.Component {
_handleCopy = (text) => { _handleCopy = (text) => {
Strings.copyText(text); Strings.copyText(text);
alert(`${text} Added to clipboard.`); dispatchCustomEvent({
name: "create-alert",
detail: { alert: { message: "Copied to clipboard!", status: "INFO" } },
});
}; };
render() { render() {