Bläddra i källkod

Add trends UI with admin and user settings (#11502)

master^2
Eugen Rochko 4 år sedan
committed by GitHub
förälder
incheckning
9072fe5ab6
Ingen känd nyckel hittad för denna signaturen i databasen GPG-nyckel ID: 4AEE18F83AFDEB23
21 ändrade filer med 189 tillägg och 13 borttagningar
  1. +1
    -0
      app/controllers/settings/preferences_controller.rb
  2. +32
    -0
      app/javascript/mastodon/actions/trends.js
  3. +43
    -0
      app/javascript/mastodon/features/getting_started/components/trends.js
  4. +13
    -0
      app/javascript/mastodon/features/getting_started/containers/trends_container.js
  5. +4
    -1
      app/javascript/mastodon/features/getting_started/index.js
  6. +5
    -1
      app/javascript/mastodon/features/ui/components/navigation_panel.js
  7. +1
    -0
      app/javascript/mastodon/initial_state.js
  8. +2
    -0
      app/javascript/mastodon/reducers/index.js
  9. +4
    -0
      app/javascript/mastodon/reducers/settings.js
  10. +23
    -0
      app/javascript/mastodon/reducers/trends.js
  11. +30
    -8
      app/javascript/styles/mastodon/components.scss
  12. +5
    -0
      app/lib/user_settings_decorator.rb
  13. +2
    -0
      app/models/form/admin_settings.rb
  14. +4
    -0
      app/models/trending_tags.rb
  15. +2
    -1
      app/models/user.rb
  16. +2
    -0
      app/serializers/initial_state_serializer.rb
  17. +3
    -0
      app/views/admin/settings/edit.html.haml
  18. +5
    -0
      app/views/settings/preferences/appearance/show.html.haml
  19. +6
    -2
      config/locales/en.yml
  20. +1
    -0
      config/locales/simple_form.en.yml
  21. +1
    -0
      config/settings.yml

+ 1
- 0
app/controllers/settings/preferences_controller.rb Visa fil

@@ -56,6 +56,7 @@ class Settings::PreferencesController < Settings::BaseController
:setting_advanced_layout,
:setting_use_blurhash,
:setting_use_pending_items,
:setting_trends,
notification_emails: %i(follow follow_request reblog favourite mention digest report pending_account trending_tag),
interactions: %i(must_be_follower must_be_following must_be_following_dm)
)


+ 32
- 0
app/javascript/mastodon/actions/trends.js Visa fil

@@ -0,0 +1,32 @@
import api from '../api';

export const TRENDS_FETCH_REQUEST = 'TRENDS_FETCH_REQUEST';
export const TRENDS_FETCH_SUCCESS = 'TRENDS_FETCH_SUCCESS';
export const TRENDS_FETCH_FAIL = 'TRENDS_FETCH_FAIL';

export const fetchTrends = () => (dispatch, getState) => {
dispatch(fetchTrendsRequest());

api(getState)
.get('/api/v1/trends')
.then(({ data }) => dispatch(fetchTrendsSuccess(data)))
.catch(err => dispatch(fetchTrendsFail(err)));
};

export const fetchTrendsRequest = () => ({
type: TRENDS_FETCH_REQUEST,
skipLoading: true,
});

export const fetchTrendsSuccess = trends => ({
type: TRENDS_FETCH_SUCCESS,
trends,
skipLoading: true,
});

export const fetchTrendsFail = error => ({
type: TRENDS_FETCH_FAIL,
error,
skipLoading: true,
skipAlert: true,
});

+ 43
- 0
app/javascript/mastodon/features/getting_started/components/trends.js Visa fil

@@ -0,0 +1,43 @@
import React from 'react';
import ImmutablePureComponent from 'react-immutable-pure-component';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import Hashtag from 'mastodon/components/hashtag';

export default class Trends extends ImmutablePureComponent {

static defaultProps = {
loading: false,
};

static propTypes = {
trends: ImmutablePropTypes.list,
fetchTrends: PropTypes.func.isRequired,
};

componentDidMount () {
this.props.fetchTrends();
this.refreshInterval = setInterval(() => this.props.fetchTrends(), 36000);
}

componentWillUnmount () {
if (this.refreshInterval) {
clearInterval(this.refreshInterval);
}
}

render () {
const { trends } = this.props;

if (!trends || trends.isEmpty()) {
return null;
}

return (
<div className='getting-started__trends'>
{trends.take(3).map(hashtag => <Hashtag key={hashtag.get('name')} hashtag={hashtag} />)}
</div>
);
}

}

