Skip to content

[WIP] Signal Scheme Alchemy Integration #1504

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

Closed
wants to merge 44 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
968d7f6
Merge pull request #1468 from daostack/dev
jellegerbrandy Mar 2, 2020
c2af3da
Merge branch 'master' into release_20200303
dkent600 Mar 3, 2020
3019382
Merge pull request #1475 from daostack/release_20200303
dkent600 Mar 5, 2020
2a8580d
migrating latest signal features commits
mrrobot16 Feb 3, 2020
e44df7e
Added DAO Header component in this branch
mrrobot16 Mar 4, 2020
8436d1f
Getting signal data and displaying it in the UI
mrrobot16 Mar 5, 2020
ee3ac8a
add action to save ipfs data
shekhar-shubhendu Mar 10, 2020
774ed7c
update signal scheme url
shekhar-shubhendu Mar 10, 2020
12c1b58
update Signals.json
shekhar-shubhendu Mar 10, 2020
867e99e
update logic to save/update/delete signals data
shekhar-shubhendu Mar 10, 2020
f67a8c8
linting and small fixes. remove hardcoded address
shekhar-shubhendu Mar 10, 2020
25a18c5
in history, open proposal in new tab on ctrl-click (#1474)
dkent600 Mar 5, 2020
243108e
show DAO total rep in sidebar (#1473)
dkent600 Mar 5, 2020
59cef63
In create proposal form tab directly from title to description
tibetsprague Mar 4, 2020
8984873
Lint fix
tibetsprague Mar 4, 2020
805a2b3
Require NETWORK env var on Heroku and default to rinkeby
tibetsprague Mar 6, 2020
67bed9a
Close modals by pressing ESC
tibetsprague Feb 26, 2020
dd12533
Fix styling of submit button on profile page when submitting
tibetsprague Feb 26, 2020
ad3e324
Make sure tooltip on redemptions button doesn't cover the button
tibetsprague Feb 26, 2020
dc8e759
Create ModalPopup component to bundle common modal stuff
tibetsprague Mar 3, 2020
e57fb22
Fix paths
tibetsprague Mar 4, 2020
09c5527
Enforce required permissions when adding/editing known Schemes
tibetsprague Mar 6, 2020
9d7afae
migrating latest signal features commits
mrrobot16 Feb 3, 2020
10c3f3c
Added DAO Header component in this branch
mrrobot16 Mar 4, 2020
49ec178
Getting signal data and displaying it in the UI
mrrobot16 Mar 5, 2020
a3c0ba7
add action to save ipfs data
shekhar-shubhendu Mar 10, 2020
77cf7df
update signal scheme url
shekhar-shubhendu Mar 10, 2020
26617c9
update Signals.json
shekhar-shubhendu Mar 10, 2020
23a99a7
update logic to save/update/delete signals data
shekhar-shubhendu Mar 10, 2020
1c955f3
linting and small fixes. remove hardcoded address
shekhar-shubhendu Mar 10, 2020
5249869
fix css
shekhar-shubhendu Mar 11, 2020
50476e0
update css, use var in tsx instead
shekhar-shubhendu Mar 11, 2020
400590b
Merge branch 'dev' into feat/signal-scheme
mrrobot16 Mar 12, 2020
6e9a3e9
eslint fixes
mrrobot16 Mar 17, 2020
8b511b7
Added responsive to this branch
mrrobot16 Apr 12, 2020
6f618ac
Latest responsive code
mrrobot16 Apr 29, 2020
f13ca00
Added dynamic holdings
mrrobot16 May 3, 2020
a65f320
deleted unneeded css code
mrrobot16 May 16, 2020
33bb933
Background image fix -back in history
mrrobot16 May 17, 2020
0f73aaf
Background image fix -back in history
mrrobot16 May 17, 2020
33869a8
Merge branch 'feat/signal-scheme' of https://github.com/apeunit/alche…
mrrobot16 May 19, 2020
6727857
Revert "Background image fix -back in history"
mrrobot16 May 19, 2020
8763f66
eslint fixes
mrrobot16 May 19, 2020
88645d8
Added subgraph endpoints json
mrrobot16 May 26, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions src/actions/arcActions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Address, DAO, IProposalCreateOptions, IProposalOutcome, ITransactionState, ITransactionUpdate, ReputationFromTokenScheme, Scheme } from "@daostack/client";
import { Address, DAO, IProposalCreateOptions, IProposalOutcome, ITransactionState,
ITransactionUpdate, ReputationFromTokenScheme, Scheme } from "@daostack/client";
import { IAsyncAction } from "actions/async";
import { getArc } from "arc";
import { toWei } from "lib/util";
Expand Down Expand Up @@ -38,11 +39,28 @@ export const operationNotifierObserver = (dispatch: Redux.Dispatch<any, any>, tx
];
};

