Skip to content

Commit 9bf624b

Browse files
Merge pull request glitch-soc#2860 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 9d664f8
2 parents 437cecc + e80971e commit 9bf624b

File tree

240 files changed

+3060
-1468
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

240 files changed

+3060
-1468
lines changed

Gemfile.lock

+1-1
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ GEM
134134
bindata (2.5.0)
135135
binding_of_caller (1.0.1)
136136
debug_inspector (>= 1.2.0)
137-
blurhash (0.1.7)
137+
blurhash (0.1.8)
138138
bootsnap (1.18.4)
139139
msgpack (~> 1.2)
140140
brakeman (6.2.1)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# frozen_string_literal: true
2+
3+
class Api::V1::DomainBlocks::PreviewsController < Api::BaseController
4+
before_action -> { doorkeeper_authorize! :follow, :write, :'write:blocks' }
5+
before_action :require_user!
6+
before_action :set_domain
7+
before_action :set_domain_block_preview
8+
9+
def show
10+
render json: @domain_block_preview, serializer: REST::DomainBlockPreviewSerializer
11+
end
12+
13+
private
14+
15+
def set_domain
16+
@domain = TagManager.instance.normalize_domain(params[:domain])
17+
end
18+
19+
def set_domain_block_preview
20+
@domain_block_preview = with_read_replica do
21+
DomainBlockPreviewPresenter.new(
22+
following_count: current_account.following.where(domain: @domain).count,
23+
followers_count: current_account.followers.where(domain: @domain).count
24+
)
25+
end
26+
end
27+
end

app/helpers/settings_helper.rb

+11-10
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,17 @@ def ui_languages
1010
end
1111

1212
def featured_tags_hint(recently_used_tags)
13-
safe_join(
14-
[
15-
t('simple_form.hints.featured_tag.name'),
16-
safe_join(
17-
links_for_featured_tags(recently_used_tags),
18-
', '
19-
),
20-
],
21-
' '
22-
)
13+
recently_used_tags.present? &&
14+
safe_join(
15+
[
16+
t('simple_form.hints.featured_tag.name'),
17+
safe_join(
18+
links_for_featured_tags(recently_used_tags),
19+
', '
20+
),
21+
],
22+
' '
23+
)
2324
end
2425

2526
def session_device_icon(session)