+ 13
- 0
app/javascript/mastodon/features/getting_started/containers/trends_container.js Visa fil

@@ -0,0 +1,13 @@
import { connect } from 'react-redux';
import { fetchTrends } from '../../../actions/trends';
import Trends from '../components/trends';

const mapStateToProps = state => ({
trends: state.getIn(['trends', 'items']),
});

const mapDispatchToProps = dispatch => ({
fetchTrends: () => dispatch(fetchTrends()),
});

export default connect(mapStateToProps, mapDispatchToProps)(Trends);

+ 4
- 1
app/javascript/mastodon/features/getting_started/index.js Visa fil

@@ -7,12 +7,13 @@ import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { me, profile_directory } from '../../initial_state';
import { me, profile_directory, showTrends } from '../../initial_state';
import { fetchFollowRequests } from 'mastodon/actions/accounts';
import { List as ImmutableList } from 'immutable';
import NavigationBar from '../compose/components/navigation_bar';
import Icon from 'mastodon/components/icon';
import LinkFooter from 'mastodon/features/ui/components/link_footer';
import TrendsContainer from './containers/trends_container';

const messages = defineMessages({
home_timeline: { id: 'tabs_bar.home', defaultMessage: 'Home' },
@@ -168,6 +169,8 @@ class GettingStarted extends ImmutablePureComponent {

<LinkFooter withHotkeys={multiColumn} />
</div>

{multiColumn && showTrends && <TrendsContainer />}
</Column>
);
}


+ 5
- 1
app/javascript/mastodon/features/ui/components/navigation_panel.js Visa fil

@@ -2,10 +2,11 @@ import React from 'react';
import { NavLink, withRouter } from 'react-router-dom';
import { FormattedMessage } from 'react-intl';
import Icon from 'mastodon/components/icon';
import { profile_directory } from 'mastodon/initial_state';
import { profile_directory, showTrends } from 'mastodon/initial_state';
import NotificationsCounterIcon from './notifications_counter_icon';
import FollowRequestsNavLink from './follow_requests_nav_link';
import ListPanel from './list_panel';
import TrendsContainer from 'mastodon/features/getting_started/containers/trends_container';

const NavigationPanel = () => (
<div className='navigation-panel'>
@@ -25,6 +26,9 @@ const NavigationPanel = () => (
<a className='column-link column-link--transparent' href='/settings/preferences'><Icon className='column-link__icon' id='cog' fixedWidth /><FormattedMessage id='navigation_bar.preferences' defaultMessage='Preferences' /></a>
<a className='column-link column-link--transparent' href='/relationships'><Icon className='column-link__icon' id='users' fixedWidth /><FormattedMessage id='navigation_bar.follows_and_followers' defaultMessage='Follows and followers' /></a>
{!!profile_directory && <a className='column-link column-link--transparent' href='/explore'><Icon className='column-link__icon' id='address-book-o' fixedWidth /><FormattedMessage id='navigation_bar.profile_directory' defaultMessage='Profile directory' /></a>}

{showTrends && <div className='flex-spacer' />}
{showTrends && <TrendsContainer />}
</div>
);



+ 1
- 0
app/javascript/mastodon/initial_state.js Visa fil

@@ -22,5 +22,6 @@ export const isStaff = getMeta('is_staff');
export const forceSingleColumn = !getMeta('advanced_layout');
export const useBlurhash = getMeta('use_blurhash');
export const usePendingItems = getMeta('use_pending_items');
export const showTrends = getMeta('trends');

export default initialState;

+ 2
- 0
app/javascript/mastodon/reducers/index.js Visa fil

@@ -31,6 +31,7 @@ import conversations from './conversations';
import suggestions from './suggestions';
import polls from './polls';
import identity_proofs from './identity_proofs';
import trends from './trends';

const reducers = {
dropdown_menu,
@@ -65,6 +66,7 @@ const reducers = {
conversations,
suggestions,
polls,
trends,
};

export default combineReducers(reducers);

+ 4
- 0
app/javascript/mastodon/reducers/settings.js Visa fil

@@ -12,6 +12,10 @@ const initialState = ImmutableMap({

skinTone: 1,

trends: ImmutableMap({
show: true,
}),

home: ImmutableMap({
shows: ImmutableMap({
reblog: true,


+ 23
- 0
app/javascript/mastodon/reducers/trends.js Visa fil

@@ -0,0 +1,23 @@
import { TRENDS_FETCH_REQUEST, TRENDS_FETCH_SUCCESS, TRENDS_FETCH_FAIL } from '../actions/trends';
import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';

const initialState = ImmutableMap({
items: ImmutableList(),
isLoading: false,
});

export default function trendsReducer(state = initialState, action) {
switch(action.type) {
case TRENDS_FETCH_REQUEST:
return state.set('isLoading', true);
case TRENDS_FETCH_SUCCESS:
return state.withMutations(map => {
map.set('items', fromJS(action.trends));
map.set('isLoading', false);
});
case TRENDS_FETCH_FAIL:
return state.set('isLoading', false);
default:
return state;
}
};

+ 30
- 8
app/javascript/styles/mastodon/components.scss Visa fil

@@ -2212,7 +2212,6 @@ a.account__display-name {
}

.getting-started__wrapper,
.getting-started__trends,
.search {
margin-bottom: 10px;
}
@@ -2319,13 +2318,24 @@ a.account__display-name {
margin-bottom: 10px;
height: calc(100% - 20px);
overflow-y: auto;
display: flex;
flex-direction: column;

& > a {
flex: 0 0 auto;
}

hr {
flex: 0 0 auto;
border: 0;
background: transparent;
border-top: 1px solid lighten($ui-base-color, 4%);
margin: 10px 0;
}

.flex-spacer {
background: transparent;
}
}

.drawer__pager {
@@ -2717,8 +2727,10 @@ a.account__display-name {
}

&__trends {
background: $ui-base-color;
flex: 0 1 auto;
opacity: 1;
animation: fade 150ms linear;
margin-top: 10px;

@media screen and (max-height: 810px) {
.trends__item:nth-child(3) {
@@ -2735,11 +2747,15 @@ a.account__display-name {
@media screen and (max-height: 670px) {
display: none;
}
}

&__scrollable {
max-height: 100%;
overflow-y: auto;
.trends__item {
border-bottom: 0;
padding: 10px;

&__current {
color: $darker-text-color;
}
}
}
}

@@ -5968,7 +5984,8 @@ noscript {
font-size: 24px;
line-height: 36px;
font-weight: 500;
text-align: center;
text-align: right;
padding-right: 15px;
color: $secondary-text-color;
}

@@ -5976,7 +5993,12 @@ noscript {
flex: 0 0 auto;
width: 50px;

path {
path:first-child {
fill: rgba($highlight-text-color, 0.25) !important;
fill-opacity: 1 !important;
}

path:last-child {
stroke: lighten($highlight-text-color, 6%) !important;
}
}


+ 5
- 0
app/lib/user_settings_decorator.rb Visa fil

@@ -36,6 +36,7 @@ class UserSettingsDecorator
user.settings['advanced_layout'] = advanced_layout_preference if change?('setting_advanced_layout')
user.settings['use_blurhash'] = use_blurhash_preference if change?('setting_use_blurhash')
user.settings['use_pending_items'] = use_pending_items_preference if change?('setting_use_pending_items')
user.settings['trends'] = trends_preference if change?('setting_trends')
end

def merged_notification_emails
@@ -122,6 +123,10 @@ class UserSettingsDecorator
boolean_cast_setting 'setting_use_pending_items'
end

def trends_preference
boolean_cast_setting 'setting_trends'
end

def boolean_cast_setting(key)
ActiveModel::Type::Boolean.new.cast(settings[key])
end


+ 2
- 0
app/models/form/admin_settings.rb Visa fil

@@ -29,6 +29,7 @@ class Form::AdminSettings
hero
mascot
spam_check_enabled
trends
).freeze

BOOLEAN_KEYS = %i(
@@ -41,6 +42,7 @@ class Form::AdminSettings
preview_sensitive_media
profile_directory
spam_check_enabled
trends
).freeze

UPLOAD_KEYS = %i(


+ 4
- 0
app/models/trending_tags.rb Visa fil

@@ -66,6 +66,10 @@ class TrendingTags
end

def request_review!(tag)
return unless Setting.trends

tag.touch(:requested_review_at)

User.staff.includes(:account).find_each { |u| AdminMailer.new_trending_tag(u.account, tag).deliver_later! if u.allows_trending_tag_emails? }
end
end


+ 2
- 1
app/models/user.rb Visa fil

@@ -107,7 +107,8 @@ class User < ApplicationRecord
delegate :auto_play_gif, :default_sensitive, :unfollow_modal, :boost_modal, :delete_modal,
:reduce_motion, :system_font_ui, :noindex, :theme, :display_media, :hide_network,
:expand_spoilers, :default_language, :aggregate_reblogs, :show_application,
:advanced_layout, :use_blurhash, :use_pending_items, to: :settings, prefix: :setting, allow_nil: false
:advanced_layout, :use_blurhash, :use_pending_items, :trends,
to: :settings, prefix: :setting, allow_nil: false

attr_reader :invite_code
attr_writer :external


+ 2
- 0
app/serializers/initial_state_serializer.rb Visa fil

@@ -20,6 +20,7 @@ class InitialStateSerializer < ActiveModel::Serializer
invites_enabled: Setting.min_invite_role == 'user',
mascot: instance_presenter.mascot&.file&.url,
profile_directory: Setting.profile_directory,
trends: Setting.trends,
}

if object.current_account
@@ -35,6 +36,7 @@ class InitialStateSerializer < ActiveModel::Serializer
store[:use_blurhash] = object.current_account.user.setting_use_blurhash
store[:use_pending_items] = object.current_account.user.setting_use_pending_items
store[:is_staff] = object.current_account.user.staff?
store[:trends] = Setting.trends && object.current_account.user.setting_trends
end

store


+ 3
- 0
app/views/admin/settings/edit.html.haml Visa fil

@@ -68,6 +68,9 @@
.fields-group
= f.input :profile_directory, as: :boolean, wrapper: :with_label, label: t('admin.settings.profile_directory.title'), hint: t('admin.settings.profile_directory.desc_html')

.fields-group
= f.input :trends, as: :boolean, wrapper: :with_label, label: t('admin.settings.trends.title'), hint: t('admin.settings.trends.desc_html')

.fields-group
= f.input :spam_check_enabled, as: :boolean, wrapper: :with_label, label: t('admin.settings.spam_check_enabled.title'), hint: t('admin.settings.spam_check_enabled.desc_html')



+ 5
- 0
app/views/settings/preferences/appearance/show.html.haml Visa fil

@@ -25,6 +25,11 @@
= f.input :setting_reduce_motion, as: :boolean, wrapper: :with_label
= f.input :setting_system_font_ui, as: :boolean, wrapper: :with_label

%h4= t 'appearance.discovery'

.fields-group
= f.input :setting_trends, as: :boolean, wrapper: :with_label

%h4= t 'appearance.confirmation_dialogs'

.fields-group


+ 6
- 2
config/locales/en.yml Visa fil

@@ -460,8 +460,8 @@ en:
title: Custom terms of service
site_title: Server name
spam_check_enabled:
desc_html: Mastodon can auto-silence and auto-report accounts based on measures such as detecting accounts who send repeated unsolicited messages. There may be false positives.
title: Anti-spam
desc_html: Mastodon can auto-silence and auto-report accounts that send repeated unsolicited messages. There may be false positives.
title: Anti-spam automation
thumbnail:
desc_html: Used for previews via OpenGraph and API. 1200x630px recommended
title: Server thumbnail
@@ -469,6 +469,9 @@ en:
desc_html: Display public timeline on landing page
title: Timeline preview
title: Site settings
trends:
desc_html: Publicly display previously reviewed hashtags that are currently trending
title: Trending hashtags
statuses:
back_to_account: Back to account page
batch:
@@ -514,6 +517,7 @@ en:
advanced_web_interface_hint: 'If you want to make use of your entire screen width, the advanced web interface allows you to configure many different columns to see as much information at the same time as you want: Home, notifications, federated timeline, any number of lists and hashtags.'
animations_and_accessibility: Animations and accessibility
confirmation_dialogs: Confirmation dialogs
discovery: Discovery
sensitive_content: Sensitive content
application_mailer:
notification_preferences: Change e-mail preferences


+ 1
- 0
config/locales/simple_form.en.yml Visa fil

@@ -114,6 +114,7 @@ en:
setting_show_application: Disclose application used to send toots
setting_system_font_ui: Use system's default font
setting_theme: Site theme
setting_trends: Show today's trends
setting_unfollow_modal: Show confirmation dialog before unfollowing someone
setting_use_blurhash: Show colorful gradients for hidden media
setting_use_pending_items: Slow mode


+ 1
- 0
config/settings.yml Visa fil

@@ -34,6 +34,7 @@ defaults: &defaults
advanced_layout: false
use_blurhash: true
use_pending_items: false
trends: true
notification_emails:
follow: false
reblog: false


Laddar…
Avbryt
Spara