Merge branch 'master' into glitch-soc/merge-upstream
Manually-resolved conflicts: .circleci/config.yml app/controllers/accounts_controller.rb app/controllers/auth/passwords_controller.rb app/controllers/statuses_controller.rb app/javascript/packs/public.js app/models/media_attachment.rb app/views/stream_entries/_content_spoiler.html.haml app/views/stream_entries/_media.html.haml config/locales/en.yml config/locales/ja.yml config/locales/pl.yml lib/mastodon/version.rb Some content from app/javascript/packs/public.js has been split to app/javascript/core/settings.js. Translation strings for glitch-soc's keyword mutes were dropped. Everything else was mostly “take both”.
This commit is contained in:
commit
c1c514ca70
187 changed files with 3356 additions and 2009 deletions
|
@ -31,7 +31,7 @@ class AboutController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_body_classes
|
def set_body_classes
|
||||||
@body_classes = 'about-body'
|
@body_classes = 'with-modals'
|
||||||
end
|
end
|
||||||
|
|
||||||
def initial_state_params
|
def initial_state_params
|
||||||
|
|
|
@ -11,6 +11,7 @@ class AccountsController < ApplicationController
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html do
|
format.html do
|
||||||
use_pack 'public'
|
use_pack 'public'
|
||||||
|
@body_classes = 'with-modals'
|
||||||
@pinned_statuses = []
|
@pinned_statuses = []
|
||||||
|
|
||||||
if current_account && @account.blocking?(current_account)
|
if current_account && @account.blocking?(current_account)
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
class Auth::ConfirmationsController < Devise::ConfirmationsController
|
class Auth::ConfirmationsController < Devise::ConfirmationsController
|
||||||
layout 'auth'
|
layout 'auth'
|
||||||
|
|
||||||
|
before_action :set_body_classes
|
||||||
before_action :set_user, only: [:finish_signup]
|
before_action :set_user, only: [:finish_signup]
|
||||||
before_action :set_pack
|
before_action :set_pack
|
||||||
|
|
||||||
|
@ -28,6 +29,10 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController
|
||||||
@user = current_user
|
@user = current_user
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_body_classes
|
||||||
|
@body_classes = 'lighter'
|
||||||
|
end
|
||||||
|
|
||||||
def user_params
|
def user_params
|
||||||
params.require(:user).permit(:email)
|
params.require(:user).permit(:email)
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
class Auth::PasswordsController < Devise::PasswordsController
|
class Auth::PasswordsController < Devise::PasswordsController
|
||||||
before_action :check_validity_of_reset_password_token, only: :edit
|
before_action :check_validity_of_reset_password_token, only: :edit
|
||||||
before_action :set_pack
|
before_action :set_pack
|
||||||
|
before_action :set_body_classes
|
||||||
|
|
||||||
layout 'auth'
|
layout 'auth'
|
||||||
|
|
||||||
|
@ -15,6 +16,10 @@ class Auth::PasswordsController < Devise::PasswordsController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_body_classes
|
||||||
|
@body_classes = 'lighter'
|
||||||
|
end
|
||||||
|
|
||||||
def reset_password_token_is_valid?
|
def reset_password_token_is_valid?
|
||||||
resource_class.with_reset_password_token(params[:reset_password_token]).present?
|
resource_class.with_reset_password_token(params[:reset_password_token]).present?
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,6 +9,7 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
||||||
before_action :set_pack
|
before_action :set_pack
|
||||||
before_action :set_sessions, only: [:edit, :update]
|
before_action :set_sessions, only: [:edit, :update]
|
||||||
before_action :set_instance_presenter, only: [:new, :create, :update]
|
before_action :set_instance_presenter, only: [:new, :create, :update]
|
||||||
|
before_action :set_body_classes, only: [:new, :create]
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
not_found
|
not_found
|
||||||
|
@ -84,6 +85,10 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
||||||
@instance_presenter = InstancePresenter.new
|
@instance_presenter = InstancePresenter.new
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_body_classes
|
||||||
|
@body_classes = 'lighter'
|
||||||
|
end
|
||||||
|
|
||||||
def set_invite
|
def set_invite
|
||||||
@invite = invite_code.present? ? Invite.find_by(code: invite_code) : nil
|
@invite = invite_code.present? ? Invite.find_by(code: invite_code) : nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,6 +10,7 @@ class Auth::SessionsController < Devise::SessionsController
|
||||||
prepend_before_action :authenticate_with_two_factor, if: :two_factor_enabled?, only: [:create]
|
prepend_before_action :authenticate_with_two_factor, if: :two_factor_enabled?, only: [:create]
|
||||||
prepend_before_action :set_pack
|
prepend_before_action :set_pack
|
||||||
before_action :set_instance_presenter, only: [:new]
|
before_action :set_instance_presenter, only: [:new]
|
||||||
|
before_action :set_body_classes
|
||||||
|
|
||||||
def new
|
def new
|
||||||
Devise.omniauth_configs.each do |provider, config|
|
Devise.omniauth_configs.each do |provider, config|
|
||||||
|
@ -114,6 +115,10 @@ class Auth::SessionsController < Devise::SessionsController
|
||||||
@instance_presenter = InstancePresenter.new
|
@instance_presenter = InstancePresenter.new
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_body_classes
|
||||||
|
@body_classes = 'lighter'
|
||||||
|
end
|
||||||
|
|
||||||
def home_paths(resource)
|
def home_paths(resource)
|
||||||
paths = [about_path]
|
paths = [about_path]
|
||||||
if single_user_mode? && resource.is_a?(User)
|
if single_user_mode? && resource.is_a?(User)
|
||||||
|
|
|
@ -8,6 +8,7 @@ module AccountControllerConcern
|
||||||
included do
|
included do
|
||||||
layout 'public'
|
layout 'public'
|
||||||
before_action :set_account
|
before_action :set_account
|
||||||
|
before_action :set_instance_presenter
|
||||||
before_action :set_link_headers
|
before_action :set_link_headers
|
||||||
before_action :check_account_suspension
|
before_action :check_account_suspension
|
||||||
end
|
end
|
||||||
|
@ -18,6 +19,10 @@ module AccountControllerConcern
|
||||||
@account = Account.find_local!(params[:account_username])
|
@account = Account.find_local!(params[:account_username])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_instance_presenter
|
||||||
|
@instance_presenter = InstancePresenter.new
|
||||||
|
end
|
||||||
|
|
||||||
def set_link_headers
|
def set_link_headers
|
||||||
response.headers['Link'] = LinkHeader.new(
|
response.headers['Link'] = LinkHeader.new(
|
||||||
[
|
[
|
||||||
|
|
|
@ -43,7 +43,7 @@ class InvitesController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def invites
|
def invites
|
||||||
Invite.where(user: current_user)
|
Invite.where(user: current_user).order(id: :desc)
|
||||||
end
|
end
|
||||||
|
|
||||||
def resource_params
|
def resource_params
|
||||||
|
|
|
@ -12,6 +12,7 @@ class StatusesController < ApplicationController
|
||||||
|
|
||||||
before_action :set_account
|
before_action :set_account
|
||||||
before_action :set_status
|
before_action :set_status
|
||||||
|
before_action :set_instance_presenter
|
||||||
before_action :set_link_headers
|
before_action :set_link_headers
|
||||||
before_action :check_account_suspension
|
before_action :check_account_suspension
|
||||||
before_action :redirect_to_original, only: [:show]
|
before_action :redirect_to_original, only: [:show]
|
||||||
|
@ -22,6 +23,8 @@ class StatusesController < ApplicationController
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html do
|
format.html do
|
||||||
use_pack 'public'
|
use_pack 'public'
|
||||||
|
@body_classes = 'with-modals'
|
||||||
|
|
||||||
set_ancestors
|
set_ancestors
|
||||||
set_descendants
|
set_descendants
|
||||||
|
|
||||||
|
@ -150,6 +153,10 @@ class StatusesController < ApplicationController
|
||||||
raise ActiveRecord::RecordNotFound
|
raise ActiveRecord::RecordNotFound
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_instance_presenter
|
||||||
|
@instance_presenter = InstancePresenter.new
|
||||||
|
end
|
||||||
|
|
||||||
def check_account_suspension
|
def check_account_suspension
|
||||||
gone if @account.suspended?
|
gone if @account.suspended?
|
||||||
end
|
end
|
||||||
|
|
|
@ -38,7 +38,7 @@ class TagsController < ApplicationController
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_body_classes
|
def set_body_classes
|
||||||
@body_classes = 'tag-body'
|
@body_classes = 'with-modals'
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_instance_presenter
|
def set_instance_presenter
|
||||||
|
|
|
@ -12,6 +12,52 @@ module StreamEntriesHelper
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def account_action_button(account)
|
||||||
|
if user_signed_in?
|
||||||
|
if account.id == current_user.account_id
|
||||||
|
link_to settings_profile_url, class: 'button logo-button' do
|
||||||
|
safe_join([render(file: Rails.root.join('app', 'javascript', 'images', 'logo.svg')), t('settings.edit_profile')])
|
||||||
|
end
|
||||||
|
elsif current_account.following?(account) || current_account.requested?(account)
|
||||||
|
link_to account_unfollow_path(account), class: 'button logo-button', data: { method: :post } do
|
||||||
|
safe_join([render(file: Rails.root.join('app', 'javascript', 'images', 'logo.svg')), t('accounts.unfollow')])
|
||||||
|
end
|
||||||
|
else
|
||||||
|
link_to account_follow_path(account), class: 'button logo-button', data: { method: :post } do
|
||||||
|
safe_join([render(file: Rails.root.join('app', 'javascript', 'images', 'logo.svg')), t('accounts.follow')])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
link_to account_remote_follow_path(account), class: 'button logo-button modal-button', target: '_new' do
|
||||||
|
safe_join([render(file: Rails.root.join('app', 'javascript', 'images', 'logo.svg')), t('accounts.follow')])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def account_badge(account)
|
||||||
|
if account.bot?
|
||||||
|
content_tag(:div, content_tag(:div, t('accounts.roles.bot'), class: 'account-role bot'), class: 'roles')
|
||||||
|
elsif Setting.show_staff_badge && account.user_staff?
|
||||||
|
content_tag(:div, class: 'roles') do
|
||||||
|
if account.user_admin?
|
||||||
|
content_tag(:div, t('accounts.roles.admin'), class: 'account-role admin')
|
||||||
|
elsif account.user_moderator?
|
||||||
|
content_tag(:div, t('accounts.roles.moderator'), class: 'account-role moderator')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def link_to_more(url)
|
||||||
|
link_to t('statuses.show_more'), url, class: 'load-more load-gap'
|
||||||
|
end
|
||||||
|
|
||||||
|
def nothing_here(extra_classes = '')
|
||||||
|
content_tag(:div, class: "nothing-here #{extra_classes}") do
|
||||||
|
t('accounts.nothing_here')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def account_description(account)
|
def account_description(account)
|
||||||
prepend_str = [
|
prepend_str = [
|
||||||
[
|
[
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// This file will be loaded on public pages, regardless of theme.
|
// This file will be loaded on public pages, regardless of theme.
|
||||||
|
|
||||||
const { delegate } = require('rails-ujs');
|
const { delegate } = require('rails-ujs');
|
||||||
|
const { length } = require('stringz');
|
||||||
|
|
||||||
delegate(document, '.webapp-btn', 'click', ({ target, button }) => {
|
delegate(document, '.webapp-btn', 'click', ({ target, button }) => {
|
||||||
if (button !== 0) {
|
if (button !== 0) {
|
||||||
|
|
|
@ -3,24 +3,29 @@
|
||||||
const { length } = require('stringz');
|
const { length } = require('stringz');
|
||||||
const { delegate } = require('rails-ujs');
|
const { delegate } = require('rails-ujs');
|
||||||
|
|
||||||
delegate(document, '.account_display_name', 'input', ({ target }) => {
|
delegate(document, '#account_display_name', 'input', ({ target }) => {
|
||||||
const nameCounter = document.querySelector('.name-counter');
|
const nameCounter = document.querySelector('.name-counter');
|
||||||
|
const name = document.querySelector('.card .display-name strong');
|
||||||
|
|
||||||
if (nameCounter) {
|
if (nameCounter) {
|
||||||
nameCounter.textContent = 30 - length(target.value);
|
nameCounter.textContent = 30 - length(target.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (name) {
|
||||||
|
name.innerHTML = emojify(target.value);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
delegate(document, '.account_note', 'input', ({ target }) => {
|
delegate(document, '#account_note', 'input', ({ target }) => {
|
||||||
const noteCounter = document.querySelector('.note-counter');
|
const noteCounter = document.querySelector('.note-counter');
|
||||||
|
|
||||||
if (noteCounter) {
|
if (noteCounter) {
|
||||||
noteCounter.textContent = 500 - length(target.value);
|
noteCounter.textContent = 160 - length(target.value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
delegate(document, '#account_avatar', 'change', ({ target }) => {
|
delegate(document, '#account_avatar', 'change', ({ target }) => {
|
||||||
const avatar = document.querySelector('.card.compact .avatar img');
|
const avatar = document.querySelector('.card .avatar img');
|
||||||
const [file] = target.files || [];
|
const [file] = target.files || [];
|
||||||
const url = file ? URL.createObjectURL(file) : avatar.dataset.originalSrc;
|
const url = file ? URL.createObjectURL(file) : avatar.dataset.originalSrc;
|
||||||
|
|
||||||
|
@ -28,9 +33,19 @@ delegate(document, '#account_avatar', 'change', ({ target }) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
delegate(document, '#account_header', 'change', ({ target }) => {
|
delegate(document, '#account_header', 'change', ({ target }) => {
|
||||||
const header = document.querySelector('.card.compact');
|
const header = document.querySelector('.card .card__img img');
|
||||||
const [file] = target.files || [];
|
const [file] = target.files || [];
|
||||||
const url = file ? URL.createObjectURL(file) : header.dataset.originalSrc;
|
const url = file ? URL.createObjectURL(file) : header.dataset.originalSrc;
|
||||||
|
|
||||||
header.style.backgroundImage = `url(${url})`;
|
header.src = url;
|
||||||
|
});
|
||||||
|
|
||||||
|
delegate(document, '#account_locked', 'change', ({ target }) => {
|
||||||
|
const lock = document.querySelector('.card .display-name i');
|
||||||
|
|
||||||
|
if (target.checked) {
|
||||||
|
lock.style.display = 'inline';
|
||||||
|
} else {
|
||||||
|
lock.style.display = 'none';
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -60,6 +60,32 @@ const getUnitDelay = units => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const timeAgoString = (intl, date, now, year) => {
|
||||||
|
const delta = now - date.getTime();
|
||||||
|
|
||||||
|
let relativeTime;
|
||||||
|
|
||||||
|
if (delta < 10 * SECOND) {
|
||||||
|
relativeTime = intl.formatMessage(messages.just_now);
|
||||||
|
} else if (delta < 7 * DAY) {
|
||||||
|
if (delta < MINUTE) {
|
||||||
|
relativeTime = intl.formatMessage(messages.seconds, { number: Math.floor(delta / SECOND) });
|
||||||
|
} else if (delta < HOUR) {
|
||||||
|
relativeTime = intl.formatMessage(messages.minutes, { number: Math.floor(delta / MINUTE) });
|
||||||
|
} else if (delta < DAY) {
|
||||||
|
relativeTime = intl.formatMessage(messages.hours, { number: Math.floor(delta / HOUR) });
|
||||||
|
} else {
|
||||||
|
relativeTime = intl.formatMessage(messages.days, { number: Math.floor(delta / DAY) });
|
||||||
|
}
|
||||||
|
} else if (date.getFullYear() === year) {
|
||||||
|
relativeTime = intl.formatDate(date, shortDateFormatOptions);
|
||||||
|
} else {
|
||||||
|
relativeTime = intl.formatDate(date, { ...shortDateFormatOptions, year: 'numeric' });
|
||||||
|
}
|
||||||
|
|
||||||
|
return relativeTime;
|
||||||
|
};
|
||||||
|
|
||||||
@injectIntl
|
@injectIntl
|
||||||
export default class RelativeTimestamp extends React.Component {
|
export default class RelativeTimestamp extends React.Component {
|
||||||
|
|
||||||
|
@ -121,28 +147,8 @@ export default class RelativeTimestamp extends React.Component {
|
||||||
render () {
|
render () {
|
||||||
const { timestamp, intl, year } = this.props;
|
const { timestamp, intl, year } = this.props;
|
||||||
|
|
||||||
const date = new Date(timestamp);
|
const date = new Date(timestamp);
|
||||||
const delta = this.state.now - date.getTime();
|
const relativeTime = timeAgoString(intl, date, this.state.now, year);
|
||||||
|
|
||||||
let relativeTime;
|
|
||||||
|
|
||||||
if (delta < 10 * SECOND) {
|
|
||||||
relativeTime = intl.formatMessage(messages.just_now);
|
|
||||||
} else if (delta < 7 * DAY) {
|
|
||||||
if (delta < MINUTE) {
|
|
||||||
relativeTime = intl.formatMessage(messages.seconds, { number: Math.floor(delta / SECOND) });
|
|
||||||
} else if (delta < HOUR) {
|
|
||||||
relativeTime = intl.formatMessage(messages.minutes, { number: Math.floor(delta / MINUTE) });
|
|
||||||
} else if (delta < DAY) {
|
|
||||||
relativeTime = intl.formatMessage(messages.hours, { number: Math.floor(delta / HOUR) });
|
|
||||||
} else {
|
|
||||||
relativeTime = intl.formatMessage(messages.days, { number: Math.floor(delta / DAY) });
|
|
||||||
}
|
|
||||||
} else if (date.getFullYear() === year) {
|
|
||||||
relativeTime = intl.formatDate(date, shortDateFormatOptions);
|
|
||||||
} else {
|
|
||||||
relativeTime = intl.formatDate(date, { ...shortDateFormatOptions, year: 'numeric' });
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<time dateTime={timestamp} title={intl.formatDate(date, dateFormatOptions)}>
|
<time dateTime={timestamp} title={intl.formatDate(date, dateFormatOptions)}>
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from 'lodash';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import StatusContainer from '../containers/status_container';
|
import StatusContainer from '../containers/status_container';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import LoadGap from './load_gap';
|
import LoadGap from './load_gap';
|
||||||
import ScrollableList from './scrollable_list';
|
import ScrollableList from './scrollable_list';
|
||||||
import { FormattedMessage } from 'react-intl';
|
|
||||||
|
|
||||||
export default class StatusList extends ImmutablePureComponent {
|
export default class StatusList extends ImmutablePureComponent {
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ export default class StatusList extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { statusIds, featuredStatusIds, onLoadMore, timelineId, ...other } = this.props;
|
const { statusIds, featuredStatusIds, shouldUpdateScroll, onLoadMore, timelineId, ...other } = this.props;
|
||||||
const { isLoading, isPartial } = other;
|
const { isLoading, isPartial } = other;
|
||||||
|
|
||||||
if (isPartial) {
|
if (isPartial) {
|
||||||
|
@ -122,7 +122,7 @@ export default class StatusList extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollableList {...other} onLoadMore={onLoadMore && this.handleLoadOlder} ref={this.setRef}>
|
<ScrollableList {...other} onLoadMore={onLoadMore && this.handleLoadOlder} shouldUpdateScroll={shouldUpdateScroll} ref={this.setRef}>
|
||||||
{scrollableContent}
|
{scrollableContent}
|
||||||
</ScrollableList>
|
</ScrollableList>
|
||||||
);
|
);
|
||||||
|
|
|
@ -29,19 +29,19 @@ export default class MediaContainer extends PureComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
handleOpenMedia = (media, index) => {
|
handleOpenMedia = (media, index) => {
|
||||||
document.body.classList.add('media-standalone__body');
|
document.body.classList.add('with-modals--active');
|
||||||
this.setState({ media, index });
|
this.setState({ media, index });
|
||||||
}
|
}
|
||||||
|
|
||||||
handleOpenVideo = (video, time) => {
|
handleOpenVideo = (video, time) => {
|
||||||
const media = ImmutableList([video]);
|
const media = ImmutableList([video]);
|
||||||
|
|
||||||
document.body.classList.add('media-standalone__body');
|
document.body.classList.add('with-modals--active');
|
||||||
this.setState({ media, time });
|
this.setState({ media, time });
|
||||||
}
|
}
|
||||||
|
|
||||||
handleCloseMedia = () => {
|
handleCloseMedia = () => {
|
||||||
document.body.classList.remove('media-standalone__body');
|
document.body.classList.remove('with-modals--active');
|
||||||
this.setState({ media: null, index: null, time: null });
|
this.setState({ media: null, index: null, time: null });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -142,17 +142,17 @@ export default class ActionBar extends React.PureComponent {
|
||||||
<div className='account__action-bar'>
|
<div className='account__action-bar'>
|
||||||
<div className='account__action-bar-links'>
|
<div className='account__action-bar-links'>
|
||||||
<Link className='account__action-bar__tab' to={`/accounts/${account.get('id')}`}>
|
<Link className='account__action-bar__tab' to={`/accounts/${account.get('id')}`}>
|
||||||
<span><FormattedMessage id='account.posts' defaultMessage='Toots' /></span>
|
<FormattedMessage id='account.posts' defaultMessage='Toots' />
|
||||||
<strong>{shortNumberFormat(account.get('statuses_count'))}</strong>
|
<strong>{shortNumberFormat(account.get('statuses_count'))}</strong>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<Link className='account__action-bar__tab' to={`/accounts/${account.get('id')}/following`}>
|
<Link className='account__action-bar__tab' to={`/accounts/${account.get('id')}/following`}>
|
||||||
<span><FormattedMessage id='account.follows' defaultMessage='Follows' /></span>
|
<FormattedMessage id='account.follows' defaultMessage='Follows' />
|
||||||
<strong>{shortNumberFormat(account.get('following_count'))}</strong>
|
<strong>{shortNumberFormat(account.get('following_count'))}</strong>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<Link className='account__action-bar__tab' to={`/accounts/${account.get('id')}/followers`}>
|
<Link className='account__action-bar__tab' to={`/accounts/${account.get('id')}/followers`}>
|
||||||
<span><FormattedMessage id='account.followers' defaultMessage='Followers' /></span>
|
<FormattedMessage id='account.followers' defaultMessage='Followers' />
|
||||||
<strong>{shortNumberFormat(account.get('followers_count'))}</strong>
|
<strong>{shortNumberFormat(account.get('followers_count'))}</strong>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -23,6 +23,7 @@ const mapStateToProps = (state, props) => ({
|
||||||
class LoadMoreMedia extends ImmutablePureComponent {
|
class LoadMoreMedia extends ImmutablePureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
shouldUpdateScroll: PropTypes.func,
|
||||||
maxId: PropTypes.string,
|
maxId: PropTypes.string,
|
||||||
onLoadMore: PropTypes.func.isRequired,
|
onLoadMore: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
@ -90,7 +91,7 @@ export default class AccountGallery extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { medias, isLoading, hasMore } = this.props;
|
const { medias, shouldUpdateScroll, isLoading, hasMore } = this.props;
|
||||||
|
|
||||||
let loadOlder = null;
|
let loadOlder = null;
|
||||||
|
|
||||||
|
@ -110,7 +111,7 @@ export default class AccountGallery extends ImmutablePureComponent {
|
||||||
<Column>
|
<Column>
|
||||||
<ColumnBackButton />
|
<ColumnBackButton />
|
||||||
|
|
||||||
<ScrollContainer scrollKey='account_gallery'>
|
<ScrollContainer scrollKey='account_gallery' shouldUpdateScroll={shouldUpdateScroll}>
|
||||||
<div className='scrollable' onScroll={this.handleScroll}>
|
<div className='scrollable' onScroll={this.handleScroll}>
|
||||||
<HeaderContainer accountId={this.props.params.accountId} />
|
<HeaderContainer accountId={this.props.params.accountId} />
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ export default class AccountTimeline extends ImmutablePureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
params: PropTypes.object.isRequired,
|
params: PropTypes.object.isRequired,
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
|
shouldUpdateScroll: PropTypes.func,
|
||||||
statusIds: ImmutablePropTypes.list,
|
statusIds: ImmutablePropTypes.list,
|
||||||
featuredStatusIds: ImmutablePropTypes.list,
|
featuredStatusIds: ImmutablePropTypes.list,
|
||||||
isLoading: PropTypes.bool,
|
isLoading: PropTypes.bool,
|
||||||
|
@ -61,7 +62,7 @@ export default class AccountTimeline extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { statusIds, featuredStatusIds, isLoading, hasMore } = this.props;
|
const { shouldUpdateScroll, statusIds, featuredStatusIds, isLoading, hasMore } = this.props;
|
||||||
|
|
||||||
if (!statusIds && isLoading) {
|
if (!statusIds && isLoading) {
|
||||||
return (
|
return (
|
||||||
|
@ -83,6 +84,7 @@ export default class AccountTimeline extends ImmutablePureComponent {
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
hasMore={hasMore}
|
hasMore={hasMore}
|
||||||
onLoadMore={this.handleLoadMore}
|
onLoadMore={this.handleLoadMore}
|
||||||
|
shouldUpdateScroll={shouldUpdateScroll}
|
||||||
/>
|
/>
|
||||||
</Column>
|
</Column>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import { defineMessages, injectIntl } from 'react-intl';
|
||||||
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import LoadingIndicator from '../../components/loading_indicator';
|
import LoadingIndicator from '../../components/loading_indicator';
|
||||||
|
@ -8,8 +10,6 @@ import Column from '../ui/components/column';
|
||||||
import ColumnBackButtonSlim from '../../components/column_back_button_slim';
|
import ColumnBackButtonSlim from '../../components/column_back_button_slim';
|
||||||
import AccountContainer from '../../containers/account_container';
|
import AccountContainer from '../../containers/account_container';
|
||||||
import { fetchBlocks, expandBlocks } from '../../actions/blocks';
|
import { fetchBlocks, expandBlocks } from '../../actions/blocks';
|
||||||
import { defineMessages, injectIntl } from 'react-intl';
|
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
heading: { id: 'column.blocks', defaultMessage: 'Blocked users' },
|
heading: { id: 'column.blocks', defaultMessage: 'Blocked users' },
|
||||||
|
@ -26,6 +26,7 @@ export default class Blocks extends ImmutablePureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
params: PropTypes.object.isRequired,
|
params: PropTypes.object.isRequired,
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
|
shouldUpdateScroll: PropTypes.func,
|
||||||
accountIds: ImmutablePropTypes.list,
|
accountIds: ImmutablePropTypes.list,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
};
|
};
|
||||||
|
@ -43,7 +44,7 @@ export default class Blocks extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, accountIds } = this.props;
|
const { intl, accountIds, shouldUpdateScroll } = this.props;
|
||||||
|
|
||||||
if (!accountIds) {
|
if (!accountIds) {
|
||||||
return (
|
return (
|
||||||
|
@ -56,7 +57,7 @@ export default class Blocks extends ImmutablePureComponent {
|
||||||
return (
|
return (
|
||||||
<Column icon='ban' heading={intl.formatMessage(messages.heading)}>
|
<Column icon='ban' heading={intl.formatMessage(messages.heading)}>
|
||||||
<ColumnBackButtonSlim />
|
<ColumnBackButtonSlim />
|
||||||
<ScrollContainer scrollKey='blocks'>
|
<ScrollContainer scrollKey='blocks' shouldUpdateScroll={shouldUpdateScroll}>
|
||||||
<div className='scrollable' onScroll={this.handleScroll}>
|
<div className='scrollable' onScroll={this.handleScroll}>
|
||||||
{accountIds.map(id =>
|
{accountIds.map(id =>
|
||||||
<AccountContainer key={id} id={id} />
|
<AccountContainer key={id} id={id} />
|
||||||
|
|
|
@ -39,6 +39,7 @@ export default class CommunityTimeline extends React.PureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
|
shouldUpdateScroll: PropTypes.func,
|
||||||
columnId: PropTypes.string,
|
columnId: PropTypes.string,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
hasUnread: PropTypes.bool,
|
hasUnread: PropTypes.bool,
|
||||||
|
@ -100,7 +101,7 @@ export default class CommunityTimeline extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, hasUnread, columnId, multiColumn, onlyMedia } = this.props;
|
const { intl, shouldUpdateScroll, hasUnread, columnId, multiColumn, onlyMedia } = this.props;
|
||||||
const pinned = !!columnId;
|
const pinned = !!columnId;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -124,6 +125,7 @@ export default class CommunityTimeline extends React.PureComponent {
|
||||||
timelineId={`community${onlyMedia ? ':media' : ''}`}
|
timelineId={`community${onlyMedia ? ':media' : ''}`}
|
||||||
onLoadMore={this.handleLoadMore}
|
onLoadMore={this.handleLoadMore}
|
||||||
emptyMessage={<FormattedMessage id='empty_column.community' defaultMessage='The local timeline is empty. Write something publicly to get the ball rolling!' />}
|
emptyMessage={<FormattedMessage id='empty_column.community' defaultMessage='The local timeline is empty. Write something publicly to get the ball rolling!' />}
|
||||||
|
shouldUpdateScroll={shouldUpdateScroll}
|
||||||
/>
|
/>
|
||||||
</Column>
|
</Column>
|
||||||
);
|
);
|
||||||
|
|
|
@ -23,6 +23,7 @@ export default class DirectTimeline extends React.PureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
|
shouldUpdateScroll: PropTypes.func,
|
||||||
columnId: PropTypes.string,
|
columnId: PropTypes.string,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
hasUnread: PropTypes.bool,
|
hasUnread: PropTypes.bool,
|
||||||
|
@ -71,7 +72,7 @@ export default class DirectTimeline extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, hasUnread, columnId, multiColumn } = this.props;
|
const { intl, shouldUpdateScroll, hasUnread, columnId, multiColumn } = this.props;
|
||||||
const pinned = !!columnId;
|
const pinned = !!columnId;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -93,6 +94,7 @@ export default class DirectTimeline extends React.PureComponent {
|
||||||
timelineId='direct'
|
timelineId='direct'
|
||||||
onLoadMore={this.handleLoadMore}
|
onLoadMore={this.handleLoadMore}
|
||||||
emptyMessage={<FormattedMessage id='empty_column.direct' defaultMessage="You don't have any direct messages yet. When you send or receive one, it will show up here." />}
|
emptyMessage={<FormattedMessage id='empty_column.direct' defaultMessage="You don't have any direct messages yet. When you send or receive one, it will show up here." />}
|
||||||
|
shouldUpdateScroll={shouldUpdateScroll}
|
||||||
/>
|
/>
|
||||||
</Column>
|
</Column>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import { defineMessages, injectIntl } from 'react-intl';
|
||||||
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
|
import { debounce } from 'lodash';
|
||||||
import LoadingIndicator from '../../components/loading_indicator';
|
import LoadingIndicator from '../../components/loading_indicator';
|
||||||
import Column from '../ui/components/column';
|
import Column from '../ui/components/column';
|
||||||
import ColumnBackButtonSlim from '../../components/column_back_button_slim';
|
import ColumnBackButtonSlim from '../../components/column_back_button_slim';
|
||||||
import DomainContainer from '../../containers/domain_container';
|
import DomainContainer from '../../containers/domain_container';
|
||||||
import { fetchDomainBlocks, expandDomainBlocks } from '../../actions/domain_blocks';
|
import { fetchDomainBlocks, expandDomainBlocks } from '../../actions/domain_blocks';
|
||||||
import { defineMessages, injectIntl } from 'react-intl';
|
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
|
||||||
import { debounce } from 'lodash';
|
|
||||||
import ScrollableList from '../../components/scrollable_list';
|
import ScrollableList from '../../components/scrollable_list';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
|
@ -28,6 +28,7 @@ export default class Blocks extends ImmutablePureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
params: PropTypes.object.isRequired,
|
params: PropTypes.object.isRequired,
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
|
shouldUpdateScroll: PropTypes.func,
|
||||||
domains: ImmutablePropTypes.orderedSet,
|
domains: ImmutablePropTypes.orderedSet,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
};
|
};
|
||||||
|
@ -41,7 +42,7 @@ export default class Blocks extends ImmutablePureComponent {
|
||||||
}, 300, { leading: true });
|
}, 300, { leading: true });
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, domains } = this.props;
|
const { intl, domains, shouldUpdateScroll } = this.props;
|
||||||
|
|
||||||
if (!domains) {
|
if (!domains) {
|
||||||
return (
|
return (
|
||||||
|
@ -54,7 +55,7 @@ export default class Blocks extends ImmutablePureComponent {
|
||||||
return (
|
return (
|
||||||
<Column icon='minus-circle' heading={intl.formatMessage(messages.heading)}>
|
<Column icon='minus-circle' heading={intl.formatMessage(messages.heading)}>
|
||||||
<ColumnBackButtonSlim />
|
<ColumnBackButtonSlim />
|
||||||
<ScrollableList scrollKey='domain_blocks' onLoadMore={this.handleLoadMore}>
|
<ScrollableList scrollKey='domain_blocks' onLoadMore={this.handleLoadMore} shouldUpdateScroll={shouldUpdateScroll}>
|
||||||
{domains.map(domain =>
|
{domains.map(domain =>
|
||||||
<DomainContainer key={domain} domain={domain} />
|
<DomainContainer key={domain} domain={domain} />
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -27,6 +27,7 @@ export default class Favourites extends ImmutablePureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
|
shouldUpdateScroll: PropTypes.func,
|
||||||
statusIds: ImmutablePropTypes.list.isRequired,
|
statusIds: ImmutablePropTypes.list.isRequired,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
columnId: PropTypes.string,
|
columnId: PropTypes.string,
|
||||||
|
@ -67,7 +68,7 @@ export default class Favourites extends ImmutablePureComponent {
|
||||||
}, 300, { leading: true })
|
}, 300, { leading: true })
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, statusIds, columnId, multiColumn, hasMore, isLoading } = this.props;
|
const { intl, shouldUpdateScroll, statusIds, columnId, multiColumn, hasMore, isLoading } = this.props;
|
||||||
const pinned = !!columnId;
|
const pinned = !!columnId;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -90,6 +91,7 @@ export default class Favourites extends ImmutablePureComponent {
|
||||||
hasMore={hasMore}
|
hasMore={hasMore}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
onLoadMore={this.handleLoadMore}
|
onLoadMore={this.handleLoadMore}
|
||||||
|
shouldUpdateScroll={shouldUpdateScroll}
|
||||||
/>
|
/>
|
||||||
</Column>
|
</Column>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import LoadingIndicator from '../../components/loading_indicator';
|
import LoadingIndicator from '../../components/loading_indicator';
|
||||||
|
@ -8,7 +9,6 @@ import { ScrollContainer } from 'react-router-scroll-4';
|
||||||
import AccountContainer from '../../containers/account_container';
|
import AccountContainer from '../../containers/account_container';
|
||||||
import Column from '../ui/components/column';
|
import Column from '../ui/components/column';
|
||||||
import ColumnBackButton from '../../components/column_back_button';
|
import ColumnBackButton from '../../components/column_back_button';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
|
||||||
|
|
||||||
const mapStateToProps = (state, props) => ({
|
const mapStateToProps = (state, props) => ({
|
||||||
accountIds: state.getIn(['user_lists', 'favourited_by', props.params.statusId]),
|
accountIds: state.getIn(['user_lists', 'favourited_by', props.params.statusId]),
|
||||||
|
@ -20,6 +20,7 @@ export default class Favourites extends ImmutablePureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
params: PropTypes.object.isRequired,
|
params: PropTypes.object.isRequired,
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
|
shouldUpdateScroll: PropTypes.func,
|
||||||
accountIds: ImmutablePropTypes.list,
|
accountIds: ImmutablePropTypes.list,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -34,7 +35,7 @@ export default class Favourites extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { accountIds } = this.props;
|
const { shouldUpdateScroll, accountIds } = this.props;
|
||||||
|
|
||||||
if (!accountIds) {
|
if (!accountIds) {
|
||||||
return (
|
return (
|
||||||
|
@ -48,7 +49,7 @@ export default class Favourites extends ImmutablePureComponent {
|
||||||
<Column>
|
<Column>
|
||||||
<ColumnBackButton />
|
<ColumnBackButton />
|
||||||
|
|
||||||
<ScrollContainer scrollKey='favourites'>
|
<ScrollContainer scrollKey='favourites' shouldUpdateScroll={shouldUpdateScroll}>
|
||||||
<div className='scrollable'>
|
<div className='scrollable'>
|
||||||
{accountIds.map(id => <AccountContainer key={id} id={id} withNote={false} />)}
|
{accountIds.map(id => <AccountContainer key={id} id={id} withNote={false} />)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import { defineMessages, injectIntl } from 'react-intl';
|
||||||
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import LoadingIndicator from '../../components/loading_indicator';
|
import LoadingIndicator from '../../components/loading_indicator';
|
||||||
|
@ -8,8 +10,6 @@ import Column from '../ui/components/column';
|
||||||
import ColumnBackButtonSlim from '../../components/column_back_button_slim';
|
import ColumnBackButtonSlim from '../../components/column_back_button_slim';
|
||||||
import AccountAuthorizeContainer from './containers/account_authorize_container';
|
import AccountAuthorizeContainer from './containers/account_authorize_container';
|
||||||
import { fetchFollowRequests, expandFollowRequests } from '../../actions/accounts';
|
import { fetchFollowRequests, expandFollowRequests } from '../../actions/accounts';
|
||||||
import { defineMessages, injectIntl } from 'react-intl';
|
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
heading: { id: 'column.follow_requests', defaultMessage: 'Follow requests' },
|
heading: { id: 'column.follow_requests', defaultMessage: 'Follow requests' },
|
||||||
|
@ -26,6 +26,7 @@ export default class FollowRequests extends ImmutablePureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
params: PropTypes.object.isRequired,
|
params: PropTypes.object.isRequired,
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
|
shouldUpdateScroll: PropTypes.func,
|
||||||
accountIds: ImmutablePropTypes.list,
|
accountIds: ImmutablePropTypes.list,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
};
|
};
|
||||||
|
@ -43,7 +44,7 @@ export default class FollowRequests extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, accountIds } = this.props;
|
const { intl, shouldUpdateScroll, accountIds } = this.props;
|
||||||
|
|
||||||
if (!accountIds) {
|
if (!accountIds) {
|
||||||
return (
|
return (
|
||||||
|
@ -57,7 +58,7 @@ export default class FollowRequests extends ImmutablePureComponent {
|
||||||
<Column icon='users' heading={intl.formatMessage(messages.heading)}>
|
<Column icon='users' heading={intl.formatMessage(messages.heading)}>
|
||||||
<ColumnBackButtonSlim />
|
<ColumnBackButtonSlim />
|
||||||
|
|
||||||
<ScrollContainer scrollKey='follow_requests'>
|
<ScrollContainer scrollKey='follow_requests' shouldUpdateScroll={shouldUpdateScroll}>
|
||||||
<div className='scrollable' onScroll={this.handleScroll}>
|
<div className='scrollable' onScroll={this.handleScroll}>
|
||||||
{accountIds.map(id =>
|
{accountIds.map(id =>
|
||||||
<AccountAuthorizeContainer key={id} id={id} />
|
<AccountAuthorizeContainer key={id} id={id} />
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import LoadingIndicator from '../../components/loading_indicator';
|
import LoadingIndicator from '../../components/loading_indicator';
|
||||||
|
@ -14,7 +15,6 @@ import Column from '../ui/components/column';
|
||||||
import HeaderContainer from '../account_timeline/containers/header_container';
|
import HeaderContainer from '../account_timeline/containers/header_container';
|
||||||
import LoadMore from '../../components/load_more';
|
import LoadMore from '../../components/load_more';
|
||||||
import ColumnBackButton from '../../components/column_back_button';
|
import ColumnBackButton from '../../components/column_back_button';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
|
||||||
|
|
||||||
const mapStateToProps = (state, props) => ({
|
const mapStateToProps = (state, props) => ({
|
||||||
accountIds: state.getIn(['user_lists', 'followers', props.params.accountId, 'items']),
|
accountIds: state.getIn(['user_lists', 'followers', props.params.accountId, 'items']),
|
||||||
|
@ -27,6 +27,7 @@ export default class Followers extends ImmutablePureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
params: PropTypes.object.isRequired,
|
params: PropTypes.object.isRequired,
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
|
shouldUpdateScroll: PropTypes.func,
|
||||||
accountIds: ImmutablePropTypes.list,
|
accountIds: ImmutablePropTypes.list,
|
||||||
hasMore: PropTypes.bool,
|
hasMore: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
@ -57,7 +58,7 @@ export default class Followers extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { accountIds, hasMore } = this.props;
|
const { shouldUpdateScroll, accountIds, hasMore } = this.props;
|
||||||
|
|
||||||
let loadMore = null;
|
let loadMore = null;
|
||||||
|
|
||||||
|
@ -77,7 +78,7 @@ export default class Followers extends ImmutablePureComponent {
|
||||||
<Column>
|
<Column>
|
||||||
<ColumnBackButton />
|
<ColumnBackButton />
|
||||||
|
|
||||||
<ScrollContainer scrollKey='followers'>
|
<ScrollContainer scrollKey='followers' shouldUpdateScroll={shouldUpdateScroll}>
|
||||||
<div className='scrollable' onScroll={this.handleScroll}>
|
<div className='scrollable' onScroll={this.handleScroll}>
|
||||||
<div className='followers'>
|
<div className='followers'>
|
||||||
<HeaderContainer accountId={this.props.params.accountId} hideTabs />
|
<HeaderContainer accountId={this.props.params.accountId} hideTabs />
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import LoadingIndicator from '../../components/loading_indicator';
|
import LoadingIndicator from '../../components/loading_indicator';
|
||||||
|
@ -14,7 +15,6 @@ import Column from '../ui/components/column';
|
||||||
import HeaderContainer from '../account_timeline/containers/header_container';
|
import HeaderContainer from '../account_timeline/containers/header_container';
|
||||||
import LoadMore from '../../components/load_more';
|
import LoadMore from '../../components/load_more';
|
||||||
import ColumnBackButton from '../../components/column_back_button';
|
import ColumnBackButton from '../../components/column_back_button';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
|
||||||
|
|
||||||
const mapStateToProps = (state, props) => ({
|
const mapStateToProps = (state, props) => ({
|
||||||
accountIds: state.getIn(['user_lists', 'following', props.params.accountId, 'items']),
|
accountIds: state.getIn(['user_lists', 'following', props.params.accountId, 'items']),
|
||||||
|
@ -27,6 +27,7 @@ export default class Following extends ImmutablePureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
params: PropTypes.object.isRequired,
|
params: PropTypes.object.isRequired,
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
|
shouldUpdateScroll: PropTypes.func,
|
||||||
accountIds: ImmutablePropTypes.list,
|
accountIds: ImmutablePropTypes.list,
|
||||||
hasMore: PropTypes.bool,
|
hasMore: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
@ -57,7 +58,7 @@ export default class Following extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { accountIds, hasMore } = this.props;
|
const { shouldUpdateScroll, accountIds, hasMore } = this.props;
|
||||||
|
|
||||||
let loadMore = null;
|
let loadMore = null;
|
||||||
|
|
||||||
|
@ -77,7 +78,7 @@ export default class Following extends ImmutablePureComponent {
|
||||||
<Column>
|
<Column>
|
||||||
<ColumnBackButton />
|
<ColumnBackButton />
|
||||||
|
|
||||||
<ScrollContainer scrollKey='following'>
|
<ScrollContainer scrollKey='following' shouldUpdateScroll={shouldUpdateScroll}>
|
||||||
<div className='scrollable' onScroll={this.handleScroll}>
|
<div className='scrollable' onScroll={this.handleScroll}>
|
||||||
<div className='following'>
|
<div className='following'>
|
||||||
<HeaderContainer accountId={this.props.params.accountId} hideTabs />
|
<HeaderContainer accountId={this.props.params.accountId} hideTabs />
|
||||||
|
|
|
@ -20,6 +20,7 @@ export default class HashtagTimeline extends React.PureComponent {
|
||||||
params: PropTypes.object.isRequired,
|
params: PropTypes.object.isRequired,
|
||||||
columnId: PropTypes.string,
|
columnId: PropTypes.string,
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
|
shouldUpdateScroll: PropTypes.func,
|
||||||
hasUnread: PropTypes.bool,
|
hasUnread: PropTypes.bool,
|
||||||
multiColumn: PropTypes.bool,
|
multiColumn: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
@ -83,7 +84,7 @@ export default class HashtagTimeline extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { hasUnread, columnId, multiColumn } = this.props;
|
const { shouldUpdateScroll, hasUnread, columnId, multiColumn } = this.props;
|
||||||
const { id } = this.props.params;
|
const { id } = this.props.params;
|
||||||
const pinned = !!columnId;
|
const pinned = !!columnId;
|
||||||
|
|
||||||
|
@ -107,6 +108,7 @@ export default class HashtagTimeline extends React.PureComponent {
|
||||||
timelineId={`hashtag:${id}`}
|
timelineId={`hashtag:${id}`}
|
||||||
onLoadMore={this.handleLoadMore}
|
onLoadMore={this.handleLoadMore}
|
||||||
emptyMessage={<FormattedMessage id='empty_column.hashtag' defaultMessage='There is nothing in this hashtag yet.' />}
|
emptyMessage={<FormattedMessage id='empty_column.hashtag' defaultMessage='There is nothing in this hashtag yet.' />}
|
||||||
|
shouldUpdateScroll={shouldUpdateScroll}
|
||||||
/>
|
/>
|
||||||
</Column>
|
</Column>
|
||||||
);
|
);
|
||||||
|
|
|
@ -25,6 +25,7 @@ export default class HomeTimeline extends React.PureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
|
shouldUpdateScroll: PropTypes.func,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
hasUnread: PropTypes.bool,
|
hasUnread: PropTypes.bool,
|
||||||
isPartial: PropTypes.bool,
|
isPartial: PropTypes.bool,
|
||||||
|
@ -93,7 +94,7 @@ export default class HomeTimeline extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, hasUnread, columnId, multiColumn } = this.props;
|
const { intl, shouldUpdateScroll, hasUnread, columnId, multiColumn } = this.props;
|
||||||
const pinned = !!columnId;
|
const pinned = !!columnId;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -117,6 +118,7 @@ export default class HomeTimeline extends React.PureComponent {
|
||||||
onLoadMore={this.handleLoadMore}
|
onLoadMore={this.handleLoadMore}
|
||||||
timelineId='home'
|
timelineId='home'
|
||||||
emptyMessage={<FormattedMessage id='empty_column.home' defaultMessage='Your home timeline is empty! Visit {public} or use search to get started and meet other users.' values={{ public: <Link to='/timelines/public'><FormattedMessage id='empty_column.home.public_timeline' defaultMessage='the public timeline' /></Link> }} />}
|
emptyMessage={<FormattedMessage id='empty_column.home' defaultMessage='Your home timeline is empty! Visit {public} or use search to get started and meet other users.' values={{ public: <Link to='/timelines/public'><FormattedMessage id='empty_column.home.public_timeline' defaultMessage='the public timeline' /></Link> }} />}
|
||||||
|
shouldUpdateScroll={shouldUpdateScroll}
|
||||||
/>
|
/>
|
||||||
</Column>
|
</Column>
|
||||||
);
|
);
|
||||||
|
|
|
@ -35,6 +35,7 @@ export default class ListTimeline extends React.PureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
params: PropTypes.object.isRequired,
|
params: PropTypes.object.isRequired,
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
|
shouldUpdateScroll: PropTypes.func,
|
||||||
columnId: PropTypes.string,
|
columnId: PropTypes.string,
|
||||||
hasUnread: PropTypes.bool,
|
hasUnread: PropTypes.bool,
|
||||||
multiColumn: PropTypes.bool,
|
multiColumn: PropTypes.bool,
|
||||||
|
@ -112,7 +113,7 @@ export default class ListTimeline extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { hasUnread, columnId, multiColumn, list } = this.props;
|
const { shouldUpdateScroll, hasUnread, columnId, multiColumn, list } = this.props;
|
||||||
const { id } = this.props.params;
|
const { id } = this.props.params;
|
||||||
const pinned = !!columnId;
|
const pinned = !!columnId;
|
||||||
const title = list ? list.get('title') : id;
|
const title = list ? list.get('title') : id;
|
||||||
|
@ -166,6 +167,7 @@ export default class ListTimeline extends React.PureComponent {
|
||||||
timelineId={`list:${id}`}
|
timelineId={`list:${id}`}
|
||||||
onLoadMore={this.handleLoadMore}
|
onLoadMore={this.handleLoadMore}
|
||||||
emptyMessage={<FormattedMessage id='empty_column.list' defaultMessage='There is nothing in this list yet. When members of this list post new statuses, they will appear here.' />}
|
emptyMessage={<FormattedMessage id='empty_column.list' defaultMessage='There is nothing in this list yet. When members of this list post new statuses, they will appear here.' />}
|
||||||
|
shouldUpdateScroll={shouldUpdateScroll}
|
||||||
/>
|
/>
|
||||||
</Column>
|
</Column>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import { defineMessages, injectIntl } from 'react-intl';
|
||||||
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import LoadingIndicator from '../../components/loading_indicator';
|
import LoadingIndicator from '../../components/loading_indicator';
|
||||||
|
@ -8,8 +10,6 @@ import Column from '../ui/components/column';
|
||||||
import ColumnBackButtonSlim from '../../components/column_back_button_slim';
|
import ColumnBackButtonSlim from '../../components/column_back_button_slim';
|
||||||
import AccountContainer from '../../containers/account_container';
|
import AccountContainer from '../../containers/account_container';
|
||||||
import { fetchMutes, expandMutes } from '../../actions/mutes';
|
import { fetchMutes, expandMutes } from '../../actions/mutes';
|
||||||
import { defineMessages, injectIntl } from 'react-intl';
|
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
heading: { id: 'column.mutes', defaultMessage: 'Muted users' },
|
heading: { id: 'column.mutes', defaultMessage: 'Muted users' },
|
||||||
|
@ -26,6 +26,7 @@ export default class Mutes extends ImmutablePureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
params: PropTypes.object.isRequired,
|
params: PropTypes.object.isRequired,
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
|
shouldUpdateScroll: PropTypes.func,
|
||||||
accountIds: ImmutablePropTypes.list,
|
accountIds: ImmutablePropTypes.list,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
};
|
};
|
||||||
|
@ -43,7 +44,7 @@ export default class Mutes extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, accountIds } = this.props;
|
const { intl, shouldUpdateScroll, accountIds } = this.props;
|
||||||
|
|
||||||
if (!accountIds) {
|
if (!accountIds) {
|
||||||
return (
|
return (
|
||||||
|
@ -56,7 +57,7 @@ export default class Mutes extends ImmutablePureComponent {
|
||||||
return (
|
return (
|
||||||
<Column icon='volume-off' heading={intl.formatMessage(messages.heading)}>
|
<Column icon='volume-off' heading={intl.formatMessage(messages.heading)}>
|
||||||
<ColumnBackButtonSlim />
|
<ColumnBackButtonSlim />
|
||||||
<ScrollContainer scrollKey='mutes'>
|
<ScrollContainer scrollKey='mutes' shouldUpdateScroll={shouldUpdateScroll}>
|
||||||
<div className='scrollable mutes' onScroll={this.handleScroll}>
|
<div className='scrollable mutes' onScroll={this.handleScroll}>
|
||||||
{accountIds.map(id =>
|
{accountIds.map(id =>
|
||||||
<AccountContainer key={id} id={id} />
|
<AccountContainer key={id} id={id} />
|
||||||
|
|
|
@ -24,6 +24,7 @@ export default class PinnedStatuses extends ImmutablePureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
|
shouldUpdateScroll: PropTypes.func,
|
||||||
statusIds: ImmutablePropTypes.list.isRequired,
|
statusIds: ImmutablePropTypes.list.isRequired,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
hasMore: PropTypes.bool.isRequired,
|
hasMore: PropTypes.bool.isRequired,
|
||||||
|
@ -42,7 +43,7 @@ export default class PinnedStatuses extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, statusIds, hasMore } = this.props;
|
const { intl, shouldUpdateScroll, statusIds, hasMore } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Column icon='thumb-tack' heading={intl.formatMessage(messages.heading)} ref={this.setRef}>
|
<Column icon='thumb-tack' heading={intl.formatMessage(messages.heading)} ref={this.setRef}>
|
||||||
|
@ -51,6 +52,7 @@ export default class PinnedStatuses extends ImmutablePureComponent {
|
||||||
statusIds={statusIds}
|
statusIds={statusIds}
|
||||||
scrollKey='pinned_statuses'
|
scrollKey='pinned_statuses'
|
||||||
hasMore={hasMore}
|
hasMore={hasMore}
|
||||||
|
shouldUpdateScroll={shouldUpdateScroll}
|
||||||
/>
|
/>
|
||||||
</Column>
|
</Column>
|
||||||
);
|
);
|
||||||
|
|
|
@ -39,6 +39,7 @@ export default class PublicTimeline extends React.PureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
|
shouldUpdateScroll: PropTypes.func,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
columnId: PropTypes.string,
|
columnId: PropTypes.string,
|
||||||
multiColumn: PropTypes.bool,
|
multiColumn: PropTypes.bool,
|
||||||
|
@ -107,7 +108,7 @@ export default class PublicTimeline extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, columnId, hasUnread, multiColumn, onlyMedia } = this.props;
|
const { intl, shouldUpdateScroll, columnId, hasUnread, multiColumn, onlyMedia } = this.props;
|
||||||
const pinned = !!columnId;
|
const pinned = !!columnId;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -131,6 +132,7 @@ export default class PublicTimeline extends React.PureComponent {
|
||||||
trackScroll={!pinned}
|
trackScroll={!pinned}
|
||||||
scrollKey={`public_timeline-${columnId}`}
|
scrollKey={`public_timeline-${columnId}`}
|
||||||
emptyMessage={<FormattedMessage id='empty_column.public' defaultMessage='There is nothing here! Write something publicly, or manually follow users from other instances to fill it up' />}
|
emptyMessage={<FormattedMessage id='empty_column.public' defaultMessage='There is nothing here! Write something publicly, or manually follow users from other instances to fill it up' />}
|
||||||
|
shouldUpdateScroll={shouldUpdateScroll}
|
||||||
/>
|
/>
|
||||||
</Column>
|
</Column>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import LoadingIndicator from '../../components/loading_indicator';
|
import LoadingIndicator from '../../components/loading_indicator';
|
||||||
|
@ -8,7 +9,6 @@ import { ScrollContainer } from 'react-router-scroll-4';
|
||||||
import AccountContainer from '../../containers/account_container';
|
import AccountContainer from '../../containers/account_container';
|
||||||
import Column from '../ui/components/column';
|
import Column from '../ui/components/column';
|
||||||
import ColumnBackButton from '../../components/column_back_button';
|
import ColumnBackButton from '../../components/column_back_button';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
|
||||||
|
|
||||||
const mapStateToProps = (state, props) => ({
|
const mapStateToProps = (state, props) => ({
|
||||||
accountIds: state.getIn(['user_lists', 'reblogged_by', props.params.statusId]),
|
accountIds: state.getIn(['user_lists', 'reblogged_by', props.params.statusId]),
|
||||||
|
@ -20,6 +20,7 @@ export default class Reblogs extends ImmutablePureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
params: PropTypes.object.isRequired,
|
params: PropTypes.object.isRequired,
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
|
shouldUpdateScroll: PropTypes.func,
|
||||||
accountIds: ImmutablePropTypes.list,
|
accountIds: ImmutablePropTypes.list,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -34,7 +35,7 @@ export default class Reblogs extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { accountIds } = this.props;
|
const { shouldUpdateScroll, accountIds } = this.props;
|
||||||
|
|
||||||
if (!accountIds) {
|
if (!accountIds) {
|
||||||
return (
|
return (
|
||||||
|
@ -48,7 +49,7 @@ export default class Reblogs extends ImmutablePureComponent {
|
||||||
<Column>
|
<Column>
|
||||||
<ColumnBackButton />
|
<ColumnBackButton />
|
||||||
|
|
||||||
<ScrollContainer scrollKey='reblogs'>
|
<ScrollContainer scrollKey='reblogs' shouldUpdateScroll={shouldUpdateScroll}>
|
||||||
<div className='scrollable reblogs'>
|
<div className='scrollable reblogs'>
|
||||||
{accountIds.map(id => <AccountContainer key={id} id={id} withNote={false} />)}
|
{accountIds.map(id => <AccountContainer key={id} id={id} withNote={false} />)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -42,7 +42,7 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import { HotKeys } from 'react-hotkeys';
|
import { HotKeys } from 'react-hotkeys';
|
||||||
import { boostModal, deleteModal } from '../../initial_state';
|
import { boostModal, deleteModal } from '../../initial_state';
|
||||||
import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from '../../features/ui/util/fullscreen';
|
import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from '../ui/util/fullscreen';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
|
deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
|
||||||
|
@ -370,7 +370,7 @@ export default class Status extends ImmutablePureComponent {
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
let ancestors, descendants;
|
let ancestors, descendants;
|
||||||
const { status, ancestorsIds, descendantsIds, intl } = this.props;
|
const { shouldUpdateScroll, status, ancestorsIds, descendantsIds, intl } = this.props;
|
||||||
const { fullscreen } = this.state;
|
const { fullscreen } = this.state;
|
||||||
|
|
||||||
if (status === null) {
|
if (status === null) {
|
||||||
|
@ -410,7 +410,7 @@ export default class Status extends ImmutablePureComponent {
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ScrollContainer scrollKey='thread'>
|
<ScrollContainer scrollKey='thread' shouldUpdateScroll={shouldUpdateScroll}>
|
||||||
<div className={classNames('scrollable', 'detailed-status__wrapper', { fullscreen })} ref={this.setRef}>
|
<div className={classNames('scrollable', 'detailed-status__wrapper', { fullscreen })} ref={this.setRef}>
|
||||||
{ancestors}
|
{ancestors}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ const messages = defineMessages({
|
||||||
next: { id: 'lightbox.next', defaultMessage: 'Next' },
|
next: { id: 'lightbox.next', defaultMessage: 'Next' },
|
||||||
});
|
});
|
||||||
|
|
||||||
const previewState = 'previewMediaModal';
|
export const previewState = 'previewMediaModal';
|
||||||
|
|
||||||
@injectIntl
|
@injectIntl
|
||||||
export default class MediaModal extends ImmutablePureComponent {
|
export default class MediaModal extends ImmutablePureComponent {
|
||||||
|
|
|
@ -41,14 +41,15 @@ export default class ModalRoot extends React.PureComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
getSnapshotBeforeUpdate () {
|
getSnapshotBeforeUpdate () {
|
||||||
const visible = !!this.props.type;
|
return { visible: !!this.props.type };
|
||||||
return {
|
|
||||||
overflowY: visible ? 'hidden' : null,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate (prevProps, prevState, { overflowY }) {
|
componentDidUpdate (prevProps, prevState, { visible }) {
|
||||||
document.body.style.overflowY = overflowY;
|
if (visible) {
|
||||||
|
document.body.classList.add('with-modals--active');
|
||||||
|
} else {
|
||||||
|
document.body.classList.remove('with-modals--active');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderLoading = modalId => () => {
|
renderLoading = modalId => () => {
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import NotificationsContainer from './containers/notifications_container';
|
import { HotKeys } from 'react-hotkeys';
|
||||||
|
import { defineMessages, injectIntl } from 'react-intl';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { Redirect, withRouter } from 'react-router-dom';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import NotificationsContainer from './containers/notifications_container';
|
||||||
import LoadingBarContainer from './containers/loading_bar_container';
|
import LoadingBarContainer from './containers/loading_bar_container';
|
||||||
import TabsBar from './components/tabs_bar';
|
import TabsBar from './components/tabs_bar';
|
||||||
import ModalContainer from './containers/modal_container';
|
import ModalContainer from './containers/modal_container';
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { Redirect, withRouter } from 'react-router-dom';
|
|
||||||
import { isMobile } from '../../is_mobile';
|
import { isMobile } from '../../is_mobile';
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from 'lodash';
|
||||||
import { uploadCompose, resetCompose } from '../../actions/compose';
|
import { uploadCompose, resetCompose } from '../../actions/compose';
|
||||||
|
@ -44,9 +46,8 @@ import {
|
||||||
PinnedStatuses,
|
PinnedStatuses,
|
||||||
Lists,
|
Lists,
|
||||||
} from './util/async-components';
|
} from './util/async-components';
|
||||||
import { HotKeys } from 'react-hotkeys';
|
|
||||||
import { me } from '../../initial_state';
|
import { me } from '../../initial_state';
|
||||||
import { defineMessages, injectIntl } from 'react-intl';
|
import { previewState } from './components/media_modal';
|
||||||
|
|
||||||
// Dummy import, to make sure that <Status /> ends up in the application bundle.
|
// Dummy import, to make sure that <Status /> ends up in the application bundle.
|
||||||
// Without this it ends up in ~8 very commonly used bundles.
|
// Without this it ends up in ~8 very commonly used bundles.
|
||||||
|
@ -117,6 +118,10 @@ class SwitchingColumnsArea extends React.PureComponent {
|
||||||
window.removeEventListener('resize', this.handleResize);
|
window.removeEventListener('resize', this.handleResize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shouldUpdateScroll (_, { location }) {
|
||||||
|
return location.state !== previewState;
|
||||||
|
}
|
||||||
|
|
||||||
handleResize = debounce(() => {
|
handleResize = debounce(() => {
|
||||||
// The cached heights are no longer accurate, invalidate
|
// The cached heights are no longer accurate, invalidate
|
||||||
this.props.onLayoutChange();
|
this.props.onLayoutChange();
|
||||||
|
@ -141,36 +146,36 @@ class SwitchingColumnsArea extends React.PureComponent {
|
||||||
{redirect}
|
{redirect}
|
||||||
<WrappedRoute path='/getting-started' component={GettingStarted} content={children} />
|
<WrappedRoute path='/getting-started' component={GettingStarted} content={children} />
|
||||||
<WrappedRoute path='/keyboard-shortcuts' component={KeyboardShortcuts} content={children} />
|
<WrappedRoute path='/keyboard-shortcuts' component={KeyboardShortcuts} content={children} />
|
||||||
<WrappedRoute path='/timelines/home' component={HomeTimeline} content={children} />
|
<WrappedRoute path='/timelines/home' component={HomeTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
|
||||||
<WrappedRoute path='/timelines/public' exact component={PublicTimeline} content={children} />
|
<WrappedRoute path='/timelines/public' exact component={PublicTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
|
||||||
<WrappedRoute path='/timelines/public/media' component={PublicTimeline} content={children} componentParams={{ onlyMedia: true }} />
|
<WrappedRoute path='/timelines/public/media' component={PublicTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll, onlyMedia: true }} />
|
||||||
<WrappedRoute path='/timelines/public/local' exact component={CommunityTimeline} content={children} />
|
<WrappedRoute path='/timelines/public/local' exact component={CommunityTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
|
||||||
<WrappedRoute path='/timelines/public/local/media' component={CommunityTimeline} content={children} componentParams={{ onlyMedia: true }} />
|
<WrappedRoute path='/timelines/public/local/media' component={CommunityTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll, onlyMedia: true }} />
|
||||||
<WrappedRoute path='/timelines/direct' component={DirectTimeline} content={children} />
|
<WrappedRoute path='/timelines/direct' component={DirectTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
|
||||||
<WrappedRoute path='/timelines/tag/:id' component={HashtagTimeline} content={children} />
|
<WrappedRoute path='/timelines/tag/:id' component={HashtagTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
|
||||||
<WrappedRoute path='/timelines/list/:id' component={ListTimeline} content={children} />
|
<WrappedRoute path='/timelines/list/:id' component={ListTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
|
||||||
|
|
||||||
<WrappedRoute path='/notifications' component={Notifications} content={children} />
|
<WrappedRoute path='/notifications' component={Notifications} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
|
||||||
<WrappedRoute path='/favourites' component={FavouritedStatuses} content={children} />
|
<WrappedRoute path='/favourites' component={FavouritedStatuses} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
|
||||||
<WrappedRoute path='/pinned' component={PinnedStatuses} content={children} />
|
<WrappedRoute path='/pinned' component={PinnedStatuses} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
|
||||||
|
|
||||||
<WrappedRoute path='/search' component={Compose} content={children} componentParams={{ isSearchPage: true }} />
|
<WrappedRoute path='/search' component={Compose} content={children} componentParams={{ isSearchPage: true }} />
|
||||||
|
|
||||||
<WrappedRoute path='/statuses/new' component={Compose} content={children} />
|
<WrappedRoute path='/statuses/new' component={Compose} content={children} />
|
||||||
<WrappedRoute path='/statuses/:statusId' exact component={Status} content={children} />
|
<WrappedRoute path='/statuses/:statusId' exact component={Status} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
|
||||||
<WrappedRoute path='/statuses/:statusId/reblogs' component={Reblogs} content={children} />
|
<WrappedRoute path='/statuses/:statusId/reblogs' component={Reblogs} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
|
||||||
<WrappedRoute path='/statuses/:statusId/favourites' component={Favourites} content={children} />
|
<WrappedRoute path='/statuses/:statusId/favourites' component={Favourites} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
|
||||||
|
|
||||||
<WrappedRoute path='/accounts/:accountId' exact component={AccountTimeline} content={children} />
|
<WrappedRoute path='/accounts/:accountId' exact component={AccountTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
|
||||||
<WrappedRoute path='/accounts/:accountId/with_replies' component={AccountTimeline} content={children} componentParams={{ withReplies: true }} />
|
<WrappedRoute path='/accounts/:accountId/with_replies' component={AccountTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll, withReplies: true }} />
|
||||||
<WrappedRoute path='/accounts/:accountId/followers' component={Followers} content={children} />
|
<WrappedRoute path='/accounts/:accountId/followers' component={Followers} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
|
||||||
<WrappedRoute path='/accounts/:accountId/following' component={Following} content={children} />
|
<WrappedRoute path='/accounts/:accountId/following' component={Following} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
|
||||||
<WrappedRoute path='/accounts/:accountId/media' component={AccountGallery} content={children} />
|
<WrappedRoute path='/accounts/:accountId/media' component={AccountGallery} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
|
||||||
|
|
||||||
<WrappedRoute path='/follow_requests' component={FollowRequests} content={children} />
|
<WrappedRoute path='/follow_requests' component={FollowRequests} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
|
||||||
<WrappedRoute path='/blocks' component={Blocks} content={children} />
|
<WrappedRoute path='/blocks' component={Blocks} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
|
||||||
<WrappedRoute path='/domain_blocks' component={DomainBlocks} content={children} />
|
<WrappedRoute path='/domain_blocks' component={DomainBlocks} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
|
||||||
<WrappedRoute path='/mutes' component={Mutes} content={children} />
|
<WrappedRoute path='/mutes' component={Mutes} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
|
||||||
<WrappedRoute path='/lists' component={Lists} content={children} />
|
<WrappedRoute path='/lists' component={Lists} content={children} />
|
||||||
|
|
||||||
<WrappedRoute component={GenericNotFound} content={children} />
|
<WrappedRoute component={GenericNotFound} content={children} />
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
{
|
{
|
||||||
"account.badges.bot": "Robot",
|
"account.badges.bot": "Robot",
|
||||||
"account.block": "Blokovat @{name}",
|
"account.block": "Zablokovat uživatele @{name}",
|
||||||
"account.block_domain": "Skrýt vše z {domain}",
|
"account.block_domain": "Skrýt vše z {domain}",
|
||||||
"account.blocked": "Blokován/a",
|
"account.blocked": "Blokován/a",
|
||||||
"account.direct": "Přímá zpráva pro uživatele @{name}",
|
"account.direct": "Přímá zpráva pro uživatele @{name}",
|
||||||
"account.disclaimer_full": "Níže uvedené informace nemusejí zcela odrážet profil uživatele.",
|
"account.disclaimer_full": "Níže uvedené informace nemusejí zcela odrážet profil uživatele.",
|
||||||
"account.domain_blocked": "Doména skryta",
|
"account.domain_blocked": "Doména skryta",
|
||||||
"account.edit_profile": "Uprav profil",
|
"account.edit_profile": "Upravit profil",
|
||||||
"account.follow": "Sleduj",
|
"account.follow": "Sleduj",
|
||||||
"account.followers": "Sledovatelé",
|
"account.followers": "Sledovatelé",
|
||||||
"account.follows": "Sleduje",
|
"account.follows": "Sleduje",
|
||||||
"account.follows_you": "Sleduje vás",
|
"account.follows_you": "Sleduje vás",
|
||||||
"account.hide_reblogs": "Skrýt povýšení od uživatele @{name}",
|
"account.hide_reblogs": "Skrýt boosty od uživatele @{name}",
|
||||||
"account.media": "Média",
|
"account.media": "Média",
|
||||||
"account.mention": "Zmínit uživatele @{name}",
|
"account.mention": "Zmínit uživatele @{name}",
|
||||||
"account.moved_to": "{name} se přesunul/a na:",
|
"account.moved_to": "{name} se přesunul/a na:",
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
"account.report": "Nahlásit uživatele @{name}",
|
"account.report": "Nahlásit uživatele @{name}",
|
||||||
"account.requested": "Požadavek čeká na schválení. Kliknutím zrušíte požadavek o sledování",
|
"account.requested": "Požadavek čeká na schválení. Kliknutím zrušíte požadavek o sledování",
|
||||||
"account.share": "Sdílet profil uživatele @{name}",
|
"account.share": "Sdílet profil uživatele @{name}",
|
||||||
"account.show_reblogs": "Zobrazit povýšení od uživatele @{name}",
|
"account.show_reblogs": "Zobrazit boosty od uživatele @{name}",
|
||||||
"account.unblock": "Odblokovat uživatele @{name}",
|
"account.unblock": "Odblokovat uživatele @{name}",
|
||||||
"account.unblock_domain": "Odkrýt doménu {domain}",
|
"account.unblock_domain": "Odkrýt doménu {domain}",
|
||||||
"account.unfollow": "Přestat sledovat",
|
"account.unfollow": "Přestat sledovat",
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
"compose_form.direct_message_warning_learn_more": "Zjistit více",
|
"compose_form.direct_message_warning_learn_more": "Zjistit více",
|
||||||
"compose_form.hashtag_warning": "Tento toot nebude zobrazen pod žádným hashtagem, neboť je neuvedený. Pouze veřejné tooty mohou být vyhledány podle hashtagu.",
|
"compose_form.hashtag_warning": "Tento toot nebude zobrazen pod žádným hashtagem, neboť je neuvedený. Pouze veřejné tooty mohou být vyhledány podle hashtagu.",
|
||||||
"compose_form.lock_disclaimer": "Váš účet není {locked}. Kdokoliv vás může sledovat a vidět vaše příspěvky pouze pro sledovatele.",
|
"compose_form.lock_disclaimer": "Váš účet není {locked}. Kdokoliv vás může sledovat a vidět vaše příspěvky pouze pro sledovatele.",
|
||||||
"compose_form.lock_disclaimer.lock": "zamknutý",
|
"compose_form.lock_disclaimer.lock": "zamčený",
|
||||||
"compose_form.placeholder": "Co máte na mysli?",
|
"compose_form.placeholder": "Co máte na mysli?",
|
||||||
"compose_form.publish": "Tootnout",
|
"compose_form.publish": "Tootnout",
|
||||||
"compose_form.publish_loud": "{publish}!",
|
"compose_form.publish_loud": "{publish}!",
|
||||||
|
@ -85,225 +85,225 @@
|
||||||
"confirmations.mute.confirm": "Ignorovat",
|
"confirmations.mute.confirm": "Ignorovat",
|
||||||
"confirmations.mute.message": "Jste si jistý/á, že chcete ignorovat uživatele {name}?",
|
"confirmations.mute.message": "Jste si jistý/á, že chcete ignorovat uživatele {name}?",
|
||||||
"confirmations.redraft.confirm": "Vymazat a přepsat",
|
"confirmations.redraft.confirm": "Vymazat a přepsat",
|
||||||
"confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.",
|
"confirmations.redraft.message": "Jste si jistý/á, že chcete vymazat a přepsat tento status? Ztratíte všechny jeho odpovědi, boosty a oblíbení.",
|
||||||
"confirmations.unfollow.confirm": "Unfollow",
|
"confirmations.unfollow.confirm": "Přestat sledovat",
|
||||||
"confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
|
"confirmations.unfollow.message": "jste si jistý/á, že chcete přestat sledovat uživatele {name}?",
|
||||||
"embed.instructions": "Embed this status on your website by copying the code below.",
|
"embed.instructions": "Pro přidání statusu na vaši webovou stránku zkopírujte níže uvedený kód.",
|
||||||
"embed.preview": "Here is what it will look like:",
|
"embed.preview": "Takhle to bude vypadat:",
|
||||||
"emoji_button.activity": "Activity",
|
"emoji_button.activity": "Aktivita",
|
||||||
"emoji_button.custom": "Custom",
|
"emoji_button.custom": "Vlastní",
|
||||||
"emoji_button.flags": "Flags",
|
"emoji_button.flags": "Vlajky",
|
||||||
"emoji_button.food": "Food & Drink",
|
"emoji_button.food": "Jídla a nápoje",
|
||||||
"emoji_button.label": "Insert emoji",
|
"emoji_button.label": "Vložit emoji",
|
||||||
"emoji_button.nature": "Nature",
|
"emoji_button.nature": "Příroda",
|
||||||
"emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻",
|
"emoji_button.not_found": "Žádné emoji!! (╯°□°)╯︵ ┻━┻",
|
||||||
"emoji_button.objects": "Objects",
|
"emoji_button.objects": "Předměty",
|
||||||
"emoji_button.people": "People",
|
"emoji_button.people": "Lidé",
|
||||||
"emoji_button.recent": "Frequently used",
|
"emoji_button.recent": "Často používané",
|
||||||
"emoji_button.search": "Search...",
|
"emoji_button.search": "Hledat...",
|
||||||
"emoji_button.search_results": "Search results",
|
"emoji_button.search_results": "Výsledky hledání",
|
||||||
"emoji_button.symbols": "Symbols",
|
"emoji_button.symbols": "Symboly",
|
||||||
"emoji_button.travel": "Travel & Places",
|
"emoji_button.travel": "Cestování a místa",
|
||||||
"empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
|
"empty_column.community": "Místní časová osa je prázdná. Napište něco veřejně a rozhýbejte to tu!",
|
||||||
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
"empty_column.direct": "Ještě nemáte žádné přímé zprávy. Pokud nějakou pošlete nebo dostanete, zobrazí se zde.",
|
||||||
"empty_column.hashtag": "There is nothing in this hashtag yet.",
|
"empty_column.hashtag": "Pod tímto hashtagem ještě nic není.",
|
||||||
"empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.",
|
"empty_column.home": "Vaše domovská časová osa je prázdná! Začněte navštívením {public} nebo použijte hledání a seznamte se s dalšími uživateli.",
|
||||||
"empty_column.home.public_timeline": "the public timeline",
|
"empty_column.home.public_timeline": "veřejné časové osy",
|
||||||
"empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.",
|
"empty_column.list": "V tomto seznamu ještě nic není. Pokud budou členové tohoto seznamu psát nové statusy, objeví se zde.",
|
||||||
"empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.",
|
"empty_column.notifications": "Ještě nemáte žádná oznámení. Začněte konverzaci komunikováním s ostatními.",
|
||||||
"empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other instances to fill it up",
|
"empty_column.public": "Tady nic není! Napište něco veřejně, nebo manuálně začněte sledovat uživatele z jiných instancí, aby tu něco přibylo",
|
||||||
"follow_request.authorize": "Authorize",
|
"follow_request.authorize": "Autorizovat",
|
||||||
"follow_request.reject": "Reject",
|
"follow_request.reject": "Odmítnout",
|
||||||
"getting_started.developers": "Developers",
|
"getting_started.developers": "Vývojáři",
|
||||||
"getting_started.documentation": "Documentation",
|
"getting_started.documentation": "Documentation",
|
||||||
"getting_started.find_friends": "Find friends from Twitter",
|
"getting_started.find_friends": "Najděte si přátele z Twitteru",
|
||||||
"getting_started.heading": "Getting started",
|
"getting_started.heading": "Začínáme",
|
||||||
"getting_started.invite": "Invite people",
|
"getting_started.invite": "Pozvat lidi",
|
||||||
"getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.",
|
"getting_started.open_source_notice": "Mastodon je otevřený software. Na GitHubu k němu můžete přispět nebo nahlásit chyby: {github}.",
|
||||||
"getting_started.security": "Security",
|
"getting_started.security": "Zabezpečení",
|
||||||
"getting_started.terms": "Terms of service",
|
"getting_started.terms": "Podmínky používání",
|
||||||
"home.column_settings.basic": "Basic",
|
"home.column_settings.basic": "Základní",
|
||||||
"home.column_settings.show_reblogs": "Show boosts",
|
"home.column_settings.show_reblogs": "Zobrazit boosty",
|
||||||
"home.column_settings.show_replies": "Show replies",
|
"home.column_settings.show_replies": "Zobrazit odpovědi",
|
||||||
"keyboard_shortcuts.back": "to navigate back",
|
"keyboard_shortcuts.back": "k návratu zpět",
|
||||||
"keyboard_shortcuts.boost": "to boost",
|
"keyboard_shortcuts.boost": "k boostnutí",
|
||||||
"keyboard_shortcuts.column": "to focus a status in one of the columns",
|
"keyboard_shortcuts.column": "k zaměření na status v jednom ze sloupců",
|
||||||
"keyboard_shortcuts.compose": "to focus the compose textarea",
|
"keyboard_shortcuts.compose": "k zaměření na psací prostor",
|
||||||
"keyboard_shortcuts.description": "Description",
|
"keyboard_shortcuts.description": "Popis",
|
||||||
"keyboard_shortcuts.down": "to move down in the list",
|
"keyboard_shortcuts.down": "k přesunutí dolů v seznamu",
|
||||||
"keyboard_shortcuts.enter": "to open status",
|
"keyboard_shortcuts.enter": "k otevření statusu",
|
||||||
"keyboard_shortcuts.favourite": "to favourite",
|
"keyboard_shortcuts.favourite": "k oblíbení",
|
||||||
"keyboard_shortcuts.heading": "Keyboard Shortcuts",
|
"keyboard_shortcuts.heading": "Klávesové zkratky",
|
||||||
"keyboard_shortcuts.hotkey": "Hotkey",
|
"keyboard_shortcuts.hotkey": "Horká klávesa",
|
||||||
"keyboard_shortcuts.legend": "to display this legend",
|
"keyboard_shortcuts.legend": "k zobrazení této legendy",
|
||||||
"keyboard_shortcuts.mention": "to mention author",
|
"keyboard_shortcuts.mention": "ke zmínění autora",
|
||||||
"keyboard_shortcuts.profile": "to open author's profile",
|
"keyboard_shortcuts.profile": "to open author's profile",
|
||||||
"keyboard_shortcuts.reply": "to reply",
|
"keyboard_shortcuts.reply": "k odpovězení",
|
||||||
"keyboard_shortcuts.search": "to focus search",
|
"keyboard_shortcuts.search": "k zaměření na vyhledávání",
|
||||||
"keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
|
"keyboard_shortcuts.toggle_hidden": "k zobrazení/skrytí textu za CW",
|
||||||
"keyboard_shortcuts.toot": "to start a brand new toot",
|
"keyboard_shortcuts.toot": "k napsání úplně nového tootu",
|
||||||
"keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
|
"keyboard_shortcuts.unfocus": "ke zrušení soustředění na psací prostor/hledání",
|
||||||
"keyboard_shortcuts.up": "to move up in the list",
|
"keyboard_shortcuts.up": "k posunutí nahoru v seznamu",
|
||||||
"lightbox.close": "Close",
|
"lightbox.close": "Zavřít",
|
||||||
"lightbox.next": "Next",
|
"lightbox.next": "Další",
|
||||||
"lightbox.previous": "Previous",
|
"lightbox.previous": "Předchozí",
|
||||||
"lists.account.add": "Add to list",
|
"lists.account.add": "Přidat do seznamu",
|
||||||
"lists.account.remove": "Remove from list",
|
"lists.account.remove": "Odebrat ze seznamu",
|
||||||
"lists.delete": "Delete list",
|
"lists.delete": "Smazat seznam",
|
||||||
"lists.edit": "Edit list",
|
"lists.edit": "Upravit seznam",
|
||||||
"lists.new.create": "Add list",
|
"lists.new.create": "Přidat seznam",
|
||||||
"lists.new.title_placeholder": "New list title",
|
"lists.new.title_placeholder": "Název nového seznamu",
|
||||||
"lists.search": "Search among people you follow",
|
"lists.search": "Hledejte mezi uživateli, které sledujete",
|
||||||
"lists.subheading": "Your lists",
|
"lists.subheading": "Vaše seznamy",
|
||||||
"loading_indicator.label": "Loading...",
|
"loading_indicator.label": "Načítám...",
|
||||||
"media_gallery.toggle_visible": "Toggle visibility",
|
"media_gallery.toggle_visible": "Přepínat viditelnost",
|
||||||
"missing_indicator.label": "Not found",
|
"missing_indicator.label": "Nenalezeno",
|
||||||
"missing_indicator.sublabel": "This resource could not be found",
|
"missing_indicator.sublabel": "Tento zdroj se nepodažilo najít",
|
||||||
"mute_modal.hide_notifications": "Hide notifications from this user?",
|
"mute_modal.hide_notifications": "Skrýt oznámení před tímto uživatelem?",
|
||||||
"navigation_bar.blocks": "Blocked users",
|
"navigation_bar.blocks": "Blokovaní uživatelé",
|
||||||
"navigation_bar.community_timeline": "Local timeline",
|
"navigation_bar.community_timeline": "Místní časová osa",
|
||||||
"navigation_bar.direct": "Direct messages",
|
"navigation_bar.direct": "Přímé zprávy",
|
||||||
"navigation_bar.discover": "Discover",
|
"navigation_bar.discover": "Objevujte",
|
||||||
"navigation_bar.domain_blocks": "Hidden domains",
|
"navigation_bar.domain_blocks": "Skryté domény",
|
||||||
"navigation_bar.edit_profile": "Edit profile",
|
"navigation_bar.edit_profile": "Upravit profil",
|
||||||
"navigation_bar.favourites": "Favourites",
|
"navigation_bar.favourites": "Oblíbené",
|
||||||
"navigation_bar.filters": "Muted words",
|
"navigation_bar.filters": "Skrytá slova",
|
||||||
"navigation_bar.follow_requests": "Follow requests",
|
"navigation_bar.follow_requests": "Žádosti o sledování",
|
||||||
"navigation_bar.info": "About this instance",
|
"navigation_bar.info": "O této instanci",
|
||||||
"navigation_bar.keyboard_shortcuts": "Hotkeys",
|
"navigation_bar.keyboard_shortcuts": "Klávesové zkratky",
|
||||||
"navigation_bar.lists": "Lists",
|
"navigation_bar.lists": "Seznamy",
|
||||||
"navigation_bar.logout": "Logout",
|
"navigation_bar.logout": "Odhlásit se",
|
||||||
"navigation_bar.mutes": "Muted users",
|
"navigation_bar.mutes": "Ignorovaní uživatelé",
|
||||||
"navigation_bar.personal": "Personal",
|
"navigation_bar.personal": "Osobní",
|
||||||
"navigation_bar.pins": "Pinned toots",
|
"navigation_bar.pins": "Připnuté tooty",
|
||||||
"navigation_bar.preferences": "Preferences",
|
"navigation_bar.preferences": "Předvolby",
|
||||||
"navigation_bar.public_timeline": "Federated timeline",
|
"navigation_bar.public_timeline": "Federovaná časová osa",
|
||||||
"navigation_bar.security": "Security",
|
"navigation_bar.security": "Zabezpečení",
|
||||||
"notification.favourite": "{name} favourited your status",
|
"notification.favourite": "{name} označil/a váš status jako oblíbený",
|
||||||
"notification.follow": "{name} followed you",
|
"notification.follow": "{name} vás začal/a sledovat",
|
||||||
"notification.mention": "{name} mentioned you",
|
"notification.mention": "{name} vás zmínil/a",
|
||||||
"notification.reblog": "{name} boosted your status",
|
"notification.reblog": "{name} vám boostnul/a status",
|
||||||
"notifications.clear": "Clear notifications",
|
"notifications.clear": "Vymazat oznámení",
|
||||||
"notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
|
"notifications.clear_confirmation": "Jste si jistý/á, že chcete trvale vymazat všechna vaše oznámení?",
|
||||||
"notifications.column_settings.alert": "Desktop notifications",
|
"notifications.column_settings.alert": "Desktopová oznámení",
|
||||||
"notifications.column_settings.favourite": "Favourites:",
|
"notifications.column_settings.favourite": "Oblíbené:",
|
||||||
"notifications.column_settings.follow": "New followers:",
|
"notifications.column_settings.follow": "Noví sledovatelé:",
|
||||||
"notifications.column_settings.mention": "Mentions:",
|
"notifications.column_settings.mention": "Zmínky:",
|
||||||
"notifications.column_settings.push": "Push notifications",
|
"notifications.column_settings.push": "Push oznámení",
|
||||||
"notifications.column_settings.push_meta": "This device",
|
"notifications.column_settings.push_meta": "Toto zařízení",
|
||||||
"notifications.column_settings.reblog": "Boosts:",
|
"notifications.column_settings.reblog": "Boosty:",
|
||||||
"notifications.column_settings.show": "Show in column",
|
"notifications.column_settings.show": "Zobrazit ve sloupci",
|
||||||
"notifications.column_settings.sound": "Play sound",
|
"notifications.column_settings.sound": "Přehrát zvuk",
|
||||||
"notifications.group": "{count} notifications",
|
"notifications.group": "{count} oznámení",
|
||||||
"onboarding.done": "Done",
|
"onboarding.done": "Hotovo",
|
||||||
"onboarding.next": "Next",
|
"onboarding.next": "Další",
|
||||||
"onboarding.page_five.public_timelines": "The local timeline shows public posts from everyone on {domain}. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new people.",
|
"onboarding.page_five.public_timelines": "Místní časová osa zobrazuje veřejné příspěvky od všech lidí na {domain}. Federovaná časová osa zobrazuje veřejné příspěvky ode všech, které lidé na {domain} sledují. Toto jsou veřejné časové osy, výborný způsob, jak objevovat nové lidi.",
|
||||||
"onboarding.page_four.home": "The home timeline shows posts from people you follow.",
|
"onboarding.page_four.home": "Domovská časová osa zobrazuje příspěvky od lidí, které sledujete.",
|
||||||
"onboarding.page_four.notifications": "The notifications column shows when someone interacts with you.",
|
"onboarding.page_four.notifications": "Sloupec oznámení se zobrazí, když s vámi někdo bude komunikovat.",
|
||||||
"onboarding.page_one.federation": "Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
|
"onboarding.page_one.federation": "Mastodon je síť nezávislých serverů, jejichž propojením vzniká jedna velká sociální síť. Těmto serverům říkáme instance.",
|
||||||
"onboarding.page_one.full_handle": "Your full handle",
|
"onboarding.page_one.full_handle": "Vaše celá adresa profilu",
|
||||||
"onboarding.page_one.handle_hint": "This is what you would tell your friends to search for.",
|
"onboarding.page_one.handle_hint": "Tohle je, co byste řekl/a svým přátelům, aby hledali.",
|
||||||
"onboarding.page_one.welcome": "Welcome to Mastodon!",
|
"onboarding.page_one.welcome": "Vítejte na Mastodonu!",
|
||||||
"onboarding.page_six.admin": "Your instance's admin is {admin}.",
|
"onboarding.page_six.admin": "Administrátorem vaší instance je {admin}.",
|
||||||
"onboarding.page_six.almost_done": "Almost done...",
|
"onboarding.page_six.almost_done": "Skoro hotovo...",
|
||||||
"onboarding.page_six.appetoot": "Bon Appetoot!",
|
"onboarding.page_six.appetoot": "Bon appetoot!",
|
||||||
"onboarding.page_six.apps_available": "There are {apps} available for iOS, Android and other platforms.",
|
"onboarding.page_six.apps_available": "Jsou dostupné {apps} pro iOS, Android a jiné platformy.",
|
||||||
"onboarding.page_six.github": "Mastodon is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
|
"onboarding.page_six.github": "Mastodon je svobodný a otevřený software. Na {github} můžete nahlásit chyby, požádat o nové funkce, nebo přispívat ke kódu.",
|
||||||
"onboarding.page_six.guidelines": "community guidelines",
|
"onboarding.page_six.guidelines": "komunitní pravidla",
|
||||||
"onboarding.page_six.read_guidelines": "Please read {domain}'s {guidelines}!",
|
"onboarding.page_six.read_guidelines": "Prosím přečtěte si {guidelines} {domain}!",
|
||||||
"onboarding.page_six.various_app": "mobile apps",
|
"onboarding.page_six.various_app": "mobilní aplikace",
|
||||||
"onboarding.page_three.profile": "Edit your profile to change your avatar, bio, and display name. There, you will also find other preferences.",
|
"onboarding.page_three.profile": "Upravte si svůj profil a změňte si svůj avatar, popis profilu a zobrazované jméno. V nastaveních najdete i další možnosti.",
|
||||||
"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_three.search": "Pomocí vyhledávacího řádku najděte lidi a podívejte se na hashtagy jako {illustration} a {introductions}. Chcete-li najít někoho, kdo není na této instanci, použijte jeho celou adresu profilu.",
|
||||||
"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.page_two.compose": "Příspěvky pište z pole na komponování. Ikonami níže můžete nahrávat obrázky, změnit nastavení soukromí a přidat varování o obsahu.",
|
||||||
"onboarding.skip": "Skip",
|
"onboarding.skip": "Přeskočit",
|
||||||
"privacy.change": "Adjust status privacy",
|
"privacy.change": "Změnit viditelnost statusu",
|
||||||
"privacy.direct.long": "Post to mentioned users only",
|
"privacy.direct.long": "Odeslat pouze zmíněným uživatelům",
|
||||||
"privacy.direct.short": "Direct",
|
"privacy.direct.short": "Přímé",
|
||||||
"privacy.private.long": "Post to followers only",
|
"privacy.private.long": "Odeslat pouze sledovatelům",
|
||||||
"privacy.private.short": "Followers-only",
|
"privacy.private.short": "Pouze pro sledovatele",
|
||||||
"privacy.public.long": "Post to public timelines",
|
"privacy.public.long": "Odeslat na veřejné časové osy",
|
||||||
"privacy.public.short": "Public",
|
"privacy.public.short": "Veřejné",
|
||||||
"privacy.unlisted.long": "Do not show in public timelines",
|
"privacy.unlisted.long": "Do not show in public timelines",
|
||||||
"privacy.unlisted.short": "Unlisted",
|
"privacy.unlisted.short": "Nezobrazované",
|
||||||
"regeneration_indicator.label": "Loading…",
|
"regeneration_indicator.label": "Načítám…",
|
||||||
"regeneration_indicator.sublabel": "Your home feed is being prepared!",
|
"regeneration_indicator.sublabel": "Váš domovský proud se připravuje!",
|
||||||
"relative_time.days": "{number}d",
|
"relative_time.days": "{number}d",
|
||||||
"relative_time.hours": "{number}h",
|
"relative_time.hours": "{number}h",
|
||||||
"relative_time.just_now": "now",
|
"relative_time.just_now": "teď",
|
||||||
"relative_time.minutes": "{number}m",
|
"relative_time.minutes": "{number}m",
|
||||||
"relative_time.seconds": "{number}s",
|
"relative_time.seconds": "{number}s",
|
||||||
"reply_indicator.cancel": "Cancel",
|
"reply_indicator.cancel": "Zrušit",
|
||||||
"report.forward": "Forward to {target}",
|
"report.forward": "Přeposlat k {target}",
|
||||||
"report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
|
"report.forward_hint": "Tento účet je z jiného serveru. Chcete na něj také poslat anonymizovanou kopii?",
|
||||||
"report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
|
"report.hint": "Toto nahlášení bude zasláno moderátorům vaší instance. Níže můžete uvést, proč tento účet nahlašujete:",
|
||||||
"report.placeholder": "Additional comments",
|
"report.placeholder": "Další komentáře",
|
||||||
"report.submit": "Submit",
|
"report.submit": "Odeslat",
|
||||||
"report.target": "Report {target}",
|
"report.target": "Nahlásit {target}",
|
||||||
"search.placeholder": "Search",
|
"search.placeholder": "Hledat",
|
||||||
"search_popout.search_format": "Advanced search format",
|
"search_popout.search_format": "Pokročilé vyhledávání",
|
||||||
"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.full_text": "Jednoduchý textový výpis statusů, které jste napsal/a, oblíbil/a si, povýšil/a, nebo v nich byl/a zmíněn/a, včetně odpovídajících přezdívek, jmen a hashtagů.",
|
||||||
"search_popout.tips.hashtag": "hashtag",
|
"search_popout.tips.hashtag": "hashtag",
|
||||||
"search_popout.tips.status": "status",
|
"search_popout.tips.status": "status",
|
||||||
"search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
|
"search_popout.tips.text": "Jednoduchý textový výpis odpovídajících jmen, přezdívek a hashtagů",
|
||||||
"search_popout.tips.user": "user",
|
"search_popout.tips.user": "uživatel",
|
||||||
"search_results.accounts": "People",
|
"search_results.accounts": "Lidé",
|
||||||
"search_results.hashtags": "Hashtags",
|
"search_results.hashtags": "Hashtagy",
|
||||||
"search_results.statuses": "Toots",
|
"search_results.statuses": "Tooty",
|
||||||
"search_results.total": "{count, number} {count, plural, one {result} other {results}}",
|
"search_results.total": "{count, number} {count, plural, one {výsledek} other {výsledků}}",
|
||||||
"standalone.public_title": "A look inside...",
|
"standalone.public_title": "Nahlédnout dovnitř...",
|
||||||
"status.block": "Block @{name}",
|
"status.block": "Zablokovat uživatele @{name}",
|
||||||
"status.cancel_reblog_private": "Unboost",
|
"status.cancel_reblog_private": "Zrušit boost",
|
||||||
"status.cannot_reblog": "This post cannot be boosted",
|
"status.cannot_reblog": "Tento příspěvek nemůže být boostnutý",
|
||||||
"status.delete": "Delete",
|
"status.delete": "Delete",
|
||||||
"status.direct": "Direct message @{name}",
|
"status.direct": "Poslat přímou zprávu uživateli @{name}",
|
||||||
"status.embed": "Embed",
|
"status.embed": "Vložit",
|
||||||
"status.favourite": "Favourite",
|
"status.favourite": "Oblíbit",
|
||||||
"status.filtered": "Filtered",
|
"status.filtered": "Filtrováno",
|
||||||
"status.load_more": "Load more",
|
"status.load_more": "Zobrazit více",
|
||||||
"status.media_hidden": "Media hidden",
|
"status.media_hidden": "Média skryta",
|
||||||
"status.mention": "Mention @{name}",
|
"status.mention": "Zmínit uživatele @{name}",
|
||||||
"status.more": "More",
|
"status.more": "Více",
|
||||||
"status.mute": "Mute @{name}",
|
"status.mute": "Ignorovat uživatele @{name}",
|
||||||
"status.mute_conversation": "Mute conversation",
|
"status.mute_conversation": "Ignorovat konverzaci",
|
||||||
"status.open": "Expand this status",
|
"status.open": "Otevřít tento status",
|
||||||
"status.pin": "Pin on profile",
|
"status.pin": "Připnout na profil",
|
||||||
"status.pinned": "Pinned toot",
|
"status.pinned": "Připnutý toot",
|
||||||
"status.reblog": "Boost",
|
"status.reblog": "Boostnout",
|
||||||
"status.reblog_private": "Boost to original audience",
|
"status.reblog_private": "Boostnout původnímu publiku",
|
||||||
"status.reblogged_by": "{name} boosted",
|
"status.reblogged_by": "{name} boostnul/a",
|
||||||
"status.redraft": "Delete & re-draft",
|
"status.redraft": "Vymazat a přepsat",
|
||||||
"status.reply": "Reply",
|
"status.reply": "Odpovědět",
|
||||||
"status.replyAll": "Reply to thread",
|
"status.replyAll": "Odpovědět na vlákno",
|
||||||
"status.report": "Report @{name}",
|
"status.report": "Nahlásit uživatele @{name}",
|
||||||
"status.sensitive_toggle": "Click to view",
|
"status.sensitive_toggle": "Klikněte pro zobrazení",
|
||||||
"status.sensitive_warning": "Sensitive content",
|
"status.sensitive_warning": "Citlivý obsah",
|
||||||
"status.share": "Share",
|
"status.share": "Sdílet",
|
||||||
"status.show_less": "Show less",
|
"status.show_less": "Zobrazit méně",
|
||||||
"status.show_less_all": "Show less for all",
|
"status.show_less_all": "Zobrazit méně pro všechny",
|
||||||
"status.show_more": "Show more",
|
"status.show_more": "Zobrazit více",
|
||||||
"status.show_more_all": "Show more for all",
|
"status.show_more_all": "Zobrazit více pro všechny",
|
||||||
"status.unmute_conversation": "Unmute conversation",
|
"status.unmute_conversation": "Přestat ignorovat konverzaci",
|
||||||
"status.unpin": "Unpin from profile",
|
"status.unpin": "Odepnout z profilu",
|
||||||
"tabs_bar.federated_timeline": "Federated",
|
"tabs_bar.federated_timeline": "Federovaná",
|
||||||
"tabs_bar.home": "Home",
|
"tabs_bar.home": "Domů",
|
||||||
"tabs_bar.local_timeline": "Local",
|
"tabs_bar.local_timeline": "Místní",
|
||||||
"tabs_bar.notifications": "Notifications",
|
"tabs_bar.notifications": "Oznámení",
|
||||||
"tabs_bar.search": "Search",
|
"tabs_bar.search": "Hledat",
|
||||||
"trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
|
"trends.count_by_accounts": "{count} {rawCount, plural, one {člověk} other {lidí}} diskutuje",
|
||||||
"ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
|
"ui.beforeunload": "Váš koncept se ztratí, pokud Mastodon opustíte.",
|
||||||
"upload_area.title": "Drag & drop to upload",
|
"upload_area.title": "Přetažením nahrajete",
|
||||||
"upload_button.label": "Add media",
|
"upload_button.label": "Přidat média",
|
||||||
"upload_form.description": "Describe for the visually impaired",
|
"upload_form.description": "Popis pro zrakově postižené",
|
||||||
"upload_form.focus": "Crop",
|
"upload_form.focus": "Vystřihnout",
|
||||||
"upload_form.undo": "Delete",
|
"upload_form.undo": "Smazat",
|
||||||
"upload_progress.label": "Uploading...",
|
"upload_progress.label": "Nahrávám...",
|
||||||
"video.close": "Close video",
|
"video.close": "Zavřít video",
|
||||||
"video.exit_fullscreen": "Exit full screen",
|
"video.exit_fullscreen": "Ukončit celou obrazovku",
|
||||||
"video.expand": "Expand video",
|
"video.expand": "Otevřít video",
|
||||||
"video.fullscreen": "Full screen",
|
"video.fullscreen": "Celá obrazovka",
|
||||||
"video.hide": "Hide video",
|
"video.hide": "Skrýt video",
|
||||||
"video.mute": "Mute sound",
|
"video.mute": "Vypnout zvuk",
|
||||||
"video.pause": "Pause",
|
"video.pause": "Pauza",
|
||||||
"video.play": "Play",
|
"video.play": "Přehrát",
|
||||||
"video.unmute": "Unmute sound"
|
"video.unmute": "Zapnout zvuk"
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,7 +167,7 @@
|
||||||
"navigation_bar.domain_blocks": "숨겨진 도메인",
|
"navigation_bar.domain_blocks": "숨겨진 도메인",
|
||||||
"navigation_bar.edit_profile": "프로필 편집",
|
"navigation_bar.edit_profile": "프로필 편집",
|
||||||
"navigation_bar.favourites": "즐겨찾기",
|
"navigation_bar.favourites": "즐겨찾기",
|
||||||
"navigation_bar.filters": "Muted words",
|
"navigation_bar.filters": "뮤트",
|
||||||
"navigation_bar.follow_requests": "팔로우 요청",
|
"navigation_bar.follow_requests": "팔로우 요청",
|
||||||
"navigation_bar.info": "이 인스턴스에 대해서",
|
"navigation_bar.info": "이 인스턴스에 대해서",
|
||||||
"navigation_bar.keyboard_shortcuts": "단축키",
|
"navigation_bar.keyboard_shortcuts": "단축키",
|
||||||
|
|
|
@ -129,11 +129,11 @@
|
||||||
"keyboard_shortcuts.boost": "para compartilhar",
|
"keyboard_shortcuts.boost": "para compartilhar",
|
||||||
"keyboard_shortcuts.column": "Focar um status em uma das colunas",
|
"keyboard_shortcuts.column": "Focar um status em uma das colunas",
|
||||||
"keyboard_shortcuts.compose": "para focar a área de redação",
|
"keyboard_shortcuts.compose": "para focar a área de redação",
|
||||||
"keyboard_shortcuts.description": "Description",
|
"keyboard_shortcuts.description": "Descrição",
|
||||||
"keyboard_shortcuts.down": "para mover para baixo na lista",
|
"keyboard_shortcuts.down": "para mover para baixo na lista",
|
||||||
"keyboard_shortcuts.enter": "to open status",
|
"keyboard_shortcuts.enter": "para expandir um status",
|
||||||
"keyboard_shortcuts.favourite": "para adicionar aos favoritos",
|
"keyboard_shortcuts.favourite": "para adicionar aos favoritos",
|
||||||
"keyboard_shortcuts.heading": "Keyboard Shortcuts",
|
"keyboard_shortcuts.heading": "Atalhos de teclado",
|
||||||
"keyboard_shortcuts.hotkey": "Atalho",
|
"keyboard_shortcuts.hotkey": "Atalho",
|
||||||
"keyboard_shortcuts.legend": "para mostrar essa legenda",
|
"keyboard_shortcuts.legend": "para mostrar essa legenda",
|
||||||
"keyboard_shortcuts.mention": "para mencionar o autor",
|
"keyboard_shortcuts.mention": "para mencionar o autor",
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
"compose_form.hashtag_warning": "ఈ టూట్ అన్లిస్టెడ్ కాబట్టి ఏ హాష్ ట్యాగ్ క్రిందకూ రాదు. పబ్లిక్ టూట్ లను మాత్రమే హాష్ ట్యాగ్ ద్వారా శోధించవచ్చు.",
|
"compose_form.hashtag_warning": "ఈ టూట్ అన్లిస్టెడ్ కాబట్టి ఏ హాష్ ట్యాగ్ క్రిందకూ రాదు. పబ్లిక్ టూట్ లను మాత్రమే హాష్ ట్యాగ్ ద్వారా శోధించవచ్చు.",
|
||||||
"compose_form.lock_disclaimer": "మీ ఖాతా {locked} చేయబడలేదు. ఎవరైనా మిమ్మల్ని అనుసరించి మీ అనుచరులకు-మాత్రమే పోస్ట్లను వీక్షించవచ్చు.",
|
"compose_form.lock_disclaimer": "మీ ఖాతా {locked} చేయబడలేదు. ఎవరైనా మిమ్మల్ని అనుసరించి మీ అనుచరులకు-మాత్రమే పోస్ట్లను వీక్షించవచ్చు.",
|
||||||
"compose_form.lock_disclaimer.lock": "బిగించబడినది",
|
"compose_form.lock_disclaimer.lock": "బిగించబడినది",
|
||||||
"compose_form.placeholder": "మీ మనస్సులో ఏమి ఉంది?",
|
"compose_form.placeholder": "మీ మనస్సులో ఏముంది?",
|
||||||
"compose_form.publish": "టూట్",
|
"compose_form.publish": "టూట్",
|
||||||
"compose_form.publish_loud": "{publish}!",
|
"compose_form.publish_loud": "{publish}!",
|
||||||
"compose_form.sensitive.marked": "మీడియా సున్నితమైనదిగా గుర్తించబడింది",
|
"compose_form.sensitive.marked": "మీడియా సున్నితమైనదిగా గుర్తించబడింది",
|
||||||
|
@ -115,7 +115,7 @@
|
||||||
"follow_request.authorize": "అనుమతించు",
|
"follow_request.authorize": "అనుమతించు",
|
||||||
"follow_request.reject": "తిరస్కరించు",
|
"follow_request.reject": "తిరస్కరించు",
|
||||||
"getting_started.developers": "డెవలపర్లు",
|
"getting_started.developers": "డెవలపర్లు",
|
||||||
"getting_started.documentation": "Documentation",
|
"getting_started.documentation": "డాక్యుమెంటేషన్",
|
||||||
"getting_started.find_friends": "ట్విట్టర్ నుండి స్నేహితులను కనుగొనండి",
|
"getting_started.find_friends": "ట్విట్టర్ నుండి స్నేహితులను కనుగొనండి",
|
||||||
"getting_started.heading": "మొదలుపెడదాం",
|
"getting_started.heading": "మొదలుపెడదాం",
|
||||||
"getting_started.invite": "వ్యక్తులను ఆహ్వానించండి",
|
"getting_started.invite": "వ్యక్తులను ఆహ్వానించండి",
|
||||||
|
@ -167,7 +167,7 @@
|
||||||
"navigation_bar.domain_blocks": "దాచిన డొమైన్లు",
|
"navigation_bar.domain_blocks": "దాచిన డొమైన్లు",
|
||||||
"navigation_bar.edit_profile": "ప్రొఫైల్ని సవరించండి",
|
"navigation_bar.edit_profile": "ప్రొఫైల్ని సవరించండి",
|
||||||
"navigation_bar.favourites": "ఇష్టపడినవి",
|
"navigation_bar.favourites": "ఇష్టపడినవి",
|
||||||
"navigation_bar.filters": "Muted words",
|
"navigation_bar.filters": "మ్యూట్ చేయబడిన పదాలు",
|
||||||
"navigation_bar.follow_requests": "అనుసరించడానికి అభ్యర్ధనలు",
|
"navigation_bar.follow_requests": "అనుసరించడానికి అభ్యర్ధనలు",
|
||||||
"navigation_bar.info": "ఈ దృష్టాంతం గురించి",
|
"navigation_bar.info": "ఈ దృష్టాంతం గురించి",
|
||||||
"navigation_bar.keyboard_shortcuts": "హాట్ కీలు",
|
"navigation_bar.keyboard_shortcuts": "హాట్ కీలు",
|
||||||
|
@ -258,7 +258,7 @@
|
||||||
"status.direct": "@{name}కు నేరుగా సందేశం పంపు",
|
"status.direct": "@{name}కు నేరుగా సందేశం పంపు",
|
||||||
"status.embed": "ఎంబెడ్",
|
"status.embed": "ఎంబెడ్",
|
||||||
"status.favourite": "ఇష్టపడు",
|
"status.favourite": "ఇష్టపడు",
|
||||||
"status.filtered": "Filtered",
|
"status.filtered": "వడకట్టబడిన",
|
||||||
"status.load_more": "మరిన్ని లోడ్ చేయి",
|
"status.load_more": "మరిన్ని లోడ్ చేయి",
|
||||||
"status.media_hidden": "మీడియా దాచబడింది",
|
"status.media_hidden": "మీడియా దాచబడింది",
|
||||||
"status.mention": "@{name}ను ప్రస్తావించు",
|
"status.mention": "@{name}ను ప్రస్తావించు",
|
||||||
|
|
|
@ -5,14 +5,16 @@ import { start } from '../mastodon/common';
|
||||||
start();
|
start();
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
const IntlRelativeFormat = require('intl-relativeformat').default;
|
const { length } = require('stringz');
|
||||||
|
const IntlMessageFormat = require('intl-messageformat').default;
|
||||||
|
const { timeAgoString } = require('../mastodon/components/relative_timestamp');
|
||||||
|
const { delegate } = require('rails-ujs');
|
||||||
const emojify = require('../mastodon/features/emoji/emoji').default;
|
const emojify = require('../mastodon/features/emoji/emoji').default;
|
||||||
const { getLocale } = require('../mastodon/locales');
|
const { getLocale } = require('../mastodon/locales');
|
||||||
const { localeData } = getLocale();
|
const { messages } = getLocale();
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
const ReactDOM = require('react-dom');
|
const ReactDOM = require('react-dom');
|
||||||
|
const Rellax = require('rellax');
|
||||||
localeData.forEach(IntlRelativeFormat.__addLocaleData);
|
|
||||||
|
|
||||||
ready(() => {
|
ready(() => {
|
||||||
const locale = document.documentElement.lang;
|
const locale = document.documentElement.lang;
|
||||||
|
@ -25,8 +27,6 @@ function main() {
|
||||||
minute: 'numeric',
|
minute: 'numeric',
|
||||||
});
|
});
|
||||||
|
|
||||||
const relativeFormat = new IntlRelativeFormat(locale);
|
|
||||||
|
|
||||||
[].forEach.call(document.querySelectorAll('.emojify'), (content) => {
|
[].forEach.call(document.querySelectorAll('.emojify'), (content) => {
|
||||||
content.innerHTML = emojify(content.innerHTML);
|
content.innerHTML = emojify(content.innerHTML);
|
||||||
});
|
});
|
||||||
|
@ -41,12 +41,16 @@ function main() {
|
||||||
|
|
||||||
[].forEach.call(document.querySelectorAll('time.time-ago'), (content) => {
|
[].forEach.call(document.querySelectorAll('time.time-ago'), (content) => {
|
||||||
const datetime = new Date(content.getAttribute('datetime'));
|
const datetime = new Date(content.getAttribute('datetime'));
|
||||||
|
const now = new Date();
|
||||||
|
|
||||||
content.title = dateTimeFormat.format(datetime);
|
content.title = dateTimeFormat.format(datetime);
|
||||||
content.textContent = relativeFormat.format(datetime);
|
content.textContent = timeAgoString({
|
||||||
|
formatMessage: ({ id, defaultMessage }, values) => (new IntlMessageFormat(messages[id] || defaultMessage, locale)).format(values),
|
||||||
|
formatDate: (date, options) => (new Intl.DateTimeFormat(locale, options)).format(date),
|
||||||
|
}, datetime, now, datetime.getFullYear());
|
||||||
});
|
});
|
||||||
|
|
||||||
[].forEach.call(document.querySelectorAll('.logo-button'), (content) => {
|
[].forEach.call(document.querySelectorAll('.modal-button'), (content) => {
|
||||||
content.addEventListener('click', (e) => {
|
content.addEventListener('click', (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
window.open(e.target.href, 'mastodon-intent', 'width=445,height=600,resizable=no,menubar=no,status=no,scrollbars=yes');
|
window.open(e.target.href, 'mastodon-intent', 'width=445,height=600,resizable=no,menubar=no,status=no,scrollbars=yes');
|
||||||
|
@ -64,6 +68,8 @@ function main() {
|
||||||
})
|
})
|
||||||
.catch(error => console.error(error));
|
.catch(error => console.error(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new Rellax('.parallax', { speed: -1 });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
@import 'mastodon/lists';
|
@import 'mastodon/lists';
|
||||||
@import 'mastodon/footer';
|
@import 'mastodon/footer';
|
||||||
@import 'mastodon/compact_header';
|
@import 'mastodon/compact_header';
|
||||||
@import 'mastodon/landing_strip';
|
@import 'mastodon/widgets';
|
||||||
@import 'mastodon/forms';
|
@import 'mastodon/forms';
|
||||||
@import 'mastodon/accounts';
|
@import 'mastodon/accounts';
|
||||||
@import 'mastodon/stream_entries';
|
@import 'mastodon/stream_entries';
|
||||||
|
|
|
@ -1115,6 +1115,21 @@ $small-breakpoint: 960px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.tag-page {
|
&.tag-page {
|
||||||
|
@media screen and (max-width: $column-breakpoint) {
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
.container {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mastodon-timeline {
|
||||||
|
display: block;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.grid {
|
.grid {
|
||||||
@media screen and (min-width: $small-breakpoint) {
|
@media screen and (min-width: $small-breakpoint) {
|
||||||
grid-template-columns: 33% 67%;
|
grid-template-columns: 33% 67%;
|
||||||
|
@ -1146,23 +1161,16 @@ $small-breakpoint: 960px;
|
||||||
|
|
||||||
@media screen and (max-width: $column-breakpoint) {
|
@media screen and (max-width: $column-breakpoint) {
|
||||||
.grid {
|
.grid {
|
||||||
.column-1 {
|
grid-gap: 0;
|
||||||
grid-column: 1;
|
|
||||||
grid-row: 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.column-2 {
|
.column-1 {
|
||||||
grid-column: 1;
|
grid-column: 1;
|
||||||
grid-row: 1;
|
grid-row: 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.brand {
|
.column-2 {
|
||||||
margin: 0;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.landing-page__features {
|
|
||||||
display: none;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,243 +1,100 @@
|
||||||
.card {
|
.card {
|
||||||
background-color: $base-shadow-color;
|
& > a {
|
||||||
background-size: cover;
|
|
||||||
background-position: center;
|
|
||||||
border-radius: 4px 4px 0 0;
|
|
||||||
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
|
||||||
overflow: hidden;
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
background: rgba(darken($ui-base-color, 8%), 0.5);
|
|
||||||
display: block;
|
display: block;
|
||||||
content: "";
|
text-decoration: none;
|
||||||
position: absolute;
|
color: inherit;
|
||||||
left: 0;
|
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||||
top: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 740px) {
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
border-radius: 0;
|
box-shadow: none;
|
||||||
box-shadow: none;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.card__illustration {
|
&:hover,
|
||||||
padding: 60px 0;
|
&:active,
|
||||||
position: relative;
|
&:focus {
|
||||||
flex: 1 1 auto;
|
.card__bar {
|
||||||
display: flex;
|
background: lighten($ui-base-color, 8%);
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card__bio {
|
|
||||||
max-width: 260px;
|
|
||||||
flex: 1 1 auto;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-between;
|
|
||||||
background: rgba(darken($ui-base-color, 8%), 0.8);
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.compact {
|
|
||||||
padding: 30px 0;
|
|
||||||
border-radius: 4px;
|
|
||||||
|
|
||||||
.avatar {
|
|
||||||
margin-bottom: 0;
|
|
||||||
|
|
||||||
img {
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.name {
|
&__img {
|
||||||
display: block;
|
height: 130px;
|
||||||
font-size: 20px;
|
|
||||||
line-height: 18px * 1.5;
|
|
||||||
color: $primary-text-color;
|
|
||||||
padding: 10px 15px;
|
|
||||||
padding-bottom: 0;
|
|
||||||
font-weight: 500;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 2;
|
background: darken($ui-base-color, 12%);
|
||||||
margin-bottom: 30px;
|
border-radius: 4px 4px 0 0;
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
|
|
||||||
small {
|
|
||||||
display: block;
|
|
||||||
font-size: 14px;
|
|
||||||
color: $highlight-text-color;
|
|
||||||
font-weight: 400;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
|
|
||||||
.fa {
|
|
||||||
margin-left: 3px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.avatar {
|
|
||||||
width: 120px;
|
|
||||||
margin: 0 auto;
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: 120px;
|
|
||||||
height: 120px;
|
|
||||||
display: block;
|
display: block;
|
||||||
border-radius: 120px;
|
|
||||||
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.roles {
|
|
||||||
margin-bottom: 30px;
|
|
||||||
padding: 0 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.details-counters {
|
|
||||||
margin-top: 30px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.counter {
|
|
||||||
width: 33.3%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
color: $darker-text-color;
|
|
||||||
padding: 5px 10px 0;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
border-right: 1px solid lighten($ui-base-color, 4%);
|
|
||||||
cursor: default;
|
|
||||||
text-align: center;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
a {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
border-right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
display: block;
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
bottom: -10px;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-bottom: 4px solid $ui-primary-color;
|
height: 100%;
|
||||||
opacity: 0.5;
|
margin: 0;
|
||||||
transition: all 400ms ease;
|
object-fit: cover;
|
||||||
|
border-radius: 4px 4px 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active {
|
@media screen and (max-width: 600px) {
|
||||||
&::after {
|
height: 200px;
|
||||||
border-bottom: 4px solid $highlight-text-color;
|
}
|
||||||
opacity: 1;
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__bar {
|
||||||
|
position: relative;
|
||||||
|
padding: 15px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
background: lighten($ui-base-color, 4%);
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
padding-top: 2px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: darken($ui-base-color, 8%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
.display-name {
|
||||||
&::after {
|
margin-left: 15px;
|
||||||
opacity: 1;
|
text-align: left;
|
||||||
transition-duration: 100ms;
|
|
||||||
|
strong {
|
||||||
|
font-size: 15px;
|
||||||
|
color: $primary-text-color;
|
||||||
|
font-weight: 500;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
span {
|
||||||
text-decoration: none;
|
display: block;
|
||||||
color: inherit;
|
font-size: 14px;
|
||||||
}
|
color: $darker-text-color;
|
||||||
|
|
||||||
.counter-label {
|
|
||||||
font-size: 12px;
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.counter-number {
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 18px;
|
|
||||||
color: $primary-text-color;
|
|
||||||
font-family: 'mastodon-font-display', sans-serif;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.bio {
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 18px;
|
|
||||||
padding: 0 15px;
|
|
||||||
color: $secondary-text-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 480px) {
|
|
||||||
display: block;
|
|
||||||
|
|
||||||
.card__bio {
|
|
||||||
max-width: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.name,
|
|
||||||
.roles {
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bio {
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.card,
|
|
||||||
.account-grid-card {
|
|
||||||
.controls {
|
|
||||||
position: absolute;
|
|
||||||
top: 15px;
|
|
||||||
left: 15px;
|
|
||||||
z-index: 2;
|
|
||||||
|
|
||||||
.icon-button {
|
|
||||||
color: rgba($white, 0.8);
|
|
||||||
text-decoration: none;
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 13px;
|
|
||||||
font-weight: 500;
|
|
||||||
|
|
||||||
.fa {
|
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
margin-right: 5px;
|
overflow: hidden;
|
||||||
}
|
text-overflow: ellipsis;
|
||||||
|
|
||||||
&:hover,
|
|
||||||
&:active,
|
|
||||||
&:focus {
|
|
||||||
color: $white;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.account-grid-card .controls {
|
|
||||||
left: auto;
|
|
||||||
right: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pagination {
|
.pagination {
|
||||||
padding: 30px 0;
|
padding: 30px 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -314,289 +171,23 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.accounts-grid {
|
|
||||||
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
|
||||||
background: darken($simple-background-color, 8%);
|
|
||||||
border-radius: 0 0 4px 4px;
|
|
||||||
padding: 20px 5px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
z-index: 2;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&.empty img {
|
|
||||||
position: absolute;
|
|
||||||
opacity: 0.2;
|
|
||||||
height: 200px;
|
|
||||||
left: 0;
|
|
||||||
bottom: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 740px) {
|
|
||||||
border-radius: 0;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.account-grid-card {
|
|
||||||
box-sizing: border-box;
|
|
||||||
width: 335px;
|
|
||||||
background: $simple-background-color;
|
|
||||||
border-radius: 4px;
|
|
||||||
color: $inverted-text-color;
|
|
||||||
margin: 0 5px 10px;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
@media screen and (max-width: 740px) {
|
|
||||||
width: calc(100% - 10px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.account-grid-card__header {
|
|
||||||
overflow: hidden;
|
|
||||||
height: 100px;
|
|
||||||
border-radius: 4px 4px 0 0;
|
|
||||||
background-color: lighten($inverted-text-color, 4%);
|
|
||||||
background-size: cover;
|
|
||||||
background-position: center;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
background: rgba(darken($ui-base-color, 8%), 0.5);
|
|
||||||
display: block;
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.account-grid-card__avatar {
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding: 15px;
|
|
||||||
position: absolute;
|
|
||||||
z-index: 2;
|
|
||||||
top: 100px - (40px + 2px);
|
|
||||||
left: -2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.avatar {
|
|
||||||
width: 80px;
|
|
||||||
height: 80px;
|
|
||||||
|
|
||||||
img {
|
|
||||||
display: block;
|
|
||||||
width: 80px;
|
|
||||||
height: 80px;
|
|
||||||
border-radius: 80px;
|
|
||||||
border: 2px solid $simple-background-color;
|
|
||||||
background: $simple-background-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.name {
|
|
||||||
padding: 15px;
|
|
||||||
padding-top: 10px;
|
|
||||||
padding-left: 15px + 80px + 15px;
|
|
||||||
|
|
||||||
a {
|
|
||||||
display: block;
|
|
||||||
color: $inverted-text-color;
|
|
||||||
text-decoration: none;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
font-weight: 500;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
.display_name {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.display_name {
|
|
||||||
font-size: 16px;
|
|
||||||
display: block;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.username {
|
|
||||||
color: $lighter-text-color;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
|
|
||||||
.account__header__content {
|
|
||||||
padding: 10px 15px;
|
|
||||||
padding-top: 15px;
|
|
||||||
color: $lighter-text-color;
|
|
||||||
word-wrap: break-word;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
height: 5.5em;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
display: block;
|
|
||||||
content: "";
|
|
||||||
width: 100%;
|
|
||||||
height: 100px;
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
background: linear-gradient(to bottom, rgba($simple-background-color, 0.01) 0%, rgba($simple-background-color, 1) 100%);
|
|
||||||
left: 0;
|
|
||||||
border-radius: 0 0 4px 4px;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.nothing-here {
|
.nothing-here {
|
||||||
width: 100%;
|
background: $ui-base-color;
|
||||||
display: block;
|
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||||
color: $light-text-color;
|
color: $light-text-color;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 130px 0;
|
display: flex;
|
||||||
padding-top: 125px;
|
justify-content: center;
|
||||||
margin: 0 auto;
|
align-items: center;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
|
||||||
|
|
||||||
.account-card {
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
text-align: left;
|
padding: 20px;
|
||||||
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
min-height: 30vh;
|
||||||
background: $simple-background-color;
|
|
||||||
|
|
||||||
&__header {
|
&--under-tabs {
|
||||||
background: $base-shadow-color;
|
border-radius: 0 0 4px 4px;
|
||||||
background-size: cover;
|
|
||||||
background-position: center center;
|
|
||||||
height: 90px;
|
|
||||||
border-radius: 4px 4px 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
& > .detailed-status__display-name {
|
|
||||||
display: block;
|
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 10px;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
& > div:first-child {
|
|
||||||
flex: 0 0 auto;
|
|
||||||
margin-right: 10px;
|
|
||||||
width: 48px;
|
|
||||||
height: 48px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.avatar {
|
|
||||||
display: block;
|
|
||||||
border-radius: 4px;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.display-name {
|
|
||||||
flex: 1 0 auto;
|
|
||||||
display: block;
|
|
||||||
max-width: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
cursor: default;
|
|
||||||
|
|
||||||
& > .detailed-status__display-name {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
strong {
|
|
||||||
font-weight: 500;
|
|
||||||
color: $ui-base-color;
|
|
||||||
|
|
||||||
@each $lang in $cjk-langs {
|
|
||||||
&:lang(#{$lang}) {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
font-size: 14px;
|
|
||||||
color: $light-text-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
.display-name {
|
|
||||||
strong {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.counter {
|
|
||||||
box-sizing: border-box;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
color: $light-text-color;
|
|
||||||
padding: 0 10px;
|
|
||||||
cursor: default;
|
|
||||||
text-align: center;
|
|
||||||
position: relative;
|
|
||||||
line-height: 24px;
|
|
||||||
|
|
||||||
.counter-label {
|
|
||||||
font-size: 12px;
|
|
||||||
display: block;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
.counter-number {
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 16px;
|
|
||||||
color: $inverted-text-color;
|
|
||||||
font-family: 'mastodon-font-display', sans-serif;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.activity-stream-tabs {
|
|
||||||
background: $simple-background-color;
|
|
||||||
border-bottom: 1px solid $ui-secondary-color;
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
|
|
||||||
a {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 15px;
|
|
||||||
text-decoration: none;
|
|
||||||
color: $highlight-text-color;
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-weight: 500;
|
|
||||||
|
|
||||||
&:hover,
|
|
||||||
&:active,
|
|
||||||
&:focus {
|
|
||||||
color: lighten($highlight-text-color, 8%);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
color: $inverted-text-color;
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -629,14 +220,14 @@
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 15px -15px -15px;
|
margin: 15px -15px -15px;
|
||||||
border: 0 none;
|
border: 0 none;
|
||||||
border-top: 1px solid lighten($ui-base-color, 4%);
|
border-top: 1px solid lighten($ui-base-color, 12%);
|
||||||
border-bottom: 1px solid lighten($ui-base-color, 4%);
|
border-bottom: 1px solid lighten($ui-base-color, 12%);
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
|
|
||||||
dl {
|
dl {
|
||||||
display: flex;
|
display: flex;
|
||||||
border-bottom: 1px solid lighten($ui-base-color, 4%);
|
border-bottom: 1px solid lighten($ui-base-color, 12%);
|
||||||
}
|
}
|
||||||
|
|
||||||
dt,
|
dt,
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
body {
|
body {
|
||||||
font-family: 'mastodon-font-sans-serif', sans-serif;
|
font-family: 'mastodon-font-sans-serif', sans-serif;
|
||||||
background: $ui-base-color;
|
background: darken($ui-base-color, 8%);
|
||||||
background-size: cover;
|
|
||||||
background-attachment: fixed;
|
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
color: $primary-text-color;
|
color: $primary-text-color;
|
||||||
padding-bottom: 20px;
|
|
||||||
text-rendering: optimizelegibility;
|
text-rendering: optimizelegibility;
|
||||||
font-feature-settings: "kern";
|
font-feature-settings: "kern";
|
||||||
text-size-adjust: none;
|
text-size-adjust: none;
|
||||||
|
@ -35,16 +32,24 @@ body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
background: $ui-base-color;
|
background: $ui-base-color;
|
||||||
|
|
||||||
|
&.with-modals--active {
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.about-body {
|
&.lighter {
|
||||||
background: darken($ui-base-color, 8%);
|
background: $ui-base-color;
|
||||||
padding-bottom: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.tag-body {
|
&.with-modals {
|
||||||
background: darken($ui-base-color, 8%);
|
overflow-x: hidden;
|
||||||
padding-bottom: 0;
|
overflow-y: scroll;
|
||||||
|
|
||||||
|
&--active {
|
||||||
|
overflow-y: hidden;
|
||||||
|
margin-right: 13px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.player {
|
&.player {
|
||||||
|
@ -52,7 +57,7 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
&.embed {
|
&.embed {
|
||||||
background: transparent;
|
background: lighten($ui-base-color, 4%);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
|
|
||||||
|
|
|
@ -946,6 +946,18 @@
|
||||||
background: lighten($ui-base-color, 4%);
|
background: lighten($ui-base-color, 4%);
|
||||||
padding: 14px 10px;
|
padding: 14px 10px;
|
||||||
|
|
||||||
|
&--flex {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-start;
|
||||||
|
|
||||||
|
.status__content,
|
||||||
|
.detailed-status__meta {
|
||||||
|
flex: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.status__content {
|
.status__content {
|
||||||
font-size: 19px;
|
font-size: 19px;
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
|
@ -1224,7 +1236,6 @@ a .account__avatar {
|
||||||
}
|
}
|
||||||
|
|
||||||
.account__action-bar-dropdown {
|
.account__action-bar-dropdown {
|
||||||
flex: 0 1 calc(50% - 140px);
|
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
|
||||||
.icon-button {
|
.icon-button {
|
||||||
|
@ -1256,9 +1267,9 @@ a .account__avatar {
|
||||||
.account__action-bar__tab {
|
.account__action-bar__tab {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
flex: 0 1 80px;
|
flex: 0 1 100%;
|
||||||
border-right: 1px solid lighten($ui-base-color, 8%);
|
border-right: 1px solid lighten($ui-base-color, 8%);
|
||||||
padding: 10px 5px;
|
padding: 10px 0;
|
||||||
|
|
||||||
& > span {
|
& > span {
|
||||||
display: block;
|
display: block;
|
||||||
|
|
|
@ -60,10 +60,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.media-standalone__body {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.account-header {
|
.account-header {
|
||||||
width: 400px;
|
width: 400px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
@ -118,3 +114,576 @@
|
||||||
margin-left: 8px;
|
margin-left: 8px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.public-layout {
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
padding-top: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 960px;
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
background: lighten($ui-base-color, 8%);
|
||||||
|
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||||
|
border-radius: 4px;
|
||||||
|
height: 48px;
|
||||||
|
margin: 10px 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: stretch;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
margin: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
z-index: 110;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
flex: 1 1 33.3%;
|
||||||
|
min-height: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-left {
|
||||||
|
display: flex;
|
||||||
|
align-items: stretch;
|
||||||
|
justify-content: flex-start;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-center {
|
||||||
|
display: flex;
|
||||||
|
align-items: stretch;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-right {
|
||||||
|
display: flex;
|
||||||
|
align-items: stretch;
|
||||||
|
justify-content: flex-end;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand {
|
||||||
|
display: block;
|
||||||
|
padding: 15px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
display: block;
|
||||||
|
height: 18px;
|
||||||
|
width: auto;
|
||||||
|
position: relative;
|
||||||
|
bottom: -2px;
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
background: lighten($ui-base-color, 12%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 1rem;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
text-decoration: none;
|
||||||
|
color: $darker-text-color;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
text-decoration: underline;
|
||||||
|
color: $primary-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-button {
|
||||||
|
background: lighten($ui-base-color, 16%);
|
||||||
|
margin: 8px;
|
||||||
|
margin-left: 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
text-decoration: none;
|
||||||
|
background: lighten($ui-base-color, 20%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$no-columns-breakpoint: 600px;
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
grid-gap: 10px;
|
||||||
|
grid-template-columns: minmax(300px, 3fr) minmax(298px, 1fr);
|
||||||
|
grid-auto-columns: 25%;
|
||||||
|
grid-auto-rows: max-content;
|
||||||
|
|
||||||
|
.column-0 {
|
||||||
|
grid-row: 1;
|
||||||
|
grid-column: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-1 {
|
||||||
|
grid-row: 1;
|
||||||
|
grid-column: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-columns-breakpoint) {
|
||||||
|
grid-template-columns: 100%;
|
||||||
|
grid-gap: 0;
|
||||||
|
|
||||||
|
.column-1 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-account-header {
|
||||||
|
overflow: hidden;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||||
|
|
||||||
|
&__image {
|
||||||
|
border-radius: 4px 4px 0 0;
|
||||||
|
overflow: hidden;
|
||||||
|
height: 300px;
|
||||||
|
position: relative;
|
||||||
|
background: darken($ui-base-color, 12%);
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
box-shadow: inset 0 -1px 1px 1px rgba($base-shadow-color, 0.15);
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
object-fit: cover;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
border-radius: 4px 4px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
margin-bottom: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
|
||||||
|
&__image::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__image,
|
||||||
|
&__image img {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__bar {
|
||||||
|
position: relative;
|
||||||
|
margin-top: -80px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
background: lighten($ui-base-color, 4%);
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 60px;
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
display: block;
|
||||||
|
width: 120px;
|
||||||
|
height: 120px;
|
||||||
|
padding-left: 20px - 4px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
|
||||||
|
img {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 4px solid lighten($ui-base-color, 4%);
|
||||||
|
background: darken($ui-base-color, 8%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
margin-top: 0;
|
||||||
|
background: lighten($ui-base-color, 4%);
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
padding: 5px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
padding: 7px 0;
|
||||||
|
padding-left: 10px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
border: 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 360px) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-columns-breakpoint) {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__tabs {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
margin-left: 20px;
|
||||||
|
|
||||||
|
&__name {
|
||||||
|
padding-top: 20px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 18px * 1.5;
|
||||||
|
color: $primary-text-color;
|
||||||
|
font-weight: 500;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
text-shadow: 1px 1px 1px $base-shadow-color;
|
||||||
|
|
||||||
|
small {
|
||||||
|
display: block;
|
||||||
|
font-size: 14px;
|
||||||
|
color: $primary-text-color;
|
||||||
|
font-weight: 400;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
margin-left: 15px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&__name {
|
||||||
|
padding-top: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 24px;
|
||||||
|
text-shadow: none;
|
||||||
|
|
||||||
|
small {
|
||||||
|
color: $darker-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__tabs {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: stretch;
|
||||||
|
height: 58px;
|
||||||
|
|
||||||
|
.details-counters {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
min-width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-columns-breakpoint) {
|
||||||
|
.details-counters {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.counter {
|
||||||
|
width: 33.3%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
color: $darker-text-color;
|
||||||
|
padding: 10px;
|
||||||
|
border-right: 1px solid lighten($ui-base-color, 4%);
|
||||||
|
cursor: default;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
display: block;
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
border-bottom: 4px solid $ui-primary-color;
|
||||||
|
opacity: 0.5;
|
||||||
|
transition: all 400ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
&::after {
|
||||||
|
border-bottom: 4px solid $highlight-text-color;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
&::after {
|
||||||
|
opacity: 1;
|
||||||
|
transition-duration: 100ms;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.counter-label {
|
||||||
|
font-size: 12px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.counter-number {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 18px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
color: $primary-text-color;
|
||||||
|
font-family: 'mastodon-font-display', sans-serif;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.spacer {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
height: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__buttons {
|
||||||
|
padding: 7px 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__extra {
|
||||||
|
display: none;
|
||||||
|
margin-top: 4px;
|
||||||
|
|
||||||
|
.public-account-bio {
|
||||||
|
border-radius: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
background: transparent;
|
||||||
|
margin: 0 -5px;
|
||||||
|
|
||||||
|
.account__header__fields {
|
||||||
|
border-top: 1px solid lighten($ui-base-color, 12%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.roles {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__links {
|
||||||
|
margin-top: -15px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: inline-block;
|
||||||
|
color: $darker-text-color;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 15px;
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-weight: 700;
|
||||||
|
color: $primary-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-columns-breakpoint) {
|
||||||
|
display: block;
|
||||||
|
flex: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.account__section-headline {
|
||||||
|
border-radius: 4px 4px 0 0;
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.detailed-status__meta {
|
||||||
|
margin-top: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-account-bio {
|
||||||
|
background: lighten($ui-base-color, 8%);
|
||||||
|
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
box-shadow: none;
|
||||||
|
margin-bottom: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account__header__fields {
|
||||||
|
margin: 0;
|
||||||
|
border-top: 0;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: lighten($ui-highlight-color, 8%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.account__header__content {
|
||||||
|
padding: 20px;
|
||||||
|
padding-bottom: 0;
|
||||||
|
color: $primary-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__extra,
|
||||||
|
.roles {
|
||||||
|
padding: 20px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.roles {
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.static-icon-button {
|
||||||
|
color: $action-button-color;
|
||||||
|
font-size: 18px;
|
||||||
|
|
||||||
|
& > span {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-grid {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
min-width: 100%;
|
||||||
|
margin: 0 -5px;
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
box-sizing: border-box;
|
||||||
|
flex: 1 0 auto;
|
||||||
|
width: 300px;
|
||||||
|
padding: 0 5px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
max-width: 33.333%;
|
||||||
|
|
||||||
|
@media screen and (max-width: 900px) {
|
||||||
|
max-width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
margin: 0;
|
||||||
|
border-top: 1px solid lighten($ui-base-color, 8%);
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
border-bottom: 1px solid lighten($ui-base-color, 8%);
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card__bar {
|
||||||
|
background: $ui-base-color;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:active,
|
||||||
|
&:focus {
|
||||||
|
background: lighten($ui-base-color, 4%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,39 +1,140 @@
|
||||||
.footer {
|
.public-layout {
|
||||||
text-align: center;
|
.footer {
|
||||||
margin-top: 30px;
|
text-align: left;
|
||||||
padding-bottom: 60px;
|
padding-top: 20px;
|
||||||
font-size: 12px;
|
padding-bottom: 60px;
|
||||||
color: $darker-text-color;
|
font-size: 12px;
|
||||||
|
color: lighten($ui-base-color, 34%);
|
||||||
|
|
||||||
.footer__domain {
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
font-weight: 500;
|
padding-left: 20px;
|
||||||
|
padding-right: 20px;
|
||||||
a {
|
|
||||||
color: inherit;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.powered-by,
|
.grid {
|
||||||
.single-user-login {
|
display: grid;
|
||||||
font-weight: 400;
|
grid-gap: 10px;
|
||||||
|
grid-template-columns: 1fr 1fr 2fr 1fr 1fr;
|
||||||
|
|
||||||
a {
|
.column-0 {
|
||||||
color: inherit;
|
grid-column: 1;
|
||||||
text-decoration: underline;
|
grid-row: 1;
|
||||||
font-weight: 500;
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
&:hover {
|
.column-1 {
|
||||||
|
grid-column: 2;
|
||||||
|
grid-row: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-2 {
|
||||||
|
grid-column: 3;
|
||||||
|
grid-row: 1;
|
||||||
|
min-width: 0;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
h4 a {
|
||||||
|
color: lighten($ui-base-color, 34%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-3 {
|
||||||
|
grid-column: 4;
|
||||||
|
grid-row: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-4 {
|
||||||
|
grid-column: 5;
|
||||||
|
grid-row: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 690px) {
|
||||||
|
grid-template-columns: 1fr 2fr 1fr;
|
||||||
|
|
||||||
|
.column-0,
|
||||||
|
.column-1 {
|
||||||
|
grid-column: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-1 {
|
||||||
|
grid-row: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-2 {
|
||||||
|
grid-column: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-3,
|
||||||
|
.column-4 {
|
||||||
|
grid-column: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-4 {
|
||||||
|
grid-row: 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
.column-1 {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
.column-0,
|
||||||
|
.column-1,
|
||||||
|
.column-3,
|
||||||
|
.column-4 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
ul a {
|
||||||
margin: 0 4px;
|
text-decoration: none;
|
||||||
position: relative;
|
color: lighten($ui-base-color, 34%);
|
||||||
bottom: -1px;
|
|
||||||
height: 18px;
|
&:hover,
|
||||||
vertical-align: top;
|
&:active,
|
||||||
|
&:focus {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand {
|
||||||
|
svg {
|
||||||
|
display: block;
|
||||||
|
height: 36px;
|
||||||
|
width: auto;
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
path {
|
||||||
|
fill: lighten($ui-base-color, 34%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
svg path {
|
||||||
|
fill: lighten($ui-base-color, 38%);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,111 +0,0 @@
|
||||||
.landing-strip,
|
|
||||||
.memoriam-strip {
|
|
||||||
background: rgba(darken($ui-base-color, 7%), 0.8);
|
|
||||||
color: $darker-text-color;
|
|
||||||
font-weight: 400;
|
|
||||||
padding: 14px;
|
|
||||||
border-radius: 4px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
strong,
|
|
||||||
a {
|
|
||||||
font-weight: 500;
|
|
||||||
|
|
||||||
@each $lang in $cjk-langs {
|
|
||||||
&:lang(#{$lang}) {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: inherit;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
margin-right: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 740px) {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.memoriam-strip {
|
|
||||||
background: rgba($base-shadow-color, 0.7);
|
|
||||||
}
|
|
||||||
|
|
||||||
.moved-strip {
|
|
||||||
padding: 14px;
|
|
||||||
border-radius: 4px;
|
|
||||||
background: rgba(darken($ui-base-color, 7%), 0.8);
|
|
||||||
color: $secondary-text-color;
|
|
||||||
font-weight: 400;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
|
|
||||||
strong,
|
|
||||||
a {
|
|
||||||
font-weight: 500;
|
|
||||||
|
|
||||||
@each $lang in $cjk-langs {
|
|
||||||
&:lang(#{$lang}) {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: inherit;
|
|
||||||
text-decoration: underline;
|
|
||||||
|
|
||||||
&.mention {
|
|
||||||
text-decoration: none;
|
|
||||||
|
|
||||||
span {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus,
|
|
||||||
&:hover,
|
|
||||||
&:active {
|
|
||||||
text-decoration: none;
|
|
||||||
|
|
||||||
span {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__message {
|
|
||||||
margin-bottom: 15px;
|
|
||||||
|
|
||||||
.fa {
|
|
||||||
margin-right: 5px;
|
|
||||||
color: $darker-text-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__card {
|
|
||||||
.detailed-status__display-avatar {
|
|
||||||
position: relative;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.detailed-status__display-name {
|
|
||||||
margin-bottom: 0;
|
|
||||||
text-decoration: none;
|
|
||||||
|
|
||||||
span {
|
|
||||||
color: $highlight-text-color;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,367 +1,145 @@
|
||||||
.activity-stream {
|
.activity-stream {
|
||||||
clear: both;
|
|
||||||
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
margin-bottom: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--headless {
|
||||||
|
border-radius: 0;
|
||||||
|
margin: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
|
||||||
|
.detailed-status,
|
||||||
|
.status {
|
||||||
|
border-radius: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
div[data-component] {
|
div[data-component] {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.entry {
|
.entry {
|
||||||
background: $simple-background-color;
|
background: $ui-base-color;
|
||||||
|
|
||||||
.detailed-status.light,
|
.detailed-status,
|
||||||
.status.light,
|
.status,
|
||||||
.more.light {
|
.load-more {
|
||||||
border-bottom: 1px solid $ui-secondary-color;
|
|
||||||
animation: none;
|
animation: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
&,
|
.detailed-status,
|
||||||
.detailed-status.light,
|
.status {
|
||||||
.status.light {
|
|
||||||
border-bottom: 0;
|
border-bottom: 0;
|
||||||
border-radius: 0 0 4px 4px;
|
border-radius: 0 0 4px 4px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:first-child {
|
&:first-child {
|
||||||
&,
|
.detailed-status,
|
||||||
.detailed-status.light,
|
.status {
|
||||||
.status.light {
|
|
||||||
border-radius: 4px 4px 0 0;
|
border-radius: 4px 4px 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
&,
|
.detailed-status,
|
||||||
.detailed-status.light,
|
.status {
|
||||||
.status.light {
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 740px) {
|
@media screen and (max-width: 740px) {
|
||||||
&,
|
.detailed-status,
|
||||||
.detailed-status.light,
|
.status {
|
||||||
.status.light {
|
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.with-header {
|
.button.logo-button {
|
||||||
.entry {
|
flex: 0 auto;
|
||||||
&:first-child {
|
font-size: 14px;
|
||||||
&,
|
background: $ui-highlight-color;
|
||||||
.detailed-status.light,
|
color: $primary-text-color;
|
||||||
.status.light {
|
text-transform: none;
|
||||||
border-radius: 0;
|
line-height: 36px;
|
||||||
}
|
height: auto;
|
||||||
|
padding: 3px 15px;
|
||||||
|
border: 0;
|
||||||
|
|
||||||
&:last-child {
|
svg {
|
||||||
&,
|
width: 20px;
|
||||||
.detailed-status.light,
|
height: auto;
|
||||||
.status.light {
|
vertical-align: middle;
|
||||||
border-radius: 0 0 4px 4px;
|
margin-right: 5px;
|
||||||
}
|
|
||||||
}
|
path:first-child {
|
||||||
}
|
fill: $primary-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
path:last-child {
|
||||||
|
fill: $ui-highlight-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.media-gallery__gifv__label {
|
&:active,
|
||||||
bottom: 9px;
|
&:focus,
|
||||||
}
|
&:hover {
|
||||||
|
background: lighten($ui-highlight-color, 10%);
|
||||||
|
|
||||||
.status.light {
|
svg path:last-child {
|
||||||
padding: 14px 14px 14px (48px + 14px * 2);
|
fill: lighten($ui-highlight-color, 10%);
|
||||||
position: relative;
|
|
||||||
min-height: 48px;
|
|
||||||
cursor: default;
|
|
||||||
|
|
||||||
.status__header {
|
|
||||||
font-size: 15px;
|
|
||||||
|
|
||||||
.status__meta {
|
|
||||||
float: right;
|
|
||||||
font-size: 14px;
|
|
||||||
|
|
||||||
.status__relative-time {
|
|
||||||
color: $lighter-text-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.status__display-name {
|
|
||||||
display: block;
|
|
||||||
max-width: 100%;
|
|
||||||
padding-right: 25px;
|
|
||||||
color: $inverted-text-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status__avatar {
|
|
||||||
position: absolute;
|
|
||||||
left: 14px;
|
|
||||||
top: 14px;
|
|
||||||
width: 48px;
|
|
||||||
height: 48px;
|
|
||||||
|
|
||||||
& > div {
|
|
||||||
width: 48px;
|
|
||||||
height: 48px;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
display: block;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.display-name {
|
|
||||||
display: block;
|
|
||||||
max-width: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
|
|
||||||
strong {
|
|
||||||
font-weight: 500;
|
|
||||||
color: $inverted-text-color;
|
|
||||||
|
|
||||||
@each $lang in $cjk-langs {
|
|
||||||
&:lang(#{$lang}) {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
font-size: 14px;
|
|
||||||
color: $light-text-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.status__content {
|
|
||||||
color: $inverted-text-color;
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: $highlight-text-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
a.status__content__spoiler-link {
|
|
||||||
color: $primary-text-color;
|
|
||||||
background: $ui-base-color;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: lighten($ui-base-color, 8%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.detailed-status.light {
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
padding: 14px;
|
svg {
|
||||||
background: $simple-background-color;
|
display: none;
|
||||||
cursor: default;
|
|
||||||
|
|
||||||
.detailed-status__display-name {
|
|
||||||
display: block;
|
|
||||||
overflow: hidden;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
|
|
||||||
& > div {
|
|
||||||
float: left;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.display-name {
|
|
||||||
display: block;
|
|
||||||
max-width: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
|
|
||||||
strong {
|
|
||||||
font-weight: 500;
|
|
||||||
color: $inverted-text-color;
|
|
||||||
|
|
||||||
@each $lang in $cjk-langs {
|
|
||||||
&:lang(#{$lang}) {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
font-size: 14px;
|
|
||||||
color: $light-text-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.avatar {
|
|
||||||
width: 48px;
|
|
||||||
height: 48px;
|
|
||||||
|
|
||||||
img {
|
|
||||||
display: block;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.status__content {
|
|
||||||
color: $inverted-text-color;
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: $highlight-text-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
a.status__content__spoiler-link {
|
|
||||||
color: $primary-text-color;
|
|
||||||
background: $ui-base-color;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: lighten($ui-base-color, 8%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.detailed-status__meta {
|
|
||||||
margin-top: 15px;
|
|
||||||
color: $light-text-color;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 18px;
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
span > span {
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 12px;
|
|
||||||
margin-left: 6px;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-card {
|
|
||||||
border-color: lighten($ui-secondary-color, 4%);
|
|
||||||
color: $lighter-text-color;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: lighten($ui-secondary-color, 4%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-card__title,
|
|
||||||
.status-card__description {
|
|
||||||
color: $inverted-text-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-card__image {
|
|
||||||
background: $ui-secondary-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.media-spoiler {
|
|
||||||
background: $ui-base-color;
|
|
||||||
color: $darker-text-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pre-header {
|
|
||||||
padding: 14px 0;
|
|
||||||
padding-left: (48px + 14px * 2);
|
|
||||||
padding-bottom: 0;
|
|
||||||
margin-bottom: -4px;
|
|
||||||
color: $light-text-color;
|
|
||||||
font-size: 14px;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.pre-header__icon {
|
|
||||||
position: absolute;
|
|
||||||
left: (48px + 14px * 2 - 30px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.status__display-name.muted strong {
|
|
||||||
color: $light-text-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.open-in-web-link {
|
|
||||||
text-decoration: none;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.more {
|
|
||||||
color: $darker-text-color;
|
|
||||||
display: block;
|
|
||||||
padding: 14px;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
&:not(:hover) {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.embed {
|
.embed,
|
||||||
.activity-stream {
|
.public-layout {
|
||||||
box-shadow: none;
|
.detailed-status {
|
||||||
|
padding: 15px;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.entry {
|
.status {
|
||||||
.detailed-status.light {
|
padding: 15px 15px 15px (48px + 15px * 2);
|
||||||
display: flex;
|
min-height: 48px + 2px;
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: flex-start;
|
|
||||||
|
|
||||||
.detailed-status__display-name {
|
&__avatar {
|
||||||
flex: 1;
|
left: 15px;
|
||||||
margin: 0 5px 15px 0;
|
top: 17px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button.button-secondary.logo-button {
|
&__content {
|
||||||
flex: 0 auto;
|
padding-top: 5px;
|
||||||
font-size: 14px;
|
|
||||||
background: $ui-highlight-color;
|
|
||||||
color: $primary-text-color;
|
|
||||||
border: 0;
|
|
||||||
|
|
||||||
svg {
|
|
||||||
width: 20px;
|
|
||||||
height: auto;
|
|
||||||
vertical-align: middle;
|
|
||||||
margin-right: 5px;
|
|
||||||
|
|
||||||
path:first-child {
|
|
||||||
fill: $primary-text-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
path:last-child {
|
|
||||||
fill: $ui-highlight-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active,
|
|
||||||
&:focus,
|
|
||||||
&:hover {
|
|
||||||
background: lighten($ui-highlight-color, 10%);
|
|
||||||
|
|
||||||
svg path:last-child {
|
|
||||||
fill: lighten($ui-highlight-color, 10%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.status__content,
|
&__prepend {
|
||||||
.detailed-status__meta {
|
margin-left: 48px + 15px * 2;
|
||||||
flex: 100%;
|
padding-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__prepend-icon-wrapper {
|
||||||
|
left: -32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-gallery,
|
||||||
|
&__action-bar,
|
||||||
|
.video-player {
|
||||||
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,3 +46,5 @@ $cjk-langs: ja, ko, zh-CN, zh-HK, zh-TW;
|
||||||
$media-modal-media-max-width: 100%;
|
$media-modal-media-max-width: 100%;
|
||||||
// put margins on top and bottom of image to avoid the screen covered by image.
|
// put margins on top and bottom of image to avoid the screen covered by image.
|
||||||
$media-modal-media-max-height: 80%;
|
$media-modal-media-max-height: 80%;
|
||||||
|
|
||||||
|
$no-gap-breakpoint: 415px;
|
||||||
|
|
161
app/javascript/styles/mastodon/widgets.scss
Normal file
161
app/javascript/styles/mastodon/widgets.scss
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
.hero-widget {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||||
|
|
||||||
|
&__img {
|
||||||
|
width: 100%;
|
||||||
|
height: 167px;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 4px 4px 0 0;
|
||||||
|
background: $base-shadow-color;
|
||||||
|
|
||||||
|
img {
|
||||||
|
object-fit: cover;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
border-radius: 4px 4px 0 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
background: $ui-base-color;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
font-size: 15px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
line-height: 20px;
|
||||||
|
word-wrap: break-word;
|
||||||
|
font-weight: 400;
|
||||||
|
|
||||||
|
.emojione {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
margin: -3px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
em {
|
||||||
|
display: inline;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-weight: 700;
|
||||||
|
background: transparent;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
color: lighten($darker-text-color, 10%);
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $secondary-text-color;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.moved-account-widget {
|
||||||
|
padding: 15px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: $ui-base-color;
|
||||||
|
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||||
|
color: $secondary-text-color;
|
||||||
|
font-weight: 400;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
strong,
|
||||||
|
a {
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
@each $lang in $cjk-langs {
|
||||||
|
&:lang(#{$lang}) {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: underline;
|
||||||
|
|
||||||
|
&.mention {
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
span {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus,
|
||||||
|
&:hover,
|
||||||
|
&:active {
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
span {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__message {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
|
||||||
|
.fa {
|
||||||
|
margin-right: 5px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__card {
|
||||||
|
.detailed-status__display-avatar {
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detailed-status__display-name {
|
||||||
|
margin-bottom: 0;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.memoriam-widget {
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: $base-shadow-color;
|
||||||
|
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||||
|
font-size: 14px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.moved-account-widget,
|
||||||
|
.memoriam-widget {
|
||||||
|
@media screen and (max-width: $no-gap-breakpoint) {
|
||||||
|
margin-bottom: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,7 +9,7 @@ class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base
|
||||||
{
|
{
|
||||||
'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers',
|
'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers',
|
||||||
'sensitive' => 'as:sensitive',
|
'sensitive' => 'as:sensitive',
|
||||||
'movedTo' => 'as:movedTo',
|
'movedTo' => { '@id' => 'as:movedTo', '@type' => '@id' },
|
||||||
'Hashtag' => 'as:Hashtag',
|
'Hashtag' => 'as:Hashtag',
|
||||||
'ostatus' => 'http://ostatus.org#',
|
'ostatus' => 'http://ostatus.org#',
|
||||||
'atomUri' => 'ostatus:atomUri',
|
'atomUri' => 'ostatus:atomUri',
|
||||||
|
@ -18,7 +18,7 @@ class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base
|
||||||
'toot' => 'http://joinmastodon.org/ns#',
|
'toot' => 'http://joinmastodon.org/ns#',
|
||||||
'Emoji' => 'toot:Emoji',
|
'Emoji' => 'toot:Emoji',
|
||||||
'focalPoint' => { '@container' => '@list', '@id' => 'toot:focalPoint' },
|
'focalPoint' => { '@container' => '@list', '@id' => 'toot:focalPoint' },
|
||||||
'featured' => 'toot:featured',
|
'featured' => { '@id' => 'toot:featured', '@type' => '@id' },
|
||||||
'schema' => 'http://schema.org#',
|
'schema' => 'http://schema.org#',
|
||||||
'PropertyValue' => 'schema:PropertyValue',
|
'PropertyValue' => 'schema:PropertyValue',
|
||||||
'value' => 'schema:value',
|
'value' => 'schema:value',
|
||||||
|
|
|
@ -70,6 +70,7 @@ class Account < ApplicationRecord
|
||||||
|
|
||||||
# Remote user validations
|
# Remote user validations
|
||||||
validates :username, uniqueness: { scope: :domain, case_sensitive: true }, if: -> { !local? && will_save_change_to_username? }
|
validates :username, uniqueness: { scope: :domain, case_sensitive: true }, if: -> { !local? && will_save_change_to_username? }
|
||||||
|
validates :username, format: { with: /\A#{USERNAME_RE}\z/i }, if: -> { !local? && will_save_change_to_username? }
|
||||||
|
|
||||||
# Local user validations
|
# Local user validations
|
||||||
validates :username, format: { with: /\A[a-z0-9_]+\z/i }, length: { maximum: 30 }, if: -> { local? && will_save_change_to_username? }
|
validates :username, format: { with: /\A[a-z0-9_]+\z/i }, length: { maximum: 30 }, if: -> { local? && will_save_change_to_username? }
|
||||||
|
|
|
@ -5,11 +5,12 @@ module AccountHeader
|
||||||
|
|
||||||
IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif'].freeze
|
IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif'].freeze
|
||||||
LIMIT = 2.megabytes
|
LIMIT = 2.megabytes
|
||||||
|
MAX_PIXELS = 750_000 # 1500x500px
|
||||||
|
|
||||||
class_methods do
|
class_methods do
|
||||||
def header_styles(file)
|
def header_styles(file)
|
||||||
styles = { original: { geometry: '700x335#', file_geometry_parser: FastGeometryParser } }
|
styles = { original: { pixels: MAX_PIXELS, file_geometry_parser: FastGeometryParser } }
|
||||||
styles[:static] = { geometry: '700x335#', format: 'png', convert_options: '-coalesce', file_geometry_parser: FastGeometryParser } if file.content_type == 'image/gif'
|
styles[:static] = { format: 'png', convert_options: '-coalesce', file_geometry_parser: FastGeometryParser } if file.content_type == 'image/gif'
|
||||||
styles
|
styles
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -25,12 +25,13 @@ class MediaAttachment < ApplicationRecord
|
||||||
enum type: [:image, :gifv, :video, :audio, :unknown]
|
enum type: [:image, :gifv, :video, :audio, :unknown]
|
||||||
|
|
||||||
IMAGE_FILE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif'].freeze
|
IMAGE_FILE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif'].freeze
|
||||||
VIDEO_FILE_EXTENSIONS = ['.webm', '.mp4', '.m4v'].freeze
|
VIDEO_FILE_EXTENSIONS = ['.webm', '.mp4', '.m4v', '.mov'].freeze
|
||||||
AUDIO_FILE_EXTENSIONS = ['.mp3', '.m4a', '.wav', '.ogg'].freeze
|
AUDIO_FILE_EXTENSIONS = ['.mp3', '.m4a', '.wav', '.ogg'].freeze
|
||||||
|
|
||||||
IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif'].freeze
|
IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif'].freeze
|
||||||
VIDEO_MIME_TYPES = ['video/webm', 'video/mp4'].freeze
|
VIDEO_MIME_TYPES = ['video/webm', 'video/mp4', 'video/quicktime'].freeze
|
||||||
AUDIO_MIME_TYPES = ['audio/mpeg', 'audio/mp4', 'audio/vnd.wav', 'audio/wav', 'audio/x-wav', 'audio/x-wave', 'audio/ogg',].freeze
|
VIDEO_CONVERTIBLE_MIME_TYPES = ['video/webm', 'video/quicktime'].freeze
|
||||||
|
AUDIO_MIME_TYPES = ['audio/mpeg', 'audio/mp4', 'audio/vnd.wav', 'audio/wav', 'audio/x-wav', 'audio/x-wave', 'audio/ogg',].freeze
|
||||||
|
|
||||||
IMAGE_STYLES = {
|
IMAGE_STYLES = {
|
||||||
original: {
|
original: {
|
||||||
|
@ -72,7 +73,25 @@ class MediaAttachment < ApplicationRecord
|
||||||
},
|
},
|
||||||
}.freeze
|
}.freeze
|
||||||
|
|
||||||
LIMIT = 8.megabytes
|
VIDEO_FORMAT = {
|
||||||
|
format: 'mp4',
|
||||||
|
convert_options: {
|
||||||
|
output: {
|
||||||
|
'movflags' => 'faststart',
|
||||||
|
'pix_fmt' => 'yuv420p',
|
||||||
|
'vf' => 'scale=\'trunc(iw/2)*2:trunc(ih/2)*2\'',
|
||||||
|
'vsync' => 'cfr',
|
||||||
|
'c:v' => 'h264',
|
||||||
|
'b:v' => '500K',
|
||||||
|
'maxrate' => '1300K',
|
||||||
|
'bufsize' => '1300K',
|
||||||
|
'crf' => 18,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}.freeze
|
||||||
|
|
||||||
|
IMAGE_LIMIT = 8.megabytes
|
||||||
|
VIDEO_LIMIT = 40.megabytes
|
||||||
|
|
||||||
belongs_to :account, inverse_of: :media_attachments, optional: true
|
belongs_to :account, inverse_of: :media_attachments, optional: true
|
||||||
belongs_to :status, inverse_of: :media_attachments, optional: true
|
belongs_to :status, inverse_of: :media_attachments, optional: true
|
||||||
|
@ -82,11 +101,10 @@ class MediaAttachment < ApplicationRecord
|
||||||
processors: ->(f) { file_processors f },
|
processors: ->(f) { file_processors f },
|
||||||
convert_options: { all: '-quality 90 -strip' }
|
convert_options: { all: '-quality 90 -strip' }
|
||||||
|
|
||||||
include Remotable
|
|
||||||
|
|
||||||
validates_attachment_content_type :file, content_type: IMAGE_MIME_TYPES + VIDEO_MIME_TYPES + AUDIO_MIME_TYPES
|
validates_attachment_content_type :file, content_type: IMAGE_MIME_TYPES + VIDEO_MIME_TYPES + AUDIO_MIME_TYPES
|
||||||
validates_attachment_size :file, less_than: LIMIT
|
validates_attachment_size :file, less_than: IMAGE_LIMIT, unless: :video?
|
||||||
remotable_attachment :file, LIMIT
|
validates_attachment_size :file, less_than: VIDEO_LIMIT, if: :video?
|
||||||
|
remotable_attachment :file, VIDEO_LIMIT
|
||||||
|
|
||||||
include Attachmentable
|
include Attachmentable
|
||||||
|
|
||||||
|
@ -142,27 +160,17 @@ class MediaAttachment < ApplicationRecord
|
||||||
if f.instance.file_content_type == 'image/gif'
|
if f.instance.file_content_type == 'image/gif'
|
||||||
{
|
{
|
||||||
small: IMAGE_STYLES[:small],
|
small: IMAGE_STYLES[:small],
|
||||||
original: {
|
original: VIDEO_FORMAT,
|
||||||
format: 'mp4',
|
|
||||||
convert_options: {
|
|
||||||
output: {
|
|
||||||
'movflags' => 'faststart',
|
|
||||||
'pix_fmt' => 'yuv420p',
|
|
||||||
'vf' => 'scale=\'trunc(iw/2)*2:trunc(ih/2)*2\'',
|
|
||||||
'vsync' => 'cfr',
|
|
||||||
'c:v' => 'h264',
|
|
||||||
'b:v' => '500K',
|
|
||||||
'maxrate' => '1300K',
|
|
||||||
'bufsize' => '1300K',
|
|
||||||
'crf' => 18,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
elsif IMAGE_MIME_TYPES.include? f.instance.file_content_type
|
elsif IMAGE_MIME_TYPES.include? f.instance.file_content_type
|
||||||
IMAGE_STYLES
|
IMAGE_STYLES
|
||||||
elsif AUDIO_MIME_TYPES.include? f.instance.file_content_type
|
elsif AUDIO_MIME_TYPES.include? f.instance.file_content_type
|
||||||
AUDIO_STYLES
|
AUDIO_STYLES
|
||||||
|
elsif VIDEO_CONVERTIBLE_MIME_TYPES.include?(f.instance.file_content_type)
|
||||||
|
{
|
||||||
|
small: VIDEO_STYLES[:small],
|
||||||
|
original: VIDEO_FORMAT,
|
||||||
|
}
|
||||||
else
|
else
|
||||||
VIDEO_STYLES
|
VIDEO_STYLES
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,14 +7,14 @@ class ActivityPub::FetchRemoteAccountService < BaseService
|
||||||
|
|
||||||
# Should be called when uri has already been checked for locality
|
# Should be called when uri has already been checked for locality
|
||||||
# Does a WebFinger roundtrip on each call
|
# Does a WebFinger roundtrip on each call
|
||||||
def call(uri, id: true, prefetched_body: nil)
|
def call(uri, id: true, prefetched_body: nil, break_on_redirect: false)
|
||||||
@json = if prefetched_body.nil?
|
@json = if prefetched_body.nil?
|
||||||
fetch_resource(uri, id)
|
fetch_resource(uri, id)
|
||||||
else
|
else
|
||||||
body_to_json(prefetched_body)
|
body_to_json(prefetched_body)
|
||||||
end
|
end
|
||||||
|
|
||||||
return unless supported_context? && expected_type?
|
return if !supported_context? || !expected_type? || (break_on_redirect && @json['movedTo'].present?)
|
||||||
|
|
||||||
@uri = @json['id']
|
@uri = @json['id']
|
||||||
@username = @json['preferredUsername']
|
@username = @json['preferredUsername']
|
||||||
|
|
|
@ -175,7 +175,7 @@ class ActivityPub::ProcessAccountService < BaseService
|
||||||
|
|
||||||
def moved_account
|
def moved_account
|
||||||
account = ActivityPub::TagManager.instance.uri_to_resource(@json['movedTo'], Account)
|
account = ActivityPub::TagManager.instance.uri_to_resource(@json['movedTo'], Account)
|
||||||
account ||= ActivityPub::FetchRemoteAccountService.new.call(@json['movedTo'], id: true)
|
account ||= ActivityPub::FetchRemoteAccountService.new.call(@json['movedTo'], id: true, break_on_redirect: true)
|
||||||
account
|
account
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
15
app/views/accounts/_bio.html.haml
Normal file
15
app/views/accounts/_bio.html.haml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
.public-account-bio
|
||||||
|
- unless account.fields.empty?
|
||||||
|
.account__header__fields
|
||||||
|
- account.fields.each do |field|
|
||||||
|
%dl
|
||||||
|
%dt.emojify{ title: field.name }= field.name
|
||||||
|
%dd.emojify{ title: field.value }= Formatter.instance.format_field(account, field.value, custom_emojify: true)
|
||||||
|
|
||||||
|
= account_badge(account)
|
||||||
|
|
||||||
|
- if account.note.present?
|
||||||
|
.account__header__content.emojify= Formatter.instance.simplified_format(account, custom_emojify: true)
|
||||||
|
|
||||||
|
.public-account-bio__extra
|
||||||
|
= t 'accounts.joined', date: l(account.created_at, format: :month)
|
|
@ -1,28 +0,0 @@
|
||||||
- relationships ||= nil
|
|
||||||
|
|
||||||
- unless account.memorial? || account.moved?
|
|
||||||
- if user_signed_in?
|
|
||||||
- requested = relationships ? relationships.requested[account.id].present? : current_account.requested?(account)
|
|
||||||
- following = relationships ? relationships.following[account.id].present? : current_account.following?(account)
|
|
||||||
|
|
||||||
- if user_signed_in? && current_account.id != account.id && !requested
|
|
||||||
.controls
|
|
||||||
- if following
|
|
||||||
= link_to (account.local? ? account_unfollow_path(account) : remote_unfollow_path(acct: account.acct)), data: { method: :post }, class: 'icon-button' do
|
|
||||||
= fa_icon 'user-times'
|
|
||||||
= t('accounts.unfollow')
|
|
||||||
- else
|
|
||||||
= link_to (account.local? ? account_follow_path(account) : authorize_follow_path(acct: account.acct)), data: { method: :post }, class: 'icon-button' do
|
|
||||||
= fa_icon 'user-plus'
|
|
||||||
= t('accounts.follow')
|
|
||||||
- elsif user_signed_in? && current_account.id == account.id
|
|
||||||
.controls
|
|
||||||
= link_to settings_profile_url, class: 'icon-button' do
|
|
||||||
= fa_icon 'pencil'
|
|
||||||
= t('settings.edit_profile')
|
|
||||||
- elsif !user_signed_in?
|
|
||||||
.controls
|
|
||||||
.remote-follow
|
|
||||||
= link_to (account.local? ? account_remote_follow_path(account) : "web+mastodon://follow?uri=#{account.uri}"), class: 'icon-button' do
|
|
||||||
= fa_icon 'user-plus'
|
|
||||||
= t('accounts.remote_follow')
|
|
|
@ -1,8 +0,0 @@
|
||||||
.accounts-grid{ class: accounts.empty? ? 'empty' : '' }
|
|
||||||
- if accounts.empty?
|
|
||||||
= image_tag asset_pack_path('elephant_ui_greeting.svg'), alt: '', role: 'presentational'
|
|
||||||
= render partial: 'accounts/nothing_here'
|
|
||||||
- else
|
|
||||||
= render partial: 'accounts/grid_card', collection: accounts, as: :account, cached: !user_signed_in?
|
|
||||||
|
|
||||||
= paginate follows
|
|
|
@ -1,3 +0,0 @@
|
||||||
.accounts-grid.empty
|
|
||||||
= image_tag asset_pack_path('elephant_ui_greeting.svg'), alt: '', role: 'presentational'
|
|
||||||
%p.nothing-here= t('accounts.network_hidden')
|
|
|
@ -1,12 +0,0 @@
|
||||||
.account-grid-card
|
|
||||||
.account-grid-card__header{ style: "background-image: url(#{account.header.url(:original)})" }
|
|
||||||
= render 'accounts/follow_button', account: account, relationships: @relationships
|
|
||||||
.account-grid-card__avatar
|
|
||||||
.avatar= image_tag account.avatar.url(:original)
|
|
||||||
.name
|
|
||||||
= link_to TagManager.instance.url_for(account) do
|
|
||||||
%span.display_name.emojify= display_name(account, custom_emojify: true)
|
|
||||||
%span.username
|
|
||||||
@#{account.local? ? account.local_username_and_domain : account.acct}
|
|
||||||
= fa_icon('lock') if account.locked?
|
|
||||||
.account__header__content.p-note.emojify= Formatter.instance.simplified_format(account)
|
|
|
@ -1,51 +1,43 @@
|
||||||
.card.h-card.p-author{ style: "background-image: url(#{account.header.url(:original)})" }
|
.public-account-header
|
||||||
.card__illustration
|
.public-account-header__image
|
||||||
= render 'accounts/follow_button', account: account
|
= image_tag account.header.url, class: 'parallax'
|
||||||
.avatar= image_tag account.avatar.url(:original), class: 'u-photo'
|
.public-account-header__bar
|
||||||
|
= link_to short_account_url(account), class: 'avatar' do
|
||||||
|
= image_tag account.avatar.url
|
||||||
|
.public-account-header__tabs
|
||||||
|
.public-account-header__tabs__name
|
||||||
|
%h1
|
||||||
|
= display_name(account)
|
||||||
|
%small
|
||||||
|
= acct(account)
|
||||||
|
= fa_icon('lock') if account.locked?
|
||||||
|
.public-account-header__tabs__tabs
|
||||||
|
.details-counters
|
||||||
|
.counter{ class: active_nav_class(short_account_url(account)) }
|
||||||
|
= link_to short_account_url(account), class: 'u-url u-uid' do
|
||||||
|
%span.counter-number= number_to_human account.statuses_count, strip_insignificant_zeros: true
|
||||||
|
%span.counter-label= t('accounts.posts')
|
||||||
|
|
||||||
.card__bio
|
.counter{ class: active_nav_class(account_following_index_url(account)) }
|
||||||
%h1.name
|
= link_to account_following_index_url(account) do
|
||||||
%span.p-name.emojify= display_name(account, custom_emojify: true)
|
%span.counter-number= number_to_human account.following_count, strip_insignificant_zeros: true
|
||||||
%small<
|
%span.counter-label= t('accounts.following')
|
||||||
%span>< @#{account.local_username_and_domain}
|
|
||||||
= fa_icon('lock') if account.locked?
|
|
||||||
|
|
||||||
- if account.bot?
|
.counter{ class: active_nav_class(account_followers_url(account)) }
|
||||||
.roles
|
= link_to account_followers_url(account) do
|
||||||
.account-role.bot
|
%span.counter-number= number_to_human account.followers_count, strip_insignificant_zeros: true
|
||||||
= t 'accounts.roles.bot'
|
%span.counter-label= t('accounts.followers')
|
||||||
- elsif Setting.show_staff_badge
|
.spacer
|
||||||
- if account.user_admin?
|
.public-account-header__tabs__tabs__buttons
|
||||||
.roles
|
= account_action_button(account)
|
||||||
.account-role.admin
|
|
||||||
= t 'accounts.roles.admin'
|
|
||||||
- elsif account.user_moderator?
|
|
||||||
.roles
|
|
||||||
.account-role.moderator
|
|
||||||
= t 'accounts.roles.moderator'
|
|
||||||
|
|
||||||
.bio
|
.public-account-header__extra
|
||||||
.account__header__content.p-note.emojify= Formatter.instance.simplified_format(account, custom_emojify: true)
|
= render 'accounts/bio', account: account
|
||||||
|
|
||||||
- unless account.fields.empty?
|
.public-account-header__extra__links
|
||||||
.account__header__fields
|
|
||||||
- account.fields.each do |field|
|
|
||||||
%dl
|
|
||||||
%dt.emojify{ title: field.name }= field.name
|
|
||||||
%dd.emojify{ title: field.value }= Formatter.instance.format_field(account, field.value, custom_emojify: true)
|
|
||||||
|
|
||||||
.details-counters
|
|
||||||
.counter{ class: active_nav_class(short_account_url(account)) }
|
|
||||||
= link_to short_account_url(account), class: 'u-url u-uid' do
|
|
||||||
%span.counter-number= number_to_human account.statuses_count, strip_insignificant_zeros: true
|
|
||||||
%span.counter-label= t('accounts.posts')
|
|
||||||
|
|
||||||
.counter{ class: active_nav_class(account_following_index_url(account)) }
|
|
||||||
= link_to account_following_index_url(account) do
|
= link_to account_following_index_url(account) do
|
||||||
%span.counter-number= number_to_human account.following_count, strip_insignificant_zeros: true
|
%strong= number_to_human account.following_count, strip_insignificant_zeros: true
|
||||||
%span.counter-label= t('accounts.following')
|
= t('accounts.following')
|
||||||
|
|
||||||
.counter{ class: active_nav_class(account_followers_url(account)) }
|
|
||||||
= link_to account_followers_url(account) do
|
= link_to account_followers_url(account) do
|
||||||
%span.counter-number= number_to_human account.followers_count, strip_insignificant_zeros: true
|
%strong= number_to_human account.followers_count, strip_insignificant_zeros: true
|
||||||
%span.counter-label= t('accounts.followers')
|
= t('accounts.followers')
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
- moved_to_account = account.moved_to_account
|
- moved_to_account = account.moved_to_account
|
||||||
|
|
||||||
.moved-strip
|
.moved-account-widget
|
||||||
.moved-strip__message
|
.moved-account-widget__message
|
||||||
= fa_icon 'suitcase'
|
= fa_icon 'suitcase'
|
||||||
= t('accounts.moved_html', name: content_tag(:strong, display_name(account, custom_emojify: true), class: :emojify), new_profile_link: link_to(content_tag(:strong, safe_join(['@', content_tag(:span, moved_to_account.acct)])), TagManager.instance.url_for(moved_to_account), class: 'mention'))
|
= t('accounts.moved_html', name: content_tag(:bdi, content_tag(:strong, display_name(account, custom_emojify: true), class: :emojify)), new_profile_link: link_to(content_tag(:strong, safe_join(['@', content_tag(:span, moved_to_account.acct)])), TagManager.instance.url_for(moved_to_account), class: 'mention'))
|
||||||
|
|
||||||
.moved-strip__card
|
.moved-account-widget__card
|
||||||
= link_to TagManager.instance.url_for(moved_to_account), class: 'detailed-status__display-name p-author h-card', target: '_blank', rel: 'noopener' do
|
= link_to TagManager.instance.url_for(moved_to_account), class: 'detailed-status__display-name p-author h-card', target: '_blank', rel: 'noopener' do
|
||||||
.detailed-status__display-avatar
|
.detailed-status__display-avatar
|
||||||
.account__avatar-overlay
|
.account__avatar-overlay
|
||||||
|
@ -13,5 +13,6 @@
|
||||||
.account__avatar-overlay-overlay{ style: "background-image: url('#{account.avatar.url(:original)}')" }
|
.account__avatar-overlay-overlay{ style: "background-image: url('#{account.avatar.url(:original)}')" }
|
||||||
|
|
||||||
%span.display-name
|
%span.display-name
|
||||||
%strong.emojify= display_name(moved_to_account, custom_emojify: true)
|
%bdi
|
||||||
|
%strong.emojify= display_name(moved_to_account, custom_emojify: true)
|
||||||
%span @#{moved_to_account.acct}
|
%span @#{moved_to_account.acct}
|
|
@ -1 +0,0 @@
|
||||||
%p.nothing-here= t('accounts.nothing_here')
|
|
|
@ -20,36 +20,39 @@
|
||||||
= opengraph 'og:type', 'profile'
|
= opengraph 'og:type', 'profile'
|
||||||
= render 'og', account: @account, url: short_account_url(@account, only_path: false)
|
= render 'og', account: @account, url: short_account_url(@account, only_path: false)
|
||||||
|
|
||||||
- if @account.memorial?
|
|
||||||
.memoriam-strip= t('in_memoriam_html')
|
|
||||||
- elsif @account.moved?
|
|
||||||
= render partial: 'moved_strip', locals: { account: @account }
|
|
||||||
- elsif show_landing_strip?
|
|
||||||
= render partial: 'shared/landing_strip', locals: { account: @account }
|
|
||||||
|
|
||||||
.h-feed
|
= render 'header', account: @account, with_bio: true
|
||||||
%data.p-name{ value: "#{@account.username} on #{site_hostname}" }/
|
|
||||||
|
|
||||||
= render 'header', account: @account
|
.grid
|
||||||
|
.column-0
|
||||||
|
.h-feed
|
||||||
|
%data.p-name{ value: "#{@account.username} on #{site_hostname}" }/
|
||||||
|
|
||||||
.activity-stream-tabs
|
.account__section-headline
|
||||||
= active_link_to t('accounts.posts'), short_account_url(@account)
|
= active_link_to t('accounts.posts'), short_account_url(@account)
|
||||||
= active_link_to t('accounts.posts_with_replies'), short_account_with_replies_url(@account)
|
= active_link_to t('accounts.posts_with_replies'), short_account_with_replies_url(@account)
|
||||||
= active_link_to t('accounts.media'), short_account_media_url(@account)
|
= active_link_to t('accounts.media'), short_account_media_url(@account)
|
||||||
|
|
||||||
- if @statuses.empty?
|
- if @statuses.empty?
|
||||||
.accounts-grid
|
= nothing_here 'nothing-here--under-tabs'
|
||||||
= render 'nothing_here'
|
- else
|
||||||
- else
|
.activity-stream
|
||||||
.activity-stream.with-header
|
- if params[:page].to_i.zero?
|
||||||
- if params[:page].to_i.zero?
|
= render partial: 'stream_entries/status', collection: @pinned_statuses, as: :status, locals: { pinned: true }
|
||||||
= render partial: 'stream_entries/status', collection: @pinned_statuses, as: :status, locals: { pinned: true }
|
|
||||||
|
|
||||||
= render partial: 'stream_entries/status', collection: @statuses, as: :status
|
- if @newer_url
|
||||||
|
.entry= link_to_more @newer_url
|
||||||
|
|
||||||
- if @newer_url || @older_url
|
= render partial: 'stream_entries/status', collection: @statuses, as: :status
|
||||||
.pagination
|
|
||||||
- if @older_url
|
- if @older_url
|
||||||
= link_to safe_join([fa_icon('chevron-left'), t('pagination.older')], ' '), @older_url, class: 'older', rel: 'next'
|
.entry= link_to_more @older_url
|
||||||
- if @newer_url
|
|
||||||
= link_to safe_join([t('pagination.newer'), fa_icon('chevron-right')], ' '), @newer_url, class: 'newer', rel: 'prev'
|
.column-1
|
||||||
|
- if @account.memorial?
|
||||||
|
.memoriam-widget= t('in_memoriam_html')
|
||||||
|
- elsif @account.moved?
|
||||||
|
= render 'moved', account: @account
|
||||||
|
|
||||||
|
= render 'bio', account: @account
|
||||||
|
= render 'application/sidebar'
|
||||||
|
|
16
app/views/application/_card.html.haml
Normal file
16
app/views/application/_card.html.haml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
- account_url = local_assigns[:admin] ? admin_account_path(account.id) : TagManager.instance.url_for(account)
|
||||||
|
|
||||||
|
.card.h-card
|
||||||
|
= link_to account_url, target: '_blank', rel: 'noopener' do
|
||||||
|
.card__img
|
||||||
|
= image_tag account.header.url, alt: ''
|
||||||
|
.card__bar
|
||||||
|
.avatar
|
||||||
|
= image_tag account.avatar.url, alt: '', width: 48, height: 48, class: 'u-photo'
|
||||||
|
|
||||||
|
.display-name
|
||||||
|
%bdi
|
||||||
|
%strong.emojify.p-name= display_name(account, custom_emojify: true)
|
||||||
|
%span
|
||||||
|
= acct(account)
|
||||||
|
= fa_icon('lock') if account.locked?
|
6
app/views/application/_sidebar.html.haml
Normal file
6
app/views/application/_sidebar.html.haml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
.hero-widget
|
||||||
|
.hero-widget__img
|
||||||
|
= image_tag @instance_presenter.hero&.file&.url || @instance_presenter.thumbnail&.file&.url || asset_pack_path('preview.jpg'), alt: @instance_presenter.site_title
|
||||||
|
|
||||||
|
.hero-widget__text
|
||||||
|
%p= @instance_presenter.site_description.html_safe.presence || t('about.generic_description', domain: site_hostname)
|
|
@ -10,7 +10,7 @@
|
||||||
- if @invite.present? && @invite.autofollow?
|
- if @invite.present? && @invite.autofollow?
|
||||||
.fields-group{ style: 'margin-bottom: 30px' }
|
.fields-group{ style: 'margin-bottom: 30px' }
|
||||||
%p.hint{ style: 'text-align: center' }= t('invites.invited_by')
|
%p.hint{ style: 'text-align: center' }= t('invites.invited_by')
|
||||||
= render 'authorize_follows/card', account: @invite.user.account
|
= render 'application/card', account: @invite.user.account
|
||||||
|
|
||||||
= f.simple_fields_for :account do |ff|
|
= f.simple_fields_for :account do |ff|
|
||||||
.input-with-append
|
.input-with-append
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
.account-card
|
|
||||||
.account-card__header{ style: "background-image: url(#{account.header.url(:original)})" }
|
|
||||||
.detailed-status__display-name
|
|
||||||
%div
|
|
||||||
= image_tag account.avatar.url(:original), alt: '', width: 48, height: 48, class: 'avatar'
|
|
||||||
|
|
||||||
%span.display-name
|
|
||||||
- account_url = local_assigns[:admin] ? admin_account_path(account.id) : TagManager.instance.url_for(account)
|
|
||||||
= link_to account_url, class: 'detailed-status__display-name p-author h-card', target: '_blank', rel: 'noopener' do
|
|
||||||
%strong.emojify= display_name(account, custom_emojify: true)
|
|
||||||
%span @#{account.acct}
|
|
||||||
|
|
||||||
.counter
|
|
||||||
%span.counter-number= number_to_human account.statuses_count, strip_insignificant_zeros: true
|
|
||||||
%span.counter-label= t('accounts.posts')
|
|
||||||
|
|
||||||
.counter
|
|
||||||
%span.counter-number= number_to_human account.following_count, strip_insignificant_zeros: true
|
|
||||||
%span.counter-label= t('accounts.following')
|
|
||||||
|
|
||||||
.counter
|
|
||||||
%span.counter-number= number_to_human account.followers_count, strip_insignificant_zeros: true
|
|
||||||
%span.counter-label= t('accounts.followers')
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
.form-container
|
.form-container
|
||||||
.follow-prompt
|
.follow-prompt
|
||||||
= render 'card', account: @account
|
= render 'application/card', account: @account
|
||||||
|
|
||||||
- if current_account.following?(@account)
|
- if current_account.following?(@account)
|
||||||
.flash-message
|
.flash-message
|
||||||
|
|
|
@ -8,6 +8,6 @@
|
||||||
- else
|
- else
|
||||||
%h2= t('authorize_follow.following')
|
%h2= t('authorize_follow.following')
|
||||||
|
|
||||||
= render 'card', account: @account
|
= render 'application/card', account: @account
|
||||||
|
|
||||||
= render 'post_follow_actions'
|
= render 'post_follow_actions'
|
||||||
|
|
|
@ -8,6 +8,11 @@
|
||||||
= render 'accounts/header', account: @account
|
= render 'accounts/header', account: @account
|
||||||
|
|
||||||
- if @account.user_hides_network?
|
- if @account.user_hides_network?
|
||||||
= render 'accounts/follow_grid_hidden'
|
.nothing-here= t('accounts.network_hidden')
|
||||||
|
- elsif @follows.empty?
|
||||||
|
= nothing_here
|
||||||
- else
|
- else
|
||||||
= render 'accounts/follow_grid', follows: @follows, accounts: @follows.map(&:account)
|
.card-grid
|
||||||
|
= render partial: 'application/card', collection: @follows.map(&:account), as: :account
|
||||||
|
|
||||||
|
= paginate @follows
|
||||||
|
|
|
@ -8,6 +8,11 @@
|
||||||
= render 'accounts/header', account: @account
|
= render 'accounts/header', account: @account
|
||||||
|
|
||||||
- if @account.user_hides_network?
|
- if @account.user_hides_network?
|
||||||
= render 'accounts/follow_grid_hidden'
|
.nothing-here= t('accounts.network_hidden')
|
||||||
|
- elsif @follows.empty?
|
||||||
|
= nothing_here
|
||||||
- else
|
- else
|
||||||
= render 'accounts/follow_grid', follows: @follows, accounts: @follows.map(&:target_account)
|
.card-grid
|
||||||
|
= render partial: 'application/card', collection: @follows.map(&:target_account), as: :account
|
||||||
|
|
||||||
|
= paginate @follows
|
||||||
|
|
|
@ -1,14 +1,47 @@
|
||||||
- content_for :content do
|
- content_for :content do
|
||||||
.container-alt= yield
|
.public-layout
|
||||||
.footer
|
.container
|
||||||
- if !user_signed_in? && single_user_mode?
|
%nav.header
|
||||||
%span.single-user-login
|
.nav-left
|
||||||
= link_to t('auth.login'), new_user_session_path
|
= link_to root_url, class: 'brand' do
|
||||||
—
|
= image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon'
|
||||||
%span.footer__domain= link_to site_hostname, about_path
|
.nav-center
|
||||||
- else
|
.nav-right
|
||||||
%span.footer__domain= link_to site_hostname, root_path
|
- if user_signed_in?
|
||||||
%span.powered-by
|
= link_to t('settings.back'), root_url, class: 'nav-link nav-button webapp-btn'
|
||||||
!= t('generic.powered_by', link: link_to('https://joinmastodon.org') { image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon' })
|
- else
|
||||||
|
= link_to t('auth.login'), new_user_session_path, class: 'webapp-btn nav-link nav-button'
|
||||||
|
= link_to t('auth.register'), new_user_registration_path, class: 'webapp-btn nav-link nav-button'
|
||||||
|
|
||||||
|
.container= yield
|
||||||
|
|
||||||
|
.container
|
||||||
|
.footer
|
||||||
|
.grid
|
||||||
|
.column-0
|
||||||
|
%h4= t 'footer.resources'
|
||||||
|
%ul
|
||||||
|
%li= link_to t('about.terms'), terms_path
|
||||||
|
%li= link_to t('about.privacy_policy'), terms_path
|
||||||
|
.column-1
|
||||||
|
%h4= t 'footer.developers'
|
||||||
|
%ul
|
||||||
|
%li= link_to t('about.documentation'), 'https://github.com/tootsuite/documentation'
|
||||||
|
%li= link_to t('about.api'), 'https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md'
|
||||||
|
.column-2
|
||||||
|
%h4= link_to t('about.what_is_mastodon'), 'https://joinmastodon.org/'
|
||||||
|
|
||||||
|
= link_to root_url, class: 'brand' do
|
||||||
|
= render file: Rails.root.join('app', 'javascript', 'images', 'logo_transparent.svg')
|
||||||
|
.column-3
|
||||||
|
%h4= site_hostname
|
||||||
|
%ul
|
||||||
|
%li= link_to t('about.about_this'), about_more_path
|
||||||
|
%li= "v#{Mastodon::Version.to_s}"
|
||||||
|
.column-4
|
||||||
|
%h4= t 'footer.more'
|
||||||
|
%ul
|
||||||
|
%li= link_to t('about.source_code'), Mastodon::Version.source_url
|
||||||
|
%li= link_to 'joinmastodon.org', 'https://joinmastodon.org'
|
||||||
|
|
||||||
= render template: 'layouts/application'
|
= render template: 'layouts/application'
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
.follow-prompt
|
.follow-prompt
|
||||||
%h2= t('remote_follow.prompt')
|
%h2= t('remote_follow.prompt')
|
||||||
|
|
||||||
= render partial: 'authorize_follows/card', locals: { account: @account }
|
= render partial: 'application/card', locals: { account: @account }
|
||||||
|
|
||||||
= simple_form_for @remote_follow, as: :remote_follow, url: account_remote_follow_path(@account) do |f|
|
= simple_form_for @remote_follow, as: :remote_follow, url: account_remote_follow_path(@account) do |f|
|
||||||
= render 'shared/error_messages', object: @remote_follow
|
= render 'shared/error_messages', object: @remote_follow
|
||||||
|
|
|
@ -5,6 +5,6 @@
|
||||||
.follow-prompt
|
.follow-prompt
|
||||||
%h2= t('remote_unfollow.unfollowed')
|
%h2= t('remote_unfollow.unfollowed')
|
||||||
|
|
||||||
= render 'card', account: @account
|
= render 'application/card', account: @account
|
||||||
|
|
||||||
= render 'post_follow_actions'
|
= render 'post_follow_actions'
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
%p.hint= t('migrations.currently_redirecting')
|
%p.hint= t('migrations.currently_redirecting')
|
||||||
|
|
||||||
.fields-group
|
.fields-group
|
||||||
= render partial: 'authorize_follows/card', locals: { account: @migration.account }
|
= render partial: 'application/card', locals: { account: @migration.account }
|
||||||
|
|
||||||
= render 'shared/error_messages', object: @migration
|
= render 'shared/error_messages', object: @migration
|
||||||
|
|
||||||
|
|
|
@ -8,13 +8,12 @@
|
||||||
= f.input :display_name, placeholder: t('simple_form.labels.defaults.display_name'), hint: t('simple_form.hints.defaults.display_name', count: 30 - @account.display_name.size).html_safe
|
= f.input :display_name, placeholder: t('simple_form.labels.defaults.display_name'), hint: t('simple_form.hints.defaults.display_name', count: 30 - @account.display_name.size).html_safe
|
||||||
= f.input :note, placeholder: t('simple_form.labels.defaults.note'), hint: t('simple_form.hints.defaults.note', count: 500 - @account.note.size).html_safe
|
= f.input :note, placeholder: t('simple_form.labels.defaults.note'), hint: t('simple_form.hints.defaults.note', count: 500 - @account.note.size).html_safe
|
||||||
|
|
||||||
.card.compact{ style: "background-image: url(#{@account.header.url(:original)})", data: { original_src: @account.header.url(:original) } }
|
= render 'application/card', account: @account
|
||||||
.avatar= image_tag @account.avatar.url(:original), data: { original_src: @account.avatar.url(:original) }
|
|
||||||
|
|
||||||
.fields-group
|
.fields-group
|
||||||
= f.input :avatar, wrapper: :with_label, input_html: { accept: AccountAvatar::IMAGE_MIME_TYPES.join(',') }, hint: t('simple_form.hints.defaults.avatar')
|
= f.input :avatar, wrapper: :with_label, input_html: { accept: AccountAvatar::IMAGE_MIME_TYPES.join(',') }, hint: t('simple_form.hints.defaults.avatar', dimensions: '400x400', size: number_to_human_size(AccountAvatar::LIMIT))
|
||||||
|
|
||||||
= f.input :header, wrapper: :with_label, input_html: { accept: AccountHeader::IMAGE_MIME_TYPES.join(',') }, hint: t('simple_form.hints.defaults.header')
|
= f.input :header, wrapper: :with_label, input_html: { accept: AccountHeader::IMAGE_MIME_TYPES.join(',') }, hint: t('simple_form.hints.defaults.header', dimensions: '1500x500', size: number_to_human_size(AccountHeader::LIMIT))
|
||||||
|
|
||||||
.fields-group
|
.fields-group
|
||||||
= f.input :locked, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.locked')
|
= f.input :locked, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.locked')
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
.landing-strip
|
|
||||||
= image_tag asset_pack_path('logo.svg'), class: 'logo'
|
|
||||||
|
|
||||||
%div
|
|
||||||
= t('landing_strip_html', name: content_tag(:span, display_name(account, custom_emojify: true), class: :emojify), link_to_root_path: link_to(content_tag(:strong, site_hostname), root_path))
|
|
||||||
= t('landing_strip_signup_html', sign_up_path: open_registrations? ? new_user_registration_path : 'https://joinmastodon.org/#getting-started')
|
|
|
@ -1,7 +0,0 @@
|
||||||
.media-spoiler-wrapper{ class: sensitive == false && 'media-spoiler-wrapper__visible' }><
|
|
||||||
.spoiler-button
|
|
||||||
.icon-button.overlayed
|
|
||||||
%i.fa.fa-fw.fa-eye
|
|
||||||
.media-spoiler
|
|
||||||
%span= t('stream_entries.sensitive_content')
|
|
||||||
%span= t('stream_entries.click_to_show')
|
|
|
@ -1,16 +1,15 @@
|
||||||
.detailed-status.light
|
.detailed-status.detailed-status--flex
|
||||||
= link_to TagManager.instance.url_for(status.account), class: 'detailed-status__display-name p-author h-card', target: stream_link_target, rel: 'noopener' do
|
= link_to TagManager.instance.url_for(status.account), class: 'detailed-status__display-name p-author h-card', target: stream_link_target, rel: 'noopener' do
|
||||||
%div
|
.detailed-status__display-avatar
|
||||||
.avatar
|
= image_tag status.account.avatar.url(:original), width: 48, height: 48, alt: '', class: 'account__avatar u-photo'
|
||||||
= image_tag status.account.avatar.url(:original), width: 48, height: 48, alt: '', class: 'u-photo'
|
|
||||||
%span.display-name
|
%span.display-name
|
||||||
%strong.p-name.emojify= display_name(status.account, custom_emojify: true)
|
%bdi
|
||||||
%span= acct(status.account)
|
%strong.display-name__html.p-name.emojify= display_name(status.account, custom_emojify: true)
|
||||||
|
%span.display-name__account
|
||||||
|
= acct(status.account)
|
||||||
|
= fa_icon('lock') if status.account.locked?
|
||||||
|
|
||||||
- if !user_signed_in? || embedded_view?
|
= account_action_button(status.account)
|
||||||
= link_to account_remote_follow_path(status.account), class: 'button button-secondary logo-button', target: '_new' do
|
|
||||||
= render file: Rails.root.join('app', 'javascript', 'images', 'logo.svg')
|
|
||||||
= t('accounts.follow')
|
|
||||||
|
|
||||||
.status__content.emojify<
|
.status__content.emojify<
|
||||||
- if status.spoiler_text?
|
- if status.spoiler_text?
|
||||||
|
@ -30,6 +29,7 @@
|
||||||
|
|
||||||
.detailed-status__meta
|
.detailed-status__meta
|
||||||
%data.dt-published{ value: status.created_at.to_time.iso8601 }
|
%data.dt-published{ value: status.created_at.to_time.iso8601 }
|
||||||
|
|
||||||
= link_to TagManager.instance.url_for(status), class: 'detailed-status__datetime u-url u-uid', target: stream_link_target, rel: 'noopener' do
|
= link_to TagManager.instance.url_for(status), class: 'detailed-status__datetime u-url u-uid', target: stream_link_target, rel: 'noopener' do
|
||||||
%time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
|
%time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
|
||||||
·
|
·
|
||||||
|
@ -40,20 +40,20 @@
|
||||||
= link_to status.application.name, status.application.website, class: 'detailed-status__application', target: '_blank', rel: 'noopener'
|
= link_to status.application.name, status.application.website, class: 'detailed-status__application', target: '_blank', rel: 'noopener'
|
||||||
·
|
·
|
||||||
- if status.direct_visibility?
|
- if status.direct_visibility?
|
||||||
%span<
|
%span.detailed-status__link<
|
||||||
= fa_icon('envelope')
|
= fa_icon('envelope')
|
||||||
- elsif status.private_visibility?
|
- elsif status.private_visibility?
|
||||||
%span<
|
%span.detailed-status__link<
|
||||||
= fa_icon('lock')
|
= fa_icon('lock')
|
||||||
- else
|
- else
|
||||||
%span<
|
%span.detailed-status__link<
|
||||||
= fa_icon('retweet')
|
= fa_icon('retweet')
|
||||||
%span= status.reblogs_count
|
%span.detailed-status__reblogs= number_to_human status.reblogs_count, strip_insignificant_zeros: true
|
||||||
·
|
·
|
||||||
%span<
|
%span.detailed-status__link<
|
||||||
= fa_icon('star')
|
= fa_icon('star')
|
||||||
%span= status.favourites_count
|
%span.detailed-status__favorites= number_to_human status.favourites_count, strip_insignificant_zeros: true
|
||||||
|
|
||||||
- if user_signed_in?
|
- if user_signed_in?
|
||||||
·
|
·
|
||||||
= link_to t('statuses.open_in_web'), web_url("statuses/#{status.id}"), class: 'open-in-web-link', target: '_blank'
|
= link_to t('statuses.open_in_web'), web_url("statuses/#{status.id}"), class: 'detailed-status__application', target: '_blank'
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
.media-item><
|
|
||||||
= link_to media.remote_url.blank? ? media.file.url(:original) : media.remote_url, style: media.image? ? "background-image: url(#{media.file.url(:original)})" : '', target: '_blank', rel: 'noopener', class: "u-#{media.video? || media.gifv? ? 'video' : 'photo'}" do
|
|
||||||
- unless media.image?
|
|
||||||
%video{ src: media.file.url(:original), autoplay: true, loop: true }/
|
|
|
@ -1,2 +0,0 @@
|
||||||
= link_to url, class: 'more light' do
|
|
||||||
= t('statuses.show_more')
|
|
|
@ -1,18 +1,19 @@
|
||||||
.status.light
|
.status
|
||||||
.status__header
|
.status__info
|
||||||
.status__meta
|
= link_to TagManager.instance.url_for(status), class: 'status__relative-time u-url u-uid', target: stream_link_target, rel: 'noopener' do
|
||||||
= link_to TagManager.instance.url_for(status), class: 'status__relative-time u-url u-uid', target: stream_link_target, rel: 'noopener' do
|
%time.time-ago{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
|
||||||
%time.time-ago{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
|
%data.dt-published{ value: status.created_at.to_time.iso8601 }
|
||||||
%data.dt-published{ value: status.created_at.to_time.iso8601 }
|
|
||||||
|
|
||||||
= link_to TagManager.instance.url_for(status.account), class: 'status__display-name p-author h-card', target: stream_link_target, rel: 'noopener' do
|
= link_to TagManager.instance.url_for(status.account), class: 'status__display-name p-author h-card', target: stream_link_target, rel: 'noopener' do
|
||||||
.status__avatar
|
.status__avatar
|
||||||
%div
|
%div
|
||||||
= image_tag status.account.avatar(:original), width: 48, height: 48, alt: '', class: 'u-photo'
|
= image_tag status.account.avatar(:original), width: 48, height: 48, alt: '', class: 'u-photo account__avatar'
|
||||||
%span.display-name
|
%span.display-name
|
||||||
%strong.p-name.emojify= display_name(status.account, custom_emojify: true)
|
%bdi
|
||||||
%span= acct(status.account)
|
%strong.display-name__html.p-name.emojify= display_name(status.account, custom_emojify: true)
|
||||||
|
%span.display-name__account
|
||||||
|
= acct(status.account)
|
||||||
|
= fa_icon('lock') if status.account.locked?
|
||||||
.status__content.emojify<
|
.status__content.emojify<
|
||||||
- if status.spoiler_text?
|
- if status.spoiler_text?
|
||||||
%p{ style: 'margin-bottom: 0' }<
|
%p{ style: 'margin-bottom: 0' }<
|
||||||
|
@ -27,3 +28,16 @@
|
||||||
= react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 610, height: 343, inline: true
|
= react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 610, height: 343, inline: true
|
||||||
- else
|
- else
|
||||||
= react_component :media_gallery, height: 343, sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }
|
= react_component :media_gallery, height: 343, sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }
|
||||||
|
|
||||||
|
.status__action-bar
|
||||||
|
.status__action-bar-button.static-icon-button<
|
||||||
|
- if status.public_visibility? || status.unlisted_visibility?
|
||||||
|
= fa_icon 'retweet fw'
|
||||||
|
%span.detailed-status__reblogs= number_to_human status.reblogs_count, strip_insignificant_zeros: true
|
||||||
|
- elsif status.private_visibility?
|
||||||
|
= fa_icon 'lock fw'
|
||||||
|
- else
|
||||||
|
= fa_icon 'envelope fw'
|
||||||
|
.status__action-bar-button.static-icon-button<
|
||||||
|
= fa_icon 'star fw'
|
||||||
|
%span.detailed-status__favorites= number_to_human status.favourites_count, strip_insignificant_zeros: true
|
||||||
|
|
|
@ -16,24 +16,25 @@
|
||||||
- if status.reply? && include_threads
|
- if status.reply? && include_threads
|
||||||
- if @next_ancestor
|
- if @next_ancestor
|
||||||
.entry{ class: entry_classes }
|
.entry{ class: entry_classes }
|
||||||
= render 'stream_entries/more', url: TagManager.instance.url_for(@next_ancestor)
|
= link_to_more TagManager.instance.url_for(@next_ancestor)
|
||||||
|
|
||||||
= render partial: 'stream_entries/status', collection: @ancestors, as: :status, locals: { is_predecessor: true, direct_reply_id: status.in_reply_to_id }
|
= render partial: 'stream_entries/status', collection: @ancestors, as: :status, locals: { is_predecessor: true, direct_reply_id: status.in_reply_to_id }
|
||||||
|
|
||||||
.entry{ class: entry_classes }
|
.entry{ class: entry_classes }
|
||||||
|
|
||||||
- if status.reblog?
|
- if status.reblog?
|
||||||
.pre-header
|
.status__prepend
|
||||||
.pre-header__icon
|
.status__prepend-icon-wrapper
|
||||||
= fa_icon('retweet fw')
|
%i.status__prepend-icon.fa.fa-fw.fa-retweet
|
||||||
%span
|
%span
|
||||||
= link_to TagManager.instance.url_for(status.account), class: 'status__display-name muted' do
|
= link_to TagManager.instance.url_for(status.account), class: 'status__display-name muted' do
|
||||||
%strong.emojify= display_name(status.account, custom_emojify: true)
|
%bdi
|
||||||
|
%strong.emojify= display_name(status.account, custom_emojify: true)
|
||||||
= t('stream_entries.reblogged')
|
= t('stream_entries.reblogged')
|
||||||
- elsif pinned
|
- elsif pinned
|
||||||
.pre-header
|
.status__prepend
|
||||||
.pre-header__icon
|
.status__prepend-icon-wrapper
|
||||||
= fa_icon('thumb-tack fw')
|
%i.status__prepend-icon.fa.fa-fw.fa-thumb-tack
|
||||||
%span
|
%span
|
||||||
= t('stream_entries.pinned')
|
= t('stream_entries.pinned')
|
||||||
|
|
||||||
|
@ -42,13 +43,13 @@
|
||||||
- if include_threads
|
- if include_threads
|
||||||
- if @since_descendant_thread_id
|
- if @since_descendant_thread_id
|
||||||
.entry{ class: entry_classes }
|
.entry{ class: entry_classes }
|
||||||
= render 'stream_entries/more', url: short_account_status_url(status.account.username, status, max_descendant_thread_id: @since_descendant_thread_id + 1)
|
= link_to_more short_account_status_url(status.account.username, status, max_descendant_thread_id: @since_descendant_thread_id + 1)
|
||||||
- @descendant_threads.each do |thread|
|
- @descendant_threads.each do |thread|
|
||||||
= render partial: 'stream_entries/status', collection: thread[:statuses], as: :status, locals: { is_successor: true, parent_id: status.id }
|
= render partial: 'stream_entries/status', collection: thread[:statuses], as: :status, locals: { is_successor: true, parent_id: status.id }
|
||||||
|
|
||||||
- if thread[:next_status]
|
- if thread[:next_status]
|
||||||
.entry{ class: entry_classes }
|
.entry{ class: entry_classes }
|
||||||
= render 'stream_entries/more', url: TagManager.instance.url_for(thread[:next_status])
|
= link_to_more TagManager.instance.url_for(thread[:next_status])
|
||||||
- if @next_descendant_thread
|
- if @next_descendant_thread
|
||||||
.entry{ class: entry_classes }
|
.entry{ class: entry_classes }
|
||||||
= render 'stream_entries/more', url: short_account_status_url(status.account.username, status, since_descendant_thread_id: @max_descendant_thread_id - 1)
|
= link_to_more short_account_status_url(status.account.username, status, since_descendant_thread_id: @max_descendant_thread_id - 1)
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
- cache @stream_entry.activity do
|
- cache @stream_entry.activity do
|
||||||
.activity-stream.activity-stream-headless
|
.activity-stream.activity-stream--headless
|
||||||
= render "stream_entries/#{@type}", @type.to_sym => @stream_entry.activity, centered: true
|
= render "stream_entries/#{@type}", @type.to_sym => @stream_entry.activity, centered: true
|
||||||
|
|
|
@ -17,8 +17,9 @@
|
||||||
= render 'stream_entries/og_description', activity: @stream_entry.activity
|
= render 'stream_entries/og_description', activity: @stream_entry.activity
|
||||||
= render 'stream_entries/og_image', activity: @stream_entry.activity, account: @account
|
= render 'stream_entries/og_image', activity: @stream_entry.activity, account: @account
|
||||||
|
|
||||||
- if show_landing_strip?
|
.grid
|
||||||
= render partial: 'shared/landing_strip', locals: { account: @stream_entry.account }
|
.column-0
|
||||||
|
.activity-stream.activity-stream-headless.h-entry
|
||||||
.activity-stream.activity-stream-headless.h-entry
|
= render partial: "stream_entries/#{@type}", locals: { @type.to_sym => @stream_entry.activity, include_threads: true }
|
||||||
= render partial: "stream_entries/#{@type}", locals: { @type.to_sym => @stream_entry.activity, include_threads: true }
|
.column-1
|
||||||
|
= render 'application/sidebar'
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
{}
|
---
|
||||||
|
ast:
|
||||||
|
|
|
@ -46,7 +46,6 @@ ar:
|
||||||
people_who_follow: الأشخاص الذين يتبعون %{name}
|
people_who_follow: الأشخاص الذين يتبعون %{name}
|
||||||
posts: منشورات
|
posts: منشورات
|
||||||
posts_with_replies: التبويقات و الردود
|
posts_with_replies: التبويقات و الردود
|
||||||
remote_follow: إتبع عن بعد
|
|
||||||
reserved_username: إسم المستخدم محجوز
|
reserved_username: إسم المستخدم محجوز
|
||||||
roles:
|
roles:
|
||||||
admin: المدير
|
admin: المدير
|
||||||
|
@ -516,7 +515,6 @@ ar:
|
||||||
unlocked_warning_title: إنّ حسابك غير مقفل
|
unlocked_warning_title: إنّ حسابك غير مقفل
|
||||||
generic:
|
generic:
|
||||||
changes_saved_msg: تم حفظ التعديلات بنجاح !
|
changes_saved_msg: تم حفظ التعديلات بنجاح !
|
||||||
powered_by: مدعوم بـ %{link}
|
|
||||||
save_changes: حفظ التغييرات
|
save_changes: حفظ التغييرات
|
||||||
validation_errors:
|
validation_errors:
|
||||||
one: لا يزال هناك خلل ما إلى حد الآن. يُرجى إعادة النظر في الخطأ أسفله
|
one: لا يزال هناك خلل ما إلى حد الآن. يُرجى إعادة النظر في الخطأ أسفله
|
||||||
|
@ -551,8 +549,6 @@ ar:
|
||||||
expires_at: تنتهي مدة صلاحيتها في
|
expires_at: تنتهي مدة صلاحيتها في
|
||||||
uses: يستخدِم
|
uses: يستخدِم
|
||||||
title: دعوة أشخاص
|
title: دعوة أشخاص
|
||||||
landing_strip_html: "<strong>%{name}</strong> هو أحد مُستخدِمي %{link_to_root_path}. بإمكانك متابعته أو التواصل معه إن كنت تملك حسابًا أيا كان على البيئة الموحَّدة فيديفرس."
|
|
||||||
landing_strip_signup_html: إن كنت لا تملك واحدا، يمكنك <a href="%{sign_up_path}">التسجيل مِن هنا</a>.
|
|
||||||
lists:
|
lists:
|
||||||
errors:
|
errors:
|
||||||
limit: لقد بلغت الحد الأقصى للقوائم
|
limit: لقد بلغت الحد الأقصى للقوائم
|
||||||
|
@ -720,7 +716,6 @@ ar:
|
||||||
unlisted: غير مُدرَج
|
unlisted: غير مُدرَج
|
||||||
unlisted_long: يُمكن لأيٍ كان رُؤيتَه و لكن لن يُعرَض على الخيوط العامة
|
unlisted_long: يُمكن لأيٍ كان رُؤيتَه و لكن لن يُعرَض على الخيوط العامة
|
||||||
stream_entries:
|
stream_entries:
|
||||||
click_to_show: إضغط للعرض
|
|
||||||
pinned: تبويق مثبّت
|
pinned: تبويق مثبّت
|
||||||
reblogged: رقى
|
reblogged: رقى
|
||||||
sensitive_content: محتوى حساس
|
sensitive_content: محتوى حساس
|
||||||
|
|
|
@ -96,8 +96,6 @@ ast:
|
||||||
followers:
|
followers:
|
||||||
domain: Dominiu
|
domain: Dominiu
|
||||||
followers_count: Númberu de siguidores
|
followers_count: Númberu de siguidores
|
||||||
generic:
|
|
||||||
powered_by: cola potencia de %{link}
|
|
||||||
invites:
|
invites:
|
||||||
expires_in:
|
expires_in:
|
||||||
'1800': 30 minutos
|
'1800': 30 minutos
|
||||||
|
@ -183,7 +181,6 @@ ast:
|
||||||
other: "%{count} vídeos"
|
other: "%{count} vídeos"
|
||||||
title: "%{name}: «%{quote}»"
|
title: "%{name}: «%{quote}»"
|
||||||
stream_entries:
|
stream_entries:
|
||||||
click_to_show: Primi p'amosar
|
|
||||||
sensitive_content: Conteníu sensible
|
sensitive_content: Conteníu sensible
|
||||||
themes:
|
themes:
|
||||||
default: Mastodon
|
default: Mastodon
|
||||||
|
|
|
@ -22,7 +22,6 @@ bg:
|
||||||
people_followed_by: Хора, които %{name} следва
|
people_followed_by: Хора, които %{name} следва
|
||||||
people_who_follow: Хора, които следват %{name}
|
people_who_follow: Хора, които следват %{name}
|
||||||
posts: Публикации
|
posts: Публикации
|
||||||
remote_follow: Последвай
|
|
||||||
unfollow: Не следвай
|
unfollow: Не следвай
|
||||||
application_mailer:
|
application_mailer:
|
||||||
settings: 'Промяна на предпочитанията за e-mail: %{link}'
|
settings: 'Промяна на предпочитанията за e-mail: %{link}'
|
||||||
|
@ -64,7 +63,6 @@ bg:
|
||||||
storage: Съхранение на мултимедия
|
storage: Съхранение на мултимедия
|
||||||
generic:
|
generic:
|
||||||
changes_saved_msg: Успешно запазване на промените!
|
changes_saved_msg: Успешно запазване на промените!
|
||||||
powered_by: поддържано от %{link}
|
|
||||||
save_changes: Запази промените
|
save_changes: Запази промените
|
||||||
validation_errors:
|
validation_errors:
|
||||||
one: Нещо все още не е наред! Моля, прегледай грешката по-долу
|
one: Нещо все още не е наред! Моля, прегледай грешката по-долу
|
||||||
|
@ -76,8 +74,6 @@ bg:
|
||||||
blocking: Списък на блокираните
|
blocking: Списък на блокираните
|
||||||
following: Списък на последователите
|
following: Списък на последователите
|
||||||
upload: Качване
|
upload: Качване
|
||||||
landing_strip_html: "<strong>%{name}</strong> е потребител от %{link_to_root_path}. Можеш да ги следваш, или да контактуваш с тях, ако имаш акаунт където и да е из федерираната вселена на Mastodon."
|
|
||||||
landing_strip_signup_html: Ако нямаш акаунт, можеш да си <a href="%{sign_up_path}">създадеш ето тук</a>.
|
|
||||||
media_attachments:
|
media_attachments:
|
||||||
validations:
|
validations:
|
||||||
images_and_video: Не мога да прикача видеоклип към публикация, която вече съдържа изображения
|
images_and_video: Не мога да прикача видеоклип към публикация, която вече съдържа изображения
|
||||||
|
@ -144,7 +140,6 @@ bg:
|
||||||
public: Публично
|
public: Публично
|
||||||
unlisted: Публично, но не показвай в публичния канал
|
unlisted: Публично, но не показвай в публичния канал
|
||||||
stream_entries:
|
stream_entries:
|
||||||
click_to_show: Покажи
|
|
||||||
reblogged: споделено
|
reblogged: споделено
|
||||||
sensitive_content: Деликатно съдържание
|
sensitive_content: Деликатно съдържание
|
||||||
time:
|
time:
|
||||||
|
|
|
@ -46,7 +46,6 @@ ca:
|
||||||
people_who_follow: Usuaris que segueixen %{name}
|
people_who_follow: Usuaris que segueixen %{name}
|
||||||
posts: Toots
|
posts: Toots
|
||||||
posts_with_replies: Toots i respostes
|
posts_with_replies: Toots i respostes
|
||||||
remote_follow: Seguiment remot
|
|
||||||
reserved_username: El nom d'usuari està reservat
|
reserved_username: El nom d'usuari està reservat
|
||||||
roles:
|
roles:
|
||||||
admin: Administrador
|
admin: Administrador
|
||||||
|
@ -504,7 +503,6 @@ ca:
|
||||||
unlocked_warning_title: El teu compte no està blocat
|
unlocked_warning_title: El teu compte no està blocat
|
||||||
generic:
|
generic:
|
||||||
changes_saved_msg: Els canvis s'han desat correctament!
|
changes_saved_msg: Els canvis s'han desat correctament!
|
||||||
powered_by: amb tecnologia %{link}
|
|
||||||
save_changes: Desa els canvis
|
save_changes: Desa els canvis
|
||||||
validation_errors:
|
validation_errors:
|
||||||
one: Alguna cosa no va bé! Si us plau, revisa l'error
|
one: Alguna cosa no va bé! Si us plau, revisa l'error
|
||||||
|
@ -540,8 +538,6 @@ ca:
|
||||||
expires_at: Caduca
|
expires_at: Caduca
|
||||||
uses: Usos
|
uses: Usos
|
||||||
title: Convida persones
|
title: Convida persones
|
||||||
landing_strip_html: "<strong>%{name}</strong> és un usuari/a de %{link_to_root_path}. Pots seguir-lo/la o interactuar amb ell/a si tens un compte a qualsevol node del fediverse."
|
|
||||||
landing_strip_signup_html: Si no en tens, pots <a href="%{sign_up_path}">registrar-te aquí</a>.
|
|
||||||
lists:
|
lists:
|
||||||
errors:
|
errors:
|
||||||
limit: Has assolit la quantitat màxima de llistes
|
limit: Has assolit la quantitat màxima de llistes
|
||||||
|
@ -710,7 +706,6 @@ ca:
|
||||||
unlisted: No llistat
|
unlisted: No llistat
|
||||||
unlisted_long: Tothom ho pot veure, però no es mostra en la història federada
|
unlisted_long: Tothom ho pot veure, però no es mostra en la història federada
|
||||||
stream_entries:
|
stream_entries:
|
||||||
click_to_show: Clic per mostrar
|
|
||||||
pinned: Toot fixat
|
pinned: Toot fixat
|
||||||
reblogged: ha impulsat
|
reblogged: ha impulsat
|
||||||
sensitive_content: Contingut sensible
|
sensitive_content: Contingut sensible
|
||||||
|
|
|
@ -46,7 +46,6 @@ co:
|
||||||
people_who_follow: Seguitanu %{name}
|
people_who_follow: Seguitanu %{name}
|
||||||
posts: Statuti
|
posts: Statuti
|
||||||
posts_with_replies: Statuti è risposte
|
posts_with_replies: Statuti è risposte
|
||||||
remote_follow: Siguità d’altrò
|
|
||||||
reserved_username: Stu cugnome hè riservatu
|
reserved_username: Stu cugnome hè riservatu
|
||||||
roles:
|
roles:
|
||||||
admin: Amministratore
|
admin: Amministratore
|
||||||
|
@ -488,7 +487,6 @@ co:
|
||||||
unlocked_warning_title: U vostru contu hè pubblicu
|
unlocked_warning_title: U vostru contu hè pubblicu
|
||||||
generic:
|
generic:
|
||||||
changes_saved_msg: Cambiamenti salvati!
|
changes_saved_msg: Cambiamenti salvati!
|
||||||
powered_by: mossu da %{link}
|
|
||||||
save_changes: Salvà e mudificazione
|
save_changes: Salvà e mudificazione
|
||||||
validation_errors:
|
validation_errors:
|
||||||
one: Qualcosa ùn và bè! Verificate u prublemu quì sottu
|
one: Qualcosa ùn và bè! Verificate u prublemu quì sottu
|
||||||
|
@ -523,8 +521,6 @@ co:
|
||||||
expires_at: Spira
|
expires_at: Spira
|
||||||
uses: Utiliza
|
uses: Utiliza
|
||||||
title: Invità ghjente
|
title: Invità ghjente
|
||||||
landing_strip_html: "<strong>%{name}</strong> hè nant’à %{link_to_root_path}. Pudete seguitallu·a o cumunicà cù ellu·a cù un contu in qualche parte di u fediverse."
|
|
||||||
landing_strip_signup_html: Pudete ancu <a href="%{sign_up_path}">arrigistravi quì</a>.
|
|
||||||
lists:
|
lists:
|
||||||
errors:
|
errors:
|
||||||
limit: Ùn pudete più creà altre liste
|
limit: Ùn pudete più creà altre liste
|
||||||
|
@ -691,7 +687,6 @@ co:
|
||||||
unlisted: Micca listatu
|
unlisted: Micca listatu
|
||||||
unlisted_long: Tuttu u mondu pò vede, mà micca indè e linee pubbliche
|
unlisted_long: Tuttu u mondu pò vede, mà micca indè e linee pubbliche
|
||||||
stream_entries:
|
stream_entries:
|
||||||
click_to_show: Cliccà per vede
|
|
||||||
pinned: Statutu puntarulatu
|
pinned: Statutu puntarulatu
|
||||||
reblogged: spartutu
|
reblogged: spartutu
|
||||||
sensitive_content: Cuntenutu sensibile
|
sensitive_content: Cuntenutu sensibile
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
cs:
|
cs:
|
||||||
about:
|
about:
|
||||||
about_hashtag_html: Toto jsou veřejné tooty označené jako <strong>#%{hashtag}</strong>. Pokud máte účet kdekoliv na fediverse, můžete s nimi interagovat.
|
about_hashtag_html: Toto jsou veřejné tooty označené hashtagem<strong>#%{hashtag}</strong>. Pokud máte účet kdekoliv na fediverse, můžete s nimi interagovat.
|
||||||
about_mastodon_html: Mastodon je sociální síť založená na otevřených webových protokolech a svobodném, otevřeném softwaru. Je decentrovalizovaná jako e-mail.
|
about_mastodon_html: Mastodon je sociální síť založená na otevřených webových protokolech a svobodném, otevřeném softwaru. Je decentrovalizovaná jako e-mail.
|
||||||
about_this: O této instanci
|
about_this: O této instanci
|
||||||
administered_by: 'Server spravuje:'
|
administered_by: 'Server spravuje:'
|
||||||
|
@ -18,14 +18,21 @@ cs:
|
||||||
features:
|
features:
|
||||||
humane_approach_body: Mastodon, poučen z chyb jiných sociálních sítí, se snaží bojovat se zneužíváním sociálních sítí vytvářením etických možností.
|
humane_approach_body: Mastodon, poučen z chyb jiných sociálních sítí, se snaží bojovat se zneužíváním sociálních sítí vytvářením etických možností.
|
||||||
humane_approach_title: Lidštější přístup
|
humane_approach_title: Lidštější přístup
|
||||||
|
not_a_product_body: Mastodon není komerční síť. Žádné reklamy, žádné dolování dat, žádné hranice. Žádná centrální autorita.
|
||||||
not_a_product_title: Jste osoba, ne produkt
|
not_a_product_title: Jste osoba, ne produkt
|
||||||
|
real_conversation_body: S 500 znaky k vaší dispozici a podporou pro varování o obsahu a médiích se můžete vyjadřovat tak, jak chcete.
|
||||||
|
real_conversation_title: Vytvořen pro opravdovou konverzaci
|
||||||
|
within_reach_body: Několik aplikací pro iOS, Android a jiné platformy vám díky jednoduchému API ekosystému dovolují držet krok s vašimi přáteli, ať už jste kdekoliv.
|
||||||
|
within_reach_title: Vždy v dosahu
|
||||||
generic_description: "%{domain} je jedním serverem v síti"
|
generic_description: "%{domain} je jedním serverem v síti"
|
||||||
|
hosted_on: Mastodon hostovaný na %{domain}
|
||||||
learn_more: Zjistit více
|
learn_more: Zjistit více
|
||||||
|
other_instances: Seznam instancí
|
||||||
source_code: Zdrojový kód
|
source_code: Zdrojový kód
|
||||||
status_count_after: příspěvků
|
status_count_after: příspěvků
|
||||||
status_count_before: Kdo je autorem
|
status_count_before: Kteří napsali
|
||||||
user_count_after: uživatelů
|
user_count_after: uživatelů
|
||||||
user_count_before: Domov pro
|
user_count_before: Domov
|
||||||
what_is_mastodon: Co je Mastodon?
|
what_is_mastodon: Co je Mastodon?
|
||||||
accounts:
|
accounts:
|
||||||
follow: Sledovat
|
follow: Sledovat
|
||||||
|
@ -35,10 +42,836 @@ cs:
|
||||||
moved_html: 'Účet %{name} byl přesunut na %{new_profile_link}:'
|
moved_html: 'Účet %{name} byl přesunut na %{new_profile_link}:'
|
||||||
network_hidden: Tato informace není k dispozici
|
network_hidden: Tato informace není k dispozici
|
||||||
nothing_here: Tady nic není!
|
nothing_here: Tady nic není!
|
||||||
|
people_followed_by: Lidé, které %{name} sleduje
|
||||||
|
people_who_follow: Lidé, kteří sledují uživatele %{name}
|
||||||
|
posts: Tooty
|
||||||
|
posts_with_replies: Tooty s odpověďmi
|
||||||
|
reserved_username: Toto uživatelské jméno je rezervováno
|
||||||
|
roles:
|
||||||
|
admin: Administrátor
|
||||||
|
bot: Robot
|
||||||
|
moderator: Moderátor
|
||||||
|
unfollow: Přestat sledovat
|
||||||
|
admin:
|
||||||
|
account_moderation_notes:
|
||||||
|
create: Zanechat poznámku
|
||||||
|
created_msg: Poznámka moderátora byla úspěšně vytvořena!
|
||||||
|
delete: Smazat
|
||||||
|
destroyed_msg: Poznámka moderátora byla úspěšně zničena!
|
||||||
|
accounts:
|
||||||
|
are_you_sure: Jste si jistý/á?
|
||||||
|
avatar: Avatar
|
||||||
|
by_domain: Doména
|
||||||
|
change_email:
|
||||||
|
changed_msg: E-mail k tomuto účtu byl úspěšně změněn!
|
||||||
|
current_email: Současný e-mail
|
||||||
|
label: Změnit e-mail
|
||||||
|
new_email: Nový e-mail
|
||||||
|
submit: Změnit e-mail
|
||||||
|
title: Změnit e-mail pro uživatele %{username}
|
||||||
|
confirm: Potvrdit
|
||||||
|
confirmed: Potvrzeno
|
||||||
|
confirming: Potvrzující
|
||||||
|
demote: Degradovat
|
||||||
|
disable: Zablokovat
|
||||||
|
disable_two_factor_authentication: Zakázat 2FA
|
||||||
|
disabled: Blokováno
|
||||||
|
display_name: Zobrazované jméno
|
||||||
|
domain: Doména
|
||||||
|
edit: Upravit
|
||||||
|
email: E-mail
|
||||||
|
email_status: Stav e-mailu
|
||||||
|
enable: Povolit
|
||||||
|
enabled: Povoleno
|
||||||
|
feed_url: URL proudu
|
||||||
|
followers: Sledovatelé
|
||||||
|
followers_url: URL sledovatelů
|
||||||
|
follows: Sleduje
|
||||||
|
inbox_url: URL přijatých zpráv
|
||||||
|
ip: IP
|
||||||
|
location:
|
||||||
|
all: Vše
|
||||||
|
local: Místní
|
||||||
|
remote: Vzdálené
|
||||||
|
title: Umístění
|
||||||
|
login_status: Stav přihlášení
|
||||||
|
media_attachments: Mediální přílohy
|
||||||
|
memorialize: Změnit na "in memoriam"
|
||||||
|
moderation:
|
||||||
|
all: Vše
|
||||||
|
silenced: Utišen
|
||||||
|
suspended: Suspendován
|
||||||
|
title: Moderace
|
||||||
|
moderation_notes: Moderační poznámky
|
||||||
|
most_recent_activity: Nejnovější aktivita
|
||||||
|
most_recent_ip: Nejnovější IP
|
||||||
|
not_subscribed: Neodebírá
|
||||||
|
order:
|
||||||
|
alphabetic: Abecedně
|
||||||
|
most_recent: Nejnovější
|
||||||
|
title: Pořadí
|
||||||
|
outbox_url: URL odchozích zpráv
|
||||||
|
perform_full_suspension: Provést plnou suspenzaci
|
||||||
|
profile_url: URL profilu
|
||||||
|
promote: Povýšit
|
||||||
|
protocol: Protokol
|
||||||
|
public: Veřejný
|
||||||
|
push_subscription_expires: Odebírání PuSH expiruje
|
||||||
|
redownload: Obnovit avatar
|
||||||
|
remove_avatar: Odstranit avatar
|
||||||
|
resend_confirmation:
|
||||||
|
already_confirmed: Tento uživatel je již potvrzen
|
||||||
|
send: Znovu odeslat potvrzovací e-mail
|
||||||
|
success: Potvrzovací e-mail byl úspěšně odeslán!
|
||||||
|
reset: Resetovat
|
||||||
|
reset_password: Obnovit heslo
|
||||||
|
resubscribe: Znovu odebírat
|
||||||
|
role: Oprávnění
|
||||||
|
roles:
|
||||||
|
admin: Administrátor
|
||||||
|
moderator: Moderátor
|
||||||
|
staff: Personál
|
||||||
|
user: Uživatel
|
||||||
|
salmon_url: URL Salmon
|
||||||
|
search: Hledat
|
||||||
|
shared_inbox_url: URL sdílené schránky
|
||||||
|
show:
|
||||||
|
created_reports: Nahlášení vytvořené z tohoto účtu
|
||||||
|
report: nahlášení
|
||||||
|
targeted_reports: Nahlášení vytvořena o tomto účtu
|
||||||
|
silence: Utišit
|
||||||
|
statuses: Statusy
|
||||||
|
subscribe: Odebírat
|
||||||
|
title: Účty
|
||||||
|
unconfirmed_email: Nepotvrzený e-mail
|
||||||
|
undo_silenced: Zrušit utišení
|
||||||
|
undo_suspension: Zrušit suspenzaci
|
||||||
|
unsubscribe: Přestat odebírat
|
||||||
|
username: Uživatelské jméno
|
||||||
|
web: Web
|
||||||
|
action_logs:
|
||||||
|
actions:
|
||||||
|
assigned_to_self_report: "%{name} přidělil/a hlášení %{target} sobě"
|
||||||
|
change_email_user: "%{name} změnil/a e-mailovou adresu uživatele %{target}"
|
||||||
|
confirm_user: "%{name} potvrdil/a e-mailovou adresu uživatele %{target}"
|
||||||
|
create_custom_emoji: "%{name} nahrál/a nové emoji %{target}"
|
||||||
|
create_domain_block: "%{name} zablokoval/a doménu %{target}"
|
||||||
|
create_email_domain_block: "%{name} přidal/a e-mailovou doménu %{target} na černou listinu"
|
||||||
|
demote_user: "%{name} degradoval/a uživatele %{target}"
|
||||||
|
destroy_domain_block: "%{name} odblokoval/a doménu %{target}"
|
||||||
|
destroy_email_domain_block: "%{name} odebral/a e-mailovou doménu %{target} z černé listiny"
|
||||||
|
destroy_status: "%{name} odstranil/a status uživatele %{target}"
|
||||||
|
disable_2fa_user: "%{name} vypnul/a požadavek pro dvoufaktorovou autentikaci pro uživatele %{target}"
|
||||||
|
disable_custom_emoji: "%{name} zakázal/a emoji %{target}"
|
||||||
|
disable_user: "%{name} zakázal/a přihlašování pro uživatele %{target}"
|
||||||
|
enable_custom_emoji: "%{name} povolil/a emoji %{target}"
|
||||||
|
enable_user: "%{name} povolil/a přihlašování pro uživatele %{target}"
|
||||||
|
memorialize_account: '%{name} změnil/a účet %{target} na stránku "in memoriam"'
|
||||||
|
promote_user: "%{name} povýšil/a uživatele %{target}"
|
||||||
|
remove_avatar_user: "%{name} odstranil/a avatar uživatele %{target}"
|
||||||
|
reopen_report: "%{name} znovuotevřel/a nahlášení %{target}"
|
||||||
|
reset_password_user: "%{name} resetoval/a heslo uživatele %{target}"
|
||||||
|
resolve_report: "%{name} vyřešil/a nahlášení %{target}"
|
||||||
|
silence_account: "%{name} utišil/a účet uživatele %{target}"
|
||||||
|
suspend_account: "%{name} suspendoval/a účet uživatele %{target}"
|
||||||
|
unassigned_report: "%{name} odebral/a nahlášení %{target}"
|
||||||
|
unsilence_account: "%{name} odtišil/a účet uživatele %{target}"
|
||||||
|
unsuspend_account: "%{name} zrušil/a suspenzaci účtu uživatele %{target}"
|
||||||
|
update_custom_emoji: "%{name} aktualizoval/a emoji %{target}"
|
||||||
|
update_status: "%{name} aktualizoval/a status uživatele %{target}"
|
||||||
|
title: Záznam auditu
|
||||||
|
custom_emojis:
|
||||||
|
by_domain: Doména
|
||||||
|
copied_msg: Místní kopie emoji byla úspěšně vytvořena
|
||||||
|
copy: Kopírovat
|
||||||
|
copy_failed_msg: Nebylo možné vytvořit místní kopii tohoto emoji
|
||||||
|
created_msg: Emoji úspěšně vytvořeno!
|
||||||
|
delete: Smazat
|
||||||
|
destroyed_msg: Emoji úspěšně zničeno!
|
||||||
|
disable: Zakázat
|
||||||
|
disabled_msg: Emoji bylo úspěšně zakázáno
|
||||||
|
emoji: Emoji
|
||||||
|
enable: Povolit
|
||||||
|
enabled_msg: Emoji bylo úspěšně povoleno
|
||||||
|
image_hint: PNG až do 50KB
|
||||||
|
listed: Uvedené
|
||||||
|
new:
|
||||||
|
title: Přidat nové vlastní emoji
|
||||||
|
overwrite: Přepsat
|
||||||
|
shortcode: Zkratka
|
||||||
|
shortcode_hint: Alespoň 2 znaky, pouze alfanumerické znaky a podtržítka
|
||||||
|
title: Vlastní emoji
|
||||||
|
unlisted: Neuvedené
|
||||||
|
update_failed_msg: Nebylo možné aktualizovat toto emoji
|
||||||
|
updated_msg: Emoji úspěšně aktualizováno!
|
||||||
|
upload: Nahrát
|
||||||
|
dashboard:
|
||||||
|
backlog: opožděné úlohy
|
||||||
|
config: Konfigurace
|
||||||
|
feature_deletions: Smazání účtů
|
||||||
|
feature_invites: Pozvánky
|
||||||
|
feature_registrations: Registrace
|
||||||
|
feature_relay: Federovací most
|
||||||
|
features: Vlastnosti
|
||||||
|
hidden_service: Federace se skrytými službami
|
||||||
|
open_reports: otevřená hlášení
|
||||||
|
recent_users: Nedávní uživatelé
|
||||||
|
search: Fulltextové vyhledávání
|
||||||
|
single_user_mode: Režim jednoho uživatele
|
||||||
|
software: Software
|
||||||
|
space: Využití prostoru
|
||||||
|
title: Přehled
|
||||||
|
total_users: uživatelů celkem
|
||||||
|
trends: Trendy
|
||||||
|
week_interactions: interakcí tento týden
|
||||||
|
week_users_active: aktivních tento týden
|
||||||
|
week_users_new: uživatelů tento týden
|
||||||
|
domain_blocks:
|
||||||
|
add_new: Přidat nové
|
||||||
|
created_msg: Blokace domény se právě vyřizuje
|
||||||
|
destroyed_msg: Blokace domény byla zrušena
|
||||||
|
domain: Doména
|
||||||
|
new:
|
||||||
|
create: Vytvořit blokaci
|
||||||
|
hint: Blokace domény nezakáže vytváření účtových záznamů v databázi, ale bude na tyto účty zpětně a automaticky aplikovat specifické metody moderace.
|
||||||
|
severity:
|
||||||
|
desc_html: Funkce <strong>Utišit</strong> zneviditelní příspěvky z účtu komukoliv, kdo jej nesleduje. Funkce <strong>Suspendovat</strong> odstraní všechen obsah, média a profilová data účtu. Pro pouhé odmítnutí mediálních souborů použijte funkci <strong>Žádné</strong>.
|
||||||
|
noop: Žádné
|
||||||
|
silence: Utišit
|
||||||
|
suspend: Suspendovat
|
||||||
|
title: Nová doménová blokace
|
||||||
|
reject_media: Odmítat mediální soubory
|
||||||
|
reject_media_hint: Odstraní lokálně uložené soubory a odmítne jejich stažení v budoucnosti. Irelevantní pro suspenzace
|
||||||
|
severities:
|
||||||
|
noop: Žádné
|
||||||
|
silence: Utišit
|
||||||
|
suspend: Suspendovat
|
||||||
|
severity: Přísnost
|
||||||
|
show:
|
||||||
|
affected_accounts:
|
||||||
|
one: Jeden účet v databázi byl ovlivněn
|
||||||
|
other: "%{count} účtů v databázi byl ovlivněn"
|
||||||
|
retroactive:
|
||||||
|
silence: Odtišit všechny existující účty z této domény
|
||||||
|
suspend: Zrušit suspenzaci všech existujících účtů z této domény
|
||||||
|
title: Zrušit blokaci domény %{domain}
|
||||||
|
undo: Odvolat
|
||||||
|
title: Doménové blokace
|
||||||
|
undo: Odvolat
|
||||||
|
email_domain_blocks:
|
||||||
|
add_new: Přidat nový
|
||||||
|
created_msg: E-mailová doména úspěšně přidána na černou listinu
|
||||||
|
delete: Smazat
|
||||||
|
destroyed_msg: E-mailová doména úspěšně odstraněna z černé listiny
|
||||||
|
domain: Doména
|
||||||
|
new:
|
||||||
|
create: Přidat doménu
|
||||||
|
title: Nový e-mail pro zablokování
|
||||||
|
title: Černá listina e-mailů
|
||||||
|
instances:
|
||||||
|
account_count: Známé účty
|
||||||
|
domain_name: Doména
|
||||||
|
reset: Resetovat
|
||||||
|
search: Hledat
|
||||||
|
title: Známé instance
|
||||||
|
invites:
|
||||||
|
filter:
|
||||||
|
all: Vše
|
||||||
|
available: Dostupné
|
||||||
|
expired: Vypršelé
|
||||||
|
title: Filtrovat
|
||||||
|
title: Pozvánky
|
||||||
|
relays:
|
||||||
|
add_new: Přidat nový most
|
||||||
|
description_html: "<strong>Federovací most</strong> je přechodný server, který vyměňuje velká množství veřejných tootů mezi servery, které z něj odebírají a poblikují na něj. <strong>Může pomoci malým a středně velkým serverům objevovat obsah z fediverse</strong>, což by jinak vyžadovalo, aby místní uživatelé manuálně sledovali jiné lidi na vzdálených serverech."
|
||||||
|
enable_hint: Je-li tohle povoleno, začne váš server odebírat všechny veřejné tooty z tohoto mostu a odesílat na něj své vlastní veřejné tooty.
|
||||||
|
inbox_url: URL mostu
|
||||||
|
setup: Nastavit připojení k mostu
|
||||||
|
status: Stav
|
||||||
|
title: Mosty
|
||||||
|
report_notes:
|
||||||
|
created_msg: Poznámka o nahlášení úspěšně vytvořena!
|
||||||
|
destroyed_msg: Poznámka o nahlášení úspěšně smazána!
|
||||||
|
reports:
|
||||||
|
account:
|
||||||
|
note: poznámka
|
||||||
|
report: nahlášení
|
||||||
|
action_taken_by: Akci vykonal/a
|
||||||
|
are_you_sure: Jste si jistý/á?
|
||||||
|
assign_to_self: Přidělit ke mně
|
||||||
|
assigned: Přiřazený moderátor
|
||||||
|
comment:
|
||||||
|
none: Žádné
|
||||||
|
created_at: Nahlášené
|
||||||
|
id: ID
|
||||||
|
mark_as_resolved: Označit jako vyřešené
|
||||||
|
mark_as_unresolved: Označit jako nevyřešené
|
||||||
|
notes:
|
||||||
|
create: Přidat poznámku
|
||||||
|
create_and_resolve: Vyřešit s poznámkou
|
||||||
|
create_and_unresolve: Znovu otevřít s poznámkou
|
||||||
|
delete: Smazat
|
||||||
|
placeholder: Popište, jaké akce byly vykonány, nebo jakékoliv jiné související aktuality...
|
||||||
|
reopen: Znovu otevřít nahlášení
|
||||||
|
report: 'Nahlásit #%{id}'
|
||||||
|
report_contents: Obsah
|
||||||
|
reported_account: Nahlášený účet
|
||||||
|
reported_by: Nahlášeno uživatelem
|
||||||
|
resolved: Vyřešeno
|
||||||
|
resolved_msg: Nahlášení úspěšně vyřešeno!
|
||||||
|
silence_account: Utišit účet
|
||||||
|
status: Stav
|
||||||
|
suspend_account: Suspendovat účet
|
||||||
|
target: Cíl
|
||||||
|
title: Nahlášení
|
||||||
|
unassign: Odebrat
|
||||||
|
unresolved: Nevyřešeno
|
||||||
|
updated_at: Aktualizováno
|
||||||
|
view: Zobrazit
|
||||||
|
settings:
|
||||||
|
activity_api_enabled:
|
||||||
|
desc_html: Počty lokálně publikovaných statusů, aktivních uživatelů a nových registrací, v týdenních intervalech
|
||||||
|
title: Publikovat hromadné statistiky o uživatelské aktivitě
|
||||||
|
bootstrap_timeline_accounts:
|
||||||
|
desc_html: Je-li uživatelskch jmen více, oddělujte je čárkami. Lze zadat pouze místní a odemknuté účty. Je-li tohle prázdné, jsou výchozí hodnotou všichni místní administrátoři.
|
||||||
|
title: Výchozí sledování pro nové uživatele
|
||||||
|
contact_information:
|
||||||
|
email: Pracovní e-mail
|
||||||
|
username: Uživatelské jméno kontaktu
|
||||||
|
hero:
|
||||||
|
desc_html: Zobrazuje se na hlavní stránce. Doporučuje se rozlišení alespoň 600x100px. Pokud toto není nastavené, bude zobrazena miniatura instance
|
||||||
|
title: Hlavní obrázek
|
||||||
|
peers_api_enabled:
|
||||||
|
desc_html: Domény, na které tato instanve narazila ve fediverse
|
||||||
|
title: Zveřejnit seznam objevených instancí
|
||||||
|
preview_sensitive_media:
|
||||||
|
desc_html: Náhledy odkazů na jiných stránkách budou zobrazeny i pokud jsou media označena jako citlivá
|
||||||
|
title: Zobrazovat v náhledech OpenGraph i citlivá média
|
||||||
|
registrations:
|
||||||
|
closed_message:
|
||||||
|
desc_html: Zobrazí se na hlavní stránce, jsou-li registrace uzavřeny. Můžete použít i HTML značky
|
||||||
|
title: Zpráva o uzavřených registracích
|
||||||
|
deletion:
|
||||||
|
desc_html: Dovolit každému smazání svého účtu
|
||||||
|
title: Zpřístupnit smazání účtu
|
||||||
|
min_invite_role:
|
||||||
|
disabled: Nikdo
|
||||||
|
title: Povolit pozvánky od
|
||||||
|
open:
|
||||||
|
desc_html: Povolit každému vytvořit si účet
|
||||||
|
title: Zpřístupnit registraci
|
||||||
|
show_known_fediverse_at_about_page:
|
||||||
|
desc_html: Je-li toto zapnuto, zobrazí se v náhledu tooty ze všech známých serverů na fediverse. Jinak budou zobrazeny pouze místní tooty.
|
||||||
|
title: Zobrazit celou známou fediverse na náhledu časové osy
|
||||||
|
show_staff_badge:
|
||||||
|
desc_html: Zobrazit na stránce uživatele odznak člena personálu
|
||||||
|
title: Zobrazit odznak personálu
|
||||||
|
site_description:
|
||||||
|
desc_html: Úvodní odstavec na hlavní straně a v meta značkách. Můžete zde používat HTML značky, hlavně <code><a></code> a <code><em></code>.
|
||||||
|
title: Popis instance
|
||||||
|
site_description_extended:
|
||||||
|
desc_html: Dobré místo pro vaše pravidla, pokyny a jiné věci, které vaši instanci odlišují od ostatních. Lze použít HTML značky
|
||||||
|
title: Vlastní doplňujísí informace
|
||||||
|
site_terms:
|
||||||
|
desc_html: Můžete si napsat vlastní zásady soukromí, podmínky používání či jiné legality. Můžete použít HTML značky
|
||||||
|
title: Vlastní podmínky používání
|
||||||
|
site_title: Název instance
|
||||||
|
thumbnail:
|
||||||
|
desc_html: Používáno pro náhledy přes OpenGraph a API. Doporučuje se rozlišení 1200x630px
|
||||||
|
title: Miniatura instance
|
||||||
|
timeline_preview:
|
||||||
|
desc_html: Zobrazit na hlavní straně veřejnou časovou osu
|
||||||
|
title: Náhled časové osy
|
||||||
|
title: Nastavení stránky
|
||||||
|
statuses:
|
||||||
|
back_to_account: Zpět na stránku účtu
|
||||||
|
batch:
|
||||||
|
delete: Vymazat
|
||||||
|
nsfw_off: Označit, že není citlivý
|
||||||
|
nsfw_on: Označit jako citlivý
|
||||||
|
failed_to_execute: Nepodařilo se vykonat
|
||||||
|
media:
|
||||||
|
title: Média
|
||||||
|
no_media: Žádná média
|
||||||
|
title: Statusy účtů
|
||||||
|
with_media: S médii
|
||||||
|
subscriptions:
|
||||||
|
callback_url: Zpáteční URL
|
||||||
|
confirmed: Potvrzeno
|
||||||
|
expires_in: Vyprší v
|
||||||
|
last_delivery: Poslední doručení
|
||||||
|
title: WebSub
|
||||||
|
topic: Téma
|
||||||
|
title: Administrace
|
||||||
|
admin_mailer:
|
||||||
|
new_report:
|
||||||
|
body: "%{reporter} nahlásil/a uživatele %{target}"
|
||||||
|
body_remote: Někdo z %{domain} nahlásil uživatele %{target}
|
||||||
|
subject: Nové nahlášení pro %{instance} (#%{id})
|
||||||
|
application_mailer:
|
||||||
|
notification_preferences: Změnit volby e-mailu
|
||||||
|
salutation: "%{name},"
|
||||||
|
settings: 'Změnit volby e-mailu: %{link}'
|
||||||
|
view: 'Zobrazit:'
|
||||||
|
view_profile: Zobrazit profil
|
||||||
|
view_status: Zobrazit status
|
||||||
|
applications:
|
||||||
|
created: Aplikace úspěšně vytvořena
|
||||||
|
destroyed: Aplikace úspěšně smazána
|
||||||
|
invalid_url: Zadaná adresa URL je neplatná
|
||||||
|
regenerate_token: Znovu vygenerovat přístupový token
|
||||||
|
token_regenerated: Přístupový token byl úspěšně vygenerován
|
||||||
|
warning: Buďte s těmito daty velmi opatrní. Nikdy je s nikým nesdílejte!
|
||||||
|
your_token: Váš přístupový token
|
||||||
|
auth:
|
||||||
|
agreement_html: Registrací souhlasíte s následováním <a href="%{rules_path}">pravidel této instance</a> a <a href="%{terms_path}">našich podmínek používání</a>.
|
||||||
|
change_password: Heslo
|
||||||
|
confirm_email: Potvrdit e-mail
|
||||||
|
delete_account: Odstranit účet
|
||||||
|
delete_account_html: Chcete-li odstranit svůj účet, <a href="%{path}">pokračujte zde</a>. Budete požádán/a o potvrzení.
|
||||||
|
didnt_get_confirmation: Neobdržel/a jste pokyny pro potvrzení?
|
||||||
|
forgot_password: Zapomněl/a jste heslo?
|
||||||
|
invalid_reset_password_token: Token na obnovu hesla je buď neplatný, nebo vypršel. Prosím vyžádejte si nový.
|
||||||
|
login: Přihlásit
|
||||||
|
logout: Odhlásit
|
||||||
|
migrate_account: Přesunout se na jiný účet
|
||||||
|
migrate_account_html: Chcete-li přesměrovat tento účet na jiný, můžete to <a href="%{path}">nastavit zde</a>.
|
||||||
|
or: nebo
|
||||||
|
or_log_in_with: Nebo se přihlaste pomocí
|
||||||
|
providers:
|
||||||
|
cas: CAS
|
||||||
|
saml: SAML
|
||||||
|
register: Registrovat
|
||||||
|
register_elsewhere: Registrovat na jiném serveru
|
||||||
|
resend_confirmation: Znovu odeslat pokyny pro potvrzení
|
||||||
|
reset_password: Obnovit heslo
|
||||||
|
security: Zabezpečení
|
||||||
|
set_new_password: Nastavit nové heslo
|
||||||
|
authorize_follow:
|
||||||
|
already_following: Tento účet již sledujete
|
||||||
|
error: Při hledání vzdáleného účtu bohužel nastala chyba
|
||||||
|
follow: Sledovat
|
||||||
|
follow_request: 'Poslal/a jste žádost o sledování uživateli:'
|
||||||
|
following: 'Podařilo se! Nyní sledujete uživatele:'
|
||||||
|
post_follow:
|
||||||
|
close: Nebo můžete toto okno klidně zavřít.
|
||||||
|
return: Zobrazit profil uživatele
|
||||||
|
web: Přejít na web
|
||||||
|
title: Sledovat uživatele %{acct}
|
||||||
|
datetime:
|
||||||
|
distance_in_words:
|
||||||
|
about_x_hours: "%{count} hod"
|
||||||
|
about_x_months: "%{count} měsíců"
|
||||||
|
about_x_years: "%{count} let"
|
||||||
|
almost_x_years: "%{count} let"
|
||||||
|
half_a_minute: Právě teď
|
||||||
|
less_than_x_minutes: "%{count} min"
|
||||||
|
less_than_x_seconds: Právě teď
|
||||||
|
over_x_years: "%{count} let"
|
||||||
|
x_days: "%{count} dní"
|
||||||
|
x_minutes: "%{count} min"
|
||||||
|
x_months: "%{count} mesíců"
|
||||||
|
x_seconds: "%{count} s"
|
||||||
|
deletes:
|
||||||
|
bad_password_msg: Dobrý pokus, hackeři! Nesprávné heslo
|
||||||
|
confirm_password: Zadejte svoje současné heslo pro ověření vaší identity
|
||||||
|
description_html: Tímto <strong>trvale a nenávratně</strong> odstraníte obsah z vašeho účtu a deaktivuje ho. Vaše uživatelské jméno zůstane rezervované pro zabránění budoucím napodobováním.
|
||||||
|
proceed: Odstranit účet
|
||||||
|
success_msg: Váš účet byl úspěšně odstraněn
|
||||||
|
warning_html: Pouze vymazání obsahu z této konkrétní instance je zaručeno. Obsah, který byl široce sdílen, po sobě pravděpodobně zanechá stopy. U offline serverů a serverů, které vaše aktualizace již neodebírají, nebudou databáze aktualizovány.
|
||||||
|
warning_title: Dostupnost rozšířeného obsahu
|
||||||
|
errors:
|
||||||
|
'403': Nemáte povolení zobrazit tuto stránku.
|
||||||
|
'404': Stránka, kterou hledáte, neexistuje.
|
||||||
|
'410': Stránka, kterou hledáte, již neexistuje.
|
||||||
|
'422':
|
||||||
|
content: Bezpečnostní ověření selhalo. Neblokujete cookoes?
|
||||||
|
title: Bezpečnostní ověření selhalo
|
||||||
|
'429': Příliš mnoho požadavků
|
||||||
|
'500':
|
||||||
|
content: Omlouváme se, ale něco se pokazilo u nás.
|
||||||
|
title: Tato stránka není správná
|
||||||
|
noscript_html: Pro použití webové aplikace Mastodon prosím povolte JavaScript. Nebo zkuste jednu z <a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">nativních aplikací</a> pro Mastodon pro vaši platformu.
|
||||||
|
exports:
|
||||||
|
archive_takeout:
|
||||||
|
date: Datum
|
||||||
|
download: Stáhnout svůj archiv
|
||||||
|
hint_html: Můžete si vyžádat archiv vašich <strong>tootů a nahraných médií</strong>. Exportovaná data budou ve formátu ActivityPub a budou čitelné kterýmkoliv kompatibilním softwarem. Archiv si můžete vyžádat každých 7 dní.
|
||||||
|
in_progress: Kompiluji váš archiv...
|
||||||
|
request: Vyžádat svůj archiv
|
||||||
|
size: Velikost
|
||||||
|
blocks: Blokujete
|
||||||
|
csv: CSV
|
||||||
|
follows: Sledujete
|
||||||
|
mutes: Ignorujete
|
||||||
|
storage: Úložisko médií
|
||||||
|
filters:
|
||||||
|
contexts:
|
||||||
|
home: Domovská časová osa
|
||||||
|
notifications: Oznámení
|
||||||
|
public: Veřejný časové osy
|
||||||
|
thread: Konverzace
|
||||||
|
edit:
|
||||||
|
title: Upravit filtr
|
||||||
|
errors:
|
||||||
|
invalid_context: Nebylo poskytnuto nic, nebo má neplatný kontext
|
||||||
|
invalid_irreversible: Nezvratné filtrování funguje pouze v souvislosti s domovskou osou či oznámeními
|
||||||
|
index:
|
||||||
|
delete: Smazat
|
||||||
|
title: Filtry
|
||||||
|
new:
|
||||||
|
title: Přidat nový filtr
|
||||||
|
followers:
|
||||||
|
domain: Doména
|
||||||
|
explanation_html: Chcete-li zaručit soukromí vašich statusů, musíte mít na vědomí, kdo vás sleduje. <strong>Vaše soukromé statusy jsou doručeny na všechny instance, kde máte sledovatele</strong>. Nejspíš si je budete chtít zkontrolovat a odstranit sledovatele na instancích, jejichž personálu či softwaru nedůvěřujete s respektováním vašeho soukromí.
|
||||||
|
followers_count: Počet sledovatelů
|
||||||
|
lock_link: Zamkněte svůj účet
|
||||||
|
purge: Odstranit ze sledovatelů
|
||||||
|
success:
|
||||||
|
one: V průběhu utišování sledovatelů z jedné domény...
|
||||||
|
other: V průběhu utišování sledovatelů z %{count} domén...
|
||||||
|
true_privacy_html: Berte prosím na vědomí, že <strong>skutečného soukromí se dá dosáhnout pouze za pomoci end-to-end šifrování</strong>.
|
||||||
|
unlocked_warning_html: Kdokoliv vás může sledovat a okamžitě vidět vaše soukromé statusy. %{lock_link}, abyste mohl/a zkontrolovat a odmítnout sledovatele.
|
||||||
|
unlocked_warning_title: Váš účet není zamknutý
|
||||||
|
generic:
|
||||||
|
changes_saved_msg: Změny byly úspěšně uloženy!
|
||||||
|
save_changes: Uložit změny
|
||||||
|
validation_errors:
|
||||||
|
one: Něco ještě není úplně v pořádku! Prosím zkontrolujte chybu níže
|
||||||
|
other: Něco ještě není úplně v pořádku! Prosím zkontrolujte %{count} chyb níže
|
||||||
|
imports:
|
||||||
|
preface: Můžete importovat data, která jste exportoval/a z jiné instance, jako například seznam lidí, které sledujete či blokujete.
|
||||||
|
success: Vaše data byla úspěšně nahrána a nyní budou zpracována v daný čas
|
||||||
|
types:
|
||||||
|
blocking: Seznam blokovaných
|
||||||
|
following: Seznam sledovaných
|
||||||
|
muting: Seznam ignorovaných
|
||||||
|
upload: Nahrát
|
||||||
|
in_memoriam_html: Navždy budeme vzpomínat.
|
||||||
|
invites:
|
||||||
|
delete: Deaktivovat
|
||||||
|
expired: Vypršelé
|
||||||
|
expires_in:
|
||||||
|
'1800': 30 minut
|
||||||
|
'21600': 6 hodin
|
||||||
|
'3600': 1 hodina
|
||||||
|
'43200': 12 hodin
|
||||||
|
'604800': 1 týden
|
||||||
|
'86400': 1 den
|
||||||
|
expires_in_prompt: Nikdy
|
||||||
|
generate: Vygenerovat
|
||||||
|
invited_by: 'Byl/a jste pozván/a uživatelem:'
|
||||||
|
max_uses:
|
||||||
|
one: 1 použití
|
||||||
|
other: "%{count} použití"
|
||||||
|
max_uses_prompt: Bez limitu
|
||||||
|
prompt: Vygenerujte a sdílejte s ostatními odkazy a umožněte jim přístup na tuto instanci
|
||||||
|
table:
|
||||||
|
expires_at: Vyprší
|
||||||
|
uses: Použití
|
||||||
|
title: Pozvěte lidi
|
||||||
|
lists:
|
||||||
|
errors:
|
||||||
|
limit: Dosáhl/a jste maximálního počtu seznamů
|
||||||
|
media_attachments:
|
||||||
|
validations:
|
||||||
|
images_and_video: Ke statusu, který již obsahuje obrázky, nelze připojit video
|
||||||
|
too_many: Nelze připojit více než 4 soubory
|
||||||
|
migrations:
|
||||||
|
acct: přezdívka@doména nového účtu
|
||||||
|
currently_redirecting: 'Váš profil má nastaveno přesměrování na:'
|
||||||
|
proceed: Uložit
|
||||||
|
updated_msg: Vaše nastavení migrace účtu bylo úspěšně aktualizováno!
|
||||||
|
moderation:
|
||||||
|
title: Moderace
|
||||||
|
notification_mailer:
|
||||||
|
digest:
|
||||||
|
action: Zobrazit všechna oznámení
|
||||||
|
body: Zde najdete stručný souhrn zpráv, které jste zmeškal/a od vaší poslední návštěvy %{since}
|
||||||
|
mention: "%{name} vás zmínil/a v:"
|
||||||
|
new_followers_summary:
|
||||||
|
one: Navíc jste získal/a jednoho nového sledovatele, zatímco jste byl/a pryč! Hurá!
|
||||||
|
other: Navíc jste získal/a %{count} nových sledovatelů, zatímco jste byl/a pryč! Hurá!
|
||||||
|
subject:
|
||||||
|
one: "Jedno nové oznámení od vaší poslední návštěvy \U0001F418"
|
||||||
|
other: "%{count} nových oznámení od vaší poslední návštěvy \U0001F418"
|
||||||
|
title: Ve vaší absenci...
|
||||||
|
favourite:
|
||||||
|
body: 'Váš status si oblíbil/a %{name}:'
|
||||||
|
subject: "%{name} si oblíbil/a váš status"
|
||||||
|
title: Nové oblíbení
|
||||||
|
follow:
|
||||||
|
body: "%{name} vás nyní sleduje!"
|
||||||
|
subject: "%{name} vás nyní sleduje"
|
||||||
|
title: Nový sledovatel
|
||||||
|
follow_request:
|
||||||
|
action: Spravovat žádosti o sledování
|
||||||
|
body: "%{name} žádá o povolení vás následovat"
|
||||||
|
subject: 'Čekající sledovatel: %{name}'
|
||||||
|
title: Nová žádost o sledování
|
||||||
|
mention:
|
||||||
|
action: Odpovědět
|
||||||
|
body: 'Byl/a jste zmíněn/a uživatelem %{name} v:'
|
||||||
|
subject: Byl/a jste zmíněn/a uživatelem %{name}
|
||||||
|
title: Nová zmínka
|
||||||
|
reblog:
|
||||||
|
body: 'Váš status byl boostnutý uživatelem %{name}:'
|
||||||
|
subject: "%{name} boostnul/a váš status"
|
||||||
|
title: Nové boostnutí
|
||||||
|
number:
|
||||||
|
human:
|
||||||
|
decimal_units:
|
||||||
|
format: "%n %u"
|
||||||
|
units:
|
||||||
|
billion: mld
|
||||||
|
million: mil
|
||||||
|
quadrillion: bld
|
||||||
|
thousand: tis
|
||||||
|
trillion: T
|
||||||
|
pagination:
|
||||||
|
newer: Novější
|
||||||
|
next: Starší
|
||||||
|
older: Starší
|
||||||
|
prev: Před
|
||||||
|
truncate: "…"
|
||||||
|
preferences:
|
||||||
|
languages: Jazyky
|
||||||
|
other: Ostatní
|
||||||
|
publishing: Publikování
|
||||||
|
web: Web
|
||||||
|
remote_follow:
|
||||||
|
acct: Napište svou přezdívku@doménu, ze které chcete sledovat
|
||||||
|
missing_resource: Nemůžeme najít požadované přesměrovací URL pro váš účet
|
||||||
|
no_account_html: Ještě nemáte účet? Můžete se <a href='%{sign_up_path}' target='_blank'>registrovat zde</a>
|
||||||
|
proceed: Pokračujte pro sledování
|
||||||
|
prompt: 'Budete sledovat:'
|
||||||
|
remote_unfollow:
|
||||||
|
error: Chyba
|
||||||
|
title: Nadpis
|
||||||
|
unfollowed: Už nesledujete
|
||||||
|
sessions:
|
||||||
|
activity: Nejnovější aktivita
|
||||||
|
browser: Prohlížeč
|
||||||
|
browsers:
|
||||||
|
alipay: Alipay
|
||||||
|
blackberry: Blackberry
|
||||||
|
chrome: Chrome
|
||||||
|
edge: Microsoft Edge
|
||||||
|
electron: Electron
|
||||||
|
firefox: Firefox
|
||||||
|
generic: Neznámý prohlížeč
|
||||||
|
ie: Internet Explorer
|
||||||
|
micro_messenger: MicroMessenger
|
||||||
|
nokia: Nokia S40 Ovi Browser
|
||||||
|
opera: Opera
|
||||||
|
otter: Otter
|
||||||
|
phantom_js: PhantomJS
|
||||||
|
qq: QQ Browser
|
||||||
|
safari: Safari
|
||||||
|
uc_browser: UCBrowser
|
||||||
|
weibo: Weibo
|
||||||
|
current_session: Aktuální relace
|
||||||
|
description: "%{browser} na %{platform}"
|
||||||
|
explanation: Toto jsou webové prohlížeče aktuálně přihlášené na váš účet Mastodon.
|
||||||
|
ip: IP
|
||||||
|
platforms:
|
||||||
|
adobe_air: Adobe Air
|
||||||
|
android: Android
|
||||||
|
blackberry: Blackberry
|
||||||
|
chrome_os: Chrome OS
|
||||||
|
firefox_os: Firefox OS
|
||||||
|
ios: iOS
|
||||||
|
linux: Linux
|
||||||
|
mac: Mac
|
||||||
|
other: neznámé platformě
|
||||||
|
windows: Windows
|
||||||
|
windows_mobile: Windows Mobile
|
||||||
|
windows_phone: Windows Phone
|
||||||
|
revoke: Zamítnout
|
||||||
|
revoke_success: Relace úspěšně zamítnuta
|
||||||
|
title: Relace
|
||||||
|
settings:
|
||||||
|
authorized_apps: Autorizované aplikace
|
||||||
|
back: Zpět na Mastodon
|
||||||
|
delete: Smazání účtu
|
||||||
|
development: Vývoj
|
||||||
|
edit_profile: Upravit profil
|
||||||
|
export: Export dat
|
||||||
|
followers: Autorizovaní sledovatelé
|
||||||
|
import: Import
|
||||||
|
migrate: Přesunutí účtu
|
||||||
|
notifications: Oznámení
|
||||||
|
preferences: Předvolby
|
||||||
|
settings: Nastavení
|
||||||
|
two_factor_authentication: Dvoufaktorové ověřování
|
||||||
|
your_apps: Vaše aplikace
|
||||||
|
statuses:
|
||||||
|
attached:
|
||||||
|
description: 'Přiloženo: %{attached}'
|
||||||
|
image:
|
||||||
|
one: "%{count} obrázek"
|
||||||
|
other: "%{count} obrázků"
|
||||||
|
video:
|
||||||
|
one: "%{count} video"
|
||||||
|
other: "%{count} videí"
|
||||||
|
boosted_from_html: Boostnuto z %{acct_link}
|
||||||
|
content_warning: 'Varování o obsahu: %{warning}'
|
||||||
|
disallowed_hashtags:
|
||||||
|
one: 'obsahuje nepovolený hashtag: %{tags}'
|
||||||
|
other: 'obsahuje nepovolené hashtagy: %{tags}'
|
||||||
|
language_detection: Zjistit jazyk automaticky
|
||||||
|
open_in_web: Otevřít na webu
|
||||||
|
over_character_limit: limit %{max} znaků byl překročen
|
||||||
|
pin_errors:
|
||||||
|
limit: Už jste si připnul/a maximální počet tootů
|
||||||
|
ownership: Nelže připnout toot někoho jiného
|
||||||
|
private: Nelze připnout neveřejné tooty
|
||||||
|
reblog: Nelze připnout boostnutí
|
||||||
|
show_more: Zobrazit více
|
||||||
|
title: '%{name}: "%{quote}"'
|
||||||
|
visibilities:
|
||||||
|
private: Pouze pro sledovatele
|
||||||
|
private_long: Zobrazit pouze sledovatelům
|
||||||
|
public: Veřejné
|
||||||
|
public_long: Všichni mohou vidět
|
||||||
|
unlisted: Neuvedené
|
||||||
|
unlisted_long: Všichni mohou vidět, ale není zahrnut ve veřejných časových osách
|
||||||
|
stream_entries:
|
||||||
|
pinned: Připnutý toot
|
||||||
|
reblogged: boostnutý
|
||||||
|
sensitive_content: CItlivý obsah
|
||||||
|
terms:
|
||||||
|
body_html: |
|
||||||
|
<h2>Zásady soukromí</h2>
|
||||||
|
<h3 id="collect">Jaké informace sbíráme?</h3>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><em>Základní informace o účtu</em>: Pokud se na tomto serveru zaregistrujete, můžeme vás požádat o zadání uživatelského jména, e-mailové adresy a hesla. Můžete také zadat dodatečné profilové informace, jako například zobrazované jméno a krátký životopis, a nahrát si profilovou fotografii a hlavičkový obrázek. Uživatelské i zobrazované jméno, životopis, profilová fotografie a hlavičkový obrázek jsou vždy uvedeny veřejně.</li>
|
||||||
|
<li><em>Příspěvky, sledovatelé a další veřejné informace</em>: Seznam lidí, které sledujete, je uveden veřejně, totéž platí i pro vaše sledovatele. Když sem nahrajete zprávu, bude uloženo datum a čas, společně s aplikací, ze které jste zprávu odeslali. Zprávy mohou obsahovat mediální přílohy, jako jsou obrázky a videa. Veřejné a nezobrazované příspěvky jsou dostupné veřejně. Pokud na vašem profilu uvedete příspěvek, je to také veřejně dostupná informace. Vaše příspěvky jsou doručeny vašim sledovatelům, což v některých případech znamená, že budou doručeny na různé servery, na kterých budou ukládány kopie. Pokud příspěvky smažete, bude tohle taktéž doručeno vašim sledovatelům. Akce znovusdílení nebo oblíbení jiného příspěvku je vždy veřejná.</li>
|
||||||
|
<li><em>Příspěvky přímé a pouze pro sledovatele</em>: Všechny příspěvky jsou uloženy a zpracovány na serveru. Příspěvky pouze pro sledovatele jsou doručeny vašim sledovatelům a uživateům v nich zmíněných a přímé příspěvky jsou doručeny pouze uživatelům v nich zmíněných. V některých případech tohle znamená, že budou doručeny na různé servery, na kterých budou ukládány kopie. Snažíme se omezit přístup k těmto příspěvkům pouze na autorizované uživatele, ovšem jiné servery tak nemusejí učinit. Proto je důležité posoudit servery, ke kterým vaši sledovatelé patří. V nastavení si můžete zapnout volbu pro manuální schvalování či odmítnutí nových sledovatelů. <em>Prosím mějte na paměti, že operátoři tohoto serveru a kteréhokoliv přijímacího serveru mohou tyto zprávy vidět</em> a příjemci mohou vytvořit jejich snímek, zkopírovat je, nebo je jinak sdílet. <em>Nesdílejte přes Mastodon jakékoliv nebezpečné informace.</em></li>
|
||||||
|
<li><em>IP adresy a další metadata</em>: Když se přihlásíte, zaznamenáváme IP adresu, ze které se přihlašujete, jakožto i název vašeho webového prohlížeče. Všechny vaše webové relace jsou v nastavení přístupné k vašemu posouzení a odvolání. Nejpozdější IP adresa použita je uložena maximálně do 12 měsíců. Můžeme také uchovávat serverové záznamy, které obsahují IP adresy každého požadavku odeslaného na náš server.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<hr class="spacer" />
|
||||||
|
|
||||||
|
<h3 id="use">Na co používáme vaše informace?</h3>
|
||||||
|
|
||||||
|
<p>Jakékoliv informace, které sbíráme, mohou být použity následujícími způsoby:</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>K poskytnutí základních funkcí Mastodonu. Interagovat s obsahem od jiných lidí a přispívat svým vlastním obsahem můžete pouze, pokud jste přihlášeni. Můžete například sledovat jiné lidi a zobrazit si jejich kombinované příspěvky ve vaší vlastní personalizované časové ose.</li>
|
||||||
|
<li>Pro pomoc moderaci komunity, například porovnáním vaší IP adresy s dalšími známými adresami pro určení vyhýbání se zákazům či jiných přestupků.</li>
|
||||||
|
<li>E-mailová adresa, kterou nám poskytnete, může být použita pro zasílání informací, oznámení o interakcích jiných uživatelů s vaším obsahem nebo přijatých zprávách a k odpovědím na dotazy a/nebo další požadavky či otázky.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<hr class="spacer" />
|
||||||
|
|
||||||
|
<h3 id="protect">Jak vaše informace chráníme?</h3>
|
||||||
|
|
||||||
|
<p>Implenentujeme různá bezpečnostní opatření pro udržování bezpečnosti vašich osobních dat, když zadáváte, odesíláte, či přistupujete k vašim osobním datům. Mimo jiné je vaše relace v prohlížeči, jakož i provoz mezi vašimi aplikacemi a API, zabezpečena pomocí SSL, a vaše heslo je hashováno pomocí silného jednosměrného algoritmu. Pro větší zabezpečení vašeho účtu můžete povolit dvoufaktorovou autentikaci.</p>
|
||||||
|
|
||||||
|
<hr class="spacer" />
|
||||||
|
|
||||||
|
<h3 id="data-retention">Jaké jsou naše zásady o uchovávání údajů?</h3>
|
||||||
|
|
||||||
|
<p>Budeme se snažit:</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Uchovávat serverové záznamy obsahující IP adresy všech požadavků pro tento server, pokud se takové záznamy uchovávají, maximálně 90 dní.</li>
|
||||||
|
<li>Uchovávat IP adresy související s registrovanými uživateli maximálně 12 měsíců.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>Kdykoliv si můžete vyžádat a stáhnout archiv vašeho obsahu, včetně vašich příspěvků, mediálních příloh, profilové fotografie a hlavičkového obrázku.</p>
|
||||||
|
|
||||||
|
<p>Kdykoliv můžete nenávratně smazat váš účet.</p>
|
||||||
|
|
||||||
|
<hr class="spacer"/>
|
||||||
|
|
||||||
|
<h3 id="cookies">Používáme cookies?</h3>
|
||||||
|
|
||||||
|
<p>Ano. Cookies jsou malé soubory, které stránka nebo její poskytovatel uloží na pevný disk vašeho počítače (pokud to dovolíte). Tyto cookies umožňují stránce rozpoznat váš prohlížeč a, pokud máte registrovaný účet, přidružit ho s vaším registrovaným účtem.</p>
|
||||||
|
|
||||||
|
<p>POužíváme cookies pro pochopení a ukládání vašich předvoleb pro budoucí návštěvy.</p>
|
||||||
|
|
||||||
|
<hr class="spacer" />
|
||||||
|
|
||||||
|
<h3 id="disclose">Zveřejňujeme jakékoliv informace třetím stranám?</h3>
|
||||||
|
|
||||||
|
<p>Vaše osobně identifikovatelné informace neprodáváme, neobchodujeme s nimi, ani je nijak nepřenášíme vnějším stranám. Do tohoto se nepočítají důvěryhodné třetí strany, které nám pomáhají provozovat naši stránku, podnikat, nebo vás obsluhovat, pokud tyto strany souhlasí se zachováním důvěrnosti těchto informací. Můžeme také uvolnit vaše informace, pokud věříme, že je to nutné pro soulad se zákonem, prosazování našich zásad, nebo ochranu práv, majetku, či bezpečnost nás či ostatních.</p>
|
||||||
|
|
||||||
|
<p>Váš veřejný obsah může být stažen jinými servery na síti. Vaše příspěvky veřejné a pouze pro sledovatele budou doručeny na servery vašich sledovatelů a přímé zprávy budou doručeny na servery příjemců, pokud jsou tito sledovatelé nebo příjemci zaregistrováni na jiném serveru, než je tento.</p>
|
||||||
|
|
||||||
|
<p>Když autorizujete aplikaci, aby používala váš účet, může, v závislosti na rozsahu oprávnění, které jí udělíte, přistupovat k vašim veřejným profilovým informacím, seznamu lidí, které sledujete, vašim sledovatelům, vašim seznamům, všem vašim příspěvkům a příspěvkům, které jste si oblíbili. Aplikace nikdy nemohou získat vaši e-mailovou adresu či heslo.</p>
|
||||||
|
|
||||||
|
<hr class="spacer" />
|
||||||
|
|
||||||
|
<h3 id="children">Používání stránky dětmi</h3>
|
||||||
|
|
||||||
|
<p>Pokud se tento server nachází v EU nebo EHP: Naše stránka, produkty a služby jsou všechny směřovány na lidi, kterým je alespoň 16 let. Pokud je vám méně než 16, dle požadavků nařízení GDPR (<a href="https://cs.wikipedia.org/wiki/Obecn%C3%A9_na%C5%99%C3%ADzen%C3%AD_o_ochran%C4%9B_osobn%C3%ADch_%C3%BAdaj%C5%AF">Obecné nařízení o ochě sobních údajů</a>) </p>
|
||||||
|
|
||||||
|
<p>Pokud se tento server nachází v USA: Naše stránka, produkty a služby jsou všechny směřovány na lidi, kterým je alespoň 13 let. Pokud je vám méně než 13, dle požadavků zákona COPPA (<a href="https://cs.wikipedia.org/wiki/Children%27s_online_privacy_protection_act">Children's Online Privacy Protection Act</a>) tuto stránku nepoužívejte.</p>
|
||||||
|
|
||||||
|
<p>Právní požadavky mohou být jiné, pokud se tento server nachází v jiné jurisdikci.</p>
|
||||||
|
|
||||||
|
<hr class="spacer" />
|
||||||
|
|
||||||
|
<h3 id="changes">Změny v našich zásadách soukromí</h3>
|
||||||
|
|
||||||
|
<p>Rozhodneme-li se naše zásady soukromí změnit, zveřejníme tyto změny na této stránce.</p>
|
||||||
|
|
||||||
|
<p>Tento dokument je dostupný pod licencí CC-BY-SA. Byl naposledy aktualizován 7 března 2018.</p>
|
||||||
|
|
||||||
|
<p>Původně adaptováno ze <a href="https://github.com/discourse/discourse">zásad soukromí Discourse</a>.</p>
|
||||||
|
title: Podmínky používání a zásady soukromí %{instance}
|
||||||
|
themes:
|
||||||
|
contrast: Vysoký kontrast
|
||||||
|
default: Mastodon
|
||||||
|
mastodon-light: Mastodon (světlý)
|
||||||
|
time:
|
||||||
|
formats:
|
||||||
|
default: "%d. %b %Y, %H:%M"
|
||||||
|
two_factor_authentication:
|
||||||
|
code_hint: Pro potvrzení zadejte kód vygenerovaný vaší autentikační aplikací
|
||||||
|
description_html: Povolíte-li <strong>dvoufaktorové ověřování</strong>, budete při přihlášení potřebovat telefon, který vám vygeneruje přístupové tokeny, které musíte zadat.
|
||||||
|
disable: Zakázat
|
||||||
|
enable: Povolit
|
||||||
|
enabled: Dvoufaktorové ověřování je povoleno
|
||||||
|
enabled_success: Dvoufaktorové ověřování bylo úspěšně povoleno
|
||||||
|
generate_recovery_codes: Vygenerovat záložní kódy
|
||||||
|
instructions_html: "<strong>Naskenujte tento QR kód Google Authenticatorem nebo jinou TOTP aplikací na vašem telefonu</strong>. Od teď bude tato aplikace generovat tokeny, které budete muset zadat při přihlášení."
|
||||||
|
lost_recovery_codes: Záložní kódy vám dovolí dostat se k vašemu účtu, pokud ztratíte telefon. Ztratíte-li záložní kódy, můžete je zde znovu vygenerovat. Vaše staré záložní kódy budou zneplatněny.
|
||||||
|
manual_instructions: 'Nemůžete-li oskenovat QR kód a je potřebovat ho zadat ručně, zde je tajemství v prostém textu:'
|
||||||
|
recovery_codes: Záložní kódy pro obnovu
|
||||||
|
recovery_codes_regenerated: Záložní kódy byly úspěšně znovu vygenerované
|
||||||
|
recovery_instructions_html: Ztratíte-li někdy přístup k vašemu telefonu, můžete k získání přístupu k účtu použít jeden ze záložních kódů. <strong>Uchovávejte tyto kódy v bezpečí</strong>. Můžete si je například vytisknout a uložit je mezi jiné důležité dokumenty.
|
||||||
|
setup: Nastavit
|
||||||
|
wrong_code: Zadaný kód byl neplatný! Je serverový čas a čas na zařízení správný?
|
||||||
user_mailer:
|
user_mailer:
|
||||||
|
backup_ready:
|
||||||
|
explanation: Vyžádal/a jste si úplnou zálohu svého účtu Mastodon. Nyní je připravena ke stažení!
|
||||||
|
subject: Váš archiv je připraven ke stažení
|
||||||
|
title: Stažení archivu
|
||||||
welcome:
|
welcome:
|
||||||
|
edit_profile_action: Nastavit profil
|
||||||
|
edit_profile_step: Můžete si přizpůsobit svůj profil nahráním avataru a obrázku na hlavičce, změnou zobrazovaného jména a dalších. Chcete-li posoudit nové sledovatele předtím, než vás mohou sledovat, můžete svůj účet uzamknout.
|
||||||
|
explanation: Zde je pár tipů na začátek
|
||||||
|
final_action: Začněte přispívat
|
||||||
|
final_step: 'Začněte psát! I když nemáte sledovatele, mohou vaše zprávy vidět jiní lidé, například na místní časové ose a mezi hashtagy. Můžete se ostatním představit pomocí hashtagu #introductions.'
|
||||||
|
full_handle: Vaše celá adresa profilu
|
||||||
|
full_handle_hint: Tohle je, co byste řekl/a svým přátelům, aby vám mohli posílat zprávy nebo vás sledovat z jiné instance.
|
||||||
|
review_preferences_action: Změnit nastavení
|
||||||
|
review_preferences_step: Nezapomeňte si nastavit své volby, například jaké e-maily chcete přijímat či jak soukromé mají být vaše příspěvky ve výchozím stavu. Nemáte-li epilepsii, můžete si nastavit automatické přehrávání obrázků GIF.
|
||||||
|
subject: Vítejte na Mastodonu
|
||||||
|
tip_bridge_html: Pokud přicházíte z Twitteru, můžete najít vaše přátele na Mastodonu pomocí <a href="%{bridge_url}">mostové aplikace</a>. Funguje ovšem pouze, pokud ji oni někdy také použili!
|
||||||
|
tip_federated_timeline: Federovaná časová osa je náhled celé sítě Mastodon. Zahrnuje ovšem pouze lidi, které sledují vaši sousedé, takže není úplná.
|
||||||
|
tip_following: Administrátora/y serveru sledujete automaticky. Chcete-li najít další zajímavé lidi, podívejte se na místní a federované časové osy.
|
||||||
|
tip_local_timeline: Místní časová osa je náhled lidí na %{instance}. Toto jsou vaši nejbližší sousedé!
|
||||||
|
tip_mobile_webapp: Pokud vám váš mobilní prohlížeč nabídne přidat si Mastodon na vaši domovskou obrazovku, můžete dostávat oznámení. V mnoha ohledech to funguje jako nativní aplikace!
|
||||||
tips: Tipy
|
tips: Tipy
|
||||||
title: Vítejte na palubě, %{name}!
|
title: Vítejte na palubě, %{name}!
|
||||||
users:
|
users:
|
||||||
invalid_email: E-mailová adresa je neplatná
|
invalid_email: E-mailová adresa je neplatná
|
||||||
|
invalid_otp_token: Neplatný kód pro dvoufaktorovou autentikaci
|
||||||
|
otp_lost_help_html: Pokud jste ztratil/a přístup k oběma, můžete se spojit %{email}
|
||||||
|
seamless_external_login: Jste přihlášen/a přes externí službu, nastavení hesla a e-mailu proto nejsou dostupná.
|
||||||
signed_in_as: 'Přihlášen/a jako:'
|
signed_in_as: 'Přihlášen/a jako:'
|
||||||
|
|
|
@ -46,7 +46,6 @@ da:
|
||||||
people_who_follow: Folk der følger %{name}
|
people_who_follow: Folk der følger %{name}
|
||||||
posts: Dyt
|
posts: Dyt
|
||||||
posts_with_replies: Toots og svar
|
posts_with_replies: Toots og svar
|
||||||
remote_follow: Følg fra andre instanser
|
|
||||||
reserved_username: Brugernavnet er reserveret
|
reserved_username: Brugernavnet er reserveret
|
||||||
roles:
|
roles:
|
||||||
admin: Administrator
|
admin: Administrator
|
||||||
|
@ -464,7 +463,6 @@ da:
|
||||||
unlocked_warning_title: Din konto er ikke låst
|
unlocked_warning_title: Din konto er ikke låst
|
||||||
generic:
|
generic:
|
||||||
changes_saved_msg: Ændringerne blev gemt!
|
changes_saved_msg: Ændringerne blev gemt!
|
||||||
powered_by: drevet af %{link}
|
|
||||||
save_changes: Gem ændringer
|
save_changes: Gem ændringer
|
||||||
imports:
|
imports:
|
||||||
types:
|
types:
|
||||||
|
@ -511,6 +509,9 @@ da:
|
||||||
action: Se alle notifikationer
|
action: Se alle notifikationer
|
||||||
mention: "%{name} nævnte dig i:"
|
mention: "%{name} nævnte dig i:"
|
||||||
title: Mens du var væk...
|
title: Mens du var væk...
|
||||||
|
favourite:
|
||||||
|
body: 'Din status blev favoriseret af %{name}:'
|
||||||
|
subject: "%{name} favoriserede din status"
|
||||||
follow:
|
follow:
|
||||||
body: "%{name} følger dig nu!"
|
body: "%{name} følger dig nu!"
|
||||||
subject: "%{name} følger dig nu"
|
subject: "%{name} følger dig nu"
|
||||||
|
@ -538,18 +539,22 @@ da:
|
||||||
preferences:
|
preferences:
|
||||||
languages: Sprog
|
languages: Sprog
|
||||||
other: Andet
|
other: Andet
|
||||||
|
publishing: Offentligører
|
||||||
web: Web
|
web: Web
|
||||||
remote_unfollow:
|
remote_unfollow:
|
||||||
error: Fejl
|
error: Fejl
|
||||||
title: Titel
|
title: Titel
|
||||||
unfollowed: Følger ikke længere
|
unfollowed: Følger ikke længere
|
||||||
sessions:
|
sessions:
|
||||||
|
activity: Sidste aktivitet
|
||||||
|
browser: Browser
|
||||||
browsers:
|
browsers:
|
||||||
blackberry: Blackberry OS
|
blackberry: Blackberry OS
|
||||||
chrome: Google Chrome
|
chrome: Google Chrome
|
||||||
firefox: Mozilla Firefox
|
firefox: Mozilla Firefox
|
||||||
generic: Ukendt browser
|
generic: Ukendt browser
|
||||||
ie: IE
|
ie: IE
|
||||||
|
safari: Apple Safari
|
||||||
description: "%{browser} på %{platform}"
|
description: "%{browser} på %{platform}"
|
||||||
ip: IP
|
ip: IP
|
||||||
platforms:
|
platforms:
|
||||||
|
@ -583,7 +588,9 @@ da:
|
||||||
content_warning: 'Advarsel om indhold: %{warning}'
|
content_warning: 'Advarsel om indhold: %{warning}'
|
||||||
language_detection: Opfang automatisk sprog
|
language_detection: Opfang automatisk sprog
|
||||||
pin_errors:
|
pin_errors:
|
||||||
|
limit: Du har allerede fastgjort det maksimale antal trut
|
||||||
ownership: Dun kan ikke fastgøre en anden persons toot
|
ownership: Dun kan ikke fastgøre en anden persons toot
|
||||||
|
private: Ikke offentlige trut kan ikke blive fastgjort
|
||||||
show_more: Vis mere
|
show_more: Vis mere
|
||||||
title: '%{name}: "%{quote}"'
|
title: '%{name}: "%{quote}"'
|
||||||
visibilities:
|
visibilities:
|
||||||
|
@ -593,7 +600,6 @@ da:
|
||||||
public_long: Alle kan se
|
public_long: Alle kan se
|
||||||
unlisted: Ikke listet
|
unlisted: Ikke listet
|
||||||
stream_entries:
|
stream_entries:
|
||||||
click_to_show: Tryk for at vise
|
|
||||||
pinned: Fastgjort toot
|
pinned: Fastgjort toot
|
||||||
sensitive_content: Følsomt indhold
|
sensitive_content: Følsomt indhold
|
||||||
themes:
|
themes:
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue