mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-11-04 22:40:29 +03:00
Fix profile field comparison
This commit is contained in:
parent
79b37e177b
commit
cfee62ffe6
2 changed files with 54 additions and 29 deletions
|
|
@ -60,7 +60,7 @@ function IdentityProviderSettings({ authMetadata }: { authMetadata: ValidatedAut
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Text size="T200">Change profile settings in your homeserver's account dashboard.</Text>
|
<Text size="T200">Change profile settings in your homeserver's account dashboard.</Text>
|
||||||
</SettingTile>
|
</SettingTile>
|
||||||
</CutoutCard>
|
</CutoutCard>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,43 @@
|
||||||
import React, { FunctionComponent, ReactNode, useCallback, useEffect, useMemo, useState } from 'react';
|
import React, {
|
||||||
|
FunctionComponent,
|
||||||
|
ReactNode,
|
||||||
|
useCallback,
|
||||||
|
useEffect,
|
||||||
|
useMemo,
|
||||||
|
useState,
|
||||||
|
} from 'react';
|
||||||
import { ExtendedProfile } from '../../../../hooks/useExtendedProfile';
|
import { ExtendedProfile } from '../../../../hooks/useExtendedProfile';
|
||||||
|
|
||||||
type ExtendedProfileKeys = keyof {
|
type ExtendedProfileKeys = keyof {
|
||||||
[Property in keyof ExtendedProfile as string extends Property ? never : Property]: ExtendedProfile[Property]
|
[Property in keyof ExtendedProfile as string extends Property
|
||||||
}
|
? never
|
||||||
|
: Property]: ExtendedProfile[Property];
|
||||||
|
};
|
||||||
|
|
||||||
type ProfileFieldElementRawProps<V, C> = {
|
type ProfileFieldElementRawProps<V, C> = {
|
||||||
defaultValue: V,
|
defaultValue: V;
|
||||||
value: V,
|
value: V;
|
||||||
setValue: (value: V) => void,
|
setValue: (value: V) => void;
|
||||||
} & C
|
} & C;
|
||||||
|
|
||||||
export type ProfileFieldElementProps<K extends ExtendedProfileKeys, C> = ProfileFieldElementRawProps<ExtendedProfile[K], C>;
|
export type ProfileFieldElementProps<
|
||||||
|
K extends ExtendedProfileKeys,
|
||||||
|
C
|
||||||
|
> = ProfileFieldElementRawProps<ExtendedProfile[K], C>;
|
||||||
|
|
||||||
type ProfileFieldElements<C> = {
|
type ProfileFieldElements<C> = {
|
||||||
[Property in ExtendedProfileKeys]?: FunctionComponent<ProfileFieldElementProps<Property, C>>;
|
[Property in ExtendedProfileKeys]?: FunctionComponent<ProfileFieldElementProps<Property, C>>;
|
||||||
}
|
};
|
||||||
|
|
||||||
type ProfileFieldContextProps<C> = {
|
type ProfileFieldContextProps<C> = {
|
||||||
fieldDefaults: ExtendedProfile;
|
fieldDefaults: ExtendedProfile;
|
||||||
fieldElements: ProfileFieldElements<C>;
|
fieldElements: ProfileFieldElements<C>;
|
||||||
children: (reset: () => void, hasChanges: boolean, fields: ExtendedProfile, fieldElements: ReactNode) => ReactNode;
|
children: (
|
||||||
|
reset: () => void,
|
||||||
|
hasChanges: boolean,
|
||||||
|
fields: ExtendedProfile,
|
||||||
|
fieldElements: ReactNode
|
||||||
|
) => ReactNode;
|
||||||
context: C;
|
context: C;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -28,7 +45,7 @@ export function ProfileFieldContext<C>({
|
||||||
fieldDefaults,
|
fieldDefaults,
|
||||||
fieldElements: fieldElementConstructors,
|
fieldElements: fieldElementConstructors,
|
||||||
children,
|
children,
|
||||||
context
|
context,
|
||||||
}: ProfileFieldContextProps<C>): ReactNode {
|
}: ProfileFieldContextProps<C>): ReactNode {
|
||||||
const [fields, setFields] = useState<ExtendedProfile>(fieldDefaults);
|
const [fields, setFields] = useState<ExtendedProfile>(fieldDefaults);
|
||||||
|
|
||||||
|
|
@ -37,7 +54,7 @@ export function ProfileFieldContext<C>({
|
||||||
}, [fieldDefaults]);
|
}, [fieldDefaults]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
reset()
|
reset();
|
||||||
}, [reset]);
|
}, [reset]);
|
||||||
|
|
||||||
const setField = useCallback(
|
const setField = useCallback(
|
||||||
|
|
@ -51,23 +68,31 @@ export function ProfileFieldContext<C>({
|
||||||
);
|
);
|
||||||
|
|
||||||
const hasChanges = useMemo(
|
const hasChanges = useMemo(
|
||||||
() => Object.entries(fields).find(([key, value]) => fieldDefaults[key as keyof ExtendedProfile] !== value) !== undefined,
|
() =>
|
||||||
|
Object.entries(fields).find(
|
||||||
|
([key, value]) =>
|
||||||
|
// this is a hack but ExtendedProfile is always valid JSON anyway
|
||||||
|
JSON.stringify(fieldDefaults[key as keyof ExtendedProfile]) !== JSON.stringify(value)
|
||||||
|
) !== undefined,
|
||||||
[fields, fieldDefaults]
|
[fields, fieldDefaults]
|
||||||
);
|
);
|
||||||
|
|
||||||
const createElement = useCallback(<K extends ExtendedProfileKeys>(key: K, element: ProfileFieldElements<C>[K]) => {
|
const createElement = useCallback(
|
||||||
const props: ProfileFieldElementRawProps<ExtendedProfile[K], C> = {
|
<K extends ExtendedProfileKeys>(key: K, element: ProfileFieldElements<C>[K]) => {
|
||||||
...context,
|
const props: ProfileFieldElementRawProps<ExtendedProfile[K], C> = {
|
||||||
defaultValue: fieldDefaults[key],
|
...context,
|
||||||
value: fields[key],
|
defaultValue: fieldDefaults[key],
|
||||||
setValue: (value) => setField(key, value),
|
value: fields[key],
|
||||||
key,
|
setValue: (value) => setField(key, value),
|
||||||
};
|
key,
|
||||||
if (element !== undefined) {
|
};
|
||||||
return React.createElement(element, props);
|
if (element !== undefined) {
|
||||||
}
|
return React.createElement(element, props);
|
||||||
return undefined;
|
}
|
||||||
}, [context, fieldDefaults, fields, setField]);
|
return undefined;
|
||||||
|
},
|
||||||
|
[context, fieldDefaults, fields, setField]
|
||||||
|
);
|
||||||
|
|
||||||
const fieldElements = Object.entries(fieldElementConstructors).map(([key, element]) =>
|
const fieldElements = Object.entries(fieldElementConstructors).map(([key, element]) =>
|
||||||
// @ts-expect-error TypeScript doesn't quite understand the magic going on here
|
// @ts-expect-error TypeScript doesn't quite understand the magic going on here
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue