diff --git a/Gemfile.lock b/Gemfile.lock index e334d5733..b16d38d38 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -407,7 +407,7 @@ GEM net-ssh (>= 2.6.5, < 7.0.0) net-ssh (6.1.0) nio4r (2.5.8) - nokogiri (1.13.6) + nokogiri (1.13.7) mini_portile2 (~> 2.8.0) racc (~> 1.4) nsa (0.2.8) @@ -415,7 +415,7 @@ GEM concurrent-ruby (~> 1.0, >= 1.0.2) sidekiq (>= 3.5) statsd-ruby (~> 1.4, >= 1.4.0) - oj (3.13.16) + oj (3.13.17) omniauth (1.9.1) hashie (>= 3.4.6) rack (>= 1.6.2, < 3) diff --git a/app/controllers/api/v1/tags_controller.rb b/app/controllers/api/v1/tags_controller.rb index d45015ff5..9e5c53330 100644 --- a/app/controllers/api/v1/tags_controller.rb +++ b/app/controllers/api/v1/tags_controller.rb @@ -24,6 +24,7 @@ class Api::V1::TagsController < Api::BaseController private def set_or_create_tag + return not_found unless /\A(#{Tag::HASHTAG_NAME_RE})\z/.match?(params[:id]) @tag = Tag.find_normalized(params[:id]) || Tag.new(name: Tag.normalize(params[:id]), display_name: params[:id]) end end diff --git a/app/javascript/mastodon/components/hashtag.js b/app/javascript/mastodon/components/hashtag.js index 7f442d189..4e9cd3569 100644 --- a/app/javascript/mastodon/components/hashtag.js +++ b/app/javascript/mastodon/components/hashtag.js @@ -1,7 +1,7 @@ // @ts-check import React from 'react'; import { Sparklines, SparklinesCurve } from 'react-sparklines'; -import { FormattedMessage } from 'react-intl'; +import { FormattedMessage, injectIntl, defineMessages } from 'react-intl'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import Permalink from './permalink'; @@ -9,6 +9,10 @@ import ShortNumber from 'mastodon/components/short_number'; import Skeleton from 'mastodon/components/skeleton'; import classNames from 'classnames'; +const messages = defineMessages({ + totalVolume: { id: 'hashtag.total_volume', defaultMessage: 'Total volume in the last {days, plural, one {day} other {{days} days}}' }, +}); + class SilentErrorBoundary extends React.Component { static propTypes = { @@ -41,10 +45,11 @@ class SilentErrorBoundary extends React.Component { export const accountsCountRenderer = (displayNumber, pluralReady) => ( {displayNumber}, + days: 2, }} /> ); @@ -64,7 +69,7 @@ ImmutableHashtag.propTypes = { hashtag: ImmutablePropTypes.map.isRequired, }; -const Hashtag = ({ name, href, to, people, uses, history, className }) => ( +const Hashtag = injectIntl(({ name, href, to, people, uses, history, className, intl }) => (
@@ -74,9 +79,10 @@ const Hashtag = ({ name, href, to, people, uses, history, className }) => ( {typeof people !== 'undefined' ? : }
-
+ {typeof uses !== 'undefined' ? : } -
+ * +
@@ -86,7 +92,7 @@ const Hashtag = ({ name, href, to, people, uses, history, className }) => (
-); +)); Hashtag.propTypes = { name: PropTypes.string, diff --git a/app/javascript/mastodon/features/ui/components/image_loader.js b/app/javascript/mastodon/features/ui/components/image_loader.js index c6f16a792..dfa0efe49 100644 --- a/app/javascript/mastodon/features/ui/components/image_loader.js +++ b/app/javascript/mastodon/features/ui/components/image_loader.js @@ -1,10 +1,10 @@ -import React from 'react'; -import PropTypes from 'prop-types'; import classNames from 'classnames'; +import PropTypes from 'prop-types'; +import React, { PureComponent } from 'react'; import { LoadingBar } from 'react-redux-loading-bar'; import ZoomableImage from './zoomable_image'; -export default class ImageLoader extends React.PureComponent { +export default class ImageLoader extends PureComponent { static propTypes = { alt: PropTypes.string, @@ -43,7 +43,7 @@ export default class ImageLoader extends React.PureComponent { this.loadImage(this.props); } - componentWillReceiveProps (nextProps) { + UNSAFE_componentWillReceiveProps (nextProps) { if (this.props.src !== nextProps.src) { this.loadImage(nextProps); } @@ -139,14 +139,18 @@ export default class ImageLoader extends React.PureComponent { return (
- {loading ? ( - + <> +
+ +
+ + ) : (