|
@ -110,6 +110,13 @@ jobs:
|
|||
environment: *ruby_environment
|
||||
<<: *install_ruby_dependencies
|
||||
|
||||
install-ruby2.3:
|
||||
<<: *defaults
|
||||
docker:
|
||||
- image: circleci/ruby:2.3.7-stretch-node
|
||||
environment: *ruby_environment
|
||||
<<: *install_ruby_dependencies
|
||||
|
||||
build:
|
||||
<<: *defaults
|
||||
steps:
|
||||
|
@ -146,6 +153,17 @@ jobs:
|
|||
- image: circleci/redis:4.0.9-alpine
|
||||
<<: *test_steps
|
||||
|
||||
test-ruby2.3:
|
||||
<<: *defaults
|
||||
docker:
|
||||
- image: circleci/ruby:2.3.7-stretch-node
|
||||
environment: *ruby_environment
|
||||
- image: circleci/postgres:10.3-alpine
|
||||
environment:
|
||||
POSTGRES_USER: root
|
||||
- image: circleci/redis:4.0.9-alpine
|
||||
<<: *test_steps
|
||||
|
||||
test-webui:
|
||||
<<: *defaults
|
||||
docker:
|
||||
|
@ -174,6 +192,9 @@ workflows:
|
|||
- install-ruby2.4:
|
||||
requires:
|
||||
- install
|
||||
- install-ruby2.3:
|
||||
requires:
|
||||
- install
|
||||
- build:
|
||||
requires:
|
||||
- install-ruby2.5
|
||||
|
@ -185,6 +206,10 @@ workflows:
|
|||
requires:
|
||||
- install-ruby2.4
|
||||
- build
|
||||
- test-ruby2.3:
|
||||
requires:
|
||||
- install-ruby2.3
|
||||
- build
|
||||
- test-webui:
|
||||
requires:
|
||||
- install
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
.bundle
|
||||
.env
|
||||
.env.*
|
||||
public/system
|
||||
|
|
|
@ -232,5 +232,3 @@ STREAMING_CLUSTER_NUM=1
|
|||
# http_proxy=http://gateway.local:8118
|
||||
# Access control for hidden service.
|
||||
# ALLOW_ACCESS_TO_HIDDEN_SERVICE=true
|
||||
# If you use transparent proxy to access to hidden service, uncomment following for skipping private address check.
|
||||
# HIDDEN_SERVICE_VIA_TRANSPARENT_PROXY=true
|
||||
|
|
|
@ -53,6 +53,7 @@ before_install:
|
|||
|
||||
before_script:
|
||||
- travis_wait ./bin/rails parallel:create parallel:load_schema parallel:prepare assets:precompile
|
||||
- yarn install --no-progress
|
||||
|
||||
script:
|
||||
- travis_retry bundle exec parallel_test spec/ --group-by filesize --type rspec
|
||||
|
|
|
@ -6,8 +6,10 @@ LABEL maintainer="https://github.com/tootsuite/mastodon" \
|
|||
ARG UID=991
|
||||
ARG GID=991
|
||||
|
||||
ENV RAILS_SERVE_STATIC_FILES=true \
|
||||
RAILS_ENV=production NODE_ENV=production
|
||||
ENV PATH=/mastodon/bin:$PATH \
|
||||
RAILS_SERVE_STATIC_FILES=true \
|
||||
RAILS_ENV=production \
|
||||
NODE_ENV=production
|
||||
|
||||
ARG YARN_VERSION=1.3.2
|
||||
ARG YARN_DOWNLOAD_SHA256=6cfe82e530ef0837212f13e45c1565ba53f5199eec2527b85ecbcd88bf26821d
|
||||
|
@ -50,6 +52,7 @@ RUN apk -U upgrade \
|
|||
&& rm yarn.tar.gz \
|
||||
&& mv /tmp/src/yarn-v$YARN_VERSION /opt/yarn \
|
||||
&& ln -s /opt/yarn/bin/yarn /usr/local/bin/yarn \
|
||||
&& ln -s /opt/yarn/bin/yarnpkg /usr/local/bin/yarnpkg \
|
||||
&& wget -O libiconv.tar.gz "https://ftp.gnu.org/pub/gnu/libiconv/libiconv-$LIBICONV_VERSION.tar.gz" \
|
||||
&& echo "$LIBICONV_DOWNLOAD_SHA256 *libiconv.tar.gz" | sha256sum -c - \
|
||||
&& tar -xzf libiconv.tar.gz -C /tmp/src \
|
||||
|
|
|
@ -21,6 +21,7 @@ module Admin
|
|||
activity_api_enabled
|
||||
peers_api_enabled
|
||||
show_known_fediverse_at_about_page
|
||||
preview_sensitive_media
|
||||
).freeze
|
||||
|
||||
BOOLEAN_SETTINGS = %w(
|
||||
|
@ -31,6 +32,7 @@ module Admin
|
|||
activity_api_enabled
|
||||
peers_api_enabled
|
||||
show_known_fediverse_at_about_page
|
||||
preview_sensitive_media
|
||||
).freeze
|
||||
|
||||
UPLOAD_SETTINGS = %w(
|
||||
|
|
|
@ -78,4 +78,8 @@ class Api::BaseController < ApplicationController
|
|||
def render_empty
|
||||
render json: {}, status: 200
|
||||
end
|
||||
|
||||
def authorize_if_got_token!(*scopes)
|
||||
doorkeeper_authorize!(*scopes) if doorkeeper_token
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Accounts::CredentialsController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read }, except: [:update]
|
||||
before_action -> { doorkeeper_authorize! :write }, only: [:update]
|
||||
before_action -> { doorkeeper_authorize! :read, :'read:accounts' }, except: [:update]
|
||||
before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, only: [:update]
|
||||
before_action :require_user!
|
||||
|
||||
def show
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Accounts::FollowerAccountsController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read }
|
||||
before_action -> { doorkeeper_authorize! :read, :'read:accounts' }
|
||||
before_action :set_account
|
||||
after_action :insert_pagination_headers
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Accounts::FollowingAccountsController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read }
|
||||
before_action -> { doorkeeper_authorize! :read, :'read:accounts' }
|
||||
before_action :set_account
|
||||
after_action :insert_pagination_headers
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Accounts::ListsController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read }
|
||||
before_action -> { doorkeeper_authorize! :read, :'read:lists' }
|
||||
before_action :require_user!
|
||||
before_action :set_account
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Accounts::RelationshipsController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read }
|
||||
before_action -> { doorkeeper_authorize! :read, :'read:follows' }
|
||||
before_action :require_user!
|
||||
|
||||
respond_to :json
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Accounts::SearchController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read }
|
||||
before_action -> { doorkeeper_authorize! :read, :'read:accounts' }
|
||||
before_action :require_user!
|
||||
|
||||
respond_to :json
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Accounts::StatusesController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read }
|
||||
before_action -> { doorkeeper_authorize! :read, :'read:statuses' }
|
||||
before_action :set_account
|
||||
after_action :insert_pagination_headers
|
||||
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::AccountsController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read }, except: [:follow, :unfollow, :block, :unblock, :mute, :unmute]
|
||||
before_action -> { doorkeeper_authorize! :follow }, only: [:follow, :unfollow, :block, :unblock, :mute, :unmute]
|
||||
before_action -> { authorize_if_got_token! :read, :'read:accounts' }, except: [:follow, :unfollow, :block, :unblock, :mute, :unmute]
|
||||
before_action -> { doorkeeper_authorize! :follow, :'write:follows' }, only: [:follow, :unfollow]
|
||||
before_action -> { doorkeeper_authorize! :follow, :'write:mutes' }, only: [:mute, :unmute]
|
||||
before_action -> { doorkeeper_authorize! :follow, :'write:blocks' }, only: [:block, :unblock]
|
||||
|
||||
before_action :require_user!, except: [:show]
|
||||
before_action :set_account
|
||||
before_action :check_account_suspension, only: [:show]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::BlocksController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :follow }
|
||||
before_action -> { doorkeeper_authorize! :follow, :'read:blocks' }
|
||||
before_action :require_user!
|
||||
after_action :insert_pagination_headers
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
class Api::V1::DomainBlocksController < Api::BaseController
|
||||
BLOCK_LIMIT = 100
|
||||
|
||||
before_action -> { doorkeeper_authorize! :follow }
|
||||
before_action -> { doorkeeper_authorize! :follow, :'read:blocks' }, only: :show
|
||||
before_action -> { doorkeeper_authorize! :follow, :'write:blocks' }, except: :show
|
||||
before_action :require_user!
|
||||
after_action :insert_pagination_headers, only: :show
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::FavouritesController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read }
|
||||
before_action -> { doorkeeper_authorize! :read, :'read:favourites' }
|
||||
before_action :require_user!
|
||||
after_action :insert_pagination_headers
|
||||
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::FiltersController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read, :'read:filters' }, only: [:index, :show]
|
||||
before_action -> { doorkeeper_authorize! :write, :'write:filters' }, except: [:index, :show]
|
||||
before_action :require_user!
|
||||
before_action :set_filters, only: :index
|
||||
before_action :set_filter, only: [:show, :update, :destroy]
|
||||
|
||||
respond_to :json
|
||||
|
||||
def index
|
||||
render json: @filters, each_serializer: REST::FilterSerializer
|
||||
end
|
||||
|
||||
def create
|
||||
@filter = current_account.custom_filters.create!(resource_params)
|
||||
render json: @filter, serializer: REST::FilterSerializer
|
||||
end
|
||||
|
||||
def show
|
||||
render json: @filter, serializer: REST::FilterSerializer
|
||||
end
|
||||
|
||||
def update
|
||||
@filter.update!(resource_params)
|
||||
render json: @filter, serializer: REST::FilterSerializer
|
||||
end
|
||||
|
||||
def destroy
|
||||
@filter.destroy!
|
||||
render_empty
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_filters
|
||||
@filters = current_account.custom_filters
|
||||
end
|
||||
|
||||
def set_filter
|
||||
@filter = current_account.custom_filters.find(params[:id])
|
||||
end
|
||||
|
||||
def resource_params
|
||||
params.permit(:phrase, :expires_in, :irreversible, :whole_word, context: [])
|
||||
end
|
||||
end
|
|
@ -1,7 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::FollowRequestsController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :follow }
|
||||
before_action -> { doorkeeper_authorize! :follow, :'read:follows' }, only: :index
|
||||
before_action -> { doorkeeper_authorize! :follow, :'write:follows' }, except: :index
|
||||
before_action :require_user!
|
||||
after_action :insert_pagination_headers, only: :index
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::FollowsController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :follow }
|
||||
before_action -> { doorkeeper_authorize! :follow, :'write:follows' }
|
||||
before_action :require_user!
|
||||
|
||||
respond_to :json
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Lists::AccountsController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read }, only: [:show]
|
||||
before_action -> { doorkeeper_authorize! :write }, except: [:show]
|
||||
before_action -> { doorkeeper_authorize! :read, :'read:lists' }, only: [:show]
|
||||
before_action -> { doorkeeper_authorize! :write, :'write:lists' }, except: [:show]
|
||||
|
||||
before_action :require_user!
|
||||
before_action :set_list
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::ListsController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read }, only: [:index, :show]
|
||||
before_action -> { doorkeeper_authorize! :write }, except: [:index, :show]
|
||||
before_action -> { doorkeeper_authorize! :read, :'read:lists' }, only: [:index, :show]
|
||||
before_action -> { doorkeeper_authorize! :write, :'write:lists' }, except: [:index, :show]
|
||||
|
||||
before_action :require_user!
|
||||
before_action :set_list, except: [:index, :create]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::MediaController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :write }
|
||||
before_action -> { doorkeeper_authorize! :write, :'write:media' }
|
||||
before_action :require_user!
|
||||
|
||||
include ObfuscateFilename
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::MutesController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :follow }
|
||||
before_action -> { doorkeeper_authorize! :follow, :'read:mutes' }
|
||||
before_action :require_user!
|
||||
after_action :insert_pagination_headers
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::NotificationsController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read }
|
||||
before_action -> { doorkeeper_authorize! :read, :'read:notifications' }, except: [:clear, :dismiss]
|
||||
before_action -> { doorkeeper_authorize! :write, :'write:notifications' }, only: [:clear, :dismiss]
|
||||
before_action :require_user!
|
||||
after_action :insert_pagination_headers, only: :index
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::ReportsController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read }, except: [:create]
|
||||
before_action -> { doorkeeper_authorize! :write }, only: [:create]
|
||||
before_action -> { doorkeeper_authorize! :read, :'read:reports' }, except: [:create]
|
||||
before_action -> { doorkeeper_authorize! :write, :'write:reports' }, only: [:create]
|
||||
before_action :require_user!
|
||||
|
||||
respond_to :json
|
||||
|
|
|
@ -5,7 +5,7 @@ class Api::V1::SearchController < Api::BaseController
|
|||
|
||||
RESULTS_LIMIT = 10
|
||||
|
||||
before_action -> { doorkeeper_authorize! :read }
|
||||
before_action -> { doorkeeper_authorize! :read, :'read:search' }
|
||||
before_action :require_user!
|
||||
|
||||
respond_to :json
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
class Api::V1::Statuses::FavouritedByAccountsController < Api::BaseController
|
||||
include Authorization
|
||||
|
||||
before_action :authorize_if_got_token
|
||||
before_action -> { authorize_if_got_token! :read, :'read:accounts' }
|
||||
before_action :set_status
|
||||
after_action :insert_pagination_headers
|
||||
|
||||
|
@ -71,11 +71,6 @@ class Api::V1::Statuses::FavouritedByAccountsController < Api::BaseController
|
|||
raise ActiveRecord::RecordNotFound
|
||||
end
|
||||
|
||||
def authorize_if_got_token
|
||||
request_token = Doorkeeper::OAuth::Token.from_request(request, *Doorkeeper.configuration.access_token_methods)
|
||||
doorkeeper_authorize! :read if request_token
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.slice(:limit).permit(:limit).merge(core_params)
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
class Api::V1::Statuses::FavouritesController < Api::BaseController
|
||||
include Authorization
|
||||
|
||||
before_action -> { doorkeeper_authorize! :write }
|
||||
before_action -> { doorkeeper_authorize! :write, :'write:favourites' }
|
||||
before_action :require_user!
|
||||
|
||||
respond_to :json
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
class Api::V1::Statuses::MutesController < Api::BaseController
|
||||
include Authorization
|
||||
|
||||
before_action -> { doorkeeper_authorize! :write }
|
||||
before_action -> { doorkeeper_authorize! :write, :'write:mutes' }
|
||||
before_action :require_user!
|
||||
before_action :set_status
|
||||
before_action :set_conversation
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
class Api::V1::Statuses::PinsController < Api::BaseController
|
||||
include Authorization
|
||||
|
||||
before_action -> { doorkeeper_authorize! :write }
|
||||
before_action -> { doorkeeper_authorize! :write, :'write:accounts' }
|
||||
before_action :require_user!
|
||||
before_action :set_status
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
class Api::V1::Statuses::RebloggedByAccountsController < Api::BaseController
|
||||
include Authorization
|
||||
|
||||
before_action :authorize_if_got_token
|
||||
before_action -> { authorize_if_got_token! :read, :'read:accounts' }
|
||||
before_action :set_status
|
||||
after_action :insert_pagination_headers
|
||||
|
||||
|
@ -68,11 +68,6 @@ class Api::V1::Statuses::RebloggedByAccountsController < Api::BaseController
|
|||
raise ActiveRecord::RecordNotFound
|
||||
end
|
||||
|
||||
def authorize_if_got_token
|
||||
request_token = Doorkeeper::OAuth::Token.from_request(request, *Doorkeeper.configuration.access_token_methods)
|
||||
doorkeeper_authorize! :read if request_token
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.slice(:limit).permit(:limit).merge(core_params)
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
class Api::V1::Statuses::ReblogsController < Api::BaseController
|
||||
include Authorization
|
||||
|
||||
before_action -> { doorkeeper_authorize! :write }
|
||||
before_action -> { doorkeeper_authorize! :write, :'write:statuses' }
|
||||
before_action :require_user!
|
||||
|
||||
respond_to :json
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
class Api::V1::StatusesController < Api::BaseController
|
||||
include Authorization
|
||||
|
||||
before_action :authorize_if_got_token, except: [:create, :destroy]
|
||||
before_action -> { doorkeeper_authorize! :write }, only: [:create, :destroy]
|
||||
before_action -> { authorize_if_got_token! :read, :'read:statuses' }, except: [:create, :destroy]
|
||||
before_action -> { doorkeeper_authorize! :write, :'write:statuses' }, only: [:create, :destroy]
|
||||
before_action :require_user!, except: [:show, :context, :card]
|
||||
before_action :set_status, only: [:show, :context, :card]
|
||||
|
||||
|
@ -84,9 +84,4 @@ class Api::V1::StatusesController < Api::BaseController
|
|||
def pagination_params(core_params)
|
||||
params.slice(:limit).permit(:limit).merge(core_params)
|
||||
end
|
||||
|
||||
def authorize_if_got_token
|
||||
request_token = Doorkeeper::OAuth::Token.from_request(request, *Doorkeeper.configuration.access_token_methods)
|
||||
doorkeeper_authorize! :read if request_token
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::SuggestionsController < Api::BaseController
|
||||
include Authorization
|
||||
|
||||
before_action -> { doorkeeper_authorize! :read }
|
||||
before_action :require_user!
|
||||
before_action :set_accounts
|
||||
|
||||
respond_to :json
|
||||
|
||||
def index
|
||||
render json: @accounts, each_serializer: REST::AccountSerializer
|
||||
end
|
||||
|
||||
def destroy
|
||||
PotentialFriendshipTracker.remove(current_account.id, params[:id])
|
||||
render_empty
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_accounts
|
||||
@accounts = PotentialFriendshipTracker.get(current_account.id, limit: limit_param(DEFAULT_ACCOUNTS_LIMIT))
|
||||
end
|
||||
end
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Timelines::DirectController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read }, only: [:show]
|
||||
before_action -> { doorkeeper_authorize! :read, :'read:statuses' }, only: [:show]
|
||||
before_action :require_user!, only: [:show]
|
||||
after_action :insert_pagination_headers, unless: -> { @statuses.empty? }
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Timelines::HomeController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read }, only: [:show]
|
||||
before_action -> { doorkeeper_authorize! :read, :'read:statuses' }, only: [:show]
|
||||
before_action :require_user!, only: [:show]
|
||||
after_action :insert_pagination_headers, unless: -> { @statuses.empty? }
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Timelines::ListController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read }
|
||||
before_action -> { doorkeeper_authorize! :read, :'read:lists' }
|
||||
before_action :require_user!
|
||||
before_action :set_list
|
||||
before_action :set_statuses
|
||||
|
|
|
@ -40,6 +40,16 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
|||
new_user_session_path
|
||||
end
|
||||
|
||||
def after_sign_in_path_for(_resource)
|
||||
set_invite
|
||||
|
||||
if @invite&.autofollow?
|
||||
short_account_path(@invite.user.account)
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def after_inactive_sign_up_path_for(_resource)
|
||||
new_user_session_path
|
||||
end
|
||||
|
|
|
@ -58,11 +58,11 @@ module SignatureVerification
|
|||
@signed_request_account = account
|
||||
@signed_request_account
|
||||
else
|
||||
@signed_verification_failure_reason = "Verification failed for #{account.username}@#{account.domain} #{account.uri}"
|
||||
@signature_verification_failure_reason = "Verification failed for #{account.username}@#{account.domain} #{account.uri}"
|
||||
@signed_request_account = nil
|
||||
end
|
||||
else
|
||||
@signed_verification_failure_reason = "Verification failed for #{account.username}@#{account.domain} #{account.uri}"
|
||||
@signature_verification_failure_reason = "Verification failed for #{account.username}@#{account.domain} #{account.uri}"
|
||||
@signed_request_account = nil
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class FiltersController < ApplicationController
|
||||
include Authorization
|
||||
|
||||
layout 'admin'
|
||||
|
||||
before_action :set_filters, only: :index
|
||||
before_action :set_filter, only: [:edit, :update, :destroy]
|
||||
before_action :set_pack
|
||||
|
||||
def index
|
||||
@filters = current_account.custom_filters
|
||||
end
|
||||
|
||||
def new
|
||||
@filter = current_account.custom_filters.build
|
||||
end
|
||||
|
||||
def create
|
||||
@filter = current_account.custom_filters.build(resource_params)
|
||||
|
||||
if @filter.save
|
||||
redirect_to filters_path
|
||||
else
|
||||
render action: :new
|
||||
end
|
||||
end
|
||||
|
||||
def edit; end
|
||||
|
||||
def update
|
||||
if @filter.update(resource_params)
|
||||
redirect_to filters_path
|
||||
else
|
||||
render action: :edit
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@filter.destroy
|
||||
redirect_to filters_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_pack
|
||||
use_pack 'settings'
|
||||
end
|
||||
|
||||
def set_filters
|
||||
@filters = current_account.custom_filters
|
||||
end
|
||||
|
||||
def set_filter
|
||||
@filter = current_account.custom_filters.find(params[:id])
|
||||
end
|
||||
|
||||
def resource_params
|
||||
params.require(:custom_filter).permit(:phrase, :expires_in, :irreversible, context: [])
|
||||
end
|
||||
end
|
|
@ -6,6 +6,7 @@ class RemoteFollowController < ApplicationController
|
|||
before_action :set_account
|
||||
before_action :set_pack
|
||||
before_action :gone, if: :suspended_account?
|
||||
before_action :set_body_classes
|
||||
|
||||
def new
|
||||
@remote_follow = RemoteFollow.new(session_params)
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Settings::KeywordMutesController < Settings::BaseController
|
||||
before_action :load_keyword_mute, only: [:edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
@keyword_mutes = paginated_keyword_mutes_for_account
|
||||
end
|
||||
|
||||
def new
|
||||
@keyword_mute = keyword_mutes_for_account.build
|
||||
end
|
||||
|
||||
def create
|
||||
@keyword_mute = keyword_mutes_for_account.create(keyword_mute_params)
|
||||
|
||||
if @keyword_mute.persisted?
|
||||
redirect_to settings_keyword_mutes_path, notice: I18n.t('generic.changes_saved_msg')
|
||||
else
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
if @keyword_mute.update(keyword_mute_params)
|
||||
redirect_to settings_keyword_mutes_path, notice: I18n.t('generic.changes_saved_msg')
|
||||
else
|
||||
render :edit
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@keyword_mute.destroy!
|
||||
|
||||
redirect_to settings_keyword_mutes_path, notice: I18n.t('generic.changes_saved_msg')
|
||||
end
|
||||
|
||||
def destroy_all
|
||||
keyword_mutes_for_account.delete_all
|
||||
|
||||
redirect_to settings_keyword_mutes_path, notice: I18n.t('generic.changes_saved_msg')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def keyword_mutes_for_account
|
||||
Glitch::KeywordMute.where(account: current_account)
|
||||
end
|
||||
|
||||
def load_keyword_mute
|
||||
@keyword_mute = keyword_mutes_for_account.find(params[:id])
|
||||
end
|
||||
|
||||
def keyword_mute_params
|
||||
params.require(:keyword_mute).permit(:keyword, :whole_word, :apply_to_mentions)
|
||||
end
|
||||
|
||||
def paginated_keyword_mutes_for_account
|
||||
keyword_mutes_for_account.order(:keyword).page params[:page]
|
||||
end
|
||||
end
|
|
@ -48,7 +48,12 @@ class StatusesController < ApplicationController
|
|||
|
||||
def embed
|
||||
use_pack 'embed'
|
||||
raise ActiveRecord::RecordNotFound if @status.hidden?
|
||||
|
||||
skip_session!
|
||||
expires_in 180, public: true
|
||||
response.headers['X-Frame-Options'] = 'ALLOWALL'
|
||||
|
||||
render 'stream_entries/embed', layout: 'embedded'
|
||||
end
|
||||
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ApplicationHelper
|
||||
DANGEROUS_SCOPES = %w(
|
||||
read
|
||||
write
|
||||
follow
|
||||
).freeze
|
||||
|
||||
def active_nav_class(path)
|
||||
current_page?(path) ? 'active' : ''
|
||||
end
|
||||
|
@ -43,6 +49,10 @@ module ApplicationHelper
|
|||
Rails.env.production? ? site_title : "#{site_title} (Dev)"
|
||||
end
|
||||
|
||||
def class_for_scope(scope)
|
||||
'scope-danger' if DANGEROUS_SCOPES.include?(scope.to_s)
|
||||
end
|
||||
|
||||
def can?(action, record)
|
||||
return false if record.nil?
|
||||
policy(record).public_send("#{action}?")
|
||||
|
|
|
@ -7,6 +7,7 @@ module SettingsHelper
|
|||
bg: 'Български',
|
||||
ca: 'Català',
|
||||
co: 'Corsu',
|
||||
da: 'Dansk',
|
||||
de: 'Deutsch',
|
||||
el: 'Ελληνικά',
|
||||
eo: 'Esperanto',
|
||||
|
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 582 B After Width: | Height: | Size: 423 B |
Before Width: | Height: | Size: 279 B After Width: | Height: | Size: 253 B |
Before Width: | Height: | Size: 520 B After Width: | Height: | Size: 387 B |
Before Width: | Height: | Size: 271 B After Width: | Height: | Size: 225 B |
Before Width: | Height: | Size: 541 B After Width: | Height: | Size: 412 B |
Before Width: | Height: | Size: 550 B After Width: | Height: | Size: 387 B |
Before Width: | Height: | Size: 512 B After Width: | Height: | Size: 376 B |
Before Width: | Height: | Size: 391 B After Width: | Height: | Size: 319 B |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 627 B After Width: | Height: | Size: 506 B |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 174 B After Width: | Height: | Size: 174 B |
|
@ -0,0 +1,26 @@
|
|||
import api from '../api';
|
||||
|
||||
export const FILTERS_FETCH_REQUEST = 'FILTERS_FETCH_REQUEST';
|
||||
export const FILTERS_FETCH_SUCCESS = 'FILTERS_FETCH_SUCCESS';
|
||||
export const FILTERS_FETCH_FAIL = 'FILTERS_FETCH_FAIL';
|
||||
|
||||
export const fetchFilters = () => (dispatch, getState) => {
|
||||
dispatch({
|
||||
type: FILTERS_FETCH_REQUEST,
|
||||
skipLoading: true,
|
||||
});
|
||||
|
||||
api(getState)
|
||||
.get('/api/v1/filters')
|
||||
.then(({ data }) => dispatch({
|
||||
type: FILTERS_FETCH_SUCCESS,
|
||||
filters: data,
|
||||
skipLoading: true,
|
||||
}))
|
||||
.catch(err => dispatch({
|
||||
type: FILTERS_FETCH_FAIL,
|
||||
err,
|
||||
skipLoading: true,
|
||||
skipAlert: true,
|
||||
}));
|
||||
};
|
|
@ -1,5 +1,5 @@
|
|||
import { autoPlayGif } from '../../initial_state';
|
||||
import { putAccounts, putStatuses } from '../../storage/modifier';
|
||||
// import { autoPlayGif } from '../../initial_state';
|
||||
// import { putAccounts, putStatuses } from '../../storage/modifier';
|
||||
import { normalizeAccount, normalizeStatus } from './normalizer';
|
||||
|
||||
export const ACCOUNT_IMPORT = 'ACCOUNT_IMPORT';
|
||||
|
@ -45,7 +45,7 @@ export function importFetchedAccounts(accounts) {
|
|||
}
|
||||
|
||||
accounts.forEach(processAccount);
|
||||
putAccounts(normalAccounts, !autoPlayGif);
|
||||
//putAccounts(normalAccounts, !autoPlayGif);
|
||||
|
||||
return importAccounts(normalAccounts);
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ export function importFetchedStatuses(statuses) {
|
|||
}
|
||||
|
||||
statuses.forEach(processStatus);
|
||||
putStatuses(normalStatuses);
|
||||
//putStatuses(normalStatuses);
|
||||
|
||||
dispatch(importFetchedAccounts(accounts));
|
||||
dispatch(importStatuses(normalStatuses));
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
} from './importer';
|
||||
import { defineMessages } from 'react-intl';
|
||||
import { unescapeHTML } from '../utils/html';
|
||||
import { getFilters, regexFromFilters } from '../selectors';
|
||||
|
||||
export const NOTIFICATIONS_UPDATE = 'NOTIFICATIONS_UPDATE';
|
||||
export const NOTIFICATIONS_UPDATE_NOOP = 'NOTIFICATIONS_UPDATE_NOOP';
|
||||
|
@ -38,6 +39,16 @@ export function updateNotifications(notification, intlMessages, intlLocale) {
|
|||
const showInColumn = getState().getIn(['settings', 'notifications', 'shows', notification.type], true);
|
||||
const showAlert = getState().getIn(['settings', 'notifications', 'alerts', notification.type], true);
|
||||
const playSound = getState().getIn(['settings', 'notifications', 'sounds', notification.type], true);
|
||||
const filters = getFilters(getState(), { contextType: 'notifications' });
|
||||
|
||||
let filtered = false;
|
||||
|
||||
if (notification.type === 'mention') {
|
||||
const regex = regexFromFilters(filters);
|
||||
const searchIndex = notification.status.spoiler_text + '\n' + unescapeHTML(notification.status.content);
|
||||
|
||||
filtered = regex && regex.test(searchIndex);
|
||||
}
|
||||
|
||||
if (showInColumn) {
|
||||
dispatch(importFetchedAccount(notification.account));
|
||||
|
@ -49,11 +60,11 @@ export function updateNotifications(notification, intlMessages, intlLocale) {
|
|||
dispatch({
|
||||
type: NOTIFICATIONS_UPDATE,
|
||||
notification,
|
||||
meta: playSound ? { sound: 'boop' } : undefined,
|
||||
meta: (playSound && !filtered) ? { sound: 'boop' } : undefined,
|
||||
});
|
||||
|
||||
fetchRelatedRelationships(dispatch, [notification]);
|
||||
} else if (playSound) {
|
||||
} else if (playSound && !filtered) {
|
||||
dispatch({
|
||||
type: NOTIFICATIONS_UPDATE_NOOP,
|
||||
meta: { sound: 'boop' },
|
||||
|
@ -61,7 +72,7 @@ export function updateNotifications(notification, intlMessages, intlLocale) {
|
|||
}
|
||||
|
||||
// Desktop notifications
|
||||
if (typeof window.Notification !== 'undefined' && showAlert) {
|
||||
if (typeof window.Notification !== 'undefined' && showAlert && !filtered) {
|
||||
const title = new IntlMessageFormat(intlMessages[`notification.${notification.type}`], intlLocale).format({ name: notification.account.display_name.length > 0 ? notification.account.display_name : notification.account.username });
|
||||
const body = (notification.status && notification.status.spoiler_text.length > 0) ? notification.status.spoiler_text : unescapeHTML(notification.status ? notification.status.content : '');
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import {
|
|||
disconnectTimeline,
|
||||
} from './timelines';
|
||||
import { updateNotifications, expandNotifications } from './notifications';
|
||||
import { fetchFilters } from './filters';
|
||||
import { getLocale } from '../locales';
|
||||
|
||||
const { messages } = getLocale();
|
||||
|
@ -30,6 +31,9 @@ export function connectTimelineStream (timelineId, path, pollingRefresh = null)
|
|||
case 'notification':
|
||||
dispatch(updateNotifications(JSON.parse(data.payload), messages, locale));
|
||||
break;
|
||||
case 'filters_changed':
|
||||
dispatch(fetchFilters());
|
||||
break;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -101,7 +101,7 @@ export default class Account extends ImmutablePureComponent {
|
|||
return (
|
||||
<div className='account'>
|
||||
<div className='account__wrapper'>
|
||||
<Permalink key={account.get('id')} className='account__display-name' href={account.get('url')} to={`/accounts/${account.get('id')}`}>
|
||||
<Permalink key={account.get('id')} className='account__display-name' title={account.get('acct')} href={account.get('url')} to={`/accounts/${account.get('id')}`}>
|
||||
<div className='account__avatar-wrapper'><Avatar account={account} size={36} /></div>
|
||||
<DisplayName account={account} />
|
||||
</Permalink>
|
||||
|
|
|
@ -122,7 +122,7 @@ class Item extends React.PureComponent {
|
|||
const hasSize = typeof originalWidth === 'number' && typeof previewWidth === 'number';
|
||||
|
||||
const srcSet = hasSize ? `${originalUrl} ${originalWidth}w, ${previewUrl} ${previewWidth}w` : null;
|
||||
const sizes = hasSize ? `${displayWidth * (width / 100)}px` : null;
|
||||
const sizes = hasSize && (displayWidth > 0) ? `${displayWidth * (width / 100)}px` : null;
|
||||
|
||||
const focusX = attachment.getIn(['meta', 'focus', 'x']) || 0;
|
||||
const focusY = attachment.getIn(['meta', 'focus', 'y']) || 0;
|
||||
|
|
|
@ -157,6 +157,21 @@ export default class Status extends ImmutablePureComponent {
|
|||
);
|
||||
}
|
||||
|
||||
if (status.get('filtered') || status.getIn(['reblog', 'filtered'])) {
|
||||
const minHandlers = this.props.muted ? {} : {
|
||||
moveUp: this.handleHotkeyMoveUp,
|
||||
moveDown: this.handleHotkeyMoveDown,
|
||||
};
|
||||
|
||||
return (
|
||||
<HotKeys handlers={minHandlers}>
|
||||
<div className='status__wrapper status__wrapper--filtered focusable' tabIndex='0'>
|
||||
<FormattedMessage id='status.filtered' defaultMessage='Filtered' />
|
||||
</div>
|
||||
</HotKeys>
|
||||
);
|
||||
}
|
||||
|
||||
if (featured) {
|
||||
prepend = (
|
||||
<div className='status__prepend'>
|
||||
|
|
|
@ -25,6 +25,7 @@ export default class StatusList extends ImmutablePureComponent {
|
|||
prepend: PropTypes.node,
|
||||
emptyMessage: PropTypes.node,
|
||||
alwaysPrepend: PropTypes.bool,
|
||||
timelineId: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
|
@ -70,7 +71,7 @@ export default class StatusList extends ImmutablePureComponent {
|
|||
}
|
||||
|
||||
render () {
|
||||
const { statusIds, featuredStatusIds, onLoadMore, ...other } = this.props;
|
||||
const { statusIds, featuredStatusIds, onLoadMore, timelineId, ...other } = this.props;
|
||||
const { isLoading, isPartial } = other;
|
||||
|
||||
if (isPartial) {
|
||||
|
@ -102,6 +103,7 @@ export default class StatusList extends ImmutablePureComponent {
|
|||
id={statusId}
|
||||
onMoveUp={this.handleMoveUp}
|
||||
onMoveDown={this.handleMoveDown}
|
||||
contextType={timelineId}
|
||||
/>
|
||||
))
|
||||
) : null;
|
||||
|
@ -114,6 +116,7 @@ export default class StatusList extends ImmutablePureComponent {
|
|||
featured
|
||||
onMoveUp={this.handleMoveUp}
|
||||
onMoveDown={this.handleMoveDown}
|
||||
contextType={timelineId}
|
||||
/>
|
||||
)).concat(scrollableContent);
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ const makeMapStateToProps = () => {
|
|||
const getStatus = makeGetStatus();
|
||||
|
||||
const mapStateToProps = (state, props) => ({
|
||||
status: getStatus(state, props.id),
|
||||
status: getStatus(state, props),
|
||||
});
|
||||
|
||||
return mapStateToProps;
|
||||
|
|
|
@ -1,15 +1,9 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||
import SettingText from '../../../components/setting_text';
|
||||
import { injectIntl, FormattedMessage } from 'react-intl';
|
||||
import SettingToggle from '../../notifications/components/setting_toggle';
|
||||
|
||||
const messages = defineMessages({
|
||||
filter_regex: { id: 'home.column_settings.filter_regex', defaultMessage: 'Filter out by regular expressions' },
|
||||
settings: { id: 'home.settings', defaultMessage: 'Column settings' },
|
||||
});
|
||||
|
||||
@injectIntl
|
||||
export default class ColumnSettings extends React.PureComponent {
|
||||
|
||||
|
@ -21,19 +15,13 @@ export default class ColumnSettings extends React.PureComponent {
|
|||
};
|
||||
|
||||
render () {
|
||||
const { settings, onChange, intl } = this.props;
|
||||
const { settings, onChange } = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='column-settings__row'>
|
||||
<SettingToggle settings={settings} settingPath={['other', 'onlyMedia']} onChange={onChange} label={<FormattedMessage id='community.column_settings.media_only' defaultMessage='Media Only' />} />
|
||||
</div>
|
||||
|
||||
<span className='column-settings__section'><FormattedMessage id='home.column_settings.advanced' defaultMessage='Advanced' /></span>
|
||||
|
||||
<div className='column-settings__row'>
|
||||
<SettingText settings={settings} settingKey={['regex', 'body']} onChange={onChange} label={intl.formatMessage(messages.filter_regex)} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ export default class AutosuggestAccount extends ImmutablePureComponent {
|
|||
const { account } = this.props;
|
||||
|
||||
return (
|
||||
<div className='autosuggest-account'>
|
||||
<div className='autosuggest-account' title={account.get('acct')}>
|
||||
<div className='autosuggest-account-icon'><Avatar account={account} size={18} /></div>
|
||||
<DisplayName account={account} />
|
||||
</div>
|
||||
|
|
|
@ -7,7 +7,7 @@ const makeMapStateToProps = () => {
|
|||
const getStatus = makeGetStatus();
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
status: getStatus(state, state.getIn(['compose', 'in_reply_to'])),
|
||||
status: getStatus(state, { id: state.getIn(['compose', 'in_reply_to']) }),
|
||||
});
|
||||
|
||||
return mapStateToProps;
|
||||
|
|
|
@ -7,7 +7,6 @@ import ColumnHeader from '../../components/column_header';
|
|||
import { expandDirectTimeline } from '../../actions/timelines';
|
||||
import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
|
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||
import ColumnSettingsContainer from './containers/column_settings_container';
|
||||
import { connectDirectStream } from '../../actions/streaming';
|
||||
|
||||
const messages = defineMessages({
|
||||
|
@ -86,9 +85,7 @@ export default class DirectTimeline extends React.PureComponent {
|
|||
onClick={this.handleHeaderClick}
|
||||
pinned={pinned}
|
||||
multiColumn={multiColumn}
|
||||
>
|
||||
<ColumnSettingsContainer />
|
||||
</ColumnHeader>
|
||||
/>
|
||||
|
||||
<StatusListContainer
|
||||
trackScroll={!pinned}
|
||||
|
|
|
@ -1,14 +1,8 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||
import { injectIntl, FormattedMessage } from 'react-intl';
|
||||
import SettingToggle from '../../notifications/components/setting_toggle';
|
||||
import SettingText from '../../../components/setting_text';
|
||||
|
||||
const messages = defineMessages({
|
||||
filter_regex: { id: 'home.column_settings.filter_regex', defaultMessage: 'Filter out by regular expressions' },
|
||||
settings: { id: 'home.settings', defaultMessage: 'Column settings' },
|
||||
});
|
||||
|
||||
@injectIntl
|
||||
export default class ColumnSettings extends React.PureComponent {
|
||||
|
@ -20,7 +14,7 @@ export default class ColumnSettings extends React.PureComponent {
|
|||
};
|
||||
|
||||
render () {
|
||||
const { settings, onChange, intl } = this.props;
|
||||
const { settings, onChange } = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
@ -33,12 +27,6 @@ export default class ColumnSettings extends React.PureComponent {
|
|||
<div className='column-settings__row'>
|
||||
<SettingToggle prefix='home_timeline' settings={settings} settingPath={['shows', 'reply']} onChange={onChange} label={<FormattedMessage id='home.column_settings.show_replies' defaultMessage='Show replies' />} />
|
||||
</div>
|
||||
|
||||
<span className='column-settings__section'><FormattedMessage id='home.column_settings.advanced' defaultMessage='Advanced' /></span>
|
||||
|
||||
<div className='column-settings__row'>
|
||||
<SettingText prefix='home_timeline' settings={settings} settingKey={['regex', 'body']} onChange={onChange} label={intl.formatMessage(messages.filter_regex)} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -91,6 +91,7 @@ export default class Notification extends ImmutablePureComponent {
|
|||
hidden={this.props.hidden}
|
||||
onMoveDown={this.handleMoveDown}
|
||||
onMoveUp={this.handleMoveUp}
|
||||
contextType='notifications'
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ const makeMapStateToProps = () => {
|
|||
const getStatus = makeGetStatus();
|
||||
|
||||
const mapStateToProps = (state, props) => {
|
||||
const status = getStatus(state, props.params.statusId);
|
||||
const status = getStatus(state, { id: props.params.statusId });
|
||||
let ancestorsIds = Immutable.List();
|
||||
let descendantsIds = Immutable.List();
|
||||
|
||||
|
@ -276,7 +276,7 @@ export default class Status extends ImmutablePureComponent {
|
|||
|
||||
handleHotkeyMention = e => {
|
||||
e.preventDefault();
|
||||
this.handleMentionClick(this.props.status);
|
||||
this.handleMentionClick(this.props.status.get('account'));
|
||||
}
|
||||
|
||||
handleHotkeyOpenProfile = () => {
|
||||
|
@ -336,6 +336,7 @@ export default class Status extends ImmutablePureComponent {
|
|||
id={id}
|
||||
onMoveUp={this.handleMoveUp}
|
||||
onMoveDown={this.handleMoveDown}
|
||||
contextType='thread'
|
||||
/>
|
||||
));
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ const messages = defineMessages({
|
|||
next: { id: 'lightbox.next', defaultMessage: 'Next' },
|
||||
});
|
||||
|
||||
const previewState = 'previewMediaModal';
|
||||
|
||||
@injectIntl
|
||||
export default class MediaModal extends ImmutablePureComponent {
|
||||
|
||||
|
@ -26,6 +28,10 @@ export default class MediaModal extends ImmutablePureComponent {
|
|||
intl: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
static contextTypes = {
|
||||
router: PropTypes.object,
|
||||
};
|
||||
|
||||
state = {
|
||||
index: null,
|
||||
navigationHidden: false,
|
||||
|
@ -61,10 +67,24 @@ export default class MediaModal extends ImmutablePureComponent {
|
|||
|
||||
componentDidMount () {
|
||||
window.addEventListener('keyup', this.handleKeyUp, false);
|
||||
if (this.context.router) {
|
||||
const history = this.context.router.history;
|
||||
history.push(history.location.pathname, previewState);
|
||||
this.unlistenHistory = history.listen(() => {
|
||||
this.props.onClose();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
window.removeEventListener('keyup', this.handleKeyUp);
|
||||
if (this.context.router) {
|
||||
this.unlistenHistory();
|
||||
|
||||
if (this.context.router.history.location.state === previewState) {
|
||||
this.context.router.history.goBack();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getIndex () {
|
||||
|
|
|
@ -8,10 +8,10 @@ import { isUserTouching } from '../../../is_mobile';
|
|||
export const links = [
|
||||
<NavLink className='tabs-bar__link primary' to='/timelines/home' data-preview-title-id='column.home' data-preview-icon='home' ><i className='fa fa-fw fa-home' /><FormattedMessage id='tabs_bar.home' defaultMessage='Home' /></NavLink>,
|
||||
<NavLink className='tabs-bar__link primary' to='/notifications' data-preview-title-id='column.notifications' data-preview-icon='bell' ><i className='fa fa-fw fa-bell' /><FormattedMessage id='tabs_bar.notifications' defaultMessage='Notifications' /></NavLink>,
|
||||
<NavLink className='tabs-bar__link primary' to='/search' data-preview-title-id='tabs_bar.search' data-preview-icon='bell' ><i className='fa fa-fw fa-search' /><FormattedMessage id='tabs_bar.search' defaultMessage='Search' /></NavLink>,
|
||||
|
||||
<NavLink className='tabs-bar__link secondary' to='/timelines/public/local' data-preview-title-id='column.community' data-preview-icon='users' ><i className='fa fa-fw fa-users' /><FormattedMessage id='tabs_bar.local_timeline' defaultMessage='Local' /></NavLink>,
|
||||
<NavLink className='tabs-bar__link secondary' exact to='/timelines/public' data-preview-title-id='column.public' data-preview-icon='globe' ><i className='fa fa-fw fa-globe' /><FormattedMessage id='tabs_bar.federated_timeline' defaultMessage='Federated' /></NavLink>,
|
||||
<NavLink className='tabs-bar__link primary' to='/search' data-preview-title-id='tabs_bar.search' data-preview-icon='bell' ><i className='fa fa-fw fa-search' /><FormattedMessage id='tabs_bar.search' defaultMessage='Search' /></NavLink>,
|
||||
|
||||
<NavLink className='tabs-bar__link primary' style={{ flexGrow: '0', flexBasis: '30px' }} to='/getting-started' data-preview-title-id='getting_started.heading' data-preview-icon='bars' ><i className='fa fa-fw fa-bars' /></NavLink>,
|
||||
];
|
||||
|
|
|
@ -11,15 +11,6 @@ const makeGetStatusIds = () => createSelector([
|
|||
(state, { type }) => state.getIn(['timelines', type, 'items'], ImmutableList()),
|
||||
(state) => state.get('statuses'),
|
||||
], (columnSettings, statusIds, statuses) => {
|
||||
const rawRegex = columnSettings.getIn(['regex', 'body'], '').trim();
|
||||
let regex = null;
|
||||
|
||||
try {
|
||||
regex = rawRegex && new RegExp(rawRegex, 'i');
|
||||
} catch (e) {
|
||||
// Bad regex, don't affect filters
|
||||
}
|
||||
|
||||
return statusIds.filter(id => {
|
||||
if (id === null) return true;
|
||||
|
||||
|
@ -34,11 +25,6 @@ const makeGetStatusIds = () => createSelector([
|
|||
showStatus = showStatus && (statusForId.get('in_reply_to_id') === null || statusForId.get('in_reply_to_account_id') === me);
|
||||
}
|
||||
|
||||
if (showStatus && regex && statusForId.get('account') !== me) {
|
||||
const searchIndex = statusForId.get('reblog') ? statuses.getIn([statusForId.get('reblog'), 'search_index']) : statusForId.get('search_index');
|
||||
showStatus = !regex.test(searchIndex);
|
||||
}
|
||||
|
||||
return showStatus;
|
||||
});
|
||||
});
|
||||
|
|
|
@ -12,6 +12,7 @@ import { debounce } from 'lodash';
|
|||
import { uploadCompose, resetCompose } from '../../actions/compose';
|
||||
import { expandHomeTimeline } from '../../actions/timelines';
|
||||
import { expandNotifications } from '../../actions/notifications';
|
||||
import { fetchFilters } from '../../actions/filters';
|
||||
import { clearHeight } from '../../actions/height_cache';
|
||||
import { WrappedSwitch, WrappedRoute } from './util/react_router_helpers';
|
||||
import UploadArea from './components/upload_area';
|
||||
|
@ -297,6 +298,7 @@ export default class UI extends React.PureComponent {
|
|||
|
||||
this.props.dispatch(expandHomeTimeline());
|
||||
this.props.dispatch(expandNotifications());
|
||||
setTimeout(() => this.props.dispatch(fetchFilters()), 500);
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
|
|
|
@ -122,12 +122,9 @@
|
|||
"getting_started.open_source_notice": "ماستدون برنامج مفتوح المصدر. يمكنك المساهمة، أو الإبلاغ عن تقارير الأخطاء، على جيت هب {github}.",
|
||||
"getting_started.security": "الأمان",
|
||||
"getting_started.terms": "شروط الخدمة",
|
||||
"home.column_settings.advanced": "متقدمة",
|
||||
"home.column_settings.basic": "أساسية",
|
||||
"home.column_settings.filter_regex": "تصفية حسب التعبيرات العادية",
|
||||
"home.column_settings.show_reblogs": "عرض الترقيات",
|
||||
"home.column_settings.show_replies": "عرض الردود",
|
||||
"home.settings": "إعدادات العمود",
|
||||
"keyboard_shortcuts.back": "للعودة",
|
||||
"keyboard_shortcuts.boost": "للترقية",
|
||||
"keyboard_shortcuts.column": "للتركيز على منشور على أحد الأعمدة",
|
||||
|
@ -259,6 +256,7 @@
|
|||
"status.direct": "رسالة خاصة إلى @{name}",
|
||||
"status.embed": "إدماج",
|
||||
"status.favourite": "أضف إلى المفضلة",
|
||||
"status.filtered": "Filtered",
|
||||
"status.load_more": "حمّل المزيد",
|
||||
"status.media_hidden": "الصورة مستترة",
|
||||
"status.mention": "أذكُر @{name}",
|
||||
|
|
|
@ -122,12 +122,9 @@
|
|||
"getting_started.open_source_notice": "Mastodon е софтуер с отворен код. Можеш да помогнеш или да докладваш за проблеми в Github: {github}.",
|
||||
"getting_started.security": "Security",
|
||||
"getting_started.terms": "Terms of service",
|
||||
"home.column_settings.advanced": "Advanced",
|
||||
"home.column_settings.basic": "Basic",
|
||||
"home.column_settings.filter_regex": "Filter out by regular expressions",
|
||||
"home.column_settings.show_reblogs": "Show boosts",
|
||||
"home.column_settings.show_replies": "Show replies",
|
||||
"home.settings": "Column settings",
|
||||
"keyboard_shortcuts.back": "to navigate back",
|
||||
"keyboard_shortcuts.boost": "to boost",
|
||||
"keyboard_shortcuts.column": "to focus a status in one of the columns",
|
||||
|
@ -259,6 +256,7 @@
|
|||
"status.direct": "Direct message @{name}",
|
||||
"status.embed": "Embed",
|
||||
"status.favourite": "Предпочитани",
|
||||
"status.filtered": "Filtered",
|
||||
"status.load_more": "Load more",
|
||||
"status.media_hidden": "Media hidden",
|
||||
"status.mention": "Споменаване",
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
"column_header.show_settings": "Mostra la configuració",
|
||||
"column_header.unpin": "No fixis",
|
||||
"column_subheading.settings": "Configuració",
|
||||
"community.column_settings.media_only": "Media Only",
|
||||
"community.column_settings.media_only": "Només multimèdia",
|
||||
"compose_form.direct_message_warning": "Aquest toot només serà enviat als usuaris esmentats. De totes maneres, els operadors de la teva o de qualsevol de les instàncies receptores poden inspeccionar aquest missatge.",
|
||||
"compose_form.direct_message_warning_learn_more": "Aprèn més",
|
||||
"compose_form.hashtag_warning": "Aquest toot no es mostrarà en cap etiqueta ja que no està llistat. Només els toots públics poden ser cercats per etiqueta.",
|
||||
|
@ -114,20 +114,17 @@
|
|||
"empty_column.public": "No hi ha res aquí! Escriu alguna cosa públicament o segueix manualment usuaris d'altres instàncies per omplir-ho",
|
||||
"follow_request.authorize": "Autoritzar",
|
||||
"follow_request.reject": "Rebutjar",
|
||||
"getting_started.developers": "Developers",
|
||||
"getting_started.developers": "Desenvolupadors",
|
||||
"getting_started.documentation": "Documentació",
|
||||
"getting_started.find_friends": "Find friends from Twitter",
|
||||
"getting_started.find_friends": "Troba amics de Twitter",
|
||||
"getting_started.heading": "Començant",
|
||||
"getting_started.invite": "Invite people",
|
||||
"getting_started.invite": "Convida gent",
|
||||
"getting_started.open_source_notice": "Mastodon és un programari de codi obert. Pots contribuir o informar de problemes a GitHub a {github}.",
|
||||
"getting_started.security": "Security",
|
||||
"getting_started.security": "Seguretat",
|
||||
"getting_started.terms": "Termes del servei",
|
||||
"home.column_settings.advanced": "Avançat",
|
||||
"home.column_settings.basic": "Bàsic",
|
||||
"home.column_settings.filter_regex": "Filtrar per expressió regular",
|
||||
"home.column_settings.show_reblogs": "Mostrar impulsos",
|
||||
"home.column_settings.show_replies": "Mostrar respostes",
|
||||
"home.settings": "Ajustos de columna",
|
||||
"keyboard_shortcuts.back": "navegar enrera",
|
||||
"keyboard_shortcuts.boost": "impulsar",
|
||||
"keyboard_shortcuts.column": "per centrar un estat en una de les columnes",
|
||||
|
@ -259,6 +256,7 @@
|
|||
"status.direct": "Missatge directe @{name}",
|
||||
"status.embed": "Incrustar",
|
||||
"status.favourite": "Favorit",
|
||||
"status.filtered": "Filtered",
|
||||
"status.load_more": "Carrega més",
|
||||
"status.media_hidden": "Multimèdia amagat",
|
||||
"status.mention": "Esmentar @{name}",
|
||||
|
|
|
@ -122,12 +122,9 @@
|
|||
"getting_started.open_source_notice": "Mastodon ghjè un lugiziale liberu. Pudete cuntribuisce à u codice o a traduzione, o palisà un bug, nant'à GitHub: {github}.",
|
||||
"getting_started.security": "Security",
|
||||
"getting_started.terms": "Terms of service",
|
||||
"home.column_settings.advanced": "Avanzati",
|
||||
"home.column_settings.basic": "Bàsichi",
|
||||
"home.column_settings.filter_regex": "Filtrà cù spressione regulare (regex)",
|
||||
"home.column_settings.show_reblogs": "Vede e spartere",
|
||||
"home.column_settings.show_replies": "Vede e risposte",
|
||||
"home.settings": "Parametri di a colonna",
|
||||
"keyboard_shortcuts.back": "rivultà",
|
||||
"keyboard_shortcuts.boost": "sparte",
|
||||
"keyboard_shortcuts.column": "fucalizà un statutu indè una colonna",
|
||||
|
@ -259,6 +256,7 @@
|
|||
"status.direct": "Mandà un missaghju @{name}",
|
||||
"status.embed": "Integrà",
|
||||
"status.favourite": "Aghjunghje à i favuriti",
|
||||
"status.filtered": "Filtered",
|
||||
"status.load_more": "Vede di più",
|
||||
"status.media_hidden": "Media piattata",
|
||||
"status.mention": "Mintuvà @{name}",
|
||||
|
|
|
@ -0,0 +1,307 @@
|
|||
{
|
||||
"account.badges.bot": "Robot",
|
||||
"account.block": "Bloker @{name}",
|
||||
"account.block_domain": "Skjul alt fra {domain}",
|
||||
"account.blocked": "Blokeret",
|
||||
"account.direct": "Send en direkte besked til @{name}",
|
||||
"account.disclaimer_full": "Nedenstående oplysninger reflekterer ikke nødvendigvis brugerens profil fuldstændigt.",
|
||||
"account.domain_blocked": "Domænet er blevet skjult",
|
||||
"account.edit_profile": "Rediger profil",
|
||||
"account.follow": "Følg",
|
||||
"account.followers": "Følgere",
|
||||
"account.follows": "Følger",
|
||||
"account.follows_you": "Følger dig",
|
||||
"account.hide_reblogs": "Skjul fremhævelserne fra @{name}",
|
||||
"account.media": "Multimedier",
|
||||
"account.mention": "Nævn @{name}",
|
||||
"account.moved_to": "{name} er flyttet til:",
|
||||
"account.mute": "Dæmp @{name}",
|
||||
"account.mute_notifications": "Dæmp notifikationer fra @{name}",
|
||||
"account.muted": "Dæmpet",
|
||||
"account.posts": "Dyt",
|
||||
"account.posts_with_replies": "Toots og svar",
|
||||
"account.report": "Rapporter @{name}",
|
||||
"account.requested": "Afventer godkendelse. Tryk for at annullere følgeanmodning",
|
||||
"account.share": "Del @{name}s profil",
|
||||
"account.show_reblogs": "Vis fremhævelserne fra @{name}",
|
||||
"account.unblock": "Fjern blokeringen af @{name}",
|
||||
"account.unblock_domain": "Skjul ikke længere {domain}",
|
||||
"account.unfollow": "Følg ikke længere",
|
||||
"account.unmute": "Fjern dæmpningen af @{name}",
|
||||
"account.unmute_notifications": "Fjern dæmpningen af notifikationer fra @{name}",
|
||||
"account.view_full_profile": "Se fuld profil",
|
||||
"alert.unexpected.message": "Der opstod en uventet fejl.",
|
||||
"alert.unexpected.title": "Ups!",
|
||||
"boost_modal.combo": "Du kan trykke {combo} for at springe dette over næste gang",
|
||||
"bundle_column_error.body": "Noget gik galt under indlæsningen af dette komponent.",
|
||||
"bundle_column_error.retry": "Prøv igen",
|
||||
"bundle_column_error.title": "Netværksfejl",
|
||||
"bundle_modal_error.close": "Luk",
|
||||
"bundle_modal_error.message": "Noget gik galt under indlæsningen af dette komponent.",
|
||||
"bundle_modal_error.retry": "Prøv igen",
|
||||
"column.blocks": "Blokerede brugere",
|
||||
"column.community": "Lokal tidslinje",
|
||||
"column.direct": "Direkte beskeder",
|
||||
"column.domain_blocks": "Skjulte domæner",
|
||||
"column.favourites": "Favoritter",
|
||||
"column.follow_requests": "Anmodning om at følge",
|
||||
"column.home": "Hjem",
|
||||
"column.lists": "Lister",
|
||||
"column.mutes": "Dæmpede brugere",
|
||||
"column.notifications": "Notifikationer",
|
||||
"column.pins": "Fastgjorte toots",
|
||||
"column.public": "Fælles tidslinje",
|
||||
"column_back_button.label": "Tilbage",
|
||||
"column_header.hide_settings": "Skjul indstillinger",
|
||||
"column_header.moveLeft_settings": "Flyt kolonne til venstre",
|
||||
"column_header.moveRight_settings": "Flyt kolonne til højre",
|
||||
"column_header.pin": "Fastgør",
|
||||
"column_header.show_settings": "Vis indstillinger",
|
||||
"column_header.unpin": "Fastgør ikke længere",
|
||||
"column_subheading.settings": "Indstillinger",
|
||||
"community.column_settings.media_only": "Kun multimedier",
|
||||
"compose_form.direct_message_warning": "Dette toot vil kun blive sendt til de nævnte brugere.",
|
||||
"compose_form.direct_message_warning_learn_more": "Lær mere",
|
||||
"compose_form.hashtag_warning": "Dette toot vil ikke blive vist under noget hashtag da det ikke er listet. Kun offentlige toots kan blive vist under søgninger med hashtags.",
|
||||
"compose_form.lock_disclaimer": "Din konto er ikke {locked}. Alle kan følge dig for at se dine følger-kun indlæg.",
|
||||
"compose_form.lock_disclaimer.lock": "låst",
|
||||
"compose_form.placeholder": "Hvad har du på hjertet?",
|
||||
"compose_form.publish": "Toot",
|
||||
"compose_form.publish_loud": "{publish}!",
|
||||
"compose_form.sensitive.marked": "Multimedie er markeret som værende følsomt",
|
||||
"compose_form.sensitive.unmarked": "Multimediet er ikke markeret som værende følsomt",
|
||||
"compose_form.spoiler.marked": "Teksten er skjult bag en advarsel",
|
||||
"compose_form.spoiler.unmarked": "Teksten er ikke skjult",
|
||||
"compose_form.spoiler_placeholder": "Skriv din advarsel her",
|
||||
"confirmation_modal.cancel": "Annuller",
|
||||
"confirmations.block.confirm": "Bloker",
|
||||
"confirmations.block.message": "Er du sikker på, du vil blokere {name}?",
|
||||
"confirmations.delete.confirm": "Slet",
|
||||
"confirmations.delete.message": "Er du sikker på, du vil slette denne status?",
|
||||
"confirmations.delete_list.confirm": "Slet",
|
||||
"confirmations.delete_list.message": "Er du sikker på, du vil slette denne liste?",
|
||||
"confirmations.domain_block.confirm": "Skjul helt domæne",
|
||||
"confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.",
|
||||
"confirmations.mute.confirm": "Dæmp",
|
||||
"confirmations.mute.message": "Er du sikker på, du vil dæmpe {name}?",
|
||||
"confirmations.redraft.confirm": "Slet & omskriv",
|
||||
"confirmations.redraft.message": "Er du sikker på, du vil slette denne status og omskrive den? Du vil miste alle svar, fremhævelser og favoritter der medfølger.",
|
||||
"confirmations.unfollow.confirm": "Følg ikke længere",
|
||||
"confirmations.unfollow.message": "Er du sikker på, du ikke længere vil følge {name}?",
|
||||
"embed.instructions": "Indlejre denne status på din side ved at kopiere nedenstående kode.",
|
||||
"embed.preview": "Det kommer til at se således ud:",
|
||||
"emoji_button.activity": "Aktivitet",
|
||||
"emoji_button.custom": "Bruger defineret",
|
||||
"emoji_button.flags": "Flag",
|
||||
"emoji_button.food": "Mad og drikke",
|
||||
"emoji_button.label": "Indsæt humørikon",
|
||||
"emoji_button.nature": "Natur",
|
||||
"emoji_button.not_found": "Ingen emojos!! (╯°□°)╯︵ ┻━┻",
|
||||
"emoji_button.objects": "Objekter",
|
||||
"emoji_button.people": "Mennesker",
|
||||
"emoji_button.recent": "Oftest brugt",
|
||||
"emoji_button.search": "Søg...",
|
||||
"emoji_button.search_results": "Søgeresultat",
|
||||
"emoji_button.symbols": "Symboler",
|
||||
"emoji_button.travel": "Rejser & steder",
|
||||
"empty_column.community": "Den lokale tidslinje er tom. Skriv noget offentligt for at starte lavinen!",
|
||||
"empty_column.direct": "Du har endnu ingen direkte beskeder. Når du sender eller modtager en, vil den vises her.",
|
||||
"empty_column.hashtag": "Dette hashtag indeholder endnu ikke noget.",
|
||||
"empty_column.home": "Din hjemme tidslinje er tom! Besøg {public} eller brug søgningen for at komme igang og møde andre brugere.",
|
||||
"empty_column.home.public_timeline": "den offentlige tidslinje",
|
||||
"empty_column.list": "Der er endnu intet i denne liste. Når medlemmer af denne liste poster nye statusser, vil de vises her.",
|
||||
"empty_column.notifications": "Du har endnu ingen notifikationer. Tag ud og bland dig med folkemængden for at starte samtalen.",
|
||||
"empty_column.public": "Der er ikke noget at se her! Skriv noget offentligt eller start ud med manuelt at følge brugere fra andre instanser for st udfylde tomrummet",
|
||||
"follow_request.authorize": "Godkend",
|
||||
"follow_request.reject": "Afvis",
|
||||
"getting_started.developers": "Udviklere",
|
||||
"getting_started.documentation": "Dokumentation",
|
||||
"getting_started.find_friends": "Find venner fra Twitter",
|
||||
"getting_started.heading": "Kom igang",
|
||||
"getting_started.invite": "Inviter folk",
|
||||
"getting_started.open_source_notice": "Mastodon er et open source software. Du kan bidrage eller rapporterer fejl på GitHub {github}.",
|
||||
"getting_started.security": "Sikkerhed",
|
||||
"getting_started.terms": "Vilkår",
|
||||
"home.column_settings.basic": "Grundlæggende",
|
||||
"home.column_settings.show_reblogs": "Vis fremhævelser",
|
||||
"home.column_settings.show_replies": "Vis svar",
|
||||
"keyboard_shortcuts.back": "for at navigere dig tilbage",
|
||||
"keyboard_shortcuts.boost": "for at fremhæve",
|
||||
"keyboard_shortcuts.column": "for at fokusere på en status i en af kolonnerne",
|
||||
"keyboard_shortcuts.compose": "for at fokusere på skriveområdet",
|
||||
"keyboard_shortcuts.description": "Beskrivelse",
|
||||
"keyboard_shortcuts.down": "for at rykke ned ad listen",
|
||||
"keyboard_shortcuts.enter": "for at åbne status",
|
||||
"keyboard_shortcuts.favourite": "for at favorisere",
|
||||
"keyboard_shortcuts.heading": "Tastaturgenveje",
|
||||
"keyboard_shortcuts.hotkey": "Hurtigtast",
|
||||
"keyboard_shortcuts.legend": "for at vise denne legende",
|
||||
"keyboard_shortcuts.mention": "for at nævne forfatteren",
|
||||
"keyboard_shortcuts.reply": "for at svare",
|
||||
"keyboard_shortcuts.search": "for at fokusere søgningen",
|
||||
"keyboard_shortcuts.toggle_hidden": "for at vise/skjule tekst bag CW",
|
||||
"keyboard_shortcuts.toot": "for at påbegynde en helt ny toot",
|
||||
"keyboard_shortcuts.unfocus": "for at fjerne fokus fra skriveområde/søgning",
|
||||
"keyboard_shortcuts.up": "for at bevæge dig op ad listen",
|
||||
"lightbox.close": "Luk",
|
||||
"lightbox.next": "Næste",
|
||||
"lightbox.previous": "Forrige",
|
||||
"lists.account.add": "Tilføj til liste",
|
||||
"lists.account.remove": "Fjern fra liste",
|
||||
"lists.delete": "Slet liste",
|
||||
"lists.edit": "Rediger liste",
|
||||
"lists.new.create": "Tilføj liste",
|
||||
"lists.new.title_placeholder": "Ny liste titel",
|
||||
"lists.search": "Søg iblandt folk du følger",
|
||||
"lists.subheading": "Dine lister",
|
||||
"loading_indicator.label": "Indlæser...",
|
||||
"media_gallery.toggle_visible": "Ændre synlighed",
|
||||
"missing_indicator.label": "Ikke fundet",
|
||||
"missing_indicator.sublabel": "Denne ressource kunne ikke blive fundet",
|
||||
"mute_modal.hide_notifications": "Skjul notifikationer fra denne bruger?",
|
||||
"navigation_bar.blocks": "Blokerede brugere",
|
||||
"navigation_bar.community_timeline": "Lokal tidslinje",
|
||||
"navigation_bar.direct": "Direkte beskeder",
|
||||
"navigation_bar.discover": "Opdag",
|
||||
"navigation_bar.domain_blocks": "Skjulte domæner",
|
||||
"navigation_bar.edit_profile": "Rediger profil",
|
||||
"navigation_bar.favourites": "Favoritter",
|
||||
"navigation_bar.follow_requests": "Følgeanmodninger",
|
||||
"navigation_bar.info": "Om denne instans",
|
||||
"navigation_bar.keyboard_shortcuts": "Hurtigtast",
|
||||
"navigation_bar.lists": "Lister",
|
||||
"navigation_bar.logout": "Logud",
|
||||
"navigation_bar.mutes": "Dæmpede brugere",
|
||||
"navigation_bar.personal": "Personligt",
|
||||
"navigation_bar.pins": "Fastgjorte toots",
|
||||
"navigation_bar.preferences": "Indstillinger",
|
||||
"navigation_bar.public_timeline": "Fælles tidslinje",
|
||||
"navigation_bar.security": "Sikkerhed",
|
||||
"notification.favourite": "{name} favoriserede din status",
|
||||
"notification.follow": "{name} fulgte dig",
|
||||
"notification.mention": "{name} nævnte dig",
|
||||
"notification.reblog": "{name} fremhævede din status",
|
||||
"notifications.clear": "Ryd notifikationer",
|
||||
"notifications.clear_confirmation": "Er du sikker på, du vil rydde alle dine notifikationer permanent?",
|
||||
"notifications.column_settings.alert": "Skrivebords notifikationer",
|
||||
"notifications.column_settings.favourite": "Favoritter:",
|
||||
"notifications.column_settings.follow": "Nye følgere:",
|
||||
"notifications.column_settings.mention": "Omtale:",
|
||||
"notifications.column_settings.push": "Push notifikationer",
|
||||
"notifications.column_settings.push_meta": "Denne enhed",
|
||||
"notifications.column_settings.reblog": "Fremhævelser:",
|
||||
"notifications.column_settings.show": "Vis i kolonne",
|
||||
"notifications.column_settings.sound": "Afspil lyd",
|
||||
"notifications.group": "{count} notifikationer",
|
||||
"onboarding.done": "Færdig",
|
||||
"onboarding.next": "Næste",
|
||||
"onboarding.page_five.public_timelines": "Den lokale tidslinje viser offentlige opslag fra alle i {domain}. Den fælles tidslinje viser opslag fra alle der følges af folk i {domain}. Disse er de offentlige tidslinjer, hvilket er en god måde at møde nye mennesker på.",
|
||||
"onboarding.page_four.home": "Hjem tidslinjen viser opslag fra folk som du følger.",
|
||||
"onboarding.page_four.notifications": "Notifikations kolonnen viser når nogen interagerer med dig.",
|
||||
"onboarding.page_one.federation": "Mastodon er et netværk af uafhængige serverer der forbindes til at udgøre et større socialt netværk. Vi kalder disse servere for instanser.",
|
||||
"onboarding.page_one.full_handle": "Dit fulde brugernavn",
|
||||
"onboarding.page_one.handle_hint": "Dette er hvad du vil fortælle dine venner hvad de skal søge efter.",
|
||||
"onboarding.page_one.welcome": "Velkommen til Mastodon!",
|
||||
"onboarding.page_six.admin": "Administratoren for denne instans er {admin}.",
|
||||
"onboarding.page_six.almost_done": "Næsten færdig...",
|
||||
"onboarding.page_six.appetoot": "God Appetoot!",
|
||||
"onboarding.page_six.apps_available": "Der er {apps} tilgængelige for iOS, Android og andre platforme.",
|
||||
"onboarding.page_six.github": "Mastodon er frit open-source software. Du kan rapportere fejl, anmode om features, eller bidrage til koden ved at gå til {github}.",
|
||||
"onboarding.page_six.guidelines": "retningslinjer for fællesskabet",
|
||||
"onboarding.page_six.read_guidelines": "Læs venligst {domain}s {guidelines}!",
|
||||
"onboarding.page_six.various_app": "apps til mobilen",
|
||||
"onboarding.page_three.profile": "Rediger din profil for at ændre profilbillede, beskrivelse og visningsnavn. Der vil du også finde andre indstillinger.",
|
||||
"onboarding.page_three.search": "Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.",
|
||||
"onboarding.page_two.compose": "Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.",
|
||||
"onboarding.skip": "Spring over",
|
||||
"privacy.change": "Ændre status privatliv",
|
||||
"privacy.direct.long": "Post til kun de nævnte brugere",
|
||||
"privacy.direct.short": "Direkte",
|
||||
"privacy.private.long": "Post kun til følgere",
|
||||
"privacy.private.short": "Kun for følgere",
|
||||
"privacy.public.long": "Post til offentlige tidslinjer",
|
||||
"privacy.public.short": "Offentligt",
|
||||
"privacy.unlisted.long": "Post ikke til offentlige tidslinjer",
|
||||
"privacy.unlisted.short": "Ikke listet",
|
||||
"regeneration_indicator.label": "Indlæser…",
|
||||
"regeneration_indicator.sublabel": "Din startside er ved at blive forberedt!",
|
||||
"relative_time.days": "{number}d",
|
||||
"relative_time.hours": "{number}t",
|
||||
"relative_time.just_now": "nu",
|
||||
"relative_time.minutes": "{number}m",
|
||||
"relative_time.seconds": "{number}s",
|
||||
"reply_indicator.cancel": "Annuller",
|
||||
"report.forward": "Videresend til {target}",
|
||||
"report.forward_hint": "Kontoen er fra en anden server. Vil du også sende en anonym kopi af anmeldelsen dertil?",
|
||||
"report.hint": "Anmeldelsen vil blive sendt til moderatorene af din instans. Du kan give en forklaring for hvorfor du anmelder denne konto nedenfor:",
|
||||
"report.placeholder": "Yderligere kommentarer",
|
||||
"report.submit": "Indsend",
|
||||
"report.target": "Anmelder {target}",
|
||||
"search.placeholder": "Søg",
|
||||
"search_popout.search_format": "Avanceret søgeformat",
|
||||
"search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.",
|
||||
"search_popout.tips.hashtag": "emnetag",
|
||||
"search_popout.tips.status": "status",
|
||||
"search_popout.tips.text": "Simpelt tekst returnerer passende visningsnavne, brugernavne og hashtags",
|
||||
"search_popout.tips.user": "bruger",
|
||||
"search_results.accounts": "Folk",
|
||||
"search_results.hashtags": "Emnetags",
|
||||
"search_results.statuses": "Toote",
|
||||
"search_results.total": "{count, number} {count, plural, et {result} andre {results}}",
|
||||
"standalone.public_title": "Et kig indenfor...",
|
||||
"status.block": "Bloker @{name}",
|
||||
"status.cancel_reblog_private": "Fremhæv ikke længere",
|
||||
"status.cannot_reblog": "Denne post kan ikke fremhæves",
|
||||
"status.delete": "Slet",
|
||||
"status.direct": "Send direkte besked til @{name}",
|
||||
"status.embed": "Indlejre",
|
||||
"status.favourite": "Favorit",
|
||||
"status.filtered": "Filtered",
|
||||
"status.load_more": "Indlæs mere",
|
||||
"status.media_hidden": "Multimedia skjult",
|
||||
"status.mention": "Nævn @{name}",
|
||||
"status.more": "Mere",
|
||||
"status.mute": "Dæmp @{name}",
|
||||
"status.mute_conversation": "Dæmp samtale",
|
||||
"status.open": "Udvid denne status",
|
||||
"status.pin": "Fastgør til profil",
|
||||
"status.pinned": "Fastgjort toot",
|
||||
"status.reblog": "Fremhæv",
|
||||
"status.reblog_private": "Fremhæv til oprindeligt publikum",
|
||||
"status.reblogged_by": "{name} fremhævede",
|
||||
"status.redraft": "Slet og omskriv",
|
||||
"status.reply": "Svar",
|
||||
"status.replyAll": "Svar tråd",
|
||||
"status.report": "Anmeld @{name}",
|
||||
"status.sensitive_toggle": "Tryk for at se",
|
||||
"status.sensitive_warning": "Følsomt indhold",
|
||||
"status.share": "Del",
|
||||
"status.show_less": "Vis mindre",
|
||||
"status.show_less_all": "Vis mindre for alle",
|
||||
"status.show_more": "Vis mere",
|
||||
"status.show_more_all": "Vis mere for alle",
|
||||
"status.unmute_conversation": "Fjern dæmpningen fra samtale",
|
||||
"status.unpin": "Fjern som fastgjort fra profil",
|
||||
"tabs_bar.federated_timeline": "Fælles",
|
||||
"tabs_bar.home": "Hjem",
|
||||
"tabs_bar.local_timeline": "Lokal",
|
||||
"tabs_bar.notifications": "Notifikationer",
|
||||
"tabs_bar.search": "Søg",
|
||||
"trends.count_by_accounts": "{count} {rawCount, flere, en {person} flere {people}} snakker",
|
||||
"ui.beforeunload": "Din kladde vil gå tabt hvis du forlader Mastodon.",
|
||||
"upload_area.title": "Træk og slip for at uploade",
|
||||
"upload_button.label": "Tilføj multimedier",
|
||||
"upload_form.description": "Beskrivelse for de svagtseende",
|
||||
"upload_form.focus": "Beskær",
|
||||
"upload_form.undo": "Slet",
|
||||
"upload_progress.label": "Uploader...",
|
||||
"video.close": "Luk video",
|
||||
"video.exit_fullscreen": "Gå ud af fuldskærm",
|
||||
"video.expand": "Udvid video",
|
||||
"video.fullscreen": "Fuldskærm",
|
||||
"video.hide": "Skjul video",
|
||||
"video.mute": "Dæmp lyd",
|
||||
"video.pause": "Sæt på pause",
|
||||
"video.play": "Afspil",
|
||||
"video.unmute": "Fjern dæmpningen af lyd"
|
||||
}
|
|
@ -122,12 +122,9 @@
|
|||
"getting_started.open_source_notice": "Mastodon ist quelloffene Software. Du kannst auf GitHub unter {github} dazu beitragen oder Probleme melden.",
|
||||
"getting_started.security": "Sicherheit",
|
||||
"getting_started.terms": "Nutzungsbedingungen",
|
||||
"home.column_settings.advanced": "Erweitert",
|
||||
"home.column_settings.basic": "Einfach",
|
||||
"home.column_settings.filter_regex": "Mit regulären Ausdrücken filtern",
|
||||
"home.column_settings.show_reblogs": "Geteilte Beiträge anzeigen",
|
||||
"home.column_settings.show_replies": "Antworten anzeigen",
|
||||
"home.settings": "Spalteneinstellungen",
|
||||
"keyboard_shortcuts.back": "zurück navigieren",
|
||||
"keyboard_shortcuts.boost": "boosten",
|
||||
"keyboard_shortcuts.column": "einen Status in einer der Spalten fokussieren",
|
||||
|
@ -259,6 +256,7 @@
|
|||
"status.direct": "Direktnachricht @{name}",
|
||||
"status.embed": "Einbetten",
|
||||
"status.favourite": "Favorisieren",
|
||||
"status.filtered": "Filtered",
|
||||
"status.load_more": "Weitere laden",
|
||||
"status.media_hidden": "Medien versteckt",
|
||||
"status.mention": "@{name} erwähnen",
|
||||
|
|
|
@ -334,6 +334,10 @@
|
|||
},
|
||||
{
|
||||
"descriptors": [
|
||||
{
|
||||
"defaultMessage": "Filtered",
|
||||
"id": "status.filtered"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Pinned toot",
|
||||
"id": "status.pinned"
|
||||
|
@ -632,21 +636,9 @@
|
|||
},
|
||||
{
|
||||
"descriptors": [
|
||||
{
|
||||
"defaultMessage": "Filter out by regular expressions",
|
||||
"id": "home.column_settings.filter_regex"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Column settings",
|
||||
"id": "home.settings"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Media Only",
|
||||
"id": "community.column_settings.media_only"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Advanced",
|
||||
"id": "home.column_settings.advanced"
|
||||
}
|
||||
],
|
||||
"path": "app/javascript/mastodon/features/community_timeline/components/column_settings.json"
|
||||
|
@ -1019,23 +1011,6 @@
|
|||
],
|
||||
"path": "app/javascript/mastodon/features/compose/index.json"
|
||||
},
|
||||
{
|
||||
"descriptors": [
|
||||
{
|
||||
"defaultMessage": "Filter out by regular expressions",
|
||||
"id": "home.column_settings.filter_regex"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Column settings",
|
||||
"id": "home.settings"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Advanced",
|
||||
"id": "home.column_settings.advanced"
|
||||
}
|
||||
],
|
||||
"path": "app/javascript/mastodon/features/direct_timeline/components/column_settings.json"
|
||||
},
|
||||
{
|
||||
"descriptors": [
|
||||
{
|
||||
|
@ -1221,14 +1196,6 @@
|
|||
},
|
||||
{
|
||||
"descriptors": [
|
||||
{
|
||||
"defaultMessage": "Filter out by regular expressions",
|
||||
"id": "home.column_settings.filter_regex"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Column settings",
|
||||
"id": "home.settings"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Basic",
|
||||
"id": "home.column_settings.basic"
|
||||
|
@ -1240,10 +1207,6 @@
|
|||
{
|
||||
"defaultMessage": "Show replies",
|
||||
"id": "home.column_settings.show_replies"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Advanced",
|
||||
"id": "home.column_settings.advanced"
|
||||
}
|
||||
],
|
||||
"path": "app/javascript/mastodon/features/home_timeline/components/column_settings.json"
|
||||
|
@ -1947,10 +1910,6 @@
|
|||
"defaultMessage": "Notifications",
|
||||
"id": "tabs_bar.notifications"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Search",
|
||||
"id": "tabs_bar.search"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Local",
|
||||
"id": "tabs_bar.local_timeline"
|
||||
|
@ -1958,6 +1917,10 @@
|
|||
{
|
||||
"defaultMessage": "Federated",
|
||||
"id": "tabs_bar.federated_timeline"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Search",
|
||||
"id": "tabs_bar.search"
|
||||
}
|
||||
],
|
||||
"path": "app/javascript/mastodon/features/ui/components/tabs_bar.json"
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"account.block": "Απόκλεισε τον/την @{name}",
|
||||
"account.block_domain": "Απόκρυψε τα πάντα από τον/την",
|
||||
"account.blocked": "Αποκλεισμένος/η",
|
||||
"account.direct": "Άμεσο μήνυμα προς @{name}",
|
||||
"account.direct": "Προσωπικό μήνυμα προς @{name}",
|
||||
"account.disclaimer_full": "Οι παρακάτω πληροφορίες μπορει να μην αντανακλούν το προφίλ του χρήστη επαρκως.",
|
||||
"account.domain_blocked": "Κρυμμένος τομέας",
|
||||
"account.edit_profile": "Επεξεργάσου το προφίλ",
|
||||
|
@ -21,7 +21,7 @@
|
|||
"account.posts": "Τουτ",
|
||||
"account.posts_with_replies": "Τουτ και απαντήσεις",
|
||||
"account.report": "Κατάγγειλε τον/την @{name}",
|
||||
"account.requested": "Εκκρεμεί έγκριση. Κάνε κλικ για να ακυρώσεις το αίτημα ακολούθησης",
|
||||
"account.requested": "Εκκρεμεί έγκριση. Κάνε κλικ για να ακυρώσεις το αίτημα παρακολούθησης",
|
||||
"account.share": "Μοιράσου το προφίλ του/της @{name}",
|
||||
"account.show_reblogs": "Δείξε τις προωθήσεις του/της @{name}",
|
||||
"account.unblock": "Ξεμπλόκαρε τον/την @{name}",
|
||||
|
@ -41,7 +41,7 @@
|
|||
"bundle_modal_error.retry": "Δοκίμασε ξανά",
|
||||
"column.blocks": "Αποκλεισμένοι χρήστες",
|
||||
"column.community": "Τοπική ροή",
|
||||
"column.direct": "Απευθείας μηνύματα",
|
||||
"column.direct": "Προσωπικά μηνύματα",
|
||||
"column.domain_blocks": "Κρυμμένοι τομείς",
|
||||
"column.favourites": "Αγαπημένα",
|
||||
"column.follow_requests": "Αιτήματα ακολούθησης",
|
||||
|
@ -59,13 +59,13 @@
|
|||
"column_header.show_settings": "Εμφάνιση ρυθμίσεων",
|
||||
"column_header.unpin": "Ξεκαρφίτσωμα",
|
||||
"column_subheading.settings": "Ρυθμίσεις",
|
||||
"community.column_settings.media_only": "Media Only",
|
||||
"community.column_settings.media_only": "Μόνο πολυμέσα",
|
||||
"compose_form.direct_message_warning": "Αυτό το τουτ θα σταλεί μόνο στους αναφερόμενους χρήστες.",
|
||||
"compose_form.direct_message_warning_learn_more": "Μάθετε περισσότερα",
|
||||
"compose_form.hashtag_warning": "Αυτό το τουτ δεν θα εμφανίζεται κάτω από κανένα hashtag καθώς είναι αφανές. Μόνο τα δημόσια τουτ μπορούν να αναζητηθούν ανά hashtag.",
|
||||
"compose_form.lock_disclaimer": "Ο λογαριασμός σου δεν είναι {locked}. Οποιοσδήποτε μπορεί να σε ακολουθήσει για να δει τις δημοσιεύσεις σας προς τους ακολούθους σας.",
|
||||
"compose_form.lock_disclaimer.lock": "κλειδωμένος",
|
||||
"compose_form.placeholder": "Τι σκέφτεσαι;",
|
||||
"compose_form.placeholder": "Τι έχεις στο μυαλό σου;",
|
||||
"compose_form.publish": "Τουτ",
|
||||
"compose_form.publish_loud": "{publish}!",
|
||||
"compose_form.sensitive.marked": "Το πολυμέσο έχει σημειωθεί ως ευαίσθητο",
|
||||
|
@ -105,7 +105,7 @@
|
|||
"emoji_button.symbols": "Σύμβολα",
|
||||
"emoji_button.travel": "Ταξίδια & Τοποθεσίες",
|
||||
"empty_column.community": "Η τοπική ροή είναι κενή. Γράψε κάτι δημόσιο παραμύθι ν' αρχινίσει!",
|
||||
"empty_column.direct": "Δεν έχεις απευθείας μηνύματα ακόμα. Όταν στείλεις ή λάβεις κανένα, θα εμφανιστεί εδώ.",
|
||||
"empty_column.direct": "Δεν έχεις προσωπικά μηνύματα ακόμα. Όταν στείλεις ή λάβεις κανένα, θα εμφανιστεί εδώ.",
|
||||
"empty_column.hashtag": "Δεν υπάρχει ακόμα κάτι για αυτή την ταμπέλα.",
|
||||
"empty_column.home": "Η τοπική σου ροή είναι κενή! Πήγαινε στο {public} ή κάνε αναζήτηση για να ξεκινήσεις και να γνωρίσεις άλλους χρήστες.",
|
||||
"empty_column.home.public_timeline": "η δημόσια ροή",
|
||||
|
@ -114,20 +114,17 @@
|
|||
"empty_column.public": "Δεν υπάρχει τίποτα εδώ! Γράψε κάτι δημόσιο, ή ακολούθησε χειροκίνητα χρήστες από άλλα instances για να τη γεμίσεις",
|
||||
"follow_request.authorize": "Ενέκρινε",
|
||||
"follow_request.reject": "Απέρριψε",
|
||||
"getting_started.developers": "Developers",
|
||||
"getting_started.developers": "Προγραμματιστές",
|
||||
"getting_started.documentation": "Documentation",
|
||||
"getting_started.find_friends": "Find friends from Twitter",
|
||||
"getting_started.find_friends": "Βρες φίλους/ες από το Twitter",
|
||||
"getting_started.heading": "Ξεκινώντας",
|
||||
"getting_started.invite": "Invite people",
|
||||
"getting_started.invite": "Προσκάλεσε κόσμο",
|
||||
"getting_started.open_source_notice": "Το Mastodon είναι ελεύθερο λογισμικό. Μπορείς να συνεισφέρεις ή να αναφέρεις ζητήματα στο GitHub στο {github}.",
|
||||
"getting_started.security": "Security",
|
||||
"getting_started.security": "Ασφάλεια",
|
||||
"getting_started.terms": "Όροι χρήσης",
|
||||
"home.column_settings.advanced": "Προχωρημένα",
|
||||
"home.column_settings.basic": "Βασικά",
|
||||
"home.column_settings.filter_regex": "Φιλτράρετε μέσω regular expressions",
|
||||
"home.column_settings.show_reblogs": "Εμφάνιση προωθήσεων",
|
||||
"home.column_settings.show_replies": "Εμφάνιση απαντήσεων",
|
||||
"home.settings": "Ρυθμίσεις στηλών",
|
||||
"keyboard_shortcuts.back": "για επιστροφή πίσω",
|
||||
"keyboard_shortcuts.boost": "για προώθηση",
|
||||
"keyboard_shortcuts.column": "για εστίαση μιας κατάστασης σε μια από τις στήλες",
|
||||
|
@ -164,7 +161,7 @@
|
|||
"mute_modal.hide_notifications": "Απόκρυψη ειδοποιήσεων αυτού του χρήστη;",
|
||||
"navigation_bar.blocks": "Αποκλεισμένοι χρήστες",
|
||||
"navigation_bar.community_timeline": "Τοπική ροή",
|
||||
"navigation_bar.direct": "Απευθείας μηνύματα",
|
||||
"navigation_bar.direct": "Προσωπικά μηνύματα",
|
||||
"navigation_bar.discover": "Ανακάλυψη",
|
||||
"navigation_bar.domain_blocks": "Κρυφοί τομείς",
|
||||
"navigation_bar.edit_profile": "Επεξεργασία προφίλ",
|
||||
|
@ -219,7 +216,7 @@
|
|||
"onboarding.skip": "Παράληψη",
|
||||
"privacy.change": "Προσαρμογή ιδιωτικότητας δημοσίευσης",
|
||||
"privacy.direct.long": "Δημοσίευση μόνο σε όσους και όσες αναφέρονται",
|
||||
"privacy.direct.short": "Απευθείας",
|
||||
"privacy.direct.short": "Προσωπικά",
|
||||
"privacy.private.long": "Δημοσίευση μόνο στους ακόλουθους",
|
||||
"privacy.private.short": "Μόνο ακόλουθοι",
|
||||
"privacy.public.long": "Δημοσίευσε στις δημόσιες ροές",
|
||||
|
@ -238,7 +235,7 @@
|
|||
"report.forward_hint": "Ο λογαριασμός είναι από διαφορετικό διακομιστή. Να σταλεί ανώνυμο αντίγραφο της καταγγελίας κι εκεί;",
|
||||
"report.hint": "Η καταγγελία θα σταλεί στους διαχειριστές του κόμβου σου. Μπορείς να περιγράψεις γιατί καταγγέλεις το λογαριασμό παρακάτω:",
|
||||
"report.placeholder": "Επιπλέον σχόλια",
|
||||
"report.submit": "Submit",
|
||||
"report.submit": "Υποβολή",
|
||||
"report.target": "Καταγγελία {target}",
|
||||
"search.placeholder": "Αναζήτηση",
|
||||
"search_popout.search_format": "Προχωρημένη αναζήτηση",
|
||||
|
@ -256,9 +253,10 @@
|
|||
"status.cancel_reblog_private": "Ακύρωσε την προώθηση",
|
||||
"status.cannot_reblog": "Αυτή η δημοσίευση δεν μπορεί να προωθηθεί",
|
||||
"status.delete": "Διαγραφή",
|
||||
"status.direct": "Απευθείας μήνυμα προς @{name}",
|
||||
"status.direct": "Προσωπικό μήνυμα προς @{name}",
|
||||
"status.embed": "Ενσωμάτωσε",
|
||||
"status.favourite": "Σημείωσε ως αγαπημένο",
|
||||
"status.filtered": "Filtered",
|
||||
"status.load_more": "Φόρτωσε περισσότερα",
|
||||
"status.media_hidden": "Κρυμμένο πολυμέσο",
|
||||
"status.mention": "Ανέφερε τον/την @{name}",
|
||||
|
@ -269,7 +267,7 @@
|
|||
"status.pin": "Καρφίτσωσε στο προφίλ",
|
||||
"status.pinned": "Καρφιτσωμένο τουτ",
|
||||
"status.reblog": "Προώθησε",
|
||||
"status.reblog_private": "Προώθησε στο αρχικό κοινό",
|
||||
"status.reblog_private": "Προώθησε στους αρχικούς παραλήπτες",
|
||||
"status.reblogged_by": "{name} προώθησε",
|
||||
"status.redraft": "Σβήσε & ξαναγράψε",
|
||||
"status.reply": "Απάντησε",
|
||||
|
@ -298,12 +296,12 @@
|
|||
"upload_form.undo": "Διαγραφή",
|
||||
"upload_progress.label": "Ανεβαίνει...",
|
||||
"video.close": "Κλείσε το βίντεο",
|
||||
"video.exit_fullscreen": "Έξοδος πλήρης οθόνης",
|
||||
"video.exit_fullscreen": "Έξοδος από πλήρη οθόνη",
|
||||
"video.expand": "Επέκταση βίντεο",
|
||||
"video.fullscreen": "Πλήρης οθόνη",
|
||||
"video.hide": "Κρύψε βίντεο",
|
||||
"video.mute": "Mute sound",
|
||||
"video.mute": "Σίγαση ήχου",
|
||||
"video.pause": "Pause",
|
||||
"video.play": "Play",
|
||||
"video.unmute": "Unmute sound"
|
||||
"video.play": "Αναπαραγωγή",
|
||||
"video.unmute": "Αναπαραγωγή ήχου"
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
|
||||
"compose_form.lock_disclaimer.lock": "locked",
|
||||
"compose_form.placeholder": "What is on your mind?",
|
||||
"compose_form.placeholder": "What's on your mind?",
|
||||
"compose_form.publish": "Toot",
|
||||
"compose_form.publish_loud": "{publish}!",
|
||||
"compose_form.sensitive.marked": "Media is marked as sensitive",
|
||||
|
@ -126,12 +126,9 @@
|
|||
"getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.",
|
||||
"getting_started.security": "Security",
|
||||
"getting_started.terms": "Terms of service",
|
||||
"home.column_settings.advanced": "Advanced",
|
||||
"home.column_settings.basic": "Basic",
|
||||
"home.column_settings.filter_regex": "Filter out by regular expressions",
|
||||
"home.column_settings.show_reblogs": "Show boosts",
|
||||
"home.column_settings.show_replies": "Show replies",
|
||||
"home.settings": "Column settings",
|
||||
"keyboard_shortcuts.back": "to navigate back",
|
||||
"keyboard_shortcuts.boost": "to boost",
|
||||
"keyboard_shortcuts.column": "to focus a status in one of the columns",
|
||||
|
@ -264,6 +261,7 @@
|
|||
"status.direct": "Direct message @{name}",
|
||||
"status.embed": "Embed",
|
||||
"status.favourite": "Favourite",
|
||||
"status.filtered": "Filtered",
|
||||
"status.load_more": "Load more",
|
||||
"status.media_hidden": "Media hidden",
|
||||
"status.mention": "Mention @{name}",
|
||||
|
|
|
@ -122,12 +122,9 @@
|
|||
"getting_started.open_source_notice": "Mastodon estas malfermitkoda programo. Vi povas kontribui aŭ raporti problemojn en GitHub je {github}.",
|
||||
"getting_started.security": "Sekureco",
|
||||
"getting_started.terms": "Uzkondiĉoj",
|
||||
"home.column_settings.advanced": "Precizaj agordoj",
|
||||
"home.column_settings.basic": "Bazaj agordoj",
|
||||
"home.column_settings.filter_regex": "Filtri per regulesprimoj",
|
||||
"home.column_settings.show_reblogs": "Montri diskonigojn",
|
||||
"home.column_settings.show_replies": "Montri respondojn",
|
||||
"home.settings": "Kolumnaj agordoj",
|
||||
"keyboard_shortcuts.back": "por reveni",
|
||||
"keyboard_shortcuts.boost": "por diskonigi",
|
||||
"keyboard_shortcuts.column": "por fokusigi mesaĝon en unu el la kolumnoj",
|
||||
|
@ -259,6 +256,7 @@
|
|||
"status.direct": "Rekte mesaĝi @{name}",
|
||||
"status.embed": "Enkorpigi",
|
||||
"status.favourite": "Stelumi",
|
||||
"status.filtered": "Filtered",
|
||||
"status.load_more": "Ŝargi pli",
|
||||
"status.media_hidden": "Aŭdovidaĵo kaŝita",
|
||||
"status.mention": "Mencii @{name}",
|
||||
|
|
|
@ -122,12 +122,9 @@
|
|||
"getting_started.open_source_notice": "Mastodon es software libre. Puedes contribuir o reportar errores en {github}.",
|
||||
"getting_started.security": "Security",
|
||||
"getting_started.terms": "Terms of service",
|
||||
"home.column_settings.advanced": "Avanzado",
|
||||
"home.column_settings.basic": "Básico",
|
||||
"home.column_settings.filter_regex": "Filtrar con expresiones regulares",
|
||||
"home.column_settings.show_reblogs": "Mostrar retoots",
|
||||
"home.column_settings.show_replies": "Mostrar respuestas",
|
||||
"home.settings": "Ajustes de columna",
|
||||
"keyboard_shortcuts.back": "volver atrás",
|
||||
"keyboard_shortcuts.boost": "retootear",
|
||||
"keyboard_shortcuts.column": "enfocar un estado en una de las columnas",
|
||||
|
@ -259,6 +256,7 @@
|
|||
"status.direct": "Direct message @{name}",
|
||||
"status.embed": "Incrustado",
|
||||
"status.favourite": "Favorito",
|
||||
"status.filtered": "Filtered",
|
||||
"status.load_more": "Cargar más",
|
||||
"status.media_hidden": "Contenido multimedia oculto",
|
||||
"status.mention": "Mencionar",
|
||||
|
|
|
@ -122,12 +122,9 @@
|
|||
"getting_started.open_source_notice": "Mastodon software librea da. Ekarpenak egin ditzakezu edo akatsen berri eman GitHub bidez: {github}.",
|
||||
"getting_started.security": "Segurtasuna",
|
||||
"getting_started.terms": "Erabilera baldintzak",
|
||||
"home.column_settings.advanced": "Aurreratua",
|
||||
"home.column_settings.basic": "Oinarrizkoa",
|
||||
"home.column_settings.filter_regex": "Iragazi adierazpen erregularren bidez",
|
||||
"home.column_settings.show_reblogs": "Erakutsi bultzadak",
|
||||
"home.column_settings.show_replies": "Erakutsi erantzunak",
|
||||
"home.settings": "Zutabearen ezarpenak",
|
||||
"keyboard_shortcuts.back": "atzera nabigatzeko",
|
||||
"keyboard_shortcuts.boost": "bultzada ematea",
|
||||
"keyboard_shortcuts.column": "mezu bat zutabe batean fokatzea",
|
||||
|
@ -259,6 +256,7 @@
|
|||
"status.direct": "Mezu zuzena @{name}(r)i",
|
||||
"status.embed": "Txertatu",
|
||||
"status.favourite": "Gogokoa",
|
||||
"status.filtered": "Filtered",
|
||||
"status.load_more": "Kargatu gehiago",
|
||||
"status.media_hidden": "Multimedia ezkutatua",
|
||||
"status.mention": "Aipatu @{name}",
|
||||
|
|
|
@ -122,12 +122,9 @@
|
|||
"getting_started.open_source_notice": "ماستدون یک نرمافزار آزاد است. میتوانید در ساخت آن مشارکت کنید یا مشکلاتش را در {github} گزارش دهید.",
|
||||
"getting_started.security": "امنیت",
|
||||
"getting_started.terms": "شرایط استفاده",
|
||||
"home.column_settings.advanced": "پیشرفته",
|
||||
"home.column_settings.basic": "اصلی",
|
||||
"home.column_settings.filter_regex": "با عبارتهای باقاعده (regexp) فیلتر کنید",
|
||||
"home.column_settings.show_reblogs": "نمایش بازبوقها",
|
||||
"home.column_settings.show_replies": "نمایش پاسخها",
|
||||
"home.settings": "تنظیمات ستون",
|
||||
"keyboard_shortcuts.back": "برای بازگشت",
|
||||
"keyboard_shortcuts.boost": "برای بازبوقیدن",
|
||||
"keyboard_shortcuts.column": "برای برجستهکردن یک نوشته در یکی از ستونها",
|
||||
|
@ -259,6 +256,7 @@
|
|||
"status.direct": "پیغام مستقیم به @{name}",
|
||||
"status.embed": "جاگذاری",
|
||||
"status.favourite": "پسندیدن",
|
||||
"status.filtered": "Filtered",
|
||||
"status.load_more": "بیشتر نشان بده",
|
||||
"status.media_hidden": "تصویر پنهان شده",
|
||||
"status.mention": "نامبردن از @{name}",
|
||||
|
|
|
@ -122,12 +122,9 @@
|
|||
"getting_started.open_source_notice": "Mastodon on avoimen lähdekoodin ohjelma. Voit avustaa tai raportoida ongelmia GitHubissa: {github}.",
|
||||
"getting_started.security": "Security",
|
||||
"getting_started.terms": "Terms of service",
|
||||
"home.column_settings.advanced": "Lisäasetukset",
|
||||
"home.column_settings.basic": "Perusasetukset",
|
||||
"home.column_settings.filter_regex": "Suodata säännöllisillä lausekkeilla",
|
||||
"home.column_settings.show_reblogs": "Näytä buustaukset",
|
||||
"home.column_settings.show_replies": "Näytä vastaukset",
|
||||
"home.settings": "Sarakeasetukset",
|
||||
"keyboard_shortcuts.back": "liiku taaksepäin",
|
||||
"keyboard_shortcuts.boost": "buustaa",
|
||||
"keyboard_shortcuts.column": "siirrä fokus tietyn sarakkeen tilapäivitykseen",
|
||||
|
@ -259,6 +256,7 @@
|
|||
"status.direct": "Viesti käyttäjälle @{name}",
|
||||
"status.embed": "Upota",
|
||||
"status.favourite": "Tykkää",
|
||||
"status.filtered": "Filtered",
|
||||
"status.load_more": "Lataa lisää",
|
||||
"status.media_hidden": "Media piilotettu",
|
||||
"status.mention": "Mainitse @{name}",
|
||||
|
|
|
@ -122,12 +122,9 @@
|
|||
"getting_started.open_source_notice": "Mastodon est un logiciel libre. Vous pouvez contribuer et envoyer vos commentaires et rapports de bogues via {github} sur GitHub.",
|
||||
"getting_started.security": "Sécurité",
|
||||
"getting_started.terms": "Conditions d’utilisation",
|
||||
"home.column_settings.advanced": "Avancé",
|
||||
"home.column_settings.basic": "Basique",
|
||||
"home.column_settings.filter_regex": "Filtrer avec une expression rationnelle",
|
||||
"home.column_settings.show_reblogs": "Afficher les partages",
|
||||
"home.column_settings.show_replies": "Afficher les réponses",
|
||||
"home.settings": "Paramètres de la colonne",
|
||||
"keyboard_shortcuts.back": "revenir en arrière",
|
||||
"keyboard_shortcuts.boost": "partager",
|
||||
"keyboard_shortcuts.column": "focaliser un statut dans l'une des colonnes",
|
||||
|
@ -259,6 +256,7 @@
|
|||
"status.direct": "Envoyer un message direct à @{name}",
|
||||
"status.embed": "Intégrer",
|
||||
"status.favourite": "Ajouter aux favoris",
|
||||
"status.filtered": "Filtered",
|
||||
"status.load_more": "Charger plus",
|
||||
"status.media_hidden": "Média caché",
|
||||
"status.mention": "Mentionner",
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
"compose_form.hashtag_warning": "Esta mensaxe non será listada baixo ningunha etiqueta xa que está marcada como non listada. Só os toots públicos poden buscarse por etiquetas.",
|
||||
"compose_form.lock_disclaimer": "A súa conta non está {locked}. Calquera pode seguila para ver as súas mensaxes só-para-seguidoras.",
|
||||
"compose_form.lock_disclaimer.lock": "bloqueado",
|
||||
"compose_form.placeholder": "A qué andas?",
|
||||
"compose_form.placeholder": "Qué contas?",
|
||||
"compose_form.publish": "Toot",
|
||||
"compose_form.publish_loud": "{publish}!",
|
||||
"compose_form.sensitive.marked": "Medios marcados como sensibles",
|
||||
|
@ -122,12 +122,9 @@
|
|||
"getting_started.open_source_notice": "Mastodon é software de código aberto. Pode contribuír ou informar de fallos en GitHub en {github}.",
|
||||
"getting_started.security": "Security",
|
||||
"getting_started.terms": "Terms of service",
|
||||
"home.column_settings.advanced": "Avanzado",
|
||||
"home.column_settings.basic": "Básico",
|
||||
"home.column_settings.filter_regex": "Filtrar expresións regulares",
|
||||
"home.column_settings.show_reblogs": "Mostrar repeticións",
|
||||
"home.column_settings.show_replies": "Mostrar respostas",
|
||||
"home.settings": "Axustes da columna",
|
||||
"keyboard_shortcuts.back": "voltar atrás",
|
||||
"keyboard_shortcuts.boost": "promover",
|
||||
"keyboard_shortcuts.column": "destacar un estado en unha das columnas",
|
||||
|
@ -259,6 +256,7 @@
|
|||
"status.direct": "Mensaxe directa @{name}",
|
||||
"status.embed": "Incrustar",
|
||||
"status.favourite": "Favorita",
|
||||
"status.filtered": "Filtered",
|
||||
"status.load_more": "Cargar máis",
|
||||
"status.media_hidden": "Medios ocultos",
|
||||
"status.mention": "Mencionar @{name}",
|
||||
|
|
|
@ -122,12 +122,9 @@
|
|||
"getting_started.open_source_notice": "מסטודון היא תוכנה חופשית (בקוד פתוח). ניתן לתרום או לדווח על בעיות בגיטהאב: {github}.",
|
||||
"getting_started.security": "Security",
|
||||
"getting_started.terms": "Terms of service",
|
||||
"home.column_settings.advanced": "למתקדמים",
|
||||
"home.column_settings.basic": "למתחילים",
|
||||
"home.column_settings.filter_regex": "סינון באמצעות ביטויים רגולריים (regular expressions)",
|
||||
"home.column_settings.show_reblogs": "הצגת הדהודים",
|
||||
"home.column_settings.show_replies": "הצגת תגובות",
|
||||
"home.settings": "הגדרות טור",
|
||||
"keyboard_shortcuts.back": "ניווט חזרה",
|
||||
"keyboard_shortcuts.boost": "להדהד",
|
||||
"keyboard_shortcuts.column": "להתמקד בהודעה באחד מהטורים",
|
||||
|
@ -259,6 +256,7 @@
|
|||
"status.direct": "Direct message @{name}",
|
||||
"status.embed": "הטמעה",
|
||||
"status.favourite": "חיבוב",
|
||||
"status.filtered": "Filtered",
|
||||
"status.load_more": "עוד",
|
||||
"status.media_hidden": "מדיה מוסתרת",
|
||||
"status.mention": "פניה אל @{name}",
|
||||
|
|
|
@ -122,12 +122,9 @@
|
|||
"getting_started.open_source_notice": "Mastodon je softver otvorenog koda. Možeš pridonijeti ili prijaviti probleme na GitHubu {github}.",
|
||||
"getting_started.security": "Security",
|
||||
"getting_started.terms": "Terms of service",
|
||||
"home.column_settings.advanced": "Napredno",
|
||||
"home.column_settings.basic": "Osnovno",
|
||||
"home.column_settings.filter_regex": "Filtriraj s regularnim izrazima",
|
||||
"home.column_settings.show_reblogs": "Pokaži boostove",
|
||||
"home.column_settings.show_replies": "Pokaži odgovore",
|
||||
"home.settings": "Postavke Stupca",
|
||||
"keyboard_shortcuts.back": "to navigate back",
|
||||
"keyboard_shortcuts.boost": "to boost",
|
||||
"keyboard_shortcuts.column": "to focus a status in one of the columns",
|
||||
|
@ -259,6 +256,7 @@
|
|||
"status.direct": "Direct message @{name}",
|
||||
"status.embed": "Embed",
|
||||
"status.favourite": "Označi omiljenim",
|
||||
"status.filtered": "Filtered",
|
||||
"status.load_more": "Učitaj više",
|
||||
"status.media_hidden": "Sakriven media sadržaj",
|
||||
"status.mention": "Spomeni @{name}",
|
||||
|
|
|
@ -122,12 +122,9 @@
|
|||
"getting_started.open_source_notice": "Mastodon egy nyílt forráskódú szoftver. Hozzájárulás vagy problémák jelentése a GitHub-on {github}.",
|
||||
"getting_started.security": "Security",
|
||||
"getting_started.terms": "Terms of service",
|
||||
"home.column_settings.advanced": "Fejlett",
|
||||
"home.column_settings.basic": "Alap",
|
||||
"home.column_settings.filter_regex": "Szűrje ki reguláris kifejezésekkel",
|
||||
"home.column_settings.show_reblogs": "Ismétlések mutatása",
|
||||
"home.column_settings.show_replies": "Válaszok mutatása",
|
||||
"home.settings": "Oszlop beállításai",
|
||||
"keyboard_shortcuts.back": "vissza navigálás",
|
||||
"keyboard_shortcuts.boost": "ismétlés",
|
||||
"keyboard_shortcuts.column": "összpontosítson egy státuszra az egyik oszlopban",
|
||||
|
@ -259,6 +256,7 @@
|
|||
"status.direct": "Direct message @{name}",
|
||||
"status.embed": "Beágyaz",
|
||||
"status.favourite": "Kedvenc",
|
||||
"status.filtered": "Filtered",
|
||||
"status.load_more": "Többet",
|
||||
"status.media_hidden": "Média elrejtve",
|
||||
"status.mention": "Említés",
|
||||
|
|
|
@ -122,12 +122,9 @@
|
|||
"getting_started.open_source_notice": "Մաստոդոնը բաց ելատեքստով ծրագրակազմ է։ Կարող ես ներդրում անել կամ վրեպներ զեկուցել ԳիթՀաբում՝ {github}։",
|
||||
"getting_started.security": "Security",
|
||||
"getting_started.terms": "Terms of service",
|
||||
"home.column_settings.advanced": "Առաջադեմ",
|
||||
"home.column_settings.basic": "Հիմնական",
|
||||
"home.column_settings.filter_regex": "Զտել օրինաչափ արտահայտությամբ",
|
||||
"home.column_settings.show_reblogs": "Ցուցադրել տարածածները",
|
||||
"home.column_settings.show_replies": "Ցուցադրել պատասխանները",
|
||||
"home.settings": "Սյան կարգավորումներ",
|
||||
"keyboard_shortcuts.back": "ետ նավարկելու համար",
|
||||
"keyboard_shortcuts.boost": "տարածելու համար",
|
||||
"keyboard_shortcuts.column": "սյուներից մեկի վրա սեւեռվելու համար",
|
||||
|
@ -259,6 +256,7 @@
|
|||
"status.direct": "Direct message @{name}",
|
||||
"status.embed": "Ներդնել",
|
||||
"status.favourite": "Հավանել",
|
||||
"status.filtered": "Filtered",
|
||||
"status.load_more": "Բեռնել ավելին",
|
||||
"status.media_hidden": "մեդիաբովանդակությունը թաքցված է",
|
||||
"status.mention": "Նշել @{name}֊ին",
|
||||
|
|