Skip to content

Commit

Permalink
Merge pull request #2806 from ClearlyClaire/glitch-soc/merge-upstream
Browse files Browse the repository at this point in the history
Merge upstream changes up to c8b9e60
  • Loading branch information
ClearlyClaire authored Aug 7, 2024
2 parents a31ab56 + 4354665 commit 241d760
Show file tree
Hide file tree
Showing 88 changed files with 1,363 additions and 713 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ FROM build AS ffmpeg

# ffmpeg version to compile, change with [--build-arg FFMPEG_VERSION="7.0.x"]
# renovate: datasource=repology depName=ffmpeg packageName=openpkg_current/ffmpeg
ARG FFMPEG_VERSION=7.0.1
ARG FFMPEG_VERSION=7.0.2
# ffmpeg download URL, change with [--build-arg FFMPEG_URL="https://ffmpeg.org/releases"]
ARG FFMPEG_URL=https://ffmpeg.org/releases

Expand Down
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ gem 'pghero'

gem 'aws-sdk-s3', '~> 1.123', require: false
gem 'blurhash', '~> 0.1'
gem 'fog-core', '<= 2.4.0'
gem 'fog-core', '<= 2.5.0'
gem 'fog-openstack', '~> 1.0', require: false
gem 'kt-paperclip', '~> 7.2'
gem 'md-paperclip-azure', '~> 2.2', require: false
Expand Down
22 changes: 11 additions & 11 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -100,20 +100,20 @@ GEM
attr_required (1.0.2)
awrence (1.2.1)
aws-eventstream (1.3.0)
aws-partitions (1.950.0)
aws-sdk-core (3.201.0)
aws-partitions (1.961.0)
aws-sdk-core (3.201.3)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.8)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.88.0)
aws-sdk-core (~> 3, >= 3.201.0)
aws-sigv4 (~> 1.5)
aws-sdk-s3 (1.156.0)
aws-sdk-s3 (1.157.0)
aws-sdk-core (~> 3, >= 3.201.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.5)
aws-sigv4 (1.8.0)
aws-sigv4 (1.9.1)
aws-eventstream (~> 1, >= 1.0.2)
azure-storage-blob (2.0.3)
azure-storage-common (~> 2.0)
Expand All @@ -135,7 +135,7 @@ GEM
binding_of_caller (1.0.1)
debug_inspector (>= 1.2.0)
blurhash (0.1.7)
bootsnap (1.18.3)
bootsnap (1.18.4)
msgpack (~> 1.2)
brakeman (6.1.2)
racc
Expand Down Expand Up @@ -229,7 +229,7 @@ GEM
erubi (1.13.0)
et-orbi (1.2.11)
tzinfo
excon (0.110.0)
excon (0.111.0)
fabrication (2.31.0)
faker (3.4.2)
i18n (>= 1.8.11, < 2)
Expand Down Expand Up @@ -269,7 +269,7 @@ GEM
flatware-rspec (2.3.2)
flatware (= 2.3.2)
rspec (>= 3.6)
fog-core (2.4.0)
fog-core (2.5.0)
builder
excon (~> 0.71)
formatador (>= 0.2, < 2.0)
Expand Down Expand Up @@ -429,7 +429,7 @@ GEM
memory_profiler (1.0.2)
mime-types (3.5.2)
mime-types-data (~> 3.2015)
mime-types-data (3.2024.0604)
mime-types-data (3.2024.0702)
mini_mime (1.1.5)
mini_portile2 (2.8.7)
minitest (5.24.1)
Expand Down Expand Up @@ -758,7 +758,7 @@ GEM
rack (>= 1.1)
rubocop (>= 1.33.0, < 2.0)
rubocop-ast (>= 1.31.1, < 2.0)
rubocop-rspec (3.0.3)
rubocop-rspec (3.0.4)
rubocop (~> 1.61)
rubocop-rspec_rails (2.30.0)
rubocop (~> 1.61)
Expand Down Expand Up @@ -796,7 +796,7 @@ GEM
redis (>= 4.5.0, < 5)
sidekiq-bulk (0.2.0)
sidekiq
sidekiq-scheduler (5.0.5)
sidekiq-scheduler (5.0.6)
rufus-scheduler (~> 3.2)
sidekiq (>= 6, < 8)
tilt (>= 1.4.0, < 3)
Expand Down Expand Up @@ -945,7 +945,7 @@ DEPENDENCIES
fast_blank (~> 1.0)
fastimage
flatware-rspec
fog-core (<= 2.4.0)
fog-core (<= 2.5.0)
fog-openstack (~> 1.0)
fuubar (~> 2.5)
haml-rails (~> 2.0)
Expand Down
25 changes: 18 additions & 7 deletions app/controllers/api/v2_alpha/notifications_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,25 @@ def index
@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)
@presenter = GroupedNotificationsPresenter.new(@grouped_notifications, expand_accounts: expand_accounts_param)

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

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.account.count' => @presenter.accounts.size,
'app.notification_grouping.partial_account.count' => @presenter.partial_accounts.size,
'app.notification_grouping.status.count' => statuses.size,
'app.notification_grouping.status.unique_count' => statuses.uniq.size
'app.notification_grouping.status.unique_count' => statuses.uniq.size,
'app.notification_grouping.expand_accounts_param' => expand_accounts_param
)

