├── .discourse-compatibility ├── .github └── workflows │ └── discourse-plugin.yml ├── .gitignore ├── .npmrc ├── .prettierrc.cjs ├── .rubocop.yml ├── .streerc ├── .template-lintrc.cjs ├── COPYRIGHT.txt ├── Gemfile ├── Gemfile.lock ├── LICENSE.txt ├── README.md ├── app ├── controllers │ └── follow │ │ └── follow_controller.rb ├── models │ ├── follow_pages_visibility.rb │ └── user_follower.rb └── serializers │ └── follow_post_serializer.rb ├── assets ├── javascripts │ └── discourse │ │ ├── components │ │ ├── follow-button.gjs │ │ ├── follow-notification-preferences.gjs │ │ ├── follow-statistic.gjs │ │ └── follow-users-list.gjs │ │ ├── connectors │ │ ├── user-card-additional-buttons │ │ │ └── follow-button-container.gjs │ │ ├── user-card-metadata │ │ │ └── follow-statistics-user-card.gjs │ │ ├── user-main-nav │ │ │ └── follow-user-container.gjs │ │ ├── user-preferences-notifications │ │ │ └── follow-notification-preferences-container.gjs │ │ ├── user-profile-controls │ │ │ └── follow-button-container.gjs │ │ └── user-profile-secondary │ │ │ └── follow-statistics-user.gjs │ │ ├── controllers │ │ └── follow.js │ │ ├── initializers │ │ └── follow-initializer.js │ │ ├── models │ │ └── post-stream.js │ │ ├── routes │ │ ├── feed.js │ │ ├── follow-index.js │ │ ├── followers.js │ │ └── following.js │ │ ├── templates │ │ ├── feed.gjs │ │ ├── follow.gjs │ │ ├── followers.gjs │ │ └── following.gjs │ │ └── users-route-map.js └── stylesheets │ └── common │ └── follow.scss ├── config ├── locales │ ├── client.ar.yml │ ├── client.be.yml │ ├── client.bg.yml │ ├── client.bs_BA.yml │ ├── client.ca.yml │ ├── client.cs.yml │ ├── client.da.yml │ ├── client.de.yml │ ├── client.el.yml │ ├── client.en.yml │ ├── client.en_GB.yml │ ├── client.es.yml │ ├── client.et.yml │ ├── client.fa_IR.yml │ ├── client.fi.yml │ ├── client.fr.yml │ ├── client.gl.yml │ ├── client.he.yml │ ├── client.hr.yml │ ├── client.hu.yml │ ├── client.hy.yml │ ├── client.id.yml │ ├── client.it.yml │ ├── client.ja.yml │ ├── client.ko.yml │ ├── client.lt.yml │ ├── client.lv.yml │ ├── client.nb_NO.yml │ ├── client.nl.yml │ ├── client.pl_PL.yml │ ├── client.pt.yml │ ├── client.pt_BR.yml │ ├── client.ro.yml │ ├── client.ru.yml │ ├── client.sk.yml │ ├── client.sl.yml │ ├── client.sq.yml │ ├── client.sr.yml │ ├── client.sv.yml │ ├── client.sw.yml │ ├── client.te.yml │ ├── client.th.yml │ ├── client.tr_TR.yml │ ├── client.ug.yml │ ├── client.uk.yml │ ├── client.ur.yml │ ├── client.vi.yml │ ├── client.zh_CN.yml │ ├── client.zh_TW.yml │ ├── server.ar.yml │ ├── server.be.yml │ ├── server.bg.yml │ ├── server.bs_BA.yml │ ├── server.ca.yml │ ├── server.cs.yml │ ├── server.da.yml │ ├── server.de.yml │ ├── server.el.yml │ ├── server.en.yml │ ├── server.en_GB.yml │ ├── server.es.yml │ ├── server.et.yml │ ├── server.fa_IR.yml │ ├── server.fi.yml │ ├── server.fr.yml │ ├── server.gl.yml │ ├── server.he.yml │ ├── server.hr.yml │ ├── server.hu.yml │ ├── server.hy.yml │ ├── server.id.yml │ ├── server.it.yml │ ├── server.ja.yml │ ├── server.ko.yml │ ├── server.lt.yml │ ├── server.lv.yml │ ├── server.nb_NO.yml │ ├── server.nl.yml │ ├── server.pl_PL.yml │ ├── server.pt.yml │ ├── server.pt_BR.yml │ ├── server.ro.yml │ ├── server.ru.yml │ ├── server.sk.yml │ ├── server.sl.yml │ ├── server.sq.yml │ ├── server.sr.yml │ ├── server.sv.yml │ ├── server.sw.yml │ ├── server.te.yml │ ├── server.th.yml │ ├── server.tr_TR.yml │ ├── server.ug.yml │ ├── server.uk.yml │ ├── server.ur.yml │ ├── server.vi.yml │ ├── server.zh_CN.yml │ └── server.zh_TW.yml ├── routes.rb └── settings.yml ├── db └── migrate │ ├── 20210901115010_create_user_follower.rb │ ├── 20210901135131_migrate_follower_data_from_custom_fields_to_tables.rb │ ├── 20210920045747_rename_follow_plugin_preference.rb │ ├── 20211004125251_create_follow_user_custom_fields_indices.rb │ ├── 20211011123651_correct_follow_plugin_site_setting_values.rb │ └── 20220617173420_enable_follow_if_already_installed.rb ├── eslint.config.mjs ├── lib └── follow │ ├── engine.rb │ ├── notification.rb │ ├── notification_handler.rb │ ├── updater.rb │ └── user_extension.rb ├── package.json ├── plugin.rb ├── pnpm-lock.yaml ├── spec ├── integration │ ├── follow_notifications_spec.rb │ ├── user_cards_route_spec.rb │ └── user_destroyer_spec.rb ├── lib │ └── updater_spec.rb ├── models │ ├── follow_pages_visibility_spec.rb │ ├── user_follower_spec.rb │ └── user_spec.rb ├── requests │ └── follow_controller_spec.rb ├── serializers │ ├── user_card_serializer_spec.rb │ └── user_serializer_spec.rb └── system │ ├── core_features_spec.rb │ ├── follow_user_pages_spec.rb │ ├── follow_user_preferences_spec.rb │ └── page_objects │ └── pages │ └── follow.rb ├── stylelint.config.mjs ├── svg-icons └── plugin-icons.svg ├── test └── javascripts │ └── acceptance │ ├── follow-notification-test.js │ └── follow-posts-feed-test.js └── translator.yml /.discourse-compatibility: -------------------------------------------------------------------------------- 1 | < 3.5.0.beta5-dev: 487205a51d55552043bdfd9be3a37facb39076de 2 | < 3.5.0.beta1-dev: 8e68082512df23fbf3bc057317267ad92f133be1 3 | < 3.4.0.beta3-dev: a84123531a6865f6e76cd210e769e0ac4d729963 4 | < 3.4.0.beta1-dev: 1294355185bb29e61d381d63b9b4036cc7af9fc9 5 | < 3.3.0.beta1-dev: da1be75dae1c5218bdc3f7672d804915272c9ee9 6 | 3.1.999: 83d3d61797ba989e5ddea8786235b9ade9ad57af 7 | 3.1.0.beta3: b17ec5a246c35e8cc2e29d74cefa18f8c87bf05b 8 | 3.1.0.beta1: bae520c491b27e23cc1b7b0b6987191fa0a7e514 9 | -------------------------------------------------------------------------------- /.github/workflows/discourse-plugin.yml: -------------------------------------------------------------------------------- 1 | name: Discourse Plugin 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | 9 | jobs: 10 | ci: 11 | uses: discourse/.github/.github/workflows/discourse-plugin.yml@v1 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict = true 2 | auto-install-peers = false 3 | -------------------------------------------------------------------------------- /.prettierrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = require("@discourse/lint-configs/prettier"); 2 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | inherit_gem: 2 | rubocop-discourse: stree-compat.yml 3 | -------------------------------------------------------------------------------- /.streerc: -------------------------------------------------------------------------------- 1 | --print-width=100 2 | --plugins=plugin/trailing_comma 3 | -------------------------------------------------------------------------------- /.template-lintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = require("@discourse/lint-configs/template-lint"); 2 | -------------------------------------------------------------------------------- /COPYRIGHT.txt: -------------------------------------------------------------------------------- 1 | All code in this repository is Copyright 2019 by Angus McLeod. 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; either version 2 of the License, or (at 6 | your option) any later version. 7 | 8 | This program is distributed in the hope that it will be useful, but 9 | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 10 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 | for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program as the file LICENSE.txt; if not, please see 15 | http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. 16 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | group :development do 6 | gem "rubocop-discourse" 7 | gem "syntax_tree" 8 | end 9 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | activesupport (8.0.2) 5 | base64 6 | benchmark (>= 0.3) 7 | bigdecimal 8 | concurrent-ruby (~> 1.0, >= 1.3.1) 9 | connection_pool (>= 2.2.5) 10 | drb 11 | i18n (>= 1.6, < 2) 12 | logger (>= 1.4.2) 13 | minitest (>= 5.1) 14 | securerandom (>= 0.3) 15 | tzinfo (~> 2.0, >= 2.0.5) 16 | uri (>= 0.13.1) 17 | ast (2.4.3) 18 | base64 (0.3.0) 19 | benchmark (0.4.1) 20 | bigdecimal (3.2.0) 21 | concurrent-ruby (1.3.5) 22 | connection_pool (2.5.3) 23 | drb (2.2.3) 24 | i18n (1.14.7) 25 | concurrent-ruby (~> 1.0) 26 | json (2.12.2) 27 | language_server-protocol (3.17.0.5) 28 | lint_roller (1.1.0) 29 | logger (1.7.0) 30 | minitest (5.25.5) 31 | parallel (1.27.0) 32 | parser (3.3.8.0) 33 | ast (~> 2.4.1) 34 | racc 35 | prettier_print (1.2.1) 36 | prism (1.4.0) 37 | racc (1.8.1) 38 | rack (3.1.15) 39 | rainbow (3.1.1) 40 | regexp_parser (2.10.0) 41 | rubocop (1.75.8) 42 | json (~> 2.3) 43 | language_server-protocol (~> 3.17.0.2) 44 | lint_roller (~> 1.1.0) 45 | parallel (~> 1.10) 46 | parser (>= 3.3.0.2) 47 | rainbow (>= 2.2.2, < 4.0) 48 | regexp_parser (>= 2.9.3, < 3.0) 49 | rubocop-ast (>= 1.44.0, < 2.0) 50 | ruby-progressbar (~> 1.7) 51 | unicode-display_width (>= 2.4.0, < 4.0) 52 | rubocop-ast (1.44.1) 53 | parser (>= 3.3.7.2) 54 | prism (~> 1.4) 55 | rubocop-capybara (2.22.1) 56 | lint_roller (~> 1.1) 57 | rubocop (~> 1.72, >= 1.72.1) 58 | rubocop-discourse (3.12.1) 59 | activesupport (>= 6.1) 60 | lint_roller (>= 1.1.0) 61 | rubocop (>= 1.73.2) 62 | rubocop-capybara (>= 2.22.0) 63 | rubocop-factory_bot (>= 2.27.0) 64 | rubocop-rails (>= 2.30.3) 65 | rubocop-rspec (>= 3.0.1) 66 | rubocop-rspec_rails (>= 2.31.0) 67 | rubocop-factory_bot (2.27.1) 68 | lint_roller (~> 1.1) 69 | rubocop (~> 1.72, >= 1.72.1) 70 | rubocop-rails (2.32.0) 71 | activesupport (>= 4.2.0) 72 | lint_roller (~> 1.1) 73 | rack (>= 1.1) 74 | rubocop (>= 1.75.0, < 2.0) 75 | rubocop-ast (>= 1.44.0, < 2.0) 76 | rubocop-rspec (3.6.0) 77 | lint_roller (~> 1.1) 78 | rubocop (~> 1.72, >= 1.72.1) 79 | rubocop-rspec_rails (2.31.0) 80 | lint_roller (~> 1.1) 81 | rubocop (~> 1.72, >= 1.72.1) 82 | rubocop-rspec (~> 3.5) 83 | ruby-progressbar (1.13.0) 84 | securerandom (0.4.1) 85 | syntax_tree (6.2.0) 86 | prettier_print (>= 1.2.0) 87 | tzinfo (2.0.6) 88 | concurrent-ruby (~> 1.0) 89 | unicode-display_width (3.1.4) 90 | unicode-emoji (~> 4.0, >= 4.0.4) 91 | unicode-emoji (4.0.4) 92 | uri (1.0.3) 93 | 94 | PLATFORMS 95 | ruby 96 | 97 | DEPENDENCIES 98 | rubocop-discourse 99 | syntax_tree 100 | 101 | BUNDLED WITH 102 | 2.6.9 103 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Discourse Follow 2 | 3 | This Discourse plugin allows you to follow other users, list the latest topics involving them and receive notifications when they post. 4 | 5 | Installation guide, plugin documentation, screenshots and more details can be found in the [plugin's topic](https://meta.discourse.org/t/follow-plugin/110579?u=osama) on Discourse Meta. Please submit bug reports and feature requests over there as well. 6 | 7 | This plugin is an official plugin maintained by the Discourse team (CDCK, Inc). 8 | 9 | ### Credits 10 | 11 | This plugin was originally developed by [Pavilion](https://thepavilion.io) and maintained by them until October 2021 when maintenance was transferred to the Discourse team. 12 | -------------------------------------------------------------------------------- /app/controllers/follow/follow_controller.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class Follow::FollowController < ApplicationController 4 | requires_plugin Follow::PLUGIN_NAME 5 | 6 | FOLLOWING = :following 7 | FOLLOWERS = :followers 8 | 9 | def index 10 | end 11 | 12 | def follow 13 | raise Discourse::InvalidAccess.new if !current_user 14 | 15 | user = fetch_user 16 | return if user.blank? 17 | 18 | Follow::Updater.new(current_user, user).watch_follow 19 | render json: success_json 20 | end 21 | 22 | def unfollow 23 | raise Discourse::InvalidAccess.new if !current_user 24 | 25 | user = fetch_user 26 | return if user.blank? 27 | 28 | Follow::Updater.new(current_user, user).unfollow 29 | render json: success_json 30 | end 31 | 32 | def list_following 33 | list(FOLLOWING) 34 | end 35 | 36 | def list_followers 37 | list(FOLLOWERS) 38 | end 39 | 40 | def posts 41 | raise Discourse::InvalidAccess.new if !current_user 42 | 43 | user = fetch_user 44 | return if user.blank? 45 | 46 | ensure_can_see_feed!(user) 47 | 48 | limit = (params[:limit].presence || 20).to_i 49 | limit = 20 if limit <= 0 50 | 51 | created_before = nil 52 | if val = params[:created_before].presence 53 | created_before = validate_date(val) 54 | if created_before.nil? 55 | return( 56 | render json: { 57 | errors: [I18n.t("follow.invalid_created_before_date", value: val.inspect)], 58 | }, 59 | status: 400 60 | ) 61 | end 62 | end 63 | 64 | posts, has_more = find_posts_feed(user, limit, created_before) 65 | render_serialized( 66 | posts, 67 | FollowPostSerializer, 68 | root: "posts", 69 | extras: { 70 | has_more: has_more, 71 | }, 72 | rest_serializer: true, 73 | ) 74 | end 75 | 76 | private 77 | 78 | def list(type) 79 | user = fetch_user 80 | return if user.blank? 81 | 82 | if type == FOLLOWERS 83 | raise Discourse::InvalidAccess.new if !can_see_followers?(user) 84 | users = user.followers.to_a 85 | elsif type == FOLLOWING 86 | raise Discourse::InvalidAccess.new if !can_see_following?(user) 87 | users = user.following.to_a 88 | else 89 | raise Discourse::InvalidParameters.new 90 | end 91 | 92 | serializer = ActiveModel::ArraySerializer.new(users, each_serializer: BasicUserSerializer) 93 | render json: MultiJson.dump(serializer) 94 | end 95 | 96 | def can_see_following?(target_user) 97 | FollowPagesVisibility.can_see_following_page?(user: current_user, target_user: target_user) 98 | end 99 | 100 | def can_see_followers?(target_user) 101 | FollowPagesVisibility.can_see_followers_page?(user: current_user, target_user: target_user) 102 | end 103 | 104 | def fetch_user 105 | user = User.find_by_username(params.require(:username)) 106 | if user.blank? 107 | render json: { 108 | errors: [I18n.t("follow.user_not_found", username: params[:username].inspect)], 109 | }, 110 | status: 404 111 | return nil 112 | end 113 | user 114 | end 115 | 116 | def ensure_can_see_feed!(target_user) 117 | raise Discourse::InvalidAccess.new if target_user.id != current_user.id && !current_user.staff? 118 | end 119 | 120 | def validate_date(value) 121 | value.to_s.to_datetime 122 | rescue Date::Error 123 | nil 124 | end 125 | 126 | def find_posts_feed(target_user, limit, created_before) 127 | posts = 128 | UserFollower.posts_for( 129 | target_user, 130 | current_user: current_user, 131 | limit: limit + 1, 132 | created_before: created_before, 133 | ).to_a 134 | 135 | has_more = false 136 | if posts.size == limit + 1 137 | has_more = true 138 | posts.pop 139 | end 140 | [posts, has_more] 141 | end 142 | end 143 | -------------------------------------------------------------------------------- /app/models/follow_pages_visibility.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class FollowPagesVisibility < EnumSiteSetting 4 | NO_ONE = "no-one" 5 | SELF = "self" 6 | EVERYONE = "everyone" 7 | 8 | class << self 9 | def valid_value?(val) 10 | values.any? { |v| v[:value] == val } 11 | end 12 | 13 | def values 14 | @values ||= 15 | [ 16 | NO_ONE, 17 | SELF, 18 | "trust_level_4", 19 | "trust_level_3", 20 | "trust_level_2", 21 | "trust_level_1", 22 | "trust_level_0", 23 | EVERYONE, 24 | ].map { |v| { name: "follow.follow_pages_visibility.#{v}", value: v } } 25 | end 26 | 27 | def translate_names? 28 | true 29 | end 30 | 31 | def can_see_followers_page?(user:, target_user:) 32 | can_see_page?(user, target_user, SiteSetting.follow_followers_visible) 33 | end 34 | 35 | def can_see_following_page?(user:, target_user:) 36 | can_see_page?(user, target_user, SiteSetting.follow_following_visible) 37 | end 38 | 39 | private 40 | 41 | def can_see_page?(user, target_user, page_setting_value) 42 | return false if !SiteSetting.discourse_follow_enabled 43 | return false if target_user.blank? 44 | return true if page_setting_value == EVERYONE 45 | return false if page_setting_value == NO_ONE 46 | return false if user.blank? 47 | return true if user.id == target_user.id 48 | return false if page_setting_value == SELF 49 | group = Group.lookup_group(page_setting_value.to_sym) 50 | return false if group.blank? 51 | GroupUser.where(user_id: user.id, group_id: group.id).exists? 52 | end 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /app/models/user_follower.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class UserFollower < ActiveRecord::Base 4 | def self.posts_for(user, current_user:, limit: nil, created_before: nil, created_after: nil) 5 | visible_post_types = [Post.types[:regular], Post.types[:moderator_action]] 6 | visible_post_types << Post.types[:whisper] if current_user.staff? 7 | 8 | results = 9 | Post 10 | .joins(:topic, :user, topic: :category) 11 | .joins("INNER JOIN user_followers ON user_followers.user_id = users.id") 12 | .preload(:user, topic: :category) 13 | .where(post_type: visible_post_types) 14 | .where("topics.archetype != ?", Archetype.private_message) 15 | .where("topics.visible") 16 | .where("user_followers.follower_id = ?", user.id) 17 | .where(action_code: nil) 18 | .order(created_at: :desc) 19 | 20 | results = filter_opted_out_users(results) 21 | results = Guardian.new(current_user).filter_allowed_categories(results) 22 | results = results.limit(limit) if limit 23 | results = results.where("posts.created_at < ?", created_before) if created_before 24 | results = results.where("posts.created_at > ?", created_after) if created_after 25 | 26 | results 27 | end 28 | 29 | def self.topics_for(user, current_user:, limit: nil, created_before: nil, created_after: nil) 30 | results = 31 | Topic 32 | .joins(:user) 33 | .joins("INNER JOIN user_followers ON user_followers.user_id = users.id") 34 | .preload(:user, :category) 35 | .where("user_followers.follower_id = ?", user.id) 36 | .listable_topics 37 | .visible 38 | .order(created_at: :desc) 39 | 40 | results = filter_opted_out_users(results) 41 | results = Guardian.new(current_user).filter_allowed_categories(results) 42 | results = results.limit(limit) if limit 43 | results = results.where("topics.created_at < ?", created_before) if created_before 44 | results = results.where("topics.created_at > ?", created_after) if created_after 45 | 46 | results 47 | end 48 | 49 | def self.filter_opted_out_users(relation) 50 | truthy_values = sanitize_sql(["?", HasCustomFields::Helpers::CUSTOM_FIELD_TRUE]) 51 | if SiteSetting.default_allow_people_to_follow_me 52 | relation = relation.joins(<<~SQL) 53 | LEFT OUTER JOIN user_custom_fields ucf 54 | ON ucf.name = 'allow_people_to_follow_me' 55 | AND ucf.user_id = users.id 56 | AND ucf.value NOT IN (#{truthy_values}) 57 | SQL 58 | relation = relation.where("ucf.user_id IS NULL") 59 | else 60 | relation = relation.joins(<<~SQL) 61 | INNER JOIN user_custom_fields ucf 62 | ON ucf.name = 'allow_people_to_follow_me' 63 | AND ucf.user_id = users.id 64 | AND ucf.value IN (#{truthy_values}) 65 | SQL 66 | end 67 | relation.joins("LEFT OUTER JOIN user_options uo ON uo.user_id = users.id").where( 68 | "uo.user_id IS NULL OR NOT uo.hide_profile", 69 | ) 70 | end 71 | 72 | belongs_to :follower_user, class_name: "User", foreign_key: :follower_id 73 | belongs_to :followed_user, class_name: "User", foreign_key: :user_id 74 | end 75 | 76 | # == Schema Information 77 | # 78 | # Table name: user_followers 79 | # 80 | # id :bigint not null, primary key 81 | # user_id :bigint not null 82 | # follower_id :bigint not null 83 | # level :integer not null 84 | # created_at :datetime not null 85 | # updated_at :datetime not null 86 | # 87 | # Indexes 88 | # 89 | # index_user_followers_on_user_id_and_follower_id (user_id,follower_id) UNIQUE 90 | # 91 | -------------------------------------------------------------------------------- /app/serializers/follow_post_serializer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class FollowPostSerializer < ApplicationSerializer 4 | include PostItemExcerpt 5 | 6 | attributes *%i[category_id created_at id post_number post_type topic_id url] 7 | 8 | has_one :user, serializer: BasicUserSerializer, embed: :object 9 | has_one :topic, serializer: BasicTopicSerializer, embed: :object 10 | 11 | def category_id 12 | object.topic.category_id 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/components/follow-button.gjs: -------------------------------------------------------------------------------- 1 | import Component from "@ember/component"; 2 | import { action } from "@ember/object"; 3 | import { alias } from "@ember/object/computed"; 4 | import { and } from "truth-helpers"; 5 | import DButton from "discourse/components/d-button"; 6 | import { ajax } from "discourse/lib/ajax"; 7 | import { popupAjaxError } from "discourse/lib/ajax-error"; 8 | import discourseComputed from "discourse/lib/decorators"; 9 | 10 | export default class FollowButton extends Component { 11 | loading = false; 12 | 13 | @alias("user.is_followed") isFollowed; 14 | @alias("user.can_follow") canFollow; 15 | 16 | @discourseComputed("user", "currentUser") 17 | showButton(user, currentUser) { 18 | if (!currentUser) { 19 | return false; 20 | } 21 | if (currentUser.id === user.id) { 22 | return false; 23 | } 24 | if (user.suspended) { 25 | return false; 26 | } 27 | if (user.staged) { 28 | return false; 29 | } 30 | if (user.id < 1) { 31 | // bot 32 | return false; 33 | } 34 | return true; 35 | } 36 | 37 | @discourseComputed("isFollowed", "canFollow") 38 | labelKey(isFollowed, canFollow) { 39 | if (isFollowed && canFollow) { 40 | return "follow.unfollow_button_label"; 41 | } else { 42 | return "follow.follow_button_label"; 43 | } 44 | } 45 | 46 | @discourseComputed("isFollowed", "canFollow") 47 | icon(isFollowed, canFollow) { 48 | if (isFollowed && canFollow) { 49 | return "user-xmark"; 50 | } else { 51 | return "user-plus"; 52 | } 53 | } 54 | 55 | @action 56 | toggleFollow() { 57 | const type = this.isFollowed ? "DELETE" : "PUT"; 58 | this.set("loading", true); 59 | ajax(`/follow/${this.user.username}.json`, { type }) 60 | .then(() => { 61 | this.set("isFollowed", !this.isFollowed); 62 | }) 63 | .catch(popupAjaxError) 64 | .finally(() => { 65 | this.set("loading", false); 66 | }); 67 | } 68 | 69 | 79 | } 80 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/components/follow-notification-preferences.gjs: -------------------------------------------------------------------------------- 1 | import Component from "@ember/component"; 2 | import { observes } from "@ember-decorators/object"; 3 | import PreferenceCheckbox from "discourse/components/preference-checkbox"; 4 | import { i18n } from "discourse-i18n"; 5 | 6 | const preferences = [ 7 | "notify_me_when_followed", 8 | "notify_followed_user_when_followed", 9 | "notify_me_when_followed_replies", 10 | "notify_me_when_followed_creates_topic", 11 | "allow_people_to_follow_me", 12 | ]; 13 | 14 | export default class FollowNotificationPreferences extends Component { 15 | @observes(...preferences.map((p) => `user.${p}`)) 16 | _updatePreferences() { 17 | if (!this.user.custom_fields) { 18 | this.user.set("custom_fields", {}); 19 | } 20 | preferences.forEach((p) => { 21 | this.user.set(`custom_fields.${p}`, this.user[p]); 22 | }); 23 | } 24 | 25 | 62 | } 63 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/components/follow-statistic.gjs: -------------------------------------------------------------------------------- 1 | import { i18n } from "discourse-i18n"; 2 | 3 | const FollowStatistic = ; 8 | 9 | export default FollowStatistic; 10 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/components/follow-users-list.gjs: -------------------------------------------------------------------------------- 1 | import Component from "@ember/component"; 2 | import { notEmpty } from "@ember/object/computed"; 3 | import UserInfo from "discourse/components/user-info"; 4 | import { propertyEqual } from "discourse/lib/computed"; 5 | import discourseComputed from "discourse/lib/decorators"; 6 | import { i18n } from "discourse-i18n"; 7 | 8 | export default class FollowUsersList extends Component { 9 | @notEmpty("users") hasUsers; 10 | @propertyEqual("user.username", "currentUser.username") viewingSelf; 11 | 12 | @discourseComputed("type", "viewingSelf") 13 | noneMessage(type, viewingSelf) { 14 | let key = viewingSelf ? "none" : "none_other"; 15 | return `user.${type}.${key}`; 16 | } 17 | 18 | 32 | } 33 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/connectors/user-card-additional-buttons/follow-button-container.gjs: -------------------------------------------------------------------------------- 1 | import Component from "@ember/component"; 2 | import { classNames, tagName } from "@ember-decorators/component"; 3 | import FollowButton from "../../components/follow-button"; 4 | 5 | @tagName("li") 6 | @classNames("user-card-additional-buttons-outlet", "follow-button-container") 7 | export default class FollowButtonContainer extends Component { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/connectors/user-card-metadata/follow-statistics-user-card.gjs: -------------------------------------------------------------------------------- 1 | import Component from "@ember/component"; 2 | import { classNames, tagName } from "@ember-decorators/component"; 3 | import { i18n } from "discourse-i18n"; 4 | 5 | @tagName("div") 6 | @classNames("user-card-metadata-outlet", "follow-statistics-user-card") 7 | export default class FollowStatisticsUserCard extends Component { 8 | static shouldRender(_, context) { 9 | return context.siteSettings.follow_show_statistics_on_profile; 10 | } 11 | 12 | 26 | } 27 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/connectors/user-main-nav/follow-user-container.gjs: -------------------------------------------------------------------------------- 1 | import Component from "@ember/component"; 2 | import { LinkTo } from "@ember/routing"; 3 | import { classNames, tagName } from "@ember-decorators/component"; 4 | import icon from "discourse/helpers/d-icon"; 5 | import { i18n } from "discourse-i18n"; 6 | 7 | @tagName("li") 8 | @classNames("user-main-nav-outlet", "follow-user-container") 9 | export default class FollowUserContainer extends Component { 10 | 18 | } 19 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/connectors/user-preferences-notifications/follow-notification-preferences-container.gjs: -------------------------------------------------------------------------------- 1 | import Component from "@ember/component"; 2 | import { classNames, tagName } from "@ember-decorators/component"; 3 | import FollowNotificationPreferences from "../../components/follow-notification-preferences"; 4 | 5 | @tagName("div") 6 | @classNames( 7 | "user-preferences-notifications-outlet", 8 | "follow-notification-preferences-container" 9 | ) 10 | export default class FollowNotificationPreferencesContainer extends Component { 11 | static shouldRender(_, context) { 12 | return context.siteSettings.follow_notifications_enabled; 13 | } 14 | 15 | 16 | } 17 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/connectors/user-profile-controls/follow-button-container.gjs: -------------------------------------------------------------------------------- 1 | import Component from "@ember/component"; 2 | import { classNames, tagName } from "@ember-decorators/component"; 3 | import FollowButton from "../../components/follow-button"; 4 | 5 | @tagName("li") 6 | @classNames("user-profile-controls-outlet", "follow-button-container") 7 | export default class FollowButtonContainer extends Component { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/connectors/user-profile-secondary/follow-statistics-user.gjs: -------------------------------------------------------------------------------- 1 | import Component from "@ember/component"; 2 | import { classNames, tagName } from "@ember-decorators/component"; 3 | import FollowStatistic from "../../components/follow-statistic"; 4 | 5 | @tagName("") 6 | @classNames("user-profile-secondary-outlet", "follow-statistics-user") 7 | export default class FollowStatisticsUser extends Component { 8 | static shouldRender(_, context) { 9 | return context.siteSettings.follow_show_statistics_on_profile; 10 | } 11 | 12 | 27 | } 28 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/controllers/follow.js: -------------------------------------------------------------------------------- 1 | import Controller from "@ember/controller"; 2 | 3 | export default class FollowController extends Controller {} 4 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/initializers/follow-initializer.js: -------------------------------------------------------------------------------- 1 | import { action } from "@ember/object"; 2 | import { withPluginApi } from "discourse/lib/plugin-api"; 3 | import { userPath } from "discourse/lib/url"; 4 | import { i18n } from "discourse-i18n"; 5 | 6 | export default { 7 | name: "follow-plugin-initializer", 8 | initialize(/*container*/) { 9 | withPluginApi("0.8.10", (api) => { 10 | const currentUser = api.getCurrentUser(); 11 | if (!currentUser) { 12 | return; 13 | } 14 | api.replaceIcon( 15 | "notification.following", 16 | "discourse-follow-new-follower" 17 | ); 18 | api.replaceIcon( 19 | "notification.following_created_topic", 20 | "discourse-follow-new-topic" 21 | ); 22 | api.replaceIcon( 23 | "notification.following_replied", 24 | "discourse-follow-new-reply" 25 | ); 26 | 27 | if (api.registerNotificationTypeRenderer) { 28 | api.registerNotificationTypeRenderer( 29 | "following", 30 | (NotificationTypeBase) => { 31 | return class extends NotificationTypeBase { 32 | get linkTitle() { 33 | return i18n("notifications.titles.following"); 34 | } 35 | 36 | get linkHref() { 37 | return userPath(this.notification.data.display_username); 38 | } 39 | 40 | get icon() { 41 | return "discourse-follow-new-follower"; 42 | } 43 | 44 | get label() { 45 | return this.notification.data.display_username; 46 | } 47 | 48 | get description() { 49 | return i18n("notifications.following_description", {}); 50 | } 51 | }; 52 | } 53 | ); 54 | } 55 | 56 | // workaround to make core save custom fields when changing 57 | // preferences 58 | api.modifyClass( 59 | "controller:preferences/notifications", 60 | (Superclass) => 61 | class extends Superclass { 62 | @action 63 | save() { 64 | if (!this.saveAttrNames.includes("custom_fields")) { 65 | this.saveAttrNames.push("custom_fields"); 66 | } 67 | super.save(); 68 | } 69 | } 70 | ); 71 | }); 72 | }, 73 | }; 74 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/models/post-stream.js: -------------------------------------------------------------------------------- 1 | import EmberObject from "@ember/object"; 2 | import { reads } from "@ember/object/computed"; 3 | import { on } from "@ember-decorators/object"; 4 | import { Promise } from "rsvp"; 5 | import { ajax } from "discourse/lib/ajax"; 6 | import discourseComputed from "discourse/lib/decorators"; 7 | import Category from "discourse/models/category"; 8 | import RestModel from "discourse/models/rest"; 9 | 10 | // this class implements an interface similar to the `UserStream` class in core 11 | // (app/models/user-stream.js) so we can use it with the `{{user-stream}}` 12 | // component (in core as well) which expects a `UserStream` instance. 13 | 14 | export default class PostStream extends RestModel { 15 | loading = false; 16 | itemsLoaded = 0; 17 | canLoadMore = true; 18 | 19 | @reads("content.lastObject.created_at") lastPostCreatedAt; 20 | 21 | @on("init") 22 | _initialize() { 23 | this.set("content", []); 24 | } 25 | 26 | @discourseComputed("loading", "content.length") 27 | noContent(loading, length) { 28 | return !loading && length === 0; 29 | } 30 | 31 | findItems() { 32 | if (!this.canLoadMore || this.loading) { 33 | return Promise.resolve(); 34 | } 35 | 36 | this.set("loading", true); 37 | const data = {}; 38 | if (this.lastPostCreatedAt) { 39 | data.created_before = this.lastPostCreatedAt; 40 | } 41 | return ajax(`/follow/posts/${this.user.username}`, { data }) 42 | .then((content) => { 43 | const streamItems = content.posts.map((post) => { 44 | return EmberObject.create({ 45 | title: post.topic.title, 46 | postUrl: post.url, 47 | created_at: post.created_at, 48 | category: Category.findById(post.category_id), 49 | topic_id: post.topic.id, 50 | post_id: post.id, 51 | post_number: post.post_number, 52 | 53 | username: post.user.username, 54 | name: post.user.name, 55 | avatar_template: post.user.avatar_template, 56 | user_id: post.user.id, 57 | 58 | excerpt: post.excerpt, 59 | truncated: post.truncated, 60 | }); 61 | }); 62 | return { posts: streamItems, hasMore: content.extras.has_more }; 63 | }) 64 | .then(({ posts: streamItems, hasMore }) => { 65 | this.content.addObjects(streamItems); 66 | this.set("itemsLoaded", this.content.length); 67 | this.set("canLoadMore", hasMore); 68 | }) 69 | .finally(() => { 70 | this.set("loading", false); 71 | }); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/routes/feed.js: -------------------------------------------------------------------------------- 1 | import DiscourseRoute from "discourse/routes/discourse"; 2 | import PostStream from "../models/post-stream"; 3 | 4 | export default class Feed extends DiscourseRoute { 5 | model() { 6 | return PostStream.create({ user: this.modelFor("user") }); 7 | } 8 | 9 | afterModel(model) { 10 | return model.findItems(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/routes/follow-index.js: -------------------------------------------------------------------------------- 1 | import { service } from "@ember/service"; 2 | import DiscourseRoute from "discourse/routes/discourse"; 3 | 4 | export default class FollowIndexRoute extends DiscourseRoute { 5 | @service router; 6 | 7 | beforeModel() { 8 | const model = this.modelFor("user"); 9 | const canSeeFollowers = model.can_see_followers; 10 | const canSeeFollowing = model.can_see_following; 11 | 12 | if (this.currentUser?.id === model.id) { 13 | this.router.replaceWith("feed"); 14 | } else if (canSeeFollowing) { 15 | this.router.replaceWith("following"); 16 | } else if (canSeeFollowers) { 17 | this.router.replaceWith("followers"); 18 | } else { 19 | this.router.replaceWith("user"); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/routes/followers.js: -------------------------------------------------------------------------------- 1 | import { ajax } from "discourse/lib/ajax"; 2 | import DiscourseRoute from "discourse/routes/discourse"; 3 | 4 | export default class Followers extends DiscourseRoute { 5 | model() { 6 | return ajax(`/u/${this.paramsFor("user").username}/follow/followers`); 7 | } 8 | 9 | setupController(controller, model) { 10 | controller.setProperties({ 11 | users: model, 12 | user: this.modelFor("user"), 13 | }); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/routes/following.js: -------------------------------------------------------------------------------- 1 | import { ajax } from "discourse/lib/ajax"; 2 | import DiscourseRoute from "discourse/routes/discourse"; 3 | 4 | export default class Following extends DiscourseRoute { 5 | model() { 6 | return ajax(`/u/${this.paramsFor("user").username}/follow/following`); 7 | } 8 | 9 | setupController(controller, model) { 10 | const user = this.modelFor("user"); 11 | controller.setProperties({ users: model, user }); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/templates/feed.gjs: -------------------------------------------------------------------------------- 1 | import Component from "@glimmer/component"; 2 | import { action } from "@ember/object"; 3 | import { service } from "@ember/service"; 4 | import RouteTemplate from "ember-route-template"; 5 | import PostList from "discourse/components/post-list"; 6 | import { i18n } from "discourse-i18n"; 7 | 8 | export default RouteTemplate( 9 | class extends Component { 10 | @service currentUser; 11 | 12 | get viewingSelf() { 13 | return this.args.model.user.id === this.currentUser.id; 14 | } 15 | 16 | @action 17 | async loadMore() { 18 | if (!this.args.model.canLoadMore) { 19 | return []; 20 | } 21 | 22 | await this.args.model.findItems(); 23 | 24 | return this.args.model.content; 25 | } 26 | 27 | 48 | } 49 | ); 50 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/templates/follow.gjs: -------------------------------------------------------------------------------- 1 | import RouteTemplate from "ember-route-template"; 2 | import { and, eq } from "truth-helpers"; 3 | import DNavigationItem from "discourse/components/d-navigation-item"; 4 | import HorizontalOverflowNav from "discourse/components/horizontal-overflow-nav"; 5 | import bodyClass from "discourse/helpers/body-class"; 6 | import { i18n } from "discourse-i18n"; 7 | 8 | export default RouteTemplate( 9 | 43 | ); 44 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/templates/followers.gjs: -------------------------------------------------------------------------------- 1 | import RouteTemplate from "ember-route-template"; 2 | import FollowUsersList from "../components/follow-users-list"; 3 | 4 | export default RouteTemplate( 5 | 12 | ); 13 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/templates/following.gjs: -------------------------------------------------------------------------------- 1 | import RouteTemplate from "ember-route-template"; 2 | import FollowUsersList from "../components/follow-users-list"; 3 | 4 | export default RouteTemplate( 5 | 12 | ); 13 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/users-route-map.js: -------------------------------------------------------------------------------- 1 | export default { 2 | resource: "user", 3 | map() { 4 | this.route("follow", { resetNamespace: true }, function () { 5 | this.route("feed", { resetNamespace: true }); 6 | this.route("followers", { resetNamespace: true }); 7 | this.route("following", { resetNamespace: true }); 8 | }); 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /assets/stylesheets/common/follow.scss: -------------------------------------------------------------------------------- 1 | .follow-statistic { 2 | span:first-of-type { 3 | margin-right: 3px; 4 | } 5 | } 6 | 7 | .follow-statistics-user-card { 8 | // ignores the wrapping div so the contents appear as siblings 9 | // along other metadata in the usercard 10 | display: contents; 11 | } 12 | 13 | .user-follows-tab .feed-link { 14 | margin-bottom: 1em; 15 | display: block; 16 | } 17 | -------------------------------------------------------------------------------- /config/locales/client.ar.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | ar: 8 | admin_js: 9 | admin: 10 | site_settings: 11 | categories: 12 | discourse_follow: "Discourse Follow" 13 | js: 14 | notifications: 15 | following: "%{username} %{description}" 16 | following_description: "بدأ في متابعتك." 17 | following_created_topic: "%{username} %{description}" 18 | following_replied: "%{username} %{description}" 19 | titles: 20 | following_created_topic: "موضوع جديد من شخص تتابعه" 21 | following_replied: "منشور جديد من شخص تتابعه" 22 | following: "بدأ شخص ما في متابعتك" 23 | popup: 24 | following: "بدأ %{username} في متابعتك." 25 | following_created_topic: 'أنشأ %{username} الموضوع "%{topic}" - %{site_title}' 26 | following_replied: 'نشر %{username} في "%{topic}" - ‏%{site_title}' 27 | user: 28 | follow_nav: "المتابعات" 29 | follow: 30 | label: "متابعة" 31 | following: 32 | feed_link: "متابعة الموجز" 33 | label: "متابَع" 34 | none: "أنت لا تتابع أي شخص حتى الآن." 35 | none_other: "%{username} لا يتابع أي شخص حتى الآن." 36 | followers: 37 | label: "المتابِعون" 38 | none: "لا أحد يتابعك حتى الآن." 39 | none_other: "لا أحد يتابع %{username} حتى الآن." 40 | feed: 41 | label: "الموجز" 42 | empty_feed_you: "لا توجد منشورات من الأشخاص الذين تتابعهم حتى الآن." 43 | empty_feed_other: "لا توجد منشورات من الأشخاص الذين يتابعهم %{username} حتى الآن." 44 | follow_notifications_options: 45 | notify_followed_user_when_followed: "إرسال إشعار إلى المستخدمين عندما أتابعهم" 46 | notify_me_when_followed: "إرسال إشعار إليَّ عندما يتابعني المستخدمون" 47 | notify_me_when_followed_replies: "إرسال إشعار إليَّ عندما يرد شخص ما أتابعه" 48 | notify_me_when_followed_creates_topic: "إرسال إشعار إليَّ عندما ينشئ شخص ما أتابعه موضوعًا" 49 | allow_people_to_follow_me: "السماح للأشخاص بمتابعتي" 50 | follow: 51 | follow_pages_visibility: 52 | no-one: "لا أحد" 53 | self: "نفسي" 54 | trust_level_4: "مستوى الثقة 4" 55 | trust_level_3: "مستوى الثقة 3" 56 | trust_level_2: "مستوى الثقة 2" 57 | trust_level_1: "مستوى الثقة 1" 58 | trust_level_0: "مستوى الثقة 0" 59 | everyone: "الجميع" 60 | follow_button_label: "متابعة" 61 | unfollow_button_label: "إلغاء المتابعة" 62 | -------------------------------------------------------------------------------- /config/locales/client.be.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | be: 8 | js: 9 | follow: 10 | follow_pages_visibility: 11 | everyone: "Усе" 12 | -------------------------------------------------------------------------------- /config/locales/client.bg.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | bg: 8 | js: 9 | notifications: 10 | following: "%{username} %{description}" 11 | following_created_topic: "%{username} %{description}" 12 | following_replied: "%{username} %{description}" 13 | popup: 14 | following_replied: '%{username} публикува в "%{topic}" - %{site_title}' 15 | follow: 16 | follow_pages_visibility: 17 | everyone: "Всички" 18 | -------------------------------------------------------------------------------- /config/locales/client.bs_BA.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | bs_BA: 8 | js: 9 | notifications: 10 | following: "%{username} %{description}" 11 | following_created_topic: "%{username} %{description}" 12 | following_replied: "%{username} %{description}" 13 | popup: 14 | following_replied: '%{username} je objavio/la "%{topic}" - %{site_title}' 15 | follow: 16 | follow_pages_visibility: 17 | everyone: "Svatko" 18 | -------------------------------------------------------------------------------- /config/locales/client.ca.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | ca: 8 | js: 9 | notifications: 10 | following: "%{username} %{description}" 11 | following_description: "t'ha començat a seguir." 12 | following_created_topic: "%{username} %{description}" 13 | following_replied: "%{username} %{description}" 14 | titles: 15 | following_created_topic: "nou tema d'algú que estàs seguint" 16 | following_replied: "nova publicació d'algú que segueixes" 17 | following: "algú t'ha començat a seguir" 18 | popup: 19 | following: "%{username} t'ha començat a seguir." 20 | following_created_topic: '%{username} ha creat "%{topic}" - %{site_title}' 21 | following_replied: '%{username} ha publicat en "%{topic}" - %{site_title}' 22 | user: 23 | follow_nav: "Xarxa" 24 | follow: 25 | label: "Seguir" 26 | following: 27 | feed_link: "Feed de seguiment" 28 | label: "Seguint" 29 | none: "Encara no segueixes a ningú." 30 | none_other: "%{username} encara no segueix a ningú." 31 | followers: 32 | label: "Seguidors" 33 | none: "Encara no et segueix ningú." 34 | none_other: "Encara ningú segueix a %{username}." 35 | feed: 36 | label: "Feed" 37 | empty_feed_you: "Encara no hi ha publicacions de les persones que segueixes." 38 | empty_feed_other: "Encara no hi ha publicacions dels usuaris que %{username} segueix." 39 | follow_notifications_options: 40 | notify_followed_user_when_followed: "Notifica als usuaris quan els segueixo." 41 | notify_me_when_followed: "Notifica'm quan els usuaris em segueixen." 42 | notify_me_when_followed_replies: "Notifica'm quan algú que segueixo respon a un tema." 43 | notify_me_when_followed_creates_topic: "Notifica'm quan algú que segueixo crea un tema." 44 | allow_people_to_follow_me: "Permetre que la gent em segueixi" 45 | follow: 46 | follow_pages_visibility: 47 | no-one: "Ningú" 48 | trust_level_4: "Nivell de confiança 4" 49 | trust_level_3: "Nivell de confiança 3" 50 | trust_level_2: "Nivell de confiança 2" 51 | trust_level_1: "Nivell de confiança 1" 52 | trust_level_0: "Nivell de confiança 0" 53 | everyone: "Tothom" 54 | follow_button_label: "Seguir" 55 | unfollow_button_label: "Deixar de seguir" 56 | -------------------------------------------------------------------------------- /config/locales/client.cs.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | cs: 8 | js: 9 | notifications: 10 | following: "%{username} %{description}" 11 | following_created_topic: "%{username} %{description}" 12 | following_replied: "%{username} %{description}" 13 | popup: 14 | following_replied: '%{username} přispěl do "%{topic}" - %{site_title}' 15 | follow: 16 | follow_pages_visibility: 17 | everyone: "Všichni" 18 | -------------------------------------------------------------------------------- /config/locales/client.da.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | da: 8 | admin_js: 9 | admin: 10 | site_settings: 11 | categories: 12 | discourse_follow: "Discourse Følg" 13 | js: 14 | notifications: 15 | following: "%{username} %{description}" 16 | following_description: "er begyndt at følge dig." 17 | following_created_topic: "%{username} %{description}" 18 | following_replied: "%{username} %{description}" 19 | titles: 20 | following_created_topic: "nyt emne fra en du følger" 21 | following_replied: "nyt indlæg fra en du følger" 22 | following: "nogen er begyndt at følge dig" 23 | popup: 24 | following: "%{username} er begyndt at følge dig." 25 | following_replied: '%{username} skrev i "%{topic}" - %{site_title}' 26 | user: 27 | follow_nav: "Følger" 28 | follow: 29 | label: "Følg" 30 | following: 31 | label: "Følger" 32 | none: "Du følger ikke nogen endnu." 33 | none_other: "%{username} følger ikke nogen endnu." 34 | followers: 35 | label: "Følgere" 36 | none: "Ingen følger dig endnu." 37 | none_other: "Ingen følger %{username} endnu." 38 | feed: 39 | empty_feed_you: "Ingen indlæg fra personer, du følger endnu." 40 | empty_feed_other: "Ingen indlæg fra personer %{username} følger endnu." 41 | follow_notifications_options: 42 | notify_followed_user_when_followed: "Giv brugerne besked, når jeg følger dem" 43 | notify_me_when_followed: "Giv mig besked, når brugere følger mig" 44 | notify_me_when_followed_replies: "Giv mig besked, når nogen, jeg følger, svarer" 45 | notify_me_when_followed_creates_topic: "Giv mig besked, når en, jeg følger, opretter et emne" 46 | allow_people_to_follow_me: "Tillad folk at følge mig" 47 | follow: 48 | follow_pages_visibility: 49 | no-one: "Ingen" 50 | self: "Selv" 51 | trust_level_4: "Tillidsniveau 4" 52 | trust_level_3: "Tillidsniveau 3" 53 | trust_level_2: "Tillidsniveau 2" 54 | trust_level_1: "Tillidsniveau 1" 55 | trust_level_0: "Tillidsniveau 0" 56 | everyone: "Alle" 57 | follow_button_label: "Følg" 58 | unfollow_button_label: "Følg ikke længere" 59 | -------------------------------------------------------------------------------- /config/locales/client.de.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | de: 8 | admin_js: 9 | admin: 10 | site_settings: 11 | categories: 12 | discourse_follow: "Discourse – Folgen" 13 | js: 14 | notifications: 15 | following: "%{username} %{description}" 16 | following_description: "folgt dir jetzt." 17 | following_created_topic: "%{username} %{description}" 18 | following_replied: "%{username} %{description}" 19 | titles: 20 | following_created_topic: "neues Thema von jemandem, dem du folgst" 21 | following_replied: "neuer Beitrag von jemandem, dem du folgst" 22 | following: "jemand folgt dir jetzt" 23 | popup: 24 | following: "%{username} folgt dir jetzt." 25 | following_created_topic: '%{username} hat „%{topic}“ erstellt – %{site_title}' 26 | following_replied: '%{username} hat geschrieben in „%{topic}“ – %{site_title}' 27 | user: 28 | follow_nav: "Folgen" 29 | follow: 30 | label: "Folgen" 31 | following: 32 | feed_link: "Folgen-Feed" 33 | label: "Folge ich" 34 | none: "Du folgst noch niemandem." 35 | none_other: "%{username} folgt noch niemandem." 36 | followers: 37 | label: "Follower" 38 | none: "Es folgt dir noch niemand." 39 | none_other: "Bislang folgt noch niemand %{username}." 40 | feed: 41 | label: "Feed" 42 | empty_feed_you: "Noch keine Beiträge von Leuten, denen du folgst." 43 | empty_feed_other: "Noch keine Beiträge von Leuten, denen %{username} folgt." 44 | follow_notifications_options: 45 | notify_followed_user_when_followed: "Benutzer benachrichtigen, wenn ich ihnen folge" 46 | notify_me_when_followed: "Mich benachrichtigen, wenn mir Benutzer folgen" 47 | notify_me_when_followed_replies: "Mich benachrichtigen, wenn jemand, dem ich folge, antwortet" 48 | notify_me_when_followed_creates_topic: "Mich benachrichtigen, wenn jemand, dem ich folge, ein Thema erstellt" 49 | allow_people_to_follow_me: "Erlaube anderen, mir zu folgen" 50 | follow: 51 | follow_pages_visibility: 52 | no-one: "Niemand" 53 | self: "Ich selbst" 54 | trust_level_4: "Vertrauensstufe 4" 55 | trust_level_3: "Vertrauensstufe 3" 56 | trust_level_2: "Vertrauensstufe 2" 57 | trust_level_1: "Vertrauensstufe 1" 58 | trust_level_0: "Vertrauensstufe 0" 59 | everyone: "Jeder" 60 | follow_button_label: "Folgen" 61 | unfollow_button_label: "Entfolgen" 62 | -------------------------------------------------------------------------------- /config/locales/client.el.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | el: 8 | js: 9 | notifications: 10 | following: "%{username} %{description}" 11 | following_created_topic: "%{username} %{description}" 12 | following_replied: "%{username} %{description}" 13 | popup: 14 | following_replied: '%{username} ανάρτησε στο "%{topic}" - %{site_title}' 15 | follow: 16 | follow_pages_visibility: 17 | everyone: "Όλοι" 18 | -------------------------------------------------------------------------------- /config/locales/client.en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | admin_js: 3 | admin: 4 | site_settings: 5 | categories: 6 | discourse_follow: "Discourse Follow" 7 | js: 8 | notifications: 9 | following: "%{username} %{description}" 10 | following_description: "has started following you." 11 | following_created_topic: "%{username} %{description}" 12 | following_replied: "%{username} %{description}" 13 | titles: 14 | following_created_topic: "new topic from someone you are following" 15 | following_replied: "new post from someone you are following" 16 | following: "someone has started following you" 17 | popup: 18 | following: "%{username} has started following you." 19 | following_created_topic: '%{username} created "%{topic}" - %{site_title}' 20 | following_replied: '%{username} posted in "%{topic}" - %{site_title}' 21 | user: 22 | follow_nav: "Follows" 23 | follow: 24 | label: "Follow" 25 | following: 26 | feed_link: "Follow feed" 27 | label: "Following" 28 | none: "You're not following anyone yet." 29 | none_other: "%{username} is not following anyone yet." 30 | followers: 31 | label: "Followers" 32 | none: "No-one is following you yet." 33 | none_other: "No-one is following %{username} yet." 34 | feed: 35 | label: "Feed" 36 | empty_feed_you: "No posts by people you follow yet." 37 | empty_feed_other: "No posts by people %{username} follows yet." 38 | follow_notifications_options: 39 | notify_followed_user_when_followed: "Notify users when I follow them" 40 | notify_me_when_followed: "Notify me when users follow me" 41 | notify_me_when_followed_replies: "Notify me when someone I follow replies" 42 | notify_me_when_followed_creates_topic: "Notify me when someone I follow creates a topic" 43 | allow_people_to_follow_me: "Allow people to follow me" 44 | follow: 45 | follow_pages_visibility: 46 | no-one: "No one" 47 | self: "Self" 48 | trust_level_4: "Trust Level 4" 49 | trust_level_3: "Trust Level 3" 50 | trust_level_2: "Trust Level 2" 51 | trust_level_1: "Trust Level 1" 52 | trust_level_0: "Trust Level 0" 53 | everyone: "Everyone" 54 | follow_button_label: "Follow" 55 | unfollow_button_label: "Unfollow" 56 | -------------------------------------------------------------------------------- /config/locales/client.en_GB.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | en_GB: 8 | -------------------------------------------------------------------------------- /config/locales/client.es.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | es: 8 | admin_js: 9 | admin: 10 | site_settings: 11 | categories: 12 | discourse_follow: "Follow de Discourse" 13 | js: 14 | notifications: 15 | following: "%{username} %{description}" 16 | following_description: "ha comenzado a seguirte." 17 | following_created_topic: "%{username} %{description}" 18 | following_replied: "%{username} %{description}" 19 | titles: 20 | following_created_topic: "nuevo tema de alguien a quien sigues" 21 | following_replied: "nueva publicación de alguien a quien sigues" 22 | following: "alguien ha comenzado a seguirte" 23 | popup: 24 | following: "%{username} ha comenzado a seguirte." 25 | following_created_topic: '%{username} creó «%{topic}» - %{site_title}' 26 | following_replied: '%{username} publicó en «%{topic}» - %{site_title}' 27 | user: 28 | follow_nav: "Seguimientos" 29 | follow: 30 | label: "Seguir" 31 | following: 32 | feed_link: "Feed de seguimiento" 33 | label: "Siguiendo" 34 | none: "Aún no sigues a nadie." 35 | none_other: "%{username} aún no sigue a nadie." 36 | followers: 37 | label: "Seguidores" 38 | none: "Nadie te sigue todavía." 39 | none_other: "Nadie sigue a %{username} todavía." 40 | feed: 41 | label: "Feed" 42 | empty_feed_you: "Aún no hay publicaciones de personas a las que sigues." 43 | empty_feed_other: "Aún no hay publicaciones de personas a las que %{username} sigue." 44 | follow_notifications_options: 45 | notify_followed_user_when_followed: "Notificar a los usuarios al seguirlos." 46 | notify_me_when_followed: "Notificarme cuando los usuarios me siguen." 47 | notify_me_when_followed_replies: "Notificarme cuando alguien a quien sigo responde a un tema." 48 | notify_me_when_followed_creates_topic: "Notificarme cuando alguien a quien sigo crea un tema" 49 | allow_people_to_follow_me: "Permitir que la gente me siga" 50 | follow: 51 | follow_pages_visibility: 52 | no-one: "Nadie" 53 | self: "Uno mismo" 54 | trust_level_4: "Nivel de confianza 4" 55 | trust_level_3: "Nivel de confianza 3" 56 | trust_level_2: "Nivel de confianza 2" 57 | trust_level_1: "Nivel de confianza 1" 58 | trust_level_0: "Nivel de confianza 0" 59 | everyone: "Todos" 60 | follow_button_label: "Seguir" 61 | unfollow_button_label: "Dejar de seguir" 62 | -------------------------------------------------------------------------------- /config/locales/client.et.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | et: 8 | admin_js: 9 | admin: 10 | site_settings: 11 | categories: 12 | discourse_follow: "Discourse jälgimine" 13 | js: 14 | notifications: 15 | following: "%{username} %{description}" 16 | following_description: "on hakanud sind jälgima." 17 | following_created_topic: "%{username} %{description}" 18 | following_replied: "%{username} %{description}" 19 | titles: 20 | following_created_topic: "uus teema kelleltki, keda jälgite." 21 | following_replied: "uus postitus kelleltki, keda sa jälgid" 22 | following: "Keegi on hakanud sind jälgima" 23 | popup: 24 | following: "%{username} on hakanud sind jälgima." 25 | following_created_topic: '%{username} lõi "%{topic}" - %{site_title}' 26 | following_replied: '%{username} postitas teemasse "%{topic}" - %{site_title}' 27 | user: 28 | follow_nav: "Jälgib" 29 | follow: 30 | label: "Jälgi" 31 | following: 32 | feed_link: "Jälgi voogu" 33 | label: "Jälgin" 34 | none: "Sa ei jälgi veel kedagi." 35 | none_other: "%{username} ei jälgi veel kedagi." 36 | followers: 37 | label: "Jälgijad" 38 | none: "Keegi ei jälgi sind veel." 39 | none_other: "Keegi ei jälgi veel %{username}." 40 | feed: 41 | label: "Voog" 42 | empty_feed_you: "Pole veel ühtegi postitust inimestelt, keda sa jälgid." 43 | empty_feed_other: "Pole veel ühtegi postitust inimestelt, keda %{username} jälgib." 44 | follow_notifications_options: 45 | notify_followed_user_when_followed: "Teavita kasutajaid, kui ma neid jälgin" 46 | notify_me_when_followed: "Teavita mind, kui kasutajad mind jälgima hakkavad." 47 | notify_me_when_followed_replies: "Teavita mind, kui keegi, keda ma jälgin, vastab" 48 | notify_me_when_followed_creates_topic: "Anna mulle teada, kui keegi, keda jälgin, loob teema" 49 | allow_people_to_follow_me: "Luba inimestel mind jälgida" 50 | follow: 51 | follow_pages_visibility: 52 | no-one: "Mitte keegi" 53 | self: "Minu" 54 | trust_level_4: "Usaldustase 4" 55 | trust_level_3: "Usaldustase 3" 56 | trust_level_2: "Usaldustase 2" 57 | trust_level_1: "Usaldustase 1" 58 | trust_level_0: "Usaldustase 0" 59 | everyone: "Kõik" 60 | follow_button_label: "Jälgi" 61 | unfollow_button_label: "Lõpeta jälgimine" 62 | -------------------------------------------------------------------------------- /config/locales/client.fa_IR.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | fa_IR: 8 | js: 9 | notifications: 10 | following: "%{username} %{description}" 11 | following_created_topic: "%{username} %{description}" 12 | following_replied: "%{username} %{description}" 13 | popup: 14 | following_replied: '%{username} در "%{topic}" - %{site_title} مطلبی نوشت' 15 | follow: 16 | follow_pages_visibility: 17 | everyone: "همه" 18 | -------------------------------------------------------------------------------- /config/locales/client.fi.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | fi: 8 | admin_js: 9 | admin: 10 | site_settings: 11 | categories: 12 | discourse_follow: "Discourse Seuraa" 13 | js: 14 | notifications: 15 | following: "%{username} %{description}" 16 | following_description: "alkoi seurata sinua." 17 | following_created_topic: "%{username} %{description}" 18 | following_replied: "%{username} %{description}" 19 | titles: 20 | following_created_topic: "uusi ketju seuraamaltasi käyttäjältä" 21 | following_replied: "uusi viesti seuraamaltasi käyttäjältä" 22 | following: "joku alkoi seurata sinua" 23 | popup: 24 | following: "%{username} alkoi seurata sinua." 25 | following_created_topic: '%{username} loi ketjun "%{topic}" – %{site_title}' 26 | following_replied: '%{username} lähetti viestin ketjuun "%{topic}" – %{site_title}' 27 | user: 28 | follow_nav: "Seuraaminen" 29 | follow: 30 | label: "Seuraa" 31 | following: 32 | feed_link: "Seuraamissyöte" 33 | label: "Seurattavat" 34 | none: "Et seuraa vielä ketään." 35 | none_other: "%{username} ei seuraa vielä ketään." 36 | followers: 37 | label: "Seuraajat" 38 | none: "Kukaan ei seuraa sinua vielä." 39 | none_other: "Kukaan ei seuraa vielä käyttäjää %{username}." 40 | feed: 41 | label: "Syöte" 42 | empty_feed_you: "Ei vielä viestejä seuraamiltasi ihmisiltä." 43 | empty_feed_other: "Ei vielä viestejä käyttäjän %{username} seuraamilta ihmisiltä." 44 | follow_notifications_options: 45 | notify_followed_user_when_followed: "Ilmoita käyttäjille, kun seuraan heitä" 46 | notify_me_when_followed: "Ilmoita minulle, kun käyttäjät seuraavat minua" 47 | notify_me_when_followed_replies: "Ilmoita minulle, kun joku seuraamani vastaa" 48 | notify_me_when_followed_creates_topic: "Ilmoita minulle, kun joku seuraamani luo ketjun" 49 | allow_people_to_follow_me: "Salli ihmisten seurata minua" 50 | follow: 51 | follow_pages_visibility: 52 | no-one: "Ei kukaan" 53 | self: "Itse" 54 | trust_level_4: "Luottamustaso 4" 55 | trust_level_3: "Luottamustaso 3" 56 | trust_level_2: "Luottamustaso 2" 57 | trust_level_1: "Luottamustaso 1" 58 | trust_level_0: "Luottamustaso 0" 59 | everyone: "Kaikki" 60 | follow_button_label: "Seuraa" 61 | unfollow_button_label: "Lopeta seuraaminen" 62 | -------------------------------------------------------------------------------- /config/locales/client.fr.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | fr: 8 | admin_js: 9 | admin: 10 | site_settings: 11 | categories: 12 | discourse_follow: "Suivi de Discourse" 13 | js: 14 | notifications: 15 | following: "%{username} %{description}" 16 | following_description: "a commencé à vous suivre." 17 | following_created_topic: "%{username} %{description}" 18 | following_replied: "%{username} %{description}" 19 | titles: 20 | following_created_topic: "nouveau sujet d'une personne que vous suivez" 21 | following_replied: "nouveau message d'une personne que vous suivez" 22 | following: "quelqu'un a commencé à vous suivre" 23 | popup: 24 | following: "%{username} a commencé à vous suivre." 25 | following_created_topic: '%{username} a créé « %{topic} » - %{site_title}' 26 | following_replied: '%{username} a publié un message dans « %{topic} » - %{site_title}' 27 | user: 28 | follow_nav: "Suivis" 29 | follow: 30 | label: "Suivre" 31 | following: 32 | feed_link: "Fil de suivi" 33 | label: "Personnes suivies" 34 | none: "Vous ne suivez encore personne." 35 | none_other: "%{username} ne suit encore personne." 36 | followers: 37 | label: "Abonnés" 38 | none: "Personne ne vous suit encore." 39 | none_other: "Personne ne suit %{username} pour le moment." 40 | feed: 41 | label: "Flux" 42 | empty_feed_you: "Aucun message de personnes que vous suivez pour le moment." 43 | empty_feed_other: "Aucun message de personnes que %{username} suit pour le moment." 44 | follow_notifications_options: 45 | notify_followed_user_when_followed: "Avertir les utilisateurs lorsque je les suis" 46 | notify_me_when_followed: "M'avertir lorsque des utilisateurs me suivent" 47 | notify_me_when_followed_replies: "M'avertir lorsque quelqu'un que je suis répond" 48 | notify_me_when_followed_creates_topic: "M'avertir lorsqu'une personne que je suis crée un sujet" 49 | allow_people_to_follow_me: "Autoriser les autres utilisateurs à me suivre" 50 | follow: 51 | follow_pages_visibility: 52 | no-one: "Personne" 53 | self: "Vous" 54 | trust_level_4: "Niveau de confiance 4" 55 | trust_level_3: "Niveau de confiance 3" 56 | trust_level_2: "Niveau de confiance 2" 57 | trust_level_1: "Niveau de confiance 1" 58 | trust_level_0: "Niveau de confiance 0" 59 | everyone: "Tout le monde" 60 | follow_button_label: "Suivre" 61 | unfollow_button_label: "Ne plus suivre" 62 | -------------------------------------------------------------------------------- /config/locales/client.gl.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | gl: 8 | js: 9 | notifications: 10 | following: "%{username} %{description}" 11 | following_created_topic: "%{username} %{description}" 12 | following_replied: "%{username} %{description}" 13 | popup: 14 | following_replied: '%{username} publicou en "%{topic}" - %{site_title}' 15 | follow: 16 | follow_pages_visibility: 17 | everyone: "Todos" 18 | -------------------------------------------------------------------------------- /config/locales/client.he.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | he: 8 | admin_js: 9 | admin: 10 | site_settings: 11 | categories: 12 | discourse_follow: "Discourse מעקב" 13 | js: 14 | notifications: 15 | following: "%{username} %{description}" 16 | following_description: "התחיל לעקוב אחריך." 17 | following_created_topic: "%{username} %{description}" 18 | following_replied: "%{username} %{description}" 19 | titles: 20 | following_created_topic: "נושא חדש ממישהו ברשימת המעקב שלך" 21 | following_replied: "פוסט חדש ממישהו ברשימת המעקב שלך" 22 | following: "מישהו התחיל לעקוב אחריך" 23 | popup: 24 | following: "%{username} התחיל לעקוב אחריך." 25 | following_created_topic: '„%{topic}” נוצר על ידי %{username}‏ - %{site_title}' 26 | following_replied: '%{username} הגיב ב"%{topic}" - %{site_title}' 27 | user: 28 | follow_nav: "עוקבים ונעקבים" 29 | follow: 30 | label: "עקוב" 31 | following: 32 | feed_link: "ערוץ עדכוני מעקב" 33 | label: "עוקב אחרי" 34 | none: "אין לך כלום ברשימת המעקב." 35 | none_other: "%{username} לא עוקב אחרי אף אחד.." 36 | followers: 37 | label: "עוקבים" 38 | none: "אף אחד לא עוקב אחריך." 39 | none_other: "אף אחד לא עוקב אחרי %{username}." 40 | feed: 41 | label: "ערוץ עדכונים" 42 | empty_feed_you: "אין פוסטים מאת אנשים ברשימת המעקב שלך." 43 | empty_feed_other: "אין פוסטים מאת אנשים ברשימת המעקב של %{username}." 44 | follow_notifications_options: 45 | notify_followed_user_when_followed: "להודיע למשתמשים כשהחלתי מעקב אחריהם." 46 | notify_me_when_followed: "הודע לי כשמשתמשים עוקבים אחריי." 47 | notify_me_when_followed_replies: "הודע לי כשמישהו שאני עוקב אחריו מגיב." 48 | notify_me_when_followed_creates_topic: "להודיע לי כשמישהו מרשימת המעקב שלי יוצר נושא" 49 | allow_people_to_follow_me: "לאפשר לאנשים לעקוב אחרי" 50 | follow: 51 | follow_pages_visibility: 52 | no-one: "אף אחד" 53 | self: "עצמי" 54 | trust_level_4: "דרגת אמון 4" 55 | trust_level_3: "דרגת אמון 3" 56 | trust_level_2: "דרגת אמון 2" 57 | trust_level_1: "דרגת אמון 1" 58 | trust_level_0: "דרגת אמון 0" 59 | everyone: "כולם" 60 | follow_button_label: "עקוב" 61 | unfollow_button_label: "ביטול מעקב" 62 | -------------------------------------------------------------------------------- /config/locales/client.hr.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | hr: 8 | js: 9 | notifications: 10 | following: "%{username} %{description}" 11 | following_created_topic: "%{username} %{description}" 12 | following_replied: "%{username} %{description}" 13 | popup: 14 | following_replied: '%{username} objavio u "%{topic}" - %{site_title}' 15 | follow: 16 | follow_pages_visibility: 17 | everyone: "Svi" 18 | -------------------------------------------------------------------------------- /config/locales/client.hu.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | hu: 8 | js: 9 | notifications: 10 | following: "%{username} %{description}" 11 | following_description: "elkezdett követni téged." 12 | following_created_topic: "%{username}%{description}" 13 | following_replied: "%{username} %{description}" 14 | popup: 15 | following: "%{username} elkezdett követni téged." 16 | following_replied: '%{username} közzétett "%{topic}" - %{site_title}' 17 | user: 18 | follow_nav: "Közösség" 19 | follow: 20 | label: "Követés" 21 | following: 22 | label: "Követett" 23 | none: "Még nem követsz senkit." 24 | none_other: "%{username} még nem követ senkit." 25 | followers: 26 | label: "Követő" 27 | none: "Még senki nem követ téged." 28 | none_other: "Még senki nem követi %{username}." 29 | follow_notifications_options: 30 | notify_followed_user_when_followed: "Értesítsd a felhasználókat, ha elkezdem követni őket." 31 | notify_me_when_followed: "Értesíts amikor elkezdenek követni." 32 | notify_me_when_followed_replies: "Értesíts, ha akit követek, válaszol egy bejegyzésre." 33 | follow: 34 | follow_pages_visibility: 35 | everyone: "Mindenki" 36 | follow_button_label: "Követés" 37 | -------------------------------------------------------------------------------- /config/locales/client.hy.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | hy: 8 | js: 9 | notifications: 10 | following: "%{username} %{description}" 11 | following_created_topic: "%{username} %{description}" 12 | following_replied: "%{username} %{description}" 13 | popup: 14 | following_replied: '%{username} -ը գրառում է կատարել այստեղ՝ "%{topic}" - %{site_title}' 15 | follow: 16 | follow_pages_visibility: 17 | everyone: "Բոլորը" 18 | -------------------------------------------------------------------------------- /config/locales/client.id.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | id: 8 | js: 9 | follow: 10 | follow_pages_visibility: 11 | everyone: "Semua orang" 12 | -------------------------------------------------------------------------------- /config/locales/client.it.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | it: 8 | admin_js: 9 | admin: 10 | site_settings: 11 | categories: 12 | discourse_follow: "Discourse Follow" 13 | js: 14 | notifications: 15 | following: "%{username} %{description}" 16 | following_description: "ha iniziato a seguirti." 17 | following_created_topic: "%{username} %{description}" 18 | following_replied: "%{username} %{description}" 19 | titles: 20 | following_created_topic: "nuovo argomento da qualcuno che segui" 21 | following_replied: "nuovo messaggio da qualcuno che segui" 22 | following: "qualcuno ha iniziato a seguirti" 23 | popup: 24 | following: "%{username} ha iniziato a seguirti." 25 | following_created_topic: '%{username} ha creato "%{topic}" - %{site_title}' 26 | following_replied: '%{username} ha risposto in "%{topic}" - %{site_title}' 27 | user: 28 | follow_nav: "Segue" 29 | follow: 30 | label: "Segui" 31 | following: 32 | feed_link: "Segui feed" 33 | label: "Segui" 34 | none: "Non stai ancora seguendo nessuno." 35 | none_other: "%{username} non sta ancora seguendo nessuno." 36 | followers: 37 | label: "Follower" 38 | none: "Nessuno ti sta ancora seguendo." 39 | none_other: "Nessuno sta ancora seguendo %{username}." 40 | feed: 41 | label: "Feed" 42 | empty_feed_you: "Ancora nessun messaggio da persone che segui." 43 | empty_feed_other: "Ancora nessun messaggio da persone seguite da %{username}." 44 | follow_notifications_options: 45 | notify_followed_user_when_followed: "Notifica gli utenti se inizio a seguirli" 46 | notify_me_when_followed: "Notificami se altri utenti iniziano a seguirmi" 47 | notify_me_when_followed_replies: "Notificami se qualcuno che seguo risponde." 48 | notify_me_when_followed_creates_topic: "Notificami se qualcuno che seguo crea un argomento" 49 | allow_people_to_follow_me: "Consenti alle persone di seguirmi" 50 | follow: 51 | follow_pages_visibility: 52 | no-one: "Nessuno" 53 | self: "Solo io" 54 | trust_level_4: "Livello di attendibilità 4" 55 | trust_level_3: "Livello di attendibilità 3" 56 | trust_level_2: "Livello di attendibilità 2" 57 | trust_level_1: "Livello di attendibilità 1" 58 | trust_level_0: "Livello di attendibilità 0" 59 | everyone: "Chiunque" 60 | follow_button_label: "Segui" 61 | unfollow_button_label: "Smetti di seguire" 62 | -------------------------------------------------------------------------------- /config/locales/client.ja.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | ja: 8 | admin_js: 9 | admin: 10 | site_settings: 11 | categories: 12 | discourse_follow: "Discourse フォロー" 13 | js: 14 | notifications: 15 | following: "%{username} %{description}" 16 | following_description: "があなたをフォローし始めました。" 17 | following_created_topic: "%{username} %{description}" 18 | following_replied: "%{username} %{description}" 19 | titles: 20 | following_created_topic: "あなたがフォローしている人の新しいトピック" 21 | following_replied: "あなたがフォローしている人の新しい投稿" 22 | following: "誰かがあなたをフォローし始めました" 23 | popup: 24 | following: "%{username} があなたをフォローし始めました。" 25 | following_created_topic: '%{username} が「%{topic}」を作成しました - %{site_title}' 26 | following_replied: '%{username} が「%{topic}」に投稿しました - %{site_title}' 27 | user: 28 | follow_nav: "フォロー" 29 | follow: 30 | label: "フォロー" 31 | following: 32 | feed_link: "フィードをフォロー" 33 | label: "フォロー中" 34 | none: "まだ誰もフォローしていません。" 35 | none_other: "%{username} はまだ誰もフォローしていません。" 36 | followers: 37 | label: "フォロワー" 38 | none: "まだ誰もあなたをフォローしていません。" 39 | none_other: "まだ誰も %{username} をフォローしていません。" 40 | feed: 41 | label: "フィード" 42 | empty_feed_you: "あなたがフォローしている人の投稿はまだありません。" 43 | empty_feed_other: "%{username} がフォローしている人の投稿はまだありません。" 44 | follow_notifications_options: 45 | notify_followed_user_when_followed: "フォローしたらそのユーザーに通知する" 46 | notify_me_when_followed: "ユーザーが自分をフォローしたら通知する" 47 | notify_me_when_followed_replies: "フォローしている人が返信したら通知する" 48 | notify_me_when_followed_creates_topic: "フォローしている人がトピックを作成したら通知する" 49 | allow_people_to_follow_me: "他のユーザーにフォローを許可する" 50 | follow: 51 | follow_pages_visibility: 52 | no-one: "誰にも表示しない" 53 | self: "自分" 54 | trust_level_4: "信頼レベル 4" 55 | trust_level_3: "信頼レベル 3" 56 | trust_level_2: "信頼レベル 2" 57 | trust_level_1: "信頼レベル 1" 58 | trust_level_0: "信頼レベル 0" 59 | everyone: "全員" 60 | follow_button_label: "フォロー" 61 | unfollow_button_label: "フォロー解除" 62 | -------------------------------------------------------------------------------- /config/locales/client.ko.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | ko: 8 | js: 9 | notifications: 10 | following: "%{username} %{description}" 11 | following_description: "님이 당신을 팔로우하기 시작했습니다." 12 | following_created_topic: "%{username} %{description}" 13 | following_replied: "%{username} %{description}" 14 | titles: 15 | following_created_topic: "팔로우 중인 사람의 새 주제" 16 | following_replied: "팔로우 중인 사람의 새 게시물" 17 | following: "누군가 당신을 팔로우하기 시작했습니다" 18 | popup: 19 | following: "%{username}님이 당신을 팔로우하기 시작했습니다." 20 | following_replied: '"%{topic}"에서 %{username}님이 글을 게시하였습니다 - %{site_title}' 21 | user: 22 | follow_nav: "팔로우" 23 | follow: 24 | label: "팔로우" 25 | following: 26 | feed_link: "팔로우 피드" 27 | label: "팔로잉" 28 | none: "아직 팔로우 중인 사람이 없습니다." 29 | followers: 30 | label: "팔로워" 31 | none: "아직 아무도 당신을 팔로우하고 있지 않습니다." 32 | none_other: "아직 아무도 %{username}을/를 팔로우하고 있지 않습니다." 33 | feed: 34 | label: "피드" 35 | follow_notifications_options: 36 | notify_me_when_followed_replies: "내가 팔로우하는 사람이 답글을 달면 알림" 37 | notify_me_when_followed_creates_topic: "내가 팔로우하는 사람이 주제를 만들면 알림" 38 | allow_people_to_follow_me: "사람들이 나를 팔로우하도록 허용" 39 | follow: 40 | follow_pages_visibility: 41 | no-one: "아무도" 42 | self: "본인" 43 | trust_level_4: "회원등급 4" 44 | trust_level_3: "회원등급 3" 45 | trust_level_2: "회원등급 2" 46 | trust_level_1: "회원등급 1" 47 | trust_level_0: "회원등급 0" 48 | everyone: "모든 사람" 49 | follow_button_label: "팔로우" 50 | unfollow_button_label: "언팔로우" 51 | -------------------------------------------------------------------------------- /config/locales/client.lt.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | lt: 8 | js: 9 | notifications: 10 | following: "%{username} %{description}" 11 | following_created_topic: "%{username} %{description}" 12 | following_replied: "%{username} %{description}" 13 | popup: 14 | following_replied: '%{username} paskelbė "%{topic}" - %{site_title}' 15 | follow: 16 | follow_pages_visibility: 17 | everyone: "Visi" 18 | -------------------------------------------------------------------------------- /config/locales/client.lv.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | lv: 8 | js: 9 | notifications: 10 | popup: 11 | following_replied: '%{username} ierakstīja "%{topic}" - %{site_title}' 12 | follow: 13 | follow_pages_visibility: 14 | everyone: "Ikviens" 15 | -------------------------------------------------------------------------------- /config/locales/client.nb_NO.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | nb_NO: 8 | js: 9 | notifications: 10 | following: "%{username} %{description}" 11 | following_created_topic: "%{username} %{description}" 12 | following_replied: "%{username} %{description}" 13 | popup: 14 | following_replied: '%{username} skrev noe i "%{topic}" - %{site_title}' 15 | follow: 16 | follow_pages_visibility: 17 | everyone: "Alle" 18 | -------------------------------------------------------------------------------- /config/locales/client.nl.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | nl: 8 | admin_js: 9 | admin: 10 | site_settings: 11 | categories: 12 | discourse_follow: "Discourse Follow" 13 | js: 14 | notifications: 15 | following: "%{username} %{description}" 16 | following_description: "is je gaan volgen." 17 | following_created_topic: "%{username} %{description}" 18 | following_replied: "%{username} %{description}" 19 | titles: 20 | following_created_topic: "nieuw topic van iemand die je volgt" 21 | following_replied: "nieuwe bericht van iemand die je volgt" 22 | following: "iemand is je gaan volgen" 23 | popup: 24 | following: "%{username} is je gaan volgen." 25 | following_created_topic: '%{username} heeft ''%{topic}'' gemaakt - %{site_title}' 26 | following_replied: '%{username} heeft een bericht geplaatst in ''%{topic}'' - %{site_title}' 27 | user: 28 | follow_nav: "Volgt" 29 | follow: 30 | label: "Volgen" 31 | following: 32 | feed_link: "Volgfeed" 33 | label: "Volgend" 34 | none: "Je volgt nog niemand." 35 | none_other: "%{username} volgt nog niemand." 36 | followers: 37 | label: "Volgers" 38 | none: "Niemand volgt je nog." 39 | none_other: "Niemand volgt %{username} nog." 40 | feed: 41 | label: "Feed" 42 | empty_feed_you: "Nog geen berichten van mensen die je volgt." 43 | empty_feed_other: "Nog geen berichten van mensen die %{username} volgt." 44 | follow_notifications_options: 45 | notify_followed_user_when_followed: "Laat gebruikers weten wanneer ik ze volg" 46 | notify_me_when_followed: "Laat me weten wanneer gebruikers me volgen" 47 | notify_me_when_followed_replies: "Laat me weten wanneer iemand die ik volg antwoordt" 48 | notify_me_when_followed_creates_topic: "Laat me weten wanneer iemand die ik volg een topic maakt" 49 | allow_people_to_follow_me: "Sta mensen toe mij te volgen" 50 | follow: 51 | follow_pages_visibility: 52 | no-one: "Niemand" 53 | self: "Zelf" 54 | trust_level_4: "Vertrouwensniveau 4" 55 | trust_level_3: "Vertrouwensniveau 3" 56 | trust_level_2: "Vertrouwensniveau 2" 57 | trust_level_1: "Vertrouwensniveau 1" 58 | trust_level_0: "Vertrouwensniveau 0" 59 | everyone: "Iedereen" 60 | follow_button_label: "Volgen" 61 | unfollow_button_label: "Ontvolgen" 62 | -------------------------------------------------------------------------------- /config/locales/client.pl_PL.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | pl_PL: 8 | js: 9 | notifications: 10 | following: "%{username} %{description}" 11 | following_description: "zaczął Cię obserwować." 12 | following_created_topic: "%{username} %{description}" 13 | following_replied: "%{username} %{description}" 14 | titles: 15 | following_created_topic: "nowy temat od kogoś, kogo obserwujesz" 16 | following_replied: "nowy post od kogoś, kogo obserwujesz" 17 | following: "ktoś zaczął Cię obserwować" 18 | popup: 19 | following: "%{username} zaczął Cię obserwować." 20 | following_created_topic: '%{username} utworzył(a) "%{topic}" - %{site_title}' 21 | following_replied: '%{username} napisał(a) w "%{topic}" - %{site_title}' 22 | user: 23 | follow_nav: "Obserwuje" 24 | follow: 25 | label: "Obserwuj" 26 | following: 27 | feed_link: "Kanał obserwowanych" 28 | label: "Obserwuje" 29 | none: "Jeszcze nikogo nie obserwujesz." 30 | none_other: "%{username} jeszcze nikogo nie obserwuje." 31 | followers: 32 | label: "Obserwujący" 33 | none: "Nikt Cię jeszcze nie obserwuje." 34 | none_other: "Nikt nie obserwuje jeszcze %{username}." 35 | feed: 36 | label: "Kanał" 37 | empty_feed_you: "Nie ma jeszcze postów osób, które obserwujesz." 38 | empty_feed_other: "Brak postów od osób, które %{username} obserwuje." 39 | follow_notifications_options: 40 | notify_followed_user_when_followed: "Powiadamiaj użytkowników, gdy ich zaobserwuję" 41 | notify_me_when_followed: "Powiadom mnie, gdy użytkownicy mnie obserwują" 42 | notify_me_when_followed_replies: "Powiadom mnie, gdy ktoś, kogo śledzę, odpowiada" 43 | notify_me_when_followed_creates_topic: "Powiadom mnie, gdy ktoś, kogo obserwuję, utworzy temat" 44 | allow_people_to_follow_me: "Pozwól ludziom mnie obserwować" 45 | follow: 46 | follow_pages_visibility: 47 | no-one: "Nikt" 48 | self: "Tylko ja" 49 | trust_level_4: "Poziom zaufania 4" 50 | trust_level_3: "Poziom zaufania 3" 51 | trust_level_2: "Poziom zaufania 2" 52 | trust_level_1: "Poziom zaufania 1" 53 | trust_level_0: "Poziom zaufania 0" 54 | everyone: "Wszyscy" 55 | follow_button_label: "Obserwuj" 56 | unfollow_button_label: "Przestań obserwować" 57 | -------------------------------------------------------------------------------- /config/locales/client.pt.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | pt: 8 | js: 9 | notifications: 10 | following: "%{username} %{description}" 11 | following_created_topic: "%{username} %{description}" 12 | following_replied: "%{username} %{description}" 13 | popup: 14 | following_replied: '%{username} publicou em "%{topic}" - %{site_title}' 15 | follow: 16 | follow_pages_visibility: 17 | everyone: "Todos" 18 | -------------------------------------------------------------------------------- /config/locales/client.pt_BR.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | pt_BR: 8 | admin_js: 9 | admin: 10 | site_settings: 11 | categories: 12 | discourse_follow: "Discourse Follow" 13 | js: 14 | notifications: 15 | following: "%{username} %{description}" 16 | following_description: "começou a segui-lo(a)." 17 | following_created_topic: "%{username} %{description}" 18 | following_replied: "%{username} %{description}" 19 | titles: 20 | following_created_topic: "novo tópico de alguém que você está seguindo" 21 | following_replied: "nova postagem de alguém que você está seguindo" 22 | following: "você começou a ser seguido(a) por alguém" 23 | popup: 24 | following: "%{username} começou a segui-lo(a)." 25 | following_created_topic: '%{username} criou "%{topic}" - %{site_title}' 26 | following_replied: '%{username} respondeu a "%{topic}" - %{site_title}' 27 | user: 28 | follow_nav: "Rede" 29 | follow: 30 | label: "Seguir" 31 | following: 32 | feed_link: "Seguir feed" 33 | label: "Seguindo" 34 | none: "Você ainda não está seguindo ninguém." 35 | none_other: "%{username} ainda não está seguindo ninguém." 36 | followers: 37 | label: "Seguidores" 38 | none: "Ninguém está te seguindo ainda." 39 | none_other: "Ninguém está seguindo %{username} ainda." 40 | feed: 41 | label: "Feed" 42 | empty_feed_you: "Ainda nenhuma postagem de pessoas que você segue." 43 | empty_feed_other: "Ainda nenhuma postagem de pessoas que %{username} segue." 44 | follow_notifications_options: 45 | notify_followed_user_when_followed: "Notificar os usuários quando eu os seguir." 46 | notify_me_when_followed: "Notificar-me quando usuários me seguirem." 47 | notify_me_when_followed_replies: "Notificar-me quando alguém que eu sigo responder." 48 | notify_me_when_followed_creates_topic: "Notificar-me quando alguém que eu sigo criar um tópico." 49 | allow_people_to_follow_me: "Permitir que me sigam" 50 | follow: 51 | follow_pages_visibility: 52 | no-one: "Ninguém" 53 | self: "Eu" 54 | trust_level_4: "Nível de confiança 4" 55 | trust_level_3: "Nível de confiança 3" 56 | trust_level_2: "Nível de confiança 2" 57 | trust_level_1: "Nível de confiança 1" 58 | trust_level_0: "Nível de confiança 0" 59 | everyone: "Todos(as)" 60 | follow_button_label: "Seguir" 61 | unfollow_button_label: "Parar de seguir" 62 | -------------------------------------------------------------------------------- /config/locales/client.ro.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | ro: 8 | js: 9 | notifications: 10 | following: "%{username} %{description}" 11 | following_created_topic: "%{username} %{description}" 12 | following_replied: "%{username} %{description}" 13 | popup: 14 | following_replied: '%{username} a postat în discuția "%{topic}" - %{site_title}' 15 | follow: 16 | follow_pages_visibility: 17 | everyone: "Toată lumea" 18 | -------------------------------------------------------------------------------- /config/locales/client.ru.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | ru: 8 | admin_js: 9 | admin: 10 | site_settings: 11 | categories: 12 | discourse_follow: "Плагин Discourse «Подписка»" 13 | js: 14 | notifications: 15 | following: "%{username} %{description}" 16 | following_description: "подписался(-ась) на вас." 17 | following_created_topic: "%{username} %{description}" 18 | following_replied: "%{username} %{description}" 19 | titles: 20 | following_created_topic: "новая тема от того, на кого вы подписаны" 21 | following_replied: "новая запись от того, на кого вы подписаны" 22 | following: "кто-то подписался на вас" 23 | popup: 24 | following: "%{username} подписался(-ась) на вас." 25 | following_created_topic: '%{username} создал(а) тему «%{topic}» — %{site_title}' 26 | following_replied: '%{username} написал(а) в теме «%{topic}» — %{site_title}' 27 | user: 28 | follow_nav: "Подписан(а)" 29 | follow: 30 | label: "Подписаться" 31 | following: 32 | feed_link: "Лента новостей по подпискам" 33 | label: "Подписан(а) на" 34 | none: "Вы пока ни на кого не подписаны." 35 | none_other: "%{username} пока ни на кого не подписан(-а)." 36 | followers: 37 | label: "Подписчики" 38 | none: "На вас пока никто не подписался." 39 | none_other: "Никто не подписан на %{username}." 40 | feed: 41 | label: "Лента" 42 | empty_feed_you: "Записей от пользователей, на которых вы подписаны, пока что нет." 43 | empty_feed_other: "Записей от пользователей в подписках %{username} пока что нет." 44 | follow_notifications_options: 45 | notify_followed_user_when_followed: "Уведомлять пользователей, когда я на них подписываюсь" 46 | notify_me_when_followed: "Уведомлять, когда подписываются на меня" 47 | notify_me_when_followed_replies: "Уведомлять, когда кто-то из моих подписок отвечает" 48 | notify_me_when_followed_creates_topic: "Уведомлять, когда кто-то из моих подписок создает тему" 49 | allow_people_to_follow_me: "Разрешить подписываться на меня" 50 | follow: 51 | follow_pages_visibility: 52 | no-one: "Никто" 53 | self: "Только я" 54 | trust_level_4: "Уровень доверия 4" 55 | trust_level_3: "Уровень доверия 3" 56 | trust_level_2: "Уровень доверия 2" 57 | trust_level_1: "Уровень доверия 1" 58 | trust_level_0: "Уровень доверия 0" 59 | everyone: "Все" 60 | follow_button_label: "Подписаться" 61 | unfollow_button_label: "Отписаться" 62 | -------------------------------------------------------------------------------- /config/locales/client.sk.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | sk: 8 | js: 9 | notifications: 10 | following: "%{username} %{description}" 11 | following_created_topic: "%{username} %{description}" 12 | following_replied: "%{username} %{description}" 13 | popup: 14 | following_replied: '%{username} prispel v "%{topic}" - %{site_title}' 15 | follow: 16 | follow_pages_visibility: 17 | everyone: "Každý" 18 | -------------------------------------------------------------------------------- /config/locales/client.sl.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | sl: 8 | js: 9 | notifications: 10 | following: "%{username} %{description}" 11 | following_created_topic: "%{username} %{description}" 12 | following_replied: "%{username} %{description}" 13 | popup: 14 | following_replied: '%{username} je objavil v "%{topic}" - %{site_title}' 15 | follow: 16 | follow_pages_visibility: 17 | everyone: "Vsi" 18 | -------------------------------------------------------------------------------- /config/locales/client.sq.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | sq: 8 | js: 9 | notifications: 10 | popup: 11 | following_replied: '%{username} postoi në "%{topic}" - %{site_title}' 12 | follow: 13 | follow_pages_visibility: 14 | everyone: "Të gjithë" 15 | -------------------------------------------------------------------------------- /config/locales/client.sr.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | sr: 8 | js: 9 | follow: 10 | follow_pages_visibility: 11 | everyone: "Svi" 12 | -------------------------------------------------------------------------------- /config/locales/client.sv.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | sv: 8 | js: 9 | notifications: 10 | following: "%{username} %{description}" 11 | following_description: "har börjat följa dig." 12 | following_created_topic: "%{username} %{description}" 13 | following_replied: "%{username} %{description}" 14 | titles: 15 | following_created_topic: "nytt ämne från någon du följer" 16 | following_replied: "nytt inlägg från någon du följer" 17 | following: "någon har börjat följa dig" 18 | popup: 19 | following: "%{username} har börjat följa dig." 20 | following_created_topic: '%{username} skapade "%{topic}" - %{site_title}' 21 | following_replied: '%{username} skrev inlägg i "%{topic}" - %{site_title}' 22 | user: 23 | follow_nav: "Följer" 24 | follow: 25 | label: "Följ" 26 | following: 27 | feed_link: "Följ flöde" 28 | label: "Följer" 29 | none: "Du följer inte någon ännu." 30 | none_other: "%{username} följer inte någon ännu." 31 | followers: 32 | label: "Följare" 33 | none: "Ingen följer dig än." 34 | none_other: "Ingen följer %{username} ännu." 35 | feed: 36 | label: "Flöde" 37 | empty_feed_you: "Inga inlägg av personer du följer ännu." 38 | empty_feed_other: "Inga inlägg ännu av personer %{username} följer." 39 | follow_notifications_options: 40 | notify_followed_user_when_followed: "Meddela användare när jag följer dem" 41 | notify_me_when_followed: "Meddela mig när användare följer mig" 42 | notify_me_when_followed_replies: "Meddela mig när någon jag följer svarar" 43 | notify_me_when_followed_creates_topic: "Meddela mig när någon jag följer skapar ett ämne" 44 | allow_people_to_follow_me: "Tillåt att folk följer mig" 45 | follow: 46 | follow_pages_visibility: 47 | no-one: "Ingen" 48 | self: "Själv" 49 | trust_level_4: "Förtroendenivå 4" 50 | trust_level_3: "Förtroendenivå 3" 51 | trust_level_2: "Förtroendenivå 2" 52 | trust_level_1: "Förtroendenivå 1" 53 | trust_level_0: "Förtroendenivå 0" 54 | everyone: "Alla" 55 | follow_button_label: "Följ" 56 | unfollow_button_label: "Sluta följa" 57 | -------------------------------------------------------------------------------- /config/locales/client.sw.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | sw: 8 | js: 9 | follow: 10 | follow_pages_visibility: 11 | everyone: "Kila Mtu" 12 | -------------------------------------------------------------------------------- /config/locales/client.te.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | te: 8 | js: 9 | notifications: 10 | following: "%{username} %{description}" 11 | following_created_topic: "%{username} %{description}" 12 | following_replied: "%{username} %{description}" 13 | popup: 14 | following_replied: '%{username} "%{topic}"- %{site_title}లో పోస్ట్ చేసారు' 15 | follow: 16 | follow_pages_visibility: 17 | everyone: "అందరూ" 18 | -------------------------------------------------------------------------------- /config/locales/client.th.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | th: 8 | js: 9 | notifications: 10 | following: "%{username}%{description}" 11 | following_created_topic: "%{username}%{description}" 12 | following_replied: "%{username}%{description}" 13 | popup: 14 | following_replied: '%{username} โพสท์ใน "%{topic}" - %{site_title}' 15 | follow: 16 | follow_pages_visibility: 17 | everyone: "ทุกคน" 18 | -------------------------------------------------------------------------------- /config/locales/client.tr_TR.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | tr_TR: 8 | admin_js: 9 | admin: 10 | site_settings: 11 | categories: 12 | discourse_follow: "Discourse Takip" 13 | js: 14 | notifications: 15 | following: "%{username} %{description}" 16 | following_description: "sizi takip etmeye başladı." 17 | following_created_topic: "%{username} %{description}" 18 | following_replied: "%{username} %{description}" 19 | titles: 20 | following_created_topic: "takip ettiğiniz birinden yeni konu" 21 | following_replied: "takip ettiğiniz birinden yeni gönderi" 22 | following: "biri sizi takip etmeye başladı" 23 | popup: 24 | following: "%{username} sizi takip etmeye başladı." 25 | following_created_topic: '%{username} "%{topic}" adlı bir konu oluşturdu - %{site_title}' 26 | following_replied: '%{username}, "%{topic}" konusuna gönderi yaptı - %{site_title}' 27 | user: 28 | follow_nav: "Takip ediyor" 29 | follow: 30 | label: "Takip et" 31 | following: 32 | feed_link: "Akışı takip et" 33 | label: "Takip ediliyor" 34 | none: "Henüz kimseyi takip etmiyorsunuz." 35 | none_other: "%{username} henüz kimseyi takip etmiyor." 36 | followers: 37 | label: "Takipçiler" 38 | none: "Henüz kimse sizi takip etmiyor." 39 | none_other: "Henüz kimse %{username} adlı kullanıcıyı takip etmiyor." 40 | feed: 41 | label: "Akış" 42 | empty_feed_you: "Takip ettiğiniz kişilerden henüz gönderi yok." 43 | empty_feed_other: "Henüz %{username} adlı kullanıcının takip ettiği kişilerden gönderi yok." 44 | follow_notifications_options: 45 | notify_followed_user_when_followed: "Takip ettiğimde kullanıcıları bilgilendir" 46 | notify_me_when_followed: "Kullanıcılar beni takip ettiğinde bana bildir" 47 | notify_me_when_followed_replies: "Takip ettiğim biri yanıt verdiğinde bana bildir" 48 | notify_me_when_followed_creates_topic: "Takip ettiğim biri bir konu oluşturduğunda bana bildir" 49 | allow_people_to_follow_me: "Kişilerin beni takip etmesine izin ver" 50 | follow: 51 | follow_pages_visibility: 52 | no-one: "Kimse" 53 | self: "Kendim" 54 | trust_level_4: "Güven Seviyesi 4" 55 | trust_level_3: "Güven Seviyesi 3" 56 | trust_level_2: "Güven Seviyesi 2" 57 | trust_level_1: "Güven Seviyesi 1" 58 | trust_level_0: "Güven Seviyesi 0" 59 | everyone: "Herkes" 60 | follow_button_label: "Takip et" 61 | unfollow_button_label: "Takibi bırak" 62 | -------------------------------------------------------------------------------- /config/locales/client.ug.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | ug: 8 | js: 9 | notifications: 10 | following: "%{username} %{description}" 11 | following_created_topic: "%{username} %{description}" 12 | following_replied: "%{username} %{description}" 13 | popup: 14 | following_replied: '%{username} «%{topic}» - %{site_title} غا يوللىدى' 15 | follow: 16 | follow_pages_visibility: 17 | everyone: "ھەممەيلەن" 18 | -------------------------------------------------------------------------------- /config/locales/client.uk.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | uk: 8 | js: 9 | notifications: 10 | following: "%{username} %{description}" 11 | following_created_topic: "%{username} %{description}" 12 | following_replied: "%{username} %{description}" 13 | popup: 14 | following_replied: '%{username} опублікував в "%{topic}" - %{site_title}' 15 | follow: 16 | follow_pages_visibility: 17 | everyone: "Усі" 18 | -------------------------------------------------------------------------------- /config/locales/client.ur.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | ur: 8 | js: 9 | notifications: 10 | following: "%{username} %{description}" 11 | following_created_topic: "%{username} %{description}" 12 | following_replied: "%{username} %{description}" 13 | popup: 14 | following_replied: '%{username} نے "%{topic}" میں پوسٹ کیا - %{site_title}' 15 | follow: 16 | follow_pages_visibility: 17 | everyone: "ہر کوئی" 18 | -------------------------------------------------------------------------------- /config/locales/client.vi.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | vi: 8 | js: 9 | notifications: 10 | following: "%{username} %{description}" 11 | following_created_topic: "%{username} %{description}" 12 | following_replied: "%{username} %{description}" 13 | popup: 14 | following_replied: '%{username} gửi bài trong "%{topic}" - %{site_title}' 15 | follow: 16 | follow_pages_visibility: 17 | everyone: "Mọi người" 18 | -------------------------------------------------------------------------------- /config/locales/client.zh_CN.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | zh_CN: 8 | admin_js: 9 | admin: 10 | site_settings: 11 | categories: 12 | discourse_follow: "Discourse Follow" 13 | js: 14 | notifications: 15 | following: "%{username} %{description}" 16 | following_description: "已开始关注您。" 17 | following_created_topic: "%{username} %{description}" 18 | following_replied: "%{username} %{description}" 19 | titles: 20 | following_created_topic: "来自您关注的人的新话题" 21 | following_replied: "来自您关注的人的新帖子" 22 | following: "有用户开始关注您" 23 | popup: 24 | following: "%{username} 已开始关注您。" 25 | following_created_topic: '%{username} 创建了 "%{topic}" - %{site_title}' 26 | following_replied: '%{username} 在 "%{topic}" 中发布了帖子 - %{site_title}' 27 | user: 28 | follow_nav: "关注" 29 | follow: 30 | label: "关注" 31 | following: 32 | feed_link: "关注动态" 33 | label: "正在关注" 34 | none: "您还没有关注任何人。" 35 | none_other: "%{username} 还没有关注任何人。" 36 | followers: 37 | label: "关注者" 38 | none: "还没有人关注您。" 39 | none_other: "还没有人关注 %{username}。" 40 | feed: 41 | label: "动态" 42 | empty_feed_you: "您关注的人还没有发布任何帖子。" 43 | empty_feed_other: "%{username} 关注的人还没有发布过帖子。" 44 | follow_notifications_options: 45 | notify_followed_user_when_followed: "当我关注用户时通知他们" 46 | notify_me_when_followed: "当用户关注我时通知我" 47 | notify_me_when_followed_replies: "当我关注的人回复时通知我" 48 | notify_me_when_followed_creates_topic: "当我关注的人创建话题时通知我" 49 | allow_people_to_follow_me: "允许其他人关注我" 50 | follow: 51 | follow_pages_visibility: 52 | no-one: "没有人" 53 | self: "仅自己" 54 | trust_level_4: "信任级别 4" 55 | trust_level_3: "信任级别 3" 56 | trust_level_2: "信任级别 2" 57 | trust_level_1: "信任级别 1" 58 | trust_level_0: "信任级别 0" 59 | everyone: "所有人" 60 | follow_button_label: "关注" 61 | unfollow_button_label: "取消关注" 62 | -------------------------------------------------------------------------------- /config/locales/client.zh_TW.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | zh_TW: 8 | js: 9 | notifications: 10 | following: "%{username} %{description}" 11 | following_created_topic: "%{username} %{description}" 12 | following_replied: "%{username} %{description}" 13 | popup: 14 | following_replied: '%{username} 在"%{topic}" 中發文 - %{site_title}' 15 | follow: 16 | follow_pages_visibility: 17 | everyone: "所有使用者" 18 | -------------------------------------------------------------------------------- /config/locales/server.ar.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | ar: 8 | discourse_push_notifications: 9 | popup: 10 | following_created_topic: 'أنشأ %{username} الموضوع "%{topic}" - %{site_title}' 11 | following_replied: 'نشر %{username} في "%{topic}" - ‏%{site_title}' 12 | site_settings: 13 | discourse_follow_enabled: "تفعيل المكوِّن الإضافي للمتابعة." 14 | follow_show_statistics_on_profile: "عرض إحصاءات المتابعة على الملفات التعريفية للمستخدمين." 15 | follow_notifications_enabled: "تفعيل جميع إشعارات المتابعة" 16 | follow_followers_visible: "رؤية المتابعين" 17 | follow_following_visible: "رؤية المتابعين" 18 | default_notify_me_when_followed: 'القيمة الافتراضية لتفضيل المستخدم Notify me when users follow me. لا ينطبق تغيير هذا الإعداد إلا على المستخدمين الذين لم يغيِّروا أبدًا تفضيلات الإشعارات الخاصة بالمكوِّن الإضافي للمتابعة' 19 | default_notify_followed_user_when_followed: 'القيمة الافتراضية لتفضيل المستخدم Notify me when users follow me. لا ينطبق تغيير هذا الإعداد إلا على المستخدمين الذين لم يغيِّروا أبدًا تفضيلات الإشعارات الخاصة بالمكوِّن الإضافي للمتابعة' 20 | default_notify_me_when_followed_replies: 'القيمة الافتراضية لتفضيل المستخدم Notify me when someone I follow replies. لا ينطبق تغيير هذا الإعداد إلا على المستخدمين الذين لم يغيِّروا أبدًا تفضيلات الإشعارات الخاصة بالمكوِّن الإضافي للمتابعة' 21 | default_notify_me_when_followed_creates_topic: 'القيمة الافتراضية لتفضيل المستخدم Notify me when someone I follow creates a topic. لا ينطبق تغيير هذا الإعداد إلا على المستخدمين الذين لم يغيِّروا أبدًا تفضيلات الإشعارات الخاصة بالمكوِّن الإضافي للمتابعة' 22 | default_allow_people_to_follow_me: 'القيمة الافتراضية لتفضيل المستخدم Allow people to follow me. لا ينطبق تغيير هذا الإعداد إلا على المستخدمين الذين لم يغيِّروا أبدًا تفضيلات الإشعارات الخاصة بالمكوِّن الإضافي للمتابعة' 23 | follow: 24 | user_not_found: "تعذَّر العثور على مستخدم باسم المستخدم %{username}" 25 | user_cannot_follow_themself: "غير مسموح للمستخدم بمتابعة نفسه" 26 | invalid_notification_level: "مستوى الإشعار %{level} غير صالح" 27 | cannot_follow_bot: "لا يمكن متابعة مستخدم من برامج الروبوت" 28 | cannot_follow_suspended: "لا يمكن متابعة مستخدم تم تعليقه" 29 | cannot_follow_staged: "لا يمكن متابعة مستخدم مؤقت" 30 | invalid_created_before_date: "تم تلقي تاريخ غير صالح للمعلمة `created_before`: %{value}" 31 | user_does_not_allow_follow: "لا يسمح %{username} للأشخاص بمتابعته." 32 | -------------------------------------------------------------------------------- /config/locales/server.be.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | be: 8 | -------------------------------------------------------------------------------- /config/locales/server.bg.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | bg: 8 | discourse_push_notifications: 9 | popup: 10 | following_replied: '%{username} публикува в "%{topic}" - %{site_title}' 11 | -------------------------------------------------------------------------------- /config/locales/server.bs_BA.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | bs_BA: 8 | discourse_push_notifications: 9 | popup: 10 | following_replied: '%{username} je objavio/la "%{topic}" - %{site_title}' 11 | -------------------------------------------------------------------------------- /config/locales/server.ca.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | ca: 8 | discourse_push_notifications: 9 | popup: 10 | following_created_topic: '%{username} ha creat "%{topic}" - %{site_title}' 11 | following_replied: '%{username} ha publicat en "%{topic}" - %{site_title}' 12 | site_settings: 13 | discourse_follow_enabled: "Activar el plugin de follow." 14 | follow_show_statistics_on_profile: "Mostrar les estadístiques de seguiment en els perfils dels usuaris." 15 | follow_notifications_enabled: "Activar totes les notificacions de seguiment." 16 | follow_followers_visible: "Visibilitat de seguidors." 17 | follow_following_visible: "Visibilitat de següents." 18 | default_notify_me_when_followed: 'Valor predeterminat per al Notifica''m quan els usuaris em segueixen preferència d''usuari. Canviar aquest ajustament només s''aplica als usuaris que mai han canviat les seves preferències de notificacions del plugin de seguiment' 19 | default_notify_followed_user_when_followed: 'Valor predeterminat per al Notificar als usuaris quan els segueixo preferència d''usuari. Canviar aquest ajustament només s''aplica als usuaris que mai han canviat les seves preferències de notificacions del plugin de seguiment' 20 | default_notify_me_when_followed_replies: 'Valor predeterminat per al Notifica''m quan algú que segueixo respon a un tema preferència d''usuari. Canviar aquest ajustament només s''aplica als usuaris que mai han canviat les seves preferències de notificacions del plugin de seguiment' 21 | default_notify_me_when_followed_creates_topic: 'Valor predeterminat per al Notifica''m quan algú que segueixo crea un tema preferència d''usuari. Canviar aquest ajustament només s''aplica als usuaris que mai han canviat les seves preferències de notificacions del plugin de seguiment' 22 | default_allow_people_to_follow_me: 'Valor predeterminat per al Permetre que la gent em segueixi preferència d''usuari. Canviar aquest ajustament només s''aplica als usuaris que mai han canviat les seves preferències de notificacions del plugin de seguiment' 23 | follow: 24 | user_not_found: "No s'ha pogut trobar l'usuari amb el nom d'usuari %{username}" 25 | user_cannot_follow_themself: "L'usuari no està permès seguir a si mateix" 26 | invalid_notification_level: "Nivell de notificació no vàlid %{level}" 27 | cannot_follow_bot: "No es pot seguir a un usuari bot" 28 | cannot_follow_suspended: "No es pot seguir un usuari suspès" 29 | cannot_follow_staged: "No es pot seguir un usuari provisional" 30 | invalid_created_before_date: "S'ha rebut una data no vàlida per al paràmetre `created_before`: %{value}" 31 | user_does_not_allow_follow: "%{username} no permet que la gent els segueixi." 32 | -------------------------------------------------------------------------------- /config/locales/server.cs.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | cs: 8 | discourse_push_notifications: 9 | popup: 10 | following_replied: '%{username} přispěl do "%{topic}" - %{site_title}' 11 | -------------------------------------------------------------------------------- /config/locales/server.da.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | da: 8 | discourse_push_notifications: 9 | popup: 10 | following_replied: '%{username} skrev i "%{topic}" - %{site_title}' 11 | site_settings: 12 | discourse_follow_enabled: "Aktiver følg plugin." 13 | -------------------------------------------------------------------------------- /config/locales/server.de.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | de: 8 | discourse_push_notifications: 9 | popup: 10 | following_created_topic: '%{username} hat „%{topic}“ erstellt – %{site_title}' 11 | following_replied: '%{username} hat geschrieben in „%{topic}“ – %{site_title}' 12 | site_settings: 13 | discourse_follow_enabled: "Follow-Plug-in aktivieren." 14 | follow_show_statistics_on_profile: "Follow-Statistiken auf Benutzerprofilen anzeigen." 15 | follow_notifications_enabled: "Alle Follow-Benachrichtigungen aktivieren." 16 | follow_followers_visible: "Sichtbarkeit der Follower." 17 | follow_following_visible: "Sichtbarkeit von „Folge ich“." 18 | default_notify_me_when_followed: 'Standardwert für die Benutzereinstellung Mich benachrichtigen, wenn mir Benutzer folgen. Das Ändern dieser Einstellung betrifft nur Benutzer, die ihre Benachrichtigungseinstellungen des Follow-Plug-ins noch nie geändert haben' 19 | default_notify_followed_user_when_followed: 'Standardwert für die Benutzereinstellung Benutzer benachrichtigen, wenn ich ihnen folge. Das Ändern dieser Einstellung betrifft nur Benutzer, die ihre Benachrichtigungseinstellungen des Follow-Plug-ins noch nie geändert haben' 20 | default_notify_me_when_followed_replies: 'Standardwert für die Benutzereinstellung Mich benachrichtigen, wenn jemand, dem ich folge, antwortet. Das Ändern dieser Einstellung betrifft nur Benutzer, die ihre Benachrichtigungseinstellungen des Follow-Plug-ins noch nie geändert haben' 21 | default_notify_me_when_followed_creates_topic: 'Standardwert für die Benutzereinstellung Mich benachrichtigen, wenn jemand, dem ich folge, ein Thema erstellt. Das Ändern dieser Einstellung betrifft nur Benutzer, die ihre Benachrichtigungseinstellungen des Follow-Plug-ins noch nie geändert haben' 22 | default_allow_people_to_follow_me: 'Standardwert für die Benutzereinstellung Erlaube anderen, mir zu folgen. Das Ändern dieser Einstellung betrifft nur Benutzer, die ihre Benachrichtigungseinstellungen des Follow-Plug-ins noch nie geändert haben' 23 | follow: 24 | user_not_found: "Benutzer mit Benutzername %{username} konnte nicht gefunden werden" 25 | user_cannot_follow_themself: "Benutzer darf sich nicht selbst folgen" 26 | invalid_notification_level: "Ungültige Benachrichtigungsstufe %{level}" 27 | cannot_follow_bot: "Kann einem Bot-Benutzer nicht folgen" 28 | cannot_follow_suspended: "Kann einem gesperrten Benutzer nicht folgen" 29 | cannot_follow_staged: "Kann einem vorbereiteten Benutzer nicht folgen" 30 | invalid_created_before_date: "Ungültiges Datum für Parameter „created_before“ erhalten: %{value}" 31 | user_does_not_allow_follow: "%{username} erlaubt es anderen nicht, ihm/ihr zu folgen." 32 | -------------------------------------------------------------------------------- /config/locales/server.el.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | el: 8 | discourse_push_notifications: 9 | popup: 10 | following_replied: '%{username} ανάρτησε στο "%{topic}" - %{site_title}' 11 | -------------------------------------------------------------------------------- /config/locales/server.en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | discourse_push_notifications: 3 | popup: 4 | following_created_topic: '%{username} created "%{topic}" - %{site_title}' 5 | following_replied: '%{username} posted in "%{topic}" - %{site_title}' 6 | site_settings: 7 | discourse_follow_enabled: "Enable follow plugin." 8 | follow_show_statistics_on_profile: "Show follow statistics on user profiles." 9 | follow_notifications_enabled: "Enable all follow notifications." 10 | follow_followers_visible: "Followers visibility." 11 | follow_following_visible: "Following visibility." 12 | default_notify_me_when_followed: 'Default value for the Notify me when users follow me user preference. Changing this setting only applies to users who have never changed their notification preferences of the follow plugin' 13 | default_notify_followed_user_when_followed: 'Default value for the Notify users when I follow them user preference. Changing this setting only applies to users who have never changed their notification preferences of the follow plugin' 14 | default_notify_me_when_followed_replies: 'Default value for the Notify me when someone I follow replies user preference. Changing this setting only applies to users who have never changed their notification preferences of the follow plugin' 15 | default_notify_me_when_followed_creates_topic: 'Default value for the Notify me when someone I follow creates a topic user preference. Changing this setting only applies to users who have never changed their notification preferences of the follow plugin' 16 | default_allow_people_to_follow_me: 'Default value for the Allow people to follow me user preference. Changing this setting only applies to users who have never changed their notification preferences of the follow plugin' 17 | 18 | follow: 19 | user_not_found: "Couldn't find user with username %{username}" 20 | user_cannot_follow_themself: "User is not allowed to follow themself" 21 | invalid_notification_level: "Invalid notification level %{level}" 22 | cannot_follow_bot: "Cannot follow a bot user" 23 | cannot_follow_suspended: "Cannot follow a suspend user" 24 | cannot_follow_staged: "Cannot follow a staged user" 25 | invalid_created_before_date: "Received an invalid date for the `created_before` param: %{value}" 26 | user_does_not_allow_follow: "%{username} does not allow people to follow them." 27 | -------------------------------------------------------------------------------- /config/locales/server.en_GB.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | en_GB: 8 | -------------------------------------------------------------------------------- /config/locales/server.es.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | es: 8 | discourse_push_notifications: 9 | popup: 10 | following_created_topic: '%{username} creó «%{topic}» - %{site_title}' 11 | following_replied: '%{username} publicó en «%{topic}» - %{site_title}' 12 | site_settings: 13 | discourse_follow_enabled: "Habilitar el plugin de seguimiento." 14 | follow_show_statistics_on_profile: "Mostrar las estadísticas de seguimiento en los perfiles de los usuarios." 15 | follow_notifications_enabled: "Habilitar todas las notificaciones de seguimiento." 16 | follow_followers_visible: "Visibilidad de seguidores." 17 | follow_following_visible: "Visibilidad de personas a las que sigues." 18 | default_notify_me_when_followed: 'Valor predeterminado para la preferencia de usuario Notificarme cuando los usuarios me siguen. Cambiar este ajuste solo se aplica a los usuarios que nunca han cambiado sus preferencias de notificaciones del plugin de seguimiento' 19 | default_notify_followed_user_when_followed: 'Valor predeterminado para la preferencia de usuario Notificar a los usuarios al seguirlos. El cambio de este ajuste solo se aplica a los usuarios que nunca han cambiado sus preferencias de notificaciones del plugin de seguimiento' 20 | default_notify_me_when_followed_replies: 'Valor predeterminado para la preferencia de usuario Notificarme cuando alguien a quien sigo responde a un tema. Cambiar este ajuste solo se aplica a los usuarios que nunca han cambiado sus preferencias de notificaciones del plugin de seguimiento' 21 | default_notify_me_when_followed_creates_topic: 'Valor predeterminado para la preferencia de usuario Notificarme cuando alguien a quien sigo crea un tema. Cambiar este ajuste solo se aplica a los usuarios que nunca han cambiado sus preferencias de notificaciones del plugin de seguimiento' 22 | default_allow_people_to_follow_me: 'Valor predeterminado para la preferencia de usuario Permitir que la gente me siga. Cambiar este ajuste solo se aplica a los usuarios que nunca han cambiado sus preferencias de notificaciones del plugin de seguimiento' 23 | follow: 24 | user_not_found: "No se pudo encontrar el usuario con el nombre de usuario %{username}" 25 | user_cannot_follow_themself: "El usuario no tiene permitido seguirse a sí mismo" 26 | invalid_notification_level: "Nivel de notificación no válido %{level}" 27 | cannot_follow_bot: "No se puede seguir a un usuario bot" 28 | cannot_follow_suspended: "No se puede seguir a un usuario suspendido" 29 | cannot_follow_staged: "No se puede seguir a un usuario provisional" 30 | invalid_created_before_date: "Se recibió una fecha no válida para el parámetro `created_before`: %{value}" 31 | user_does_not_allow_follow: "%{username} no permite que la gente le siga." 32 | -------------------------------------------------------------------------------- /config/locales/server.et.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | et: 8 | discourse_push_notifications: 9 | popup: 10 | following_created_topic: '%{username} lõi "%{topic}" - %{site_title}' 11 | following_replied: '%{username} postitas teemasse "%{topic}" - %{site_title}' 12 | site_settings: 13 | discourse_follow_enabled: "Luba jälgimise plugin" 14 | follow_show_statistics_on_profile: "Näita jälgimisstatistikat kasutajaprofiililidel" 15 | follow_notifications_enabled: "Luba kõik jälgimismärguanded." 16 | follow_followers_visible: "Jälgijate nähtavus." 17 | follow: 18 | user_cannot_follow_themself: "Kasutajal ei ole lubatud ennast jälgida" 19 | invalid_notification_level: "Kehtetu teavituse tase %{level}" 20 | cannot_follow_bot: "Ei saa jälgida bot-kasutajat" 21 | cannot_follow_suspended: "Peatatud kasutajat ei saa jälgida" 22 | user_does_not_allow_follow: "%{username} ei luba inimestel ennast jälgida." 23 | -------------------------------------------------------------------------------- /config/locales/server.fa_IR.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | fa_IR: 8 | discourse_push_notifications: 9 | popup: 10 | following_replied: '%{username} در "%{topic}" - %{site_title} مطلبی نوشت' 11 | -------------------------------------------------------------------------------- /config/locales/server.fi.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | fi: 8 | discourse_push_notifications: 9 | popup: 10 | following_created_topic: '%{username} loi ketjun "%{topic}" – %{site_title}' 11 | following_replied: '%{username} lähetti viestin ketjuun "%{topic}" – %{site_title}' 12 | site_settings: 13 | discourse_follow_enabled: "Ota seuraamislisäosa käyttöön." 14 | follow_show_statistics_on_profile: "Näytä seuraamistilastot käyttäjäprofiileissa." 15 | follow_notifications_enabled: "Ota kaikki seurantailmoitukset käyttöön." 16 | follow_followers_visible: "Seuraajien näkyvyys." 17 | follow_following_visible: "Seuraamisen näkyvyys." 18 | default_notify_me_when_followed: 'Ilmoita minulle, kun käyttäjät seuraavat minua -käyttäjäasetuksen oletusarvo. Tämän asetuksen muuttaminen koskee vain käyttäjiä, jotka eivät ole koskaan muuttaneet follow-lisäosan ilmoitusasetuksiaan.' 19 | default_notify_followed_user_when_followed: 'Ilmoita käyttäjille, kun seuraan heitä -käyttäjäasetuksen oletusarvo. Tämän asetuksen muuttaminen koskee vain käyttäjiä, jotka eivät ole koskaan muuttaneet follow-lisäosan ilmoitusasetuksiaan.' 20 | default_notify_me_when_followed_replies: 'Ilmoita minulle, kun joku seuraamani vastaa -käyttäjäasetuksen oletusarvo. Tämän asetuksen muuttaminen koskee vain käyttäjiä, jotka eivät ole koskaan muuttaneet follow-lisäosan ilmoitusasetuksiaan.' 21 | default_notify_me_when_followed_creates_topic: 'Ilmoita minulle, kun joku seuraamani luo ketjun -käyttäjäasetuksen oletusarvo. Tämän asetuksen muuttaminen koskee vain käyttäjiä, jotka eivät ole koskaan muuttaneet follow-lisäosan ilmoitusasetuksiaan.' 22 | default_allow_people_to_follow_me: 'Salli ihmisten seurata minua -käyttäjäasetuksen oletusarvo. Tämän asetuksen muuttaminen koskee vain käyttäjiä, jotka eivät ole koskaan muuttaneet follow-lisäosan ilmoitusasetuksiaan.' 23 | follow: 24 | user_not_found: "Käyttäjätunnuksella %{username} ei löydy käyttäjää" 25 | user_cannot_follow_themself: "Käyttäjä ei saa seurata itseään" 26 | invalid_notification_level: "Virheellinen ilmoitustaso %{level}" 27 | cannot_follow_bot: "Bottikäyttäjää ei voi seurata" 28 | cannot_follow_suspended: "Estettyä käyttäjää ei voi seurata" 29 | cannot_follow_staged: "Vaiheistettua käyttäjää ei voi seurata" 30 | invalid_created_before_date: "Virheellinen päivämäärä vastaanotettu \"created_before\"-parametrille: %{value}" 31 | user_does_not_allow_follow: "%{username} ei salli ihmisten seuraavan häntä." 32 | -------------------------------------------------------------------------------- /config/locales/server.fr.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | fr: 8 | discourse_push_notifications: 9 | popup: 10 | following_created_topic: '%{username} a créé « %{topic} » - %{site_title}' 11 | following_replied: '%{username} a publié un message dans « %{topic} » - %{site_title}' 12 | site_settings: 13 | discourse_follow_enabled: "Activer l'extension de suivi." 14 | follow_show_statistics_on_profile: "Afficher les statistiques de suivi sur les profils des utilisateurs." 15 | follow_notifications_enabled: "Activer toutes les notifications de suivi." 16 | follow_followers_visible: "Visibilité des abonnés." 17 | follow_following_visible: "Visibilité du suivi." 18 | default_notify_me_when_followed: 'Valeur par défaut pour la préférence utilisateur M''avertir lorsque des utilisateurs me suivent. La modification de ce paramètre ne s''applique qu''aux utilisateurs qui n''ont jamais modifié leurs préférences de notification de l''extension de suivi' 19 | default_notify_followed_user_when_followed: 'Valeur par défaut pour la préférence utilisateur Avertir les utilisateurs lorsque je les suis. La modification de ce paramètre ne s''applique qu''aux utilisateurs qui n''ont jamais modifié leurs préférences de notification de l''extension de suivi' 20 | default_notify_me_when_followed_replies: 'Valeur par défaut pour la préférence utilisateur M''avertir lorsque quelqu''un que je suis répond. La modification de ce paramètre ne s''applique qu''aux utilisateurs qui n''ont jamais modifié leurs préférences de notification de l''extension de suivi' 21 | default_notify_me_when_followed_creates_topic: 'Valeur par défaut pour la préférence utilisateur M''avertir lorsqu''une personne que je suis crée un sujet. La modification de ce paramètre ne s''applique qu''aux utilisateurs qui n''ont jamais modifié leurs préférences de notification de l''extension de suivi' 22 | default_allow_people_to_follow_me: 'Valeur par défaut pour la préférence utilisateur Autoriser les autres utilisateurs à me suivre. La modification de ce paramètre ne s''applique qu''aux utilisateurs qui n''ont jamais modifié leurs préférences de notification de l''extension de suivi' 23 | follow: 24 | user_not_found: "Impossible de trouver l'utilisateur avec le nom d'utilisateur %{username}" 25 | user_cannot_follow_themself: "L'utilisateur n'est pas autorisé à se suivre lui-même" 26 | invalid_notification_level: "Niveau de notification invalide %{level}" 27 | cannot_follow_bot: "Impossible de suivre un utilisateur robot" 28 | cannot_follow_suspended: "Impossible de suivre un utilisateur suspendu" 29 | cannot_follow_staged: "Impossible de suivre un utilisateur distant" 30 | invalid_created_before_date: "Réception d'une date invalide pour le paramètre « created_before » : %{value}" 31 | user_does_not_allow_follow: "%{username} n'autorise pas les autres utilisateurs à le ou la suivre." 32 | -------------------------------------------------------------------------------- /config/locales/server.gl.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | gl: 8 | discourse_push_notifications: 9 | popup: 10 | following_replied: '%{username} publicou en "%{topic}" - %{site_title}' 11 | -------------------------------------------------------------------------------- /config/locales/server.he.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | he: 8 | discourse_push_notifications: 9 | popup: 10 | following_created_topic: '„%{topic}” נוצר על ידי %{username}‏ - %{site_title}' 11 | following_replied: '%{username} הגיב ב"%{topic}" - %{site_title}' 12 | site_settings: 13 | discourse_follow_enabled: "הפעל את תוסף המעקב." 14 | follow_show_statistics_on_profile: "הצג סטטיסטיקות מעקב בפרופילים של משתמשים." 15 | follow_notifications_enabled: "הפעל את כל התראות המעקב." 16 | follow_followers_visible: "נראות העוקבים." 17 | follow_following_visible: "נראות הנעקבים." 18 | default_notify_me_when_followed: 'ערך ברירת מחדל להעדפת המשתמש להודיע לי כשמשתמשים עוקבים אחרי. שינוי ההגדרה הזאת משפיע רק על משתמשים שמעולם לא שינוי את העדפות ההתראה שלהם בתוסף המעקב.' 19 | default_notify_followed_user_when_followed: 'ערך ברירת מחדל להעדפת המשתמש להודיע לשמשתמשים עם הוספתם לרשימת המעקב שלי. שינוי ההגדרה הזאת משפיע רק על משתמשים שמעולם לא שינוי את העדפות ההתראה שלהם בתוסף המעקב.' 20 | default_notify_me_when_followed_replies: 'ערך ברירת מחדל להעדפת המשתמש להודיע לי כשמשתמשים מרשימת המעקב שלי מגיבים. שינוי ההגדרה הזאת משפיע רק על משתמשים שמעולם לא שינוי את העדפות ההתראה שלהם בתוסף המעקב.' 21 | default_notify_me_when_followed_creates_topic: 'ערך ברירת מחדל להעדפת המשתמש להודיע לי כשמשתמשים מרשימת המעקב שלי יוצרים נושא. שינוי ההגדרה הזאת משפיע רק על משתמשים שמעולם לא שינוי את העדפות ההתראה שלהם בתוסף המעקב.' 22 | default_allow_people_to_follow_me: 'ערך ברירת מחדל להעדפת המשתמש לאפשר לאנשים לעקוב אחריי. שינוי ההגדרה הזאת משפיע רק על משתמשים שמעולם לא שינוי את העדפות ההתראה שלהם בתוסף המעקב.' 23 | follow: 24 | user_not_found: "לא ניתן למצוא משתמש בשם %{username}" 25 | user_cannot_follow_themself: "משתמש לא רשאי לעקוב אחרי עצמו" 26 | invalid_notification_level: "דרגת ההתראה %{level} שגויה" 27 | cannot_follow_bot: "לא ניתן לעקוב אחר משתמש בוט" 28 | cannot_follow_suspended: "לא ניתן לעקוב אחר משתמש בהשעיה" 29 | cannot_follow_staged: "לא ניתן לעקוב אחר משתמש מבוים" 30 | invalid_created_before_date: "התקבל תאריך שגוי עבור המשתנה ‚created_before’‏ (נוצר לפני): %{value}" 31 | user_does_not_allow_follow: "אין הרשאה מצד %{username} להוספה שלהם לרשימת מעקב." 32 | -------------------------------------------------------------------------------- /config/locales/server.hr.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | hr: 8 | discourse_push_notifications: 9 | popup: 10 | following_replied: '%{username} objavio u "%{topic}" - %{site_title}' 11 | -------------------------------------------------------------------------------- /config/locales/server.hu.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | hu: 8 | discourse_push_notifications: 9 | popup: 10 | following_replied: '%{username} bejegyzést tett itt: „%{topic}” – %{site_title}' 11 | site_settings: 12 | discourse_follow_enabled: "Követő plugin engedélyezése" 13 | follow_show_statistics_on_profile: "Követési statisztika megjelenítése a felhasználói profilban" 14 | follow_notifications_enabled: "Az összes követési értesítés engedélyezése." 15 | follow_followers_visible: "Követők láthatósága." 16 | follow_following_visible: "Követettek láthatósága." 17 | -------------------------------------------------------------------------------- /config/locales/server.hy.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | hy: 8 | discourse_push_notifications: 9 | popup: 10 | following_replied: '%{username} -ը գրառում է կատարել այստեղ՝ "%{topic}" - %{site_title}' 11 | -------------------------------------------------------------------------------- /config/locales/server.id.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | id: 8 | -------------------------------------------------------------------------------- /config/locales/server.it.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | it: 8 | discourse_push_notifications: 9 | popup: 10 | following_created_topic: '%{username} ha creato "%{topic}" - %{site_title}' 11 | following_replied: '%{username} ha pubblicato qualcosa in "%{topic}" - %{site_title}' 12 | site_settings: 13 | discourse_follow_enabled: "Abilita il plug-in follow." 14 | follow_show_statistics_on_profile: "Mostra le statistiche di utenti che seguono sui profili utente." 15 | follow_notifications_enabled: "Abilita tutte le notifiche di utenti che seguono." 16 | follow_followers_visible: "Visibilità dei follower." 17 | follow_following_visible: "Visibilità di chi segui" 18 | default_notify_me_when_followed: 'Valore predefinito per la preferenza utente Avvisami quando gli utenti mi seguono. La modifica di questa impostazione si applica solo agli utenti che non hanno mai modificato le proprie preferenze di notifica del plugin follow' 19 | default_notify_followed_user_when_followed: 'Valore predefinito per la preferenza utente Avvisa gli utenti che seguo. La modifica di questa impostazione si applica solo agli utenti che non hanno mai modificato le proprie preferenze di notifica del plugin follow' 20 | default_notify_me_when_followed_replies: 'Valore predefinito per la preferenza utente Avvisami quando qualcuno che seguo risponde. La modifica di questa impostazione si applica solo agli utenti che non hanno mai modificato le proprie preferenze di notifica del plugin follow' 21 | default_notify_me_when_followed_creates_topic: 'Valore predefinito per la preferenza utente Avvisami quando qualcuno che seguo crea un argomento. La modifica di questa impostazione si applica solo agli utenti che non hanno mai modificato le proprie preferenze di notifica del plugin follow' 22 | default_allow_people_to_follow_me: 'Valore predefinito per la preferenza utente Consenti agli utenti di seguirmi. La modifica di questa impostazione si applica solo agli utenti che non hanno mai modificato le proprie preferenze di notifica del plug-in follow' 23 | follow: 24 | user_not_found: "Impossibile trovare l'utente con nome utente %{username}" 25 | user_cannot_follow_themself: "L'utente non è autorizzato a seguire se stesso" 26 | invalid_notification_level: "Livello di notifica %{level} non valido" 27 | cannot_follow_bot: "Impossibile seguire un utente bot" 28 | cannot_follow_suspended: "Impossibile seguire un utente sospeso" 29 | cannot_follow_staged: "Impossibile seguire un utente temporaneo" 30 | invalid_created_before_date: "Ricevuta una data non valida per il parametro `created_before`: %{value}" 31 | user_does_not_allow_follow: "%{username} non consente alle persone di seguirlo." 32 | -------------------------------------------------------------------------------- /config/locales/server.ja.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | ja: 8 | discourse_push_notifications: 9 | popup: 10 | following_created_topic: '%{username} が「%{topic}」を作成しました - %{site_title}' 11 | following_replied: '%{username} が「%{topic}」に投稿しました - %{site_title}' 12 | site_settings: 13 | discourse_follow_enabled: "フォロープラグインを有効にします。" 14 | follow_show_statistics_on_profile: "ユーザープロファイルにフォロー統計を表示します。" 15 | follow_notifications_enabled: "すべてのフォロー通知を有効にします。" 16 | follow_followers_visible: "フォロワーの表示状態。" 17 | follow_following_visible: "フォロー中の表示状態。" 18 | default_notify_me_when_followed: '「ユーザーが自分をフォローしたら通知する」ユーザー設定のデフォルト値。この設定の変更は、フォロープラグインの通知設定を変更したことのないユーザーのみに適用されます。' 19 | default_notify_followed_user_when_followed: '「フォローしたらそのユーザーに通知する」ユーザー設定のデフォルト値。この設定の変更は、フォロープラグインの通知設定を変更したことのないユーザーのみに適用されます。' 20 | default_notify_me_when_followed_replies: '「フォローしている人が返信したら通知する」ユーザー設定のデフォルト値。この設定の変更は、フォロープラグインの通知設定を変更したことのないユーザーのみに適用されます。' 21 | default_notify_me_when_followed_creates_topic: '「フォローしている人がトピックを作成したら通知する」ユーザー設定のデフォルト値。この設定の変更は、フォロープラグインの通知設定を変更したことのないユーザーのみに適用されます。' 22 | default_allow_people_to_follow_me: '「他のユーザーにフォローを許可する」ユーザー設定のデフォルト値。この設定の変更は、フォロープラグインの通知設定を変更したことのないユーザーのみに適用されます。' 23 | follow: 24 | user_not_found: "ユーザー名 %{username} のユーザーが見つかりませんでした" 25 | user_cannot_follow_themself: "ユーザーは自身をフォローすることはできません" 26 | invalid_notification_level: "無効な通知レベル %{level}" 27 | cannot_follow_bot: "ボットユーザーをフォローできません" 28 | cannot_follow_suspended: "凍結中のユーザーをフォローできません" 29 | cannot_follow_staged: "ステージングユーザーをフォローできません" 30 | invalid_created_before_date: "`created_before` パラメーターに無効な日付を受け取りました: %{value}" 31 | user_does_not_allow_follow: "%{username} はユーザーのフォローを許可していません。" 32 | -------------------------------------------------------------------------------- /config/locales/server.ko.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | ko: 8 | discourse_push_notifications: 9 | popup: 10 | following_replied: '"%{topic}"에서 %{username}님이 글을 게시하였습니다 - %{site_title}' 11 | site_settings: 12 | discourse_follow_enabled: "팔로우 플러그인을 활성화합니다." 13 | -------------------------------------------------------------------------------- /config/locales/server.lt.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | lt: 8 | discourse_push_notifications: 9 | popup: 10 | following_replied: '%{username} paskelbė "%{topic}" - %{site_title}' 11 | -------------------------------------------------------------------------------- /config/locales/server.lv.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | lv: 8 | discourse_push_notifications: 9 | popup: 10 | following_replied: '%{username} ierakstīja "%{topic}" - %{site_title}' 11 | -------------------------------------------------------------------------------- /config/locales/server.nb_NO.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | nb_NO: 8 | discourse_push_notifications: 9 | popup: 10 | following_replied: '%{username} skrev noe i "%{topic}" - %{site_title}' 11 | -------------------------------------------------------------------------------- /config/locales/server.nl.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | nl: 8 | discourse_push_notifications: 9 | popup: 10 | following_created_topic: '%{username} heeft ''%{topic}'' gemaakt - %{site_title}' 11 | following_replied: '%{username} heeft een bericht geplaatst in ''%{topic}'' - %{site_title}' 12 | site_settings: 13 | discourse_follow_enabled: "Schakel de volgplug-in in." 14 | follow_show_statistics_on_profile: "Toon volgstatistieken in gebruikersprofielen." 15 | follow_notifications_enabled: "Schakel alle volgmeldingen in." 16 | follow_followers_visible: "Zichtbaarheid van volgers." 17 | follow_following_visible: "Zichtbaarheid van volgend." 18 | default_notify_me_when_followed: 'Standaardwaarde voor de gebruikersvoorkeur Laat me weten wanneer gebruikers mij volgen. Het wijzigen van deze instelling is alleen van toepassing op gebruikers die hun meldingsvoorkeuren van de volgplug-in nooit hebben gewijzigd' 19 | default_notify_followed_user_when_followed: 'Standaardwaarde voor de gebruikersvoorkeur Laat gebruikers weten wanneer ik ze volg. Het wijzigen van deze instelling is alleen van toepassing op gebruikers die hun meldingsvoorkeuren van de volgplug-in nooit hebben gewijzigd' 20 | default_notify_me_when_followed_replies: 'Standaardwaarde voor de gebruikersvoorkeur Laat me weten wanneer iemand die ik volg antwoordt. Het wijzigen van deze instelling is alleen van toepassing op gebruikers die hun meldingsvoorkeuren van de volgplug-in nooit hebben gewijzigd' 21 | default_notify_me_when_followed_creates_topic: 'Standaardwaarde voor de gebruikersvoorkeur Laat me weten wanneer die ik volg een topic maakt. Het wijzigen van deze instelling is alleen van toepassing op gebruikers die hun meldingsvoorkeuren van de volgplug-in nooit hebben gewijzigd' 22 | default_allow_people_to_follow_me: 'Standaardwaarde voor de gebruikersvoorkeur Sta mensen toe mij te volgen. Het wijzigen van deze instelling is alleen van toepassing op gebruikers die hun meldingsvoorkeuren van de volgplug-in nooit hebben gewijzigd' 23 | follow: 24 | user_not_found: "Kon gebruiker met gebruikersnaam %{username} niet vinden." 25 | user_cannot_follow_themself: "Gebruiker mag zichzelf niet volgen" 26 | invalid_notification_level: "Ongeldig meldingsniveau %{level}" 27 | cannot_follow_bot: "Kan een botgebruiker niet volgen" 28 | cannot_follow_suspended: "Kan een geschorste gebruiker niet volgen" 29 | cannot_follow_staged: "Kan een gefaseerde gebruiker niet volgen" 30 | invalid_created_before_date: "Ongeldige datum ontvangen voor de parameter `created_before`: %{value}" 31 | user_does_not_allow_follow: "%{username} staat niet toe dat mensen hem/haar volgen." 32 | -------------------------------------------------------------------------------- /config/locales/server.pl_PL.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | pl_PL: 8 | discourse_push_notifications: 9 | popup: 10 | following_created_topic: '%{username} utworzył(a) "%{topic}" - %{site_title}' 11 | following_replied: '%{username} napisał(a) w "%{topic}" - %{site_title}' 12 | site_settings: 13 | discourse_follow_enabled: "Włącz wtyczkę obserwacji." 14 | follow_show_statistics_on_profile: "Pokaż statystyki obserwowania w profilach użytkowników." 15 | follow_notifications_enabled: "Włącz wszystkie powiadomienia o obserwacjach." 16 | follow_followers_visible: "Widoczność obserwujących." 17 | follow_following_visible: "Widoczność obserwowanych." 18 | default_notify_me_when_followed: 'Wartość domyślna dla preferencji Powiadom mnie, gdy użytkownicy mnie obserwują użytkownika. Zmiana tego ustawienia dotyczy tylko użytkowników, którzy nigdy nie zmienili swoich preferencji powiadamiania we wtyczce obserwacji.' 19 | default_notify_followed_user_when_followed: 'Wartość domyślna dla preferencji Powiadamiaj użytkowników, gdy ich zaobserwuję użytkownika. Zmiana tego ustawienia dotyczy tylko użytkowników, którzy nigdy nie zmienili swoich preferencji powiadamiania we wtyczce obserwacji.' 20 | default_notify_me_when_followed_replies: 'Wartość domyślna dla preferencji Powiadom mnie, gdy ktoś, kogo śledzę, odpowiada użytkownika. Zmiana tego ustawienia dotyczy tylko użytkowników, którzy nigdy nie zmienili swoich preferencji powiadamiania we wtyczce obserwacji.' 21 | default_notify_me_when_followed_creates_topic: 'Wartość domyślna dla preferencji Powiadom mnie, gdy ktoś, kogo obserwuję, utworzy temat użytkownika. Zmiana tego ustawienia dotyczy tylko użytkowników, którzy nigdy nie zmienili swoich preferencji powiadamiania we wtyczce obserwacji.' 22 | default_allow_people_to_follow_me: 'Wartość domyślna dla preferencji Pozwól ludziom mnie obserwować użytkownika. Zmiana tego ustawienia dotyczy tylko użytkowników, którzy nigdy nie zmienili swoich preferencji powiadamiania we wtyczce obserwacji.' 23 | follow: 24 | user_not_found: "Nie można znaleźć użytkownika o nazwie %{username}" 25 | user_cannot_follow_themself: "Użytkownik nie może obserwować samego siebie" 26 | invalid_notification_level: "Nieprawidłowy poziom powiadomień %{level}" 27 | cannot_follow_bot: "Nie można obserwować bota" 28 | cannot_follow_suspended: "Nie można obserwować zawieszonego użytkownika" 29 | cannot_follow_staged: "Nie można obserwować użytkownika etapowego" 30 | invalid_created_before_date: "Otrzymano nieprawidłową datę dla parametru `created_before`: %{value}" 31 | user_does_not_allow_follow: "%{username} nie pozwala na obserwowanie." 32 | -------------------------------------------------------------------------------- /config/locales/server.pt.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | pt: 8 | discourse_push_notifications: 9 | popup: 10 | following_replied: '%{username} publicou em "%{topic}" - %{site_title}' 11 | -------------------------------------------------------------------------------- /config/locales/server.pt_BR.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | pt_BR: 8 | discourse_push_notifications: 9 | popup: 10 | following_created_topic: '%{username} criou "%{topic}" - %{site_title}' 11 | following_replied: '%{username} postou em "%{topic}" - %{site_title}' 12 | site_settings: 13 | discourse_follow_enabled: "Ativar o plugin de acompanhamento." 14 | follow_show_statistics_on_profile: "Exibir estatísticas de acompanhamento nos perfis dos(as) usuários(as)." 15 | follow_notifications_enabled: "Ativar todas as notificações de acompanhamento." 16 | follow_followers_visible: "Visibilidade dos(as) seguidores(as)." 17 | follow_following_visible: "Visibilidade dos(as) seguidos(as)." 18 | default_notify_me_when_followed: 'Valor padrão para a preferência de usuário(a) Notificar-me quando usuários(as) me seguirem. A alteração dessa configuração se aplica apenas a usuários(as) que nunca alteraram suas preferências de notificação ou o plugin de acompanhamento' 19 | default_notify_followed_user_when_followed: 'Valor padrão para a preferência de usuário(a) Notificar usuários(as) quando eu seguir. A alteração dessa configuração se aplica apenas a usuários(as) que nunca alteraram suas preferências de notificação ou o plugin de acompanhamento' 20 | default_notify_me_when_followed_replies: 'Valor padrão para a preferência de usuário(a) Notificar-me quando eu acompanhar respostas. A alteração dessa configuração se aplica apenas a usuários(as) que nunca alteraram suas preferências de notificação ou o plugin de acompanhamento' 21 | default_notify_me_when_followed_creates_topic: 'Valor padrão para a preferência de usuário(a) Notificar-me quando eu criar um tópico. A alteração dessa configuração se aplica apenas a usuários(as) que nunca alteraram suas preferências de notificação ou o plugin de acompanhamento' 22 | default_allow_people_to_follow_me: 'Valor padrão para a preferência de usuário(a) Permitir que me sigam. A alteração dessa configuração se aplica apenas a usuários(as) que nunca alteraram suas preferências de notificação ou o plugin de acompanhamento' 23 | follow: 24 | user_not_found: "Não foi possível encontrar usuário(a) com o nome de usuário(a) %{username}" 25 | user_cannot_follow_themself: "O(a) usuário(a) não pode seguir a si" 26 | invalid_notification_level: "Nível de notificação inválido %{level}" 27 | cannot_follow_bot: "Não é possível seguir um(a) usuário(a) robô" 28 | cannot_follow_suspended: "Não é possível seguir um(a) usuário(a) suspenso(a)" 29 | cannot_follow_staged: "Não é possível seguir um(a) usuário(a) encenado(a)" 30 | invalid_created_before_date: "Data inválida recebida para o parâmetro \"created_before\": %{value}" 31 | user_does_not_allow_follow: "%{username} não permite ser seguido(a)" 32 | -------------------------------------------------------------------------------- /config/locales/server.ro.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | ro: 8 | discourse_push_notifications: 9 | popup: 10 | following_replied: '%{username} a postat în discuția "%{topic}" - %{site_title}' 11 | -------------------------------------------------------------------------------- /config/locales/server.ru.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | ru: 8 | discourse_push_notifications: 9 | popup: 10 | following_created_topic: '%{username} создал(а) тему «%{topic}» — %{site_title}' 11 | following_replied: '%{username} написал(а) в теме «%{topic}» — %{site_title}' 12 | site_settings: 13 | discourse_follow_enabled: "Включить плагин подписок." 14 | follow_show_statistics_on_profile: "Показывать статистику подписок в профилях пользователей." 15 | follow_notifications_enabled: "Включите все уведомления о подписках." 16 | follow_followers_visible: "Кто видит подписчиков." 17 | follow_following_visible: "Кто видит подписки." 18 | default_notify_me_when_followed: 'Значение по умолчанию для параметра пользователя Уведомлять, когда подписываются на меня. Изменение этого параметра действует только на пользователей, которые не меняли настройки уведомлений для плагина подписок.' 19 | default_notify_followed_user_when_followed: 'Значение по умолчанию для параметра пользователя Уведомлять пользователей, когда я на них подписываюсь. Изменение этого параметра действует только на пользователей, которые не меняли настройки уведомлений для плагина подписок.' 20 | default_notify_me_when_followed_replies: 'Значение по умолчанию для параметра пользователя Уведомлять, когда кто-то из моих подписок отвечает. Изменение этого параметра действует только на пользователей, которые не меняли настройки уведомлений для плагина подписок.' 21 | default_notify_me_when_followed_creates_topic: 'Значение по умолчанию для параметра пользователя Уведомлять, когда кто-то из моих подписок создает тему. Изменение этого параметра действует только на пользователей, которые не меняли настройки уведомлений для плагина подписок.' 22 | default_allow_people_to_follow_me: 'Значение по умолчанию для параметра пользователя Разрешить подписываться на меня. Изменение этого параметра действует только на пользователей, которые не меняли настройки уведомлений для плагина подписок.' 23 | follow: 24 | user_not_found: "Не удалось найти имя пользователя %{username}" 25 | user_cannot_follow_themself: "Подписываться на себя нельзя" 26 | invalid_notification_level: "Неверный уровень уведомлений %{level}" 27 | cannot_follow_bot: "Подписаться на бота нельзя" 28 | cannot_follow_suspended: "Подписаться на замороженного пользователя нельзя" 29 | cannot_follow_staged: "Подписаться на сымитированного пользователя нельзя" 30 | invalid_created_before_date: "Получена неверная дата для параметра `created_before`: %{value}" 31 | user_does_not_allow_follow: "%{username} запрещает подписываться на себя." 32 | -------------------------------------------------------------------------------- /config/locales/server.sk.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | sk: 8 | discourse_push_notifications: 9 | popup: 10 | following_replied: '%{username} prispel v "%{topic}" - %{site_title}' 11 | -------------------------------------------------------------------------------- /config/locales/server.sl.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | sl: 8 | discourse_push_notifications: 9 | popup: 10 | following_replied: '%{username} je objavil v "%{topic}" - %{site_title}' 11 | -------------------------------------------------------------------------------- /config/locales/server.sq.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | sq: 8 | discourse_push_notifications: 9 | popup: 10 | following_replied: '%{username} postoi në "%{topic}" - %{site_title}' 11 | -------------------------------------------------------------------------------- /config/locales/server.sr.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | sr: 8 | -------------------------------------------------------------------------------- /config/locales/server.sv.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | sv: 8 | discourse_push_notifications: 9 | popup: 10 | following_created_topic: '%{username} skapade "%{topic}" - %{site_title}' 11 | following_replied: '%{username} skrev inlägg i "%{topic}" - %{site_title}' 12 | site_settings: 13 | discourse_follow_enabled: "Aktivera insticksprogram Följare" 14 | follow_show_statistics_on_profile: "Visa följestatistik på användarprofiler." 15 | follow_notifications_enabled: "Aktivera alla följaviseringar." 16 | follow_followers_visible: "Följares synlighet." 17 | follow_following_visible: "Synlighet för följer." 18 | default_notify_me_when_followed: 'Standardvärde för användarinställning Meddela mig när användare följer mig. Att ändra den här inställningen gäller bara användare som aldrig har ändrat sina aviseringsinställningar för följande plugin' 19 | default_notify_followed_user_when_followed: 'Standardvärde för användarinställning Meddela användare när jag följer dem. Att ändra den här inställningen gäller bara användare som aldrig har ändrat sina aviseringsinställningar för följande plugin' 20 | default_notify_me_when_followed_replies: 'Standardvärde för användarinställning Meddela mig när någon jag följer svarar. Att ändra den här inställningen gäller bara användare som aldrig har ändrat sina aviseringsinställningar för följande plugin' 21 | default_notify_me_when_followed_creates_topic: 'Standardvärde för användarinställningMeddela mig när någon jag följer skapar ett ämne. Att ändra den här inställningen gäller bara användare som aldrig har ändrat sina aviseringsinställningar för följande plugin' 22 | default_allow_people_to_follow_me: 'Standardvärdet för användarinställning Tillåt folk att följa mig. Att ändra den här inställningen gäller bara användare som aldrig har ändrat sina aviseringsinställningar för följande plugin' 23 | follow: 24 | user_not_found: "Kunde inte hitta användare med användarnamn %{username}" 25 | user_cannot_follow_themself: "Användaren kan inte följa sig själv" 26 | invalid_notification_level: "Ogiltig aviseringsnivå %{level}" 27 | cannot_follow_bot: "Kan inte följa en botanvändare" 28 | cannot_follow_suspended: "Det går inte att följa en avstängd användare" 29 | cannot_follow_staged: "Det går inte att följa en iscensatt användare" 30 | invalid_created_before_date: "Fick ett ogiltigt datum för parametern 'created_before': %{value}" 31 | user_does_not_allow_follow: "%{username} tillåter inte att personer följer dem." 32 | -------------------------------------------------------------------------------- /config/locales/server.sw.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | sw: 8 | -------------------------------------------------------------------------------- /config/locales/server.te.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | te: 8 | discourse_push_notifications: 9 | popup: 10 | following_replied: '%{username} "%{topic}"- %{site_title}లో పోస్ట్ చేసారు' 11 | -------------------------------------------------------------------------------- /config/locales/server.th.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | th: 8 | discourse_push_notifications: 9 | popup: 10 | following_replied: '%{username} โพสท์ใน "%{topic}" - %{site_title}' 11 | -------------------------------------------------------------------------------- /config/locales/server.tr_TR.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | tr_TR: 8 | discourse_push_notifications: 9 | popup: 10 | following_created_topic: '%{username} "%{topic}" başlıklı bir konu oluşturdu - %{site_title}' 11 | following_replied: '%{username}, "%{topic}" başlıklı konuya gönderi yaptı - %{site_title}' 12 | site_settings: 13 | discourse_follow_enabled: "Takip eklentisini etkinleştirin." 14 | follow_show_statistics_on_profile: "Kullanıcı profillerinde takip istatistiklerini gösterin." 15 | follow_notifications_enabled: "Tüm takip bildirimlerini etkinleştirin." 16 | follow_followers_visible: "Takipçi görünürlüğü." 17 | follow_following_visible: "Takip ediliyor görünürlüğü." 18 | default_notify_me_when_followed: 'Kullanıcılar beni takip ettiğinde bana bildir kullanıcı tercihi için varsayılan değer. Bu ayarın değiştirilmesi yalnızca takip eklentisinin bildirim tercihlerini hiç değiştirmemiş kullanıcılar için geçerlidir' 19 | default_notify_followed_user_when_followed: 'Kullanıcıları takip ettiğimde onlara bildir kullanıcı tercihi için varsayılan değer. Bu ayarın değiştirilmesi yalnızca takip eklentisinin bildirim tercihlerini hiç değiştirmemiş kullanıcılar için geçerlidir' 20 | default_notify_me_when_followed_replies: 'Takip ettiğim biri yanıt verdiğinde bana bildir kullanıcı tercihi için varsayılan değer. Bu ayarın değiştirilmesi yalnızca takip eklentisinin bildirim tercihlerini hiç değiştirmemiş kullanıcılar için geçerlidir' 21 | default_notify_me_when_followed_creates_topic: 'Takip ettiğim biri konu oluşturduğunda bana bildir kullanıcı tercihi için varsayılan değer. Bu ayarın değiştirilmesi yalnızca takip eklentisinin bildirim tercihlerini hiç değiştirmemiş kullanıcılar için geçerlidir' 22 | default_allow_people_to_follow_me: 'Kişilerin beni takip etmesine izin ver kullanıcı tercihi için varsayılan değer. Bu ayarın değiştirilmesi yalnızca takip eklentisinin bildirim tercihlerini hiç değiştirmemiş kullanıcılar için geçerlidir' 23 | follow: 24 | user_not_found: "Kullanıcı adı %{username} olan kullanıcı bulunamadı" 25 | user_cannot_follow_themself: "Kullanıcının kendisini takip etmesine izin verilmez" 26 | invalid_notification_level: "Geçersiz bildirim seviyesi %{level}" 27 | cannot_follow_bot: "Bir bot kullanıcısı takip edilemez" 28 | cannot_follow_suspended: "Askıya alınmış bir kullanıcı takip edilemez" 29 | cannot_follow_staged: "Aşamalı bir kullanıcı takip edilemez" 30 | invalid_created_before_date: "\"created_before\" parametresi için geçersiz bir tarih alındı: %{value}" 31 | user_does_not_allow_follow: "%{username} kişilerin kendisini takip etmelerine izin vermiyor." 32 | -------------------------------------------------------------------------------- /config/locales/server.ug.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | ug: 8 | discourse_push_notifications: 9 | popup: 10 | following_replied: '%{username} «%{topic}» - %{site_title} غا يوللىدى' 11 | -------------------------------------------------------------------------------- /config/locales/server.uk.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | uk: 8 | discourse_push_notifications: 9 | popup: 10 | following_replied: '%{username} опублікував в "%{topic}" - %{site_title}' 11 | -------------------------------------------------------------------------------- /config/locales/server.ur.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | ur: 8 | discourse_push_notifications: 9 | popup: 10 | following_replied: '%{username} نے "%{topic}" میں پوسٹ کیا - %{site_title}' 11 | -------------------------------------------------------------------------------- /config/locales/server.vi.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | vi: 8 | discourse_push_notifications: 9 | popup: 10 | following_replied: '%{username} gửi bài trong "%{topic}" - %{site_title}' 11 | -------------------------------------------------------------------------------- /config/locales/server.zh_CN.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | zh_CN: 8 | discourse_push_notifications: 9 | popup: 10 | following_created_topic: '%{username} 创建了 "%{topic}" - %{site_title}' 11 | following_replied: '%{username} 在 "%{topic}" 中发布了帖子 - %{site_title}' 12 | site_settings: 13 | discourse_follow_enabled: "启用关注插件。" 14 | follow_show_statistics_on_profile: "在用户个人资料上显示关注统计信息" 15 | follow_notifications_enabled: "启用所有关注通知。" 16 | follow_followers_visible: "关注者可见性。" 17 | follow_following_visible: "正在关注可见性。" 18 | default_notify_me_when_followed: '用户偏好设置当用户关注我时通知我的默认值。更改此设置仅适用于从未更改过关注插件的通知偏好设置的用户' 19 | default_notify_followed_user_when_followed: '用户偏好设置当我关注用户时通知他们的默认值。更改此设置仅适用于从未更改过关注插件的通知偏好设置的用户' 20 | default_notify_me_when_followed_replies: '用户偏好设置当我关注的用户回复时通知我的默认值。更改此设置仅适用于从未更改过关注插件的通知偏好设置的用户' 21 | default_notify_me_when_followed_creates_topic: '用户偏好设置当我关注的用户创建话题时通知我的默认值。更改此设置仅适用于从未更改过关注插件的通知偏好设置的用户' 22 | default_allow_people_to_follow_me: '用户偏好设置允许其他人关注我的默认值。更改此设置仅适用于从未更改过关注插件的通知偏好设置的用户' 23 | follow: 24 | user_not_found: "找不到用户名为 %{username} 的用户" 25 | user_cannot_follow_themself: "用户不能关注自己" 26 | invalid_notification_level: "无效的通知级别 %{level}" 27 | cannot_follow_bot: "无法关注机器人用户" 28 | cannot_follow_suspended: "无法关注已被封禁的用户" 29 | cannot_follow_staged: "无法关注暂存用户" 30 | invalid_created_before_date: "`created_before` 参数收到无效日期:%{value}" 31 | user_does_not_allow_follow: "%{username} 不允许其他人关注他。" 32 | -------------------------------------------------------------------------------- /config/locales/server.zh_TW.yml: -------------------------------------------------------------------------------- 1 | # WARNING: Never edit this file. 2 | # It will be overwritten when translations are pulled from Crowdin. 3 | # 4 | # To work with us on translations, join this project: 5 | # https://translate.discourse.org/ 6 | 7 | zh_TW: 8 | discourse_push_notifications: 9 | popup: 10 | following_replied: '%{username} 在"%{topic}" 中發文 - %{site_title}' 11 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Follow::Engine.routes.draw do 4 | put ":username" => "follow#follow", 5 | :constraints => { 6 | username: RouteFormat.username, 7 | format: /(json|html)/, 8 | }, 9 | :defaults => { 10 | format: :json, 11 | } 12 | 13 | delete ":username" => "follow#unfollow", 14 | :constraints => { 15 | username: RouteFormat.username, 16 | format: /(json|html)/, 17 | }, 18 | :defaults => { 19 | format: :json, 20 | } 21 | 22 | get "posts/:username" => "follow#posts", 23 | :constraints => { 24 | username: RouteFormat.username, 25 | format: /(json|html)/, 26 | }, 27 | :defaults => { 28 | format: :json, 29 | } 30 | end 31 | 32 | Discourse::Application.routes.draw do 33 | mount ::Follow::Engine, at: "follow" 34 | 35 | %w[users u].each_with_index do |root_path, index| 36 | get "#{root_path}/:username/follow" => "follow/follow#index", 37 | :constraints => { 38 | username: RouteFormat.username, 39 | } 40 | 41 | get "#{root_path}/:username/follow/feed" => "follow/follow#index", 42 | :constraints => { 43 | username: RouteFormat.username, 44 | } 45 | 46 | get "#{root_path}/:username/follow/following" => "follow/follow#list_following", 47 | :constraints => { 48 | username: RouteFormat.username, 49 | } 50 | 51 | get "#{root_path}/:username/follow/followers" => "follow/follow#list_followers", 52 | :constraints => { 53 | username: RouteFormat.username, 54 | } 55 | end 56 | end 57 | -------------------------------------------------------------------------------- /config/settings.yml: -------------------------------------------------------------------------------- 1 | discourse_follow: 2 | discourse_follow_enabled: 3 | default: false 4 | client: true 5 | follow_show_statistics_on_profile: 6 | default: true 7 | client: true 8 | follow_notifications_enabled: 9 | default: true 10 | client: true 11 | follow_followers_visible: 12 | enum: "FollowPagesVisibility" 13 | default: everyone 14 | follow_following_visible: 15 | enum: "FollowPagesVisibility" 16 | default: everyone 17 | default_notify_me_when_followed: 18 | default: true 19 | default_notify_followed_user_when_followed: 20 | default: true 21 | default_notify_me_when_followed_replies: 22 | default: false 23 | default_notify_me_when_followed_creates_topic: 24 | default: false 25 | default_allow_people_to_follow_me: 26 | default: true 27 | -------------------------------------------------------------------------------- /db/migrate/20210901115010_create_user_follower.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class CreateUserFollower < ActiveRecord::Migration[6.1] 4 | def change 5 | create_table :user_followers do |t| 6 | t.bigint :user_id, null: false 7 | t.bigint :follower_id, null: false 8 | t.integer :level, null: false 9 | 10 | t.timestamps null: false 11 | end 12 | 13 | add_index :user_followers, %i[user_id follower_id], unique: true 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /db/migrate/20210901135131_migrate_follower_data_from_custom_fields_to_tables.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class MigrateFollowerDataFromCustomFieldsToTables < ActiveRecord::Migration[6.1] 4 | def up 5 | DB.exec <<~SQL 6 | INSERT INTO user_followers (follower_id, user_id, level, updated_at, created_at) ( 7 | SELECT 8 | user_id::bigint AS follower_id, 9 | split_part(value, ',', 1)::bigint AS user_id, 10 | ( 11 | CASE 12 | WHEN split_part(value, ',', 2)::integer = 0 THEN 3 13 | WHEN split_part(value, ',', 2)::integer = 1 THEN 4 14 | ELSE split_part(value, ',', 2)::integer 15 | END 16 | ) AS level, 17 | updated_at, 18 | created_at 19 | FROM user_custom_fields 20 | WHERE name = 'following' AND TRIM(value) != '' AND user_id >= 1 21 | ) 22 | ON CONFLICT DO NOTHING 23 | SQL 24 | 25 | DB.exec <<~SQL 26 | DELETE FROM user_custom_fields WHERE name = 'following' OR name = 'followers' 27 | SQL 28 | end 29 | 30 | def down 31 | DB.exec <<~SQL 32 | INSERT INTO user_custom_fields (user_id, name, value, created_at, updated_at) ( 33 | SELECT 34 | follower_id::integer AS user_id, 35 | 'following' AS name, 36 | user_id::text || ',' || level::text AS value, 37 | created_at, 38 | updated_at 39 | FROM user_followers 40 | ) 41 | SQL 42 | 43 | DB.exec <<~SQL 44 | INSERT INTO user_custom_fields (user_id, name, value, created_at, updated_at) ( 45 | SELECT 46 | user_id::integer AS user_id, 47 | 'followers' AS name, 48 | ARRAY_TO_STRING(ARRAY_AGG(follower_id), ',') AS value, 49 | CURRENT_TIMESTAMP AS created_at, 50 | CURRENT_TIMESTAMP AS updated_at 51 | FROM user_followers 52 | GROUP BY user_id 53 | ) 54 | SQL 55 | 56 | DB.exec("DELETE FROM user_followers") 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /db/migrate/20210920045747_rename_follow_plugin_preference.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class RenameFollowPluginPreference < ActiveRecord::Migration[6.1] 4 | def up 5 | DB.exec <<~SQL 6 | UPDATE user_custom_fields ucf 7 | SET name = 'notify_me_when_followed_creates_topic' 8 | WHERE ucf.name = 'notify_me_when_followed_posts' 9 | SQL 10 | end 11 | 12 | def down 13 | DB.exec <<~SQL 14 | UPDATE user_custom_fields ucf 15 | SET name = 'notify_me_when_followed_posts' 16 | WHERE ucf.name = 'notify_me_when_followed_creates_topic' 17 | SQL 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /db/migrate/20211004125251_create_follow_user_custom_fields_indices.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class CreateFollowUserCustomFieldsIndices < ActiveRecord::Migration[6.1] 4 | def up 5 | %w[ 6 | notify_me_when_followed 7 | notify_followed_user_when_followed 8 | notify_me_when_followed_replies 9 | notify_me_when_followed_creates_topic 10 | allow_people_to_follow_me 11 | ].each do |field| 12 | DB.exec(<<~SQL, field: field) 13 | DELETE FROM user_custom_fields ucf1 14 | USING user_custom_fields ucf2 15 | WHERE ucf1.id != ucf2.id 16 | AND ucf1.name = :field 17 | AND ucf2.name = :field 18 | AND ucf1.user_id = ucf2.user_id 19 | AND ucf1.updated_at < ucf2.updated_at 20 | SQL 21 | add_index( 22 | :user_custom_fields, 23 | %i[name user_id], 24 | name: index_name_for(field), 25 | unique: true, 26 | where: "name = '#{field}'", 27 | ) 28 | end 29 | end 30 | 31 | def down 32 | %w[ 33 | notify_me_when_followed 34 | notify_followed_user_when_followed 35 | notify_me_when_followed_replies 36 | notify_me_when_followed_creates_topic 37 | allow_people_to_follow_me 38 | ].each do |field| 39 | remove_index(:user_custom_fields, name: index_name_for(field), if_exists: true) 40 | end 41 | end 42 | 43 | private 44 | 45 | def index_name_for(name) 46 | :"idx_user_custom_fields_#{name}" 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /db/migrate/20211011123651_correct_follow_plugin_site_setting_values.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class CorrectFollowPluginSiteSettingValues < ActiveRecord::Migration[6.1] 4 | def up 5 | DB.exec(<<~SQL) 6 | UPDATE site_settings 7 | SET value = 'no-one' 8 | WHERE name IN ('follow_followers_visible', 'follow_following_visible') AND value = 'none' 9 | SQL 10 | end 11 | 12 | def down 13 | raise ActiveRecord::IrreversibleMigration 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /db/migrate/20220617173420_enable_follow_if_already_installed.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class EnableFollowIfAlreadyInstalled < ActiveRecord::Migration[6.1] 4 | def up 5 | follow_installed_at = DB.query_single(<<~SQL)&.first 6 | SELECT created_at FROM schema_migration_details WHERE version='20210901115010' 7 | SQL 8 | 9 | if follow_installed_at && follow_installed_at < 1.hour.ago 10 | # The plugin was installed before we changed it to be disabled-by-default 11 | # Therefore, if there is no existing database value, enable the plugin 12 | execute <<~SQL 13 | INSERT INTO site_settings(name, data_type, value, created_at, updated_at) 14 | VALUES('discourse_follow_enabled', 5, 't', NOW(), NOW()) 15 | ON CONFLICT (name) DO NOTHING 16 | SQL 17 | end 18 | end 19 | 20 | def down 21 | # do nothing 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import DiscourseRecommended from "@discourse/lint-configs/eslint"; 2 | 3 | export default [...DiscourseRecommended]; 4 | -------------------------------------------------------------------------------- /lib/follow/engine.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module ::Follow 4 | class Engine < ::Rails::Engine 5 | engine_name "follow" 6 | isolate_namespace Follow 7 | config.autoload_paths << File.join(config.root, "lib") 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/follow/notification.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class Follow::Notification 4 | def self.levels 5 | @levels ||= Enum.new(regular: 1, watching: 3, watching_first_post: 4) 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/follow/notification_handler.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class Follow::NotificationHandler 4 | attr_reader :post 5 | 6 | def initialize(post, notified_users) 7 | @post = post 8 | @notified_users = notified_users 9 | end 10 | 11 | def handle 12 | return if post.post_type == Post.types[:whisper] && post.action_code.present? 13 | return if [Post.types[:regular], Post.types[:whisper]].exclude?(post.post_type) 14 | return if !SiteSetting.follow_notifications_enabled 15 | return if !post.user.allow_people_to_follow_me 16 | return if post.user.user_option&.hide_profile 17 | 18 | topic = post.topic 19 | return if !topic || topic.private_message? 20 | 21 | poster_followers.each do |follower| 22 | next if follower.bot? || follower.staged? 23 | next if topic_muted_by?(follower) 24 | 25 | if post.post_number == 1 26 | next if !follower.notify_me_when_followed_creates_topic 27 | else 28 | next if !follower.notify_me_when_followed_replies 29 | end 30 | 31 | guardian = Guardian.new(follower) 32 | next if !guardian.can_see?(post) 33 | 34 | if post.post_number == 1 35 | notification_type = Notification.types[:following_created_topic] 36 | else 37 | notification_type = Notification.types[:following_replied] 38 | end 39 | 40 | # sometimes the `post_alerter_after_save_post` event can be fired twice 41 | # for the same post resulting (incorrectly) in merged or double 42 | # notifications. skip if we've already created a notification for this 43 | # post 44 | next if already_notified?(follower, notification_type) 45 | 46 | # if the user has received a notification for the post because they're 47 | # watching the topic, category or a tag, then delete the notification so 48 | # they don't end up with double notifications. 49 | # 50 | # the `notified` array provided by the event includes users who are 51 | # notified due to a mention (directly or via a group), quote, link to a 52 | # post of theirs, or reply to them directly. It does not include users 53 | # who are notified because they're watching the topic, category or a tag. 54 | follower 55 | .notifications 56 | .where( 57 | topic_id: topic.id, 58 | notification_type: [Notification.types[:posted], Notification.types[:replied]], 59 | post_number: post.post_number, 60 | ) 61 | .destroy_all 62 | 63 | # delete all existing follow notifications for the topic because we'll 64 | # collapse them 65 | follower 66 | .notifications 67 | .where( 68 | topic_id: topic.id, 69 | notification_type: [ 70 | Notification.types[:following_replied], 71 | Notification.types[:following_created_topic], 72 | ], 73 | ) 74 | .destroy_all 75 | 76 | posts_by_following = 77 | topic 78 | .posts 79 | .secured(guardian) 80 | .where(user_id: follower.following.pluck(:id)) 81 | .where(<<~SQL, follower_id: follower.id, topic_id: topic.id) 82 | post_number > COALESCE(( 83 | SELECT last_read_post_number FROM topic_users tu 84 | WHERE tu.user_id = :follower_id AND tu.topic_id = :topic_id 85 | ), 0) 86 | SQL 87 | 88 | count = posts_by_following.count 89 | first_unread_post = posts_by_following.order("post_number").first || post 90 | 91 | display_username = first_unread_post.user.username 92 | if count > 1 93 | I18n.with_locale(follower.effective_locale) do 94 | display_username = I18n.t("embed.replies", count: count) 95 | end 96 | end 97 | 98 | notification_data = { 99 | topic_title: topic.title, 100 | original_post_id: post.id, 101 | original_post_type: post.post_type, 102 | display_username: display_username, 103 | } 104 | 105 | notification = 106 | follower.notifications.create!( 107 | notification_type: notification_type, 108 | topic_id: topic.id, 109 | post_number: first_unread_post.post_number, 110 | data: notification_data.to_json, 111 | ) 112 | @notified_users << follower 113 | 114 | if notification&.id && !follower.suspended? 115 | PostAlerter.create_notification_alert( 116 | user: follower, 117 | post: post, 118 | notification_type: notification_type, 119 | ) 120 | end 121 | end 122 | end 123 | 124 | private 125 | 126 | def topic_muted_by?(user) 127 | TopicUser.exists?( 128 | topic_id: post.topic.id, 129 | user_id: user.id, 130 | notification_level: TopicUser.notification_levels[:muted], 131 | ) 132 | end 133 | 134 | def already_notified?(user, notification_type) 135 | Notification.exists?( 136 | topic_id: post.topic.id, 137 | user_id: user.id, 138 | notification_type: notification_type, 139 | post_number: post.post_number, 140 | ) 141 | end 142 | 143 | def poster_followers 144 | followers = post.user.followers 145 | if @notified_users.present? 146 | followers = followers.where("users.id NOT IN (?)", @notified_users.map(&:id)) 147 | end 148 | followers 149 | end 150 | end 151 | -------------------------------------------------------------------------------- /lib/follow/updater.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class Follow::Updater 4 | def initialize(follower, target) 5 | @follower = follower 6 | @target = target 7 | end 8 | 9 | def watch_follow 10 | follow(Follow::Notification.levels[:watching]) 11 | end 12 | 13 | def unfollow 14 | UserFollower.where(follower_id: @follower.id, user_id: @target.id).destroy_all 15 | end 16 | 17 | private 18 | 19 | def follow(notification_level) 20 | if @target.id == @follower.id 21 | raise Discourse::InvalidAccess.new( 22 | nil, 23 | nil, 24 | custom_message: "follow.user_cannot_follow_themself", 25 | ) 26 | end 27 | 28 | %i[bot staged suspended].each do |status| 29 | if @target.public_send(:"#{status}?") 30 | raise Discourse::InvalidAccess.new( 31 | nil, 32 | nil, 33 | custom_message: "follow.user_cannot_follow_#{status}", 34 | ) 35 | end 36 | end 37 | 38 | if !Follow::Notification.levels.invert.key?(notification_level) 39 | raise Discourse::InvalidParameters.new( 40 | I18n.t("follow.invalid_notification_level", level: notification_level.inspect), 41 | ) 42 | end 43 | 44 | if !@target.allow_people_to_follow_me 45 | raise Discourse::InvalidAccess.new( 46 | nil, 47 | nil, 48 | custom_message: "follow.user_does_not_allow_follow", 49 | custom_message_params: { 50 | username: @target.username, 51 | }, 52 | ) 53 | end 54 | 55 | if @target.user_option&.hide_profile 56 | raise Discourse::InvalidAccess.new( 57 | nil, 58 | nil, 59 | custom_message: "follow.user_does_not_allow_follow", 60 | custom_message_params: { 61 | username: @target.username, 62 | }, 63 | ) 64 | end 65 | 66 | relation = UserFollower.find_or_initialize_by(user_id: @target.id, follower_id: @follower.id) 67 | relation.level = notification_level 68 | relation.save! 69 | 70 | payload = { 71 | notification_type: Notification.types[:following], 72 | data: { display_username: @follower.username }.to_json, 73 | } 74 | send_notification(payload) if should_notify?(payload) 75 | 76 | relation 77 | end 78 | 79 | def should_notify?(payload) 80 | SiteSetting.follow_notifications_enabled && @follower.notify_followed_user_when_followed && 81 | @target.notify_me_when_followed && !notification_sent_recently(payload) 82 | end 83 | 84 | def send_notification(payload) 85 | @target.notifications.create!(payload) 86 | end 87 | 88 | def notification_sent_recently(payload) 89 | @target.notifications.where(payload).where("created_at >= ?", 1.day.ago).exists? 90 | end 91 | end 92 | -------------------------------------------------------------------------------- /lib/follow/user_extension.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Follow::UserExtension 4 | def self.prepended(base) 5 | base.has_many :follower_relations, class_name: "UserFollower", dependent: :delete_all 6 | base.has_many :followers, 7 | ->(user) do 8 | if !user.allow_people_to_follow_me || user.user_option&.hide_profile 9 | where("1=0") 10 | end 11 | end, 12 | through: :follower_relations, 13 | source: :follower_user 14 | 15 | base.has_many :following_relations, 16 | class_name: "UserFollower", 17 | foreign_key: :follower_id, 18 | dependent: :delete_all 19 | base.has_many :following, 20 | -> { UserFollower.filter_opted_out_users(self) }, 21 | through: :following_relations, 22 | source: :followed_user 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "devDependencies": { 4 | "@discourse/lint-configs": "2.23.0", 5 | "ember-template-lint": "7.7.0", 6 | "eslint": "9.28.0", 7 | "prettier": "3.5.3", 8 | "stylelint": "16.20.0" 9 | }, 10 | "engines": { 11 | "node": ">= 22", 12 | "npm": "please-use-pnpm", 13 | "yarn": "please-use-pnpm", 14 | "pnpm": "9.x" 15 | }, 16 | "packageManager": "pnpm@9.15.5" 17 | } 18 | -------------------------------------------------------------------------------- /plugin.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # name: discourse-follow 4 | # about: Allows users to follow other users, list the latest topics involving them, and receive notifications when they post. 5 | # meta_topic_id: 110579 6 | # version: 1.0 7 | # authors: Angus McLeod, Robert Barrow, CDCK Inc 8 | # url: https://github.com/discourse/discourse-follow 9 | 10 | enabled_site_setting :discourse_follow_enabled 11 | 12 | register_asset "stylesheets/common/follow.scss" 13 | 14 | register_svg_icon "discourse-follow-new-reply" 15 | register_svg_icon "discourse-follow-new-follower" 16 | register_svg_icon "discourse-follow-new-topic" 17 | 18 | module ::Follow 19 | PLUGIN_NAME = "discourse-follow" 20 | end 21 | 22 | require_relative "lib/follow/engine" 23 | 24 | after_initialize do 25 | Notification.types[:following] = 800 26 | Notification.types[:following_created_topic] = 801 27 | Notification.types[:following_replied] = 802 28 | 29 | reloadable_patch { |plugin| User.prepend(Follow::UserExtension) } 30 | 31 | add_to_serializer(:user, :can_see_following) do 32 | FollowPagesVisibility.can_see_following_page?(user: scope.current_user, target_user: user) 33 | end 34 | add_to_serializer(:user, :can_see_followers) do 35 | FollowPagesVisibility.can_see_followers_page?(user: scope.current_user, target_user: user) 36 | end 37 | add_to_serializer(:user, :can_see_network_tab) do 38 | user_is_current_user || can_see_following || can_see_followers 39 | end 40 | 41 | # UserSerializer in core inherits from UserCardSerializer. 42 | # we don't need to duplicate these attrs for UserSerializer. 43 | # 44 | # the `!options.key?(:each_serializer)` check is a temporary hack to exclude 45 | # the attributes we add here from the user card serializer when multiple user 46 | # objects are being serialized (e.g. the /user-cards.json route in core). If 47 | # we don't do this, we end up introducing a horrible 3N+1 on the 48 | # /user-cards.json route and it's not easily fixable. 49 | # when serializing a single user object, the options of the serializer 50 | # doesn't have a `each_serializer` key. 51 | add_to_serializer(:user_card, :can_follow) do 52 | !options.key?(:each_serializer) && scope.current_user.present? && user.allow_people_to_follow_me 53 | end 54 | 55 | add_to_serializer(:user_card, :is_followed) do 56 | !options.key?(:each_serializer) && scope.current_user.present? && 57 | scope.current_user.following.where(id: user.id).exists? 58 | end 59 | 60 | add_to_serializer( 61 | :user_card, 62 | :total_followers, 63 | include_condition: -> do 64 | !options.key?(:each_serializer) && SiteSetting.discourse_follow_enabled && 65 | SiteSetting.follow_show_statistics_on_profile && 66 | FollowPagesVisibility.can_see_followers_page?(user: scope.current_user, target_user: object) 67 | end, 68 | ) { object.followers.count } 69 | 70 | add_to_serializer( 71 | :user_card, 72 | :total_following, 73 | include_condition: -> do 74 | !options.key?(:each_serializer) && SiteSetting.discourse_follow_enabled && 75 | SiteSetting.follow_show_statistics_on_profile && 76 | FollowPagesVisibility.can_see_following_page?(user: scope.current_user, target_user: object) 77 | end, 78 | ) { object.following.count } 79 | 80 | %i[ 81 | notify_me_when_followed 82 | notify_followed_user_when_followed 83 | notify_me_when_followed_replies 84 | notify_me_when_followed_creates_topic 85 | allow_people_to_follow_me 86 | ].each do |field| 87 | add_to_class(:user, field) do 88 | v = custom_fields[field] 89 | if !v.nil? 90 | HasCustomFields::Helpers::CUSTOM_FIELD_TRUE.include?(v.to_s.downcase) 91 | else 92 | SiteSetting.public_send(:"default_#{field}") 93 | end 94 | end 95 | 96 | User.register_custom_field_type(field, :boolean) 97 | DiscoursePluginRegistry.serialized_current_user_fields << field 98 | add_to_serializer(:user, field) { object.public_send(field) } 99 | register_editable_user_custom_field(field) 100 | end 101 | 102 | on(:post_alerter_before_post) do |post, new_record, notified| 103 | Follow::NotificationHandler.new(post, notified).handle if new_record 104 | end 105 | 106 | # TODO(2022-08-30): Remove when post_alerter_before_post is available 107 | on(:post_alerter_after_save_post) do |post, new_record, notified| 108 | next if !new_record 109 | Follow::NotificationHandler.new(post, notified).handle 110 | end 111 | 112 | filter_following_topics = ->(scope, username, guardian) do 113 | user = User.find_by(username: username) 114 | 115 | next scope if user.nil? 116 | next scope.none if user.id != guardian.user.id && !guardian.user.staff? 117 | 118 | topic_ids = UserFollower.topics_for(user, current_user: guardian.user).pluck(:id) 119 | 120 | scope.where("topics.id IN (?)", topic_ids) 121 | end 122 | 123 | add_filter_custom_filter("following-feed", &filter_following_topics) 124 | end 125 | -------------------------------------------------------------------------------- /spec/integration/user_cards_route_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "rails_helper" 4 | 5 | describe "Attrs added by the plugin to the UserCardSerializer" do 6 | fab!(:follower) { Fabricate(:user) } 7 | fab!(:followed) { Fabricate(:user) } 8 | 9 | before do 10 | SiteSetting.discourse_follow_enabled = true 11 | Follow::Updater.new(follower, followed).watch_follow 12 | sign_in(follower) 13 | end 14 | 15 | it "do not break the /user-cards.json route" do 16 | get "/user-cards.json", params: { user_ids: [followed.id].join(",") } 17 | expect(response.status).to eq(200) 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /spec/integration/user_destroyer_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "rails_helper" 4 | 5 | describe "User destroyer with the follow plugin" do 6 | let(:user_a) { Fabricate(:user) } 7 | let(:user_b) { Fabricate(:user) } 8 | let(:user_c) { Fabricate(:user) } 9 | 10 | before do 11 | SiteSetting.discourse_follow_enabled = true 12 | Jobs.run_immediately! 13 | Follow::Updater.new(user_a, user_b).watch_follow 14 | Follow::Updater.new(user_c, user_a).watch_follow 15 | end 16 | 17 | it "deletes all the follower and following relationships of the user being deleted" do 18 | UserDestroyer.new(Discourse.system_user).destroy(user_a) 19 | user_b.reload 20 | user_c.reload 21 | expect(user_b.id).to be_present 22 | expect(user_c.id).to be_present 23 | expect(user_b.follower_relations.count).to eq(0) 24 | expect(user_c.following_relations.count).to eq(0) 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /spec/models/user_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "rails_helper" 4 | 5 | describe User do 6 | fab!(:followed1) { Fabricate(:user) } 7 | fab!(:followed2) { Fabricate(:user) } 8 | fab!(:follower1) { Fabricate(:user) } 9 | fab!(:follower2) { Fabricate(:user) } 10 | 11 | before do 12 | SiteSetting.discourse_follow_enabled = true 13 | [followed1, followed2].each do |followed| 14 | [follower1, follower2].each do |follower| 15 | Follow::Updater.new(follower, followed).watch_follow 16 | end 17 | end 18 | end 19 | 20 | describe "#followers" do 21 | it "returns followers" do 22 | expect(followed1.followers.pluck(:id)).to contain_exactly(follower1.id, follower2.id) 23 | expect(followed2.followers.pluck(:id)).to contain_exactly(follower1.id, follower2.id) 24 | 25 | expect(follower1.followers.pluck(:id)).to be_empty 26 | expect(follower2.followers.pluck(:id)).to be_empty 27 | end 28 | 29 | it "returns empty relation if the user has disabled follows" do 30 | followed1.custom_fields["allow_people_to_follow_me"] = false 31 | followed1.save! 32 | expect(followed1.followers.pluck(:id)).to be_empty 33 | expect(followed2.followers.pluck(:id)).to contain_exactly(follower1.id, follower2.id) 34 | end 35 | 36 | it "returns empty relation if the user has hidden their profile" do 37 | followed1.user_option.update!(hide_profile: true) 38 | expect(followed1.followers.pluck(:id)).to be_empty 39 | expect(followed2.followers.pluck(:id)).to contain_exactly(follower1.id, follower2.id) 40 | end 41 | 42 | it "returns empty relation if the default_allow_people_to_follow_me setting " \ 43 | "is false and the user has no explicit preference" do 44 | SiteSetting.default_allow_people_to_follow_me = false 45 | expect(followed1.followers.pluck(:id)).to be_empty 46 | expect(followed2.followers.pluck(:id)).to be_empty 47 | 48 | followed1.custom_fields["allow_people_to_follow_me"] = true 49 | followed1.save! 50 | expect(followed1.followers.pluck(:id)).to contain_exactly(follower1.id, follower2.id) 51 | expect(followed2.followers.pluck(:id)).to be_empty 52 | end 53 | end 54 | 55 | describe "#following" do 56 | it "returns followed users" do 57 | expect(follower1.following.pluck(:id)).to contain_exactly(followed1.id, followed2.id) 58 | expect(follower2.following.pluck(:id)).to contain_exactly(followed1.id, followed2.id) 59 | 60 | expect(followed1.following.pluck(:id)).to be_empty 61 | expect(followed2.following.pluck(:id)).to be_empty 62 | end 63 | 64 | it "excludes users who have disabled follows" do 65 | followed1.custom_fields["allow_people_to_follow_me"] = false 66 | followed1.save! 67 | 68 | expect(follower1.following.pluck(:id)).to contain_exactly(followed2.id) 69 | expect(follower2.following.pluck(:id)).to contain_exactly(followed2.id) 70 | end 71 | 72 | it "excludes users who have hidden their profile" do 73 | followed1.user_option.update!(hide_profile: true) 74 | 75 | expect(follower1.following.pluck(:id)).to contain_exactly(followed2.id) 76 | expect(follower2.following.pluck(:id)).to contain_exactly(followed2.id) 77 | end 78 | 79 | it "excludes users who do not have an explicit preference and the " \ 80 | "default_allow_people_to_follow_me setting is false" do 81 | SiteSetting.default_allow_people_to_follow_me = false 82 | expect(follower1.following.pluck(:id)).to be_empty 83 | expect(follower2.following.pluck(:id)).to be_empty 84 | 85 | followed1.custom_fields["allow_people_to_follow_me"] = true 86 | followed1.save! 87 | 88 | expect(follower1.following.pluck(:id)).to contain_exactly(followed1.id) 89 | expect(follower2.following.pluck(:id)).to contain_exactly(followed1.id) 90 | end 91 | end 92 | end 93 | -------------------------------------------------------------------------------- /spec/serializers/user_card_serializer_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "rails_helper" 4 | 5 | describe UserCardSerializer do 6 | fab!(:follower) { Fabricate(:user) } 7 | fab!(:followed) { Fabricate(:user) } 8 | 9 | before do 10 | SiteSetting.discourse_follow_enabled = true 11 | ::Follow::Updater.new(follower, followed).watch_follow 12 | end 13 | 14 | def get_serializer(user, current_user:) 15 | UserCardSerializer.new(user, scope: Guardian.new(current_user), root: false).as_json 16 | end 17 | 18 | context "when no settings are restrictive" do 19 | before do 20 | SiteSetting.discourse_follow_enabled = true 21 | SiteSetting.follow_show_statistics_on_profile = true 22 | SiteSetting.follow_followers_visible = FollowPagesVisibility::EVERYONE 23 | SiteSetting.follow_following_visible = FollowPagesVisibility::EVERYONE 24 | end 25 | 26 | it "is_followed field is included" do 27 | expect(get_serializer(followed, current_user: follower)[:is_followed]).to eq(true) 28 | end 29 | 30 | it "total_followers field is included" do 31 | expect(get_serializer(followed, current_user: nil)[:total_followers]).to eq(1) 32 | end 33 | 34 | it "total_following field is included" do 35 | expect(get_serializer(follower, current_user: nil)[:total_following]).to eq(1) 36 | end 37 | end 38 | 39 | context "when discourse_follow_enabled setting is off" do 40 | before { SiteSetting.discourse_follow_enabled = false } 41 | 42 | it "is_followed field is not included" do 43 | expect(get_serializer(followed, current_user: follower)).not_to include(:is_followed) 44 | end 45 | 46 | it "total_followers field is not included" do 47 | expect(get_serializer(followed, current_user: followed)).not_to include(:total_followers) 48 | end 49 | 50 | it "total_following field is not included" do 51 | expect(get_serializer(follower, current_user: follower)).not_to include(:total_following) 52 | end 53 | end 54 | 55 | context "when follow_show_statistics_on_profile setting is off" do 56 | before { SiteSetting.follow_show_statistics_on_profile = false } 57 | 58 | it "is_followed field is included" do 59 | expect(get_serializer(followed, current_user: follower)[:is_followed]).to eq(true) 60 | end 61 | 62 | it "total_followers field is not included" do 63 | expect(get_serializer(followed, current_user: followed)).not_to include(:total_followers) 64 | end 65 | 66 | it "total_following field is not included" do 67 | expect(get_serializer(follower, current_user: follower)).not_to include(:total_following) 68 | end 69 | end 70 | 71 | context "when follow_followers_visible does not allow anyone" do 72 | before { SiteSetting.follow_followers_visible = FollowPagesVisibility::NO_ONE } 73 | 74 | it "total_followers field is not included" do 75 | expect(get_serializer(followed, current_user: followed)).not_to include(:total_followers) 76 | end 77 | 78 | it "total_following field is included" do 79 | expect(get_serializer(follower, current_user: follower)[:total_following]).to eq(1) 80 | end 81 | end 82 | 83 | context "when follow_following_visible does not allow anyone" do 84 | before { SiteSetting.follow_following_visible = FollowPagesVisibility::NO_ONE } 85 | 86 | it "total_followers field is included" do 87 | expect(get_serializer(followed, current_user: followed)[:total_followers]).to eq(1) 88 | end 89 | 90 | it "total_following field is not included" do 91 | expect(get_serializer(follower, current_user: follower)).not_to include(:total_following) 92 | end 93 | end 94 | 95 | context "when there is no current user" do 96 | it "is_followed is false" do 97 | expect(get_serializer(followed, current_user: nil)[:is_followed]).to eq(false) 98 | end 99 | 100 | it "can_follow is false" do 101 | expect(get_serializer(followed, current_user: nil)[:can_follow]).to eq(false) 102 | end 103 | end 104 | 105 | context "when there is current user" do 106 | it "is_followed is true if current user is following the user" do 107 | expect(get_serializer(followed, current_user: follower)[:is_followed]).to eq(true) 108 | end 109 | 110 | it "is_followed is false if current user is not following the user" do 111 | expect(get_serializer(followed, current_user: Fabricate(:user))[:is_followed]).to eq(false) 112 | end 113 | 114 | it "can_follow is true" do 115 | expect(get_serializer(followed, current_user: Fabricate(:user))[:can_follow]).to eq(true) 116 | end 117 | 118 | it "can_follow is false if user disables follows" do 119 | followed.custom_fields["allow_people_to_follow_me"] = false 120 | followed.save! 121 | expect(get_serializer(followed, current_user: follower)[:can_follow]).to eq(false) 122 | expect(get_serializer(followed, current_user: Fabricate(:user))[:can_follow]).to eq(false) 123 | expect(get_serializer(followed, current_user: nil)[:can_follow]).to eq(false) 124 | end 125 | end 126 | end 127 | -------------------------------------------------------------------------------- /spec/system/core_features_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.describe "Core features", type: :system do 4 | before { enable_current_plugin } 5 | 6 | it_behaves_like "having working core features" 7 | end 8 | -------------------------------------------------------------------------------- /spec/system/follow_user_pages_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.describe "Follow user pages", type: :system, js: true do 4 | fab!(:user1) { Fabricate(:user) } 5 | fab!(:user2) { Fabricate(:user) } 6 | fab!(:user3) { Fabricate(:user) } 7 | fab!(:user2_post) { Fabricate(:post, user: user2) } 8 | let(:everyone_group) { Group[:everyone] } 9 | 10 | before do 11 | SiteSetting.discourse_follow_enabled = true 12 | SiteSetting.follow_followers_visible = FollowPagesVisibility::EVERYONE 13 | SiteSetting.follow_following_visible = FollowPagesVisibility::EVERYONE 14 | 15 | Follow::Updater.new(user1, user2).watch_follow 16 | Follow::Updater.new(user3, user1).watch_follow 17 | end 18 | 19 | before { sign_in(user1) } 20 | 21 | it "should allow user to navigate to the follow user profile pages" do 22 | follow_page = PageObjects::Pages::Follow.new(user1) 23 | follow_page.visit 24 | 25 | expect(follow_page).to have_following_topic(user2_post.topic) 26 | 27 | follow_page.click_on_followers 28 | 29 | expect(follow_page).to have_follower(user3) 30 | 31 | follow_page.click_on_following 32 | 33 | expect(follow_page).to have_following(user2) 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /spec/system/follow_user_preferences_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.describe "Follow user preferences", type: :system, js: true do 4 | fab!(:user) 5 | 6 | before do 7 | SiteSetting.discourse_follow_enabled = true 8 | sign_in(user) 9 | end 10 | 11 | it "should allow user to modify preferences" do 12 | visit("/u/#{user.username}/preferences/notifications") 13 | 14 | expect(user.custom_fields["allow_people_to_follow_me"]).to eq(nil) 15 | 16 | checkbox1 = page.find(".pref-allow-people-to-follow-me input") 17 | expect(checkbox1).to be_checked 18 | 19 | checkbox1.click 20 | page.find(".save-changes").click 21 | expect(page).to have_content(I18n.t("js.saved")) 22 | 23 | # Navigate away 24 | visit("/latest") 25 | 26 | # Come back to user preferences and check that the checkbox is now unchecked 27 | visit("/u/#{user.username}/preferences/notifications") 28 | 29 | checkbox1 = page.find(".pref-allow-people-to-follow-me input") 30 | expect(checkbox1).not_to be_checked 31 | 32 | expect(user.reload.custom_fields["allow_people_to_follow_me"]).to eq("false") 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /spec/system/page_objects/pages/follow.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module PageObjects 4 | module Pages 5 | class Follow < PageObjects::Pages::Base 6 | CONTENT_CLASS = ".user-follows-tab" 7 | 8 | def initialize(user) 9 | super() 10 | @user = user 11 | end 12 | 13 | def visit 14 | page.visit("/u/#{@user.username}") 15 | click_on I18n.t("js.user.follow_nav") 16 | self 17 | end 18 | 19 | def click_on_followers 20 | click_on I18n.t("js.user.followers.label") 21 | self 22 | end 23 | 24 | def click_on_following 25 | click_on I18n.t("js.user.following.label") 26 | self 27 | end 28 | 29 | def has_follower?(user) 30 | within(CONTENT_CLASS) { page.has_content?(user.username) } 31 | end 32 | alias_method :has_following?, :has_follower? 33 | 34 | def has_following_topic?(topic) 35 | within(CONTENT_CLASS) { page.has_content?(topic.title) } 36 | end 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /stylelint.config.mjs: -------------------------------------------------------------------------------- 1 | export default { 2 | extends: ["@discourse/lint-configs/stylelint"], 3 | }; 4 | -------------------------------------------------------------------------------- /svg-icons/plugin-icons.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /test/javascripts/acceptance/follow-notification-test.js: -------------------------------------------------------------------------------- 1 | import { visit } from "@ember/test-helpers"; 2 | import { test } from "qunit"; 3 | import { acceptance } from "discourse/tests/helpers/qunit-helpers"; 4 | import { i18n } from "discourse-i18n"; 5 | 6 | acceptance("Discourse Follow - notification", function (needs) { 7 | needs.user(); 8 | 9 | needs.pretender((server, helper) => { 10 | server.get("/notifications", () => { 11 | return helper.response({ 12 | notifications: [ 13 | { 14 | id: 25201, 15 | user_id: 1, 16 | external_id: "1", 17 | notification_type: 800, 18 | read: false, 19 | high_priority: false, 20 | slug: null, 21 | data: { 22 | display_username: "steaky", 23 | }, 24 | created_at: "2023-12-06 21:39:57.412408", 25 | }, 26 | ], 27 | total_rows_notifications: 1, 28 | }); 29 | }); 30 | }); 31 | 32 | test("shows follow notification", async (assert) => { 33 | await visit("/u/eviltrout/notifications"); 34 | 35 | const notification = document.querySelector( 36 | ".user-notifications-list .notification" 37 | ); 38 | 39 | assert.strictEqual( 40 | notification.querySelector(".item-label").textContent.trim(), 41 | "steaky", 42 | "Renders username" 43 | ); 44 | 45 | assert.strictEqual( 46 | notification.querySelector(".item-description").textContent.trim(), 47 | "has started following you.", 48 | "Renders description" 49 | ); 50 | 51 | assert.ok( 52 | notification.querySelector("a").href.includes("/u/steaky"), 53 | "leads to the user's profile" 54 | ); 55 | 56 | assert.strictEqual( 57 | notification.querySelector("a").title, 58 | i18n("notifications.titles.following"), 59 | "displays the right title" 60 | ); 61 | }); 62 | }); 63 | -------------------------------------------------------------------------------- /translator.yml: -------------------------------------------------------------------------------- 1 | # Configuration file for discourse-translator-bot 2 | 3 | files: 4 | - source_path: config/locales/client.en.yml 5 | destination_path: client.yml 6 | - source_path: config/locales/server.en.yml 7 | destination_path: server.yml 8 | --------------------------------------------------------------------------------