Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wallet: Delegation and Staking flows #3864

Merged
merged 40 commits into from Nov 14, 2019
Merged
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
c48bc88
initial refactor
figitaki Nov 4, 2019
e6e5855
added routes
michellewong793 Nov 5, 2019
86314d2
Get Delegation flow working
figitaki Nov 6, 2019
998348c
Change Settings button to Close when active
michellewong793 Nov 6, 2019
53ceff8
Wallet: add default toast
Schmavery Nov 6, 2019
348dc89
Add staking rewards page
figitaki Nov 6, 2019
a6547ac
Changed icon color on Close button to be currentcolor
michellewong793 Nov 7, 2019
aab03ae
fix gexExn crash when syncing
figitaki Nov 7, 2019
4d98dbe
fix settings container height bug
figitaki Nov 7, 2019
9a71bfa
Add divider
figitaki Nov 7, 2019
b1f2c23
add onClick to toast
figitaki Nov 7, 2019
1500448
Add breadcrumbs
michellewong793 Nov 7, 2019
97c4112
fix staking toggle
figitaki Nov 7, 2019
08cc6e3
Add unlock modal for accounts in Settings page
michellewong793 Nov 7, 2019
5e68d29
Fixed unlock modal
michellewong793 Nov 7, 2019
fee7962
Updated to reflect last design pass on Figma, includes new Block Rewa…
michellewong793 Nov 11, 2019
89c273a
Two changes: use account instead of passing in both pubkey and acct i…
michellewong793 Nov 11, 2019
81a4055
Refactored duplicated code for delegation
michellewong793 Nov 11, 2019
b96ddbc
Reformat and also edits to Delegation button
michellewong793 Nov 12, 2019
4bebfa1
initial refactor
figitaki Nov 4, 2019
fa11357
added routes
michellewong793 Nov 5, 2019
710044a
Get Delegation flow working
figitaki Nov 6, 2019
ee02315
Wallet: add default toast
Schmavery Nov 6, 2019
0e012bc
fix settings container height bug
figitaki Nov 7, 2019
3ca9dac
add onClick to toast
figitaki Nov 7, 2019
6cbd116
Add breadcrumbs
michellewong793 Nov 7, 2019
fdcf8d8
fix staking toggle
figitaki Nov 7, 2019
f727919
Fixed unlock modal
michellewong793 Nov 7, 2019
f6a3aa0
Updated to reflect last design pass on Figma, includes new Block Rewa…
michellewong793 Nov 11, 2019
23dbfee
Reformat and also edits to Delegation button
michellewong793 Nov 12, 2019
885568b
Change toast defaultStyle prop
michellewong793 Nov 12, 2019
743b7f3
Merge branch 'develop' into feature/block-rewards
michellewong793 Nov 12, 2019
b1eb646
Delete extra Button hyperlinkblue style
michellewong793 Nov 12, 2019
4a9aa60
remove flatmap
figitaki Nov 13, 2019
c3e5b35
Merge branch 'develop' into feature/block-rewards
figitaki Nov 13, 2019
4d3815b
Merge remote-tracking branch 'origin/develop' into feature/block-rewards
bkase Nov 13, 2019
5184476
Merge branch 'develop' into feature/block-rewards
michellewong793 Nov 13, 2019
a523e1e
Fixed compilation
wu-s-john Nov 13, 2019
0729262
Merge branch 'develop' into feature/block-rewards
bkase Nov 13, 2019
f206467
Merge branch 'develop' into feature/block-rewards
bkase Nov 14, 2019
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