export function saveSignalDescription(signalDescription: any): ThunkAction<any, IRootState, null> {
return async (_getState: () => IRootState) => {
const arc = getArc();
let ipfsDataToSave: object = {};
if (signalDescription.key && signalDescription.value !== undefined) {
if (!arc.ipfsProvider) {
throw Error("No ipfsProvider set on Arc instance - cannot save data on IPFS");
}
ipfsDataToSave = {
key: signalDescription.key,
value: signalDescription.value,
};
}
return await arc.ipfs.addAndPinString(Buffer.from(JSON.stringify(ipfsDataToSave)));
};
}

export function createProposal(proposalOptions: IProposalCreateOptions): ThunkAction<any, IRootState, null> {
return async (dispatch: Redux.Dispatch<any, any>, _getState: () => IRootState) => {
try {
const arc = getArc();

const dao = new DAO(proposalOptions.dao, arc);

const observer = operationNotifierObserver(dispatch, "Create proposal");
Expand Down
5 changes: 3 additions & 2 deletions src/components/Account/AccountImage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ interface IProps {
accountAddress: string;
profile?: IProfileState;
width: number;
style?: any;
}

export default class AccountImage extends React.Component<IProps, null> {

public render(): RenderOutput {
const { accountAddress, profile, width } = this.props;
const { accountAddress, profile, width, style } = this.props;

let url;
if (profile && profile.image && profile.image[0] && profile.image[0].contentUrl) {
Expand All @@ -25,6 +26,6 @@ export default class AccountImage extends React.Component<IProps, null> {
});
}

return (<img src={url} className={css.accountImage} width={width} />);
return (<img src={url} className={css.accountImage} width={width} style={style ? style : {}}/>);
}
}
102 changes: 102 additions & 0 deletions src/components/Dao/DaoHeader.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
.headerWrap {
background: white;
margin: 8rem 2.5% 0 0;
padding: 25px;
padding-top: 94px;
position: relative;
border-radius: 20px 20px 0 0;
z-index: 9999999999;
}

.reputationHolders {
display: block;
position: absolute;
font-size: 10px;
font-weight: normal;
color: $gray-1;
white-space: nowrap;
}

.daoName {
font-size: 24px;
color: #689bd6;
}

.daoInfo {
margin-left: 100px;
top: 15px;
position: absolute;
}

.daoDescription {
font-family: $body-font;
color: $black;
font-weight: 500;
font-size: 13px;
width: 75%;
}

.circularSquare {
border-radius: 50%;
border-color: white;
border-style: solid
}

.daoImg {
top: -40px !important;
left: 5px !important;
position: absolute;
}

.daoHeadingGroup {
.header {
margin: unset;
}
p {
margin-top: unset;
}
}


.holdings {
padding: 15px;
border: 1px solid #dbd7d7;
border-radius: 7px;
float: right;
position: relative;
top: -75px;
}

.holdings .holdingsAmount {
margin-top: 5px;
color: #565a5d;
font-size: 12px
}

.holdings .holdingsAmount .holdingsName {
float: right;
margin-left: 25px;
}

.holdingsNumber {
margin-right: 10px;
}

.holdingsList {
list-style: none;
padding-inline-start: 0px;
}

@media only screen and (max-width: 650px) {
.daoImg {
top: -75px;
left: 75px;
position: absolute;
}
}

@media only screen and (max-width: 768px) {
.holdings {
top: unset;
}
}
169 changes: 169 additions & 0 deletions src/components/Dao/DaoHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
import * as React from "react";
import { IDAOState, Scheme, Token } from "@daostack/client";
import { getArc } from "arc";
import { first } from "rxjs/operators";

import { formatTokens, supportedTokens, fromWei, baseTokenName, ethErrorHandler, genName } from "lib/util";
import withSubscription, { ISubscriptionProps } from "components/Shared/withSubscription";
import AccountImage from "components/Account/AccountImage";

import BN = require("bn.js");
import * as css from "./DaoHeader.scss";

const styles = {
circularSquare: {
borderRadius: "50%",
borderColor: "white",
borderStyle: "solid",
},
};

interface ISignal {
id: string;
data: any | string;
}

interface IExternalProps {
daoState: IDAOState | any;
signal?: ISignal | any;
}

type IProps = IExternalProps & ISubscriptionProps<[Scheme[], ISignal, IDAOState | any]>;

class DaoHeaderComponent extends React.Component<IProps, any> {

render() {
const { daoState, signal } = this.props;
const { name, memberCount, address, reputationTotalSupply } = daoState;
const data = {
daoImg: "/assets/images/generic-user-avatar.png",
reputationHolders: memberCount,
description: `
${name} is an independent, global community of people working together to build and promote Decentralized Autonomous Organizations (DAOs).
It’s the perfect place to get involved with DAOstack.
`,
};

const SupportedTokens = (): any => {
const tokensSupported = (tokenAddress: any) => {
return <SubscribedTokenBalance tokenAddress={tokenAddress} dao={daoState} key={"token_" + tokenAddress} />;
};
return Object.keys(supportedTokens()).map(tokensSupported);
};

const REP = fromWei(reputationTotalSupply).toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: 2 });

return (
<div className={css.headerWrap}>
<div className={css.daoImg}>
{/* Logo will go here instead of AccountImage this is just a placeholder */}
<AccountImage
accountAddress={address}
width={106}
style={styles.circularSquare}
/>
</div>
<div className={css.daoInfo}>
<b className={css.daoName}>
{ signal.name ? signal.name : name }
</b>
<b className={css.reputationHolders}>
{ data.reputationHolders } Reputation Holders
</b>
</div>

<div className={css.holdings}>
<span>Holdings</span>
<ul className={css.holdingsList}>
<li className={css.holdingsAmount}>
<span>{ REP } REP</span>
</li>
<SubscribedEthBalance dao={daoState} />
<SupportedTokens />
</ul>
</div>

<div className={css.daoHeadingGroup}>
<div className="header">
This is the { name } Header
</div>
<p className={css.daoDescription}>
{ data.description }
</p>
</div>
</div>
);
}
}
/***** DAO ETH Balance *****/
interface IEthProps extends ISubscriptionProps<BN|null> {
dao: IDAOState;
}

