Merge remote-tracking branch 'soapbox/develop' into cleanup

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
environments/review-cleanup-4am6ej/deployments/2092
marcin mikołajczak 2023-01-03 21:09:43 +01:00
commit 08a47bed5d
12 zmienionych plików z 644 dodań i 537 usunięć

Wyświetl plik

@ -146,9 +146,9 @@ pages:
docker:
stage: deploy
image: docker:20.10.17
image: docker:20.10.22
services:
- docker:20.10.17-dind
- docker:20.10.22-dind
tags:
- dind
# https://medium.com/devops-with-valentine/how-to-build-a-docker-image-and-push-it-to-the-gitlab-container-registry-from-a-gitlab-ci-pipeline-acac0d1f26df

Wyświetl plik

@ -1 +1 @@
nodejs 18.2.0
nodejs 18.12.1

Wyświetl plik

@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Compatibility: rudimentary support for Takahē.
- UI: added backdrop blur behind modals.
- Admin: let admins configure media preview for attachment thumbnails.
### Changed
- Posts: letterbox images to 19:6 again.

Wyświetl plik

@ -5,7 +5,7 @@ import Blurhash from 'soapbox/components/blurhash';
import Icon from 'soapbox/components/icon';
import StillImage from 'soapbox/components/still-image';
import { MIMETYPE_ICONS } from 'soapbox/components/upload';
import { useSettings } from 'soapbox/hooks';
import { useSettings, useSoapboxConfig } from 'soapbox/hooks';
import { Attachment } from 'soapbox/types/entities';
import { truncateFilename } from 'soapbox/utils/media';
@ -72,6 +72,7 @@ const Item: React.FC<IItem> = ({
}) => {
const settings = useSettings();
const autoPlayGif = settings.get('autoPlayGif') === true;
const { mediaPreview } = useSoapboxConfig();
const handleMouseEnter: React.MouseEventHandler<HTMLVideoElement> = ({ currentTarget: video }) => {
if (hoverToPlay()) {
@ -171,7 +172,7 @@ const Item: React.FC<IItem> = ({
>
<StillImage
className='w-full h-full'
src={attachment.url}
src={mediaPreview ? attachment.preview_url : attachment.url}
alt={attachment.description}
letterboxed={letterboxed}
showExt

Wyświetl plik

@ -1,5 +1,5 @@
import classNames from 'clsx';
import React, { useEffect, useMemo, useState } from 'react';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import { FormattedMessage } from 'react-intl';
import { replaceHomeTimeline } from 'soapbox/actions/timelines';
@ -11,7 +11,7 @@ import PlaceholderAvatar from '../placeholder/components/placeholder-avatar';
const CarouselItem = React.forwardRef((
{ avatar, seen, onViewed, onPinned }: { avatar: Avatar, seen: boolean, onViewed: (account_id: string) => void, onPinned?: (avatar: null | Avatar) => void },
ref: any,
ref: React.ForwardedRef<HTMLDivElement>,
) => {
const dispatch = useAppDispatch();
@ -40,8 +40,11 @@ const CarouselItem = React.forwardRef((
onPinned(avatar);
}
onViewed(avatar.account_id);
markAsSeen.mutate(avatar.account_id);
if (!seen) {
onViewed(avatar.account_id);
markAsSeen.mutate(avatar.account_id);
}
dispatch(replaceHomeTimeline(avatar.account_id, { maxId: null }, () => setLoading(false)));
}
};
@ -51,7 +54,7 @@ const CarouselItem = React.forwardRef((
ref={ref}
aria-disabled={isFetching}
onClick={handleClick}
className='cursor-pointer snap-start py-4'
className='cursor-pointer py-4'
role='filter-feed-by-user'
data-testid='carousel-item'
>
@ -87,6 +90,7 @@ const FeedCarousel = () => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [_ref, setContainerRef, { width }] = useDimensions();
const carouselItemRef = useRef<HTMLDivElement>(null);
const [seenAccountIds, setSeenAccountIds] = useState<string[]>([]);
const [pageSize, setPageSize] = useState<number>(0);
@ -151,18 +155,18 @@ const FeedCarousel = () => {
data-testid='feed-carousel'
>
<HStack alignItems='stretch'>
<div className='z-10 rounded-l-xl bg-white dark:bg-gray-900 w-8 flex self-stretch items-center justify-center'>
<div className='z-10 rounded-l-xl bg-white dark:bg-primary-900 w-8 flex self-stretch items-center justify-center'>
<button
data-testid='prev-page'
onClick={handlePrevPage}
className='h-7 w-7 flex items-center justify-center disabled:opacity-25 transition-opacity duration-500'
className='w-7 flex items-center justify-center disabled:opacity-25 transition-opacity duration-500'
disabled={!hasPrevPage}
>
<Icon src={require('@tabler/icons/chevron-left.svg')} className='text-black dark:text-white h-5 w-5' />
</button>
</div>
<div className='overflow-hidden relative'>
<div className='overflow-hidden relative w-full'>
{pinnedAvatar ? (
<div
className='z-10 flex items-center justify-center absolute left-0 top-0 bottom-0 bg-white dark:bg-primary-900'
@ -175,6 +179,7 @@ const FeedCarousel = () => {
seen={seenAccountIds?.includes(pinnedAvatar.account_id)}
onViewed={markAsSeen}
onPinned={(avatar) => setPinnedAvatar(avatar)}
ref={carouselItemRef}
/>
</div>
) : null}
@ -203,7 +208,11 @@ const FeedCarousel = () => {
}}
>
{avatar === null ? (
<Stack className='w-14 snap-start py-4 h-auto' space={3}>
<Stack
className='w-14 py-4 h-auto'
space={3}
style={{ height: carouselItemRef.current?.clientHeight }}
>
<div className='block mx-auto relative w-16 h-16 rounded-full'>
<div className='w-16 h-16' />
</div>
@ -227,11 +236,11 @@ const FeedCarousel = () => {
</HStack>
</div>
<div className='z-10 rounded-r-xl bg-white dark:bg-gray-900 w-8 self-stretch flex items-center justify-center'>
<div className='z-10 rounded-r-xl bg-white dark:bg-primary-900 w-8 self-stretch flex items-center justify-center'>
<button
data-testid='next-page'
onClick={handleNextPage}
className='h-7 w-7 flex items-center justify-center disabled:opacity-25 transition-opacity duration-500'
className='w-7 flex items-center justify-center disabled:opacity-25 transition-opacity duration-500'
disabled={!hasNextPage}
>
<Icon src={require('@tabler/icons/chevron-right.svg')} className='text-black dark:text-white h-5 w-5' />

Wyświetl plik

@ -50,6 +50,8 @@ const messages = defineMessages({
singleUserModeHint: { id: 'soapbox_config.single_user_mode_hint', defaultMessage: 'Front page will redirect to a given user profile.' },
singleUserModeProfileLabel: { id: 'soapbox_config.single_user_mode_profile_label', defaultMessage: 'Main user handle' },
singleUserModeProfileHint: { id: 'soapbox_config.single_user_mode_profile_hint', defaultMessage: '@handle' },
mediaPreviewLabel: { id: 'soapbox_config.media_preview_label', defaultMessage: 'Prefer preview media for thumbnails' },
mediaPreviewHint: { id: 'soapbox_config.media_preview_hint', defaultMessage: 'Some backends provide an optimized version of media for display in timelines. However, these preview images may be too small without additional configuration.' },
feedInjectionLabel: { id: 'soapbox_config.feed_injection_label', defaultMessage: 'Feed injection' },
feedInjectionHint: { id: 'soapbox_config.feed_injection_hint', defaultMessage: 'Inject the feed with additional content, such as suggested profiles.' },
tileServerLabel: { id: 'soapbox_config.tile_server_label', defaultMessage: 'Map tile server' },
@ -250,6 +252,16 @@ const SoapboxConfig: React.FC = () => {
/>
</ListItem>
<ListItem
label={intl.formatMessage(messages.mediaPreviewLabel)}
hint={intl.formatMessage(messages.mediaPreviewHint)}
>
<Toggle
checked={soapbox.mediaPreview === true}
onChange={handleChange(['mediaPreview'], (e) => e.target.checked)}
/>
</ListItem>
<ListItem label={intl.formatMessage(messages.displayCtaLabel)}>
<Toggle
checked={soapbox.displayCta === true}

Wyświetl plik

@ -1191,6 +1191,8 @@
"soapbox_config.hints.promo_panel_icons.link": "Soapbox Icons List",
"soapbox_config.home_footer.meta_fields.label_placeholder": "Label",
"soapbox_config.home_footer.meta_fields.url_placeholder": "URL",
"soapbox_config.media_preview_hint": "Some backends provide an optimized version of media for display in timelines. However, these preview images may be too small without additional configuration.",
"soapbox_config.media_preview_label": "Prefer preview media for thumbnails",
"soapbox_config.promo_panel.meta_fields.icon_placeholder": "Icon",
"soapbox_config.promo_panel.meta_fields.label_placeholder": "Label",
"soapbox_config.promo_panel.meta_fields.url_placeholder": "URL",

Wyświetl plik

@ -115,6 +115,11 @@ export const SoapboxConfigRecord = ImmutableRecord({
feedInjection: true,
tileServer: '',
tileServerAttribution: '',
/**
* Whether to use the preview URL for media thumbnails.
* On some platforms this can be too blurry without additional configuration.
*/
mediaPreview: false,
}, 'SoapboxConfig');
type SoapboxConfigMap = ImmutableMap<string, any>;

Wyświetl plik

@ -52,7 +52,7 @@
"@fontsource/inter": "^4.5.1",
"@fontsource/roboto": "^4.5.0",
"@gamestdio/websocket": "^0.3.2",
"@jest/globals": "^28.1.2",
"@jest/globals": "^29.0.0",
"@lcdp/offline-plugin": "^5.1.0",
"@metamask/providers": "^9.0.0",
"@popperjs/core": "^2.11.5",
@ -75,7 +75,7 @@
"@testing-library/react": "^12.1.4",
"@types/escape-html": "^1.0.1",
"@types/http-link-header": "^1.0.3",
"@types/jest": "^28.1.4",
"@types/jest": "^29.0.0",
"@types/leaflet": "^1.8.0",
"@types/lodash": "^4.14.180",
"@types/object-assign": "^4.0.30",
@ -209,13 +209,14 @@
},
"devDependencies": {
"@jedmao/redux-mock-store": "^3.0.5",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.10",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react-hooks": "^8.0.1",
"@testing-library/user-event": "^14.0.3",
"@typescript-eslint/eslint-plugin": "^5.15.0",
"@typescript-eslint/parser": "^5.15.0",
"babel-eslint": "^10.1.0",
"babel-jest": "^28.1.2",
"babel-jest": "^29.0.0",
"cross-env": "^7.0.3",
"danger": "^11.0.7",
"eslint": "^7.0.0",
@ -228,17 +229,18 @@
"eslint-plugin-react-hooks": "^4.2.0",
"fake-indexeddb": "^4.0.0",
"husky": "^7.0.2",
"jest": "^28.1.2",
"jest-environment-jsdom": "^28.1.2",
"jest": "^29.0.0",
"jest-environment-jsdom": "^29.0.0",
"jest-junit": "^15.0.0",
"lint-staged": ">=10",
"raf": "^3.4.1",
"react-intl-translations-manager": "^5.0.3",
"react-refresh": "^0.14.0",
"stylelint": "^13.7.2",
"stylelint-config-standard": "^22.0.0",
"stylelint-scss": "^3.18.0",
"tailwindcss": "^3.2.1",
"ts-jest": "^28.0.5",
"ts-jest": "^29.0.0",
"webpack-dev-server": "^4.9.1",
"yargs": "^17.6.2"
},

Wyświetl plik

@ -3,6 +3,7 @@ console.log('Running in development mode'); // eslint-disable-line no-console
import { join } from 'path';
import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin';
import { merge } from 'webpack-merge';
import sharedConfig from './shared';
@ -78,7 +79,7 @@ const devServer: DevServerConfiguration = {
host: devServerUrl.hostname,
port: devServerUrl.port,
https: devServerUrl.protocol === 'https:',
hot: false,
hot: true,
allowedHosts: 'all',
historyApiFallback: {
disableDotRule: true,
@ -116,6 +117,10 @@ const configuration: Configuration = {
watchOptions,
),
plugins: [
new ReactRefreshWebpackPlugin(),
],
devServer,
};

Wyświetl plik

@ -4,6 +4,8 @@ import { env, settings } from '../configuration';
import type { RuleSetRule } from 'webpack';
const isDevelopment = process.env.NODE_ENV === 'development';
const rule: RuleSetRule = {
test: /\.(js|jsx|mjs|ts|tsx)$/,
include: [
@ -25,6 +27,7 @@ const rule: RuleSetRule = {
cacheDirectory: join(settings.cache_path, 'babel-loader'),
cacheCompression: env.NODE_ENV === 'production',
compact: env.NODE_ENV === 'production',
plugins: isDevelopment ? ['react-refresh/babel'] : [],
},
},
],

1095
yarn.lock

Plik diff jest za duży Load Diff