mirror of
https://github.com/filecoin-project/slate.git
synced 2024-12-23 09:01:56 +03:00
initial sketch: filecoin deal UI and scene
This commit is contained in:
parent
d72d2147b0
commit
6b7e547b06
@ -149,6 +149,12 @@ export const generate = ({ library = [], slates = [] }) => [
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "V1_NAVIGATION_FILECOIN_STORAGE_DEAL",
|
||||
decorator: "MAKE_DEAL",
|
||||
name: "Storage deal",
|
||||
pageTitle: "Make a one-off Filecoin storage deal",
|
||||
},
|
||||
{
|
||||
id: "V1_NAVIGATION_PROFILE_EDIT",
|
||||
decorator: "EDIT_ACCOUNT",
|
||||
|
@ -1,5 +1,7 @@
|
||||
import * as Constants from "~/common/constants";
|
||||
|
||||
import { FilecoinNumber, Converter } from "@openworklabs/filecoin-number";
|
||||
|
||||
const MINUTE = 60;
|
||||
const HOUR = MINUTE * 60;
|
||||
const DAY = HOUR * 24;
|
||||
@ -69,8 +71,10 @@ export const getCIDFromIPFS = (url) => {
|
||||
};
|
||||
|
||||
export const formatAsFilecoinConversion = (number) => {
|
||||
number = number / Math.pow(10, 18);
|
||||
return `${formatAsFilecoin(number)}`;
|
||||
const filecoinNumber = new FilecoinNumber(`${number}`, "attofil");
|
||||
//const inAttoFil = filecoinNumber.toAttoFil();
|
||||
const inFil = filecoinNumber.toFil();
|
||||
return `${formatAsFilecoin(inFil)}`;
|
||||
};
|
||||
|
||||
export const formatAsFilecoin = (number) => {
|
||||
|
@ -423,6 +423,7 @@ export const Deals = (props) => (
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="1.5"
|
||||
>
|
||||
<path d="m23.5 22-1-1.934v-4.566c.042-1.778-2.081-3.363-4-5" />
|
||||
<path d="m20.019 17.5-2.551-2.607.00000002.00000002c-.476378-.495833-1.26451-.511603-1.76034-.035225-.495833.476378-.511603 1.26451-.035225 1.76034.00382974.00398614.00768599.00794673.0115685.0118815l2.816 2.87v1.5l-.00000021-.0000012c.153133.894577.493939 1.74659 1 2.5" />
|
||||
|
@ -30,6 +30,7 @@ import SceneSentinel from "~/scenes/SceneSentinel";
|
||||
import ScenePublicProfile from "~/scenes/ScenePublicProfile";
|
||||
import ScenePublicSlate from "~/scenes/ScenePublicSlate";
|
||||
import SceneArchive from "~/scenes/SceneArchive";
|
||||
import SceneMakeFilecoinDeal from "~/scenes/SceneMakeFilecoinDeal";
|
||||
|
||||
// NOTE(jim):
|
||||
// Sidebars each have a decorator and can be shown to with _handleAction
|
||||
@ -88,6 +89,7 @@ const SCENES = {
|
||||
NETWORK: <SceneSentinel />,
|
||||
DIRECTORY: <SceneDirectory />,
|
||||
FILECOIN: <SceneArchive />,
|
||||
MAKE_DEAL: <SceneMakeFilecoinDeal />,
|
||||
};
|
||||
|
||||
export default class ApplicationPage extends React.Component {
|
||||
|
@ -14,6 +14,7 @@ const IconMap = {
|
||||
FOLDER: <SVG.Folder height="20px" />,
|
||||
WALLET: <SVG.OldWallet height="20px" />,
|
||||
DEALS: <SVG.Deals height="20px" />,
|
||||
MAKE_DEAL: <SVG.Deals height="20px" />,
|
||||
SLATES: <SVG.Layers height="20px" />,
|
||||
SLATE: <SVG.Slate height="20px" />,
|
||||
LOCAL_DATA: <SVG.HardDrive height="20px" />,
|
||||
|
@ -45,6 +45,7 @@
|
||||
"@emotion/react": "11.0.0-next.12",
|
||||
"@emotion/server": "11.0.0-next.12",
|
||||
"@improbable-eng/grpc-web": "^0.13.0",
|
||||
"@openworklabs/filecoin-number": "0.0.10",
|
||||
"@react-hook/window-size": "^3.0.7",
|
||||
"@slack/webhook": "^5.0.3",
|
||||
"@textile/grpc-transport": "0.0.3",
|
||||
|
158
scenes/SceneMakeFilecoinDeal.js
Normal file
158
scenes/SceneMakeFilecoinDeal.js
Normal file
@ -0,0 +1,158 @@
|
||||
import * as React from "react";
|
||||
import * as Strings from "~/common/strings";
|
||||
import * as Constants from "~/common/constants";
|
||||
import * as System from "~/components/system";
|
||||
|
||||
import { css } from "@emotion/react";
|
||||
import { createState } from "~/scenes/SceneSettings";
|
||||
import { LoaderSpinner } from "~/components/system/components/Loaders";
|
||||
import { FilecoinNumber, Converter } from "@openworklabs/filecoin-number";
|
||||
|
||||
import Section from "~/components/core/Section";
|
||||
import ScenePage from "~/components/core/ScenePage";
|
||||
import ScenePageHeader from "~/components/core/ScenePageHeader";
|
||||
|
||||
const STYLES_SECTION_UPLOAD = css`
|
||||
background: white;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 88px 48px 88px 48px;
|
||||
border: 1px solid #ececec;
|
||||
margin-top: 48px;
|
||||
max-width: 688px;
|
||||
font-family: ${Constants.font.semiBold};
|
||||
`;
|
||||
|
||||
export default class SceneDeals extends React.Component {
|
||||
state = {};
|
||||
|
||||
async componentDidMount() {
|
||||
let networkViewer;
|
||||
try {
|
||||
const response = await fetch("/api/network");
|
||||
const json = await response.json();
|
||||
networkViewer = json.data;
|
||||
} catch (e) {}
|
||||
|
||||
this.setState({
|
||||
networkViewer,
|
||||
...createState(networkViewer.powerInfo.defaultStorageConfig),
|
||||
settings_cold_default_max_price: 1000000000000000,
|
||||
});
|
||||
}
|
||||
|
||||
_handleChange = (e) => {
|
||||
this.setState({ [e.target.name]: e.target.value });
|
||||
};
|
||||
|
||||
render() {
|
||||
let inFil = 0;
|
||||
if (this.state.networkViewer) {
|
||||
const filecoinNumber = new FilecoinNumber(
|
||||
`${this.state.settings_cold_default_max_price}`,
|
||||
"attofil"
|
||||
);
|
||||
|
||||
inFil = filecoinNumber.toFil();
|
||||
}
|
||||
|
||||
return (
|
||||
<ScenePage>
|
||||
<ScenePageHeader title="Make a one-off Flecoin Storage Deal">
|
||||
This is a simple tool to upload data and make one-off storage deals in
|
||||
the Filecoin network.
|
||||
</ScenePageHeader>
|
||||
|
||||
{this.state.networkViewer ? (
|
||||
<React.Fragment>
|
||||
<div css={STYLES_SECTION_UPLOAD}>
|
||||
Drag and drop a file here or <a href="#">click</a> to
|
||||
upload.
|
||||
</div>
|
||||
|
||||
<System.Input
|
||||
containerStyle={{ marginTop: 24 }}
|
||||
label="Filecoin address (Read only)"
|
||||
description="This is the Filecoin address your funds will come from."
|
||||
name="settings_cold_default_duration"
|
||||
readOnly
|
||||
type="text"
|
||||
value={this.state.settings_cold_default_address}
|
||||
onChange={this._handleChange}
|
||||
/>
|
||||
|
||||
<System.Input
|
||||
containerStyle={{ marginTop: 24 }}
|
||||
label="Default Filecoin replication and availability factor"
|
||||
description="How many times should we replicate this deal across your selected miners?"
|
||||
name="settings_cold_default_replication_factor"
|
||||
type="number"
|
||||
value={this.state.settings_cold_default_replication_factor}
|
||||
placeholder="Type in amount of miners"
|
||||
onChange={this._handleChange}
|
||||
/>
|
||||
|
||||
<System.Input
|
||||
containerStyle={{ marginTop: 24 }}
|
||||
label="Default Filecoin deal duration"
|
||||
description="Current deal duration is in epochs."
|
||||
name="settings_cold_default_duration"
|
||||
type="number"
|
||||
value={this.state.settings_cold_default_duration}
|
||||
placeholder="Type in epochs (~25 seconds)"
|
||||
onChange={this._handleChange}
|
||||
/>
|
||||
|
||||
<System.Input
|
||||
containerStyle={{ marginTop: 24 }}
|
||||
label="Max Filecoin price (attoFIL)"
|
||||
type="number"
|
||||
description={`Set the maximum Filecoin price you're willing to pay. The current price you have set is equivalent to ${inFil} FIL`}
|
||||
name="settings_cold_default_max_price"
|
||||
value={this.state.settings_cold_default_max_price}
|
||||
placeholder="Type in amount of Filecoin (attoFIL)"
|
||||
onChange={this._handleChange}
|
||||
/>
|
||||
|
||||
<Section
|
||||
title="Targeted miners"
|
||||
style={{ marginTop: 48, maxWidth: 688, minWidth: "auto" }}
|
||||
onAction={this.props.onAction}
|
||||
buttons={[
|
||||
{
|
||||
name: "Add miner",
|
||||
},
|
||||
]}
|
||||
>
|
||||
<System.Table
|
||||
data={{
|
||||
columns: [
|
||||
{
|
||||
key: "miner",
|
||||
name: "Miner ID",
|
||||
width: "100%",
|
||||
},
|
||||
],
|
||||
rows: this.state.settings_cold_default_trusted_miners.map(
|
||||
(miner) => {
|
||||
return {
|
||||
miner,
|
||||
};
|
||||
}
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</Section>
|
||||
|
||||
<System.ButtonPrimary style={{ marginTop: 48 }}>
|
||||
Make storage deal
|
||||
</System.ButtonPrimary>
|
||||
</React.Fragment>
|
||||
) : (
|
||||
<LoaderSpinner style={{ marginTop: 48, height: 32, width: 32 }} />
|
||||
)}
|
||||
</ScenePage>
|
||||
);
|
||||
}
|
||||
}
|
@ -39,7 +39,7 @@ const STYLES_RIGHT = css`
|
||||
flex-shrink: 0;
|
||||
`;
|
||||
|
||||
const createState = (config) => {
|
||||
export const createState = (config) => {
|
||||
return {
|
||||
settings_hot_enabled: config.hot.enabled,
|
||||
settings_hot_allow_unfreeze: config.hot.allowUnfreeze,
|
||||
|
Loading…
Reference in New Issue
Block a user