diff --git a/lib/shared/threads/protocols/dm-thread-protocol.js b/lib/shared/threads/protocols/dm-thread-protocol.js --- a/lib/shared/threads/protocols/dm-thread-protocol.js +++ b/lib/shared/threads/protocols/dm-thread-protocol.js @@ -924,6 +924,12 @@ shouldConvertIDs: false, dataIsBackedUp: true, + supportedThreadSettings: { + avatar: true, + name: true, + description: true, + color: true, + }, }); function pendingThreadType(numberOfOtherMembers: number) { diff --git a/lib/shared/threads/protocols/farcaster-thread-protocol.js b/lib/shared/threads/protocols/farcaster-thread-protocol.js --- a/lib/shared/threads/protocols/farcaster-thread-protocol.js +++ b/lib/shared/threads/protocols/farcaster-thread-protocol.js @@ -272,6 +272,14 @@ membershipMessageNotifAction: messageNotifyTypes.NONE, shouldConvertIDs: false, dataIsBackedUp: true, + + supportedThreadSettings: { + avatar: true, + name: true, + description: true, + // Farcaster threads do not support color changes + color: false, + }, }; export { farcasterThreadProtocol }; diff --git a/lib/shared/threads/protocols/keyserver-thread-protocol.js b/lib/shared/threads/protocols/keyserver-thread-protocol.js --- a/lib/shared/threads/protocols/keyserver-thread-protocol.js +++ b/lib/shared/threads/protocols/keyserver-thread-protocol.js @@ -680,6 +680,13 @@ shouldConvertIDs: true, dataIsBackedUp: false, + + supportedThreadSettings: { + avatar: true, + name: true, + description: true, + color: true, + }, }); function pendingThreadType(numberOfOtherMembers: number) { diff --git a/lib/shared/threads/thread-spec.js b/lib/shared/threads/thread-spec.js --- a/lib/shared/threads/thread-spec.js +++ b/lib/shared/threads/thread-spec.js @@ -423,6 +423,12 @@ // In practice, this means that this data storage is in tables // that are included in the backup. +dataIsBackedUp: boolean, + +supportedThreadSettings: { + +avatar: boolean, + +name: boolean, + +description: boolean, + +color: boolean, + }, }; export type ThreadSpec< diff --git a/native/chat/settings/thread-settings.react.js b/native/chat/settings/thread-settings.react.js --- a/native/chat/settings/thread-settings.react.js +++ b/native/chat/settings/thread-settings.react.js @@ -381,7 +381,13 @@ canEditThreadDescription: boolean, canEditThreadColor: boolean, ) => { - const canChangeAvatar = canEditThreadAvatar && canStartEditing; + const { supportedThreadSettings } = + threadSpecs[threadInfo.type].protocol(); + + const canChangeAvatar = + canEditThreadAvatar && + canStartEditing && + supportedThreadSettings.avatar; const canChangeName = canEditThreadName && canStartEditing; const canChangeDescription = canEditThreadDescription && canStartEditing; @@ -412,33 +418,41 @@ title: 'Basics', categoryType: 'full', }); - listData.push({ - itemType: 'name', - key: 'name', - threadInfo, - nameEditValue, - canChangeSettings: canChangeName, - }); - listData.push({ - itemType: 'color', - key: 'color', - threadInfo, - colorEditValue, - canChangeSettings: canChangeColor, - navigate, - threadSettingsRouteKey: routeKey, - }); + if (supportedThreadSettings.name) { + listData.push({ + itemType: 'name', + key: 'name', + threadInfo, + nameEditValue, + canChangeSettings: canChangeName, + }); + } + if (supportedThreadSettings.color) { + listData.push({ + itemType: 'color', + key: 'color', + threadInfo, + colorEditValue, + canChangeSettings: canChangeColor, + navigate, + threadSettingsRouteKey: routeKey, + }); + } listData.push({ itemType: 'footer', key: 'basicsFooter', categoryType: 'full', }); - if ( + const shouldShowThreadDescription = (descriptionEditValue !== null && descriptionEditValue !== undefined) || threadInfo.description || - canEditThreadDescription + canEditThreadDescription; + + if ( + shouldShowThreadDescription && + supportedThreadSettings.description ) { listData.push({ itemType: 'description', diff --git a/web/avatars/edit-thread-avatar.react.js b/web/avatars/edit-thread-avatar.react.js --- a/web/avatars/edit-thread-avatar.react.js +++ b/web/avatars/edit-thread-avatar.react.js @@ -5,6 +5,7 @@ import { EditThreadAvatarContext } from 'lib/components/base-edit-thread-avatar-provider.react.js'; import { useThreadHasPermission } from 'lib/shared/thread-utils.js'; +import { threadSpecs } from 'lib/shared/threads/thread-specs.js'; import type { ThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js'; import { threadPermissions } from 'lib/types/thread-permission-types.js'; @@ -27,9 +28,15 @@ threadInfo, threadPermissions.EDIT_THREAD_AVATAR, ); + const threadSupportAvatarEdit = + threadSpecs[threadInfo.type].protocol().supportedThreadSettings.avatar; let editThreadAvatarMenu; - if (canEditThreadAvatar && !threadAvatarSaveInProgress) { + if ( + canEditThreadAvatar && + !threadAvatarSaveInProgress && + threadSupportAvatarEdit + ) { editThreadAvatarMenu = ; } diff --git a/web/modals/threads/settings/thread-settings-general-tab.react.js b/web/modals/threads/settings/thread-settings-general-tab.react.js --- a/web/modals/threads/settings/thread-settings-general-tab.react.js +++ b/web/modals/threads/settings/thread-settings-general-tab.react.js @@ -4,6 +4,7 @@ import tinycolor from 'tinycolor2'; import { useThreadHasPermission } from 'lib/shared/thread-utils.js'; +import { threadSpecs } from 'lib/shared/threads/thread-specs.js'; import { type SetState } from 'lib/types/hook-types.js'; import type { ThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js'; import { threadPermissions } from 'lib/types/thread-permission-types.js'; @@ -87,12 +88,12 @@ const threadNameInputDisabled = !canEditThreadName; - return ( -
-
-
- -
+ const nameSection = React.useMemo(() => { + if (!threadSpecs[threadInfo.type].protocol().supportedThreadSettings.name) { + return null; + } + return ( + <>
Chat name
-
+ + ); + }, [ + onChangeName, + queuedChanges.name, + threadInfo.name, + threadInfo.type, + threadNameInputDisabled, + threadNamePlaceholder, + threadSettingsOperationInProgress, + ]); + + const descriptionSection = React.useMemo(() => { + if ( + !threadSpecs[threadInfo.type].protocol().supportedThreadSettings + .description + ) { + return null; + } + return (
Description
@@ -120,6 +140,22 @@ />
+ ); + }, [ + onChangeDescription, + queuedChanges.description, + threadInfo.description, + threadInfo.type, + threadSettingsOperationInProgress, + ]); + + const colorSection = React.useMemo(() => { + if ( + !threadSpecs[threadInfo.type].protocol().supportedThreadSettings.color + ) { + return null; + } + return (
Color
@@ -129,6 +165,19 @@ />
+ ); + }, [onChangeColor, queuedChanges.color, threadInfo.color, threadInfo.type]); + + return ( +
+
+
+ +
+ {nameSection} +
+ {descriptionSection} + {colorSection}
); }