app/javascript/flavours/glitch/api.ts

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ export async function apiRequest<ApiResponse = unknown>(
7070
args: {
7171
params?: RequestParamsOrData;
7272
data?: RequestParamsOrData;
73+
timeout?: number;
7374
} = {},
7475
) {
7576
const { data } = await api().request<ApiResponse>({
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { useState, useCallback, useRef } from 'react';
2+
3+
import { FormattedMessage } from 'react-intl';
4+
5+
import Overlay from 'react-overlays/Overlay';
6+
import type {
7+
OffsetValue,
8+
UsePopperOptions,
9+
} from 'react-overlays/esm/usePopper';
10+
11+
const offset = [0, 4] as OffsetValue;
12+
const popperConfig = { strategy: 'fixed' } as UsePopperOptions;
13+
14+
export const AltTextBadge: React.FC<{
15+
description: string;
16+
}> = ({ description }) => {
17+
const anchorRef = useRef<HTMLButtonElement>(null);
18+
const [open, setOpen] = useState(false);
19+
20+
const handleClick = useCallback(() => {
21+
setOpen((v) => !v);
22+
}, [setOpen]);
23+
24+
const handleClose = useCallback(() => {
25+
setOpen(false);
26+
}, [setOpen]);
27+
28+
return (
29+
<>
30+
<button
31+
ref={anchorRef}
32+
className='media-gallery__alt__label'
33+
onClick={handleClick}
34+
>
35+
ALT
36+
</button>
37+
38+
<Overlay
39+
rootClose
40+
onHide={handleClose}
41+
show={open}
42+
target={anchorRef.current}
43+
placement='top-end'
44+
flip
45+
offset={offset}
46+
popperConfig={popperConfig}
47+
>
48+
{({ props }) => (
49+
<div {...props} className='hover-card-controller'>
50+
<div
51+
className='media-gallery__alt__popover dropdown-animation'
52+
role='tooltip'
53+
>
54+
<h4>
55+
<FormattedMessage
56+
id='alt_text_badge.title'
57+
defaultMessage='Alt text'
58+
/>
59+
</h4>
60+
<p>{description}</p>
61+
</div>
62+
</div>
63+
)}
64+
</Overlay>
65+
</>
66+
);
67+
};

app/javascript/flavours/glitch/components/button.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ interface BaseProps
77
extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {
88
block?: boolean;
99
secondary?: boolean;
10+
dangerous?: boolean;
1011
}
1112

1213
interface PropsChildren extends PropsWithChildren<BaseProps> {
@@ -26,6 +27,7 @@ export const Button: React.FC<Props> = ({
2627
disabled,
2728
block,
2829
secondary,
30+
dangerous,
2931
className,
3032
title,
3133
text,
@@ -46,6 +48,7 @@ export const Button: React.FC<Props> = ({
4648
className={classNames('button', className, {
4749
'button-secondary': secondary,
4850
'button--block': block,
51+
'button--dangerous': dangerous,
4952
})}
5053
disabled={disabled}
5154
onClick={handleClick}

app/javascript/flavours/glitch/components/media_gallery.jsx

+12-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
1010

1111
import { debounce } from 'lodash';
1212

13+
import { AltTextBadge } from 'flavours/glitch/components/alt_text_badge';
1314
import { Blurhash } from 'flavours/glitch/components/blurhash';
15+
import { formatTime } from 'flavours/glitch/features/video';
1416

1517
import { autoPlayGif, displayMedia, useBlurhash } from '../initial_state';
1618

@@ -58,7 +60,7 @@ class Item extends PureComponent {
5860

5961
hoverToPlay () {
6062
const { attachment } = this.props;
61-
return !this.getAutoPlay() && attachment.get('type') === 'gifv';
63+
return !this.getAutoPlay() && ['gifv', 'video'].includes(attachment.get('type'));
6264
}
6365

6466
handleClick = (e) => {
@@ -97,7 +99,7 @@ class Item extends PureComponent {
9799
}
98100

99101
if (attachment.get('description')?.length > 0) {
100-
badges.push(<span key='alt' className='media-gallery__alt__label'>ALT</span>);
102+
badges.push(<AltTextBadge key='alt' description={attachment.get('description')} />);
101103
}
102104

103105
const description = attachment.getIn(['translation', 'description']) || attachment.get('description');
@@ -152,10 +154,15 @@ class Item extends PureComponent {
152154
/>
153155
</a>
154156
);
155-
} else if (attachment.get('type') === 'gifv') {
157+
} else if (['gifv', 'video'].includes(attachment.get('type'))) {
156158
const autoPlay = this.getAutoPlay();
159+
const duration = attachment.getIn(['meta', 'original', 'duration']);
157160

158-
badges.push(<span key='gif' className='media-gallery__gifv__label'>GIF</span>);
161+
if (attachment.get('type') === 'gifv') {
162+
badges.push(<span key='gif' className='media-gallery__alt__label media-gallery__alt__label--non-interactive'>GIF</span>);
163+
} else {
164+
badges.push(<span key='video' className='media-gallery__alt__label media-gallery__alt__label--non-interactive'>{formatTime(Math.floor(duration))}</span>);
165+
}
159166

160167
thumbnail = (
161168
<div className={classNames('media-gallery__gifv', { autoplay: autoPlay })}>
@@ -169,6 +176,7 @@ class Item extends PureComponent {
169176
onClick={this.handleClick}
170177
onMouseEnter={this.handleMouseEnter}
171178
onMouseLeave={this.handleMouseLeave}
179+
onLoadedData={this.handleImageLoad}
172180
autoPlay={autoPlay}
173181
playsInline
174182
loop

app/javascript/flavours/glitch/components/navigation_portal.tsx

+16-16
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,22 @@ import AccountNavigation from 'flavours/glitch/features/account/navigation';
44
import Trends from 'flavours/glitch/features/getting_started/containers/trends_container';
55
import { showTrends } from 'flavours/glitch/initial_state';
66

7-
const DefaultNavigation: React.FC = () =>
8-
showTrends ? (
9-
<>
10-
<div className='flex-spacer' />
11-
<Trends />
12-
</>
13-
) : null;
7+
const DefaultNavigation: React.FC = () => (showTrends ? <Trends /> : null);
148

159
export const NavigationPortal: React.FC = () => (
16-
<Switch>
17-
<Route path='/@:acct' exact component={AccountNavigation} />
18-
<Route path='/@:acct/tagged/:tagged?' exact component={AccountNavigation} />
19-
<Route path='/@:acct/with_replies' exact component={AccountNavigation} />
20-
<Route path='/@:acct/followers' exact component={AccountNavigation} />
21-
<Route path='/@:acct/following' exact component={AccountNavigation} />
22-
<Route path='/@:acct/media' exact component={AccountNavigation} />
23-
<Route component={DefaultNavigation} />
24-
</Switch>
10+
<div className='navigation-panel__portal'>
11+
<Switch>
12+
<Route path='/@:acct' exact component={AccountNavigation} />
13+
<Route
14+
path='/@:acct/tagged/:tagged?'
15+
exact
16+
component={AccountNavigation}
17+
/>
18+
<Route path='/@:acct/with_replies' exact component={AccountNavigation} />
19+
<Route path='/@:acct/followers' exact component={AccountNavigation} />
20+
<Route path='/@:acct/following' exact component={AccountNavigation} />
21+
<Route path='/@:acct/media' exact component={AccountNavigation} />
22+
<Route component={DefaultNavigation} />
23+
</Switch>
24+
</div>
2525
);

app/javascript/flavours/glitch/components/status.jsx

+21-21
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,27 @@ class Status extends ImmutablePureComponent {
648648
media={status.get('media_attachments')}
649649
/>,
650650
);
651+
} else if (['image', 'gifv'].includes(status.getIn(['media_attachments', 0, 'type'])) || status.get('media_attachments').size > 1) {
652+
media.push(
653+
<Bundle fetchComponent={MediaGallery} loading={this.renderLoadingMediaGallery}>
654+
{Component => (
655+
<Component
656+
media={attachments}
657+
lang={language}
658+
sensitive={status.get('sensitive')}
659+
letterbox={settings.getIn(['media', 'letterbox'])}
660+
fullwidth={!rootId && settings.getIn(['media', 'fullwidth'])}
661+
hidden={isCollapsed || !isExpanded}
662+
onOpenMedia={this.handleOpenMedia}
663+
cacheWidth={this.props.cacheMediaWidth}
664+
defaultWidth={this.props.cachedMediaWidth}
665+
visible={this.state.showMedia}
666+
onToggleVisibility={this.handleToggleMediaVisibility}
667+
/>
668+
)}
669+
</Bundle>,
670+
);
671+
mediaIcons.push('picture-o');
651672
} else if (attachments.getIn([0, 'type']) === 'audio') {
652673
const attachment = status.getIn(['media_attachments', 0]);
653674
const description = attachment.getIn(['translation', 'description']) || attachment.get('description');
@@ -703,27 +724,6 @@ class Status extends ImmutablePureComponent {
703724
</Bundle>,
704725
);
705726
mediaIcons.push('video-camera');
706-
} else { // Media type is 'image' or 'gifv'
707-
media.push(
708-
<Bundle fetchComponent={MediaGallery} loading={this.renderLoadingMediaGallery}>
709-
{Component => (
710-
<Component
711-
media={attachments}
712-
lang={language}
713-
sensitive={status.get('sensitive')}
714-
letterbox={settings.getIn(['media', 'letterbox'])}
715-
fullwidth={!rootId && settings.getIn(['media', 'fullwidth'])}
716-
hidden={isCollapsed || !isExpanded}
717-
onOpenMedia={this.handleOpenMedia}
718-
cacheWidth={this.props.cacheMediaWidth}
719-
defaultWidth={this.props.cachedMediaWidth}
720-
visible={this.state.showMedia}
721-
onToggleVisibility={this.handleToggleMediaVisibility}
722-
/>
723-
)}
724-
</Bundle>,
725-
);
726-
mediaIcons.push('picture-o');
727727
}
728728

729729
if (!status.get('sensitive') && !(status.get('spoiler_text').length > 0) && settings.getIn(['collapsed', 'backgrounds', 'preview_images'])) {

app/javascript/flavours/glitch/features/account/navigation.jsx

+1-4
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,7 @@ class AccountNavigation extends PureComponent {
4343
}
4444

4545
return (
46-
<>
47-
<div className='flex-spacer' />
48-
<FeaturedTags accountId={accountId} tagged={tagged} />
49-
</>
46+
<FeaturedTags accountId={accountId} tagged={tagged} />
5047
);
5148
}
5249

0 commit comments

Comments
 (0)