Merge pull request #3083 from ClearlyClaire/glitch-soc/merge-upstream

Merge upstream changes up to 44d71d59ef
This commit is contained in:
Claire
2025-05-31 17:32:21 +02:00
committed by GitHub
8 changed files with 95 additions and 12 deletions

View File

@@ -36,7 +36,6 @@ Rails/OutputSafety:
Style/FetchEnvVar:
Exclude:
- 'config/initializers/2_limited_federation_mode.rb'
- 'config/initializers/3_omniauth.rb'
- 'config/initializers/paperclip.rb'
- 'lib/tasks/repo.rake'

View File

@@ -1,5 +1,12 @@
import type { ComponentPropsWithRef } from 'react';
import { useCallback, useEffect, useRef, useState } from 'react';
import {
useCallback,
useEffect,
useLayoutEffect,
useRef,
useState,
useId,
} from 'react';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
@@ -11,11 +18,14 @@ import { animated, useSpring } from '@react-spring/web';
import { useDrag } from '@use-gesture/react';
import { expandAccountFeaturedTimeline } from '@/flavours/glitch/actions/timelines';
import { Icon } from '@/flavours/glitch/components/icon';
import { IconButton } from '@/flavours/glitch/components/icon_button';
import StatusContainer from '@/flavours/glitch/containers/status_container';
import { usePrevious } from '@/flavours/glitch/hooks/usePrevious';
import { useAppDispatch, useAppSelector } from '@/flavours/glitch/store';
import ChevronLeftIcon from '@/material-icons/400-24px/chevron_left.svg?react';
import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react';
import PushPinIcon from '@/material-icons/400-24px/push_pin.svg?react';
const messages = defineMessages({
previous: { id: 'featured_carousel.previous', defaultMessage: 'Previous' },
@@ -31,6 +41,7 @@ export const FeaturedCarousel: React.FC<{
tagged?: string;
}> = ({ accountId, tagged }) => {
const intl = useIntl();
const accessibilityId = useId();
// Load pinned statuses
const dispatch = useAppDispatch();
@@ -74,6 +85,7 @@ export const FeaturedCarousel: React.FC<{
const [currentSlideHeight, setCurrentSlideHeight] = useState(
wrapperRef.current?.scrollHeight ?? 0,
);
const previousSlideHeight = usePrevious(currentSlideHeight);
const observerRef = useRef<ResizeObserver>(
new ResizeObserver(() => {
handleSlideChange(0);
@@ -82,8 +94,10 @@ export const FeaturedCarousel: React.FC<{
const wrapperStyles = useSpring({
x: `-${slideIndex * 100}%`,
height: currentSlideHeight,
// Don't animate from zero to the height of the initial slide
immediate: !previousSlideHeight,
});
useEffect(() => {
useLayoutEffect(() => {
// Update slide height when the component mounts
if (currentSlideHeight === 0) {
handleSlideChange(0);
@@ -110,11 +124,15 @@ export const FeaturedCarousel: React.FC<{
className='featured-carousel'
{...bind()}
aria-roledescription='carousel'
aria-labelledby='featured-carousel-title'
aria-labelledby={`${accessibilityId}-title`}
role='region'
>
<div className='featured-carousel__header'>
<h4 className='featured-carousel__title' id='featured-carousel-title'>
<h4
className='featured-carousel__title'
id={`${accessibilityId}-title`}
>
<Icon id='thumb-tack' icon={PushPinIcon} />
<FormattedMessage
id='featured_carousel.header'
defaultMessage='{count, plural, one {Pinned Post} other {Pinned Posts}}'

View File

@@ -0,0 +1,16 @@
import { useRef, useEffect } from 'react';
/**
* Returns the previous state of the passed in value.
* On first render, undefined is returned.
*/
export function usePrevious<T>(value: T): T | undefined {
const ref = useRef<T>();
useEffect(() => {
ref.current = value;
}, [value]);
return ref.current;
}

View File

@@ -11397,5 +11397,13 @@ noscript {
font-size: 12px;
font-weight: 500;
text-transform: uppercase;
display: flex;
align-items: center;
gap: 4px;
.icon {
width: 16px;
height: 16px;
}
}
}

View File

@@ -1,5 +1,12 @@
import type { ComponentPropsWithRef } from 'react';
import { useCallback, useEffect, useRef, useState } from 'react';
import {
useCallback,
useEffect,
useLayoutEffect,
useRef,
useState,
useId,
} from 'react';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
@@ -11,11 +18,14 @@ import { animated, useSpring } from '@react-spring/web';
import { useDrag } from '@use-gesture/react';
import { expandAccountFeaturedTimeline } from '@/mastodon/actions/timelines';
import { Icon } from '@/mastodon/components/icon';
import { IconButton } from '@/mastodon/components/icon_button';
import StatusContainer from '@/mastodon/containers/status_container';
import { usePrevious } from '@/mastodon/hooks/usePrevious';
import { useAppDispatch, useAppSelector } from '@/mastodon/store';
import ChevronLeftIcon from '@/material-icons/400-24px/chevron_left.svg?react';
import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react';
import PushPinIcon from '@/material-icons/400-24px/push_pin.svg?react';
const messages = defineMessages({
previous: { id: 'featured_carousel.previous', defaultMessage: 'Previous' },
@@ -31,6 +41,7 @@ export const FeaturedCarousel: React.FC<{
tagged?: string;
}> = ({ accountId, tagged }) => {
const intl = useIntl();
const accessibilityId = useId();
// Load pinned statuses
const dispatch = useAppDispatch();
@@ -74,6 +85,7 @@ export const FeaturedCarousel: React.FC<{
const [currentSlideHeight, setCurrentSlideHeight] = useState(
wrapperRef.current?.scrollHeight ?? 0,
);
const previousSlideHeight = usePrevious(currentSlideHeight);
const observerRef = useRef<ResizeObserver>(
new ResizeObserver(() => {
handleSlideChange(0);
@@ -82,8 +94,10 @@ export const FeaturedCarousel: React.FC<{
const wrapperStyles = useSpring({
x: `-${slideIndex * 100}%`,
height: currentSlideHeight,
// Don't animate from zero to the height of the initial slide
immediate: !previousSlideHeight,
});
useEffect(() => {
useLayoutEffect(() => {
// Update slide height when the component mounts
if (currentSlideHeight === 0) {
handleSlideChange(0);
@@ -110,11 +124,15 @@ export const FeaturedCarousel: React.FC<{
className='featured-carousel'
{...bind()}
aria-roledescription='carousel'
aria-labelledby='featured-carousel-title'
aria-labelledby={`${accessibilityId}-title`}
role='region'
>
<div className='featured-carousel__header'>
<h4 className='featured-carousel__title' id='featured-carousel-title'>
<h4
className='featured-carousel__title'
id={`${accessibilityId}-title`}
>
<Icon id='thumb-tack' icon={PushPinIcon} />
<FormattedMessage
id='featured_carousel.header'
defaultMessage='{count, plural, one {Pinned Post} other {Pinned Posts}}'

View File

@@ -0,0 +1,16 @@
import { useRef, useEffect } from 'react';
/**
* Returns the previous state of the passed in value.
* On first render, undefined is returned.
*/
export function usePrevious<T>(value: T): T | undefined {
const ref = useRef<T>();
useEffect(() => {
ref.current = value;
}, [value]);
return ref.current;
}

View File

@@ -11074,5 +11074,13 @@ noscript {
font-size: 12px;
font-weight: 500;
text-transform: uppercase;
display: flex;
align-items: center;
gap: 4px;
.icon {
width: 16px;
height: 16px;
}
}
}

View File

@@ -12,7 +12,7 @@ Devise.setup do |config|
# CAS strategy
if ENV['CAS_ENABLED'] == 'true'
cas_options = {}
cas_options[:display_name] = ENV['CAS_DISPLAY_NAME']
cas_options[:display_name] = ENV.fetch('CAS_DISPLAY_NAME', nil)
cas_options[:url] = ENV['CAS_URL'] if ENV['CAS_URL']
cas_options[:host] = ENV['CAS_HOST'] if ENV['CAS_HOST']
cas_options[:port] = ENV['CAS_PORT'] if ENV['CAS_PORT']
@@ -41,7 +41,7 @@ Devise.setup do |config|
# SAML strategy
if ENV['SAML_ENABLED'] == 'true'
saml_options = {}
saml_options[:display_name] = ENV['SAML_DISPLAY_NAME']
saml_options[:display_name] = ENV.fetch('SAML_DISPLAY_NAME', nil)
saml_options[:assertion_consumer_service_url] = ENV['SAML_ACS_URL'] if ENV['SAML_ACS_URL']
saml_options[:issuer] = ENV['SAML_ISSUER'] if ENV['SAML_ISSUER']
saml_options[:idp_sso_target_url] = ENV['SAML_IDP_SSO_TARGET_URL'] if ENV['SAML_IDP_SSO_TARGET_URL']
@@ -73,7 +73,7 @@ Devise.setup do |config|
# OpenID Connect Strategy
if ENV['OIDC_ENABLED'] == 'true'
oidc_options = {}
oidc_options[:display_name] = ENV['OIDC_DISPLAY_NAME'] # OPTIONAL
oidc_options[:display_name] = ENV.fetch('OIDC_DISPLAY_NAME', nil) # OPTIONAL
oidc_options[:issuer] = ENV['OIDC_ISSUER'] if ENV['OIDC_ISSUER'] # NEED
oidc_options[:discovery] = ENV['OIDC_DISCOVERY'] == 'true' if ENV['OIDC_DISCOVERY'] # OPTIONAL (default: false)
oidc_options[:client_auth_method] = ENV['OIDC_CLIENT_AUTH_METHOD'] if ENV['OIDC_CLIENT_AUTH_METHOD'] # OPTIONAL (default: basic)