From b8b1d3a9344c768b96d9eab53f366eb0c1e11f9a Mon Sep 17 00:00:00 2001 From: Echo Date: Tue, 17 Feb 2026 16:45:24 +0100 Subject: [PATCH] [Glitch] Profile editing: Add initial route Port 4b1f66418b0173dd5edcfe9153e00dfe2e4ab948 to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/components/column.tsx | 12 ++++- .../glitch/components/column_header.tsx | 9 ++-- .../glitch/components/follow_button.tsx | 18 +++++-- .../glitch/features/account_edit/index.tsx | 53 +++++++++++++++++++ .../features/account_edit/styles.module.scss | 26 +++++++++ .../flavours/glitch/features/ui/index.jsx | 5 +- .../features/ui/util/async-components.js | 5 ++ .../flavours/glitch/hooks/useAccountId.ts | 4 ++ .../flavours/glitch/utils/environment.ts | 2 +- 9 files changed, 124 insertions(+), 10 deletions(-) create mode 100644 app/javascript/flavours/glitch/features/account_edit/index.tsx create mode 100644 app/javascript/flavours/glitch/features/account_edit/styles.module.scss diff --git a/app/javascript/flavours/glitch/components/column.tsx b/app/javascript/flavours/glitch/components/column.tsx index 0830b89f8e..804d83ede0 100644 --- a/app/javascript/flavours/glitch/components/column.tsx +++ b/app/javascript/flavours/glitch/components/column.tsx @@ -1,6 +1,8 @@ import { forwardRef, useRef, useImperativeHandle } from 'react'; import type { Ref } from 'react'; +import classNames from 'classnames'; + import { scrollTop } from 'flavours/glitch/scroll'; export interface ColumnRef { @@ -12,10 +14,11 @@ interface ColumnProps { children?: React.ReactNode; label?: string; bindToDocument?: boolean; + className?: string; } export const Column = forwardRef( - ({ children, label, bindToDocument }, ref: Ref) => { + ({ children, label, bindToDocument, className }, ref: Ref) => { const nodeRef = useRef(null); useImperativeHandle(ref, () => ({ @@ -39,7 +42,12 @@ export const Column = forwardRef( })); return ( -
+
{children}
); diff --git a/app/javascript/flavours/glitch/components/column_header.tsx b/app/javascript/flavours/glitch/components/column_header.tsx index aa6ab61f75..05a52b4012 100644 --- a/app/javascript/flavours/glitch/components/column_header.tsx +++ b/app/javascript/flavours/glitch/components/column_header.tsx @@ -73,6 +73,7 @@ export interface Props { iconComponent?: IconProp; active?: boolean; children?: React.ReactNode; + className?: string; pinned?: boolean; multiColumn?: boolean; extraButton?: React.ReactNode; @@ -91,6 +92,7 @@ export const ColumnHeader: React.FC = ({ iconComponent, active, children, + className, pinned, multiColumn, extraButton, @@ -141,7 +143,7 @@ export const ColumnHeader: React.FC = ({ onPin?.(); }, [history, pinned, onPin]); - const wrapperClassName = classNames('column-header__wrapper', { + const wrapperClassName = classNames('column-header__wrapper', className, { active, }); @@ -256,7 +258,8 @@ export const ColumnHeader: React.FC = ({ } const hasIcon = icon && iconComponent; - const hasTitle = hasIcon && title; + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + const hasTitle = (hasIcon || backButton) && title; const component = (
@@ -270,7 +273,7 @@ export const ColumnHeader: React.FC = ({ className='column-header__title' type='button' > - {!backButton && ( + {!backButton && hasIcon && ( + {label} + + ); + } + return ( {label} diff --git a/app/javascript/flavours/glitch/features/account_edit/index.tsx b/app/javascript/flavours/glitch/features/account_edit/index.tsx new file mode 100644 index 0000000000..f8a71aae66 --- /dev/null +++ b/app/javascript/flavours/glitch/features/account_edit/index.tsx @@ -0,0 +1,53 @@ +import type { FC } from 'react'; + +import { FormattedMessage, useIntl } from 'react-intl'; + +import { Link } from 'react-router-dom'; + +import { Column } from '@/flavours/glitch/components/column'; +import { ColumnHeader } from '@/flavours/glitch/components/column_header'; +import { LoadingIndicator } from '@/flavours/glitch/components/loading_indicator'; +import BundleColumnError from '@/flavours/glitch/features/ui/components/bundle_column_error'; +import { useAccount } from '@/flavours/glitch/hooks/useAccount'; +import { useCurrentAccountId } from '@/flavours/glitch/hooks/useAccountId'; + +import classes from './styles.module.scss'; + +export const AccountEdit: FC<{ multiColumn: boolean }> = ({ multiColumn }) => { + const accountId = useCurrentAccountId(); + const account = useAccount(accountId); + const intl = useIntl(); + + if (!accountId) { + return ; + } + + if (!account) { + return ( + + + + ); + } + + return ( + + + + + } + /> + + ); +}; diff --git a/app/javascript/flavours/glitch/features/account_edit/styles.module.scss b/app/javascript/flavours/glitch/features/account_edit/styles.module.scss new file mode 100644 index 0000000000..3662b51443 --- /dev/null +++ b/app/javascript/flavours/glitch/features/account_edit/styles.module.scss @@ -0,0 +1,26 @@ +.column { + border: 1px solid var(--color-border-primary); + border-top-width: 0; +} + +.header { + :global(.column-header__buttons) { + align-items: center; + padding-inline-end: 16px; + height: auto; + } +} + +.nav { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + padding: 24px 24px 12px; + + > h1 { + flex-grow: 1; + font-weight: 600; + font-size: 15px; + } +} diff --git a/app/javascript/flavours/glitch/features/ui/index.jsx b/app/javascript/flavours/glitch/features/ui/index.jsx index d692359300..3e38f99c08 100644 --- a/app/javascript/flavours/glitch/features/ui/index.jsx +++ b/app/javascript/flavours/glitch/features/ui/index.jsx @@ -25,7 +25,7 @@ import { layoutFromWindow } from 'flavours/glitch/is_mobile'; import { selectUnreadNotificationGroupsCount } from 'flavours/glitch/selectors/notifications'; import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router'; import { checkAnnualReport } from '@/flavours/glitch/reducers/slices/annual_report'; -import { isServerFeatureEnabled } from '@/flavours/glitch/utils/environment'; +import { isClientFeatureEnabled, isServerFeatureEnabled } from '@/flavours/glitch/utils/environment'; import { uploadCompose, resetCompose, changeComposeSpoilerness } from '../../actions/compose'; import { clearHeight } from '../../actions/height_cache'; @@ -83,6 +83,7 @@ import { TermsOfService, AccountFeatured, AccountAbout, + AccountEdit, Quotes, } from './util/async-components'; import { ColumnsContextProvider } from './util/columns_context'; @@ -240,6 +241,8 @@ class SwitchingColumnsArea extends PureComponent { + {isClientFeatureEnabled('profile_editing') && } + diff --git a/app/javascript/flavours/glitch/features/ui/util/async-components.js b/app/javascript/flavours/glitch/features/ui/util/async-components.js index db5cdf9f2a..20f70b447b 100644 --- a/app/javascript/flavours/glitch/features/ui/util/async-components.js +++ b/app/javascript/flavours/glitch/features/ui/util/async-components.js @@ -92,6 +92,11 @@ export function AccountAbout() { .then((module) => ({ default: module.AccountAbout })); } +export function AccountEdit() { + return import('../../account_edit') + .then((module) => ({ default: module.AccountEdit })); +} + export function Followers () { return import('../../followers'); } diff --git a/app/javascript/flavours/glitch/hooks/useAccountId.ts b/app/javascript/flavours/glitch/hooks/useAccountId.ts index 91f0b27000..ae1d7b5be2 100644 --- a/app/javascript/flavours/glitch/hooks/useAccountId.ts +++ b/app/javascript/flavours/glitch/hooks/useAccountId.ts @@ -55,3 +55,7 @@ export function useAccountId() { return accountId satisfies AccountId; } + +export function useCurrentAccountId() { + return useAppSelector((state) => state.meta.get('me', null) as string | null); +} diff --git a/app/javascript/flavours/glitch/utils/environment.ts b/app/javascript/flavours/glitch/utils/environment.ts index 5f736fa80c..58421817ad 100644 --- a/app/javascript/flavours/glitch/utils/environment.ts +++ b/app/javascript/flavours/glitch/utils/environment.ts @@ -18,7 +18,7 @@ export function isServerFeatureEnabled(feature: ServerFeatures) { return initialState?.features.includes(feature) ?? false; } -type ClientFeatures = 'collections'; +type ClientFeatures = 'collections' | 'profile_editing'; export function isClientFeatureEnabled(feature: ClientFeatures) { try {