Update story settings modal design, add group details page
This commit is contained in:
parent
8f62442822
commit
97b7f3dbc1
7 changed files with 369 additions and 46 deletions
|
@ -5512,21 +5512,37 @@
|
||||||
"description": "Toast message"
|
"description": "Toast message"
|
||||||
},
|
},
|
||||||
"StoriesSettings__title": {
|
"StoriesSettings__title": {
|
||||||
"message": "Story settings",
|
"message": "Story privacy",
|
||||||
"description": "Title for the story settings modal"
|
"description": "Title for the story settings modal"
|
||||||
},
|
},
|
||||||
"icu:StoriesSettings__description": {
|
"icu:StoriesSettings__description": {
|
||||||
"messageformat": "Stories automatically disapper after 24 hours. Choose who can view your story or create new stories with specific viewers or groups.",
|
"messageformat": "Stories automatically disapper after 24 hours. Choose who can view your story or create new stories with specific viewers or groups.",
|
||||||
"description": "Description for story settings modal"
|
"description": "Description for story settings modal"
|
||||||
},
|
},
|
||||||
|
"icu:StoriesSettings__my_stories": {
|
||||||
|
"messageformat": "My Stories",
|
||||||
|
"description": "Title of distribution lists section in stories settings modal"
|
||||||
|
},
|
||||||
"StoriesSettings__new-list": {
|
"StoriesSettings__new-list": {
|
||||||
"message": "New custom story",
|
"message": "New Story",
|
||||||
"description": "Label to create a new custom distribution list"
|
"description": "Label to create a new custom distribution list"
|
||||||
},
|
},
|
||||||
"StoriesSettings__new-list--visibility": {
|
"StoriesSettings__new-list--visibility": {
|
||||||
"message": "Only you can see the name of this story.",
|
"message": "Only you can see the name of this story.",
|
||||||
"description": "Explanation about the visibility of custom distribution list names"
|
"description": "Explanation about the visibility of custom distribution list names"
|
||||||
},
|
},
|
||||||
|
"icu:StoriesSettings__my-story-subtitle": {
|
||||||
|
"messageformat": "All Signal connections",
|
||||||
|
"description": "Story settings modal my story distribution list selection subtitle"
|
||||||
|
},
|
||||||
|
"icu:StoriesSettings__custom-story-subtitle": {
|
||||||
|
"messageformat": "Custom story",
|
||||||
|
"description": "Story settings modal custom story distribution list selection subtitle"
|
||||||
|
},
|
||||||
|
"icu:StoriesSettings__group-story-subtitle": {
|
||||||
|
"messageformat": "Group story",
|
||||||
|
"description": "Story settings modal group story selection subtitle"
|
||||||
|
},
|
||||||
"StoriesSettings__viewers--singular": {
|
"StoriesSettings__viewers--singular": {
|
||||||
"message": "$num$ viewer",
|
"message": "$num$ viewer",
|
||||||
"description": "(deleted 2022/10/21) A single viewer"
|
"description": "(deleted 2022/10/21) A single viewer"
|
||||||
|
@ -5643,6 +5659,22 @@
|
||||||
"message": "To change this setting, open the Signal app on your mobile device and navigate to Settings -> Stories",
|
"message": "To change this setting, open the Signal app on your mobile device and navigate to Settings -> Stories",
|
||||||
"description": "Description of how view receipts can be changed in story settings"
|
"description": "Description of how view receipts can be changed in story settings"
|
||||||
},
|
},
|
||||||
|
"icu:GroupStorySettingsModal__members_title": {
|
||||||
|
"messageformat": "Who can view this story",
|
||||||
|
"description": "Stories settings > Group Story > members list title"
|
||||||
|
},
|
||||||
|
"icu:GroupStorySettingsModal__members_help": {
|
||||||
|
"messageformat": "Members of the group chat “{groupTitle}” can view and reply to this story. You can update the membership for this chat in the group.",
|
||||||
|
"description": "Stories settings > Group Story > group story help text"
|
||||||
|
},
|
||||||
|
"icu:GroupStorySettingsModal__remove_group": {
|
||||||
|
"messageformat": "Remove group story",
|
||||||
|
"descirption": "Stories settings > Group Story > button to remove group story"
|
||||||
|
},
|
||||||
|
"icu:StoriesSettings__remove_group--confirm": {
|
||||||
|
"messageformat": "Are you sure you want to remove “{groupTitle}”?",
|
||||||
|
"descirption": "Stories settings > Group Story > confirm to remove group story"
|
||||||
|
},
|
||||||
"SendStoryModal__choose-who-can-view": {
|
"SendStoryModal__choose-who-can-view": {
|
||||||
"message": "Choose who can view your story",
|
"message": "Choose who can view your story",
|
||||||
"description": "Shown during the first time posting a story"
|
"description": "Shown during the first time posting a story"
|
||||||
|
@ -5732,9 +5764,13 @@
|
||||||
"description": "Select box title for the stories on/off toggle"
|
"description": "Select box title for the stories on/off toggle"
|
||||||
},
|
},
|
||||||
"Stories__settings-toggle--description": {
|
"Stories__settings-toggle--description": {
|
||||||
"message": "You will no longer be able to share or view Stories when this option is turned off.",
|
"message": "If you opt out of stories you will no longer be able to share or view stories.",
|
||||||
"description": "Select box description for the stories on/off toggle"
|
"description": "Select box description for the stories on/off toggle"
|
||||||
},
|
},
|
||||||
|
"Stories__settings-toggle--button": {
|
||||||
|
"message": "Turn off stories",
|
||||||
|
"description": "Button to turn off stories in stories settings modal"
|
||||||
|
},
|
||||||
"StoryViewer__pause": {
|
"StoryViewer__pause": {
|
||||||
"message": "Pause",
|
"message": "Pause",
|
||||||
"description": "Aria label for pausing a story"
|
"description": "Aria label for pausing a story"
|
||||||
|
|
5
images/icons/v2/disable-outline-20.svg
Normal file
5
images/icons/v2/disable-outline-20.svg
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M10 19.375C15.1287 19.375 19.375 15.1195 19.375 10C19.375 4.87132 15.1195 0.625 9.99081 0.625C4.87132 0.625 0.625 4.87132 0.625 10C0.625 15.1195 4.88051 19.375 10 19.375ZM10 17.8125C5.66176 17.8125 2.19669 14.3382 2.19669 10C2.19669 5.66176 5.65257 2.1875 9.99081 2.1875C14.329 2.1875 17.8033 5.66176 17.8125 10C17.8217 14.3382 14.3382 17.8125 10 17.8125ZM6.38787 10.7812H13.6029C14.1176 10.7812 14.4669 10.5055 14.4669 10.0184C14.4669 9.52206 14.136 9.23713 13.6029 9.23713H6.38787C5.85478 9.23713 5.51471 9.52206 5.51471 10.0184C5.51471 10.5055 5.87316 10.7812 6.38787 10.7812Z"
|
||||||
|
fill="#F44336" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 721 B |
|
@ -2,6 +2,14 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
.StoriesSettingsModal {
|
.StoriesSettingsModal {
|
||||||
|
&__width-container {
|
||||||
|
max-width: 420px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__modal {
|
||||||
|
width: 420px;
|
||||||
|
}
|
||||||
|
|
||||||
&__conversation-list {
|
&__conversation-list {
|
||||||
.module-conversation-list {
|
.module-conversation-list {
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
|
@ -83,6 +91,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&__viewers {
|
&__viewers {
|
||||||
|
display: flex;
|
||||||
|
@include font-body-2;
|
||||||
color: $color-gray-25;
|
color: $color-gray-25;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,27 +193,6 @@
|
||||||
margin-right: 8px;
|
margin-right: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__listHeader__button {
|
|
||||||
@include button-reset;
|
|
||||||
@include button-secondary;
|
|
||||||
@include rounded-corners;
|
|
||||||
padding: 4px 10px;
|
|
||||||
@include font-family;
|
|
||||||
font-size: 12px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: '';
|
|
||||||
display: inline-block;
|
|
||||||
width: 12px;
|
|
||||||
height: 12px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
margin-right: 6px;
|
|
||||||
@include color-svg('../images/icons/v2/plus-24.svg', $color-white);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__delete-list {
|
&__delete-list {
|
||||||
@include button-reset;
|
@include button-reset;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -261,12 +250,62 @@
|
||||||
|
|
||||||
&__stories-off-container {
|
&__stories-off-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 16;
|
gap: 16px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__stories-off-text {
|
&__stories-off-text {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
font-size: 12px;
|
color: $color-gray-25;
|
||||||
|
@include font-subtitle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.GroupStorySettingsModal {
|
||||||
|
&__header {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
align-items: center;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__members_title {
|
||||||
|
@include font-body-1-bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__members_item {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&__name {
|
||||||
|
@include font-body-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__members_help {
|
||||||
|
@include font-body-2;
|
||||||
|
color: $color-gray-25;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__remove_group {
|
||||||
|
@include button-reset;
|
||||||
|
align-items: center;
|
||||||
|
color: $color-accent-red;
|
||||||
|
display: flex;
|
||||||
|
padding: 8px 0;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 12px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
@include color-svg(
|
||||||
|
'../images/icons/v2/disable-outline-20.svg',
|
||||||
|
$color-accent-red
|
||||||
|
);
|
||||||
|
content: '';
|
||||||
|
height: 20px;
|
||||||
|
margin-right: 20px;
|
||||||
|
width: 20px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ export default {
|
||||||
},
|
},
|
||||||
storyViewReceiptsEnabled: { control: 'boolean' },
|
storyViewReceiptsEnabled: { control: 'boolean' },
|
||||||
onDeleteList: { action: true },
|
onDeleteList: { action: true },
|
||||||
|
toggleGroupsForStorySend: { action: true },
|
||||||
onDistributionListCreated: { action: true },
|
onDistributionListCreated: { action: true },
|
||||||
onHideMyStoriesFrom: { action: true },
|
onHideMyStoriesFrom: { action: true },
|
||||||
onRemoveMember: { action: true },
|
onRemoveMember: { action: true },
|
||||||
|
@ -53,6 +54,9 @@ export default {
|
||||||
setMyStoriesToAllSignalConnections: { action: true },
|
setMyStoriesToAllSignalConnections: { action: true },
|
||||||
toggleSignalConnectionsModal: { action: true },
|
toggleSignalConnectionsModal: { action: true },
|
||||||
setStoriesDisabled: { action: true },
|
setStoriesDisabled: { action: true },
|
||||||
|
getConversationByUuid: {
|
||||||
|
defaultValue: () => getDefaultGroup(),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
} as Meta;
|
} as Meta;
|
||||||
|
|
||||||
|
|
|
@ -37,16 +37,19 @@ import {
|
||||||
asyncShouldNeverBeCalled,
|
asyncShouldNeverBeCalled,
|
||||||
} from '../util/shouldNeverBeCalled';
|
} from '../util/shouldNeverBeCalled';
|
||||||
import { useConfirmDiscard } from '../hooks/useConfirmDiscard';
|
import { useConfirmDiscard } from '../hooks/useConfirmDiscard';
|
||||||
|
import { getGroupMemberships } from '../util/getGroupMemberships';
|
||||||
|
|
||||||
export type PropsType = {
|
export type PropsType = {
|
||||||
candidateConversations: Array<ConversationType>;
|
candidateConversations: Array<ConversationType>;
|
||||||
distributionLists: Array<StoryDistributionListWithMembersDataType>;
|
distributionLists: Array<StoryDistributionListWithMembersDataType>;
|
||||||
|
groupStories: Array<ConversationType>;
|
||||||
signalConnections: Array<ConversationType>;
|
signalConnections: Array<ConversationType>;
|
||||||
getPreferredBadge: PreferredBadgeSelectorType;
|
getPreferredBadge: PreferredBadgeSelectorType;
|
||||||
hideStoriesSettings: () => unknown;
|
hideStoriesSettings: () => unknown;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
me: ConversationType;
|
me: ConversationType;
|
||||||
onDeleteList: (listId: string) => unknown;
|
onDeleteList: (listId: string) => unknown;
|
||||||
|
toggleGroupsForStorySend: (groupIds: Array<string>) => unknown;
|
||||||
onDistributionListCreated: (
|
onDistributionListCreated: (
|
||||||
name: string,
|
name: string,
|
||||||
viewerUuids: Array<UUIDStringType>
|
viewerUuids: Array<UUIDStringType>
|
||||||
|
@ -66,6 +69,7 @@ export type PropsType = {
|
||||||
toggleSignalConnectionsModal: () => unknown;
|
toggleSignalConnectionsModal: () => unknown;
|
||||||
toggleStoriesView: () => void;
|
toggleStoriesView: () => void;
|
||||||
setStoriesDisabled: (value: boolean) => void;
|
setStoriesDisabled: (value: boolean) => void;
|
||||||
|
getConversationByUuid: (uuid: UUIDStringType) => ConversationType | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export enum Page {
|
export enum Page {
|
||||||
|
@ -124,6 +128,7 @@ function DistributionListItem({
|
||||||
signalConnections,
|
signalConnections,
|
||||||
onSelectItemToEdit,
|
onSelectItemToEdit,
|
||||||
}: DistributionListItemProps) {
|
}: DistributionListItemProps) {
|
||||||
|
const isMyStories = distributionList.id === MY_STORIES_ID;
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
className="StoriesSettingsModal__list"
|
className="StoriesSettingsModal__list"
|
||||||
|
@ -147,7 +152,7 @@ function DistributionListItem({
|
||||||
title={me.title}
|
title={me.title}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<span className="StoriesSettingsModal__list__avatar--private" />
|
<span className="StoriesSettingsModal__list__avatar--custom" />
|
||||||
)}
|
)}
|
||||||
<span className="StoriesSettingsModal__list__title">
|
<span className="StoriesSettingsModal__list__title">
|
||||||
<StoryDistributionListName
|
<StoryDistributionListName
|
||||||
|
@ -155,10 +160,61 @@ function DistributionListItem({
|
||||||
id={distributionList.id}
|
id={distributionList.id}
|
||||||
name={distributionList.name}
|
name={distributionList.name}
|
||||||
/>
|
/>
|
||||||
|
<span className="StoriesSettingsModal__list__viewers">
|
||||||
|
{isMyStories
|
||||||
|
? i18n('icu:StoriesSettings__my-story-subtitle')
|
||||||
|
: i18n('icu:StoriesSettings__custom-story-subtitle')}
|
||||||
|
·
|
||||||
|
{getListViewers(distributionList, i18n, signalConnections)}
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span className="StoriesSettingsModal__list__viewers">
|
</button>
|
||||||
{getListViewers(distributionList, i18n, signalConnections)}
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
type GroupStoryItemProps = {
|
||||||
|
i18n: LocalizerType;
|
||||||
|
groupStory: ConversationType;
|
||||||
|
onSelectGroupToView(id: string): void;
|
||||||
|
};
|
||||||
|
|
||||||
|
function GroupStoryItem({
|
||||||
|
i18n,
|
||||||
|
groupStory,
|
||||||
|
onSelectGroupToView,
|
||||||
|
}: GroupStoryItemProps) {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
className="StoriesSettingsModal__list"
|
||||||
|
onClick={() => {
|
||||||
|
onSelectGroupToView(groupStory.id);
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span className="StoriesSettingsModal__list__left">
|
||||||
|
<Avatar
|
||||||
|
acceptedMessageRequest={groupStory.acceptedMessageRequest}
|
||||||
|
avatarPath={groupStory.avatarPath}
|
||||||
|
badge={undefined}
|
||||||
|
color={groupStory.color}
|
||||||
|
conversationType={groupStory.type}
|
||||||
|
i18n={i18n}
|
||||||
|
isMe={false}
|
||||||
|
sharedGroupNames={[]}
|
||||||
|
size={AvatarSize.THIRTY_SIX}
|
||||||
|
title={groupStory.title}
|
||||||
|
/>
|
||||||
|
<span className="StoriesSettingsModal__list__title">
|
||||||
|
{groupStory.title}
|
||||||
|
<span className="StoriesSettingsModal__list__viewers">
|
||||||
|
{i18n('icu:StoriesSettings__group-story-subtitle')}
|
||||||
|
·
|
||||||
|
{i18n('icu:StoriesSettings__viewers', {
|
||||||
|
count: groupStory.membersCount,
|
||||||
|
})}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
@ -167,12 +223,14 @@ function DistributionListItem({
|
||||||
export const StoriesSettingsModal = ({
|
export const StoriesSettingsModal = ({
|
||||||
candidateConversations,
|
candidateConversations,
|
||||||
distributionLists,
|
distributionLists,
|
||||||
|
groupStories,
|
||||||
signalConnections,
|
signalConnections,
|
||||||
getPreferredBadge,
|
getPreferredBadge,
|
||||||
hideStoriesSettings,
|
hideStoriesSettings,
|
||||||
i18n,
|
i18n,
|
||||||
me,
|
me,
|
||||||
onDeleteList,
|
onDeleteList,
|
||||||
|
toggleGroupsForStorySend,
|
||||||
onDistributionListCreated,
|
onDistributionListCreated,
|
||||||
onHideMyStoriesFrom,
|
onHideMyStoriesFrom,
|
||||||
onRemoveMember,
|
onRemoveMember,
|
||||||
|
@ -183,6 +241,7 @@ export const StoriesSettingsModal = ({
|
||||||
toggleSignalConnectionsModal,
|
toggleSignalConnectionsModal,
|
||||||
toggleStoriesView,
|
toggleStoriesView,
|
||||||
setStoriesDisabled,
|
setStoriesDisabled,
|
||||||
|
getConversationByUuid,
|
||||||
}: PropsType): JSX.Element => {
|
}: PropsType): JSX.Element => {
|
||||||
const [confirmDiscardModal, confirmDiscardIf] = useConfirmDiscard(i18n);
|
const [confirmDiscardModal, confirmDiscardIf] = useConfirmDiscard(i18n);
|
||||||
|
|
||||||
|
@ -195,6 +254,13 @@ export const StoriesSettingsModal = ({
|
||||||
[distributionLists, listToEditId]
|
[distributionLists, listToEditId]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const [groupToViewId, setGroupToViewId] = useState<string | null>(null);
|
||||||
|
const groupToView = useMemo(() => {
|
||||||
|
return groupStories.find(group => {
|
||||||
|
return group.id === groupToViewId;
|
||||||
|
});
|
||||||
|
}, [groupStories, groupToViewId]);
|
||||||
|
|
||||||
const [page, setPage] = useState<Page>(Page.DistributionLists);
|
const [page, setPage] = useState<Page>(Page.DistributionLists);
|
||||||
|
|
||||||
const [selectedContacts, setSelectedContacts] = useState<
|
const [selectedContacts, setSelectedContacts] = useState<
|
||||||
|
@ -210,6 +276,11 @@ export const StoriesSettingsModal = ({
|
||||||
{ id: string; name: string } | undefined
|
{ id: string; name: string } | undefined
|
||||||
>();
|
>();
|
||||||
|
|
||||||
|
const [confirmRemoveGroup, setConfirmRemoveGroup] = useState<{
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
} | null>(null);
|
||||||
|
|
||||||
let modal: RenderModalPage | null;
|
let modal: RenderModalPage | null;
|
||||||
|
|
||||||
if (page !== Page.DistributionLists) {
|
if (page !== Page.DistributionLists) {
|
||||||
|
@ -237,6 +308,8 @@ export const StoriesSettingsModal = ({
|
||||||
resetChooseViewersScreen();
|
resetChooseViewersScreen();
|
||||||
} else if (listToEdit) {
|
} else if (listToEdit) {
|
||||||
setListToEditId(undefined);
|
setListToEditId(undefined);
|
||||||
|
} else if (groupToView) {
|
||||||
|
setGroupToViewId(null);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -277,6 +350,22 @@ export const StoriesSettingsModal = ({
|
||||||
onClose={handleClose}
|
onClose={handleClose}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
} else if (groupToView) {
|
||||||
|
modal = onClose => (
|
||||||
|
<GroupStorySettingsModal
|
||||||
|
i18n={i18n}
|
||||||
|
group={groupToView}
|
||||||
|
onClose={onClose}
|
||||||
|
onBackButtonClick={() => setGroupToViewId(null)}
|
||||||
|
getConversationByUuid={getConversationByUuid}
|
||||||
|
onRemoveGroup={group => {
|
||||||
|
setConfirmRemoveGroup({
|
||||||
|
id: group.id,
|
||||||
|
title: group.title,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
modal = onClose => (
|
modal = onClose => (
|
||||||
<ModalPage
|
<ModalPage
|
||||||
|
@ -292,22 +381,29 @@ export const StoriesSettingsModal = ({
|
||||||
|
|
||||||
<div className="StoriesSettingsModal__listHeader">
|
<div className="StoriesSettingsModal__listHeader">
|
||||||
<h2 className="StoriesSettingsModal__listHeader__title">
|
<h2 className="StoriesSettingsModal__listHeader__title">
|
||||||
{i18n('Stories__mine')}
|
{i18n('icu:StoriesSettings__my_stories')}
|
||||||
</h2>
|
</h2>
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="StoriesSettingsModal__listHeader__button"
|
|
||||||
onClick={() => {
|
|
||||||
setPage(Page.ChooseViewers);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{i18n('StoriesSettings__new-list')}
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
className="StoriesSettingsModal__list"
|
||||||
|
onClick={() => {
|
||||||
|
setPage(Page.ChooseViewers);
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span className="StoriesSettingsModal__list__left">
|
||||||
|
<span className="StoriesSettingsModal__list__avatar--new" />
|
||||||
|
<span className="StoriesSettingsModal__list__title">
|
||||||
|
{i18n('StoriesSettings__new-list')}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
{distributionLists.map(distributionList => {
|
{distributionLists.map(distributionList => {
|
||||||
return (
|
return (
|
||||||
<DistributionListItem
|
<DistributionListItem
|
||||||
|
key={distributionList.id}
|
||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
me={me}
|
me={me}
|
||||||
distributionList={distributionList}
|
distributionList={distributionList}
|
||||||
|
@ -317,6 +413,17 @@ export const StoriesSettingsModal = ({
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
||||||
|
{groupStories.map(groupStory => {
|
||||||
|
return (
|
||||||
|
<GroupStoryItem
|
||||||
|
key={groupStory.id}
|
||||||
|
i18n={i18n}
|
||||||
|
groupStory={groupStory}
|
||||||
|
onSelectGroupToView={setGroupToViewId}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
|
||||||
<hr className="StoriesSettingsModal__divider" />
|
<hr className="StoriesSettingsModal__divider" />
|
||||||
|
|
||||||
<Checkbox
|
<Checkbox
|
||||||
|
@ -331,17 +438,18 @@ export const StoriesSettingsModal = ({
|
||||||
|
|
||||||
<div className="StoriesSettingsModal__stories-off-container">
|
<div className="StoriesSettingsModal__stories-off-container">
|
||||||
<p className="StoriesSettingsModal__stories-off-text">
|
<p className="StoriesSettingsModal__stories-off-text">
|
||||||
{i18n('Preferences__turn-stories-off--body')}
|
{i18n('Stories__settings-toggle--description')}
|
||||||
</p>
|
</p>
|
||||||
<Button
|
<Button
|
||||||
className="Preferences__stories-off"
|
className="Preferences__stories-off"
|
||||||
|
variant={ButtonVariant.SecondaryDestructive}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
setStoriesDisabled(true);
|
setStoriesDisabled(true);
|
||||||
toggleStoriesView();
|
toggleStoriesView();
|
||||||
onClose();
|
onClose();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{i18n('Preferences__turn-stories-off')}
|
{i18n('Stories__settings-toggle--button')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</ModalPage>
|
</ModalPage>
|
||||||
|
@ -353,6 +461,7 @@ export const StoriesSettingsModal = ({
|
||||||
{!confirmDiscardModal && (
|
{!confirmDiscardModal && (
|
||||||
<PagedModal
|
<PagedModal
|
||||||
modalName="StoriesSettingsModal"
|
modalName="StoriesSettingsModal"
|
||||||
|
moduleClassName="StoriesSettingsModal"
|
||||||
theme={Theme.Dark}
|
theme={Theme.Dark}
|
||||||
onClose={() =>
|
onClose={() =>
|
||||||
confirmDiscardIf(selectedContacts.length > 0, hideStoriesSettings)
|
confirmDiscardIf(selectedContacts.length > 0, hideStoriesSettings)
|
||||||
|
@ -385,6 +494,31 @@ export const StoriesSettingsModal = ({
|
||||||
])}
|
])}
|
||||||
</ConfirmationDialog>
|
</ConfirmationDialog>
|
||||||
)}
|
)}
|
||||||
|
{confirmRemoveGroup != null && (
|
||||||
|
<ConfirmationDialog
|
||||||
|
dialogName="StoriesSettings.removeGroupStory"
|
||||||
|
actions={[
|
||||||
|
{
|
||||||
|
action: () => {
|
||||||
|
toggleGroupsForStorySend([confirmRemoveGroup.id]);
|
||||||
|
setConfirmRemoveGroup(null);
|
||||||
|
setGroupToViewId(null);
|
||||||
|
},
|
||||||
|
style: 'negative',
|
||||||
|
text: i18n('delete'),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
i18n={i18n}
|
||||||
|
onClose={() => {
|
||||||
|
setConfirmRemoveGroup(null);
|
||||||
|
}}
|
||||||
|
theme={Theme.Dark}
|
||||||
|
>
|
||||||
|
{i18n('icu:StoriesSettings__remove_group--confirm', {
|
||||||
|
groupTitle: confirmRemoveGroup.title,
|
||||||
|
})}
|
||||||
|
</ConfirmationDialog>
|
||||||
|
)}
|
||||||
{confirmDiscardModal}
|
{confirmDiscardModal}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -1071,3 +1205,96 @@ export const EditDistributionListModal = ({
|
||||||
</ModalPage>
|
</ModalPage>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type GroupStorySettingsModalProps = {
|
||||||
|
i18n: LocalizerType;
|
||||||
|
group: ConversationType;
|
||||||
|
onClose(): void;
|
||||||
|
onBackButtonClick(): void;
|
||||||
|
getConversationByUuid(uuid: UUIDStringType): ConversationType | undefined;
|
||||||
|
onRemoveGroup(group: ConversationType): void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const GroupStorySettingsModal = ({
|
||||||
|
i18n,
|
||||||
|
group,
|
||||||
|
onClose,
|
||||||
|
onBackButtonClick,
|
||||||
|
getConversationByUuid,
|
||||||
|
onRemoveGroup,
|
||||||
|
}: GroupStorySettingsModalProps): JSX.Element => {
|
||||||
|
const groupMemberships = getGroupMemberships(group, getConversationByUuid);
|
||||||
|
return (
|
||||||
|
<ModalPage
|
||||||
|
modalName="GroupStorySettingsModal"
|
||||||
|
i18n={i18n}
|
||||||
|
onClose={onClose}
|
||||||
|
onBackButtonClick={onBackButtonClick}
|
||||||
|
title={group.title}
|
||||||
|
{...modalCommonProps}
|
||||||
|
>
|
||||||
|
<div className="GroupStorySettingsModal__header">
|
||||||
|
<Avatar
|
||||||
|
acceptedMessageRequest={group.acceptedMessageRequest}
|
||||||
|
avatarPath={group.avatarPath}
|
||||||
|
badge={undefined}
|
||||||
|
color={group.color}
|
||||||
|
conversationType={group.type}
|
||||||
|
i18n={i18n}
|
||||||
|
isMe={false}
|
||||||
|
sharedGroupNames={[]}
|
||||||
|
size={AvatarSize.THIRTY_SIX}
|
||||||
|
title={group.title}
|
||||||
|
/>
|
||||||
|
<span className="GroupStorySettingsModal__title">{group.title}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr className="StoriesSettingsModal__divider" />
|
||||||
|
|
||||||
|
<p className="GroupStorySettingsModal__members_title">
|
||||||
|
{i18n('icu:GroupStorySettingsModal__members_title')}
|
||||||
|
</p>
|
||||||
|
{groupMemberships.memberships.map(membership => {
|
||||||
|
const { member } = membership;
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={member.id}
|
||||||
|
className="GroupStorySettingsModal__members_item"
|
||||||
|
>
|
||||||
|
<Avatar
|
||||||
|
acceptedMessageRequest={member.acceptedMessageRequest}
|
||||||
|
avatarPath={member.avatarPath}
|
||||||
|
badge={undefined}
|
||||||
|
color={member.color}
|
||||||
|
conversationType={member.type}
|
||||||
|
i18n={i18n}
|
||||||
|
isMe={false}
|
||||||
|
sharedGroupNames={[]}
|
||||||
|
size={AvatarSize.THIRTY_SIX}
|
||||||
|
title={member.title}
|
||||||
|
/>
|
||||||
|
<p className="GroupStorySettingsModal__members_item__name">
|
||||||
|
{member.title}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
|
||||||
|
<p className="GroupStorySettingsModal__members_help">
|
||||||
|
{i18n('icu:GroupStorySettingsModal__members_help', {
|
||||||
|
groupTitle: group.title,
|
||||||
|
})}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<hr className="StoriesSettingsModal__divider" />
|
||||||
|
|
||||||
|
<button
|
||||||
|
className="GroupStorySettingsModal__remove_group"
|
||||||
|
onClick={() => onRemoveGroup(group)}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
{i18n('icu:GroupStorySettingsModal__remove_group')}
|
||||||
|
</button>
|
||||||
|
</ModalPage>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
|
@ -10,6 +10,8 @@ import { StoriesSettingsModal } from '../../components/StoriesSettingsModal';
|
||||||
import {
|
import {
|
||||||
getAllSignalConnections,
|
getAllSignalConnections,
|
||||||
getCandidateContactsForNewGroup,
|
getCandidateContactsForNewGroup,
|
||||||
|
getConversationByUuidSelector,
|
||||||
|
getGroupStories,
|
||||||
getMe,
|
getMe,
|
||||||
} from '../selectors/conversations';
|
} from '../selectors/conversations';
|
||||||
import { getDistributionListsWithMembers } from '../selectors/storyDistributionLists';
|
import { getDistributionListsWithMembers } from '../selectors/storyDistributionLists';
|
||||||
|
@ -19,6 +21,7 @@ import { getHasStoryViewReceiptSetting } from '../selectors/items';
|
||||||
import { useGlobalModalActions } from '../ducks/globalModals';
|
import { useGlobalModalActions } from '../ducks/globalModals';
|
||||||
import { useStoryDistributionListsActions } from '../ducks/storyDistributionLists';
|
import { useStoryDistributionListsActions } from '../ducks/storyDistributionLists';
|
||||||
import { useStoriesActions } from '../ducks/stories';
|
import { useStoriesActions } from '../ducks/stories';
|
||||||
|
import { useConversationsActions } from '../ducks/conversations';
|
||||||
|
|
||||||
export function SmartStoriesSettingsModal(): JSX.Element | null {
|
export function SmartStoriesSettingsModal(): JSX.Element | null {
|
||||||
const { toggleStoriesView, setStoriesDisabled } = useStoriesActions();
|
const { toggleStoriesView, setStoriesDisabled } = useStoriesActions();
|
||||||
|
@ -33,6 +36,7 @@ export function SmartStoriesSettingsModal(): JSX.Element | null {
|
||||||
setMyStoriesToAllSignalConnections,
|
setMyStoriesToAllSignalConnections,
|
||||||
updateStoryViewers,
|
updateStoryViewers,
|
||||||
} = useStoryDistributionListsActions();
|
} = useStoryDistributionListsActions();
|
||||||
|
const { toggleGroupsForStorySend } = useConversationsActions();
|
||||||
const signalConnections = useSelector(getAllSignalConnections);
|
const signalConnections = useSelector(getAllSignalConnections);
|
||||||
|
|
||||||
const getPreferredBadge = useSelector(getPreferredBadgeSelector);
|
const getPreferredBadge = useSelector(getPreferredBadgeSelector);
|
||||||
|
@ -42,17 +46,23 @@ export function SmartStoriesSettingsModal(): JSX.Element | null {
|
||||||
|
|
||||||
const candidateConversations = useSelector(getCandidateContactsForNewGroup);
|
const candidateConversations = useSelector(getCandidateContactsForNewGroup);
|
||||||
const distributionLists = useSelector(getDistributionListsWithMembers);
|
const distributionLists = useSelector(getDistributionListsWithMembers);
|
||||||
|
const groupStories = useSelector(getGroupStories);
|
||||||
|
|
||||||
|
const getConversationByUuid = useSelector(getConversationByUuidSelector);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StoriesSettingsModal
|
<StoriesSettingsModal
|
||||||
candidateConversations={candidateConversations}
|
candidateConversations={candidateConversations}
|
||||||
distributionLists={distributionLists}
|
distributionLists={distributionLists}
|
||||||
|
groupStories={groupStories}
|
||||||
signalConnections={signalConnections}
|
signalConnections={signalConnections}
|
||||||
hideStoriesSettings={hideStoriesSettings}
|
hideStoriesSettings={hideStoriesSettings}
|
||||||
getPreferredBadge={getPreferredBadge}
|
getPreferredBadge={getPreferredBadge}
|
||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
me={me}
|
me={me}
|
||||||
|
getConversationByUuid={getConversationByUuid}
|
||||||
onDeleteList={deleteDistributionList}
|
onDeleteList={deleteDistributionList}
|
||||||
|
toggleGroupsForStorySend={toggleGroupsForStorySend}
|
||||||
onDistributionListCreated={createDistributionList}
|
onDistributionListCreated={createDistributionList}
|
||||||
onHideMyStoriesFrom={hideMyStoriesFrom}
|
onHideMyStoriesFrom={hideMyStoriesFrom}
|
||||||
onRemoveMember={removeMemberFromDistributionList}
|
onRemoveMember={removeMemberFromDistributionList}
|
||||||
|
|
|
@ -10,6 +10,12 @@ import type { ConversationType } from '../state/ducks/conversations';
|
||||||
import type { UUIDStringType } from '../types/UUID';
|
import type { UUIDStringType } from '../types/UUID';
|
||||||
import { isConversationUnregistered } from './isConversationUnregistered';
|
import { isConversationUnregistered } from './isConversationUnregistered';
|
||||||
|
|
||||||
|
export type GroupMemberships = {
|
||||||
|
memberships: Array<GroupV2Membership>;
|
||||||
|
pendingApprovalMemberships: Array<GroupV2RequestingMembership>;
|
||||||
|
pendingMemberships: Array<GroupV2PendingMembership>;
|
||||||
|
};
|
||||||
|
|
||||||
export const getGroupMemberships = (
|
export const getGroupMemberships = (
|
||||||
{
|
{
|
||||||
memberships = [],
|
memberships = [],
|
||||||
|
@ -22,11 +28,7 @@ export const getGroupMemberships = (
|
||||||
>
|
>
|
||||||
>,
|
>,
|
||||||
getConversationByUuid: (uuid: UUIDStringType) => undefined | ConversationType
|
getConversationByUuid: (uuid: UUIDStringType) => undefined | ConversationType
|
||||||
): {
|
): GroupMemberships => ({
|
||||||
memberships: Array<GroupV2Membership>;
|
|
||||||
pendingApprovalMemberships: Array<GroupV2RequestingMembership>;
|
|
||||||
pendingMemberships: Array<GroupV2PendingMembership>;
|
|
||||||
} => ({
|
|
||||||
memberships: memberships.reduce(
|
memberships: memberships.reduce(
|
||||||
(result: Array<GroupV2Membership>, membership) => {
|
(result: Array<GroupV2Membership>, membership) => {
|
||||||
const member = getConversationByUuid(membership.uuid);
|
const member = getConversationByUuid(membership.uuid);
|
||||||
|
|
Loading…
Add table
Reference in a new issue