From 7efe20337cba4516983b820865156c7837e4a08a Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 30 May 2025 11:32:47 -0400 Subject: [PATCH 1/5] Fix `Style/FetchEnvVar` cop in omniauth config (#34862) --- .rubocop_todo.yml | 1 - config/initializers/3_omniauth.rb | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 62c9c5f51a..d8b1448321 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -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' diff --git a/config/initializers/3_omniauth.rb b/config/initializers/3_omniauth.rb index 0f8378ee14..607d9c15ba 100644 --- a/config/initializers/3_omniauth.rb +++ b/config/initializers/3_omniauth.rb @@ -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) From 1cc853059f68f12cddbd09ad8017c3d196d384f4 Mon Sep 17 00:00:00 2001 From: diondiondion Date: Fri, 30 May 2025 20:06:41 +0200 Subject: [PATCH 2/5] refactor(Pinned posts carousel): Don't animate initial resize (#34868) --- .../mastodon/components/featured_carousel.tsx | 14 ++++++++++++-- app/javascript/mastodon/hooks/usePrevious.ts | 16 ++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 app/javascript/mastodon/hooks/usePrevious.ts diff --git a/app/javascript/mastodon/components/featured_carousel.tsx b/app/javascript/mastodon/components/featured_carousel.tsx index efdf275fcb..f84f7865c1 100644 --- a/app/javascript/mastodon/components/featured_carousel.tsx +++ b/app/javascript/mastodon/components/featured_carousel.tsx @@ -1,5 +1,11 @@ import type { ComponentPropsWithRef } from 'react'; -import { useCallback, useEffect, useRef, useState } from 'react'; +import { + useCallback, + useEffect, + useLayoutEffect, + useRef, + useState, +} from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; @@ -13,6 +19,7 @@ import { useDrag } from '@use-gesture/react'; import { expandAccountFeaturedTimeline } from '@/mastodon/actions/timelines'; 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'; @@ -74,6 +81,7 @@ export const FeaturedCarousel: React.FC<{ const [currentSlideHeight, setCurrentSlideHeight] = useState( wrapperRef.current?.scrollHeight ?? 0, ); + const previousSlideHeight = usePrevious(currentSlideHeight); const observerRef = useRef( new ResizeObserver(() => { handleSlideChange(0); @@ -82,8 +90,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); diff --git a/app/javascript/mastodon/hooks/usePrevious.ts b/app/javascript/mastodon/hooks/usePrevious.ts new file mode 100644 index 0000000000..95f42e2ed6 --- /dev/null +++ b/app/javascript/mastodon/hooks/usePrevious.ts @@ -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(value: T): T | undefined { + const ref = useRef(); + + useEffect(() => { + ref.current = value; + }, [value]); + + return ref.current; +} From 44d71d59efd79ee723a1dec72ec77833560c45cf Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 31 May 2025 00:24:34 +0200 Subject: [PATCH 3/5] Add icon to header of pinned posts carousel in web UI (#34869) --- .../mastodon/components/featured_carousel.tsx | 12 ++++++++++-- app/javascript/styles/mastodon/components.scss | 8 ++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/app/javascript/mastodon/components/featured_carousel.tsx b/app/javascript/mastodon/components/featured_carousel.tsx index f84f7865c1..195331ef9f 100644 --- a/app/javascript/mastodon/components/featured_carousel.tsx +++ b/app/javascript/mastodon/components/featured_carousel.tsx @@ -5,6 +5,7 @@ import { useLayoutEffect, useRef, useState, + useId, } from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; @@ -17,12 +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' }, @@ -38,6 +41,7 @@ export const FeaturedCarousel: React.FC<{ tagged?: string; }> = ({ accountId, tagged }) => { const intl = useIntl(); + const accessibilityId = useId(); // Load pinned statuses const dispatch = useAppDispatch(); @@ -120,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' >
-

+ Date: Fri, 30 May 2025 20:06:41 +0200 Subject: [PATCH 4/5] [Glitch] refactor(Pinned posts carousel): Don't animate initial resize Port 1cc853059f68f12cddbd09ad8017c3d196d384f4 to glitch-soc Signed-off-by: Claire --- .../glitch/components/featured_carousel.tsx | 14 ++++++++++++-- .../flavours/glitch/hooks/usePrevious.ts | 16 ++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 app/javascript/flavours/glitch/hooks/usePrevious.ts diff --git a/app/javascript/flavours/glitch/components/featured_carousel.tsx b/app/javascript/flavours/glitch/components/featured_carousel.tsx index 9c1efb48c4..b102caf5bb 100644 --- a/app/javascript/flavours/glitch/components/featured_carousel.tsx +++ b/app/javascript/flavours/glitch/components/featured_carousel.tsx @@ -1,5 +1,11 @@ import type { ComponentPropsWithRef } from 'react'; -import { useCallback, useEffect, useRef, useState } from 'react'; +import { + useCallback, + useEffect, + useLayoutEffect, + useRef, + useState, +} from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; @@ -13,6 +19,7 @@ import { useDrag } from '@use-gesture/react'; import { expandAccountFeaturedTimeline } from '@/flavours/glitch/actions/timelines'; 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'; @@ -74,6 +81,7 @@ export const FeaturedCarousel: React.FC<{ const [currentSlideHeight, setCurrentSlideHeight] = useState( wrapperRef.current?.scrollHeight ?? 0, ); + const previousSlideHeight = usePrevious(currentSlideHeight); const observerRef = useRef( new ResizeObserver(() => { handleSlideChange(0); @@ -82,8 +90,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); diff --git a/app/javascript/flavours/glitch/hooks/usePrevious.ts b/app/javascript/flavours/glitch/hooks/usePrevious.ts new file mode 100644 index 0000000000..95f42e2ed6 --- /dev/null +++ b/app/javascript/flavours/glitch/hooks/usePrevious.ts @@ -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(value: T): T | undefined { + const ref = useRef(); + + useEffect(() => { + ref.current = value; + }, [value]); + + return ref.current; +} From 2cf44bc9144da9515675f1f5c31444c9ce62df13 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 31 May 2025 00:24:34 +0200 Subject: [PATCH 5/5] [Glitch] Add icon to header of pinned posts carousel in web UI Port 44d71d59efd79ee723a1dec72ec77833560c45cf to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/components/featured_carousel.tsx | 12 ++++++++++-- .../flavours/glitch/styles/components.scss | 8 ++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/app/javascript/flavours/glitch/components/featured_carousel.tsx b/app/javascript/flavours/glitch/components/featured_carousel.tsx index b102caf5bb..120797f7c5 100644 --- a/app/javascript/flavours/glitch/components/featured_carousel.tsx +++ b/app/javascript/flavours/glitch/components/featured_carousel.tsx @@ -5,6 +5,7 @@ import { useLayoutEffect, useRef, useState, + useId, } from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; @@ -17,12 +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' }, @@ -38,6 +41,7 @@ export const FeaturedCarousel: React.FC<{ tagged?: string; }> = ({ accountId, tagged }) => { const intl = useIntl(); + const accessibilityId = useId(); // Load pinned statuses const dispatch = useAppDispatch(); @@ -120,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' >
-

+