mirror of
https://github.com/lunaisnotaboy/mastodon.git
synced 2024-11-18 12:52:52 +00:00
Merge branch 'master' into glitch-soc/merge-upstream
This commit is contained in:
commit
2b7158427f
|
@ -3,8 +3,8 @@ FROM ubuntu:18.04 as build-dep
|
|||
# Use bash for the shell
|
||||
SHELL ["bash", "-c"]
|
||||
|
||||
# Install Node
|
||||
ENV NODE_VER="12.11.1"
|
||||
# Install Node v12 (LTS)
|
||||
ENV NODE_VER="12.13.1"
|
||||
RUN echo "Etc/UTC" > /etc/localtime && \
|
||||
apt update && \
|
||||
apt -y install wget python && \
|
||||
|
|
10
Gemfile
10
Gemfile
|
@ -12,7 +12,7 @@ gem 'thor', '~> 0.20'
|
|||
gem 'hamlit-rails', '~> 0.2'
|
||||
gem 'pg', '~> 1.1'
|
||||
gem 'makara', '~> 0.4'
|
||||
gem 'pghero', '~> 2.3'
|
||||
gem 'pghero', '~> 2.4'
|
||||
gem 'dotenv-rails', '~> 2.7'
|
||||
|
||||
gem 'aws-sdk-s3', '~> 1.55', require: false
|
||||
|
@ -27,7 +27,7 @@ gem 'active_model_serializers', '~> 0.10'
|
|||
gem 'addressable', '~> 2.7'
|
||||
gem 'bootsnap', '~> 1.4', require: false
|
||||
gem 'browser'
|
||||
gem 'charlock_holmes', '~> 0.7.6'
|
||||
gem 'charlock_holmes', '~> 0.7.7'
|
||||
gem 'iso-639'
|
||||
gem 'chewy', '~> 5.1'
|
||||
gem 'cld3', '~> 3.2.4'
|
||||
|
@ -38,7 +38,7 @@ group :pam_authentication, optional: true do
|
|||
gem 'devise_pam_authenticatable2', '~> 9.2'
|
||||
end
|
||||
|
||||
gem 'net-ldap', '~> 0.10'
|
||||
gem 'net-ldap', '~> 0.16'
|
||||
gem 'omniauth-cas', '~> 1.1'
|
||||
gem 'omniauth-saml', '~> 1.10'
|
||||
gem 'omniauth', '~> 1.9'
|
||||
|
@ -68,12 +68,12 @@ gem 'oj', '~> 3.9'
|
|||
gem 'ostatus2', '~> 2.0'
|
||||
gem 'ox', '~> 2.11'
|
||||
gem 'parslet'
|
||||
gem 'parallel', '~> 1.18'
|
||||
gem 'parallel', '~> 1.19'
|
||||
gem 'posix-spawn', git: 'https://github.com/rtomayko/posix-spawn', ref: '58465d2e213991f8afb13b984854a49fcdcc980c'
|
||||
gem 'pundit', '~> 2.1'
|
||||
gem 'premailer-rails'
|
||||
gem 'rack-attack', '~> 6.2'
|
||||
gem 'rack-cors', '~> 1.0', require: 'rack/cors'
|
||||
gem 'rack-cors', '~> 1.1', require: 'rack/cors'
|
||||
gem 'rails-i18n', '~> 5.1'
|
||||
gem 'rails-settings-cached', '~> 0.6'
|
||||
gem 'redis', '~> 4.1', require: ['redis', 'redis/connection/hiredis']
|
||||
|
|
24
Gemfile.lock
24
Gemfile.lock
|
@ -133,7 +133,7 @@ GEM
|
|||
bootsnap (1.4.5)
|
||||
msgpack (~> 1.0)
|
||||
brakeman (4.7.1)
|
||||
browser (2.6.1)
|
||||
browser (2.7.1)
|
||||
builder (3.2.3)
|
||||
bullet (6.0.2)
|
||||
activesupport (>= 3.0.0)
|
||||
|
@ -168,7 +168,7 @@ GEM
|
|||
xpath (~> 3.2)
|
||||
case_transform (0.2)
|
||||
activesupport
|
||||
charlock_holmes (0.7.6)
|
||||
charlock_holmes (0.7.7)
|
||||
chewy (5.1.0)
|
||||
activesupport (>= 4.0)
|
||||
elasticsearch (>= 2.0.0)
|
||||
|
@ -385,7 +385,7 @@ GEM
|
|||
multi_json (1.13.1)
|
||||
multipart-post (2.1.1)
|
||||
necromancer (0.5.0)
|
||||
net-ldap (0.16.1)
|
||||
net-ldap (0.16.2)
|
||||
net-scp (2.0.0)
|
||||
net-ssh (>= 2.6.5, < 6.0.0)
|
||||
net-ssh (5.2.0)
|
||||
|
@ -425,7 +425,7 @@ GEM
|
|||
paperclip-av-transcoder (0.6.4)
|
||||
av (~> 0.9.0)
|
||||
paperclip (>= 2.5.2)
|
||||
parallel (1.18.0)
|
||||
parallel (1.19.1)
|
||||
parallel_tests (2.29.2)
|
||||
parallel
|
||||
parser (2.6.5.0)
|
||||
|
@ -435,7 +435,7 @@ GEM
|
|||
equatable (~> 0.6)
|
||||
tty-color (~> 0.5)
|
||||
pg (1.1.4)
|
||||
pghero (2.3.0)
|
||||
pghero (2.4.1)
|
||||
activerecord (>= 5)
|
||||
pkg-config (1.4.0)
|
||||
premailer (1.11.1)
|
||||
|
@ -463,8 +463,8 @@ GEM
|
|||
rack (2.0.7)
|
||||
rack-attack (6.2.1)
|
||||
rack (>= 1.0, < 3)
|
||||
rack-cors (1.0.6)
|
||||
rack (>= 1.6.0)
|
||||
rack-cors (1.1.0)
|
||||
rack (>= 2.0.0)
|
||||
rack-protection (2.0.7)
|
||||
rack
|
||||
rack-proxy (0.6.5)
|
||||
|
@ -699,7 +699,7 @@ DEPENDENCIES
|
|||
capistrano-rbenv (~> 2.1)
|
||||
capistrano-yarn (~> 2.0)
|
||||
capybara (~> 3.29)
|
||||
charlock_holmes (~> 0.7.6)
|
||||
charlock_holmes (~> 0.7.7)
|
||||
chewy (~> 5.1)
|
||||
cld3 (~> 3.2.4)
|
||||
climate_control (~> 0.2)
|
||||
|
@ -744,7 +744,7 @@ DEPENDENCIES
|
|||
memory_profiler
|
||||
microformats (~> 4.1)
|
||||
mime-types (~> 3.3)
|
||||
net-ldap (~> 0.10)
|
||||
net-ldap (~> 0.16)
|
||||
nilsimsa!
|
||||
nokogiri (~> 1.10)
|
||||
nsa (~> 0.2)
|
||||
|
@ -756,11 +756,11 @@ DEPENDENCIES
|
|||
ox (~> 2.11)
|
||||
paperclip (~> 6.0)
|
||||
paperclip-av-transcoder (~> 0.6)
|
||||
parallel (~> 1.18)
|
||||
parallel (~> 1.19)
|
||||
parallel_tests (~> 2.29)
|
||||
parslet
|
||||
pg (~> 1.1)
|
||||
pghero (~> 2.3)
|
||||
pghero (~> 2.4)
|
||||
pkg-config (~> 1.4)
|
||||
posix-spawn!
|
||||
premailer-rails
|
||||
|
@ -770,7 +770,7 @@ DEPENDENCIES
|
|||
puma (~> 4.2)
|
||||
pundit (~> 2.1)
|
||||
rack-attack (~> 6.2)
|
||||
rack-cors (~> 1.0)
|
||||
rack-cors (~> 1.1)
|
||||
rails (~> 5.2.3)
|
||||
rails-controller-testing (~> 1.0)
|
||||
rails-i18n (~> 5.1)
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
class Api::ProofsController < Api::BaseController
|
||||
include AccountOwnedConcern
|
||||
|
||||
skip_before_action :require_authenticated_user!
|
||||
|
||||
before_action :set_provider
|
||||
|
||||
def index
|
||||
|
|
|
@ -236,7 +236,7 @@ export function uploadCompose(files) {
|
|||
dispatch(uploadComposeProgress(progress.reduce((a, v) => a + v, 0), total));
|
||||
},
|
||||
}).then(({ data }) => dispatch(uploadComposeSuccess(data, f)));
|
||||
}).catch(error => dispatch(uploadComposeFail(error, true)));
|
||||
}).catch(error => dispatch(uploadComposeFail(error)));
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -267,11 +267,10 @@ export function changeUploadComposeSuccess(media) {
|
|||
};
|
||||
};
|
||||
|
||||
export function changeUploadComposeFail(error, decrement = false) {
|
||||
export function changeUploadComposeFail(error) {
|
||||
return {
|
||||
type: COMPOSE_UPLOAD_CHANGE_FAIL,
|
||||
error: error,
|
||||
decrement: decrement,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -214,6 +214,22 @@ class Status extends ImmutablePureComponent {
|
|||
this.props.onOpenVideo(media, startTime);
|
||||
}
|
||||
|
||||
handleHotkeyOpenMedia = e => {
|
||||
const { status, onOpenMedia, onOpenVideo } = this.props;
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
if (status.get('media_attachments').size > 0) {
|
||||
if (status.getIn(['media_attachments', 0, 'type']) === 'audio') {
|
||||
// TODO: toggle play/paused?
|
||||
} else if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
|
||||
onOpenVideo(status.getIn(['media_attachments', 0]), 0);
|
||||
} else {
|
||||
onOpenMedia(status.get('media_attachments'), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleHotkeyReply = e => {
|
||||
e.preventDefault();
|
||||
this.props.onReply(this._properStatus(), this.context.router.history);
|
||||
|
@ -293,6 +309,7 @@ class Status extends ImmutablePureComponent {
|
|||
moveDown: this.handleHotkeyMoveDown,
|
||||
toggleHidden: this.handleHotkeyToggleHidden,
|
||||
toggleSensitive: this.handleHotkeyToggleSensitive,
|
||||
openMedia: this.handleHotkeyOpenMedia,
|
||||
};
|
||||
|
||||
if (hidden) {
|
||||
|
|
|
@ -56,6 +56,10 @@ class KeyboardShortcuts extends ImmutablePureComponent {
|
|||
<td><kbd>enter</kbd>, <kbd>o</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.enter' defaultMessage='to open status' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>e</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.open_media' defaultMessage='to open media' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>x</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.toggle_hidden' defaultMessage='to show/hide text behind CW' /></td>
|
||||
|
|
|
@ -281,6 +281,22 @@ class Status extends ImmutablePureComponent {
|
|||
this.props.dispatch(openModal('VIDEO', { media, time }));
|
||||
}
|
||||
|
||||
handleHotkeyOpenMedia = e => {
|
||||
const { status } = this.props;
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
if (status.get('media_attachments').size > 0) {
|
||||
if (status.getIn(['media_attachments', 0, 'type']) === 'audio') {
|
||||
// TODO: toggle play/paused?
|
||||
} else if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
|
||||
this.handleOpenVideo(status.getIn(['media_attachments', 0]), 0);
|
||||
} else {
|
||||
this.handleOpenMedia(status.get('media_attachments'), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleMuteClick = (account) => {
|
||||
this.props.dispatch(initMuteModal(account));
|
||||
}
|
||||
|
@ -506,6 +522,7 @@ class Status extends ImmutablePureComponent {
|
|||
openProfile: this.handleHotkeyOpenProfile,
|
||||
toggleHidden: this.handleHotkeyToggleHidden,
|
||||
toggleSensitive: this.handleHotkeyToggleSensitive,
|
||||
openMedia: this.handleHotkeyOpenMedia,
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
|
@ -214,7 +214,7 @@ class FocalPointModal extends ImmutablePureComponent {
|
|||
langPath: `${assetHost}/ocr/lang-data`,
|
||||
});
|
||||
|
||||
let media_url = media.get('file');
|
||||
let media_url = media.get('url');
|
||||
|
||||
if (window.URL && URL.createObjectURL) {
|
||||
try {
|
||||
|
|
|
@ -100,6 +100,7 @@ const keyMap = {
|
|||
goToRequests: 'g r',
|
||||
toggleHidden: 'x',
|
||||
toggleSensitive: 'h',
|
||||
openMedia: 'e',
|
||||
};
|
||||
|
||||
class SwitchingColumnsArea extends React.PureComponent {
|
||||
|
|
|
@ -467,7 +467,7 @@ class Video extends React.PureComponent {
|
|||
|
||||
<div className='video-player__buttons-bar'>
|
||||
<div className='video-player__buttons left'>
|
||||
<button type='button' aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} onClick={this.togglePlay}><Icon id={paused ? 'play' : 'pause'} fixedWidth /></button>
|
||||
<button type='button' aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} onClick={this.togglePlay} autoFocus={detailed}><Icon id={paused ? 'play' : 'pause'} fixedWidth /></button>
|
||||
<button type='button' aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} onClick={this.toggleMute}><Icon id={muted ? 'volume-off' : 'volume-up'} fixedWidth /></button>
|
||||
|
||||
<div className='video-player__volume' onMouseDown={this.handleVolumeMouseDown} ref={this.setVolumeRef}>
|
||||
|
|
|
@ -328,7 +328,7 @@ export default function compose(state = initialState, action) {
|
|||
case COMPOSE_UPLOAD_SUCCESS:
|
||||
return appendMedia(state, fromJS(action.media), action.file);
|
||||
case COMPOSE_UPLOAD_FAIL:
|
||||
return state.set('is_uploading', false).update('pending_media_attachments', n => action.decrement ? n - 1 : n);
|
||||
return state.set('is_uploading', false).update('pending_media_attachments', n => n - 1);
|
||||
case COMPOSE_UPLOAD_UNDO:
|
||||
return removeMedia(state, action.media_id);
|
||||
case COMPOSE_UPLOAD_PROGRESS:
|
||||
|
|
|
@ -646,7 +646,7 @@
|
|||
}
|
||||
|
||||
.counter {
|
||||
width: 33.3%;
|
||||
min-width: 33.3%;
|
||||
box-sizing: border-box;
|
||||
flex: 0 0 auto;
|
||||
color: $darker-text-color;
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class StatusRelationshipsPresenter
|
||||
attr_reader :reblogs_map, :favourites_map, :mutes_map, :pins_map
|
||||
attr_reader :reblogs_map, :favourites_map, :mutes_map, :pins_map,
|
||||
:bookmarks_map
|
||||
|
||||
def initialize(statuses, current_account_id = nil, **options)
|
||||
if current_account_id.nil?
|
||||
|
|
|
@ -97,8 +97,8 @@ class REST::StatusSerializer < ActiveModel::Serializer
|
|||
end
|
||||
|
||||
def bookmarked
|
||||
if instance_options && instance_options[:bookmarks]
|
||||
instance_options[:bookmarks].bookmarks_map[object.id] || false
|
||||
if instance_options && instance_options[:relationships]
|
||||
instance_options[:relationships].bookmarks_map[object.id] || false
|
||||
else
|
||||
current_user.account.bookmarked?(object)
|
||||
end
|
||||
|
|
|
@ -30,7 +30,7 @@ class ActivityPub::ProcessPollService < BaseService
|
|||
|
||||
voters_count = @json['votersCount']
|
||||
|
||||
latest_options = items.map { |item| item['name'].presence || item['content'] }
|
||||
latest_options = items.map { |item| item['name'].presence || item['content'] }.compact
|
||||
|
||||
# If for some reasons the options were changed, it invalidates all previous
|
||||
# votes, so we need to remove them
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
= simple_form_for current_user, url: settings_preferences_notifications_path, html: { method: :put } do |f|
|
||||
= render 'shared/error_messages', object: current_user
|
||||
|
||||
%h4= t('notifications.email_events')
|
||||
|
||||
%p.hint = t('notifications.email_events_hint')
|
||||
|
||||
.fields-group
|
||||
= f.simple_fields_for :notification_emails, hash_to_object(current_user.settings.notification_emails) do |ff|
|
||||
= ff.input :follow, as: :boolean, wrapper: :with_label
|
||||
|
@ -21,6 +25,8 @@
|
|||
= f.simple_fields_for :notification_emails, hash_to_object(current_user.settings.notification_emails) do |ff|
|
||||
= ff.input :digest, as: :boolean, wrapper: :with_label
|
||||
|
||||
%h4 = t('notifications.other_settings')
|
||||
|
||||
.fields-group
|
||||
= f.simple_fields_for :interactions, hash_to_object(current_user.settings.interactions) do |ff|
|
||||
= ff.input :must_be_follower, as: :boolean, wrapper: :with_label
|
||||
|
|
|
@ -900,6 +900,10 @@ en:
|
|||
body: 'Your status was boosted by %{name}:'
|
||||
subject: "%{name} boosted your status"
|
||||
title: New boost
|
||||
notifications:
|
||||
email_events: Events for e-mail notifications
|
||||
email_events_hint: 'Select events that you want to receive notifications for:'
|
||||
other_settings: Other notifications settings
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
|
|
@ -163,14 +163,14 @@ en:
|
|||
text: Why do you want to join?
|
||||
notification_emails:
|
||||
digest: Send digest e-mails
|
||||
favourite: Send e-mail when someone favourites your status
|
||||
follow: Send e-mail when someone follows you
|
||||
follow_request: Send e-mail when someone requests to follow you
|
||||
mention: Send e-mail when someone mentions you
|
||||
pending_account: Send e-mail when a new account needs review
|
||||
reblog: Send e-mail when someone boosts your status
|
||||
report: Send e-mail when a new report is submitted
|
||||
trending_tag: Send e-mail when an unreviewed hashtag is trending
|
||||
favourite: Someone favourited your status
|
||||
follow: Someone followed you
|
||||
follow_request: Someone requested to follow you
|
||||
mention: Someone mentioned you
|
||||
pending_account: New account needs review
|
||||
reblog: Someone boosted your status
|
||||
report: New report is submitted
|
||||
trending_tag: An unreviewed hashtag is trending
|
||||
tag:
|
||||
listable: Allow this hashtag to appear in searches and on the profile directory
|
||||
name: Hashtag
|
||||
|
|
41
config/pghero.yml
Normal file
41
config/pghero.yml
Normal file
|
@ -0,0 +1,41 @@
|
|||
databases:
|
||||
primary:
|
||||
# Database URL (defaults to app database)
|
||||
# url: <%= ENV["DATABASE_URL"] %>
|
||||
|
||||
# Add more databases
|
||||
# other:
|
||||
# url: <%= ENV["OTHER_DATABASE_URL"] %>
|
||||
|
||||
# Minimum time for long running queries
|
||||
# long_running_query_sec: 60
|
||||
|
||||
# Minimum average time for slow queries
|
||||
# slow_query_ms: 20
|
||||
|
||||
# Minimum calls for slow queries
|
||||
# slow_query_calls: 100
|
||||
|
||||
# Minimum connections for high connections warning
|
||||
# total_connections_threshold: 500
|
||||
|
||||
# Statement timeout for explain
|
||||
# explain_timeout_sec: 10
|
||||
|
||||
# Time zone (defaults to app time zone)
|
||||
# time_zone: "Pacific Time (US & Canada)"
|
||||
|
||||
# Basic authentication
|
||||
# username: admin
|
||||
# password: secret
|
||||
|
||||
# Stats database URL (defaults to app database)
|
||||
# stats_database_url: <%= ENV["PGHERO_STATS_DATABASE_URL"] %>
|
||||
|
||||
# AWS configuration (defaults to app AWS config)
|
||||
# also need aws_db_instance_identifier with each database
|
||||
# aws_access_key_id: ...
|
||||
# aws_secret_access_key: ...
|
||||
# aws_region: us-east-1
|
||||
|
||||
override_csp: true
|
14
package.json
14
package.json
|
@ -64,14 +64,14 @@
|
|||
"@babel/plugin-proposal-class-properties": "^7.7.0",
|
||||
"@babel/plugin-proposal-decorators": "^7.7.0",
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.6.2",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
|
||||
"@babel/plugin-transform-react-inline-elements": "^7.2.0",
|
||||
"@babel/plugin-transform-react-jsx-self": "^7.2.0",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.7.4",
|
||||
"@babel/plugin-transform-react-inline-elements": "^7.7.4",
|
||||
"@babel/plugin-transform-react-jsx-self": "^7.7.4",
|
||||
"@babel/plugin-transform-react-jsx-source": "^7.5.0",
|
||||
"@babel/plugin-transform-runtime": "^7.5.5",
|
||||
"@babel/preset-env": "^7.7.1",
|
||||
"@babel/plugin-transform-runtime": "^7.7.4",
|
||||
"@babel/preset-env": "^7.7.4",
|
||||
"@babel/preset-react": "^7.7.0",
|
||||
"@babel/runtime": "^7.7.2",
|
||||
"@babel/runtime": "^7.7.4",
|
||||
"@clusterws/cws": "^0.16.0",
|
||||
"array-includes": "^3.0.3",
|
||||
"atrament": "^0.2.3",
|
||||
|
@ -161,7 +161,7 @@
|
|||
"stringz": "^2.0.0",
|
||||
"substring-trie": "^1.0.2",
|
||||
"terser-webpack-plugin": "^2.2.1",
|
||||
"tesseract.js": "^2.0.0-beta.2",
|
||||
"tesseract.js": "^2.0.0-alpha.16",
|
||||
"throng": "^4.0.0",
|
||||
"tiny-queue": "^0.2.1",
|
||||
"uuid": "^3.3.3",
|
||||
|
|
Loading…
Reference in a new issue