diff --git a/app/javascript/flavours/glitch/components/domain.js b/app/javascript/flavours/glitch/components/domain.js
new file mode 100644
index 000000000..f657cb8d2
--- /dev/null
+++ b/app/javascript/flavours/glitch/components/domain.js
@@ -0,0 +1,42 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import IconButton from './icon_button';
+import { defineMessages, injectIntl } from 'react-intl';
+import ImmutablePureComponent from 'react-immutable-pure-component';
+
+const messages = defineMessages({
+ unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unhide {domain}' },
+});
+
+@injectIntl
+export default class Account extends ImmutablePureComponent {
+
+ static propTypes = {
+ domain: PropTypes.string,
+ onUnblockDomain: PropTypes.func.isRequired,
+ intl: PropTypes.object.isRequired,
+ };
+
+ handleDomainUnblock = () => {
+ this.props.onUnblockDomain(this.props.domain);
+ }
+
+ render () {
+ const { domain, intl } = this.props;
+
+ return (
+
+ );
+ }
+
+}
diff --git a/app/javascript/flavours/glitch/containers/domain_container.js b/app/javascript/flavours/glitch/containers/domain_container.js
new file mode 100644
index 000000000..52d5c1613
--- /dev/null
+++ b/app/javascript/flavours/glitch/containers/domain_container.js
@@ -0,0 +1,33 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import { blockDomain, unblockDomain } from '../actions/domain_blocks';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
+import Domain from '../components/domain';
+import { openModal } from '../actions/modal';
+
+const messages = defineMessages({
+ blockDomainConfirm: { id: 'confirmations.domain_block.confirm', defaultMessage: 'Hide entire domain' },
+});
+
+const makeMapStateToProps = () => {
+ const mapStateToProps = (state, { }) => ({
+ });
+
+ return mapStateToProps;
+};
+
+const mapDispatchToProps = (dispatch, { intl }) => ({
+ onBlockDomain (domain) {
+ dispatch(openModal('CONFIRM', {
+ message: {domain} }} />,
+ confirm: intl.formatMessage(messages.blockDomainConfirm),
+ onConfirm: () => dispatch(blockDomain(domain)),
+ }));
+ },
+
+ onUnblockDomain (domain) {
+ dispatch(unblockDomain(domain));
+ },
+});
+
+export default injectIntl(connect(makeMapStateToProps, mapDispatchToProps)(Domain));
diff --git a/app/javascript/flavours/glitch/features/domain_blocks/index.js b/app/javascript/flavours/glitch/features/domain_blocks/index.js
new file mode 100644
index 000000000..b17c47e91
--- /dev/null
+++ b/app/javascript/flavours/glitch/features/domain_blocks/index.js
@@ -0,0 +1,66 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import PropTypes from 'prop-types';
+import LoadingIndicator from '../../components/loading_indicator';
+import Column from '../ui/components/column';
+import ColumnBackButtonSlim from '../../components/column_back_button_slim';
+import DomainContainer from '../../containers/domain_container';
+import { fetchDomainBlocks, expandDomainBlocks } from '../../actions/domain_blocks';
+import { defineMessages, injectIntl } from 'react-intl';
+import ImmutablePureComponent from 'react-immutable-pure-component';
+import { debounce } from 'lodash';
+import ScrollableList from '../../components/scrollable_list';
+
+const messages = defineMessages({
+ heading: { id: 'column.domain_blocks', defaultMessage: 'Hidden domains' },
+ unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unhide {domain}' },
+});
+
+const mapStateToProps = state => ({
+ domains: state.getIn(['domain_lists', 'blocks', 'items']),
+});
+
+@connect(mapStateToProps)
+@injectIntl
+export default class Blocks extends ImmutablePureComponent {
+
+ static propTypes = {
+ params: PropTypes.object.isRequired,
+ dispatch: PropTypes.func.isRequired,
+ domains: ImmutablePropTypes.list,
+ intl: PropTypes.object.isRequired,
+ };
+
+ componentWillMount () {
+ this.props.dispatch(fetchDomainBlocks());
+ }
+
+ handleLoadMore = debounce(() => {
+ this.props.dispatch(expandDomainBlocks());
+ }, 300, { leading: true });
+
+ render () {
+ const { intl, domains } = this.props;
+
+ if (!domains) {
+ return (
+
+
+
+ );
+ }
+
+ return (
+
+
+
+ {domains.map(domain =>
+
+ )}
+
+
+ );
+ }
+
+}
diff --git a/app/javascript/flavours/glitch/features/ui/index.js b/app/javascript/flavours/glitch/features/ui/index.js
index 0b031a7f0..48c7e1145 100644
--- a/app/javascript/flavours/glitch/features/ui/index.js
+++ b/app/javascript/flavours/glitch/features/ui/index.js
@@ -38,6 +38,7 @@ import {
FavouritedStatuses,
ListTimeline,
Blocks,
+ DomainBlocks,
Mutes,
PinnedStatuses,
Lists,
@@ -438,6 +439,7 @@ export default class UI extends React.Component {
+
diff --git a/app/javascript/flavours/glitch/styles/components/domains.scss b/app/javascript/flavours/glitch/styles/components/domains.scss
new file mode 100644
index 000000000..a99ccd02b
--- /dev/null
+++ b/app/javascript/flavours/glitch/styles/components/domains.scss
@@ -0,0 +1,23 @@
+.domain {
+ padding: 10px;
+ border-bottom: 1px solid lighten($ui-base-color, 8%);
+
+ .domain__domain-name {
+ flex: 1 1 auto;
+ display: block;
+ color: $primary-text-color;
+ text-decoration: none;
+ font-size: 14px;
+ font-weight: 500;
+ }
+}
+
+.domain__wrapper {
+ display: flex;
+}
+
+.domain_buttons {
+ height: 18px;
+ padding: 10px;
+ white-space: nowrap;
+}
diff --git a/app/javascript/flavours/glitch/styles/components/index.scss b/app/javascript/flavours/glitch/styles/components/index.scss
index 3d16c856d..aa33c9333 100644
--- a/app/javascript/flavours/glitch/styles/components/index.scss
+++ b/app/javascript/flavours/glitch/styles/components/index.scss
@@ -1173,6 +1173,7 @@ noscript {
@import 'boost';
@import 'accounts';
+@import 'domains';
@import 'status';
@import 'modal';
@import 'metadata';
diff --git a/app/javascript/flavours/glitch/util/async-components.js b/app/javascript/flavours/glitch/util/async-components.js
index 2aa9659e8..acda92d54 100644
--- a/app/javascript/flavours/glitch/util/async-components.js
+++ b/app/javascript/flavours/glitch/util/async-components.js
@@ -98,6 +98,10 @@ export function Blocks () {
return import(/* webpackChunkName: "flavours/glitch/async/blocks" */'flavours/glitch/features/blocks');
}
+export function DomainBlocks () {
+ return import(/* webpackChunkName: "flavours/glitch/async/domain_blocks" */'flavours/glitch/features/domain_blocks');
+}
+
export function Mutes () {
return import(/* webpackChunkName: "flavours/glitch/async/mutes" */'flavours/glitch/features/mutes');
}