mirror of https://github.com/mastodon/mastodon
				
				
				
			Redesign public hashtag pages (#5237)
							parent
							
								
									d2dee6ea43
								
							
						
					
					
						commit
						f486ef2666
					
				@ -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 (
 | 
			
		||||
      <Column ref={this.setRef}>
 | 
			
		||||
        <ColumnHeader
 | 
			
		||||
          icon='hashtag'
 | 
			
		||||
          title={hashtag}
 | 
			
		||||
          onClick={this.handleHeaderClick}
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
        <StatusListContainer
 | 
			
		||||
          trackScroll={false}
 | 
			
		||||
          scrollKey='standalone_hashtag_timeline'
 | 
			
		||||
          timelineId={`hashtag:${hashtag}`}
 | 
			
		||||
          loadMore={this.handleLoadMore}
 | 
			
		||||
        />
 | 
			
		||||
      </Column>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,6 @@
 | 
			
		||||
= opengraph 'og:site_name', t('about.hosted_on', domain: site_hostname)
 | 
			
		||||
= opengraph 'og:url', tag_url(@tag)
 | 
			
		||||
= opengraph 'og:type', 'website'
 | 
			
		||||
= opengraph 'og:title', "##{@tag.name}"
 | 
			
		||||
= opengraph 'og:description', t('about.about_hashtag_html', hashtag: @tag.name)
 | 
			
		||||
= opengraph 'twitter:card', 'summary'
 | 
			
		||||
@ -1,19 +1,38 @@
 | 
			
		||||
- content_for :page_title do
 | 
			
		||||
  = "##{@tag.name}"
 | 
			
		||||
 | 
			
		||||
.compact-header
 | 
			
		||||
  %h1<
 | 
			
		||||
    = link_to site_title, root_path
 | 
			
		||||
    %br
 | 
			
		||||
    %small ##{@tag.name}
 | 
			
		||||
- content_for :header_tags do
 | 
			
		||||
  %script#initial-state{ type: 'application/json' }!= json_escape(@initial_state_json)
 | 
			
		||||
  = javascript_pack_tag 'about', integrity: true, crossorigin: 'anonymous'
 | 
			
		||||
  = render 'og'
 | 
			
		||||
 | 
			
		||||
- if @statuses.empty?
 | 
			
		||||
  .accounts-grid
 | 
			
		||||
    = render partial: 'accounts/nothing_here'
 | 
			
		||||
- else
 | 
			
		||||
  .activity-stream.h-feed
 | 
			
		||||
    = render partial: 'stream_entries/status', collection: @statuses, as: :status
 | 
			
		||||
.landing-page.tag-page
 | 
			
		||||
  .stripe
 | 
			
		||||
  .features
 | 
			
		||||
    .container
 | 
			
		||||
      #mastodon-timeline{ data: { props: Oj.dump(default_props.merge(hashtag: @tag.name)) } }
 | 
			
		||||
 | 
			
		||||
- if @statuses.size == 20
 | 
			
		||||
  .pagination
 | 
			
		||||
    = link_to safe_join([t('pagination.next'), fa_icon('chevron-right')], ' '), tag_url(@tag, max_id: @statuses.last.id), class: 'next', rel: 'next'
 | 
			
		||||
      .about-mastodon
 | 
			
		||||
        .brand
 | 
			
		||||
          = link_to root_url do
 | 
			
		||||
            = image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon'
 | 
			
		||||
 | 
			
		||||
        %p= t 'about.about_hashtag_html', hashtag: @tag.name
 | 
			
		||||
 | 
			
		||||
        .cta
 | 
			
		||||
          = link_to t('auth.login'), new_user_session_path, class: 'button button-secondary'
 | 
			
		||||
          = link_to t('about.learn_more'), root_url, class: 'button button-alternative'
 | 
			
		||||
 | 
			
		||||
        .features-list
 | 
			
		||||
          .features-list__row
 | 
			
		||||
            .text
 | 
			
		||||
              %h6= t 'about.features.not_a_product_title'
 | 
			
		||||
              = t 'about.features.not_a_product_body'
 | 
			
		||||
            .visual
 | 
			
		||||
              = fa_icon 'fw users'
 | 
			
		||||
          .features-list__row
 | 
			
		||||
            .text
 | 
			
		||||
              %h6= t 'about.features.humane_approach_title'
 | 
			
		||||
              = t 'about.features.humane_approach_body'
 | 
			
		||||
            .visual
 | 
			
		||||
              = fa_icon 'fw leaf'
 | 
			
		||||
 | 
			
		||||
					Loading…
					
					
				
		Reference in New Issue