Merge pull request #886 from ThibG/glitch-soc/merge-upstream

Merge upstream changes
This commit is contained in:
ThibG 2019-01-14 11:48:36 +01:00 committed by GitHub
commit 077639c274
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 198 additions and 19 deletions

View File

@ -429,7 +429,7 @@ GEM
rack-attack (5.4.2) rack-attack (5.4.2)
rack (>= 1.0, < 3) rack (>= 1.0, < 3)
rack-cors (1.0.2) rack-cors (1.0.2)
rack-protection (2.0.4) rack-protection (2.0.5)
rack rack
rack-proxy (0.6.4) rack-proxy (0.6.4)
rack rack
@ -553,8 +553,9 @@ GEM
scss_lint (0.57.1) scss_lint (0.57.1)
rake (>= 0.9, < 13) rake (>= 0.9, < 13)
sass (~> 3.5, >= 3.5.5) sass (~> 3.5, >= 3.5.5)
sidekiq (5.2.3) sidekiq (5.2.5)
connection_pool (~> 2.2, >= 2.2.2) connection_pool (~> 2.2, >= 2.2.2)
rack (>= 1.5.0)
rack-protection (>= 1.5.0) rack-protection (>= 1.5.0)
redis (>= 3.3.5, < 5) redis (>= 3.3.5, < 5)
sidekiq-bulk (0.2.0) sidekiq-bulk (0.2.0)
@ -639,7 +640,7 @@ GEM
activesupport (>= 4.2) activesupport (>= 4.2)
rack-proxy (>= 0.6.1) rack-proxy (>= 0.6.1)
railties (>= 4.2) railties (>= 4.2)
webpush (0.3.5) webpush (0.3.6)
hkdf (~> 0.2) hkdf (~> 0.2)
jwt (~> 2.0) jwt (~> 2.0)
websocket-driver (0.7.0) websocket-driver (0.7.0)

View File

@ -69,8 +69,12 @@ module ApplicationHelper
tag(:meta, content: content, property: property) tag(:meta, content: content, property: property)
end end
def react_component(name, props = {}) def react_component(name, props = {}, &block)
content_tag(:div, nil, data: { component: name.to_s.camelcase, props: Oj.dump(props) }) if block.nil?
content_tag(:div, nil, data: { component: name.to_s.camelcase, props: Oj.dump(props) })
else
content_tag(:div, data: { component: name.to_s.camelcase, props: Oj.dump(props) }, &block)
end
end end
def body_classes def body_classes

View File

