Remove group from story feature
This commit is contained in:
parent
0c13ee896a
commit
9d7eaa003f
10 changed files with 584 additions and 268 deletions
|
@ -7443,6 +7443,14 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"SendStoryModal__delete-story": {
|
||||
"message": "Delete story",
|
||||
"description": "Button label to delete a story"
|
||||
},
|
||||
"SendStoryModal__confirm-remove-group": {
|
||||
"message": "Remove story? This will remove the story from your list, but you will still be able to view stories from this group.",
|
||||
"description": "Confirmation body for removing a group story"
|
||||
},
|
||||
"Stories__settings-toggle--title": {
|
||||
"message": "Share & View Stories",
|
||||
"description": "Select box title for the stories on/off toggle"
|
||||
|
|
|
@ -27,6 +27,16 @@
|
|||
}
|
||||
|
||||
&__icon {
|
||||
&--delete {
|
||||
@include color-svg(
|
||||
'../images/icons/v2/trash-outline-24.svg',
|
||||
$color-white
|
||||
);
|
||||
height: 14px;
|
||||
margin-top: 2px;
|
||||
width: 14px;
|
||||
}
|
||||
|
||||
&--lock {
|
||||
@include color-svg(
|
||||
'../images/icons/v2/lock-outline-24.svg',
|
||||
|
@ -46,6 +56,28 @@
|
|||
margin-top: 2px;
|
||||
width: 14px;
|
||||
}
|
||||
|
||||
&--settings {
|
||||
@include color-svg(
|
||||
'../images/icons/v2/settings-outline-16.svg',
|
||||
$color-white
|
||||
);
|
||||
height: 14px;
|
||||
margin-top: 2px;
|
||||
width: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
&__distribution-list-context {
|
||||
&__container {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&__button {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&__distribution-list {
|
||||
|
|
|
@ -14,11 +14,16 @@ import {
|
|||
import { setupI18n } from '../util/setupI18n';
|
||||
import {
|
||||
getMyStories,
|
||||
getFakeDistributionLists,
|
||||
getFakeDistributionListsWithMembers,
|
||||
} from '../test-both/helpers/getFakeDistributionLists';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const myStories = {
|
||||
...getMyStories(),
|
||||
members: [],
|
||||
};
|
||||
|
||||
export default {
|
||||
title: 'Components/SendStoryModal',
|
||||
component: SendStoryModal,
|
||||
|
@ -27,7 +32,7 @@ export default {
|
|||
defaultValue: Array.from(Array(100), () => getDefaultConversation()),
|
||||
},
|
||||
distributionLists: {
|
||||
defaultValue: [getMyStories()],
|
||||
defaultValue: [myStories],
|
||||
},
|
||||
getPreferredBadge: { action: true },
|
||||
groupConversations: {
|
||||
|
@ -46,6 +51,7 @@ export default {
|
|||
defaultValue: getDefaultConversation(),
|
||||
},
|
||||
onClose: { action: true },
|
||||
onDeleteList: { action: true },
|
||||
onDistributionListCreated: { action: true },
|
||||
onHideMyStoriesFrom: { action: true },
|
||||
onSend: { action: true },
|
||||
|
@ -54,7 +60,7 @@ export default {
|
|||
signalConnections: {
|
||||
defaultValue: Array.from(Array(42), getDefaultConversation),
|
||||
},
|
||||
tagGroupsAsNewGroupStory: { action: true },
|
||||
toggleGroupsForStorySend: { action: true },
|
||||
toggleSignalConnectionsModal: { action: true },
|
||||
},
|
||||
} as Meta;
|
||||
|
@ -63,12 +69,25 @@ const Template: Story<PropsType> = args => <SendStoryModal {...args} />;
|
|||
|
||||
export const Modal = Template.bind({});
|
||||
Modal.args = {
|
||||
distributionLists: getFakeDistributionLists(),
|
||||
distributionLists: getFakeDistributionListsWithMembers(),
|
||||
};
|
||||
|
||||
export const FirstTime = Template.bind({});
|
||||
FirstTime.args = {
|
||||
distributionLists: [getMyStories()],
|
||||
distributionLists: [myStories],
|
||||
groupStories: [],
|
||||
hasFirstStoryPostExperience: true,
|
||||
};
|
||||
|
||||
export const FirstTimeAlreadyConfiguredOnMobile = Template.bind({});
|
||||
FirstTime.args = {
|
||||
distributionLists: [
|
||||
{
|
||||
...myStories,
|
||||
isBlockList: false,
|
||||
members: Array.from(Array(3), getDefaultConversation),
|
||||
},
|
||||
],
|
||||
groupStories: [],
|
||||
hasFirstStoryPostExperience: true,
|
||||
};
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { noop } from 'lodash';
|
||||
|
||||
import { SearchInput } from './SearchInput';
|
||||
import { filterAndSortConversationsByRecent } from '../util/filterAndSortConversations';
|
||||
|
@ -10,13 +11,15 @@ import type { ConversationType } from '../state/ducks/conversations';
|
|||
import type { LocalizerType } from '../types/Util';
|
||||
import type { PreferredBadgeSelectorType } from '../state/selectors/badges';
|
||||
import type { PropsType as StoriesSettingsModalPropsType } from './StoriesSettingsModal';
|
||||
import type { StoryDistributionListDataType } from '../state/ducks/storyDistributionLists';
|
||||
import type { StoryDistributionListWithMembersDataType } from '../types/Stories';
|
||||
import type { UUIDStringType } from '../types/UUID';
|
||||
import { Avatar, AvatarSize } from './Avatar';
|
||||
import { Button, ButtonVariant } from './Button';
|
||||
import { Checkbox } from './Checkbox';
|
||||
import { ConfirmationDialog } from './ConfirmationDialog';
|
||||
import { ContextMenu } from './ContextMenu';
|
||||
import {
|
||||
DistributionListSettings,
|
||||
EditDistributionList,
|
||||
EditMyStoriesPrivacy,
|
||||
Page as StoriesSettingsPage,
|
||||
|
@ -29,7 +32,7 @@ import { isNotNil } from '../util/isNotNil';
|
|||
|
||||
export type PropsType = {
|
||||
candidateConversations: Array<ConversationType>;
|
||||
distributionLists: Array<StoryDistributionListDataType>;
|
||||
distributionLists: Array<StoryDistributionListWithMembersDataType>;
|
||||
getPreferredBadge: PreferredBadgeSelectorType;
|
||||
groupConversations: Array<ConversationType>;
|
||||
groupStories: Array<ConversationType>;
|
||||
|
@ -37,6 +40,7 @@ export type PropsType = {
|
|||
i18n: LocalizerType;
|
||||
me: ConversationType;
|
||||
onClose: () => unknown;
|
||||
onDeleteList: (listId: string) => unknown;
|
||||
onDistributionListCreated: (
|
||||
name: string,
|
||||
viewerUuids: Array<UUIDStringType>
|
||||
|
@ -47,23 +51,20 @@ export type PropsType = {
|
|||
conversationIds: Array<string>
|
||||
) => unknown;
|
||||
signalConnections: Array<ConversationType>;
|
||||
tagGroupsAsNewGroupStory: (cids: Array<string>) => unknown;
|
||||
toggleGroupsForStorySend: (cids: Array<string>) => unknown;
|
||||
} & Pick<
|
||||
StoriesSettingsModalPropsType,
|
||||
| 'onHideMyStoriesFrom'
|
||||
| 'onRemoveMember'
|
||||
| 'onRepliesNReactionsChanged'
|
||||
| 'onViewersUpdated'
|
||||
| 'setMyStoriesToAllSignalConnections'
|
||||
| 'toggleSignalConnectionsModal'
|
||||
>;
|
||||
|
||||
enum MyStoriesPrivacy {
|
||||
AllSignalConnections = 'AllSignalConnections',
|
||||
Exclude = 'Exclude',
|
||||
OnlyShareWith = 'OnlyShareWith',
|
||||
}
|
||||
|
||||
enum SendStoryPage {
|
||||
ChooseGroups = 'ChooseGroups',
|
||||
EditingDistributionList = 'EditingDistributionList',
|
||||
SendStory = 'SendStory',
|
||||
SetMyStoriesPrivacy = 'SetMyStoriesPrivacy',
|
||||
}
|
||||
|
@ -76,30 +77,32 @@ const Page = {
|
|||
type PageType = SendStoryPage | StoriesSettingsPage;
|
||||
|
||||
function getListMemberUuids(
|
||||
list: StoryDistributionListDataType,
|
||||
list: StoryDistributionListWithMembersDataType,
|
||||
signalConnections: Array<ConversationType>
|
||||
): Array<string> {
|
||||
const memberUuids = list.members.map(({ uuid }) => uuid).filter(isNotNil);
|
||||
|
||||
if (list.id === MY_STORIES_ID && list.isBlockList) {
|
||||
const excludeUuids = new Set<string>(list.memberUuids);
|
||||
const excludeUuids = new Set<string>(memberUuids);
|
||||
return signalConnections
|
||||
.map(conversation => conversation.uuid)
|
||||
.filter(isNotNil)
|
||||
.filter(uuid => !excludeUuids.has(uuid));
|
||||
}
|
||||
|
||||
return list.memberUuids;
|
||||
return memberUuids;
|
||||
}
|
||||
|
||||
function getListViewers(
|
||||
list: StoryDistributionListDataType,
|
||||
list: StoryDistributionListWithMembersDataType,
|
||||
i18n: LocalizerType,
|
||||
signalConnections: Array<ConversationType>
|
||||
): string {
|
||||
let memberCount = list.memberUuids.length;
|
||||
let memberCount = list.members.length;
|
||||
|
||||
if (list.id === MY_STORIES_ID && list.isBlockList) {
|
||||
memberCount = list.isBlockList
|
||||
? signalConnections.length - list.memberUuids.length
|
||||
? signalConnections.length - list.members.length
|
||||
: signalConnections.length;
|
||||
}
|
||||
|
||||
|
@ -118,14 +121,17 @@ export const SendStoryModal = ({
|
|||
i18n,
|
||||
me,
|
||||
onClose,
|
||||
onDeleteList,
|
||||
onDistributionListCreated,
|
||||
onHideMyStoriesFrom,
|
||||
onSend,
|
||||
onRemoveMember,
|
||||
onRepliesNReactionsChanged,
|
||||
onSelectedStoryList,
|
||||
onSend,
|
||||
onViewersUpdated,
|
||||
setMyStoriesToAllSignalConnections,
|
||||
signalConnections,
|
||||
tagGroupsAsNewGroupStory,
|
||||
toggleGroupsForStorySend,
|
||||
toggleSignalConnectionsModal,
|
||||
}: PropsType): JSX.Element => {
|
||||
const [page, setPage] = useState<PageType>(Page.SendStory);
|
||||
|
@ -192,27 +198,61 @@ export const SendStoryModal = ({
|
|||
Array<ConversationType>
|
||||
>([]);
|
||||
|
||||
const [myStoriesPrivacy, setMyStoriesPrivacy] = useState<MyStoriesPrivacy>(
|
||||
MyStoriesPrivacy.AllSignalConnections
|
||||
);
|
||||
const [myStoriesPrivacyUuids, setMyStoriesPrivacyUuids] = useState<
|
||||
Set<UUIDStringType>
|
||||
>(new Set());
|
||||
const [confirmRemoveGroupId, setConfirmRemoveGroupId] = useState<
|
||||
string | undefined
|
||||
>();
|
||||
const [confirmDeleteListId, setConfirmDeleteListId] = useState<
|
||||
string | undefined
|
||||
>();
|
||||
|
||||
const myStories = useMemo(() => {
|
||||
return {
|
||||
const [listIdToEdit, setListIdToEdit] = useState<string | undefined>();
|
||||
|
||||
useEffect(() => {
|
||||
if (listIdToEdit) {
|
||||
setPage(Page.EditingDistributionList);
|
||||
} else {
|
||||
setPage(Page.SendStory);
|
||||
}
|
||||
}, [listIdToEdit]);
|
||||
|
||||
const listToEdit = useMemo(() => {
|
||||
if (!listIdToEdit) {
|
||||
return;
|
||||
}
|
||||
|
||||
return distributionLists.find(list => list.id === listIdToEdit);
|
||||
}, [distributionLists, listIdToEdit]);
|
||||
|
||||
// myStoriesPrivacy, myStoriesPrivacyUuids, and myStories are only used
|
||||
// during the first time posting to My Stories experience where we have
|
||||
// to select the privacy settings.
|
||||
const ogMyStories = useMemo(
|
||||
() => distributionLists.find(list => list.id === MY_STORIES_ID),
|
||||
[distributionLists]
|
||||
);
|
||||
|
||||
const initialMyStories = useMemo(
|
||||
() => ({
|
||||
allowsReplies: true,
|
||||
id: MY_STORIES_ID,
|
||||
name: MY_STORIES_ID,
|
||||
isBlockList: myStoriesPrivacy !== MyStoriesPrivacy.OnlyShareWith,
|
||||
members:
|
||||
myStoriesPrivacy === MyStoriesPrivacy.AllSignalConnections
|
||||
? []
|
||||
: candidateConversations.filter(
|
||||
convo => convo.uuid && myStoriesPrivacyUuids.has(convo.uuid)
|
||||
),
|
||||
};
|
||||
}, [candidateConversations, myStoriesPrivacy, myStoriesPrivacyUuids]);
|
||||
name: i18n('Stories__mine'),
|
||||
isBlockList: ogMyStories?.isBlockList ?? true,
|
||||
members: ogMyStories?.members || [],
|
||||
}),
|
||||
[i18n, ogMyStories]
|
||||
);
|
||||
|
||||
const initialMyStoriesMemberUuids = useMemo(
|
||||
() => (ogMyStories?.members || []).map(({ uuid }) => uuid).filter(isNotNil),
|
||||
[ogMyStories]
|
||||
);
|
||||
|
||||
const [stagedMyStories, setStagedMyStories] =
|
||||
useState<StoryDistributionListWithMembersDataType>(initialMyStories);
|
||||
|
||||
const [stagedMyStoriesMemberUuids, setStagedMyStoriesMemberUuids] = useState<
|
||||
Array<UUIDStringType>
|
||||
>(initialMyStoriesMemberUuids);
|
||||
|
||||
let content: JSX.Element;
|
||||
if (page === Page.SetMyStoriesPrivacy) {
|
||||
|
@ -221,28 +261,63 @@ export const SendStoryModal = ({
|
|||
hasDisclaimerAbove
|
||||
i18n={i18n}
|
||||
learnMore="SendStoryModal__privacy-disclaimer"
|
||||
myStories={myStories}
|
||||
myStories={stagedMyStories}
|
||||
onClickExclude={() => {
|
||||
setMyStoriesPrivacy(MyStoriesPrivacy.Exclude);
|
||||
setMyStoriesPrivacyUuids(new Set());
|
||||
setSelectedContacts([]);
|
||||
let nextSelectedContacts = stagedMyStories.members;
|
||||
|
||||
if (!stagedMyStories.isBlockList) {
|
||||
setStagedMyStories(myStories => ({
|
||||
...myStories,
|
||||
isBlockList: true,
|
||||
members: [],
|
||||
}));
|
||||
nextSelectedContacts = [];
|
||||
}
|
||||
|
||||
setSelectedContacts(nextSelectedContacts);
|
||||
|
||||
setPage(Page.HideStoryFrom);
|
||||
}}
|
||||
onClickOnlyShareWith={() => {
|
||||
setMyStoriesPrivacy(MyStoriesPrivacy.OnlyShareWith);
|
||||
setMyStoriesPrivacyUuids(new Set());
|
||||
setSelectedContacts([]);
|
||||
if (!stagedMyStories.isBlockList) {
|
||||
setSelectedContacts(stagedMyStories.members);
|
||||
} else {
|
||||
setStagedMyStories(myStories => ({
|
||||
...myStories,
|
||||
isBlockList: false,
|
||||
members: [],
|
||||
}));
|
||||
}
|
||||
|
||||
setPage(Page.AddViewer);
|
||||
}}
|
||||
setSelectedContacts={setSelectedContacts}
|
||||
setMyStoriesToAllSignalConnections={() => {
|
||||
setMyStoriesPrivacy(MyStoriesPrivacy.AllSignalConnections);
|
||||
setMyStoriesPrivacyUuids(new Set());
|
||||
setStagedMyStories(myStories => ({
|
||||
...myStories,
|
||||
isBlockList: true,
|
||||
members: [],
|
||||
}));
|
||||
setSelectedContacts([]);
|
||||
}}
|
||||
toggleSignalConnectionsModal={toggleSignalConnectionsModal}
|
||||
/>
|
||||
);
|
||||
} else if (page === Page.EditingDistributionList && listToEdit) {
|
||||
content = (
|
||||
<DistributionListSettings
|
||||
getPreferredBadge={getPreferredBadge}
|
||||
i18n={i18n}
|
||||
listToEdit={listToEdit}
|
||||
onRemoveMember={onRemoveMember}
|
||||
onRepliesNReactionsChanged={onRepliesNReactionsChanged}
|
||||
setConfirmDeleteListId={setConfirmDeleteListId}
|
||||
setMyStoriesToAllSignalConnections={setMyStoriesToAllSignalConnections}
|
||||
setPage={setPage}
|
||||
setSelectedContacts={setSelectedContacts}
|
||||
toggleSignalConnectionsModal={toggleSignalConnectionsModal}
|
||||
/>
|
||||
);
|
||||
} else if (
|
||||
page === Page.ChooseViewers ||
|
||||
page === Page.NameStory ||
|
||||
|
@ -254,15 +329,21 @@ export const SendStoryModal = ({
|
|||
candidateConversations={candidateConversations}
|
||||
getPreferredBadge={getPreferredBadge}
|
||||
i18n={i18n}
|
||||
onDone={(name, uuids) => {
|
||||
onCreateList={(name, uuids) => {
|
||||
onDistributionListCreated(name, uuids);
|
||||
setPage(Page.SendStory);
|
||||
}}
|
||||
onViewersUpdated={uuids => {
|
||||
if (page === Page.ChooseViewers) {
|
||||
if (listIdToEdit && page === Page.AddViewer) {
|
||||
onViewersUpdated(listIdToEdit, uuids);
|
||||
setPage(Page.EditingDistributionList);
|
||||
} else if (page === Page.ChooseViewers) {
|
||||
setPage(Page.NameStory);
|
||||
} else if (listIdToEdit && page === Page.HideStoryFrom) {
|
||||
onHideMyStoriesFrom(uuids);
|
||||
setPage(Page.SendStory);
|
||||
} else if (page === Page.HideStoryFrom || page === Page.AddViewer) {
|
||||
setMyStoriesPrivacyUuids(new Set(uuids));
|
||||
setStagedMyStoriesMemberUuids(uuids);
|
||||
setPage(Page.SetMyStoriesPrivacy);
|
||||
} else {
|
||||
setPage(Page.SendStory);
|
||||
|
@ -415,7 +496,38 @@ export const SendStoryModal = ({
|
|||
}}
|
||||
>
|
||||
{({ id, checkboxNode }) => (
|
||||
<>
|
||||
<ContextMenu
|
||||
i18n={i18n}
|
||||
menuOptions={
|
||||
list.id === MY_STORIES_ID
|
||||
? [
|
||||
{
|
||||
label: i18n('StoriesSettings__context-menu'),
|
||||
icon: 'SendStoryModal__icon--delete',
|
||||
onClick: () => setListIdToEdit(list.id),
|
||||
},
|
||||
]
|
||||
: [
|
||||
{
|
||||
label: i18n('StoriesSettings__context-menu'),
|
||||
icon: 'SendStoryModal__icon--settings',
|
||||
onClick: () => setListIdToEdit(list.id),
|
||||
},
|
||||
{
|
||||
label: i18n('SendStoryModal__delete-story'),
|
||||
icon: 'SendStoryModal__icon--delete',
|
||||
onClick: () => setConfirmDeleteListId(list.id),
|
||||
},
|
||||
]
|
||||
}
|
||||
moduleClassName="SendStoryModal__distribution-list-context"
|
||||
onClick={noop}
|
||||
popperOptions={{
|
||||
placement: 'bottom',
|
||||
strategy: 'absolute',
|
||||
}}
|
||||
theme={Theme.Dark}
|
||||
>
|
||||
<label
|
||||
className="SendStoryModal__distribution-list__label"
|
||||
htmlFor={id}
|
||||
|
@ -454,7 +566,7 @@ export const SendStoryModal = ({
|
|||
</div>
|
||||
</label>
|
||||
{checkboxNode}
|
||||
</>
|
||||
</ContextMenu>
|
||||
)}
|
||||
</Checkbox>
|
||||
))}
|
||||
|
@ -484,7 +596,23 @@ export const SendStoryModal = ({
|
|||
}}
|
||||
>
|
||||
{({ id, checkboxNode }) => (
|
||||
<>
|
||||
<ContextMenu
|
||||
i18n={i18n}
|
||||
menuOptions={[
|
||||
{
|
||||
label: i18n('SendStoryModal__delete-story'),
|
||||
icon: 'SendStoryModal__icon--delete',
|
||||
onClick: () => setConfirmRemoveGroupId(group.id),
|
||||
},
|
||||
]}
|
||||
moduleClassName="SendStoryModal__distribution-list-context"
|
||||
onClick={noop}
|
||||
popperOptions={{
|
||||
placement: 'bottom',
|
||||
strategy: 'absolute',
|
||||
}}
|
||||
theme={Theme.Dark}
|
||||
>
|
||||
<label
|
||||
className="SendStoryModal__distribution-list__label"
|
||||
htmlFor={id}
|
||||
|
@ -517,7 +645,7 @@ export const SendStoryModal = ({
|
|||
</div>
|
||||
</label>
|
||||
{checkboxNode}
|
||||
</>
|
||||
</ContextMenu>
|
||||
)}
|
||||
</Checkbox>
|
||||
))}
|
||||
|
@ -568,7 +696,7 @@ export const SendStoryModal = ({
|
|||
className="SendStoryModal__ok"
|
||||
disabled={!chosenGroupIds.size}
|
||||
onClick={() => {
|
||||
tagGroupsAsNewGroupStory(Array.from(chosenGroupIds));
|
||||
toggleGroupsForStorySend(Array.from(chosenGroupIds));
|
||||
setChosenGroupIds(new Set());
|
||||
setPage(Page.SendStory);
|
||||
}}
|
||||
|
@ -598,21 +726,16 @@ export const SendStoryModal = ({
|
|||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
if (
|
||||
myStoriesPrivacy === MyStoriesPrivacy.AllSignalConnections
|
||||
) {
|
||||
if (stagedMyStories.isBlockList) {
|
||||
if (stagedMyStories.members.length) {
|
||||
onHideMyStoriesFrom(stagedMyStoriesMemberUuids);
|
||||
} else {
|
||||
setMyStoriesToAllSignalConnections();
|
||||
} else if (myStoriesPrivacy === MyStoriesPrivacy.Exclude) {
|
||||
onHideMyStoriesFrom(Array.from(myStoriesPrivacyUuids));
|
||||
} else if (
|
||||
myStoriesPrivacy === MyStoriesPrivacy.OnlyShareWith
|
||||
) {
|
||||
onViewersUpdated(
|
||||
MY_STORIES_ID,
|
||||
Array.from(myStoriesPrivacyUuids)
|
||||
);
|
||||
}
|
||||
setMyStoriesPrivacyUuids(new Set());
|
||||
} else {
|
||||
onViewersUpdated(MY_STORIES_ID, stagedMyStoriesMemberUuids);
|
||||
}
|
||||
|
||||
setSelectedContacts([]);
|
||||
setPage(Page.SendStory);
|
||||
}}
|
||||
|
@ -628,6 +751,7 @@ export const SendStoryModal = ({
|
|||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal
|
||||
hasStickyButtons
|
||||
hasXButton
|
||||
|
@ -636,17 +760,28 @@ export const SendStoryModal = ({
|
|||
onBackButtonClick={
|
||||
hasBackButton
|
||||
? () => {
|
||||
if (page === Page.SetMyStoriesPrivacy) {
|
||||
if (listIdToEdit) {
|
||||
if (
|
||||
page === Page.AddViewer ||
|
||||
page === Page.HideStoryFrom ||
|
||||
page === Page.ChooseViewers
|
||||
) {
|
||||
setPage(Page.EditingDistributionList);
|
||||
} else {
|
||||
setListIdToEdit(undefined);
|
||||
}
|
||||
} else if (page === Page.SetMyStoriesPrivacy) {
|
||||
setSelectedContacts([]);
|
||||
setMyStoriesPrivacyUuids(new Set());
|
||||
setMyStoriesPrivacy(MyStoriesPrivacy.AllSignalConnections);
|
||||
setStagedMyStories(initialMyStories);
|
||||
setStagedMyStoriesMemberUuids(initialMyStoriesMemberUuids);
|
||||
setPage(Page.SendStory);
|
||||
} else if (
|
||||
page === Page.HideStoryFrom ||
|
||||
page === Page.AddViewer
|
||||
) {
|
||||
setSelectedContacts([]);
|
||||
setMyStoriesPrivacyUuids(new Set());
|
||||
setStagedMyStories(initialMyStories);
|
||||
setStagedMyStoriesMemberUuids(initialMyStoriesMemberUuids);
|
||||
setPage(Page.SetMyStoriesPrivacy);
|
||||
} else if (page === Page.ChooseGroups) {
|
||||
setChosenGroupIds(new Set());
|
||||
|
@ -666,5 +801,47 @@ export const SendStoryModal = ({
|
|||
>
|
||||
{content}
|
||||
</Modal>
|
||||
{confirmRemoveGroupId && (
|
||||
<ConfirmationDialog
|
||||
actions={[
|
||||
{
|
||||
action: () => {
|
||||
toggleGroupsForStorySend([confirmRemoveGroupId]);
|
||||
setConfirmRemoveGroupId(undefined);
|
||||
},
|
||||
style: 'negative',
|
||||
text: i18n('delete'),
|
||||
},
|
||||
]}
|
||||
i18n={i18n}
|
||||
onClose={() => {
|
||||
setConfirmRemoveGroupId(undefined);
|
||||
}}
|
||||
>
|
||||
{i18n('SendStoryModal__confirm-remove-group')}
|
||||
</ConfirmationDialog>
|
||||
)}
|
||||
{confirmDeleteListId && (
|
||||
<ConfirmationDialog
|
||||
actions={[
|
||||
{
|
||||
action: () => {
|
||||
onDeleteList(confirmDeleteListId);
|
||||
setConfirmDeleteListId(undefined);
|
||||
// setListToEditId(undefined);
|
||||
},
|
||||
style: 'negative',
|
||||
text: i18n('delete'),
|
||||
},
|
||||
]}
|
||||
i18n={i18n}
|
||||
onClose={() => {
|
||||
setConfirmDeleteListId(undefined);
|
||||
}}
|
||||
>
|
||||
{i18n('StoriesSettings__delete-list--confirm')}
|
||||
</ConfirmationDialog>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -117,14 +117,6 @@ export const StoriesSettingsModal = ({
|
|||
const [confirmDeleteListId, setConfirmDeleteListId] = useState<
|
||||
string | undefined
|
||||
>();
|
||||
const [confirmRemoveMember, setConfirmRemoveMember] = useState<
|
||||
| undefined
|
||||
| {
|
||||
listId: string;
|
||||
title: string;
|
||||
uuid: UUIDStringType | undefined;
|
||||
}
|
||||
>();
|
||||
|
||||
let content: JSX.Element | null;
|
||||
|
||||
|
@ -134,7 +126,7 @@ export const StoriesSettingsModal = ({
|
|||
candidateConversations={candidateConversations}
|
||||
getPreferredBadge={getPreferredBadge}
|
||||
i18n={i18n}
|
||||
onDone={(name, uuids) => {
|
||||
onCreateList={(name, uuids) => {
|
||||
onDistributionListCreated(name, uuids);
|
||||
resetChooseViewersScreen();
|
||||
}}
|
||||
|
@ -159,142 +151,19 @@ export const StoriesSettingsModal = ({
|
|||
/>
|
||||
);
|
||||
} else if (listToEdit) {
|
||||
const isMyStories = listToEdit.id === MY_STORIES_ID;
|
||||
|
||||
content = (
|
||||
<>
|
||||
{!isMyStories && (
|
||||
<>
|
||||
<div className="StoriesSettingsModal__list StoriesSettingsModal__list--no-pointer">
|
||||
<span className="StoriesSettingsModal__list__left">
|
||||
<span className="StoriesSettingsModal__list__avatar--private" />
|
||||
<span className="StoriesSettingsModal__list__title">
|
||||
<StoryDistributionListName
|
||||
<DistributionListSettings
|
||||
getPreferredBadge={getPreferredBadge}
|
||||
i18n={i18n}
|
||||
id={listToEdit.id}
|
||||
name={listToEdit.name}
|
||||
/>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<hr className="StoriesSettingsModal__divider" />
|
||||
</>
|
||||
)}
|
||||
|
||||
<div className="StoriesSettingsModal__title">
|
||||
{i18n('StoriesSettings__who-can-see')}
|
||||
</div>
|
||||
|
||||
{isMyStories && (
|
||||
<EditMyStoriesPrivacy
|
||||
i18n={i18n}
|
||||
learnMore="StoriesSettings__mine_disclaimer"
|
||||
myStories={listToEdit}
|
||||
onClickExclude={() => {
|
||||
setPage(Page.HideStoryFrom);
|
||||
}}
|
||||
onClickOnlyShareWith={() => {
|
||||
setPage(Page.AddViewer);
|
||||
}}
|
||||
listToEdit={listToEdit}
|
||||
onRemoveMember={onRemoveMember}
|
||||
onRepliesNReactionsChanged={onRepliesNReactionsChanged}
|
||||
setConfirmDeleteListId={setConfirmDeleteListId}
|
||||
setMyStoriesToAllSignalConnections={setMyStoriesToAllSignalConnections}
|
||||
setPage={setPage}
|
||||
setSelectedContacts={setSelectedContacts}
|
||||
setMyStoriesToAllSignalConnections={
|
||||
setMyStoriesToAllSignalConnections
|
||||
}
|
||||
toggleSignalConnectionsModal={toggleSignalConnectionsModal}
|
||||
/>
|
||||
)}
|
||||
|
||||
{!isMyStories && (
|
||||
<>
|
||||
<button
|
||||
className="StoriesSettingsModal__list"
|
||||
onClick={() => {
|
||||
setSelectedContacts(listToEdit.members);
|
||||
setPage(Page.AddViewer);
|
||||
}}
|
||||
type="button"
|
||||
>
|
||||
<span className="StoriesSettingsModal__list__left">
|
||||
<span className="StoriesSettingsModal__list__avatar--new" />
|
||||
<span className="StoriesSettingsModal__list__title">
|
||||
{i18n('StoriesSettings__add-viewer')}
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
|
||||
{listToEdit.members.map(member => (
|
||||
<div
|
||||
className="StoriesSettingsModal__list StoriesSettingsModal__list--no-pointer"
|
||||
key={member.id}
|
||||
>
|
||||
<span className="StoriesSettingsModal__list__left">
|
||||
<Avatar
|
||||
acceptedMessageRequest={member.acceptedMessageRequest}
|
||||
avatarPath={member.avatarPath}
|
||||
badge={getPreferredBadge(member.badges)}
|
||||
color={member.color}
|
||||
conversationType={member.type}
|
||||
i18n={i18n}
|
||||
isMe
|
||||
sharedGroupNames={member.sharedGroupNames}
|
||||
size={AvatarSize.THIRTY_SIX}
|
||||
theme={ThemeType.dark}
|
||||
title={member.title}
|
||||
/>
|
||||
<span className="StoriesSettingsModal__list__title">
|
||||
{member.title}
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<button
|
||||
aria-label={i18n('StoriesSettings__remove--title', [
|
||||
member.title,
|
||||
])}
|
||||
className="StoriesSettingsModal__list__delete"
|
||||
onClick={() =>
|
||||
setConfirmRemoveMember({
|
||||
listId: listToEdit.id,
|
||||
title: member.title,
|
||||
uuid: member.uuid,
|
||||
})
|
||||
}
|
||||
type="button"
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
|
||||
<hr className="StoriesSettingsModal__divider" />
|
||||
|
||||
<div className="StoriesSettingsModal__title">
|
||||
{i18n('StoriesSettings__replies-reactions--title')}
|
||||
</div>
|
||||
|
||||
<Checkbox
|
||||
checked={listToEdit.allowsReplies}
|
||||
description={i18n('StoriesSettings__replies-reactions--description')}
|
||||
label={i18n('StoriesSettings__replies-reactions--label')}
|
||||
moduleClassName="StoriesSettingsModal__checkbox"
|
||||
name="replies-reactions"
|
||||
onChange={value => onRepliesNReactionsChanged(listToEdit.id, value)}
|
||||
/>
|
||||
|
||||
{!isMyStories && (
|
||||
<>
|
||||
<hr className="StoriesSettingsModal__divider" />
|
||||
|
||||
<button
|
||||
className="StoriesSettingsModal__delete-list"
|
||||
onClick={() => setConfirmDeleteListId(listToEdit.id)}
|
||||
type="button"
|
||||
>
|
||||
{i18n('StoriesSettings__delete-list')}
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
} else {
|
||||
const privateStories = distributionLists.filter(
|
||||
|
@ -447,6 +316,182 @@ export const StoriesSettingsModal = ({
|
|||
{i18n('StoriesSettings__delete-list--confirm')}
|
||||
</ConfirmationDialog>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
type DistributionListSettingsPropsType = {
|
||||
i18n: LocalizerType;
|
||||
listToEdit: StoryDistributionListWithMembersDataType;
|
||||
setConfirmDeleteListId: (id: string) => unknown;
|
||||
setPage: (page: Page) => unknown;
|
||||
setSelectedContacts: (contacts: Array<ConversationType>) => unknown;
|
||||
} & Pick<
|
||||
PropsType,
|
||||
| 'getPreferredBadge'
|
||||
| 'onRemoveMember'
|
||||
| 'onRepliesNReactionsChanged'
|
||||
| 'setMyStoriesToAllSignalConnections'
|
||||
| 'toggleSignalConnectionsModal'
|
||||
>;
|
||||
|
||||
export const DistributionListSettings = ({
|
||||
getPreferredBadge,
|
||||
i18n,
|
||||
listToEdit,
|
||||
onRemoveMember,
|
||||
onRepliesNReactionsChanged,
|
||||
setConfirmDeleteListId,
|
||||
setMyStoriesToAllSignalConnections,
|
||||
setPage,
|
||||
setSelectedContacts,
|
||||
toggleSignalConnectionsModal,
|
||||
}: DistributionListSettingsPropsType): JSX.Element => {
|
||||
const [confirmRemoveMember, setConfirmRemoveMember] = useState<
|
||||
| undefined
|
||||
| {
|
||||
listId: string;
|
||||
title: string;
|
||||
uuid: UUIDStringType | undefined;
|
||||
}
|
||||
>();
|
||||
|
||||
const isMyStories = listToEdit.id === MY_STORIES_ID;
|
||||
|
||||
return (
|
||||
<>
|
||||
{!isMyStories && (
|
||||
<>
|
||||
<div className="StoriesSettingsModal__list StoriesSettingsModal__list--no-pointer">
|
||||
<span className="StoriesSettingsModal__list__left">
|
||||
<span className="StoriesSettingsModal__list__avatar--private" />
|
||||
<span className="StoriesSettingsModal__list__title">
|
||||
<StoryDistributionListName
|
||||
i18n={i18n}
|
||||
id={listToEdit.id}
|
||||
name={listToEdit.name}
|
||||
/>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<hr className="StoriesSettingsModal__divider" />
|
||||
</>
|
||||
)}
|
||||
|
||||
<div className="StoriesSettingsModal__title">
|
||||
{i18n('StoriesSettings__who-can-see')}
|
||||
</div>
|
||||
|
||||
{isMyStories && (
|
||||
<EditMyStoriesPrivacy
|
||||
i18n={i18n}
|
||||
learnMore="StoriesSettings__mine_disclaimer"
|
||||
myStories={listToEdit}
|
||||
onClickExclude={() => {
|
||||
setPage(Page.HideStoryFrom);
|
||||
}}
|
||||
onClickOnlyShareWith={() => {
|
||||
setPage(Page.AddViewer);
|
||||
}}
|
||||
setSelectedContacts={setSelectedContacts}
|
||||
setMyStoriesToAllSignalConnections={
|
||||
setMyStoriesToAllSignalConnections
|
||||
}
|
||||
toggleSignalConnectionsModal={toggleSignalConnectionsModal}
|
||||
/>
|
||||
)}
|
||||
|
||||
{!isMyStories && (
|
||||
<>
|
||||
<button
|
||||
className="StoriesSettingsModal__list"
|
||||
onClick={() => {
|
||||
setSelectedContacts(listToEdit.members);
|
||||
setPage(Page.AddViewer);
|
||||
}}
|
||||
type="button"
|
||||
>
|
||||
<span className="StoriesSettingsModal__list__left">
|
||||
<span className="StoriesSettingsModal__list__avatar--new" />
|
||||
<span className="StoriesSettingsModal__list__title">
|
||||
{i18n('StoriesSettings__add-viewer')}
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
|
||||
{listToEdit.members.map(member => (
|
||||
<div
|
||||
className="StoriesSettingsModal__list StoriesSettingsModal__list--no-pointer"
|
||||
key={member.id}
|
||||
>
|
||||
<span className="StoriesSettingsModal__list__left">
|
||||
<Avatar
|
||||
acceptedMessageRequest={member.acceptedMessageRequest}
|
||||
avatarPath={member.avatarPath}
|
||||
badge={getPreferredBadge(member.badges)}
|
||||
color={member.color}
|
||||
conversationType={member.type}
|
||||
i18n={i18n}
|
||||
isMe
|
||||
sharedGroupNames={member.sharedGroupNames}
|
||||
size={AvatarSize.THIRTY_SIX}
|
||||
theme={ThemeType.dark}
|
||||
title={member.title}
|
||||
/>
|
||||
<span className="StoriesSettingsModal__list__title">
|
||||
{member.title}
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<button
|
||||
aria-label={i18n('StoriesSettings__remove--title', [
|
||||
member.title,
|
||||
])}
|
||||
className="StoriesSettingsModal__list__delete"
|
||||
onClick={() =>
|
||||
setConfirmRemoveMember({
|
||||
listId: listToEdit.id,
|
||||
title: member.title,
|
||||
uuid: member.uuid,
|
||||
})
|
||||
}
|
||||
type="button"
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
|
||||
<hr className="StoriesSettingsModal__divider" />
|
||||
|
||||
<div className="StoriesSettingsModal__title">
|
||||
{i18n('StoriesSettings__replies-reactions--title')}
|
||||
</div>
|
||||
|
||||
<Checkbox
|
||||
checked={listToEdit.allowsReplies}
|
||||
description={i18n('StoriesSettings__replies-reactions--description')}
|
||||
label={i18n('StoriesSettings__replies-reactions--label')}
|
||||
moduleClassName="StoriesSettingsModal__checkbox"
|
||||
name="replies-reactions"
|
||||
onChange={value => onRepliesNReactionsChanged(listToEdit.id, value)}
|
||||
/>
|
||||
|
||||
{!isMyStories && (
|
||||
<>
|
||||
<hr className="StoriesSettingsModal__divider" />
|
||||
|
||||
<button
|
||||
className="StoriesSettingsModal__delete-list"
|
||||
onClick={() => setConfirmDeleteListId(listToEdit.id)}
|
||||
type="button"
|
||||
>
|
||||
{i18n('StoriesSettings__delete-list')}
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
|
||||
{confirmRemoveMember && (
|
||||
<ConfirmationDialog
|
||||
actions={[
|
||||
|
@ -581,7 +626,7 @@ export const EditMyStoriesPrivacy = ({
|
|||
};
|
||||
|
||||
type EditDistributionListPropsType = {
|
||||
onDone: (name: string, viewerUuids: Array<UUIDStringType>) => unknown;
|
||||
onCreateList: (name: string, viewerUuids: Array<UUIDStringType>) => unknown;
|
||||
onViewersUpdated: (viewerUuids: Array<UUIDStringType>) => unknown;
|
||||
page: Page;
|
||||
selectedContacts: Array<ConversationType>;
|
||||
|
@ -592,7 +637,7 @@ export const EditDistributionList = ({
|
|||
candidateConversations,
|
||||
getPreferredBadge,
|
||||
i18n,
|
||||
onDone,
|
||||
onCreateList,
|
||||
onViewersUpdated,
|
||||
page,
|
||||
selectedContacts,
|
||||
|
@ -716,7 +761,7 @@ export const EditDistributionList = ({
|
|||
<Button
|
||||
disabled={!storyName}
|
||||
onClick={() => {
|
||||
onDone(storyName, Array.from(selectedConversationUuids));
|
||||
onCreateList(storyName, Array.from(selectedConversationUuids));
|
||||
setStoryName('');
|
||||
}}
|
||||
variant={ButtonVariant.Primary}
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
getDefaultConversation,
|
||||
getDefaultGroup,
|
||||
} from '../test-both/helpers/getDefaultConversation';
|
||||
import { getFakeDistributionLists } from '../test-both/helpers/getFakeDistributionLists';
|
||||
import { getFakeDistributionListsWithMembers } from '../test-both/helpers/getFakeDistributionLists';
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
@ -25,7 +25,7 @@ export default {
|
|||
defaultValue: Array.from(Array(100), getDefaultConversation),
|
||||
},
|
||||
debouncedMaybeGrabLinkPreview: { action: true },
|
||||
distributionLists: { defaultValue: getFakeDistributionLists() },
|
||||
distributionLists: { defaultValue: getFakeDistributionListsWithMembers() },
|
||||
getPreferredBadge: { action: true },
|
||||
groupConversations: {
|
||||
defaultValue: Array.from(Array(7), getDefaultGroup),
|
||||
|
@ -47,6 +47,7 @@ export default {
|
|||
defaultValue: getDefaultConversation(),
|
||||
},
|
||||
onClose: { action: true },
|
||||
onDeleteList: { action: true },
|
||||
onDistributionListCreated: { action: true },
|
||||
onHideMyStoriesFrom: { action: true },
|
||||
onSend: { action: true },
|
||||
|
|
|
@ -31,7 +31,6 @@ export type PropsType = {
|
|||
i18n: LocalizerType;
|
||||
linkPreview?: LinkPreviewType;
|
||||
onClose: () => unknown;
|
||||
onSelectedStoryList: (memberUuids: Array<string>) => unknown;
|
||||
onSend: (
|
||||
listIds: Array<UUIDStringType>,
|
||||
conversationIds: Array<string>,
|
||||
|
@ -51,12 +50,16 @@ export type PropsType = {
|
|||
| 'groupStories'
|
||||
| 'hasFirstStoryPostExperience'
|
||||
| 'me'
|
||||
| 'onDeleteList'
|
||||
| 'onDistributionListCreated'
|
||||
| 'onHideMyStoriesFrom'
|
||||
| 'onRemoveMember'
|
||||
| 'onRepliesNReactionsChanged'
|
||||
| 'onSelectedStoryList'
|
||||
| 'onViewersUpdated'
|
||||
| 'setMyStoriesToAllSignalConnections'
|
||||
| 'signalConnections'
|
||||
| 'tagGroupsAsNewGroupStory'
|
||||
| 'toggleGroupsForStorySend'
|
||||
| 'toggleSignalConnectionsModal'
|
||||
>;
|
||||
|
||||
|
@ -74,8 +77,11 @@ export const StoryCreator = ({
|
|||
linkPreview,
|
||||
me,
|
||||
onClose,
|
||||
onDeleteList,
|
||||
onDistributionListCreated,
|
||||
onHideMyStoriesFrom,
|
||||
onRemoveMember,
|
||||
onRepliesNReactionsChanged,
|
||||
onSelectedStoryList,
|
||||
onSend,
|
||||
onViewersUpdated,
|
||||
|
@ -84,7 +90,7 @@ export const StoryCreator = ({
|
|||
sendStoryModalOpenStateChanged,
|
||||
setMyStoriesToAllSignalConnections,
|
||||
signalConnections,
|
||||
tagGroupsAsNewGroupStory,
|
||||
toggleGroupsForStorySend,
|
||||
toggleSignalConnectionsModal,
|
||||
}: PropsType): JSX.Element => {
|
||||
const [draftAttachment, setDraftAttachment] = useState<
|
||||
|
@ -141,8 +147,11 @@ export const StoryCreator = ({
|
|||
i18n={i18n}
|
||||
me={me}
|
||||
onClose={() => setDraftAttachment(undefined)}
|
||||
onDeleteList={onDeleteList}
|
||||
onDistributionListCreated={onDistributionListCreated}
|
||||
onHideMyStoriesFrom={onHideMyStoriesFrom}
|
||||
onRemoveMember={onRemoveMember}
|
||||
onRepliesNReactionsChanged={onRepliesNReactionsChanged}
|
||||
onSelectedStoryList={onSelectedStoryList}
|
||||
onSend={(listIds, groupIds) => {
|
||||
onSend(listIds, groupIds, draftAttachment);
|
||||
|
@ -154,7 +163,7 @@ export const StoryCreator = ({
|
|||
setMyStoriesToAllSignalConnections
|
||||
}
|
||||
signalConnections={signalConnections}
|
||||
tagGroupsAsNewGroupStory={tagGroupsAsNewGroupStory}
|
||||
toggleGroupsForStorySend={toggleGroupsForStorySend}
|
||||
toggleSignalConnectionsModal={toggleSignalConnectionsModal}
|
||||
/>
|
||||
)}
|
||||
|
|
|
@ -861,10 +861,10 @@ export const actions = {
|
|||
showConversation,
|
||||
startComposing,
|
||||
startSettingGroupMetadata,
|
||||
tagGroupsAsNewGroupStory,
|
||||
toggleAdmin,
|
||||
toggleConversationInChooseMembers,
|
||||
toggleComposeEditingAvatar,
|
||||
toggleGroupsForStorySend,
|
||||
toggleHideStories,
|
||||
updateConversationModelSharedGroups,
|
||||
verifyConversationsStoppingSend,
|
||||
|
@ -1963,7 +1963,7 @@ function removeMemberFromGroup(
|
|||
};
|
||||
}
|
||||
|
||||
function tagGroupsAsNewGroupStory(
|
||||
function toggleGroupsForStorySend(
|
||||
conversationIds: Array<string>
|
||||
): ThunkAction<void, RootStateType, unknown, NoopActionType> {
|
||||
return async dispatch => {
|
||||
|
@ -1974,7 +1974,9 @@ function tagGroupsAsNewGroupStory(
|
|||
return;
|
||||
}
|
||||
|
||||
conversation.set({ isGroupStorySendReady: true });
|
||||
conversation.set({
|
||||
isGroupStorySendReady: !conversation.get('isGroupStorySendReady'),
|
||||
});
|
||||
await window.Signal.Data.updateConversation(conversation.attributes);
|
||||
})
|
||||
);
|
||||
|
|
|
@ -15,7 +15,7 @@ import {
|
|||
getMe,
|
||||
getNonGroupStories,
|
||||
} from '../selectors/conversations';
|
||||
import { getDistributionLists } from '../selectors/storyDistributionLists';
|
||||
import { getDistributionListsWithMembers } from '../selectors/storyDistributionLists';
|
||||
import { getIntl } from '../selectors/user';
|
||||
import {
|
||||
getInstalledStickerPacks,
|
||||
|
@ -46,17 +46,20 @@ export function SmartStoryCreator({
|
|||
sendStoryMessage,
|
||||
verifyStoryListMembers,
|
||||
} = useStoriesActions();
|
||||
const { tagGroupsAsNewGroupStory } = useConversationsActions();
|
||||
const { toggleGroupsForStorySend } = useConversationsActions();
|
||||
const {
|
||||
allowsRepliesChanged,
|
||||
createDistributionList,
|
||||
deleteDistributionList,
|
||||
hideMyStoriesFrom,
|
||||
removeMemberFromDistributionList,
|
||||
setMyStoriesToAllSignalConnections,
|
||||
updateStoryViewers,
|
||||
} = useStoryDistributionListsActions();
|
||||
const { toggleSignalConnectionsModal } = useGlobalModalActions();
|
||||
|
||||
const candidateConversations = useSelector(getCandidateContactsForNewGroup);
|
||||
const distributionLists = useSelector(getDistributionLists);
|
||||
const distributionLists = useSelector(getDistributionListsWithMembers);
|
||||
const getPreferredBadge = useSelector(getPreferredBadgeSelector);
|
||||
const groupConversations = useSelector(getNonGroupStories);
|
||||
const groupStories = useSelector(getGroupStories);
|
||||
|
@ -83,8 +86,11 @@ export function SmartStoryCreator({
|
|||
linkPreview={linkPreviewForSource(LinkPreviewSourceType.StoryCreator)}
|
||||
me={me}
|
||||
onClose={onClose}
|
||||
onDeleteList={deleteDistributionList}
|
||||
onDistributionListCreated={createDistributionList}
|
||||
onHideMyStoriesFrom={hideMyStoriesFrom}
|
||||
onRemoveMember={removeMemberFromDistributionList}
|
||||
onRepliesNReactionsChanged={allowsRepliesChanged}
|
||||
onSelectedStoryList={verifyStoryListMembers}
|
||||
onSend={sendStoryMessage}
|
||||
onViewersUpdated={updateStoryViewers}
|
||||
|
@ -93,7 +99,7 @@ export function SmartStoryCreator({
|
|||
sendStoryModalOpenStateChanged={sendStoryModalOpenStateChanged}
|
||||
setMyStoriesToAllSignalConnections={setMyStoriesToAllSignalConnections}
|
||||
signalConnections={signalConnections}
|
||||
tagGroupsAsNewGroupStory={tagGroupsAsNewGroupStory}
|
||||
toggleGroupsForStorySend={toggleGroupsForStorySend}
|
||||
toggleSignalConnectionsModal={toggleSignalConnectionsModal}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -4,8 +4,25 @@
|
|||
import casual from 'casual';
|
||||
|
||||
import type { StoryDistributionListDataType } from '../../state/ducks/storyDistributionLists';
|
||||
import type { StoryDistributionListWithMembersDataType } from '../../types/Stories';
|
||||
import { MY_STORIES_ID } from '../../types/Stories';
|
||||
import { UUID } from '../../types/UUID';
|
||||
import { getDefaultConversation } from './getDefaultConversation';
|
||||
|
||||
export function getFakeDistributionListsWithMembers(): Array<StoryDistributionListWithMembersDataType> {
|
||||
return [
|
||||
{
|
||||
...getMyStories(),
|
||||
members: [],
|
||||
},
|
||||
...Array.from(Array(casual.integer(2, 8)), () => ({
|
||||
...getFakeDistributionList(),
|
||||
members: Array.from(Array(casual.integer(3, 12)), () =>
|
||||
getDefaultConversation()
|
||||
),
|
||||
})),
|
||||
];
|
||||
}
|
||||
|
||||
export function getFakeDistributionLists(): Array<StoryDistributionListDataType> {
|
||||
return [
|
||||
|
|
Loading…
Reference in a new issue