diff --git a/CHANGELOG.md b/CHANGELOG.md index bbbe54b66..7021218f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +## 0.10.12 + - Features Added + - added custom landing page data for Venus Project + - made it easier for anyone to submit a PR to create their own DAO custom landing page + - added support for awarding the GEM and DXD tokens + + - Bugs Fixed + - DAO and account balances are now computed correctly on xDAI + - contract and account etherscan links now direct to blockscout, for xDAI + - enabling predictions now works on xDAI + - fixed several visual bugs + - fixed layout of description label on Blockchain interaction proposal create modal + - fixed crash when clicking on a DAO on the DAO Langing page. + ## 0.10.11 - Features Added - added the ability to receive email notifications, per DAO, when proposals are created diff --git a/README.md b/README.md index 3e071e395..6cb928b23 100644 --- a/README.md +++ b/README.md @@ -64,3 +64,7 @@ See [working with docker](./docs/docker.md) for details and troubleshooting. 1. If you need more than one test account you can also import these private keys: `0x6cbed15c793ce57650b9877cf6fa156fbef513c4e6134f022a85b1ffdd59b2a1`, `0x6370fd033278c143179d81c5526140625662b8daa446c22ee2d73db3707e620c` and `0x646f1ce2fdad0e6deeeb5c7e8e5543bdde65e86029e2fd9fc169899c440a7913`. Make sure to give them all differnent names. 1. Make sure that Metamask is connected to `127.0.0.1:8545` (choose from the "Networks" picklist in Metamask) 1. Go to http://127.0.0.1:3000 to load Alchemy + +## Adding custom landing page content for your DAO + +Just submit a PR to https://github.com/daostack/alchemy with your desired changes in src/customDaoInfo.tsx. You may supply plain text or HTML inside of parentheses. The HTML may contain React.js components, most notably `Link` which will cleanly navigate to pages within Alchemy. diff --git a/data/tokens.json b/data/tokens.json index dca20d186..4fbbe0828 100644 --- a/data/tokens.json +++ b/data/tokens.json @@ -62,6 +62,16 @@ "decimals": 18, "name": "Centrality Token", "symbol": "CENNZ" + }, + "0x859401b46E0f8b1CdF5432Af4b1426a8a5E5e0C8": { + "decimals": 18, + "name": "i4 token", + "symbol": "GEMS" + }, + "0xa1d65E8fB6e87b60FECCBc582F7f97804B725521": { + "decimals": 18, + "name": "DXdao", + "symbol": "DXD" } } }, diff --git a/package-lock.json b/package-lock.json index e2722a515..8a1fc54ea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "alchemy-client", - "version": "0.10.11", + "version": "0.10.12", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 5cd221464..35c24b78c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "alchemy-client", - "version": "0.10.11", + "version": "0.10.12", "description": "An app for collaborative networks (DAOs), based on the DAO stack.", "author": "DAOstack", "license": "GPL-3.0", diff --git a/src/components/Account/AccountBalances.tsx b/src/components/Account/AccountBalances.tsx index a1eb9de9f..fbffe4970 100644 --- a/src/components/Account/AccountBalances.tsx +++ b/src/components/Account/AccountBalances.tsx @@ -1,5 +1,5 @@ import { Address, IDAOState, IMemberState } from "@daostack/arc.js"; -import { baseTokenName, ethErrorHandler, genName } from "lib/util"; +import { baseTokenName, ethErrorHandler, genName, ethBalance } from "lib/util"; import BN = require("bn.js"); import AccountBalance from "components/Account/AccountBalance"; @@ -8,6 +8,7 @@ import withSubscription, { ISubscriptionProps } from "components/Shared/withSubs import * as css from "layouts/App.scss"; import * as React from "react"; import { combineLatest, of } from "rxjs"; +import { getArc } from "arc"; interface IExternalProps { dao?: IDAOState; @@ -68,10 +69,11 @@ export default withSubscription({ return of(null); } const daoState = dao; - const arc = daoState.dao.context; + const arc = getArc(); + return combineLatest( address && daoState.dao.member(address).state( { subscribe: true }) || of(null), - arc.ethBalance(address).pipe(ethErrorHandler()), + ethBalance(address).pipe(ethErrorHandler()), arc.GENToken().balanceOf(address).pipe(ethErrorHandler()), ); }, diff --git a/src/components/Account/AccountProfilePage.tsx b/src/components/Account/AccountProfilePage.tsx index f7cde8d5d..7dd5d83e4 100644 --- a/src/components/Account/AccountProfilePage.tsx +++ b/src/components/Account/AccountProfilePage.tsx @@ -12,7 +12,7 @@ import ThreeboxModal from "components/Shared/ThreeboxModal"; import withSubscription, { ISubscriptionProps } from "components/Shared/withSubscription"; import { Field, Formik, FormikProps } from "formik"; import Analytics from "lib/analytics"; -import { baseTokenName, ethErrorHandler, genName, formatTokens } from "lib/util"; +import { baseTokenName, ethErrorHandler, genName, formatTokens, ethBalance } from "lib/util"; import CopyToClipboard, { IconColor } from "components/Shared/CopyToClipboard"; import { Page } from "pages"; import { parse } from "query-string"; @@ -331,7 +331,7 @@ const SubscribedAccountProfilePage = withSubscription({ // subscribe if only to to get DAO reputation supply updates daoAvatarAddress ? dao.state( {subscribe: true}) : of(null), daoAvatarAddress ? dao.member(accountAddress).state() : of(null), - arc.ethBalance(accountAddress) + ethBalance(accountAddress) .pipe(ethErrorHandler()), arc.GENToken().balanceOf(accountAddress) .pipe(ethErrorHandler()) diff --git a/src/components/Dao/DaoLandingPage.scss b/src/components/Dao/DaoLandingPage.scss index 63b494501..05298cb15 100644 --- a/src/components/Dao/DaoLandingPage.scss +++ b/src/components/Dao/DaoLandingPage.scss @@ -45,9 +45,10 @@ } } - .welcome, - .visitProposals { - margin-bottom: 16px; + .infoContainer { + div { + margin-bottom: 16px; + } } .wallContainer { diff --git a/src/components/Dao/DaoLandingPage.tsx b/src/components/Dao/DaoLandingPage.tsx index 339c5db8b..3409de96e 100644 --- a/src/components/Dao/DaoLandingPage.tsx +++ b/src/components/Dao/DaoLandingPage.tsx @@ -6,7 +6,8 @@ import Analytics from "lib/analytics"; import { Link } from "react-router-dom"; import { BreadcrumbsItem } from "react-breadcrumbs-dynamic"; import { DiscussionEmbed } from "disqus-react"; -import { showSimpleMessage } from "lib/util"; +import { showSimpleMessage, targetedNetwork } from "lib/util"; +import customDaoInfo from "../../customDaoInfo"; type IExternalProps = { daoState: IDAOState; @@ -41,6 +42,7 @@ export default class DaoLandingPage extends React.Component { public render() { const daoState = this.props.daoState; + const customData = customDaoInfo[targetedNetwork()]?.[daoState.id.toLowerCase()]; this.disqusConfig.url = `${process.env.BASE_URL}/dao/${this.props.daoState.address}/discussion`; this.disqusConfig.identifier = this.props.daoState.address; @@ -61,21 +63,12 @@ export default class DaoLandingPage extends React.Component { - { (daoState.address === "0xfaf05fedf06cac499b899d6a2052f23ae239b29d") ? // SoS Collective on xDAI - <> -
Welcome to the {daoState.name} digital co-op.
-
Our first event is the SoS Hackathon: Fund your ideas and solutions to heal the world in crisis.
- - + {customData ? + <>{customData} : <> -
Welcome to {daoState.name}, a decentralized organization built on DAOstack.
- -
Visit the Proposals page to +
Welcome to {daoState.name}, a decentralized organization built on DAOstack.
+
Visit the Proposals page to make a proposal to the DAO or vote on existing proposals.
} diff --git a/src/components/Proposal/Create/SchemeForms/CreateKnownGenericSchemeProposal.tsx b/src/components/Proposal/Create/SchemeForms/CreateKnownGenericSchemeProposal.tsx index 41f013e5b..1d148330a 100644 --- a/src/components/Proposal/Create/SchemeForms/CreateKnownGenericSchemeProposal.tsx +++ b/src/components/Proposal/Create/SchemeForms/CreateKnownGenericSchemeProposal.tsx @@ -286,6 +286,7 @@ class CreateKnownSchemeProposal extends React.Component { const actions = this.state.actions; const currentAction = this.state.currentAction; + const fnDescription = () => (Short description of the proposal.
  • What are you proposing to do?
  • Why is it important?
  • How much will it cost the DAO?
  • When do you plan to deliver the work?
); return (
@@ -409,13 +410,15 @@ class CreateKnownSchemeProposal extends React.Component { className={touched.title && errors.title ? css.error : null} /> - + + + { setFieldValue("description", value); }} diff --git a/src/components/Proposal/Create/SchemeForms/CreateUnknownGenericSchemeProposal.tsx b/src/components/Proposal/Create/SchemeForms/CreateUnknownGenericSchemeProposal.tsx index 49ebc6782..1a2d1e6ac 100644 --- a/src/components/Proposal/Create/SchemeForms/CreateUnknownGenericSchemeProposal.tsx +++ b/src/components/Proposal/Create/SchemeForms/CreateUnknownGenericSchemeProposal.tsx @@ -185,8 +185,10 @@ class CreateGenericScheme extends React.Component { diff --git a/src/components/Proposal/ProposalData.tsx b/src/components/Proposal/ProposalData.tsx index 34af85456..dd55353ef 100644 --- a/src/components/Proposal/ProposalData.tsx +++ b/src/components/Proposal/ProposalData.tsx @@ -1,6 +1,6 @@ import { Address, IDAOState, IMemberState, IProposalState, IRewardState, Reward, Stake, Vote } from "@daostack/arc.js"; import { getArc } from "arc"; -import { ethErrorHandler } from "lib/util"; +import { ethErrorHandler, ethBalance } from "lib/util"; import BN = require("bn.js"); import withSubscription, { ISubscriptionProps } from "components/Shared/withSubscription"; @@ -142,7 +142,7 @@ export default withSubscription({ // TODO: also need the member state for the proposal proposer and beneficiary // but since we need the proposal state first to get those addresses we will need to // update the arc.js query to load them inline - concat(of(new BN("0")), arcDao.ethBalance()) + concat(of(new BN("0")), ethBalance(daoState.address)) .pipe(ethErrorHandler()), arc.GENToken().balanceOf(currentAccountAddress) .pipe(ethErrorHandler()), @@ -156,7 +156,7 @@ export default withSubscription({ of([]), // stakes of(null), // rewards of(null), // current account member state - concat(of(new BN(0)), arcDao.ethBalance()) // dao eth balance + concat(of(new BN(0)), ethBalance(daoState.address)) // dao eth balance .pipe(ethErrorHandler()), of(new BN(0)), // current account gen balance of(null), // current account GEN allowance diff --git a/src/components/Proposal/ProposalDetails.scss b/src/components/Proposal/ProposalDetails.scss index 2bf8bdc71..f3463876c 100644 --- a/src/components/Proposal/ProposalDetails.scss +++ b/src/components/Proposal/ProposalDetails.scss @@ -40,7 +40,6 @@ button.disabled { margin-bottom: 0px; display: flex; position: relative; - overflow: hidden; transition: all 0.25s ease; vertical-align: top; height: auto; @@ -124,64 +123,25 @@ button.disabled { } } -.statusTitle { - position: absolute; - top: 12px; - padding-bottom: 12px; - border-bottom: $gray-border-2; - width: 100%; - height: 20px; - line-height: 20px; - - h3 { - margin: 0; - padding: 0; - margin-left: 17px; - display: inline; - color: rgba(104, 155, 214, 1); - } - - span { - display: inline-block; - padding-left: 10px; - color: rgba(0, 113, 255, 1); - font-size: 11px; - margin-left: 10px; - border-left: 1px solid rgba(233, 238, 244, 1); - } -} - -.voteBox { +.votes { position: relative; background-color: $white; border-right: 1px solid rgba(215, 225, 237, 1); border-radius: 0 15px 15px 15px; margin: 0 0 20px 20px; -} -.voteButtons { - float: right; - top: 15px; - right: 10px; - position: relative; -} + .voteStatus { + height: 140px; + padding-top: 22px; -.altVoteButtons { - display: inline-block; - margin-bottom: 8px; -} - -.voteStatus { - height: 140px; - padding-top: 70px; - - .voteGraph { - float: right; - text-align: left; - display: inline-block; - right: 40px; - top: 12px; - position: relative; + .voteGraph { + float: right; + text-align: left; + display: inline-block; + right: 40px; + top: 12px; + position: relative; + } } } @@ -195,15 +155,46 @@ button.disabled { margin: 0 0 20px 20px; .predictionStatus { - padding-top: 45px; + padding-top: 8px; } } -.stakeButtons { - float: right; - top: 9px; - right: 10px; - position: relative; +.votes, +.predictions { + .header { + display: flex; + align-items: center; + justify-content: center; + border-bottom: $gray-border-2; + padding-top: 12px; + padding-bottom: 8px; + line-height: 20px; + + .title { + font-weight: 300; + font-size: 1.17em; + // margin: 0; + // padding: 0; + padding-left: 17px; + color: rgba(104, 155, 214, 1); + } + + .voters { + padding-left: 10px; + color: rgba(0, 113, 255, 1); + font-size: 11px; + margin-left: 10px; + border-left: 1px solid rgba(233, 238, 244, 1); + white-space: nowrap; + } + + .voteButtons, + .stakeButtons { + flex-grow: 2; + text-align: right; + padding-right: 13px; + } + } } .timer { @@ -281,6 +272,11 @@ button.disabled { font-size: 16px; font-weight: bold; } + + .altVoteButtons { + display: inline-block; + margin-bottom: 8px; + } } button.shareButton { @@ -324,7 +320,7 @@ button.disabled { } } - .voteBox { + .votes { margin: 0 0 0 0; border-radius: 0; } diff --git a/src/components/Proposal/ProposalDetailsPage.tsx b/src/components/Proposal/ProposalDetailsPage.tsx index 1ff129df2..d40b5ebbf 100644 --- a/src/components/Proposal/ProposalDetailsPage.tsx +++ b/src/components/Proposal/ProposalDetailsPage.tsx @@ -242,17 +242,11 @@ class ProposalDetailsPage extends React.Component {
-
- -
-
-

Votes

- 0 })}> - {proposal.votesCount} Vote{proposal.votesCount === 1 ? "" : "s"} > - +
+
+
Votes
+
0 })}> + {proposal.votesCount} Vote{proposal.votesCount === 1 ? "" : "s"} >
@@ -268,7 +262,7 @@ class ProposalDetailsPage extends React.Component {
-
+
@@ -284,22 +278,22 @@ class ProposalDetailsPage extends React.Component {
-
-

Predictions

-
+
+
Predictions
-
- +
+ +
diff --git a/src/components/Proposal/RedemptionsTip.scss b/src/components/Proposal/RedemptionsTip.scss new file mode 100644 index 000000000..ee1f23552 --- /dev/null +++ b/src/components/Proposal/RedemptionsTip.scss @@ -0,0 +1,22 @@ +.tipContainer { + padding-top: 8px; + + .message { + padding-bottom: 6px; + border-bottom: $gray-border; + margin-bottom: 6px; + + .icon { + display: inline-block; + margin-right: 6px; + position: relative; + top: 2px; + } + + .text { + display: inline-block; + width: 300px; + vertical-align: top; + } + } +} diff --git a/src/components/Proposal/RedemptionsTip.tsx b/src/components/Proposal/RedemptionsTip.tsx index 3de268bf6..ffc0bb38f 100644 --- a/src/components/Proposal/RedemptionsTip.tsx +++ b/src/components/Proposal/RedemptionsTip.tsx @@ -2,7 +2,7 @@ import { Address, IDAOState, IProposalState, IProposalOutcome } from "@daostack/ import Reputation from "components/Account/Reputation"; import { baseTokenName, formatTokens, fromWei, genName, tokenDecimals, tokenSymbol, AccountClaimableRewardsType } from "lib/util"; import * as React from "react"; -import * as css from "components/Shared/PreTransactionModal.scss"; +import * as css from "./RedemptionsTip.scss"; interface IProps { canRewardNone: boolean; diff --git a/src/components/Proposal/Staking/StakeButtons.scss b/src/components/Proposal/Staking/StakeButtons.scss index aaa4e9cc2..dd6726384 100644 --- a/src/components/Proposal/Staking/StakeButtons.scss +++ b/src/components/Proposal/Staking/StakeButtons.scss @@ -23,8 +23,12 @@ } .disabledPredictions { + position: relative; + bottom: 1px; font-size: 11px; color: $gray-1; + line-height: normal; + padding-right: 2px; } button { @@ -156,34 +160,20 @@ } .enablePredictions { - display: block; - width: 100%; - text-align: center; - margin-bottom: 10px; - button { - width: auto; - display: block; + width: 100px; + text-align: center; + height: 44px; border-radius: 12.5px; - position: relative; - top: 3px; - height: auto; padding-left: 5px; padding-right: 6px; padding-top: 5px; padding-bottom: 7px; - margin: 0 auto; background-color: #0076ff; color: white; font-weight: normal; font-family: LucidaGrande; } - - span { - display: block; - margin-top: 25px; - margin-bottom: 8px; - } } .toBoostMessage { @@ -217,22 +207,11 @@ } } - .disabledPredictions { - position: relative; - top: 3px; - } - .enablePredictions { - display: block; - width: 120px; - position: absolute; - top: 3px; - right: 18px; - text-align: right; - button { - display: inline-block; - top: 0; + width: 120px; + white-space: nowrap; + height: auto; } } } @@ -246,11 +225,6 @@ } } -.stakeControls { - position: relative; - text-align: center; -} - @keyframes pendingPassPrediction { 0% { border: 1px solid $black-tenthtone; @@ -294,7 +268,6 @@ } .preapproveWrapper { - position: relative; background-color: white; width: 280px; position: absolute; diff --git a/src/components/Proposal/Staking/StakeButtons.tsx b/src/components/Proposal/Staking/StakeButtons.tsx index 5471e58a2..08c8187bc 100644 --- a/src/components/Proposal/Staking/StakeButtons.tsx +++ b/src/components/Proposal/Staking/StakeButtons.tsx @@ -267,9 +267,9 @@ class StakeButtons extends React.Component { : "" } -
+
{stakingEnabled ? -
+ <> { (currentAccountAddress && tip(IProposalOutcome.Fail) !== "") ? @@ -290,7 +290,7 @@ class StakeButtons extends React.Component { {parentPage !== Page.ProposalDetails && proposal.stage === IProposalStage.PreBoosted && !expired && proposal.downStakeNeededToQueue.gtn(0) ?
>= {formatTokens(proposal.downStakeNeededToQueue, " GEN to un-boost")}
: ""} -
+ : {disabledMessage} diff --git a/src/components/Proposal/Voting/VoteButtons.scss b/src/components/Proposal/Voting/VoteButtons.scss index 7325d7776..b00821e5b 100644 --- a/src/components/Proposal/Voting/VoteButtons.scss +++ b/src/components/Proposal/Voting/VoteButtons.scss @@ -171,8 +171,12 @@ } .votingDisabled { + position: relative; + bottom: 2px; font-size: 11px; color: $gray-1; + line-height: normal; + padding-right: 2px; } button.disabled { diff --git a/src/components/Proposal/Voting/VoteButtons.tsx b/src/components/Proposal/Voting/VoteButtons.tsx index 30ba5152e..e72e3e8a6 100644 --- a/src/components/Proposal/Voting/VoteButtons.tsx +++ b/src/components/Proposal/Voting/VoteButtons.tsx @@ -173,7 +173,7 @@ class VoteButtons extends React.Component { /> : "" } {contextMenu ? -
+ <>
@@ -220,9 +220,9 @@ class VoteButtons extends React.Component { }
-
+ : -
+ <>
{!votingDisabled ?
@@ -253,7 +253,7 @@ class VoteButtons extends React.Component { - Against
-
+ }
); diff --git a/src/components/Redemptions/RedemptionsMenu.tsx b/src/components/Redemptions/RedemptionsMenu.tsx index f915242ec..4c93ed5ce 100644 --- a/src/components/Redemptions/RedemptionsMenu.tsx +++ b/src/components/Redemptions/RedemptionsMenu.tsx @@ -7,7 +7,7 @@ import withSubscription, { ISubscriptionProps } from "components/Shared/withSubs import ActionButton from "components/Proposal/ActionButton"; import RedemptionsString from "components/Proposal/RedemptionsString"; import ProposalSummary from "components/Proposal/ProposalSummary"; -import { ethErrorHandler, humanProposalTitle } from "lib/util"; +import { ethErrorHandler, humanProposalTitle, ethBalance } from "lib/util"; import { Page } from "pages"; import * as React from "react"; import { connect } from "react-redux"; @@ -198,12 +198,12 @@ const SubscribedMenuItemContent = withSubscription({ const { currentAccountAddress, proposal } = props; const arc = getArc(); const dao = arc.dao(proposal.dao.id); - const ethBalance = concat(of(new BN("0")), dao.ethBalance()).pipe(ethErrorHandler()); + const daoEthBalance = concat(of(new BN("0")), ethBalance(proposal.dao.id)).pipe(ethErrorHandler()); const rewards = proposal.proposal.rewards({ where: { beneficiary: currentAccountAddress }}) .pipe(map((rewards: Reward[]): Reward => rewards.length === 1 && rewards[0] || null)) .pipe(mergeMap(((reward: Reward): Observable => reward ? reward.state() : of(null)))); // subscribe to dao to get DAO reputation supply updates - return combineLatest(dao.state( { subscribe: true }), ethBalance, rewards); + return combineLatest(dao.state( { subscribe: true }), daoEthBalance, rewards); }, }); diff --git a/src/components/Shared/PreTransactionModal.scss b/src/components/Shared/PreTransactionModal.scss index 5df06989f..9f5c1b036 100644 --- a/src/components/Shared/PreTransactionModal.scss +++ b/src/components/Shared/PreTransactionModal.scss @@ -396,7 +396,8 @@ input[type="number"] { } .modalWindow { - width: 500px; + max-width: 500px; + width: 90vw; position: absolute; left: 50%; top: 50%; @@ -530,6 +531,8 @@ input[type="number"] { display: inline; color: $gray-1; opacity: 0.7; + position: relative; + bottom: 1px; strong { font-weight: normal; @@ -538,6 +541,7 @@ input[type="number"] { .transactionType { font-size: 21px; + margin-right: 6px; .passVote { color: $accent-3; @@ -585,7 +589,7 @@ input[type="number"] { .stakingForm { position: relative; - padding: 40px; + padding: 30px 40px; .formGroup { line-height: 24px; @@ -610,7 +614,7 @@ input[type="number"] { align-items: center; .predictionAmount { - margin-right: 16px; + padding-right: 16px; input { background-color: transparent; @@ -628,6 +632,7 @@ input[type="number"] { .genLabel { display: inline-block; + margin-bottom: 10px; &.genSymbol { opacity: 0.5; @@ -641,6 +646,12 @@ input[type="number"] { line-height: 1.2em; text-align: left; + .balance { + display: inline-block; + margin-right: 6px; + margin-bottom: 4px; + } + .exchangeList { color: rgba(5, 113, 255, 1); font-size: 11px; @@ -725,28 +736,13 @@ input[type="number"] { } .genError { - position: absolute; - width: 300px; - text-align: center; - color: rgba(80, 97, 118, 1); - left: 41px; - top: 81px; - - h4 { - color: $accent-2; - font-size: 14px; - font-family: $body-font; - text-align: left; - font-weight: normal; - margin: 0; - padding-top: 8px; - } + color: $accent-2; + font-size: 14px; + font-family: $body-font; + font-weight: normal; - span { - display: block; - font-size: 10px; - font-weight: normal; - color: rgba(80, 97, 118, 1); + &.hidden { + display: none; } } } @@ -769,26 +765,3 @@ input[type="number"] { } } } - -.tipContainer { - padding-top: 8px; - - .message { - padding-bottom: 6px; - border-bottom: $gray-border; - margin-bottom: 6px; - - .icon { - display: inline-block; - margin-right: 6px; - position: relative; - top: 2px; - } - - .text { - display: inline-block; - width: 300px; - vertical-align: top; - } - } -} diff --git a/src/components/Shared/PreTransactionModal.tsx b/src/components/Shared/PreTransactionModal.tsx index 63e7b1453..30abe7f2d 100644 --- a/src/components/Shared/PreTransactionModal.tsx +++ b/src/components/Shared/PreTransactionModal.tsx @@ -343,11 +343,6 @@ class PreTransactionModal extends React.Component {
Your stake -
-

- You do not have enough GEN -

-
{
GEN
-
Your balance: {formatTokens(currentAccountGens)} GEN
+
Your balance: {formatTokens(currentAccountGens)} GEN
- Buy GEN > + [Buy GEN]
    { getExchangesList().map(this.exchangeHtml) @@ -380,6 +375,7 @@ class PreTransactionModal extends React.Component { }
+
You do not have enough GEN
: "" } diff --git a/src/customDaoInfo.tsx b/src/customDaoInfo.tsx new file mode 100644 index 000000000..ac9295ec7 --- /dev/null +++ b/src/customDaoInfo.tsx @@ -0,0 +1,40 @@ +import * as React from "react"; +import { Link } from "react-router-dom"; +import { ReactElement } from "react"; + +interface IDaoCustomInfo { + [network: string]: { [address: string]: ReactElement | string }; +} + +const data: IDaoCustomInfo = { + ganache: { + }, + rinkeby: { + "0x9003196e314e03dae65f0bf26788befc714d68a1": ( + <> +
Welcome to The Venus Project DAO, a decentralized organization built on DAOstack.
+
This is a DAO for the purpose of exploring new governance models and platforms for The Venus Project.
+
Visit the Proposals page to make a proposal to the DAO or vote on existing proposals.
+ + ), + }, + kovan: { + }, + xdai: { + "0xfaf05fedf06cac499b899d6a2052f23ae239b29d": ( + <> +
Welcome to the SoS Collective digital co-op.
+
Our first event is the SoS Hackathon: Fund your ideas and solutions to heal the world in crisis.
+
    +
  • Register for the hackathon here.
  • +
  • Create an onboarding proposal for the cooperative here.
  • +
  • Join our Discord community for fu,ther discussions here: https://discord.gg/rUr3rp7
  • +
+ + ), + }, + main: { + }, +}; + +export default data; diff --git a/src/layouts/SidebarMenu.tsx b/src/layouts/SidebarMenu.tsx index 41d509837..1a247448d 100644 --- a/src/layouts/SidebarMenu.tsx +++ b/src/layouts/SidebarMenu.tsx @@ -9,7 +9,7 @@ import FollowButton from "components/Shared/FollowButton"; import withSubscription, { ISubscriptionProps } from "components/Shared/withSubscription"; import { generate } from "geopattern"; import Analytics from "lib/analytics"; -import { baseTokenName, ethErrorHandler, formatTokens, genName, getExchangesList, supportedTokens, fromWei } from "lib/util"; +import { baseTokenName, ethErrorHandler, formatTokens, genName, getExchangesList, supportedTokens, fromWei, ethBalance, linkToEtherScan } from "lib/util"; import { parse } from "query-string"; import * as React from "react"; import { matchPath, Link, RouteComponentProps } from "react-router-dom"; @@ -85,7 +85,7 @@ class SidebarMenu extends React.Component { public daoMenu() { const dao = this.props.data; - const daoHoldingsAddress = "https://etherscan.io/tokenholdings?a=" + dao.address; + const daoHoldingsAddress = linkToEtherScan(dao.address, true); const bgPattern = generate(dao.address + dao.name); return ( @@ -281,8 +281,7 @@ const SubscribedEthBalance = withSubscription({ return oldProps.dao.address !== newProps.dao.address; }, createObservable: (props: IEthProps) => { - const arc = getArc(); - return arc.dao(props.dao.address).ethBalance().pipe(ethErrorHandler()); + return ethBalance(props.dao.address).pipe(ethErrorHandler()); }, }); diff --git a/src/lib/util.ts b/src/lib/util.ts index 82ac78bb1..6b5f85aca 100644 --- a/src/lib/util.ts +++ b/src/lib/util.ts @@ -5,7 +5,7 @@ import { IProposalState, IRewardState, } from "@daostack/arc.js"; -import { of } from "rxjs"; +import { of, Observable } from "rxjs"; import { catchError } from "rxjs/operators"; import BN = require("bn.js"); @@ -17,7 +17,6 @@ import * as moment from "moment-timezone"; import { getArc } from "../arc"; import { ISimpleMessagePopupProps } from "components/Shared/SimpleMessagePopup"; - const tokens = require("data/tokens.json"); const exchangesList = require("data/exchangesList.json"); const Web3 = require("web3"); @@ -325,7 +324,7 @@ export async function getNetworkName(id?: string): Promise { } } -export function linkToEtherScan(address: Address) { +export function linkToEtherScan(address: Address, tokenHoldings = false) { let prefix = ""; const arc = getArc(); switch (arc.web3.currentProvider.__networkId) { @@ -335,8 +334,14 @@ export function linkToEtherScan(address: Address) { case "42": prefix = "kovan."; break; + case "100": // xdai + return tokenHoldings ? + `https://blockscout.com/poa/xdai/address/${address}/tokens` : + `https://blockscout.com/poa/xdai/${address.length > 42 ? "tx" : "address"}/${address}`; } - return `https://${prefix}etherscan.io/address/${address}`; + return tokenHoldings ? + `https://${prefix}etherscan.io/tokenholdings?a=${address}` : + `https://${prefix}etherscan.io/address/${address}`; } export type AccountClaimableRewardsType = { [key: string]: BN }; @@ -587,3 +592,8 @@ export function initializeUtils(options: IInitializeOptions) { * which when wrong would be more wrong than not splitting (like "I D").) **/ export const splitCamelCase = (str: string): string => `${str[0].toUpperCase()}${str.slice(1).replace(/([a-z])([A-Z])/g, "$1 $2")}`; + +export function ethBalance(address: Address): Observable { + const arc = getArc(); + return arc.ethBalance(address); +} diff --git a/src/settings.ts b/src/settings.ts index a8232ce22..b6ed19a8d 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -200,8 +200,8 @@ export const settings = { graphqlHttpProvider: process.env.ARC_GRAPHQLHTTPPROVIDER || SubgraphEndpoints.http_xdai, graphqlWsProvider: process.env.ARC_GRAPHQLWSPROVIDER || SubgraphEndpoints.ws_xdai, graphqlSubscribeToQueries: false, - web3Provider: process.env.ARC_WEB3PROVIDER || "wss://poa.api.nodesmith.io/v1/dai/jsonrpc?apiKey=128059b9320a462699aef283a7ae2546", - web3ProviderRead: process.env.ARC_WEB3PROVIDERREAD || "wss://poa.api.nodesmith.io/v1/dai/jsonrpc/ws?apiKey=128059b9320a462699aef283a7ae2546", + web3Provider: process.env.ARC_WEB3PROVIDER || "wss://xdai.poanetwork.dev/wss", + web3ProviderRead: process.env.ARC_WEB3PROVIDERREAD || "wss://xdai.poanetwork.dev/wss", ipfsProvider: process.env.ARC_IPFSPROVIDER || "https://api.thegraph.com:443/ipfs-daostack/api/v0", txSenderServiceUrl: "", web3ConnectProviderOptions: getWeb3ConnectProviderOptions("xdai"),