logo

mastofe

My custom branche(s) on git.pleroma.social/pleroma/mastofe
commit: f025cc67827a5b1b1faf10dec9d5a1e14e67fa5f
parent: 3988f2dade8a75cb642db8c239097bfcf8943a0d
Author: Matt Jankowski <mjankowski@thoughtbot.com>
Date:   Mon,  1 May 2017 11:42:13 -0400

Filter on allowed user language preferences (#2361)

* Naive approached to timeline filtering

* Convert allowed_languages into a db column

* Allow users to choose languages to see statuses in

* Style list items as two columns

* Add a hint to explain language filtering preference

Diffstat:

Mapp/assets/stylesheets/forms.scss7+++++++
Mapp/controllers/settings/preferences_controller.rb3++-
Mapp/models/account.rb2++
Mapp/models/status.rb5+++++
Mapp/views/settings/preferences/show.html.haml10++++++++++
Mconfig/locales/simple_form.en.yml2++
Adb/migrate/20170423005413_add_allowed_languages_to_user.rb6++++++
Mdb/schema.rb2++
Mspec/controllers/settings/preferences_controller_spec.rb8+++++---
Mspec/models/status_spec.rb25+++++++++++++++++++++++++
10 files changed, 66 insertions(+), 4 deletions(-)

diff --git a/app/assets/stylesheets/forms.scss b/app/assets/stylesheets/forms.scss @@ -326,3 +326,10 @@ code { flex: 0 0 auto; } } + +.user_allowed_languages { + li { + float: left; + width: 50%; + } +} diff --git a/app/controllers/settings/preferences_controller.rb b/app/controllers/settings/preferences_controller.rb @@ -25,7 +25,8 @@ class Settings::PreferencesController < ApplicationController def user_params params.require(:user).permit( - :locale + :locale, + allowed_languages: [] ) end diff --git a/app/models/account.rb b/app/models/account.rb @@ -82,6 +82,8 @@ class Account < ApplicationRecord prefix: true, allow_nil: true + delegate :allowed_languages, to: :user, prefix: false, allow_nil: true + def follow!(other_account) active_relationships.where(target_account: other_account).first_or_create!(target_account: other_account) end diff --git a/app/models/status.rb b/app/models/status.rb @@ -119,6 +119,10 @@ class Status < ApplicationRecord end class << self + def in_allowed_languages(account) + where(language: account.allowed_languages) + end + def as_home_timeline(account) where(account: [account] + account.following) end @@ -198,6 +202,7 @@ class Status < ApplicationRecord def filter_timeline_for_account(query, account) query = query.not_excluded_by_account(account) + query = query.in_allowed_languages(account) if account.allowed_languages.present? query.merge(account_silencing_filter(account)) end diff --git a/app/views/settings/preferences/show.html.haml b/app/views/settings/preferences/show.html.haml @@ -7,6 +7,16 @@ .fields-group = f.input :locale, collection: I18n.available_locales, wrapper: :with_label, include_blank: false, label_method: lambda { |locale| human_locale(locale) } + = f.input :allowed_languages, + collection: I18n.available_locales, + wrapper: :with_label, + include_blank: false, + label_method: lambda { |locale| human_locale(locale) }, + required: false, + as: :check_boxes, + collection_wrapper_tag: 'ul', + item_wrapper_tag: 'li' + = f.input :setting_default_privacy, collection: Status.visibilities.keys - ['direct'], wrapper: :with_label, include_blank: false, label_method: lambda { |visibility| safe_join([I18n.t("statuses.visibilities.#{visibility}"), content_tag(:span, I18n.t("statuses.visibilities.#{visibility}_long"), class: 'hint')]) }, required: false, as: :radio_buttons, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li' .fields-group diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml @@ -12,6 +12,8 @@ en: data: CSV file exported from another Mastodon instance sessions: otp: Enter the Two-factor code from your phone or use one of your recovery codes. + user: + allowed_languages: These languages will be allowed in your public timelines. Languages that are not selected will be filtered out. labels: defaults: avatar: Avatar diff --git a/db/migrate/20170423005413_add_allowed_languages_to_user.rb b/db/migrate/20170423005413_add_allowed_languages_to_user.rb @@ -0,0 +1,6 @@ +class AddAllowedLanguagesToUser < ActiveRecord::Migration[5.0] + def change + add_column :users, :allowed_languages, :string, array: true, default: [], null: false + add_index :users, :allowed_languages, using: :gin + end +end diff --git a/db/schema.rb b/db/schema.rb @@ -326,7 +326,9 @@ ActiveRecord::Schema.define(version: 20170425202925) do t.boolean "otp_required_for_login" t.datetime "last_emailed_at" t.string "otp_backup_codes", array: true + t.string "allowed_languages", default: [], null: false, array: true t.index ["account_id"], name: "index_users_on_account_id", using: :btree + t.index ["allowed_languages"], name: "index_users_on_allowed_languages", using: :gin t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree t.index ["email"], name: "index_users_on_email", unique: true, using: :btree t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree diff --git a/spec/controllers/settings/preferences_controller_spec.rb b/spec/controllers/settings/preferences_controller_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' describe Settings::PreferencesController do render_views - let(:user) { Fabricate(:user) } + let(:user) { Fabricate(:user, allowed_languages: []) } before do sign_in user, scope: :user @@ -18,10 +18,12 @@ describe Settings::PreferencesController do describe 'PUT #update' do it 'updates the user record' do - put :update, params: { user: { locale: 'en' } } + put :update, params: { user: { locale: 'en', allowed_languages: ['es', 'fr'] } } expect(response).to redirect_to(settings_preferences_path) - expect(user.reload.locale).to eq 'en' + user.reload + expect(user.locale).to eq 'en' + expect(user.allowed_languages).to eq ['es', 'fr'] end it 'updates user settings' do diff --git a/spec/models/status_spec.rb b/spec/models/status_spec.rb @@ -251,6 +251,31 @@ RSpec.describe Status, type: :model do expect(results).not_to include(muted_status) end + context 'with language preferences' do + it 'excludes statuses in languages not allowed by the account user' do + user = Fabricate(:user, allowed_languages: [:en, :es]) + @account.update(user: user) + en_status = Fabricate(:status, language: 'en') + es_status = Fabricate(:status, language: 'es') + fr_status = Fabricate(:status, language: 'fr') + + results = Status.as_public_timeline(@account) + expect(results).to include(en_status) + expect(results).to include(es_status) + expect(results).not_to include(fr_status) + end + + it 'includes all languages when account does not have a user' do + expect(@account.user).to be_nil + en_status = Fabricate(:status, language: 'en') + es_status = Fabricate(:status, language: 'es') + + results = Status.as_public_timeline(@account) + expect(results).to include(en_status) + expect(results).to include(es_status) + end + end + context 'where that account is silenced' do it 'includes statuses from other accounts that are silenced' do @account.update(silenced: true)