stuff for messaging box

messaging
Baptiste Lemoine 2019-12-21 15:16:13 +01:00
commit 15a9f2633f
92 changed files with 569 additions and 1079 deletions

View File

@ -6,7 +6,8 @@ ruby '>= 2.4.0', '< 2.7.0'
gem 'pkg-config', '~> 1.4'
gem 'puma', '~> 4.3'
gem 'rails', '~> 5.2.3'
gem 'rails', '~> 5.2.4'
gem 'sprockets', '~> 3.7'
gem 'thor', '~> 0.20'
gem 'hamlit-rails', '~> 0.2'
@ -122,7 +123,7 @@ group :test do
gem 'rspec-sidekiq', '~> 3.0'
gem 'simplecov', '~> 0.17', require: false
gem 'webmock', '~> 3.7'
gem 'parallel_tests', '~> 2.29'
gem 'parallel_tests', '~> 2.30'
end
group :development do

View File

@ -44,25 +44,25 @@ GIT
GEM
remote: https://rubygems.org/
specs:
actioncable (5.2.3)
actionpack (= 5.2.3)
actioncable (5.2.4)
actionpack (= 5.2.4)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
actionmailer (5.2.3)
actionpack (= 5.2.3)
actionview (= 5.2.3)
activejob (= 5.2.3)
actionmailer (5.2.4)
actionpack (= 5.2.4)
actionview (= 5.2.4)
activejob (= 5.2.4)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0)
actionpack (5.2.3)
actionview (= 5.2.3)
activesupport (= 5.2.3)
actionpack (5.2.4)
actionview (= 5.2.4)
activesupport (= 5.2.4)
rack (~> 2.0)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (5.2.3)
activesupport (= 5.2.3)
actionview (5.2.4)
activesupport (= 5.2.4)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
@ -73,20 +73,20 @@ GEM
case_transform (>= 0.2)
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
active_record_query_trace (1.7)
activejob (5.2.3)
activesupport (= 5.2.3)
activejob (5.2.4)
activesupport (= 5.2.4)
globalid (>= 0.3.6)
activemodel (5.2.3)
activesupport (= 5.2.3)
activerecord (5.2.3)
activemodel (= 5.2.3)
activesupport (= 5.2.3)
activemodel (5.2.4)
activesupport (= 5.2.4)
activerecord (5.2.4)
activemodel (= 5.2.4)
activesupport (= 5.2.4)
arel (>= 9.0)
activestorage (5.2.3)
actionpack (= 5.2.3)
activerecord (= 5.2.3)
activestorage (5.2.4)
actionpack (= 5.2.4)
activerecord (= 5.2.4)
marcel (~> 0.3.1)
activesupport (5.2.3)
activesupport (5.2.4)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
@ -134,7 +134,7 @@ GEM
msgpack (~> 1.0)
brakeman (4.7.2)
browser (2.7.1)
builder (3.2.3)
builder (3.2.4)
bullet (6.0.2)
activesupport (>= 3.0.0)
uniform_notifier (~> 1.11)
@ -218,7 +218,7 @@ GEM
docile (1.3.2)
domain_name (0.5.20180417)
unf (>= 0.0.5, < 1.0.0)
doorkeeper (5.2.2)
doorkeeper (5.2.3)
railties (>= 5)
dotenv (2.7.5)
dotenv-rails (2.7.5)
@ -238,9 +238,9 @@ GEM
erubi (1.9.0)
et-orbi (1.1.6)
tzinfo
excon (0.62.0)
excon (0.71.0)
fabrication (2.21.0)
faker (2.8.0)
faker (2.8.1)
i18n (>= 1.6, < 1.8)
faraday (0.15.4)
multipart-post (>= 1.2, < 3)
@ -324,7 +324,7 @@ GEM
jmespath (1.4.0)
json (2.2.0)
json-canonicalization (0.1.0)
json-ld-preloaded (3.0.4)
json-ld-preloaded (3.0.6)
json-ld (~> 3.0)
multi_json (~> 1.12)
rdf (~> 3.0)
@ -356,7 +356,7 @@ GEM
activesupport (>= 4)
railties (>= 4)
request_store (~> 1.0)
loofah (2.3.1)
loofah (2.4.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.7.1)
@ -380,7 +380,7 @@ GEM
mini_portile2 (2.4.0)
minitest (5.13.0)
msgpack (1.3.1)
multi_json (1.13.1)
multi_json (1.14.1)
multipart-post (2.1.1)
necromancer (0.5.1)
net-ldap (0.16.2)
@ -424,7 +424,7 @@ GEM
av (~> 0.9.0)
paperclip (>= 2.5.2)
parallel (1.19.1)
parallel_tests (2.29.2)
parallel_tests (2.30.0)
parallel
parser (2.6.5.0)
ast (~> 2.4.0)
@ -458,7 +458,7 @@ GEM
pundit (2.1.0)
activesupport (>= 3.0.0)
raabro (1.1.6)
rack (2.0.7)
rack (2.0.8)
rack-attack (6.2.1)
rack (>= 1.0, < 3)
rack-cors (1.1.0)
@ -469,18 +469,18 @@ GEM
rack
rack-test (1.1.0)
rack (>= 1.0, < 3)
rails (5.2.3)
actioncable (= 5.2.3)
actionmailer (= 5.2.3)
actionpack (= 5.2.3)
actionview (= 5.2.3)
activejob (= 5.2.3)
activemodel (= 5.2.3)
activerecord (= 5.2.3)
activestorage (= 5.2.3)
activesupport (= 5.2.3)
rails (5.2.4)
actioncable (= 5.2.4)
actionmailer (= 5.2.4)
actionpack (= 5.2.4)
actionview (= 5.2.4)
activejob (= 5.2.4)
activemodel (= 5.2.4)
activerecord (= 5.2.4)
activestorage (= 5.2.4)
activesupport (= 5.2.4)
bundler (>= 1.3.0)
railties (= 5.2.3)
railties (= 5.2.4)
sprockets-rails (>= 2.0.0)
rails-controller-testing (1.0.4)
actionpack (>= 5.0.1.x)
@ -496,15 +496,15 @@ GEM
railties (>= 5.0, < 6)
rails-settings-cached (0.6.6)
rails (>= 4.2.0)
railties (5.2.3)
actionpack (= 5.2.3)
activesupport (= 5.2.3)
railties (5.2.4)
actionpack (= 5.2.4)
activesupport (= 5.2.4)
method_source
rake (>= 0.8.7)
thor (>= 0.19.0, < 2.0)
rainbow (3.0.0)
rake (13.0.1)
rdf (3.0.12)
rdf (3.0.13)
hamster (~> 3.0)
link_header (~> 0.0, >= 0.0.8)
rdf-normalize (0.3.3)
@ -615,7 +615,7 @@ GEM
sshkit (1.20.0)
net-scp (>= 1.1.2)
net-ssh (>= 2.8.0)
stackprof (0.2.13)
stackprof (0.2.14)
statsd-ruby (1.4.0)
stoplight (2.2.0)
streamio-ffmpeg (3.0.2)
@ -660,16 +660,16 @@ GEM
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
webpacker (4.2.0)
webpacker (4.2.2)
activesupport (>= 4.2)
rack-proxy (>= 0.6.1)
railties (>= 4.2)
webpush (0.3.8)
hkdf (~> 0.2)
jwt (~> 2.0)
websocket-driver (0.7.0)
websocket-driver (0.7.1)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.3)
websocket-extensions (0.1.4)
wisper (2.0.1)
xpath (3.2.0)
nokogiri (~> 1.8)
@ -753,7 +753,7 @@ DEPENDENCIES
paperclip (~> 6.0)
paperclip-av-transcoder (~> 0.6)
parallel (~> 1.19)
parallel_tests (~> 2.29)
parallel_tests (~> 2.30)
parslet
pg (~> 1.1)
pghero (~> 2.4)
@ -767,7 +767,7 @@ DEPENDENCIES
pundit (~> 2.1)
rack-attack (~> 6.2)
rack-cors (~> 1.1)
rails (~> 5.2.3)
rails (~> 5.2.4)
rails-controller-testing (~> 1.0)
rails-i18n (~> 5.1)
rails-settings-cached (~> 0.6)
@ -789,6 +789,7 @@ DEPENDENCIES
simple-navigation (~> 4.1)
simple_form (~> 5.0)
simplecov (~> 0.17)
sprockets (~> 3.7)
sprockets-rails (~> 3.2)
stackprof
stoplight (~> 2.2.0)

