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 (
-
- -
- + {(format === 'plainText') ? +
+ +
{label} - +
-
+ : +
+ +
+ + {label} + +
+
+ }
); }; @@ -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 @@ + \ 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 @@ +Icon-54 \ 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 @@ +Icon-54 \ No newline at end of file