Skip to content

Commit

Permalink
Merge pull request #1499 from S-H-GAMELINKS/merge/mastodon-main-branch
Browse files Browse the repository at this point in the history
Merge/mastodon main branch
  • Loading branch information
S-H-GAMELINKS authored Jul 20, 2024
2 parents 72990dd + 2c06dc0 commit 0b14bd5
Show file tree
Hide file tree
Showing 275 changed files with 7,092 additions and 1,393 deletions.
4 changes: 2 additions & 2 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ public/gallery/asset-manifest.json
public/creatodon-folio/static/css/*.css
public/gallery/static/css/*.css

# Ignore Twitetr theme json
app/javascript/styles/twitter/package.json
# Ignore Twitetr theme
app/javascript/styles/twitter/*

# Process a few selected JS files
!lint-staged.config.js
5 changes: 5 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ You can contribute in the following ways:

If your contributions are accepted into Mastodon, you can request to be paid through [our OpenCollective](https://opencollective.com/mastodon).

Please review the org-level [contribution guidelines] for high-level acceptance
criteria guidance.

[contribution guidelines]: https://github.com/mastodon/.github/blob/main/CONTRIBUTING.md

## API Changes and Additions

Please note that any changes or additions made to the API should have an accompanying pull request on [our documentation repository](https://github.com/mastodon/documentation).
Expand Down
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ gem 'sidekiq-unique-jobs', '~> 7.1'
gem 'simple_form', '~> 5.2'
gem 'simple-navigation', '~> 4.4'
gem 'stoplight', '~> 4.1'
gem 'strong_migrations', '1.8.0'
gem 'strong_migrations'
gem 'tty-prompt', '~> 0.23', require: false
gem 'twitter-text', '~> 3.1.0'
gem 'tzinfo-data', '~> 1.2023'
Expand Down
19 changes: 10 additions & 9 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ GEM
tzinfo
excon (0.110.0)
fabrication (2.31.0)
faker (3.4.1)
faker (3.4.2)
i18n (>= 1.8.11, < 2)
faraday (1.10.3)
faraday-em_http (~> 1.0)
Expand Down Expand Up @@ -395,7 +395,7 @@ GEM
json-ld-preloaded (3.3.0)
json-ld (~> 3.3)
rdf (~> 3.3)
json-schema (4.3.0)
json-schema (4.3.1)
addressable (>= 2.8)
jsonapi-renderer (0.2.2)
jwt (2.7.1)
Expand Down Expand Up @@ -738,7 +738,7 @@ GEM
responders (3.1.1)
actionpack (>= 5.2)
railties (>= 5.2)
rexml (3.3.1)
rexml (3.3.2)
strscan
rotp (6.3.0)
rouge (4.2.1)
Expand Down Expand Up @@ -808,8 +808,9 @@ GEM
ruby-saml (1.16.0)
nokogiri (>= 1.13.10)
rexml
ruby-vips (2.2.1)
ruby-vips (2.2.2)
ffi (~> 1.12)
logger
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
rufus-scheduler (3.9.1)
Expand All @@ -825,7 +826,7 @@ GEM
activerecord (>= 4.0.0)
railties (>= 4.0.0)
securerandom (0.3.1)
selenium-webdriver (4.22.0)
selenium-webdriver (4.23.0)
base64 (~> 0.2)
logger (~> 1.4)
rexml (~> 3.2, >= 3.2.5)
Expand Down Expand Up @@ -880,8 +881,8 @@ GEM
stoplight (4.1.0)
redlock (~> 1.0)
stringio (3.1.1)
strong_migrations (1.8.0)
activerecord (>= 5.2)
strong_migrations (2.0.0)
activerecord (>= 6.1)
strscan (3.0.9)
swd (1.3.0)
activesupport (>= 3)
Expand Down Expand Up @@ -955,7 +956,7 @@ GEM
railties (>= 5.2)
semantic_range (>= 2.3.0)
webrick (1.8.1)
websocket (1.2.10)
websocket (1.2.11)
websocket-driver (0.7.6)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
Expand Down Expand Up @@ -1117,7 +1118,7 @@ DEPENDENCIES
stackprof
steep
stoplight (~> 4.1)
strong_migrations (= 1.8.0)
strong_migrations
strscan (= 3.0.9)
test-prof
thor (~> 1.2)
Expand Down
7 changes: 1 addition & 6 deletions app/controllers/api/v1/admin/domain_allows_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,13 @@ def destroy
private

def set_domain_allows
@domain_allows = filtered_domain_allows.order(id: :desc).to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
@domain_allows = DomainAllow.order(id: :desc).to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
end

def set_domain_allow
@domain_allow = DomainAllow.find(params[:id])
end

def filtered_domain_allows
# TODO: no filtering yet
DomainAllow.all
end

def next_path
api_v1_admin_domain_allows_url(pagination_params(max_id: pagination_max_id)) if records_continue?
end
Expand Down
7 changes: 1 addition & 6 deletions app/controllers/api/v1/admin/domain_blocks_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,13 @@ def conflicts_with_existing_block?(domain_block, existing_domain_block)
end

def set_domain_blocks
@domain_blocks = filtered_domain_blocks.order(id: :desc).to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
@domain_blocks = DomainBlock.order(id: :desc).to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
end

def set_domain_block
@domain_block = DomainBlock.find(params[:id])
end

def filtered_domain_blocks
# TODO: no filtering yet
DomainBlock.all
end

def domain_block_params
params.permit(:severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate)
end
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/api/v1/reports_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def create
@report = ReportService.new.call(
current_account,
reported_account,
report_params
report_params.merge(application: doorkeeper_token.application)
)

render json: @report, serializer: REST::ReportSerializer
Expand Down
55 changes: 41 additions & 14 deletions app/controllers/api/v2_alpha/notifications_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,27 @@ def index
with_read_replica do
@notifications = load_notifications
@group_metadata = load_group_metadata
@grouped_notifications = load_grouped_notifications
@relationships = StatusRelationshipsPresenter.new(target_statuses_from_notifications, current_user&.account_id)
@sample_accounts = @grouped_notifications.flat_map(&:sample_accounts)

# Preload associations to avoid N+1s
ActiveRecord::Associations::Preloader.new(records: @sample_accounts, associations: [:account_stat, { user: :role }]).call
end

render json: @notifications.map { |notification| NotificationGroup.from_notification(notification, max_id: @group_metadata.dig(notification.group_key, :max_id)) }, each_serializer: REST::NotificationGroupSerializer, relationships: @relationships, group_metadata: @group_metadata
MastodonOTELTracer.in_span('Api::V2Alpha::NotificationsController#index rendering') do |span|
statuses = @grouped_notifications.filter_map { |group| group.target_status&.id }

span.add_attributes(
'app.notification_grouping.count' => @grouped_notifications.size,
'app.notification_grouping.sample_account.count' => @sample_accounts.size,
'app.notification_grouping.sample_account.unique_count' => @sample_accounts.pluck(:id).uniq.size,
'app.notification_grouping.status.count' => statuses.size,
'app.notification_grouping.status.unique_count' => statuses.uniq.size
)

render json: @grouped_notifications, each_serializer: REST::NotificationGroupSerializer, relationships: @relationships, group_metadata: @group_metadata
end
end

def show
Expand All @@ -36,25 +53,35 @@ def dismiss
private

def load_notifications
notifications = browserable_account_notifications.includes(from_account: [:account_stat, :user]).to_a_grouped_paginated_by_id(
limit_param(DEFAULT_NOTIFICATIONS_LIMIT),
params_slice(:max_id, :since_id, :min_id)
)

Notification.preload_cache_collection_target_statuses(notifications) do |target_statuses|
preload_collection(target_statuses, Status)
MastodonOTELTracer.in_span('Api::V2Alpha::NotificationsController#load_notifications') do
notifications = browserable_account_notifications.includes(from_account: [:account_stat, :user]).to_a_grouped_paginated_by_id(
limit_param(DEFAULT_NOTIFICATIONS_LIMIT),
params_slice(:max_id, :since_id, :min_id)
)

Notification.preload_cache_collection_target_statuses(notifications) do |target_statuses|
preload_collection(target_statuses, Status)
end
end
end

def load_group_metadata
return {} if @notifications.empty?

browserable_account_notifications
.where(group_key: @notifications.filter_map(&:group_key))
.where(id: (@notifications.last.id)..(@notifications.first.id))
.group(:group_key)
.pluck(:group_key, 'min(notifications.id) as min_id', 'max(notifications.id) as max_id', 'max(notifications.created_at) as latest_notification_at')
.to_h { |group_key, min_id, max_id, latest_notification_at| [group_key, { min_id: min_id, max_id: max_id, latest_notification_at: latest_notification_at }] }
MastodonOTELTracer.in_span('Api::V2Alpha::NotificationsController#load_group_metadata') do
browserable_account_notifications
.where(group_key: @notifications.filter_map(&:group_key))
.where(id: (@notifications.last.id)..(@notifications.first.id))
.group(:group_key)
.pluck(:group_key, 'min(notifications.id) as min_id', 'max(notifications.id) as max_id', 'max(notifications.created_at) as latest_notification_at')
.to_h { |group_key, min_id, max_id, latest_notification_at| [group_key, { min_id: min_id, max_id: max_id, latest_notification_at: latest_notification_at }] }
end
end

def load_grouped_notifications
MastodonOTELTracer.in_span('Api::V2Alpha::NotificationsController#load_grouped_notifications') do
@notifications.map { |notification| NotificationGroup.from_notification(notification, max_id: @group_metadata.dig(notification.group_key, :max_id)) }
end
end

def browserable_account_notifications
Expand Down
12 changes: 8 additions & 4 deletions app/helpers/theme_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,21 @@
module ThemeHelper
def theme_style_tags(theme)
if theme == 'system'
stylesheet_pack_tag('mastodon-light', media: 'not all and (prefers-color-scheme: dark)', crossorigin: 'anonymous') +
stylesheet_pack_tag('default', media: '(prefers-color-scheme: dark)', crossorigin: 'anonymous')
''.html_safe.tap do |tags|
tags << stylesheet_pack_tag('mastodon-light', media: 'not all and (prefers-color-scheme: dark)', crossorigin: 'anonymous')
tags << stylesheet_pack_tag('default', media: '(prefers-color-scheme: dark)', crossorigin: 'anonymous')
end
else
stylesheet_pack_tag theme, media: 'all', crossorigin: 'anonymous'
end
end

def theme_color_tags(theme)
if theme == 'system'
tag.meta(name: 'theme-color', content: Themes::THEME_COLORS[:dark], media: '(prefers-color-scheme: dark)') +
tag.meta(name: 'theme-color', content: Themes::THEME_COLORS[:light], media: '(prefers-color-scheme: light)')
''.html_safe.tap do |tags|
tags << tag.meta(name: 'theme-color', content: Themes::THEME_COLORS[:dark], media: '(prefers-color-scheme: dark)')
tags << tag.meta(name: 'theme-color', content: Themes::THEME_COLORS[:light], media: '(prefers-color-scheme: light)')
end
else
tag.meta name: 'theme-color', content: theme_color_for(theme)
end
Expand Down
4 changes: 2 additions & 2 deletions app/javascript/entrypoints/public.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,8 @@ function loaded() {

const message =
statusEl.dataset.spoiler === 'expanded'
? localeData['status.show_less'] ?? 'Show less'
: localeData['status.show_more'] ?? 'Show more';
? (localeData['status.show_less'] ?? 'Show less')
: (localeData['status.show_more'] ?? 'Show more');
spoilerLink.textContent = new IntlMessageFormat(
message,
locale,
Expand Down
29 changes: 15 additions & 14 deletions app/javascript/mastodon/actions/compose.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import axios from 'axios';
import { throttle } from 'lodash';

import api from 'mastodon/api';
import { browserHistory } from 'mastodon/components/router';
import { search as emojiSearch } from 'mastodon/features/emoji/emoji_mart_search_light';
import { tagHistory } from 'mastodon/settings';

Expand Down Expand Up @@ -99,9 +100,9 @@ const messages = defineMessages({
saved: { id: 'compose.saved.body', defaultMessage: 'Post saved.' },
});

export const ensureComposeIsVisible = (getState, routerHistory) => {
export const ensureComposeIsVisible = (getState) => {
if (!getState().getIn(['compose', 'mounted'])) {
routerHistory.push('/publish');
browserHistory.push('/publish');
}
};

Expand All @@ -121,14 +122,14 @@ export function changeCompose(text) {
};
}

export function replyCompose(status, routerHistory) {
export function replyCompose(status) {
return (dispatch, getState) => {
dispatch({
type: COMPOSE_REPLY,
status: status,
});

ensureComposeIsVisible(getState, routerHistory);
ensureComposeIsVisible(getState);
};
}

Expand All @@ -144,38 +145,38 @@ export function resetCompose() {
};
}

export const focusCompose = (routerHistory, defaultText) => (dispatch, getState) => {
export const focusCompose = (defaultText) => (dispatch, getState) => {
dispatch({
type: COMPOSE_FOCUS,
defaultText,
});

ensureComposeIsVisible(getState, routerHistory);
ensureComposeIsVisible(getState);
};

export function mentionCompose(account, routerHistory) {
export function mentionCompose(account) {
return (dispatch, getState) => {
dispatch({
type: COMPOSE_MENTION,
account: account,
});

ensureComposeIsVisible(getState, routerHistory);
ensureComposeIsVisible(getState);
};
}

export function directCompose(account, routerHistory) {
export function directCompose(account) {
return (dispatch, getState) => {
dispatch({
type: COMPOSE_DIRECT,
account: account,
});

ensureComposeIsVisible(getState, routerHistory);
ensureComposeIsVisible(getState);
};
}

export function submitCompose(routerHistory) {
export function submitCompose() {
return function (dispatch, getState) {
const status = getState().getIn(['compose', 'text'], '');
const media = getState().getIn(['compose', 'media_attachments']);
Expand Down Expand Up @@ -244,8 +245,8 @@ export function submitCompose(routerHistory) {
dispatch(submitScheduledStatusSuccess({ ...response.data }));
return;
}
if (routerHistory && (routerHistory.location.pathname === '/publish' || routerHistory.location.pathname === '/statuses/new') && window.history.state) {
routerHistory.goBack();
if ((browserHistory.location.pathname === '/publish' || browserHistory.location.pathname === '/statuses/new') && window.history.state) {
browserHistory.goBack();
}

dispatch(insertIntoTagHistory(response.data.tags, status));
Expand Down Expand Up @@ -279,7 +280,7 @@ export function submitCompose(routerHistory) {
message: statusId === null ? messages.published : messages.saved,
action: messages.open,
dismissAfter: 10000,
onClick: () => routerHistory.push(`/@${response.data.account.username}/${response.data.id}`),
onClick: () => browserHistory.push(`/@${response.data.account.username}/${response.data.id}`),
}));
}).catch(function (error) {
dispatch(submitComposeFail(error));
Expand Down
14 changes: 11 additions & 3 deletions app/javascript/mastodon/actions/markers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,17 @@ interface MarkerParam {
}

function getLastNotificationId(state: RootState): string | undefined {
// @ts-expect-error state.notifications is not yet typed
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call
return state.getIn(['notifications', 'lastReadId']);
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
const enableBeta = state.settings.getIn(
['notifications', 'groupingBeta'],
false,
) as boolean;
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return enableBeta
? state.notificationGroups.lastReadId
: // @ts-expect-error state.notifications is not yet typed
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
state.getIn(['notifications', 'lastReadId']);
}

const buildPostMarkersParams = (state: RootState) => {
Expand Down
Loading

0 comments on commit 0b14bd5

Please sign in to comment.