Merge remote-tracking branch 'tootsuite/master' into glitchsoc/master
commit
6e821c4273
|
@ -4,6 +4,7 @@ class Api::Web::PushSubscriptionsController < Api::BaseController
|
|||
respond_to :json
|
||||
|
||||
before_action :require_user!
|
||||
protect_from_forgery with: :exception
|
||||
|
||||
def create
|
||||
params.require(:subscription).require(:endpoint)
|
||||
|
|
|
@ -37,6 +37,7 @@ export default class ColumnsArea extends ImmutablePureComponent {
|
|||
static propTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
columns: ImmutablePropTypes.list.isRequired,
|
||||
isModalOpen: PropTypes.bool.isRequired,
|
||||
singleColumn: PropTypes.bool,
|
||||
children: PropTypes.node,
|
||||
};
|
||||
|
@ -144,7 +145,7 @@ export default class ColumnsArea extends ImmutablePureComponent {
|
|||
}
|
||||
|
||||
render () {
|
||||
const { columns, children, singleColumn } = this.props;
|
||||
const { columns, children, singleColumn, isModalOpen } = this.props;
|
||||
const { shouldAnimate } = this.state;
|
||||
|
||||
const columnIndex = getIndex(this.context.router.history.location.pathname);
|
||||
|
@ -159,7 +160,7 @@ export default class ColumnsArea extends ImmutablePureComponent {
|
|||
}
|
||||
|
||||
return (
|
||||
<div className='columns-area' ref={this.setRef}>
|
||||
<div className={`columns-area ${ isModalOpen ? 'unscrollable' : '' }`} ref={this.setRef}>
|
||||
{columns.map(column => {
|
||||
const params = column.get('params', null) === null ? null : column.get('params').toJS();
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import ColumnsArea from '../components/columns_area';
|
|||
|
||||
const mapStateToProps = state => ({
|
||||
columns: state.getIn(['settings', 'columns']),
|
||||
isModalOpen: !!state.get('modal').modalType,
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, null, null, { withRef: true })(ColumnsArea);
|
||||
|
|
|
@ -1613,6 +1613,10 @@
|
|||
justify-content: flex-start;
|
||||
overflow-x: auto;
|
||||
position: relative;
|
||||
|
||||
&.unscrollable {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 360px) {
|
||||
|
|
|
@ -170,6 +170,10 @@ class User < ApplicationRecord
|
|||
settings.default_privacy || (account.locked? ? 'private' : 'public')
|
||||
end
|
||||
|
||||
def allows_digest_emails?
|
||||
settings.notification_emails['digest']
|
||||
end
|
||||
|
||||
def token_for_app(a)
|
||||
return nil if a.nil? || a.owner != self
|
||||
Doorkeeper::AccessToken
|
||||
|
|
|
@ -30,7 +30,7 @@ class ActivityPub::FetchRemoteStatusService < BaseService
|
|||
end
|
||||
|
||||
def actor_id
|
||||
first_of_value(@json['attributedTo'])
|
||||
value_or_id(first_of_value(@json['attributedTo']))
|
||||
end
|
||||
|
||||
def trustworthy_attribution?(uri, attributed_to)
|
||||
|
|
|
@ -9,7 +9,7 @@ class DigestMailerWorker
|
|||
|
||||
def perform(user_id)
|
||||
@user = User.find(user_id)
|
||||
deliver_digest if user_receives_digest?
|
||||
deliver_digest if @user.allows_digest_emails?
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -18,8 +18,4 @@ class DigestMailerWorker
|
|||
NotificationMailer.digest(user.account).deliver_now!
|
||||
user.touch(:last_emailed_at)
|
||||
end
|
||||
|
||||
def user_receives_digest?
|
||||
user.settings.notification_emails['digest']
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
# frozen_string_literal: true
|
||||
require 'sidekiq-scheduler'
|
||||
|
||||
class Scheduler::EmailScheduler
|
||||
include Sidekiq::Worker
|
||||
|
||||
def perform
|
||||
eligible_users.find_each do |user|
|
||||
next unless user.allows_digest_emails?
|
||||
DigestMailerWorker.perform_async(user.id)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def eligible_users
|
||||
User.confirmed
|
||||
.joins(:account)
|
||||
.where(accounts: { silenced: false, suspended: false })
|
||||
.where(disabled: false)
|
||||
.where('current_sign_in_at < ?', 20.days.ago)
|
||||
.where('last_emailed_at IS NULL OR last_emailed_at < ?', 20.days.ago)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,3 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
ActionController::Base.log_warning_on_csrf_failure = false
|
|
@ -561,12 +561,14 @@ en:
|
|||
blackberry: Blackberry
|
||||
chrome: Chrome
|
||||
edge: Microsoft Edge
|
||||
electron: Electron
|
||||
firefox: Firefox
|
||||
generic: Unknown browser
|
||||
ie: Internet Explorer
|
||||
micro_messenger: MicroMessenger
|
||||
nokia: Nokia S40 Ovi Browser
|
||||
opera: Opera
|
||||
otter: Otter
|
||||
phantom_js: PhantomJS
|
||||
qq: QQ Browser
|
||||
safari: Safari
|
||||
|
|
|
@ -4,7 +4,7 @@ en:
|
|||
hints:
|
||||
defaults:
|
||||
avatar: PNG, GIF or JPG. At most 2MB. Will be downscaled to 120x120px
|
||||
digest: Sent after a long period of inactivity with a summary of mentions you've received in your absence
|
||||
digest: Only sent after a long period of inactivity and only if you have received any personal messages in your absence
|
||||
display_name:
|
||||
one: <span class="name-counter">1</span> character left
|
||||
other: <span class="name-counter">%{count}</span> characters left
|
||||
|
|
|
@ -27,3 +27,6 @@
|
|||
ip_cleanup_scheduler:
|
||||
cron: '<%= Random.rand(0..59) %> <%= Random.rand(3..5) %> * * *'
|
||||
class: Scheduler::IpCleanupScheduler
|
||||
email_scheduler:
|
||||
cron: '0 10 * * 2'
|
||||
class: Scheduler::EmailScheduler
|
||||
|
|
|
@ -171,11 +171,10 @@ namespace :mastodon do
|
|||
end
|
||||
|
||||
namespace :emails do
|
||||
desc 'Send out digest e-mails'
|
||||
desc 'Send out digest e-mails (deprecated)'
|
||||
task digest: :environment do
|
||||
User.confirmed.joins(:account).where(accounts: { silenced: false, suspended: false }).where('current_sign_in_at < ?', 20.days.ago).find_each do |user|
|
||||
DigestMailerWorker.perform_async(user.id)
|
||||
end
|
||||
# No-op
|
||||
# This task is now executed via sidekiq-scheduler
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue