diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json
index ebc1c72de..3b42b05a0 100644
--- a/i18n/en.i18n.json
+++ b/i18n/en.i18n.json
@@ -154,7 +154,7 @@
"email-username": "E-mail",
"email-sample": "satoshi@nakamoto.org",
"password-sample": "make it long.",
- "sign-in": "Sign In",
+ "sign-in": "Connect Wallet",
"password": "Password",
"please-wait": "Please wait...",
"use-social-media": "or use:",
@@ -889,5 +889,23 @@
"voted-no": "{{shares}} {{label}} for No to {{proposal}}",
"shares": "shares",
"share": "share",
- "arrow-verb": " → "
+ "arrow-verb": " → ",
+ "overview": "Overview",
+ "recent": "Recent",
+ "in-queue": "In Queue",
+ "voting-now": "Voting Now",
+ "grace-period": "Grace Period",
+ "ready-to-process": "Ready to process",
+ "rejected": "Rejected",
+ "approved": "Approved",
+ "quits": "Quits",
+ "jailed": "Jailed",
+ "kicked": "Kicked",
+ "sponsored": "Sponsored",
+ "guild-kicks": "Guild Kicks",
+ "proposals-account": "Proposals by {{account}}",
+ "memberships-account": "Memberships of {{account}}",
+ "proposals-sidebar": "Recent Proposals",
+ "memberships-sidebar": "Your Memberships",
+ "no-memberships-found": "No DAO memberships found."
}
diff --git a/imports/ui/components/Account/Account.jsx b/imports/ui/components/Account/Account.jsx
index 502b3c95d..f9c33773a 100644
--- a/imports/ui/components/Account/Account.jsx
+++ b/imports/ui/components/Account/Account.jsx
@@ -5,6 +5,7 @@ import PropTypes from 'prop-types';
import ApolloClient, { gql, InMemoryCache } from 'apollo-boost';
import { ApolloProvider } from 'react-apollo';
import { useQuery } from '@apollo/react-hooks';
+import { gui } from '/lib/const';
import { shortenCryptoName } from '/imports/startup/both/modules/metamask';
@@ -38,7 +39,7 @@ const ENS_ACCOUNT = `
*/
const getENSName = (data, publicAddress) => {
if (data.domains.length > 0) {
- return data.domains[0].name;
+ return (data.domains[0].name.length > gui.MAX_LENGTH_ACCOUNT_NAMES) ? `${data.domains[0].name.slice(0, gui.MAX_LENGTH_ACCOUNT_NAMES)}...` : data.domains[0].name;
}
return shortenCryptoName(publicAddress);
};
diff --git a/imports/ui/components/Choice/Choice.jsx b/imports/ui/components/Choice/Choice.jsx
index b11dfd380..e370026e6 100644
--- a/imports/ui/components/Choice/Choice.jsx
+++ b/imports/ui/components/Choice/Choice.jsx
@@ -37,7 +37,8 @@ export default class Choice extends Component {
}
pollOpen() {
- return (this.props.votingPeriodBegins > this.props.now && this.props.votingPeriodEnds < this.props.now);
+ const now = parseInt(this.props.now / 1000, 10);
+ return ((this.props.votingPeriodBegins < now) && (this.props.votingPeriodEnds > now));
}
canVote = async (accountAddress) => {
@@ -108,6 +109,8 @@ export default class Choice extends Component {
return alreadyVoted();
}
+ console.log(`this.pollOpen():`);
+ console.log(this.pollOpen());
// poll date
if (!this.pollOpen()) {
return pollClosed();
diff --git a/imports/ui/components/Countdown/Countdown.jsx b/imports/ui/components/Countdown/Countdown.jsx
index 0049e789d..b4e009cd2 100644
--- a/imports/ui/components/Countdown/Countdown.jsx
+++ b/imports/ui/components/Countdown/Countdown.jsx
@@ -48,6 +48,8 @@ export default class Countdown extends Component {
getPollLabel() {
let delta;
let label;
+ const now = parseInt(this.props.now / 1000, 10);
+
if (this.props.now > this.state.graceEnd) {
delta = parseInt(this.props.now - this.state.end, 10);
label = 'poll-ended-days-ago';
diff --git a/imports/ui/components/DAO/DAO.jsx b/imports/ui/components/DAO/DAO.jsx
index 44100f52c..4bd98cdfa 100644
--- a/imports/ui/components/DAO/DAO.jsx
+++ b/imports/ui/components/DAO/DAO.jsx
@@ -5,6 +5,7 @@ import PropTypes from 'prop-types';
import ApolloClient, { gql, InMemoryCache } from 'apollo-boost';
import { ApolloProvider } from 'react-apollo';
import { useQuery } from '@apollo/react-hooks';
+import { gui } from '/lib/const';
import { shortenCryptoName } from '/imports/startup/both/modules/metamask';
@@ -29,7 +30,7 @@ const makeBlockie = require('ethereum-blockies-base64');
/**
* @summary renders a post in the timeline
*/
-const DAOQuery = ({ publicAddress, width, height }) => {
+const DAOQuery = ({ publicAddress, width, height, format }) => {
const { loading, error, data } = useQuery(gql(GET_DAO.replace('{{molochAddress}}', publicAddress)));
const image = makeBlockie(publicAddress);
@@ -56,19 +57,28 @@ const DAOQuery = ({ publicAddress, width, height }) => {
if (!daoTitle) {
label = shortenCryptoName(publicAddress);
} else {
- label = (daoTitle.length > 20) ? `${daoTitle.slice(0, 19)}...` : daoTitle;
+ label = (daoTitle.length > gui.MAX_LENGTH_ACCOUNT_NAMES) ? `${daoTitle.slice(0, gui.MAX_LENGTH_ACCOUNT_NAMES)}...` : daoTitle;
}
return (
-
-
-
+ :
+
+
+
+
+ }
);
};
@@ -77,6 +87,7 @@ DAOQuery.propTypes = {
publicAddress: PropTypes.string,
width: PropTypes.string,
height: PropTypes.string,
+ format: PropTypes.string,
};
@@ -86,7 +97,7 @@ DAOQuery.propTypes = {
const DAO = (props) => {
return (
-
+
);
};
diff --git a/imports/ui/components/Item/Item.jsx b/imports/ui/components/Item/Item.jsx
new file mode 100644
index 000000000..d91aea3e0
--- /dev/null
+++ b/imports/ui/components/Item/Item.jsx
@@ -0,0 +1,113 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import { Router } from 'meteor/iron:router';
+
+import { getTemplateImage } from '/imports/ui/templates/layout/templater.js';
+
+/**
+* @summary checks if href matches to current url
+* @param {string} url with href to match
+* @return {boolean}
+*/
+const _matchingContext = (url) => {
+ if (url) {
+ const current = Router.current().url.replace(window.location.origin, '');
+ if ((Router.current().params.username === url.substring(6))
+ || (current === url)
+ ) {
+ return true;
+ }
+ }
+ return false;
+};
+
+
+/**
+* @summary displays the contents of a poll
+*/
+export default class Item extends Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ inContext: _matchingContext(this.props.href),
+ icon: {
+ paper: '',
+ paperActive: '',
+ },
+ };
+ }
+
+ async componentDidMount() {
+ await this.setIcons();
+ }
+
+ async setIcons() {
+ this.setState({
+ icon: {
+ paper: await getTemplateImage('paper'),
+ paperActive: await getTemplateImage('paper-active'),
+ },
+ });
+ }
+
+ getLabel() {
+ if (this.props.children) {
+ return this.props.children;
+ }
+ return (this.props.label);
+ }
+
+ getStyle() {
+ return `menu-item ${this.state.inContext ? 'menu-item-selected' : null}`;
+ }
+
+ getTagStyle() {
+ return `sidebar-tag ${this.state.inContext ? 'sidebar-tag-selected' : null}`;
+ }
+
+ getIcon() {
+ return (this.state.inContext) ? this.state.icon.paperActive : this.state.icon.paper;
+ }
+
+ getLabelStyle() {
+ if (this.props.children) {
+ return `sidebar-label sidebar-label-${this.props.children.type.name.toLowerCase()}`;
+ }
+ return 'sidebar-label';
+ }
+
+ render() {
+ if (this.props.hideEmpty && this.props.score === 0) return null;
+ return (
+
+ {(this.props.sharp) ?
+
+
+
+ :
+ null
+ }
+
+ {this.getLabel()}
+
+
+ {this.props.score}
+
+
+ );
+ }
+}
+
+Item.propTypes = {
+ sharp: PropTypes.bool,
+ label: PropTypes.string,
+ score: PropTypes.number,
+ hideEmpty: PropTypes.bool,
+ href: PropTypes.string,
+ children: PropTypes.oneOfType([
+ PropTypes.arrayOf(PropTypes.node),
+ PropTypes.node,
+ ]),
+};
+
diff --git a/imports/ui/components/Menu/Menu.jsx b/imports/ui/components/Menu/Menu.jsx
new file mode 100644
index 000000000..1ce0f0385
--- /dev/null
+++ b/imports/ui/components/Menu/Menu.jsx
@@ -0,0 +1,271 @@
+import { Meteor } from 'meteor/meteor';
+import React, { Component } from 'react';
+import { Router } from 'meteor/iron:router';
+
+import ApolloClient, { gql, InMemoryCache } from 'apollo-boost';
+import { ApolloProvider } from 'react-apollo';
+import { useQuery } from '@apollo/react-hooks';
+import { TAPi18n } from 'meteor/tap:i18n';
+import PropTypes from 'prop-types';
+import { shortenCryptoName, getWeb3Wallet } from '/imports/startup/both/modules/metamask';
+import { defaults } from '/lib/const.js';
+
+import Item from '/imports/ui/components/Item/Item.jsx';
+import DAO from '/imports/ui/components/DAO/DAO.jsx';
+
+const numeral = require('numeral');
+
+export const GET_MEMBERSHIPS = `
+{
+ members(where: { memberAddress: "{{memberAddress}}" }) {
+ id
+ memberAddress
+ moloch {
+ id
+ title
+ }
+ tokenTribute
+ exists
+ shares
+ didRagequit
+ submissions {
+ id
+ didPass
+ guildkick
+ gracePeriodEnds
+ votingPeriodStarts
+ votingPeriodEnds
+ sponsor
+ processed
+ }
+ kicked
+ jailed {
+ id
+ }
+ proposedToKick
+ }
+}
+`;
+
+const client = new ApolloClient({
+ uri: Meteor.settings.public.graph.molochs,
+ cache: new InMemoryCache(),
+});
+
+/**
+ * @summary style based on type of device
+ * @return {string} with css classes
+ */
+const _getMenuStyle = () => {
+ if (Meteor.Device.isPhone()) {
+ return 'sidebar sidebar-desktop';
+ }
+ return 'sidebar';
+};
+
+/**
+ * @summary based on a members data, count the types of proposals
+ * @return {number} with final count
+ */
+const _getProposalCount = (list, label) => {
+ const now = parseInt(new Date().getTime() / 1000, 10);
+ const counter = [];
+
+ _.reduce(list, (memo, num) => {
+ if (label === 'all') {
+ counter.push(num.submissions.length);
+ }
+ counter.push(
+ _.reduce(num.submissions, (iterator, proposal) => {
+ switch (label) {
+ case 'in-queue':
+ if (proposal.votingPeriodStarts.toNumber() > now) return parseInt(iterator + 1, 10);
+ break;
+ case 'voting-now':
+ if ((proposal.votingPeriodStarts.toNumber() > now) && (proposal.votingPeriodEnds.toNumber() < now)) return parseInt(iterator + 1, 10);
+ break;
+ case 'grace-period':
+ if (proposal.votingPeriodEnds.toNumber() > now && (proposal.gracePeriodEnds.toNumber() < now)) return parseInt(iterator + 1, 10);
+ break;
+ case 'ready-to-process':
+ if ((proposal.gracePeriodEnds.toNumber() < now) && !proposal.processed) return parseInt(iterator + 1, 10);
+ break;
+ case 'rejected':
+ if (proposal.gracePeriodEnds.toNumber() < now && !proposal.didPass) return parseInt(iterator + 1, 10);
+ break;
+ case 'approved':
+ if (proposal.didPass) return parseInt(iterator + 1, 10);
+ break;
+ case 'sponsored':
+ if (proposal.sponsor) return parseInt(iterator + 1, 10);
+ break;
+ case 'kicked':
+ if (proposal.guildKick) return parseInt(iterator + 1, 10);
+ break;
+ default:
+ }
+ return iterator;
+ }, 0)
+ );
+ }, 0);
+ return _.reduce(counter, (memory, numerator) => { return parseInt(memory + numerator, 10); }, 0);
+};
+
+/**
+* @summary displays corresponding separator headline
+* @param {string} headline from TAPi18n dictionary
+* @param {string} account to parse in title
+* @return {string} with headline for separator
+*/
+const _getHeadline = (headline, account) => {
+ if (Router.current().url.replace(window.location.origin, '') === '/') {
+ return TAPi18n.__(`${headline}-sidebar`);
+ }
+ return TAPi18n.__(`${headline}-account`).replace('{{account}}', shortenCryptoName(account));
+};
+
+/**
+* @summary displays the contents of a poll
+*/
+const MenuQuery = ({ account }) => {
+ const atHome = (Router.current().url.replace(window.location.origin, '') === '/');
+ const hideEmpty = !atHome;
+ const defaultLabels = ['all', 'in-queue', 'voting-now', 'grace-period', 'ready-to-process', 'guild-kicks', 'rejected', 'approved'];
+
+ const defaultMenu = (
+
+
+
+
+
+
+
+
+
+
+ );
+
+ if (account !== defaults.EMPTY) {
+ const { loading, error, data } = useQuery(gql(GET_MEMBERSHIPS.replace('{{memberAddress}}', account)));
+
+ if (loading) {
+ return (
+
+
+
+
+ {_getHeadline('proposals', account)}
+
+ {
}
+
+
+
+
+ );
+ }
+ if (error) return `Error! ${error}`;
+
+ console.log(data);
+
+ const sorted = _.sortBy(data.members, (item) => { return (item.submissions.length * -1); });
+ const daoList = sorted.map((item, key) => {
+ return (
+
-
+
+
+ );
+ });
+
+ let i = 0;
+ for (const defaultItem of defaultMenu.props.children) {
+ defaultItem.props.score = (atHome) ? null : _getProposalCount(data.members, defaultLabels[i]);
+ i += 1;
+ }
+ const menuList = defaultMenu;
+
+ return (
+
+
+
+
+ {_getHeadline('proposals', account)}
+
+ {menuList}
+
+ {_getHeadline('memberships', account)}
+
+ {(daoList.length > 0) ?
+ daoList
+ :
+
+ {TAPi18n.__('no-memberships-found')}
+
+ }
+
+
+
+ );
+ }
+
+ return (
+
+
+
+
+ {_getHeadline('proposals', account)}
+
+ {defaultMenu}
+
+
+
+ );
+};
+
+MenuQuery.propTypes = {
+ account: PropTypes.string,
+};
+
+/**
+* @summary renders a post in the timeline
+*/
+export default class Menu extends Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ accounts: [defaults.EMPTY],
+ };
+ }
+
+ async componentDidMount() {
+ await this.getAccounts();
+ }
+
+ async getAccounts() {
+ const web3 = getWeb3Wallet();
+ const accounts = await web3.eth.getAccounts();
+
+ if (accounts.length > 0) {
+ this.setState({ accounts });
+ }
+ }
+
+ getContext() {
+ const current = Router.current().url.replace(window.location.origin, '');
+ if (current === '/') {
+ return this.state.accounts[0];
+ }
+ return Router.current().params.account;
+ }
+
+ render() {
+ return (
+
+
+
+ );
+ }
+}
+
+Menu.propTypes = MenuQuery.propTypes;
+
diff --git a/imports/ui/components/Menu/menu.html b/imports/ui/components/Menu/menu.html
new file mode 100644
index 000000000..3fde190a5
--- /dev/null
+++ b/imports/ui/components/Menu/menu.html
@@ -0,0 +1,5 @@
+
+
+ {{> React component=Menu}}
+
+
\ No newline at end of file
diff --git a/imports/ui/components/Menu/menu.js b/imports/ui/components/Menu/menu.js
new file mode 100644
index 000000000..4d6902f76
--- /dev/null
+++ b/imports/ui/components/Menu/menu.js
@@ -0,0 +1,12 @@
+import { Template } from 'meteor/templating';
+
+import Menu from '/imports/ui/components/Menu/Menu.jsx';
+
+import '/imports/ui/components/Menu/menu.html';
+
+Template.menu.helpers({
+ Menu() {
+ return Menu;
+ },
+});
+
diff --git a/imports/ui/components/Timeline/Timeline.jsx b/imports/ui/components/Timeline/Timeline.jsx
index 9b8955cba..4c92bff1a 100644
--- a/imports/ui/components/Timeline/Timeline.jsx
+++ b/imports/ui/components/Timeline/Timeline.jsx
@@ -1,9 +1,9 @@
import { Meteor } from 'meteor/meteor';
import React from 'react';
-import ApolloClient, { InMemoryCache } from 'apollo-boost';
-import { ApolloProvider, Query } from 'react-apollo';
+import ApolloClient, { InMemoryCache, gql } from 'apollo-boost';
+import { ApolloProvider } from 'react-apollo';
import { TAPi18n } from 'meteor/tap:i18n';
-import PropTypes from 'prop-types';
+import { useQuery } from '@apollo/react-hooks';
import Account from '/imports/ui/components/Account/Account.jsx';
import Post from '/imports/ui/components/Post/Post.jsx';
@@ -20,7 +20,37 @@ import Survey from '/imports/ui/components/Poll/Survey';
import Social from '/imports/ui/components/Social/Social';
import { defaults } from '/lib/const';
-import { MOLOCHS } from '/imports/ui/components/Timeline/queries';
+
+export const GET_PROPOSALS = `
+{
+ proposals(first: 50, orderBy:createdAt, orderDirection:desc) {
+ id
+ proposalId
+ createdAt
+ proposalIndex
+ startingPeriod
+ moloch {
+ id
+ }
+ memberAddress
+ applicant
+ tributeOffered
+ tributeToken
+ tributeTokenSymbol
+ tributeTokenDecimals
+ sharesRequested
+ yesVotes
+ noVotes
+ yesShares
+ noShares
+ details
+ processed
+ votingPeriodStarts
+ votingPeriodEnds
+ gracePeriodEnds
+ }
+}
+`;
const client = new ApolloClient({
uri: Meteor.settings.public.graph.molochs,
@@ -31,100 +61,90 @@ const _getPercentage = (percentageAmount, remainder) => {
return parseFloat((percentageAmount * 100) / (percentageAmount + remainder), 10);
};
-const Feed = (props) => {
- return (
-
- {({ loading, error, data }) => {
- if (loading) return ;
- if (error) return Error!
;
+const Feed = () => {
+ const { loading, error, data } = useQuery(gql(GET_PROPOSALS));
- console.log(data.proposals);
+ if (loading) return ;
+ if (error) return Error!
;
- const accountAddress = Meteor.user() ? Meteor.user().username : null;
- const daoName = 'MolochDAO';
- const timestamp = new Date().getTime();
+ console.log(data.proposals);
- return data.proposals.map((proposal) => {
- const totalVoters = parseInt(proposal.yesVotes.toNumber() + proposal.noVotes.toNumber(), 10).toString();
- const yesPercentage = _getPercentage(proposal.yesShares.toNumber(), proposal.noShares.toNumber()).toString();
- const noPercentage = _getPercentage(proposal.noShares.toNumber(), proposal.yesShares.toNumber()).toString();
- const daoAddress = proposal.moloch.id;
- const status = (proposal.didPass) ? 'PASSED' : 'FAILED';
- const isPoll = (proposal.startingPeriod !== '0');
- const url = `/proposal/${proposal.id}`;
+ const accountAddress = Meteor.user() ? Meteor.user().username : null;
+ const daoName = 'MolochDAO';
+ const timestamp = new Date().getTime();
- return (
-
-
-
-
-
-
-
-
-
-
-
-
- {(isPoll) ?
-
-
-
-
-
-
-
-
-
-
-
-
- :
- null
- }
-
-
-
-
- );
- });
- }}
-
- );
-};
+ return data.proposals.map((proposal) => {
+ const totalVoters = parseInt(proposal.yesVotes.toNumber() + proposal.noVotes.toNumber(), 10).toString();
+ const yesPercentage = _getPercentage(proposal.yesShares.toNumber(), proposal.noShares.toNumber()).toString();
+ const noPercentage = _getPercentage(proposal.noShares.toNumber(), proposal.yesShares.toNumber()).toString();
+ const daoAddress = proposal.moloch.id;
+ const status = (proposal.didPass) ? 'PASSED' : 'FAILED';
+ const isPoll = (proposal.startingPeriod !== '0');
+ const url = `/dao/${proposal.moloch.id}/proposal/${proposal.proposalIndex}`;
-Feed.propTypes = {
- query: PropTypes.instanceOf(Object),
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ {(isPoll) ?
+
+
+
+
+
+
+
+
+
+
+
+
+ :
+ null
+ }
+
+
+
+
+ );
+ });
};
const Timeline = () => {
return (
-
+
);
};
diff --git a/imports/ui/components/Timeline/queries.js b/imports/ui/components/Timeline/queries.js
deleted file mode 100644
index 58d6d3dea..000000000
--- a/imports/ui/components/Timeline/queries.js
+++ /dev/null
@@ -1,63 +0,0 @@
-import { gql } from 'apollo-boost';
-
-export const MOLOCH_DAO = gql`
-{
- proposals(first: 25) {
- id
- timestamp
- proposalIndex
- startingPeriod
- member {
- id
- }
- memberAddress
- applicant {
- applicantAddress
- }
- tokenTribute
- sharesRequested
- yesVotes
- noVotes
- yesShares
- noShares
- details
- processed
- status
- votingPeriodBegins
- votingPeriodEnds
- gracePeriodEnds
- }
-}
-`;
-
-export const MOLOCHS = gql`
-{
- proposals(first: 50, orderBy:createdAt, orderDirection:desc) {
- id
- proposalId
- createdAt
- proposalIndex
- startingPeriod
- moloch {
- id
- }
- memberAddress
- applicant
- tributeOffered
- tributeToken
- tributeTokenSymbol
- tributeTokenDecimals
- sharesRequested
- yesVotes
- noVotes
- yesShares
- noShares
- details
- processed
- votingPeriodStarts
- votingPeriodEnds
- gracePeriodEnds
- }
-}
-`;
-
diff --git a/imports/ui/components/Vote/Vote.jsx b/imports/ui/components/Vote/Vote.jsx
index 6d3beb445..442634d9e 100644
--- a/imports/ui/components/Vote/Vote.jsx
+++ b/imports/ui/components/Vote/Vote.jsx
@@ -63,7 +63,7 @@ const VoteQuery = () => {
return data.votes.map((vote) => {
return (
-
+
diff --git a/imports/ui/templates/layout/main.html b/imports/ui/templates/layout/main.html
index a8f8d8140..3ffefced0 100644
--- a/imports/ui/templates/layout/main.html
+++ b/imports/ui/templates/layout/main.html
@@ -17,7 +17,7 @@
{{#unless landingMode}}
- {{> sidebar}}
+ {{> menu}}
{{/unless}}
{{> preloader}}
diff --git a/imports/ui/templates/layout/main.js b/imports/ui/templates/layout/main.js
index f73c4286e..ee8c95f5d 100644
--- a/imports/ui/templates/layout/main.js
+++ b/imports/ui/templates/layout/main.js
@@ -34,6 +34,7 @@ import { getCSS } from '/imports/ui/templates/layout/templater';
import { resetSplit } from '/imports/ui/modules/split';
import { getLandingMode } from '/imports/ui/templates/layout/url/home/home';
+import '/imports/ui/components/Menu/menu.js';
import '/imports/ui/templates/layout/main.html';
import '/imports/ui/templates/widgets/modal/modal';
import '/imports/ui/templates/widgets/popup/popup';
diff --git a/lib/const.js b/lib/const.js
index 4725e4cfc..41a38ffec 100644
--- a/lib/const.js
+++ b/lib/const.js
@@ -88,6 +88,7 @@ const _gui = {
MOLOCH_DAPP: true,
LIMIT_TRANSACTIONS_PER_LEDGER: 10,
COLLECTIVE_MAX_FETCH: 25,
+ MAX_LENGTH_ACCOUNT_NAMES: 19,
};
/**
@@ -115,6 +116,7 @@ const _defaults = {
START_BLOCK: 5000000,
CRON_JOB_TIMER: '0 59 * * * *',
ORACLE_BLOCKTIME: 25000,
+ EMPTY: '0x0',
};
const _replicaThreshold = {
diff --git a/public/templates/daoverse/css/daoverse.css b/public/templates/daoverse/css/daoverse.css
index f0f1099e6..65e1a6d88 100755
--- a/public/templates/daoverse/css/daoverse.css
+++ b/public/templates/daoverse/css/daoverse.css
@@ -1404,7 +1404,6 @@ blockquote {
background-color: #fff;
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(64%, #fff), to(#ececec));
background-image: linear-gradient(180deg, #fff 64%, #ececec);
- box-shadow: inset 0 0 1px 0 #dfdfdf, 0 5px 20px -10px #838383;
}
.vote.vote-search.vote-feed {
@@ -1413,10 +1412,10 @@ blockquote {
padding-bottom: 0px;
border-style: solid;
border-width: 1px;
- border-color: rgba(0, 0, 0, .02);
+ border-color: rgb(224 218 226);
border-radius: 8px;
background-image: none;
- box-shadow: 0 2px 8px 0 hsla(0, 0%, 72%, .37);
+ /* box-shadow: 0 2px 8px 0 hsla(0, 0%, 72%, .37); */
-webkit-transition: all 200ms ease;
transition: all 200ms ease;
color: #000;
@@ -1424,16 +1423,13 @@ blockquote {
}
.vote.vote-search.vote-feed:hover {
- margin-top: 0px;
- margin-bottom: 25px;
- box-shadow: 0 10px 20px 0 rgba(0, 0, 0, .1);
color: #0d0d17;
+ border-color: rgb(88 1 115 / 40%);
}
.vote.vote-search.vote-feed:active {
margin-top: 0px;
margin-bottom: 21px;
- box-shadow: 0 5px 10px 0 rgba(0, 0, 0, .1);
}
.vote.vote-search.vote-feed.vote-empty {
@@ -1441,7 +1437,6 @@ blockquote {
border-width: 1px;
border-color: hsla(0, 0%, 90%, .72);
background-color: transparent;
- box-shadow: none;
}
.event-vote {
@@ -1452,7 +1447,7 @@ blockquote {
border: 1px solid #7d849f33;
border-top: 1px dotted #7d849f33;
border-radius: 0px;
- background-color: #f9fafb;
+ background-color: var(--proposal-bar-color);
width: 100%;
cursor: default;
}
@@ -4543,21 +4538,26 @@ blockquote {
.menu-item {
min-width: 100%;
- margin-top: 3px;
- margin-bottom: 12px;
- padding: 2px 5px 1px 10px;
- border-radius: 20px;
+ padding: 0px 5px;
+ border-radius: 5px;
color: #0d0d17;
font-size: 13px;
line-height: 30px;
text-align: left;
cursor: pointer;
+ display:inline-block;
}
.menu-item:hover {
background-color: #e6e0ee;
}
+.menu-item-icon {
+ width: 16px;
+ height: 16px;
+ padding: 2px;
+}
+
.menu-item.cast-action {
position: absolute;
top: 50%;
@@ -4622,7 +4622,7 @@ blockquote {
.sidebar {
position: absolute;
top: 60px;
- bottom: 60px;
+ bottom: 0px;
display: inline-block;
overflow: scroll;
width: 100%;
@@ -4689,6 +4689,7 @@ blockquote {
line-height: 22px;
font-weight: 500;
text-align: left;
+ clear:both;
text-transform: uppercase;
}
@@ -5940,6 +5941,15 @@ blockquote {
float: left;
}
+.sidebar-sharp {
+ font-family: Arial, Helvetica, sans-serif;
+ margin: 0px 5px 0px 0px;
+ float: left;
+ font-weight: 100;
+ color: var(--main-link-color);
+ font-size: 1.2em;
+}
+
.post-button {
margin: 2px 10px -5px;
float: right;
diff --git a/public/templates/daoverse/css/extra.css b/public/templates/daoverse/css/extra.css
index b27717bcf..42f92362b 100644
--- a/public/templates/daoverse/css/extra.css
+++ b/public/templates/daoverse/css/extra.css
@@ -770,6 +770,20 @@ width: 1px;
box-shadow: -1px 5px 10px 0px rgba(0, 0, 0, .2);
}
+.empty {
+ border: 1px dashed #bfb8c6;
+ font-size: 0.8em;
+ padding: 10px;
+ text-align: left;
+ border-radius: 5px;
+ color: #bfb8c6;
+}
+
+.sidebar-label.sidebar-label-dao {
+ max-height: 33px;
+ margin-top: -3px;
+}
+
.token-wrap.token-wrap-multi {
margin-bottom:10px;
}
@@ -792,7 +806,7 @@ width: 1px;
color: #5a0075;
border: 1px solid #f2eff5;
min-width: 140px;
- background: #f9fafb;
+ background: var(--proposal-bar-color);
float: left;
height: 80px;
overflow: hidden;
@@ -858,7 +872,7 @@ width: 1px;
margin-bottom: 10px;
float: left;
border: 1px solid #e8e2ef;
- border-radius: 3px;
+ border-radius: 50px;
background-color: #e8e2ef;
}
@@ -1179,7 +1193,7 @@ h4 {
display: inline-block;
padding: 0px 7px;
width: 100%;
- background-color: #f9fafb;
+ background-color: var(--proposal-bar-color);
margin: -5px 0px;
}
@@ -1275,7 +1289,7 @@ h4 {
}
.vote.vote-search.vote-feed.vote-delegation.guild-block {
- border: 5px solid #f9fafb;
+ border: 5px solid var(--proposal-bar-color);
}
.mobile-search {
diff --git a/public/templates/daoverse/daoverse.json b/public/templates/daoverse/daoverse.json
index c5fd3a357..7b9ef89db 100644
--- a/public/templates/daoverse/daoverse.json
+++ b/public/templates/daoverse/daoverse.json
@@ -80,6 +80,8 @@
"rejected": "/templates/daoverse/images/rejected.png",
"signout": "/templates/daoverse/images/signout.png",
"calendar": "/templates/daoverse/images/calendar.svg",
- "blocks": "/templates/daoverse/images/blocks.gif"
+ "blocks": "/templates/daoverse/images/blocks.gif",
+ "paper": "/templates/daoverse/images/paper.svg",
+ "paper-active": "/templates/daoverse/images/paper-active.svg"
}
}
diff --git a/public/templates/daoverse/images/paper-active.svg b/public/templates/daoverse/images/paper-active.svg
new file mode 100644
index 000000000..786328fd0
--- /dev/null
+++ b/public/templates/daoverse/images/paper-active.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/templates/daoverse/images/paper.svg b/public/templates/daoverse/images/paper.svg
new file mode 100644
index 000000000..61bf738a3
--- /dev/null
+++ b/public/templates/daoverse/images/paper.svg
@@ -0,0 +1 @@
+
\ No newline at end of file