@@ -26,14 +26,14 @@
"node": "^8.15.0"
},
"scripts": {
"fake": "graphql-faker --port 8080 -- schema.graphql",
"fake": "graphql-faker --port 3085 -- schema.graphql",
"real": "./_build/coda-daemon-macos/coda.exe daemon -rest-port 8080 &> /dev/tty",
"fake-inspector": "graphql-faker --open -- schema.graphql",
"build": "yarn copy-schema && bsb -make-world",
"build-ci": "yarn run query-fake && yarn run build",
"clean": "bsb -clean-world",
"pack": "fpack --development ./lib/js/src/render/Index.js",
"query": "send-introspection-query http://localhost:8080/graphql",
"query": "send-introspection-query http://localhost:3085/graphql",
"query-fake": "concurrently --kill-others 'yarn run fake' 'sleep 5 && yarn run query' || true",
"query-real": "concurrently --kill-others 'yarn run real' 'sleep 15 && yarn run query' || true",
"reformat": "bsrefmt --in-place $(find src -name '*.re' -or -name '*.rei' -print)",
Git LFS file not shown
Git LFS file not shown
@@ -1,20 +1,22 @@
module Styles = {
open Css;
let fadeIn =
open Css;
let fadeIn =
keyframes([
(0, [opacity(0.), top(`rem(1.0))]),
(100, [opacity(1.), top(`zero)]),
]);

let animate = (duration, delay) => style([position(`relative), opacity(0.), animation(fadeIn, ~duration=duration, ~iterationCount=`count(1)), animationDelay(delay), animationFillMode(`forwards),]);

};

let animate = (duration, delay) =>
style([
position(`relative),
opacity(0.),
animation(fadeIn, ~duration, ~iterationCount=`count(1)),
animationDelay(delay),
animationFillMode(`forwards),
]);
};
[@react.component]
let make = (~children, ~duration, ~delay=0) =>
<div className={Css.(style([position( `relative)]))}>
<div
className={Styles.animate(duration, delay)}>
children
</div>
</div>;

<div className=Css.(style([position(`relative)]))>
<div className={Styles.animate(duration, delay)}> children </div>
</div>;
@@ -1,7 +1,7 @@
open BsElectron;
open Tc;

[@bs.module "electron"][@bs.scope "shell"][@bs.val]
[@bs.module "electron"] [@bs.scope "shell"] [@bs.val]
external openItem: string => unit = "openItem";

let createTray = dispatch => {
@@ -52,7 +52,17 @@ module Decoders = {

// hack for supporting faker
if (s == "<PublicKey>" && isFaker) {
PublicKey.ofStringExn("Co9TeE1xZduCMtisEo9wadZ81g9bBPGgVKdQUrVZ2Z");
let values = [
"Co9TeE1xZduCMtisEo9wadZ81g9bBPGgVKdQUrVZ2Z",
"5RSJVkduNzMensh2SS12GRy8oQpfxR9oUDr7ETvu1b",
"2A3Kkh68yoXAkEgAK1M52qYysJzUga6GxLrfjdv2ds",
];
PublicKey.ofStringExn(
Option.withDefault(
~default="",
List.getAt(~index=Random.int(3), values),
),
);
} else {
PublicKey.ofStringExn(s);
};
@@ -2,6 +2,7 @@ let useActiveAccount = () => {
let url = ReasonReact.Router.useUrl();
switch (url.path) {
| ["account", accountKey] => Some(PublicKey.uriDecode(accountKey))
| ["settings", accountKey, ..._] => Some(PublicKey.uriDecode(accountKey))
| _ => None
};
};
@@ -4,18 +4,19 @@ let make = () => {
let (isOnboarding, _) as onboardingValue =
OnboardingProvider.createContext();
let dispatch = CodaProcess.useHook();
let toastValue = ToastProvider.createContext();

<AddressBookProvider value=settingsValue>
<OnboardingProvider value=onboardingValue>
<ProcessDispatchProvider value=dispatch>
<ReasonApollo.Provider client=Apollo.client>
{isOnboarding
? <Onboarding />
: <>
: <ToastProvider value=toastValue>
<Header />
<Main> <SideBar /> <Router /> </Main>
<Footer />
</>}
</ToastProvider>}
</ReasonApollo.Provider>
</ProcessDispatchProvider>
</OnboardingProvider>
@@ -26,6 +26,10 @@ let make = () => {
| ["settings"] => <SettingsPage />
| ["settings", publicKey] =>
<AccountSettings publicKey={PublicKey.uriDecode(publicKey)} />
| ["settings", publicKey, "delegate"] =>
<DelegationSettings publicKey={PublicKey.uriDecode(publicKey)} />
| ["settings", publicKey, "stake"] =>
<StakingSettings publicKey={PublicKey.uriDecode(publicKey)} />
| ["account", _pk, ..._] => <Transactions />
| _ =>
<AccountQuery>
@@ -7,7 +7,12 @@ module Styles = {
color(textColor),
display(`flex),
borderRadius(`px(3)),
padding4(~top=`rem(0.25), ~right=`rem(0.75), ~bottom=`rem(0.25), ~left=`rem(0.5)),
padding4(
~top=`rem(0.25),
~right=`rem(0.75),
~bottom=`rem(0.25),
~left=`rem(0.5),
),
]);

let text = Theme.Text.Body.semiBold;
@@ -1,5 +1,6 @@
type mode =
| Blue
| HyperlinkBlue
| Gray
| Green
| Red;
@@ -36,6 +37,18 @@ module Styles = {
]),
]);

let hyperlinkBlue =
merge([
base,
style([
color(Theme.Colors.hyperlink),
backgroundColor(Theme.Colors.hyperlinkAlpha(0.15)),
hover([backgroundColor(Theme.Colors.hyperlink), color(white)]),
focus([backgroundColor(Theme.Colors.hyperlink), color(white)]),
active([backgroundColor(Theme.Colors.hyperlink), color(white)]),
]),
]);

let green =
merge([
base,
@@ -86,10 +99,14 @@ let make =
~height=3.,
~icon=?,
~type_="button",
~onMouseEnter=?,
~onMouseLeave=?,
) =>
<button
disabled
?onClick
?onMouseEnter
?onMouseLeave
className={Css.merge([
disabled ? Styles.disabled : "",
Css.style([Css.minWidth(`rem(width)), Css.height(`rem(height))]),
@@ -98,6 +115,7 @@ let make =
| Green => Styles.green
| Red => Styles.red
| Gray => Styles.gray
| HyperlinkBlue => Styles.hyperlinkBlue
},
])}
type_>
@@ -1,5 +1,3 @@
let component = ReasonReact.statelessComponent("Header");

module Styles = {
open Css;
open Theme;
@@ -11,6 +9,9 @@ module Styles = {
top(`px(0)),
left(`px(0)),
right(`px(0)),
zIndex(100),
background(`url("bg-texture.png")),
backgroundColor(`hex("f2f2f2")),
height(Spacing.headerHeight),
maxHeight(Spacing.headerHeight),
minHeight(Spacing.headerHeight),
@@ -124,6 +125,64 @@ module SyncStatus = {
};
};

module DefaultToast = {
type accountBsRecord = {
delegateAccount: option({. "publicKey": PublicKey.t}),
stakingActive: bool,
};

module DelegationQ = [%graphql
{|
query queryDelegation($publicKey: PublicKey!) {
account(publicKey: $publicKey) @bsRecord {
delegateAccount {
publicKey @bsDecoder(fn: "Apollo.Decoders.publicKey")
}
stakingActive
}
}
|}
];

module DelegationQuery = ReasonApollo.CreateQuery(DelegationQ);

[@react.component]
let make = () => {
let pk = Hooks.useActiveAccount();
switch (pk) {
| Some(pk) =>
<DelegationQuery
variables={
DelegationQ.make(~publicKey=Apollo.Encoders.publicKey(pk), ())##variables;
}>
(
response =>
switch (response.result) {
| Data(d) =>
switch (d##account) {
| Some({delegateAccount: Some(delegate), stakingActive: false})
when delegate##publicKey == pk =>
<Toast
onClick={() =>
ReasonReactRouter.push(
"/settings/" ++ PublicKey.uriEncode(pk),
)
}
defaultStyle=ToastProvider.Success
defaultText={js|Participate in consensus to earn coda →|js}
/>
| _ => <Toast />
}
| Loading
| Error(_) => <Toast />
}
)
</DelegationQuery>
| None => <Toast />
};
};
};

[@react.component]
let make = () => {
let url = ReasonReact.Router.useUrl();
@@ -137,7 +196,7 @@ let make = () => {
<div className=Styles.logo onClick={_ => ReasonReact.Router.push("/")}>
<img src=codaSvg alt="Coda logo" />
</div>
<Toast />
<DefaultToast />
<div className=Styles.rightButtons>
<SyncStatusQuery fetchPolicy="no-cache" partialRefetch=true>
{response =>
@@ -155,9 +214,16 @@ let make = () => {
onClick={_e =>
ReasonReact.Router.push(onSettingsPage ? "/" : "/settings")
}>
<Icon kind=Icon.Settings />
{onSettingsPage
? <Icon kind=Icon.Cross /> : <Icon kind=Icon.Settings />}
<Spacer width=0.25 />
{React.string("Settings")}
{onSettingsPage
? {
React.string("Close");
}
: {
React.string("Settings");
}}
</a>
</div>
</header>;
@@ -11,7 +11,8 @@ type kind =
| Danger
| BackArrow
| Locked
| Unlocked;
| Unlocked
| Cross;

[@react.component]
let make = (~kind) =>
@@ -91,5 +92,11 @@ let make = (~kind) =>
clipRule="evenodd"
d="M17.42 11.2809H18.52H18.54V20.8409H6V11.2809H15.1L15.22 11.2009C15.64 10.9009 15.92 10.4609 16 9.96093C16.08 9.46093 15.96 8.96093 15.66 8.54093L14.26 6.60093C13.64 5.74093 12.44 5.54093 11.58 6.16093L9.02 8.00093L7.96 6.54093L10.52 4.70093C12.18 3.50093 14.5 3.88093 15.7 5.54093L17.1 7.48093C17.68 8.28093 17.92 9.26093 17.76 10.2409C17.7 10.6009 17.58 10.9609 17.42 11.2809ZM13.36 18.2807H11.14L11.46 16.1807C11.24 15.9607 11.1 15.6607 11.1 15.3407C11.1 14.7007 11.6 14.2007 12.24 14.2007C12.88 14.2007 13.38 14.7207 13.38 15.3407C13.38 15.6807 13.24 15.9807 13 16.2007L13.36 18.2807Z"
/>
| Cross =>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M6.55558 5L5.00002 6.55546L10.4449 12L5 17.4446L6.55556 19.0001L12.0005 13.5555L17.4445 18.9992L19 17.4437L13.556 12L19 6.55636L17.4444 5.00089L12.0005 10.4446L6.55558 5Z"
/>
}}
</svg>;
@@ -5,6 +5,9 @@ module Styles = {
style([
display(`flex),
flexDirection(`row),
position(`relative),
background(`url("bg-texture.png")),
backgroundColor(`hex("f2f2f2")),
paddingTop(Theme.Spacing.headerHeight),
paddingBottom(Theme.Spacing.footerHeight),
height(`vh(100.)),
@@ -37,6 +37,7 @@ module Styles = {
top(`zero),
right(`zero),
bottom(`zero),
zIndex(999),
display(`flex),
justifyContent(`center),
alignItems(`center),
@@ -1,3 +1,5 @@
open Tc;

module Styles = {
open Css;
let toast = (bgColor, textColor) =>
@@ -9,10 +11,20 @@ module Styles = {
};

[@react.component]
let make = () => {
let make =
(
~defaultText=?,
~defaultStyle=ToastProvider.Default,
~onClick: unit => unit=() => (),
This conversation was marked as resolved by michellewong793

This comment has been minimized.

Copy link
@Schmavery

Schmavery Nov 7, 2019

Contributor

It seems kinda weird that this onClick applies even when another toast is showing.

) => {
let (value, _) = React.useContext(ToastProvider.context);
switch (value) {
| Some({text, style}) =>
let value =
Option.map(value, ~f=({ToastProvider.text, style}) => (text, style));
let default = Option.map(defaultText, ~f=text => (text, defaultStyle));

// The second arg to orElse has precedence
switch (Option.orElse(default, value)) {
| Some((text, style)) =>
let (bgColor, textColor) =
Theme.Colors.(
switch (style) {
@@ -22,7 +34,8 @@ let make = () => {
| Warning => (yeezyAlpha(0.15), yeezy)
}
);
<div className={Styles.toast(bgColor, textColor)}>
<div
className={Styles.toast(bgColor, textColor)} onClick={_ => onClick()}>
<p className=Theme.Text.Body.regular> {React.string(text)} </p>
</div>;
| None => React.null
@@ -46,6 +46,7 @@ let make = (~options, ~selected, ~onChange) => {
{Array.mapi(
(i, option_) =>
<button
key={string_of_int(i) ++ option_}
className={Styles.button(i == selected)}
onClick={_e => onChange(i)}>
{React.string(option_)}
@@ -1,2 +1,3 @@
[@react.component] [@bs.module "react-waypoint"]
external make: (~onEnter: unit => unit, ~topOffset: string=?) => React.element = "Waypoint";
external make: (~onEnter: unit => unit, ~topOffset: string=?) => React.element =
"Waypoint";
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.