const ETHBalance = (props: IEthProps) => {
const { data } = props;
return <li key="ETH" className={css.holdingsAmount}><span>{formatTokens(data)} {baseTokenName()}</span></li>;
};

const SubscribedEthBalance = withSubscription({
wrappedComponent: ETHBalance,
loadingComponent: <li key="ETH">... {baseTokenName()}</li>,
errorComponent: null,
checkForUpdate: (oldProps: IEthProps, newProps: IEthProps) => {
return oldProps.dao.address !== newProps.dao.address;
},
createObservable: (props: IEthProps) => {
const arc = getArc();
return arc.dao(props.dao.address).ethBalance().pipe(ethErrorHandler());
},
});

/***** Token Balance *****/
interface ITokenProps extends ISubscriptionProps<any> {
dao: IDAOState;
tokenAddress: string;
}

const TokenBalance = (props: ITokenProps) => {
const { data, error, isLoading, tokenAddress } = props;

const tokenData = supportedTokens()[tokenAddress];
if (isLoading || error || ((data === null || isNaN(data) || data.isZero()) && tokenData.symbol !== genName())) {
return null;
}

return (
<li key={tokenAddress} className={css.holdingsAmount}>
<span>{formatTokens(data, tokenData["symbol"], tokenData["decimals"])}</span>
</li>
);
};

const SubscribedTokenBalance = withSubscription({
wrappedComponent: TokenBalance,
checkForUpdate: (oldProps: ITokenProps, newProps: ITokenProps) => {
return oldProps.dao.address !== newProps.dao.address || oldProps.tokenAddress !== newProps.tokenAddress;
},
createObservable: async (props: ITokenProps) => {
// General cache priming for the DAO we do here
// prime the cache: get all members fo this DAO -
const daoState = props.dao;

await daoState.dao.members({ first: 1000, skip: 0 }).pipe(first()).toPromise();

const arc = getArc();
const token = new Token(props.tokenAddress, arc);
return token.balanceOf(daoState.address).pipe(ethErrorHandler());
},
});

const DaoHeader = withSubscription({
wrappedComponent: DaoHeaderComponent,
checkForUpdate: [],
createObservable: (props: IExternalProps) => {
const dao = props.daoState.dao;
return dao.schemes({}, { fetchAllData: true, subscribe: true });
},
});

export default DaoHeader;
11 changes: 11 additions & 0 deletions src/components/Dao/DaoSchemesPage.scss
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@
padding-top: 30px;
}

.daoHeaderBackground {
// @TODO Image is repeating, check this later when using real image
// background-image: url(/assets/images/bg-test.jpeg);
width: 100vw;
position: fixed;
display: flex;
height: 30%;
top:0;
right: 0;
z-index: 9999999;
}

@media only screen and (max-width: 425px) {
.wrapper h1 {
Expand Down
Loading