@ -61,6 +61,12 @@ function main() {
if (reactComponents.length > 0) { if (reactComponents.length > 0) {
import(/* webpackChunkName: "containers/media_container" */ 'flavours/glitch/containers/media_container') import(/* webpackChunkName: "containers/media_container" */ 'flavours/glitch/containers/media_container')
.then(({ default: MediaContainer }) => { .then(({ default: MediaContainer }) => {
[].forEach.call(reactComponents, (component) => {
[].forEach.call(component.children, (child) => {
component.removeChild(child);
});
});
const content = document.createElement('div'); const content = document.createElement('div');
ReactDOM.render(<MediaContainer locale={locale} components={reactComponents} />, content); ReactDOM.render(<MediaContainer locale={locale} components={reactComponents} />, content);

View File

@ -1044,6 +1044,10 @@ $small-breakpoint: 960px;
.scrollable { .scrollable {
height: 400px; height: 400px;
@media screen and (max-width: $column-breakpoint) {
height: 90vh;
}
} }
p { p {

View File

@ -1,4 +1,6 @@
$no-columns-breakpoint: 600px; $no-columns-breakpoint: 600px;
$sidebar-width: 240px;
$content-width: 840px;
.admin-wrapper { .admin-wrapper {
display: flex; display: flex;
@ -6,7 +8,7 @@ $no-columns-breakpoint: 600px;
height: 100%; height: 100%;
.sidebar-wrapper { .sidebar-wrapper {
flex: 1; flex: 1 1 $sidebar-width;
height: 100%; height: 100%;
background: $ui-base-color; background: $ui-base-color;
display: flex; display: flex;
@ -14,7 +16,7 @@ $no-columns-breakpoint: 600px;
} }
.sidebar { .sidebar {
width: 240px; width: $sidebar-width;
height: 100%; height: 100%;
padding: 0; padding: 0;
overflow-y: auto; overflow-y: auto;
@ -95,12 +97,12 @@ $no-columns-breakpoint: 600px;
} }
.content-wrapper { .content-wrapper {
flex: 2; flex: 2 1 $content-width;
overflow: auto; overflow: auto;
} }
.content { .content {
max-width: 700px; max-width: $content-width;
padding: 20px 15px; padding: 20px 15px;
padding-top: 60px; padding-top: 60px;
padding-left: 25px; padding-left: 25px;

View File

@ -92,11 +92,14 @@ const handlePush = (event) => {
options.image = notification.status && notification.status.media_attachments.length > 0 && notification.status.media_attachments[0].preview_url || undefined; options.image = notification.status && notification.status.media_attachments.length > 0 && notification.status.media_attachments[0].preview_url || undefined;
options.data = { access_token, preferred_locale, id: notification.status ? notification.status.id : notification.account.id, url: notification.status ? `/web/statuses/${notification.status.id}` : `/web/accounts/${notification.account.id}` }; options.data = { access_token, preferred_locale, id: notification.status ? notification.status.id : notification.account.id, url: notification.status ? `/web/statuses/${notification.status.id}` : `/web/accounts/${notification.account.id}` };
if (notification.status && notification.status.sensitive) { if (notification.status && notification.status.spoiler_text || notification.status.sensitive) {
options.data.hiddenBody = htmlToPlainText(notification.status.content); options.data.hiddenBody = htmlToPlainText(notification.status.content);
options.data.hiddenImage = notification.status.media_attachments.length > 0 && notification.status.media_attachments[0].preview_url; options.data.hiddenImage = notification.status.media_attachments.length > 0 && notification.status.media_attachments[0].preview_url;
options.body = notification.status.spoiler_text; if (notification.status.spoiler_text) {
options.body = notification.status.spoiler_text;
}
options.image = undefined; options.image = undefined;
options.actions = [actionExpand(preferred_locale)]; options.actions = [actionExpand(preferred_locale)];
} else if (notification.type === 'mention') { } else if (notification.type === 'mention') {

View File

@ -66,6 +66,12 @@ function main() {
if (reactComponents.length > 0) { if (reactComponents.length > 0) {
import(/* webpackChunkName: "containers/media_container" */ '../mastodon/containers/media_container') import(/* webpackChunkName: "containers/media_container" */ '../mastodon/containers/media_container')
.then(({ default: MediaContainer }) => { .then(({ default: MediaContainer }) => {
[].forEach.call(reactComponents, (component) => {
[].forEach.call(component.children, (child) => {
component.removeChild(child);
});
});
const content = document.createElement('div'); const content = document.createElement('div');
ReactDOM.render(<MediaContainer locale={locale} components={reactComponents} />, content); ReactDOM.render(<MediaContainer locale={locale} components={reactComponents} />, content);

View File

@ -1041,6 +1041,10 @@ $small-breakpoint: 960px;
.scrollable { .scrollable {
height: 400px; height: 400px;
@media screen and (max-width: $column-breakpoint) {
height: 90vh;
}
} }
p { p {

View File

@ -1,4 +1,6 @@
$no-columns-breakpoint: 600px; $no-columns-breakpoint: 600px;
$sidebar-width: 240px;
$content-width: 840px;
.admin-wrapper { .admin-wrapper {
display: flex; display: flex;
@ -6,7 +8,7 @@ $no-columns-breakpoint: 600px;
height: 100%; height: 100%;
.sidebar-wrapper { .sidebar-wrapper {
flex: 1; flex: 1 1 $sidebar-width;
height: 100%; height: 100%;
background: $ui-base-color; background: $ui-base-color;
display: flex; display: flex;
@ -14,7 +16,7 @@ $no-columns-breakpoint: 600px;
} }
.sidebar { .sidebar {
width: 240px; width: $sidebar-width;
height: 100%; height: 100%;
padding: 0; padding: 0;
overflow-y: auto; overflow-y: auto;
@ -95,12 +97,12 @@ $no-columns-breakpoint: 600px;
} }
.content-wrapper { .content-wrapper {
flex: 2; flex: 2 1 $content-width;
overflow: auto; overflow: auto;
} }
.content { .content {
max-width: 700px; max-width: $content-width;
padding: 20px 15px; padding: 20px 15px;
padding-top: 60px; padding-top: 60px;
padding-left: 25px; padding-left: 25px;

View File

@ -0,0 +1,8 @@
.attachment-list
.attachment-list__icon
= fa_icon 'link'
%ul.attachment-list__list
- attachments.each do |media|
%li
- url = media.remote_url.presence || media.file.url
= link_to File.basename(url), url, title: media.description

View File

@ -25,9 +25,11 @@
- if !status.media_attachments.empty? - if !status.media_attachments.empty?
- if status.media_attachments.first.video? - if status.media_attachments.first.video?
- video = status.media_attachments.first - video = status.media_attachments.first
= react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: !current_account&.user&.show_all_media? && status.sensitive? || current_account&.user&.hide_all_media?, width: 670, height: 380, detailed: true, inline: true, alt: video.description = react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: !current_account&.user&.show_all_media? && status.sensitive? || current_account&.user&.hide_all_media?, width: 670, height: 380, detailed: true, inline: true, alt: video.description do
= render partial: 'stream_entries/attachment_list', locals: { attachments: status.media_attachments }
- else - else
= react_component :media_gallery, height: 380, sensitive: !current_account&.user&.show_all_media? && status.sensitive? || current_account&.user&.hide_all_media?, standalone: true, 'autoPlayGif': current_account&.user&.setting_auto_play_gif || autoplay, 'reduceMotion': current_account&.user&.setting_reduce_motion, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json } = react_component :media_gallery, height: 380, sensitive: !current_account&.user&.show_all_media? && status.sensitive? || current_account&.user&.hide_all_media?, standalone: true, 'autoPlayGif': current_account&.user&.setting_auto_play_gif || autoplay, 'reduceMotion': current_account&.user&.setting_reduce_motion, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json } do
= render partial: 'stream_entries/attachment_list', locals: { attachments: status.media_attachments }
- elsif status.preview_card - elsif status.preview_card
= react_component :card, 'maxDescription': 160, card: ActiveModelSerializers::SerializableResource.new(status.preview_card, serializer: REST::PreviewCardSerializer).as_json = react_component :card, 'maxDescription': 160, card: ActiveModelSerializers::SerializableResource.new(status.preview_card, serializer: REST::PreviewCardSerializer).as_json

View File

@ -30,9 +30,11 @@
- if !status.media_attachments.empty? - if !status.media_attachments.empty?
- if status.media_attachments.first.video? - if status.media_attachments.first.video?
- video = status.media_attachments.first - video = status.media_attachments.first
= react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: !current_account&.user&.show_all_media? && status.sensitive? || current_account&.user&.hide_all_media?, width: 610, height: 343, inline: true, alt: video.description = react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: !current_account&.user&.show_all_media? && status.sensitive? || current_account&.user&.hide_all_media?, width: 610, height: 343, inline: true, alt: video.description do
= render partial: 'stream_entries/attachment_list', locals: { attachments: status.media_attachments }
- else - else
= react_component :media_gallery, height: 343, sensitive: !current_account&.user&.show_all_media? && status.sensitive? || current_account&.user&.hide_all_media?, 'autoPlayGif': current_account&.user&.setting_auto_play_gif || autoplay, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json } = react_component :media_gallery, height: 343, sensitive: !current_account&.user&.show_all_media? && status.sensitive? || current_account&.user&.hide_all_media?, 'autoPlayGif': current_account&.user&.setting_auto_play_gif || autoplay, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json } do
= render partial: 'stream_entries/attachment_list', locals: { attachments: status.media_attachments }
- elsif status.preview_card - elsif status.preview_card
= react_component :card, 'maxDescription': 160, card: ActiveModelSerializers::SerializableResource.new(status.preview_card, serializer: REST::PreviewCardSerializer).as_json = react_component :card, 'maxDescription': 160, card: ActiveModelSerializers::SerializableResource.new(status.preview_card, serializer: REST::PreviewCardSerializer).as_json

View File

@ -1,4 +1,131 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe Admin::AccountAction, type: :model do RSpec.describe Admin::AccountAction, type: :model do
let(:account_action) { described_class.new }
describe '#save!' do
subject { account_action.save! }
let(:account) { Fabricate(:account, user: Fabricate(:user, admin: true)) }
let(:target_account) { Fabricate(:account, user: Fabricate(:user)) }
let(:type) { 'disable' }
before do
account_action.assign_attributes(
type: type,
current_account: account,
target_account: target_account
)
end
context 'type is "disable"' do
let(:type) { 'disable' }
it 'disable user' do
subject
expect(target_account.user).to be_disabled
end
end
context 'type is "silence"' do
let(:type) { 'silence' }
it 'silences account' do
subject
expect(target_account).to be_silenced
end
end
context 'type is "suspend"' do
let(:type) { 'suspend' }
it 'suspends account' do
subject
expect(target_account).to be_suspended
end
it 'queues Admin::SuspensionWorker by 1' do
Sidekiq::Testing.fake! do
expect do
subject
end.to change { Admin::SuspensionWorker.jobs.size }.by 1
end
end
end
it 'creates Admin::ActionLog' do
expect do
subject
end.to change { Admin::ActionLog.count }.by 1
end
it 'calls queue_email!' do
expect(account_action).to receive(:queue_email!)
subject
end
it 'calls process_reports!' do
expect(account_action).to receive(:process_reports!)
subject
end
end
describe '#report' do
subject { account_action.report }
context 'report_id.present?' do
before do
account_action.report_id = Fabricate(:report).id
end
it 'returns Report' do
expect(subject).to be_instance_of Report
end
end
context '!report_id.present?' do
it 'returns nil' do
expect(subject).to be_nil
end
end
end
describe '#with_report?' do
subject { account_action.with_report? }
context '!report.nil?' do
before do
account_action.report_id = Fabricate(:report).id
end
it 'returns true' do
expect(subject).to be true
end
end
context '!(!report.nil?)' do
it 'returns false' do
expect(subject).to be false
end
end
end
describe '.types_for_account' do
subject { described_class.types_for_account(account) }
context 'account.local?' do
let(:account) { Fabricate(:account, domain: nil) }
it 'returns ["none", "disable", "silence", "suspend"]' do
expect(subject).to eq %w(none disable silence suspend)
end
end
context '!account.local?' do
let(:account) { Fabricate(:account, domain: 'hoge.com') }
it 'returns ["silence", "suspend"]' do
expect(subject).to eq %w(silence suspend)
end
end
end
end end

View File

@ -1,4 +1,12 @@
# frozen_string_literal: true
require 'rails_helper' require 'rails_helper'
RSpec.describe Admin::ActionLog, type: :model do RSpec.describe Admin::ActionLog, type: :model do
describe '#action' do
it 'returns action' do
action_log = described_class.new(action: 'hoge')
expect(action_log.action).to be :hoge
end
end
end end