presenter = GroupedNotificationsPresenter.new(@grouped_notifications)
render json: presenter, serializer: REST::DedupNotificationGroupSerializer, relationships: @relationships, group_metadata: @group_metadata
render json: @presenter, serializer: REST::DedupNotificationGroupSerializer, relationships: @relationships, group_metadata: @group_metadata, expand_accounts: expand_accounts_param
end
end

Expand Down Expand Up @@ -131,4 +131,15 @@ def browserable_params
def pagination_params(core_params)
params.slice(:limit, :types, :exclude_types, :include_filtered).permit(:limit, :include_filtered, types: [], exclude_types: []).merge(core_params)
end

def expand_accounts_param
case params[:expand_accounts]
when nil, 'full'
'full'
when 'partial_avatars'
'partial_avatars'
else
raise Mastodon::InvalidParameterError, "Invalid value for 'expand_accounts': '#{params[:expand_accounts]}', allowed values are 'full' and 'partial_avatars'"
end
end
end
36 changes: 36 additions & 0 deletions app/javascript/entrypoints/public.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,42 @@ Rails.delegate(document, 'img.custom-emoji', 'mouseout', ({ target }) => {
target.src = target.dataset.static;
});

const setInputDisabled = (
input: HTMLInputElement | HTMLSelectElement,
disabled: boolean,
) => {
input.disabled = disabled;

const wrapper = input.closest('.with_label');
if (wrapper) {
wrapper.classList.toggle('disabled', input.disabled);

const hidden =
input.type === 'checkbox' &&
wrapper.querySelector<HTMLInputElement>('input[type=hidden][value="0"]');
if (hidden) {
hidden.disabled = input.disabled;
}
}
};

Rails.delegate(
document,
'#account_statuses_cleanup_policy_enabled',
'change',
({ target }) => {
if (!(target instanceof HTMLInputElement) || !target.form) return;

target.form
.querySelectorAll<
HTMLInputElement | HTMLSelectElement
>('input:not([type=hidden], #account_statuses_cleanup_policy_enabled), select')
.forEach((input) => {
setInputDisabled(input, !target.checked);
});
},
);