View File

@ -1,5 +1,5 @@
import 'intersection-observer';
import 'requestidlecallback';
import objectFitImages from 'object-fit-images';
import objectFitImages from 'object-fit-images';
objectFitImages();

View File

@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
import IconButton from 'mastodon/components/icon_button';
import Icon from 'mastodon/components/icon';
import AutosuggestInput from 'mastodon/components/autosuggest_input';
@ -56,19 +56,19 @@ class Option extends React.PureComponent {
if (e.key === 'Enter' || e.key === ' ') {
this.handleToggleMultiple(e);
}
}
};
onSuggestionsClearRequested = () => {
this.props.onClearSuggestions();
}
};
onSuggestionsFetchRequested = (token) => {
this.props.onFetchSuggestions(token);
}
};
onSuggestionSelected = (tokenStart, token, value) => {
this.props.onSuggestionSelected(tokenStart, token, value, ['poll', 'options', this.props.index]);
}
};
render () {
const { isPollMultiple, title, index, intl } = this.props;
@ -82,8 +82,8 @@ class Option extends React.PureComponent {
onKeyPress={this.handleCheckboxKeypress}
role='button'
tabIndex='0'
title={intl.formatMessage(isPollMultiple ? messages.switchToMultiple : messages.switchToSingle)}
aria-label={intl.formatMessage(isPollMultiple ? messages.switchToMultiple : messages.switchToSingle)}
title={intl.formatMessage(isPollMultiple ? messages.switchToSingle : messages.switchToMultiple)}
aria-label={intl.formatMessage(isPollMultiple ? messages.switchToSingle : messages.switchToMultiple)}
/>
<AutosuggestInput

View File

@ -1,23 +1,27 @@
import ImmutablePureComponent from 'react-immutable-pure-component';
import React from 'react';
export default class Messaging extends ImmutablePureComponent {
import ImmutablePropTypes from 'react-immutable-proptypes';
import { isStaff } from '../../../initial_state';
export default class Messaging extends React.PureComponent {
static propTypes = {
// following : ImmutablePropTypes.list,
// conversations: ImmutablePropTypes.list,
// newMessage : ImmutablePropTypes.string,
following : ImmutablePropTypes.list,
conversations: ImmutablePropTypes.list,
};
const;
newMessage = 'meh';
// openConversationWith(account) {
// let conversationFound = account;
// if conversation exist, focus on it
// if (conversationFound) {
//
// } else {
//
// }
// else, create conversation and focus on it
// };
openConversationWith(account) {
let conversationFound = account;
// if conversation exist, focus on it
if (conversationFound) {
} else {
}
// else, create conversation and focus on it
};
submitCompose() {
@ -26,34 +30,35 @@ export default class Messaging extends ImmutablePureComponent {
constructor() {
super();
// this.props.newMessage = 'meh';
// this.props.conversations = [
// {
// withAccount: '@machin',
// messages : [],
// opened : true,
// },
// {
// withAccount: '@chuck',
// messages : [],
// opened : false,
// },
// ];
// this.props.following = [
// { username: 'wulfila', handle: '@wulfila' },
// { username: 'machin', handle: '@machin' },
// { username: 'chuck norris', handle: '@chuck' },
// ];
this.props.conversations = [
{
withAccount: '@machin',
messages : [],
opened : true,
},
{
withAccount: '@chuck',
messages : [],
opened : false,
},
];
this.props.following = [
{ username: 'wulfila', handle: '@wulfila' },
{ username: 'machin', handle: '@machin' },
{ username: 'chuck norris', handle: '@chuck' },
];
}
render() {
// const contactlist = null;
return (
<div >
messagerie todo
</div >
);
const contactlist = null;
// return (
// <div >
// messagerie todo
//
//
// </div >
// );
// const contactlist = this.props.following.foreEach(elem => (
// <li className='user-item'>
// <div
@ -65,83 +70,87 @@ export default class Messaging extends ImmutablePureComponent {
// <div className='last-active'>3 min</div >
// </li >
// ));
// return (
// <div className='messaging-container'>
// <div className='messaging-box'>
// <div className='title'>
// <i
// role='img'
// className='fa fa-envelope column-header__icon fa-fw'
// />
// Messaging box
// </div >
// <div className='user-list column-header'>
// <h2 className='title'>User list</h2 >
// <ul >
// {contactlist}
// </ul >
// </div >
//
// </div >
// <div className='conversations_list'>
// <ul >
// <li className='conversations_item has-new-message'>
// <div className='title'>
// <i
// role='img'
// className='fa fa-envelope column-header__icon fa-fw'
// />
// Un Gens
// <span className='new-message-counter'>
// (3)</span >
// <button className='btn-small'>
// <i
// role='img'
// className='fa fa-caret-down column-header__icon fa-fw'
// />
// </button >
// </div >
// <div className='conversation_stream'>
// <div className='message theirs'>
// <p >oh hello there! 😋 </p >
// <div className='arrow-down' />
// </div >
// <div className='message mine'>
// <p >General Emoji</p >
// <div className='arrow-down' />
// </div >
// <div className='message theirs'>
// <p >we just achieved comedy</p >
// <div className='arrow-down' />
// </div >
// </div >
// <div className='conversation_input'>
// <form
// action='#'
// // onSubmit={this.submitCompose()}
// >
// {/*value={this.newMessage.toString()}*/}
// <textarea
// name='messager'
// id=''
// cols='30'
// rows='10'
// className='messager-textarea'
// placeholder='allez dis nous tout'
//
// />
// <input
// type='submit'
// name='submit'
// value='Send'
// />
// </form >
// </div >
// </li >
// </ul >
// </div >
// </div >
// );
return (
<div className='messaging-container'>
<div className='messaging-box'>
<div className='title'>
<i
role='img'
className='fa fa-envelope column-header__icon fa-fw'
/>
Messaging box
{isStaff &&
<span >
Je suis admin oui oui
</span >
}
</div >
<div className='user-list column-header'>
<h2 className='title'>User list</h2 >
<ul >
{contactlist}
</ul >
</div >
</div >
<div className='conversations_list'>
<ul >
<li className='conversations_item has-new-message'>
<div className='title'>
<i
role='img'
className='fa fa-envelope column-header__icon fa-fw'
/>
Un Gens
<span className='new-message-counter'>
(3)</span >
<button className='btn-small'>
<i
role='img'
className='fa fa-caret-down column-header__icon fa-fw'
/>
</button >
</div >
<div className='conversation_stream'>
<div className='message theirs'>
<p >oh hello there! 😋 </p >
<div className='arrow-down' />
</div >
<div className='message mine'>
<p >General Emoji</p >
<div className='arrow-down' />
</div >
<div className='message theirs'>
<p >we just achieved comedy</p >
<div className='arrow-down' />
</div >
</div >
<div className='conversation_input'>
<form
action='#'
onSubmit={this.submitCompose()}
>
<textarea
name='messager'
id=''
cols='30'
rows='10'
className='messager-textarea'
placeholder='allez dis nous tout'
/>
<input
type='submit'
name='submit'
value='Send'
/>
</form >
</div >
</li >
</ul >
</div >
</div >
);
}
};

View File

@ -7,12 +7,21 @@ import NotificationsCounterIcon from './notifications_counter_icon';
import FollowRequestsNavLink from './follow_requests_nav_link';
import ListPanel from './list_panel';
import TrendsContainer from 'mastodon/features/getting_started/containers/trends_container';
import Messaging from './messaging';
const showMessaging = true;
const themeIsDark = true;
const NavigationPanel = () => (
<div className='navigation-panel'>
<button className='mod-theme'>
{themeIsDark ? (
<span >set light</span >
) : (
<span >set dark</span >
)}
</button >
<NavLink
className='column-link column-link--transparent'
to='/timelines/home'
@ -151,8 +160,7 @@ const NavigationPanel = () => (
{showTrends && <div className='flex-spacer' />}
{showTrends && <TrendsContainer />}
{/*{showMessaging && <Messaging />}*/}
{/*<Messaging />*/}
{showMessaging && <Messaging />}
</div >
);

View File

@ -15,9 +15,9 @@ class ReducedMotion extends React.Component {
static propTypes = {
defaultStyle: PropTypes.object,
style: PropTypes.object,
children: PropTypes.func,
}
style : PropTypes.object,
children : PropTypes.func,
};
render() {
@ -33,9 +33,12 @@ class ReducedMotion extends React.Component {
});
return (
<Motion style={style} defaultStyle={defaultStyle}>
<Motion
style={style}
defaultStyle={defaultStyle}
>
{children}
</Motion>
</Motion >
);
}

View File

@ -52,6 +52,7 @@
"bundle_modal_error.retry": "Réessayer",
"column.bookmarks": "Marque pages",
"column.blocks": "Comptes bloqués",
"column.bookmarks": "Bookmarks",
"column.community": "Fil public local",
"column.direct": "Messages privés",
"column.directory": "Parcourir les profils",
@ -139,6 +140,7 @@
"empty_column.account_timeline": "Aucun pouet ici !",
"empty_column.account_unavailable": "Profil non disponible",
"empty_column.blocks": "Vous navez bloqué aucun·e utilisateur·rice pour le moment.",
"empty_column.bookmarked_statuses": "You don't have any bookmarked toots yet. When you bookmark one, it will show up here.",
"empty_column.community": "Le fil public local est vide. Écrivez donc quelque chose pour le remplir!",
"empty_column.direct": "Vous navez pas encore de messages directs. Lorsque vous en enverrez ou recevrez un, il saffichera ici.",
"empty_column.domain_blocks": "Il ny a aucun domaine caché pour le moment.",
@ -164,7 +166,7 @@
"getting_started.documentation": "Documentation",
"getting_started.heading": "Pour commencer",
"getting_started.invite": "Inviter des gens",
"getting_started.open_source_notice": "Mastodon est un logiciel libre. Vous pouvez contribuer ou faire des rapports de bogues via {github} sur GitHub.",
"getting_started.open_source_notice": "Mastodon est un logiciel libre. Vous pouvez contribuer ou faire des rapports de bogues via {forge} sur GitHub.",
"getting_started.security": "Sécurité",
"getting_started.terms": "Conditions dutilisation",
"hashtag.column_header.tag_mode.all": "et {additional}",
@ -253,6 +255,7 @@
"mute_modal.hide_notifications": "Masquer les notifications de cette personne?",
"navigation_bar.apps": "Applications mobiles",
"navigation_bar.blocks": "Comptes bloqués",
"navigation_bar.bookmarks": "Bookmarks",
"navigation_bar.community_timeline": "Fil public local",
"navigation_bar.compose": "Rédiger un nouveau pouet",
"navigation_bar.direct": "Messages directs",
@ -371,6 +374,7 @@
"status.reblogged_by": "{name} a partagé:",
"status.reblogs.empty": "Personne na encore partagé ce pouet. Lorsque quelquun le fera, il apparaîtra ici.",
"status.redraft": "Effacer et ré-écrire",
"status.remove_bookmark": "Enlever le marque-page",
"status.reply": "Répondre",
"status.replyAll": "Répondre au fil",
"status.report": "Signaler @{name}",

View File

@ -45,7 +45,25 @@ const onDomainBlockSeverityChange = (target) => {
delegate(document, '#domain_block_severity', 'change', ({ target }) => onDomainBlockSeverityChange(target));
const onEnableBootstrapTimelineAccountsChange = (target) => {
const bootstrapTimelineAccountsField = document.querySelector('#form_admin_settings_bootstrap_timeline_accounts');
if (bootstrapTimelineAccountsField) {
bootstrapTimelineAccountsField.disabled = !target.checked;
if (target.checked) {
bootstrapTimelineAccountsField.parentElement.classList.remove('disabled');
} else {
bootstrapTimelineAccountsField.parentElement.classList.add('disabled');
}
}
};
delegate(document, '#form_admin_settings_enable_bootstrap_timeline_accounts', 'change', ({ target }) => onEnableBootstrapTimelineAccountsChange(target));
ready(() => {
const input = document.getElementById('domain_block_severity');
if (input) onDomainBlockSeverityChange(input);
const domainBlockSeverityInput = document.getElementById('domain_block_severity');
if (domainBlockSeverityInput) onDomainBlockSeverityChange(domainBlockSeverityInput);
const enableBootstrapTimelineAccounts = document.getElementById('form_admin_settings_enable_bootstrap_timeline_accounts');
if (enableBootstrapTimelineAccounts) onEnableBootstrapTimelineAccountsChange(enableBootstrapTimelineAccounts);
});

View File

@ -181,18 +181,39 @@ $content-width: 840px;
padding-top: 30px;
}
&-heading {
display: flex;
padding-bottom: 40px;
border-bottom: 1px solid lighten($ui-base-color, 8%);
margin-bottom: 40px;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
&-actions {
display: inline-flex;
& > * {
margin-left: 5px;
}
}
@media screen and (max-width: $no-columns-breakpoint) {
border-bottom: 0;
padding-bottom: 0;
}
}
h2 {
color: $secondary-text-color;
font-size: 24px;
line-height: 28px;
font-weight: 400;
padding-bottom: 40px;
border-bottom: 1px solid lighten($ui-base-color, 8%);
margin-bottom: 40px;
@media screen and (max-width: $no-columns-breakpoint) {
border-bottom: 0;
padding-bottom: 0;
font-weight: 700;
}
}

View File

@ -2512,7 +2512,6 @@ a.account__display-name {
overflow-x: hidden;
flex: 1 1 auto;
-webkit-overflow-scrolling: touch;
will-change: transform; // improves perf in mobile Chrome
&.optionally-scrollable {
overflow-y: auto;

View File

@ -5,7 +5,7 @@ class ActivityPub::Activity
include Redisable
SUPPORTED_TYPES = %w(Note Question).freeze
CONVERTED_TYPES = %w(Image Audio Video Article Page).freeze
CONVERTED_TYPES = %w(Image Audio Video Article Page Event).freeze
def initialize(json, account, **options)
@json = json

View File

@ -157,7 +157,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
return if tag['name'].blank?
Tag.find_or_create_by_names(tag['name']) do |hashtag|
@tags << hashtag unless @tags.include?(hashtag)
@tags << hashtag unless @tags.include?(hashtag) || !hashtag.valid?
end
rescue ActiveRecord::RecordInvalid
nil
@ -167,7 +167,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
return if tag['href'].blank?
account = account_from_uri(tag['href'])
account = ::FetchRemoteAccountService.new.call(tag['href']) if account.nil?
account = ActivityPub::FetchRemoteAccountService.new.call(tag['href']) if account.nil?
return if account.nil?

View File

@ -7,7 +7,7 @@
# user_id :bigint(8)
# dump_file_name :string
# dump_content_type :string
# dump_file_size :integer
# dump_file_size :bigint
# dump_updated_at :datetime
# processed :boolean default(FALSE), not null
# created_at :datetime not null

View File

@ -16,6 +16,7 @@ class Form::AdminSettings
open_deletion
timeline_preview
show_staff_badge
enable_bootstrap_timeline_accounts
bootstrap_timeline_accounts
theme
min_invite_role
@ -40,6 +41,7 @@ class Form::AdminSettings
open_deletion
timeline_preview
show_staff_badge
enable_bootstrap_timeline_accounts
activity_api_enabled
peers_api_enabled
show_known_fediverse_at_about_page

View File

@ -40,7 +40,7 @@ class Form::CustomEmojiBatch
if category_id.present?
CustomEmojiCategory.find(category_id)
elsif category_name.present?
CustomEmojiCategory.create!(name: category_name)
CustomEmojiCategory.find_or_create_by!(name: category_name)
end
end

View File

@ -117,7 +117,7 @@ class Tag < ApplicationRecord
class << self
def find_or_create_by_names(name_or_names)
Array(name_or_names).map(&method(:normalize)).uniq { |str| str.mb_chars.downcase.to_s }.map do |normalized_name|
tag = matching_name(normalized_name).first || create!(name: normalized_name)
tag = matching_name(normalized_name).first || create(name: normalized_name)
yield tag if block_given?

View File

@ -3,6 +3,8 @@
require 'rubygems/package'
class BackupService < BaseService
include Payloadable
attr_reader :account, :backup, :collection
def call(backup)
@ -20,7 +22,7 @@ class BackupService < BaseService
account.statuses.with_includes.reorder(nil).find_in_batches do |statuses|
statuses.each do |status|
item = serialize(status, ActivityPub::ActivitySerializer)
item = serialize_payload(status, ActivityPub::ActivitySerializer, signer: @account)
item.delete(:'@context')
unless item[:type] == 'Announce' || item[:object][:attachment].blank?

View File

@ -5,7 +5,7 @@ class BootstrapTimelineService < BaseService
@source_account = source_account
autofollow_inviter!
autofollow_bootstrap_timeline_accounts!
autofollow_bootstrap_timeline_accounts! if Setting.enable_bootstrap_timeline_accounts
end
private

View File

@ -45,7 +45,7 @@ class FetchLinkCardService < BaseService
def html
return @html if defined?(@html)
Request.new(:get, @url).perform do |res|
Request.new(:get, @url).add_headers('Accept' => 'text/html').perform do |res|
if res.code == 200 && res.mime_type == 'text/html'
@html = res.body_with_limit
@html_charset = res.charset

View File

@ -93,7 +93,7 @@ class FetchOEmbedService
def html
return @html if defined?(@html)
@html = @options[:html] || Request.new(:get, @url).perform do |res|
@html = @options[:html] || Request.new(:get, @url).add_headers('Accept' => 'text/html').perform do |res|
res.code != 200 || res.mime_type != 'text/html' ? nil : res.body_with_limit
end
end

View File

@ -1,17 +0,0 @@
# frozen_string_literal: true
class FetchRemoteAccountService < BaseService
def call(url, prefetched_body = nil, protocol = :ostatus)
if prefetched_body.nil?
resource_url, resource_options, protocol = FetchResourceService.new.call(url)
else
resource_url = url
resource_options = { prefetched_body: prefetched_body }
end
case protocol
when :activitypub
ActivityPub::FetchRemoteAccountService.new.call(resource_url, **resource_options)
end
end
end

View File

@ -1,17 +1,14 @@
# frozen_string_literal: true
class FetchRemoteStatusService < BaseService
def call(url, prefetched_body = nil, protocol = :ostatus)
def call(url, prefetched_body = nil)
if prefetched_body.nil?
resource_url, resource_options, protocol = FetchResourceService.new.call(url)
resource_url, resource_options = FetchResourceService.new.call(url)
else
resource_url = url
resource_options = { prefetched_body: prefetched_body }
end
case protocol
when :activitypub
ActivityPub::FetchRemoteStatusService.new.call(resource_url, **resource_options)
end
ActivityPub::FetchRemoteStatusService.new.call(resource_url, **resource_options) unless resource_url.nil?
end
end

View File

@ -33,7 +33,7 @@ class FetchResourceService < BaseService
body = response.body_with_limit
json = body_to_json(body)
[json['id'], { prefetched_body: body, id: true }, :activitypub] if supported_context?(json) && (equals_or_includes_any?(json['type'], ActivityPub::FetchRemoteAccountService::SUPPORTED_TYPES) || expected_type?(json))
[json['id'], { prefetched_body: body, id: true }] if supported_context?(json) && (equals_or_includes_any?(json['type'], ActivityPub::FetchRemoteAccountService::SUPPORTED_TYPES) || expected_type?(json))
elsif !terminal
link_header = response['Link'] && parse_link_header(response)

View File

@ -19,9 +19,9 @@ class ResolveURLService < BaseService
def process_url
if equals_or_includes_any?(type, ActivityPub::FetchRemoteAccountService::SUPPORTED_TYPES)
FetchRemoteAccountService.new.call(resource_url, body, protocol)
ActivityPub::FetchRemoteAccountService.new.call(resource_url, prefetched_body: body)
elsif equals_or_includes_any?(type, ActivityPub::Activity::Create::SUPPORTED_TYPES + ActivityPub::Activity::Create::CONVERTED_TYPES)
status = FetchRemoteStatusService.new.call(resource_url, body, protocol)
status = FetchRemoteStatusService.new.call(resource_url, body)
authorize_with @on_behalf_of, status, :show? unless status.nil?
status
elsif fetched_resource.nil? && @on_behalf_of.present?
@ -45,12 +45,8 @@ class ResolveURLService < BaseService
fetched_resource.second[:prefetched_body]
end
def protocol
fetched_resource.third
end
def type
return json_data['type'] if protocol == :activitypub
json_data['type']
end
def json_data

View File

@ -4,21 +4,12 @@
- content_for :page_title do
= t('admin.reports.report', id: @report.id)
%div{ style: 'overflow: hidden; margin-bottom: 20px' }
- content_for :page_heading_actions do
- if @report.unresolved?
%div{ style: 'float: right' }
- if @report.target_account.local?
= link_to t('admin.accounts.warn'), new_admin_account_action_path(@report.target_account_id, type: 'none', report_id: @report.id), class: 'button'
= link_to t('admin.accounts.disable'), new_admin_account_action_path(@report.target_account_id, type: 'disable', report_id: @report.id), class: 'button button--destructive'
= link_to t('admin.accounts.silence'), new_admin_account_action_path(@report.target_account_id, type: 'silence', report_id: @report.id), class: 'button button--destructive'
= link_to t('admin.accounts.perform_full_suspension'), new_admin_account_action_path(@report.target_account_id, type: 'suspend', report_id: @report.id), class: 'button button--destructive'
%div{ style: 'float: left' }
= link_to t('admin.reports.mark_as_resolved'), resolve_admin_report_path(@report), method: :post, class: 'button'
= link_to t('admin.reports.mark_as_resolved'), resolve_admin_report_path(@report), method: :post, class: 'button'
- else
= link_to t('admin.reports.mark_as_unresolved'), reopen_admin_report_path(@report), method: :post, class: 'button'
%hr.spacer
.table-wrapper
%table.table.inline-table
%tbody
@ -77,6 +68,17 @@
%hr.spacer
%div{ style: 'overflow: hidden; margin-bottom: 20px; clear: both' }
- if @report.unresolved?
%div{ style: 'float: right' }
- if @report.target_account.local?
= link_to t('admin.accounts.warn'), new_admin_account_action_path(@report.target_account_id, type: 'none', report_id: @report.id), class: 'button'
= link_to t('admin.accounts.disable'), new_admin_account_action_path(@report.target_account_id, type: 'disable', report_id: @report.id), class: 'button button--destructive'
= link_to t('admin.accounts.silence'), new_admin_account_action_path(@report.target_account_id, type: 'silence', report_id: @report.id), class: 'button button--destructive'
= link_to t('admin.accounts.perform_full_suspension'), new_admin_account_action_path(@report.target_account_id, type: 'suspend', report_id: @report.id), class: 'button button--destructive'
%hr.spacer
.speech-bubble
.speech-bubble__bubble= simple_format(@report.comment.presence || t('admin.reports.comment.none'))
.speech-bubble__owner

View File

@ -1,3 +1,6 @@
- content_for :header_tags do
= javascript_pack_tag 'admin', integrity: true, async: true, crossorigin: 'anonymous'
- content_for :page_title do
= t('admin.settings.title')
@ -38,7 +41,9 @@
%hr.spacer/
.fields-group
= f.input :bootstrap_timeline_accounts, wrapper: :with_block_label, label: t('admin.settings.bootstrap_timeline_accounts.title'), hint: t('admin.settings.bootstrap_timeline_accounts.desc_html')
= f.input :enable_bootstrap_timeline_accounts, as: :boolean, wrapper: :with_label, label: t('admin.settings.enable_bootstrap_timeline_accounts.title')
.fields-group
= f.input :bootstrap_timeline_accounts, wrapper: :with_block_label, label: t('admin.settings.bootstrap_timeline_accounts.title'), hint: t('admin.settings.bootstrap_timeline_accounts.desc_html'), disabled: !Setting.enable_bootstrap_timeline_accounts
%hr.spacer/

View File

@ -21,7 +21,12 @@
.content-wrapper
.content
%h2= yield :page_title
.content-heading
%h2= yield :page_title
- if :page_heading_actions
.content-heading-actions
= yield :page_heading_actions
= render 'application/flashes'

View File

@ -9,11 +9,11 @@
%td= number_to_human_size @export.total_storage
%td
%tr
%th= t('accounts.posts', count: @export.total_statuses)
%th= t('accounts.posts_tab_heading')
%td= number_with_delimiter @export.total_statuses
%td
%tr
%th= t('exports.follows')
%th= t('admin.accounts.follows')
%td= number_with_delimiter @export.total_follows
%td= table_link_to 'download', t('exports.csv'), settings_exports_follows_path(format: :csv)
%tr
@ -21,7 +21,7 @@
%td= number_with_delimiter @export.total_lists
%td= table_link_to 'download', t('exports.csv'), settings_exports_lists_path(format: :csv)
%tr
%th= t('accounts.followers', count: @export.total_followers)
%th= t('admin.accounts.followers')
%td= number_with_delimiter @export.total_followers
%td
%tr

View File

@ -124,9 +124,7 @@ ar:
email_status: حالة البريد الإلكتروني
enable: تفعيل
enabled: مفعَّل
feed_url: عنوان رابط التغذية
followers: المتابِعون
followers_url: عنوان رابط المتابِعين
follows: يتابع
header: الرأسية
inbox_url: رابط صندوق الوارد
@ -154,10 +152,8 @@ ar:
no_account_selected: لم يطرأ أي تغيير على أي حساب بما أنه لم يتم اختيار أي واحد
no_limits_imposed: مِن دون حدود مشروطة
not_subscribed: غير مشترك
outbox_url: رابط صندوق الصادر
pending: في انتظار المراجعة
perform_full_suspension: تعليق الحساب
profile_url: رابط الصفحة التعريفية
promote: ترقية
protocol: البروتوكول
public: عمومي
@ -180,7 +176,6 @@ ar:
moderator: مشرف
staff: الفريق
user: مستخدِم
salmon_url: عنوان رابط سالمون Salmon
search: البحث
shared_inbox_url: رابط الصندوق المُشترَك للبريد الوارد
show:

View File

@ -118,9 +118,7 @@ bn:
email_status: ইমেইলের অবস্থা
enable: চালু করুন
enabled: চালু করুন
feed_url: সম্মিলিত(feed) লিংক
followers: অনুসরকারীরা
followers_url: অনুসরণকারীদের লিংক
follows: অনুসরণ করে
header: শিরোলেখা
inbox_url: চিঠি পাওয়ার বক্স লিংক
@ -148,10 +146,8 @@ bn:
no_account_selected: কোনও অ্যাকাউন্টই নির্বাচন করা হয়নি বলে কোনও অ্যাকাউন্ট পরিবর্তন করা হয়নি
no_limits_imposed: কোন সীমা আরোপ করা নেই
not_subscribed: সাবস্ক্রাইব নেই
outbox_url: চিঠি পাঠানোর বাক্স লিংক
pending: পয্র্যবেক্ষণের অপেক্ষায় আছে
perform_full_suspension: বাতিল করা
profile_url: প্রোফাইল URL
promote: প্রচার
protocol: প্রোটোকল
public: সর্বজনীন
@ -174,7 +170,6 @@ bn:
moderator: নিয়ামক
staff: কর্মী
user: ব্যবহারকারী
salmon_url: সালমন URL
search: অনুসন্ধান
search_same_ip: একই IP সহ অন্যান্য ব্যবহারকারীরা
shared_inbox_url: ভাগ করা ইনবক্স URL

View File

@ -118,9 +118,7 @@ ca:
email_status: Estat del correu electrònic
enable: Habilita
enabled: Habilitat
feed_url: URL del canal
followers: Seguidors
followers_url: URL dels seguidors
follows: Segueix
header: Capçalera
inbox_url: URL de la safata d'entrada
@ -148,10 +146,8 @@ ca:
no_account_selected: No s'han canviat els comptes perque no s'han seleccionat
no_limits_imposed: Sense límits imposats
not_subscribed: No subscrit
outbox_url: URL de la bústia de sortida
pending: Revisió pendent
perform_full_suspension: Suspèn
profile_url: URL del perfil
promote: Promociona
protocol: Protocol
public: Públic
@ -174,7 +170,6 @@ ca:
moderator: Moderador
staff: Personal
user: Usuari
salmon_url: URL Salmon
search: Cerca
search_same_ip: Altres usuaris amb la mateixa IP
shared_inbox_url: URL de la safata d'entrada compartida

View File

@ -118,9 +118,7 @@ co:
email_status: Statutu di le-mail
enable: Attivà
enabled: Attivatu
feed_url: URL di u flussu
followers: Abbunati
followers_url: URL di labbunati
follows: Abbunamenti
header: Intistatura
inbox_url: URL di linbox
@ -148,10 +146,8 @@ co:
no_account_selected: Nisun contu hè statu cambiatu postu ch'ùn c'eranu micca selezziunati
no_limits_imposed: Nisuna limita imposta
not_subscribed: Micca abbunatu
outbox_url: URL di loutbox
pending: In attesa di rivista
perform_full_suspension: Suspende
profile_url: URL di u prufile
promote: Prumove
protocol: Prutucollu
public: Pubblicu
@ -174,7 +170,6 @@ co:
moderator: Muderatore
staff: Squadra
user: Utilizatore
salmon_url: URL di Salmon
search: Cercà
search_same_ip: Altri utilizatori cù listessa IP
shared_inbox_url: URL di linbox spartuta

View File

@ -126,9 +126,7 @@ cs:
email_status: Stav e-mailu
enable: Povolit
enabled: Povoleno
feed_url: URL proudu
followers: Sledující
followers_url: URL sledujících
follows: Sledovaní
header: Záhlaví
inbox_url: URL příchozí schránky
@ -156,10 +154,8 @@ cs:
no_account_selected: Nebyl změněn žádný účet, neboť žádný nebyl zvolen
no_limits_imposed: Nejsou nastavena žádná omezení
not_subscribed: Neodebírá
outbox_url: URL odchozí schránky
pending: Čeká na posouzení
perform_full_suspension: Pozastavit
profile_url: URL profilu
promote: Povýšit
protocol: Protokol
public: Veřejný
@ -182,7 +178,6 @@ cs:
moderator: Moderátor
staff: Člen personálu
user: Uživatel
salmon_url: URL Salmon
search: Hledat
search_same_ip: Další uživatelé se stejnou IP adresou
shared_inbox_url: URL sdílené příchozí schránky

View File

@ -133,9 +133,7 @@ cy:
email_status: Statws E-bost
enable: Galluogi
enabled: Wedi ei alluogi
feed_url: