From f486ef2666dacbcb6fcd26e371bb5e945369dcfe Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 7 Oct 2017 20:00:35 +0200 Subject: Redesign public hashtag pages (#5237) --- .../mastodon/containers/timeline_container.js | 14 +++- .../features/standalone/hashtag_timeline/index.js | 70 +++++++++++++++++ app/javascript/packs/about.js | 6 +- app/javascript/styles/about.scss | 91 ++++++++++++++++++++++ app/javascript/styles/basics.scss | 5 ++ app/javascript/styles/components.scss | 1 + 6 files changed, 182 insertions(+), 5 deletions(-) create mode 100644 app/javascript/mastodon/features/standalone/hashtag_timeline/index.js (limited to 'app/javascript') diff --git a/app/javascript/mastodon/containers/timeline_container.js b/app/javascript/mastodon/containers/timeline_container.js index 6b545ef09..4be037955 100644 --- a/app/javascript/mastodon/containers/timeline_container.js +++ b/app/javascript/mastodon/containers/timeline_container.js @@ -6,6 +6,7 @@ import { hydrateStore } from '../actions/store'; import { IntlProvider, addLocaleData } from 'react-intl'; import { getLocale } from '../locales'; import PublicTimeline from '../features/standalone/public_timeline'; +import HashtagTimeline from '../features/standalone/hashtag_timeline'; const { localeData, messages } = getLocale(); addLocaleData(localeData); @@ -22,15 +23,24 @@ export default class TimelineContainer extends React.PureComponent { static propTypes = { locale: PropTypes.string.isRequired, + hashtag: PropTypes.string, }; render () { - const { locale } = this.props; + const { locale, hashtag } = this.props; + + let timeline; + + if (hashtag) { + timeline = ; + } else { + timeline = ; + } return ( - + {timeline} ); diff --git a/app/javascript/mastodon/features/standalone/hashtag_timeline/index.js b/app/javascript/mastodon/features/standalone/hashtag_timeline/index.js new file mode 100644 index 000000000..f15fbb2f4 --- /dev/null +++ b/app/javascript/mastodon/features/standalone/hashtag_timeline/index.js @@ -0,0 +1,70 @@ +import React from 'react'; +import { connect } from 'react-redux'; +import PropTypes from 'prop-types'; +import StatusListContainer from '../../ui/containers/status_list_container'; +import { + refreshHashtagTimeline, + expandHashtagTimeline, +} from '../../../actions/timelines'; +import Column from '../../../components/column'; +import ColumnHeader from '../../../components/column_header'; + +@connect() +export default class HashtagTimeline extends React.PureComponent { + + static propTypes = { + dispatch: PropTypes.func.isRequired, + hashtag: PropTypes.string.isRequired, + }; + + handleHeaderClick = () => { + this.column.scrollTop(); + } + + setRef = c => { + this.column = c; + } + + componentDidMount () { + const { dispatch, hashtag } = this.props; + + dispatch(refreshHashtagTimeline(hashtag)); + + this.polling = setInterval(() => { + dispatch(refreshHashtagTimeline(hashtag)); + }, 10000); + } + + componentWillUnmount () { + if (typeof this.polling !== 'undefined') { + clearInterval(this.polling); + this.polling = null; + } + } + + handleLoadMore = () => { + this.props.dispatch(expandHashtagTimeline(this.props.hashtag)); + } + + render () { + const { hashtag } = this.props; + + return ( + + + + + + ); + } + +} diff --git a/app/javascript/packs/about.js b/app/javascript/packs/about.js index 6705377c1..50c81198e 100644 --- a/app/javascript/packs/about.js +++ b/app/javascript/packs/about.js @@ -4,9 +4,9 @@ require.context('../images/', true); function loaded() { const TimelineContainer = require('../mastodon/containers/timeline_container').default; - const React = require('react'); - const ReactDOM = require('react-dom'); - const mountNode = document.getElementById('mastodon-timeline'); + const React = require('react'); + const ReactDOM = require('react-dom'); + const mountNode = document.getElementById('mastodon-timeline'); if (mountNode !== null) { const props = JSON.parse(mountNode.getAttribute('data-props')); diff --git a/app/javascript/styles/about.scss b/app/javascript/styles/about.scss index 2adcb5ba2..a15afc32c 100644 --- a/app/javascript/styles/about.scss +++ b/app/javascript/styles/about.scss @@ -481,6 +481,7 @@ flex: 0 0 auto; background: $ui-base-color; overflow: hidden; + border-radius: 4px; box-shadow: 0 0 6px rgba($black, 0.1); .column-header { @@ -703,8 +704,98 @@ .features #mastodon-timeline { height: 70vh; width: 100%; + min-width: 330px; margin-bottom: 50px; + + .column { + width: 100%; + } + } + } + + .cta { + margin: 20px; + } + + &.tag-page { + .brand { + padding-top: 20px; + margin-bottom: 20px; + + img { + height: 48px; + width: auto; + } + } + + .container { + max-width: 690px; + } + + .cta { + margin: 40px 0; + margin-bottom: 80px; + + .button { + margin-right: 4px; + } + } + + .about-mastodon { + max-width: 330px; + + p { + strong { + color: $ui-secondary-color; + font-weight: 700; + } + } } + + @media screen and (max-width: 675px) { + .container { + display: flex; + flex-direction: column; + } + + .features { + padding: 20px 0; + } + + .about-mastodon { + order: 1; + flex: 0 0 auto; + max-width: 100%; + } + + #mastodon-timeline { + order: 2; + flex: 0 0 auto; + height: 60vh; + } + + .cta { + margin: 20px 0; + margin-bottom: 30px; + } + + .features-list { + display: none; + } + + .stripe { + display: none; + } + } + } + + .stripe { + width: 100%; + height: 360px; + overflow: hidden; + background: darken($ui-base-color, 4%); + position: absolute; + z-index: -1; } } diff --git a/app/javascript/styles/basics.scss b/app/javascript/styles/basics.scss index 0018c9a5d..500e506f6 100644 --- a/app/javascript/styles/basics.scss +++ b/app/javascript/styles/basics.scss @@ -42,6 +42,11 @@ body { padding-bottom: 0; } + &.tag-body { + background: darken($ui-base-color, 8%); + padding-bottom: 0; + } + &.embed { background: transparent; margin: 0; diff --git a/app/javascript/styles/components.scss b/app/javascript/styles/components.scss index 6c64528d6..0e7022e9b 100644 --- a/app/javascript/styles/components.scss +++ b/app/javascript/styles/components.scss @@ -66,6 +66,7 @@ text-transform: none; background: transparent; padding: 3px 15px; + border-radius: 4px; border: 1px solid $ui-primary-color; &:active, -- cgit