// Empty the honeypot fields in JS in case something like an extension
// automatically filled them.
Rails.delegate(document, '#registration_new_user,#new_user', 'submit', () => {
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/flavours/glitch/components/account.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ const Account = ({ size = 46, account, onFollow, onBlock, onMute, onMuteNotifica
</>
);
} else if (defaultAction === 'mute') {
buttons = <Button title={intl.formatMessage(messages.mute)} onClick={handleMute} />;
buttons = <Button text={intl.formatMessage(messages.mute)} onClick={handleMute} />;
} else if (defaultAction === 'block') {
buttons = <Button text={intl.formatMessage(messages.block)} onClick={handleBlock} />;
} else if (!account.get('suspended') && !account.get('moved') || following) {
Expand Down
18 changes: 18 additions & 0 deletions app/javascript/flavours/glitch/components/hover_card_account.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { useEffect, forwardRef } from 'react';

import { FormattedMessage } from 'react-intl';

import classNames from 'classnames';

import { fetchAccount } from 'flavours/glitch/actions/accounts';
Expand All @@ -25,6 +27,11 @@ export const HoverCardAccount = forwardRef<
accountId ? state.accounts.get(accountId) : undefined,
);

const note = useAppSelector(
(state) =>
state.relationships.getIn([accountId, 'note']) as string | undefined,
);

useEffect(() => {
if (accountId && !account) {
dispatch(fetchAccount(accountId));
Expand Down Expand Up @@ -57,6 +64,17 @@ export const HoverCardAccount = forwardRef<
className='hover-card__bio'
/>
<AccountFields fields={account.fields} limit={2} />
{note && note.length > 0 && (
<dl className='hover-card__note'>
<dt className='hover-card__note-label'>
<FormattedMessage
id='account.account_note_header'
defaultMessage='Personal note'
/>
</dt>
<dd>{note}</dd>
</dl>
)}
</div>

<div className='hover-card__number'>
Expand Down
36 changes: 36 additions & 0 deletions app/javascript/flavours/glitch/entrypoints/public.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,42 @@ Rails.delegate(document, 'img.custom-emoji', 'mouseout', ({ target }) => {
target.src = target.dataset.static;
});

const setInputDisabled = (
input: HTMLInputElement | HTMLSelectElement,
disabled: boolean,
) => {
input.disabled = disabled;

const wrapper = input.closest('.with_label');
if (wrapper) {
wrapper.classList.toggle('disabled', input.disabled);

const hidden =
input.type === 'checkbox' &&
wrapper.querySelector<HTMLInputElement>('input[type=hidden][value="0"]');
if (hidden) {
hidden.disabled = input.disabled;
}
}
};

Rails.delegate(
document,
'#account_statuses_cleanup_policy_enabled',
'change',
({ target }) => {
if (!(target instanceof HTMLInputElement) || !target.form) return;

target.form
.querySelectorAll<
HTMLInputElement | HTMLSelectElement
>('input:not([type=hidden], #account_statuses_cleanup_policy_enabled), select')
.forEach((input) => {
setInputDisabled(input, !target.checked);
});
},
);

// Empty the honeypot fields in JS in case something like an extension
// automatically filled them.
Rails.delegate(document, '#registration_new_user,#new_user', 'submit', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ class AccountNote extends ImmutablePureComponent {
return (
<div className='account__header__account-note'>
<label htmlFor={`account-note-${account.get('id')}`}>
<FormattedMessage id='account.account_note_header' defaultMessage='Note' /> <InlineAlert show={saved} />
<FormattedMessage id='account.account_note_header' defaultMessage='Personal note' /> <InlineAlert show={saved} />
</label>

<Textarea
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const ColumnSettings = () => {
settingPath={['minimizeFilteredBanner']}
onChange={onChange}
label={
<FormattedMessage id='notification_requests.minimize_banner' defaultMessage='Minimize filtred notifications banner' />
<FormattedMessage id='notification_requests.minimize_banner' defaultMessage='Minimize filtered notifications banner' />
}
/>
</div>
Expand Down
13 changes: 13 additions & 0 deletions app/javascript/flavours/glitch/reducers/notification_requests.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';

import { blockAccountSuccess, muteAccountSuccess } from 'flavours/glitch/actions/accounts';
import {
NOTIFICATION_REQUESTS_EXPAND_REQUEST,
NOTIFICATION_REQUESTS_EXPAND_SUCCESS,
Expand Down Expand Up @@ -51,6 +52,14 @@ const removeRequest = (state, id) => {
return state.update('items', list => list.filterNot(item => item.get('id') === id));
};

const removeRequestByAccount = (state, account_id) => {
if (state.getIn(['current', 'item', 'account']) === account_id) {
state = state.setIn(['current', 'removed'], true);
}

return state.update('items', list => list.filterNot(item => item.get('account') === account_id));
};

export const notificationRequestsReducer = (state = initialState, action) => {
switch(action.type) {
case NOTIFICATION_REQUESTS_FETCH_SUCCESS:
Expand All @@ -74,6 +83,10 @@ export const notificationRequestsReducer = (state = initialState, action) => {
case NOTIFICATION_REQUEST_ACCEPT_REQUEST:
case NOTIFICATION_REQUEST_DISMISS_REQUEST:
return removeRequest(state, action.id);
case blockAccountSuccess.type:
return removeRequestByAccount(state, action.payload.relationship.id);
case muteAccountSuccess.type:
return action.payload.relationship.muting_notifications ? removeRequestByAccount(state, action.payload.relationship.id) : state;
case NOTIFICATION_REQUEST_FETCH_REQUEST:
return state.set('current', initialState.get('current').set('isLoading', true));
case NOTIFICATION_REQUEST_FETCH_SUCCESS:
Expand Down
30 changes: 10 additions & 20 deletions app/javascript/flavours/glitch/store/typed_functions.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import type { GetThunkAPI } from '@reduxjs/toolkit';
import { createAsyncThunk } from '@reduxjs/toolkit';
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
import { useDispatch, useSelector } from 'react-redux';

import type { BaseThunkAPI } from '@reduxjs/toolkit/dist/createAsyncThunk';

import type { AppDispatch, RootState } from './store';

export const useAppDispatch = useDispatch.withTypes<AppDispatch>();
Expand All @@ -25,29 +24,20 @@ export const createAppAsyncThunk = createAsyncThunk.withTypes<{
rejectValue: AsyncThunkRejectValue;
}>();

type AppThunkApi = Pick<
BaseThunkAPI<
RootState,
unknown,
AppDispatch,
AsyncThunkRejectValue,
AppMeta,
AppMeta
>,
'getState' | 'dispatch'
>;

interface AppThunkOptions {
skipLoading?: boolean;
}

const createBaseAsyncThunk = createAsyncThunk.withTypes<{
interface AppThunkConfig {
state: RootState;
dispatch: AppDispatch;
rejectValue: AsyncThunkRejectValue;
fulfilledMeta: AppMeta;
rejectedMeta: AppMeta;
}>();
}
type AppThunkApi = Pick<GetThunkAPI<AppThunkConfig>, 'getState' | 'dispatch'>;

interface AppThunkOptions {
skipLoading?: boolean;
}

const createBaseAsyncThunk = createAsyncThunk.withTypes<AppThunkConfig>();

export function createThunk<Arg = void, Returned = void>(
name: string,
Expand Down
Loading

0 comments on commit 241d760

Please sign in to comment.