diff --git a/.changeset/clean_up_the_design_of_persona_settings.md b/.changeset/clean_up_the_design_of_persona_settings.md
new file mode 100644
index 000000000..49f3e9c89
--- /dev/null
+++ b/.changeset/clean_up_the_design_of_persona_settings.md
@@ -0,0 +1,5 @@
+---
+default: minor
+---
+
+# Clean up the design of Persona settings
diff --git a/src/app/features/settings/Persona/PKCompat.tsx b/src/app/features/settings/Persona/PKCompat.tsx
index 8d55eaec1..dd8fb2965 100644
--- a/src/app/features/settings/Persona/PKCompat.tsx
+++ b/src/app/features/settings/Persona/PKCompat.tsx
@@ -31,6 +31,13 @@ export function PKCompatSettings() {
/>
}
/>
+
+
void;
onDelete?: (profileId: string) => void;
};
@@ -38,7 +39,6 @@ export function PerMessageProfileEditor({
avatarMxcUrl,
displayName,
pronouns = Array(),
- onChange,
onDelete,
}: Readonly) {
const useAuthentication = useMediaAuthentication();
@@ -46,8 +46,6 @@ export function PerMessageProfileEditor({
const [currentId, setCurrentId] = useState(profileId);
const [newId, setNewId] = useState(profileId);
- console.warn(pronouns);
-
// Pronouns
const [currentPronouns, setCurrentPronouns] = useState(pronouns);
const [newPronouns, setNewPronouns] = useState(pronouns);
@@ -86,22 +84,13 @@ export function PerMessageProfileEditor({
setImageFile(undefined);
setImageHasChanges(true);
}, []);
- const handleUploaded = useCallback(
- (upload: { status: string; mxc: string }) => {
- if (upload?.status === 'success') {
- setAvatarMxc(upload.mxc);
- if (onChange)
- onChange({
- id: profileId,
- name: newDisplayName,
- avatarUrl: upload.mxc,
- });
- setImageHasChanges(true);
- }
- setImageFile(undefined);
- },
- [onChange, profileId, newDisplayName]
- );
+ const handleUploaded = useCallback((upload: { status: string; mxc: string }) => {
+ if (upload?.status === 'success') {
+ setAvatarMxc(upload.mxc);
+ setImageHasChanges(true);
+ }
+ setImageFile(undefined);
+ }, []);
const handleNameChange = useCallback((e: React.ChangeEvent) => {
setNewDisplayName(e.target.value);
}, []);
@@ -187,109 +176,62 @@ export function PerMessageProfileEditor({
return (
+ Profile
+
- {/* Profile ID heading and input */}
-
-
- Profile ID:
-
-
-
-
-
-
+
+
+ placeholder="Profile ID"
+ style={{ paddingRight: config.space.S200 }}
+ aria-label="profile id"
+ title="profile id"
+ />
+
+
+
+
+
+
(
- p
+ {nameInitials(displayName)}
)}
alt={`Avatar for profile ${profileId}`}
/>
+ }
+ >
+
- {uploadAtom && (
-
-
-
- )}
-
-
- Display Name:
-
+
+
+ )}
+
+
+
+
+
+
-
- Pronouns:
-
+
+
+
+
+
+
-
- {/* Rechte Spalte: Save Button */}
-
-
-
-
-
+ }
+ >
+
+
+
+
+
);
}
diff --git a/src/app/features/settings/Persona/PerMessageProfileEditorView.tsx b/src/app/features/settings/Persona/PerMessageProfileEditorView.tsx
new file mode 100644
index 000000000..c23bb712d
--- /dev/null
+++ b/src/app/features/settings/Persona/PerMessageProfileEditorView.tsx
@@ -0,0 +1,63 @@
+import { Box, IconButton, Text, Scroll, Chip } from 'folds';
+import { ArrowLeft, composerIcon, sizedIcon, X } from '$components/icons/phosphor';
+import { Page, PageHeader, PageContent } from '$components/page';
+import type { MatrixClient } from 'matrix-js-sdk';
+import type { PronounSet } from '$utils/pronouns';
+import { PerMessageProfileEditor } from './PerMessageProfileEditor';
+
+type PerMessageProfileEditorViewProps = {
+ mx: MatrixClient;
+ profileId: string;
+ avatarMxcUrl?: string;
+ displayName?: string;
+ pronouns?: PronounSet[];
+ onChange?: (profile: { id: string; name: string; avatarUrl?: string }) => void;
+ onDelete?: (profileId: string) => void;
+ requestClose: () => void;
+};
+export function PerMessageProfileEditorView({
+ mx,
+ profileId,
+ avatarMxcUrl,
+ displayName,
+ pronouns = Array(),
+ requestClose,
+}: Readonly) {
+ return (
+
+
+
+
+
+ Persona
+
+
+
+
+ {composerIcon(X)}
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/app/features/settings/Persona/PerMessageProfileListItem.tsx b/src/app/features/settings/Persona/PerMessageProfileListItem.tsx
new file mode 100644
index 000000000..40fa89dc6
--- /dev/null
+++ b/src/app/features/settings/Persona/PerMessageProfileListItem.tsx
@@ -0,0 +1,90 @@
+import { color, Box, Text, Avatar, Chip } from 'folds';
+import type { MatrixClient } from '$types/matrix-sdk';
+import { useCallback, useMemo } from 'react';
+import { nameInitials } from '$utils/common';
+import { mxcUrlToHttp } from '$utils/matrix';
+import { useMediaAuthentication } from '$hooks/useMediaAuthentication';
+import { UserAvatar } from '$components/user-avatar';
+import type { PronounSet } from '$utils/pronouns';
+import { SettingTile } from '$components/setting-tile';
+import { toSettingsFocusIdPart } from '../settingsLink';
+import { Pronouns } from '$features/room/message';
+
+/**
+ * the props we use for the per-message profile list item, which is used to display a per-message profile. This is used in the settings page when the user wants to view all of their profiles.
+ */
+type PerMessageProfileListItemProps = {
+ mx: MatrixClient;
+ profileId: string;
+ avatarMxcUrl?: string;
+ displayName?: string;
+ pronouns?: PronounSet[];
+ onOpenEditor: (profileId: string) => void;
+};
+
+export function PerMessageProfileListItem({
+ mx,
+ profileId,
+ avatarMxcUrl,
+ displayName,
+ pronouns = Array(),
+ onOpenEditor,
+}: Readonly) {
+ const useAuthentication = useMediaAuthentication();
+
+ const avatarUrl = useMemo(() => {
+ if (avatarMxcUrl) {
+ return mxcUrlToHttp(mx, avatarMxcUrl, useAuthentication, 96, 96, 'crop') ?? undefined;
+ }
+ return undefined;
+ }, [avatarMxcUrl, mx, useAuthentication]);
+
+ const handleOpenEditor = useCallback(() => onOpenEditor(profileId), [profileId, onOpenEditor]);
+
+ return (
+
+ {displayName ?? 'Unnamed Profile'}
+
+
+ }
+ description={profileId}
+ before={
+
+ (
+
+
+ {nameInitials(displayName ?? '?')}
+
+
+ )}
+ alt={`Avatar for profile ${profileId}`}
+ />
+
+ }
+ after={
+
+ Edit
+
+ }
+ >
+ );
+}
diff --git a/src/app/features/settings/Persona/PerMessageProfileOverview.tsx b/src/app/features/settings/Persona/PerMessageProfileOverview.tsx
index 61a2ce57e..2f6dd55a1 100644
--- a/src/app/features/settings/Persona/PerMessageProfileOverview.tsx
+++ b/src/app/features/settings/Persona/PerMessageProfileOverview.tsx
@@ -3,17 +3,28 @@ import type { PerMessageProfile } from '$hooks/usePerMessageProfile';
import {
addOrUpdatePerMessageProfile,
getAllPerMessageProfiles,
+ getPerMessageProfileById,
} from '$hooks/usePerMessageProfile';
import { useEffect, useState } from 'react';
import { Box, Button, Text } from 'folds';
import { generateShortId } from '$utils/shortIdGen';
-import { PerMessageProfileEditor } from './PerMessageProfileEditor';
+import { SequenceCard } from '$components/sequence-card';
+import { SequenceCardStyle } from '../styles.css';
+import { PerMessageProfileListItem } from './PerMessageProfileListItem';
+import { SettingTile } from '$components/setting-tile';
+type PerMessageProfileOverviewProps = {
+ onCreateProfile: (profile: PerMessageProfile) => void;
+ onEditProfile: (profile: PerMessageProfile) => void;
+};
/**
* Renders a list of per-message profiles along with an editor.
* @returns rendering of per message profile list including editor
*/
-export function PerMessageProfileOverview() {
+export function PerMessageProfileOverview({
+ onCreateProfile,
+ onEditProfile,
+}: PerMessageProfileOverviewProps) {
const mx = useMatrixClient();
const [profiles, setProfiles] = useState([]);
@@ -25,40 +36,61 @@ export function PerMessageProfileOverview() {
fetchProfiles();
}, [mx]);
- // Handler to remove a profile from the list after deletion
- const handleDelete = (profileId: string) => {
- setProfiles((prevProfiles) => prevProfiles.filter((profile) => profile.id !== profileId));
+ const handleEdit = async (profileId: string) => {
+ const profile = await getPerMessageProfileById(mx, profileId);
+ if (profile) onEditProfile(profile);
};
return (
-
-
- Per-Message Profiles
-
-
+
+ Personas
+
+
+ {
+ const newProfile: PerMessageProfile = {
+ id: generateShortId(5),
+ name: 'New Profile',
+ };
+ addOrUpdatePerMessageProfile(mx, newProfile).then(() => {
+ onCreateProfile(newProfile);
+ });
+ }}
+ >
+ Add
+
+ }
+ />
+
+
{profiles.map((profile) => (
-
+ >
+
+
))}
);
diff --git a/src/app/features/settings/Persona/ProfilesPage.tsx b/src/app/features/settings/Persona/ProfilesPage.tsx
index 961d8af0b..a193138dc 100644
--- a/src/app/features/settings/Persona/ProfilesPage.tsx
+++ b/src/app/features/settings/Persona/ProfilesPage.tsx
@@ -1,9 +1,13 @@
-import { PageNavContent } from '$components/page';
-import { Box } from 'folds';
+import { PageContent } from '$components/page';
+import { Box, Scroll } from 'folds';
import { SettingsSectionPage } from '../SettingsSectionPage';
import { PerMessageProfileOverview } from './PerMessageProfileOverview';
import { PKCompatSettings } from './PKCompat';
import { PickerPageSettings } from './PickerPage';
+import type { PerMessageProfile } from '$hooks/usePerMessageProfile';
+import { useState } from 'react';
+import { useMatrixClient } from '$hooks/useMatrixClient';
+import { PerMessageProfileEditorView } from './PerMessageProfileEditorView';
type PerMessageProfilePageProps = {
requestBack?: () => void;
@@ -11,27 +15,41 @@ type PerMessageProfilePageProps = {
};
export function PerMessageProfilePage({ requestBack, requestClose }: PerMessageProfilePageProps) {
+ const mx = useMatrixClient();
+ const [editingProfile, setEditingProfile] = useState();
+
+ const handleEditorClose = () => {
+ setEditingProfile(undefined);
+ };
+
+ if (editingProfile) {
+ return (
+
+ );
+ }
return (
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
);
}