Story settings modal copy and design changes
This commit is contained in:
parent
7f0a66847b
commit
5ccfabeb0c
9 changed files with 295 additions and 93 deletions
|
@ -5388,7 +5388,7 @@
|
||||||
"description": "Label of the button on the bottom of the media editor that trigger the add-caption dialog"
|
"description": "Label of the button on the bottom of the media editor that trigger the add-caption dialog"
|
||||||
},
|
},
|
||||||
"MyStories__title": {
|
"MyStories__title": {
|
||||||
"message": "My Stories",
|
"message": "My Story",
|
||||||
"description": "Title for the my stories list"
|
"description": "Title for the my stories list"
|
||||||
},
|
},
|
||||||
"MyStories__story": {
|
"MyStories__story": {
|
||||||
|
@ -5460,7 +5460,7 @@
|
||||||
"description": "Title for the stories list"
|
"description": "Title for the stories list"
|
||||||
},
|
},
|
||||||
"Stories__mine": {
|
"Stories__mine": {
|
||||||
"message": "My Stories",
|
"message": "My Story",
|
||||||
"description": "Label for your stories"
|
"description": "Label for your stories"
|
||||||
},
|
},
|
||||||
"Stories__add": {
|
"Stories__add": {
|
||||||
|
@ -5515,6 +5515,10 @@
|
||||||
"message": "Story settings",
|
"message": "Story settings",
|
||||||
"description": "Title for the story settings modal"
|
"description": "Title for the story settings modal"
|
||||||
},
|
},
|
||||||
|
"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.",
|
||||||
|
"description": "Description for story settings modal"
|
||||||
|
},
|
||||||
"StoriesSettings__new-list": {
|
"StoriesSettings__new-list": {
|
||||||
"message": "New custom story",
|
"message": "New custom story",
|
||||||
"description": "Label to create a new custom distribution list"
|
"description": "Label to create a new custom distribution list"
|
||||||
|
@ -5600,7 +5604,7 @@
|
||||||
"description": "Description of button StoriesSettings__mine__all--label"
|
"description": "Description of button StoriesSettings__mine__all--label"
|
||||||
},
|
},
|
||||||
"StoriesSettings__mine__exclude--label": {
|
"StoriesSettings__mine__exclude--label": {
|
||||||
"message": "All Signal connections except...",
|
"message": "All except...",
|
||||||
"description": "Input label to create a block list"
|
"description": "Input label to create a block list"
|
||||||
},
|
},
|
||||||
"StoriesSettings__mine__exclude--description": {
|
"StoriesSettings__mine__exclude--description": {
|
||||||
|
@ -5704,8 +5708,8 @@
|
||||||
"description": "Modal title when choosing groups"
|
"description": "Modal title when choosing groups"
|
||||||
},
|
},
|
||||||
"SendStoryModal__my-stories-privacy": {
|
"SendStoryModal__my-stories-privacy": {
|
||||||
"message": "My stories privacy",
|
"message": "My Story privacy",
|
||||||
"description": "Modal title for setting privacy for My Stories"
|
"description": "Modal title for setting privacy for My Story"
|
||||||
},
|
},
|
||||||
"SendStoryModal__privacy-disclaimer": {
|
"SendStoryModal__privacy-disclaimer": {
|
||||||
"message": "Choose which Signal connections can view your story. You can always change this in privacy settings. $learnMore$",
|
"message": "Choose which Signal connections can view your story. You can always change this in privacy settings. $learnMore$",
|
||||||
|
|
|
@ -74,7 +74,7 @@
|
||||||
|
|
||||||
@mixin font-subtitle {
|
@mixin font-subtitle {
|
||||||
@include font-family;
|
@include font-family;
|
||||||
font-size: 11px;
|
font-size: 12px;
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
letter-spacing: 0;
|
letter-spacing: 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,9 +74,9 @@
|
||||||
@include font-body-1;
|
@include font-body-1;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 52px;
|
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
padding: 8px 0;
|
||||||
|
|
||||||
&--no-pointer {
|
&--no-pointer {
|
||||||
cursor: inherit;
|
cursor: inherit;
|
||||||
|
@ -144,9 +144,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&__divider {
|
&__divider {
|
||||||
border-color: $color-gray-65;
|
|
||||||
border-style: solid;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
border: 0 solid $color-gray-65;
|
||||||
|
border-top-width: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__input__container {
|
&__input__container {
|
||||||
|
@ -165,12 +165,51 @@
|
||||||
margin-top: 32px;
|
margin-top: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__description {
|
||||||
|
@include font-subtitle;
|
||||||
|
color: $color-gray-25;
|
||||||
|
margin-top: 0px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__listHeader {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__listHeader__title {
|
||||||
|
flex: 1;
|
||||||
|
@include font-body-1-bold;
|
||||||
|
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;
|
||||||
color: $color-accent-red;
|
color: $color-accent-red;
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 52px;
|
padding: 8px 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
|
@ -186,7 +225,22 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&__checkbox {
|
&__checkbox {
|
||||||
margin: 18px 0;
|
margin: 14px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__checkbox-container {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__checkbox-label {
|
||||||
|
flex: 1;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__checkbox-description {
|
||||||
|
color: $color-gray-25;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__conversation-list {
|
&__conversation-list {
|
||||||
|
@ -204,4 +258,15 @@
|
||||||
color: $color-gray-05;
|
color: $color-gray-05;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__stories-off-container {
|
||||||
|
display: flex;
|
||||||
|
gap: 16;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__stories-off-text {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ export type PropsType = {
|
||||||
id: string;
|
id: string;
|
||||||
checkboxNode: JSX.Element;
|
checkboxNode: JSX.Element;
|
||||||
labelNode: JSX.Element;
|
labelNode: JSX.Element;
|
||||||
|
checked?: boolean;
|
||||||
}) => JSX.Element;
|
}) => JSX.Element;
|
||||||
description?: string;
|
description?: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
@ -65,7 +66,7 @@ export const Checkbox = ({
|
||||||
<div className={getClassName('')}>
|
<div className={getClassName('')}>
|
||||||
<div className={getClassName('__container')}>
|
<div className={getClassName('__container')}>
|
||||||
{children ? (
|
{children ? (
|
||||||
children({ id, checkboxNode, labelNode })
|
children({ id, checkboxNode, labelNode, checked })
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
{checkboxNode}
|
{checkboxNode}
|
||||||
|
|
|
@ -113,7 +113,7 @@ function getKeyForMyStoryType(list: StoryDistributionListWithMembersDataType) {
|
||||||
return 'StoriesSettings__mine__all--label';
|
return 'StoriesSettings__mine__all--label';
|
||||||
}
|
}
|
||||||
|
|
||||||
function getListViewers(
|
export function getListViewers(
|
||||||
list: StoryDistributionListWithMembersDataType,
|
list: StoryDistributionListWithMembersDataType,
|
||||||
i18n: LocalizerType,
|
i18n: LocalizerType,
|
||||||
signalConnections: Array<ConversationType>
|
signalConnections: Array<ConversationType>
|
||||||
|
|
|
@ -7,7 +7,10 @@ import React from 'react';
|
||||||
import type { PropsType } from './StoriesSettingsModal';
|
import type { PropsType } from './StoriesSettingsModal';
|
||||||
import enMessages from '../../_locales/en/messages.json';
|
import enMessages from '../../_locales/en/messages.json';
|
||||||
import { StoriesSettingsModal } from './StoriesSettingsModal';
|
import { StoriesSettingsModal } from './StoriesSettingsModal';
|
||||||
import { getDefaultConversation } from '../test-both/helpers/getDefaultConversation';
|
import {
|
||||||
|
getDefaultConversation,
|
||||||
|
getDefaultGroup,
|
||||||
|
} from '../test-both/helpers/getDefaultConversation';
|
||||||
import { setupI18n } from '../util/setupI18n';
|
import { setupI18n } from '../util/setupI18n';
|
||||||
import {
|
import {
|
||||||
getMyStories,
|
getMyStories,
|
||||||
|
@ -23,9 +26,15 @@ export default {
|
||||||
candidateConversations: {
|
candidateConversations: {
|
||||||
defaultValue: Array.from(Array(100), () => getDefaultConversation()),
|
defaultValue: Array.from(Array(100), () => getDefaultConversation()),
|
||||||
},
|
},
|
||||||
|
signalConnections: {
|
||||||
|
defaultValue: Array.from(Array(42), getDefaultConversation),
|
||||||
|
},
|
||||||
distributionLists: {
|
distributionLists: {
|
||||||
defaultValue: [],
|
defaultValue: [],
|
||||||
},
|
},
|
||||||
|
groupStories: {
|
||||||
|
defaultValue: Array.from(Array(2), getDefaultGroup),
|
||||||
|
},
|
||||||
getPreferredBadge: { action: true },
|
getPreferredBadge: { action: true },
|
||||||
hideStoriesSettings: { action: true },
|
hideStoriesSettings: { action: true },
|
||||||
i18n: {
|
i18n: {
|
||||||
|
@ -43,6 +52,7 @@ export default {
|
||||||
onViewersUpdated: { action: true },
|
onViewersUpdated: { action: true },
|
||||||
setMyStoriesToAllSignalConnections: { action: true },
|
setMyStoriesToAllSignalConnections: { action: true },
|
||||||
toggleSignalConnectionsModal: { action: true },
|
toggleSignalConnectionsModal: { action: true },
|
||||||
|
setStoriesDisabled: { action: true },
|
||||||
},
|
},
|
||||||
} as Meta;
|
} as Meta;
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import type { MeasuredComponentProps } from 'react-measure';
|
import type { MeasuredComponentProps } from 'react-measure';
|
||||||
|
import type { ReactNode } from 'react';
|
||||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import Measure from 'react-measure';
|
import Measure from 'react-measure';
|
||||||
import { noop } from 'lodash';
|
import { noop } from 'lodash';
|
||||||
|
@ -36,10 +37,12 @@ import {
|
||||||
asyncShouldNeverBeCalled,
|
asyncShouldNeverBeCalled,
|
||||||
} from '../util/shouldNeverBeCalled';
|
} from '../util/shouldNeverBeCalled';
|
||||||
import { useConfirmDiscard } from '../hooks/useConfirmDiscard';
|
import { useConfirmDiscard } from '../hooks/useConfirmDiscard';
|
||||||
|
import { getListViewers } from './SendStoryModal';
|
||||||
|
|
||||||
export type PropsType = {
|
export type PropsType = {
|
||||||
candidateConversations: Array<ConversationType>;
|
candidateConversations: Array<ConversationType>;
|
||||||
distributionLists: Array<StoryDistributionListWithMembersDataType>;
|
distributionLists: Array<StoryDistributionListWithMembersDataType>;
|
||||||
|
signalConnections: Array<ConversationType>;
|
||||||
getPreferredBadge: PreferredBadgeSelectorType;
|
getPreferredBadge: PreferredBadgeSelectorType;
|
||||||
hideStoriesSettings: () => unknown;
|
hideStoriesSettings: () => unknown;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
|
@ -62,6 +65,8 @@ export type PropsType = {
|
||||||
setMyStoriesToAllSignalConnections: () => unknown;
|
setMyStoriesToAllSignalConnections: () => unknown;
|
||||||
storyViewReceiptsEnabled: boolean;
|
storyViewReceiptsEnabled: boolean;
|
||||||
toggleSignalConnectionsModal: () => unknown;
|
toggleSignalConnectionsModal: () => unknown;
|
||||||
|
toggleStoriesView: () => void;
|
||||||
|
setStoriesDisabled: (value: boolean) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export enum Page {
|
export enum Page {
|
||||||
|
@ -89,9 +94,65 @@ const modalCommonProps: Pick<ModalPropsType, 'hasXButton' | 'moduleClassName'> =
|
||||||
moduleClassName: 'StoriesSettingsModal__modal',
|
moduleClassName: 'StoriesSettingsModal__modal',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type DistributionListItemProps = {
|
||||||
|
i18n: LocalizerType;
|
||||||
|
distributionList: StoryDistributionListWithMembersDataType;
|
||||||
|
me: ConversationType;
|
||||||
|
signalConnections: Array<ConversationType>;
|
||||||
|
onSelectItemToEdit(id: UUIDStringType): void;
|
||||||
|
};
|
||||||
|
|
||||||
|
function DistributionListItem({
|
||||||
|
i18n,
|
||||||
|
distributionList,
|
||||||
|
me,
|
||||||
|
signalConnections,
|
||||||
|
onSelectItemToEdit,
|
||||||
|
}: DistributionListItemProps) {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
className="StoriesSettingsModal__list"
|
||||||
|
onClick={() => {
|
||||||
|
onSelectItemToEdit(distributionList.id);
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span className="StoriesSettingsModal__list__left">
|
||||||
|
{distributionList.id === MY_STORIES_ID ? (
|
||||||
|
<Avatar
|
||||||
|
acceptedMessageRequest={me.acceptedMessageRequest}
|
||||||
|
avatarPath={me.avatarPath}
|
||||||
|
badge={undefined}
|
||||||
|
color={me.color}
|
||||||
|
conversationType={me.type}
|
||||||
|
i18n={i18n}
|
||||||
|
isMe
|
||||||
|
sharedGroupNames={me.sharedGroupNames}
|
||||||
|
size={AvatarSize.THIRTY_SIX}
|
||||||
|
title={me.title}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<span className="StoriesSettingsModal__list__avatar--private" />
|
||||||
|
)}
|
||||||
|
<span className="StoriesSettingsModal__list__title">
|
||||||
|
<StoryDistributionListName
|
||||||
|
i18n={i18n}
|
||||||
|
id={distributionList.id}
|
||||||
|
name={distributionList.name}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<span className="StoriesSettingsModal__list__viewers">
|
||||||
|
{getListViewers(distributionList, i18n, signalConnections)}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export const StoriesSettingsModal = ({
|
export const StoriesSettingsModal = ({
|
||||||
candidateConversations,
|
candidateConversations,
|
||||||
distributionLists,
|
distributionLists,
|
||||||
|
signalConnections,
|
||||||
getPreferredBadge,
|
getPreferredBadge,
|
||||||
hideStoriesSettings,
|
hideStoriesSettings,
|
||||||
i18n,
|
i18n,
|
||||||
|
@ -105,6 +166,8 @@ export const StoriesSettingsModal = ({
|
||||||
setMyStoriesToAllSignalConnections,
|
setMyStoriesToAllSignalConnections,
|
||||||
storyViewReceiptsEnabled,
|
storyViewReceiptsEnabled,
|
||||||
toggleSignalConnectionsModal,
|
toggleSignalConnectionsModal,
|
||||||
|
toggleStoriesView,
|
||||||
|
setStoriesDisabled,
|
||||||
}: PropsType): JSX.Element => {
|
}: PropsType): JSX.Element => {
|
||||||
const [confirmDiscardModal, confirmDiscardIf] = useConfirmDiscard(i18n);
|
const [confirmDiscardModal, confirmDiscardIf] = useConfirmDiscard(i18n);
|
||||||
|
|
||||||
|
@ -200,10 +263,6 @@ export const StoriesSettingsModal = ({
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
const privateStories = distributionLists.filter(
|
|
||||||
list => list.id !== MY_STORIES_ID
|
|
||||||
);
|
|
||||||
|
|
||||||
modal = onClose => (
|
modal = onClose => (
|
||||||
<ModalPage
|
<ModalPage
|
||||||
modalName="StoriesSettingsModal__list"
|
modalName="StoriesSettingsModal__list"
|
||||||
|
@ -212,72 +271,36 @@ export const StoriesSettingsModal = ({
|
||||||
title={i18n('StoriesSettings__title')}
|
title={i18n('StoriesSettings__title')}
|
||||||
{...modalCommonProps}
|
{...modalCommonProps}
|
||||||
>
|
>
|
||||||
<button
|
<p className="StoriesSettingsModal__description">
|
||||||
className="StoriesSettingsModal__list"
|
{i18n('icu:StoriesSettings__description')}
|
||||||
onClick={() => {
|
</p>
|
||||||
setListToEditId(MY_STORIES_ID);
|
|
||||||
}}
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
<span className="StoriesSettingsModal__list__left">
|
|
||||||
<Avatar
|
|
||||||
acceptedMessageRequest={me.acceptedMessageRequest}
|
|
||||||
avatarPath={me.avatarPath}
|
|
||||||
badge={getPreferredBadge(me.badges)}
|
|
||||||
color={me.color}
|
|
||||||
conversationType={me.type}
|
|
||||||
i18n={i18n}
|
|
||||||
isMe
|
|
||||||
sharedGroupNames={me.sharedGroupNames}
|
|
||||||
size={AvatarSize.THIRTY_SIX}
|
|
||||||
theme={ThemeType.dark}
|
|
||||||
title={me.title}
|
|
||||||
/>
|
|
||||||
<span className="StoriesSettingsModal__list__title">
|
|
||||||
{i18n('Stories__mine')}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span className="StoriesSettingsModal__list__viewers" />
|
<div className="StoriesSettingsModal__listHeader">
|
||||||
</button>
|
<h2 className="StoriesSettingsModal__listHeader__title">
|
||||||
|
{i18n('Stories__mine')}
|
||||||
<button
|
</h2>
|
||||||
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>
|
|
||||||
{privateStories.map(list => (
|
|
||||||
<button
|
<button
|
||||||
className="StoriesSettingsModal__list"
|
|
||||||
key={list.id}
|
|
||||||
onClick={() => {
|
|
||||||
setListToEditId(list.id);
|
|
||||||
}}
|
|
||||||
type="button"
|
type="button"
|
||||||
|
className="StoriesSettingsModal__listHeader__button"
|
||||||
|
onClick={() => {
|
||||||
|
setPage(Page.ChooseViewers);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<span className="StoriesSettingsModal__list__left">
|
{i18n('StoriesSettings__new-list')}
|
||||||
<span className="StoriesSettingsModal__list__avatar--custom" />
|
|
||||||
<span className="StoriesSettingsModal__list__title">
|
|
||||||
{list.name}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span className="StoriesSettingsModal__list__viewers">
|
|
||||||
{i18n('icu:StoriesSettings__viewers', {
|
|
||||||
count: list.members.length,
|
|
||||||
})}
|
|
||||||
</span>
|
|
||||||
</button>
|
</button>
|
||||||
))}
|
</div>
|
||||||
|
|
||||||
|
{distributionLists.map(distributionList => {
|
||||||
|
return (
|
||||||
|
<DistributionListItem
|
||||||
|
i18n={i18n}
|
||||||
|
me={me}
|
||||||
|
distributionList={distributionList}
|
||||||
|
signalConnections={signalConnections}
|
||||||
|
onSelectItemToEdit={setListToEditId}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
|
||||||
<hr className="StoriesSettingsModal__divider" />
|
<hr className="StoriesSettingsModal__divider" />
|
||||||
|
|
||||||
|
@ -290,6 +313,22 @@ export const StoriesSettingsModal = ({
|
||||||
name="view-receipts"
|
name="view-receipts"
|
||||||
onChange={noop}
|
onChange={noop}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<div className="StoriesSettingsModal__stories-off-container">
|
||||||
|
<p className="StoriesSettingsModal__stories-off-text">
|
||||||
|
{i18n('Preferences__turn-stories-off--body')}
|
||||||
|
</p>
|
||||||
|
<Button
|
||||||
|
className="Preferences__stories-off"
|
||||||
|
onClick={async () => {
|
||||||
|
setStoriesDisabled(true);
|
||||||
|
toggleStoriesView();
|
||||||
|
onClose();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{i18n('Preferences__turn-stories-off')}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</ModalPage>
|
</ModalPage>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -555,6 +594,30 @@ export const DistributionListSettingsModal = ({
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type CheckboxRenderProps = {
|
||||||
|
checkboxNode: ReactNode;
|
||||||
|
labelNode: ReactNode;
|
||||||
|
descriptionNode: ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
function CheckboxRender({
|
||||||
|
checkboxNode,
|
||||||
|
labelNode,
|
||||||
|
descriptionNode,
|
||||||
|
}: CheckboxRenderProps) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{checkboxNode}
|
||||||
|
<div className="StoriesSettingsModal__checkbox-container">
|
||||||
|
<div className="StoriesSettingsModal__checkbox-label">{labelNode}</div>
|
||||||
|
<div className="StoriesSettingsModal__checkbox-description">
|
||||||
|
{descriptionNode}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
type EditMyStoriesPrivacyPropsType = {
|
type EditMyStoriesPrivacyPropsType = {
|
||||||
hasDisclaimerAbove?: boolean;
|
hasDisclaimerAbove?: boolean;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
|
@ -605,7 +668,6 @@ export const EditMyStoriesPrivacy = ({
|
||||||
|
|
||||||
<Checkbox
|
<Checkbox
|
||||||
checked={!myStories.members.length}
|
checked={!myStories.members.length}
|
||||||
description={i18n('StoriesSettings__mine__all--description')}
|
|
||||||
isRadio
|
isRadio
|
||||||
label={i18n('StoriesSettings__mine__all--label')}
|
label={i18n('StoriesSettings__mine__all--label')}
|
||||||
moduleClassName="StoriesSettingsModal__checkbox"
|
moduleClassName="StoriesSettingsModal__checkbox"
|
||||||
|
@ -613,13 +675,28 @@ export const EditMyStoriesPrivacy = ({
|
||||||
onChange={() => {
|
onChange={() => {
|
||||||
setMyStoriesToAllSignalConnections();
|
setMyStoriesToAllSignalConnections();
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
|
{({ checkboxNode, labelNode, checked }) => {
|
||||||
|
return (
|
||||||
|
<CheckboxRender
|
||||||
|
checkboxNode={checkboxNode}
|
||||||
|
labelNode={labelNode}
|
||||||
|
descriptionNode={
|
||||||
|
checked && (
|
||||||
|
<>
|
||||||
|
{i18n('icu:StoriesSettings__viewers', {
|
||||||
|
count: myStories.members.length,
|
||||||
|
})}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</Checkbox>
|
||||||
|
|
||||||
<Checkbox
|
<Checkbox
|
||||||
checked={myStories.isBlockList && myStories.members.length > 0}
|
checked={myStories.isBlockList && myStories.members.length > 0}
|
||||||
description={i18n('StoriesSettings__mine__exclude--description', [
|
|
||||||
myStories.isBlockList ? String(myStories.members.length) : '0',
|
|
||||||
])}
|
|
||||||
isRadio
|
isRadio
|
||||||
label={i18n('StoriesSettings__mine__exclude--label')}
|
label={i18n('StoriesSettings__mine__exclude--label')}
|
||||||
moduleClassName="StoriesSettingsModal__checkbox"
|
moduleClassName="StoriesSettingsModal__checkbox"
|
||||||
|
@ -631,17 +708,28 @@ export const EditMyStoriesPrivacy = ({
|
||||||
}
|
}
|
||||||
onClickExclude();
|
onClickExclude();
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
|
{({ checkboxNode, labelNode, checked }) => {
|
||||||
|
return (
|
||||||
|
<CheckboxRender
|
||||||
|
checkboxNode={checkboxNode}
|
||||||
|
labelNode={labelNode}
|
||||||
|
descriptionNode={
|
||||||
|
checked && (
|
||||||
|
<>
|
||||||
|
{i18n('icu:StoriesSettings__viewers', {
|
||||||
|
count: myStories.members.length,
|
||||||
|
})}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</Checkbox>
|
||||||
|
|
||||||
<Checkbox
|
<Checkbox
|
||||||
checked={!myStories.isBlockList && myStories.members.length > 0}
|
checked={!myStories.isBlockList && myStories.members.length > 0}
|
||||||
description={
|
|
||||||
!myStories.isBlockList && myStories.members.length
|
|
||||||
? i18n('StoriesSettings__mine__only--description--people', [
|
|
||||||
String(myStories.members.length),
|
|
||||||
])
|
|
||||||
: i18n('StoriesSettings__mine__only--description')
|
|
||||||
}
|
|
||||||
isRadio
|
isRadio
|
||||||
label={i18n('StoriesSettings__mine__only--label')}
|
label={i18n('StoriesSettings__mine__only--label')}
|
||||||
moduleClassName="StoriesSettingsModal__checkbox"
|
moduleClassName="StoriesSettingsModal__checkbox"
|
||||||
|
@ -653,7 +741,25 @@ export const EditMyStoriesPrivacy = ({
|
||||||
}
|
}
|
||||||
onClickOnlyShareWith();
|
onClickOnlyShareWith();
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
|
{({ checkboxNode, labelNode, checked }) => {
|
||||||
|
return (
|
||||||
|
<CheckboxRender
|
||||||
|
checkboxNode={checkboxNode}
|
||||||
|
labelNode={labelNode}
|
||||||
|
descriptionNode={
|
||||||
|
checked && (
|
||||||
|
<>
|
||||||
|
{i18n('icu:StoriesSettings__viewers', {
|
||||||
|
count: myStories.members.length,
|
||||||
|
})}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</Checkbox>
|
||||||
|
|
||||||
{!hasDisclaimerAbove && disclaimerElement}
|
{!hasDisclaimerAbove && disclaimerElement}
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -1130,6 +1130,14 @@ const viewStory: ViewStoryActionCreatorType = (
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function setStoriesDisabled(
|
||||||
|
value: boolean
|
||||||
|
): ThunkAction<void, RootStateType, unknown, never> {
|
||||||
|
return async () => {
|
||||||
|
await window.Events.setHasStoriesDisabled(value);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export const actions = {
|
export const actions = {
|
||||||
deleteStoryForEveryone,
|
deleteStoryForEveryone,
|
||||||
loadStoryReplies,
|
loadStoryReplies,
|
||||||
|
@ -1145,6 +1153,7 @@ export const actions = {
|
||||||
verifyStoryListMembers,
|
verifyStoryListMembers,
|
||||||
viewUserStories,
|
viewUserStories,
|
||||||
viewStory,
|
viewStory,
|
||||||
|
setStoriesDisabled,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useStoriesActions = (): typeof actions => useBoundActions(actions);
|
export const useStoriesActions = (): typeof actions => useBoundActions(actions);
|
||||||
|
|
|
@ -8,6 +8,7 @@ import type { LocalizerType } from '../../types/Util';
|
||||||
import type { StateType } from '../reducer';
|
import type { StateType } from '../reducer';
|
||||||
import { StoriesSettingsModal } from '../../components/StoriesSettingsModal';
|
import { StoriesSettingsModal } from '../../components/StoriesSettingsModal';
|
||||||
import {
|
import {
|
||||||
|
getAllSignalConnections,
|
||||||
getCandidateContactsForNewGroup,
|
getCandidateContactsForNewGroup,
|
||||||
getMe,
|
getMe,
|
||||||
} from '../selectors/conversations';
|
} from '../selectors/conversations';
|
||||||
|
@ -17,8 +18,10 @@ import { getPreferredBadgeSelector } from '../selectors/badges';
|
||||||
import { getHasStoryViewReceiptSetting } from '../selectors/items';
|
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';
|
||||||
|
|
||||||
export function SmartStoriesSettingsModal(): JSX.Element | null {
|
export function SmartStoriesSettingsModal(): JSX.Element | null {
|
||||||
|
const { toggleStoriesView, setStoriesDisabled } = useStoriesActions();
|
||||||
const { hideStoriesSettings, toggleSignalConnectionsModal } =
|
const { hideStoriesSettings, toggleSignalConnectionsModal } =
|
||||||
useGlobalModalActions();
|
useGlobalModalActions();
|
||||||
const {
|
const {
|
||||||
|
@ -30,6 +33,7 @@ export function SmartStoriesSettingsModal(): JSX.Element | null {
|
||||||
setMyStoriesToAllSignalConnections,
|
setMyStoriesToAllSignalConnections,
|
||||||
updateStoryViewers,
|
updateStoryViewers,
|
||||||
} = useStoryDistributionListsActions();
|
} = useStoryDistributionListsActions();
|
||||||
|
const signalConnections = useSelector(getAllSignalConnections);
|
||||||
|
|
||||||
const getPreferredBadge = useSelector(getPreferredBadgeSelector);
|
const getPreferredBadge = useSelector(getPreferredBadgeSelector);
|
||||||
const storyViewReceiptsEnabled = useSelector(getHasStoryViewReceiptSetting);
|
const storyViewReceiptsEnabled = useSelector(getHasStoryViewReceiptSetting);
|
||||||
|
@ -43,6 +47,7 @@ export function SmartStoriesSettingsModal(): JSX.Element | null {
|
||||||
<StoriesSettingsModal
|
<StoriesSettingsModal
|
||||||
candidateConversations={candidateConversations}
|
candidateConversations={candidateConversations}
|
||||||
distributionLists={distributionLists}
|
distributionLists={distributionLists}
|
||||||
|
signalConnections={signalConnections}
|
||||||
hideStoriesSettings={hideStoriesSettings}
|
hideStoriesSettings={hideStoriesSettings}
|
||||||
getPreferredBadge={getPreferredBadge}
|
getPreferredBadge={getPreferredBadge}
|
||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
|
@ -56,6 +61,8 @@ export function SmartStoriesSettingsModal(): JSX.Element | null {
|
||||||
setMyStoriesToAllSignalConnections={setMyStoriesToAllSignalConnections}
|
setMyStoriesToAllSignalConnections={setMyStoriesToAllSignalConnections}
|
||||||
storyViewReceiptsEnabled={storyViewReceiptsEnabled}
|
storyViewReceiptsEnabled={storyViewReceiptsEnabled}
|
||||||
toggleSignalConnectionsModal={toggleSignalConnectionsModal}
|
toggleSignalConnectionsModal={toggleSignalConnectionsModal}
|
||||||
|
toggleStoriesView={toggleStoriesView}
|
||||||
|
setStoriesDisabled={setStoriesDisabled}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue