Do not allow replies to self story
This commit is contained in:
parent
d221895b3a
commit
b04fbb6d8d
7 changed files with 70 additions and 17 deletions
|
@ -5591,6 +5591,10 @@
|
|||
"message": "No replies yet",
|
||||
"description": "Placeholder text for when there are no replies"
|
||||
},
|
||||
"StoryViewsNRepliesModal__no-views": {
|
||||
"message": "No views yet",
|
||||
"description": "Placeholder text for when there are no views"
|
||||
},
|
||||
"StoryViewsNRepliesModal__tab--views": {
|
||||
"message": "Views",
|
||||
"description": "Title for views tab"
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
display: flex;
|
||||
flex: 1;
|
||||
justify-content: center;
|
||||
padding: 80px 0;
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -424,8 +424,10 @@ export const StoryViewer = ({
|
|||
muteClassName = 'StoryViewer__soundless';
|
||||
}
|
||||
|
||||
const isSent = Boolean(sendState);
|
||||
|
||||
const contextMenuOptions: ReadonlyArray<ContextMenuOptionType<unknown>> =
|
||||
sendState
|
||||
isSent
|
||||
? [
|
||||
{
|
||||
icon: 'StoryListItem__icon--info',
|
||||
|
@ -654,7 +656,7 @@ export const StoryViewer = ({
|
|||
))}
|
||||
</div>
|
||||
<div className="StoryViewer__actions">
|
||||
{(canReply || sendState) && (
|
||||
{(canReply || isSent) && (
|
||||
<button
|
||||
className="StoryViewer__reply"
|
||||
onClick={() => setHasStoryViewsNRepliesModal(true)}
|
||||
|
@ -662,12 +664,12 @@ export const StoryViewer = ({
|
|||
type="button"
|
||||
>
|
||||
<>
|
||||
{sendState || replyCount > 0 ? (
|
||||
{isSent || replyCount > 0 ? (
|
||||
<span className="StoryViewer__reply__chevron">
|
||||
{sendState && !hasReadReceiptSetting && !replyCount && (
|
||||
{isSent && !hasReadReceiptSetting && !replyCount && (
|
||||
<>{i18n('StoryViewer__views-off')}</>
|
||||
)}
|
||||
{sendState &&
|
||||
{isSent &&
|
||||
hasReadReceiptSetting &&
|
||||
(viewCount === 1 ? (
|
||||
<Intl
|
||||
|
@ -682,7 +684,7 @@ export const StoryViewer = ({
|
|||
components={[<strong>{viewCount}</strong>]}
|
||||
/>
|
||||
))}
|
||||
{(sendState || viewCount > 0) && replyCount > 0 && ' '}
|
||||
{(isSent || viewCount > 0) && replyCount > 0 && ' '}
|
||||
{replyCount > 0 &&
|
||||
(replyCount === 1 ? (
|
||||
<Intl
|
||||
|
@ -699,7 +701,7 @@ export const StoryViewer = ({
|
|||
))}
|
||||
</span>
|
||||
) : null}
|
||||
{!sendState && !replyCount && (
|
||||
{!isSent && !replyCount && (
|
||||
<span className="StoryViewer__reply__arrow">
|
||||
{isGroupStory
|
||||
? i18n('StoryViewer__reply-group')
|
||||
|
@ -758,6 +760,7 @@ export const StoryViewer = ({
|
|||
canReply={Boolean(canReply)}
|
||||
getPreferredBadge={getPreferredBadge}
|
||||
hasReadReceiptSetting={hasReadReceiptSetting}
|
||||
hasViewsCapability={isSent}
|
||||
i18n={i18n}
|
||||
isGroupStory={isGroupStory}
|
||||
onClose={() => setHasStoryViewsNRepliesModal(false)}
|
||||
|
|
|
@ -31,6 +31,9 @@ export default {
|
|||
hasReadReceiptSetting: {
|
||||
defaultValue: true,
|
||||
},
|
||||
hasViewsCapability: {
|
||||
defaultValue: false,
|
||||
},
|
||||
i18n: {
|
||||
defaultValue: i18n,
|
||||
},
|
||||
|
@ -168,10 +171,20 @@ CanReply.storyName = 'Can reply';
|
|||
|
||||
export const ViewsOnly = Template.bind({});
|
||||
ViewsOnly.args = {
|
||||
canReply: false,
|
||||
hasViewsCapability: true,
|
||||
views: getViewsAndReplies().views,
|
||||
};
|
||||
ViewsOnly.storyName = 'Views only';
|
||||
|
||||
export const NoViews = Template.bind({});
|
||||
NoViews.args = {
|
||||
canReply: false,
|
||||
hasViewsCapability: true,
|
||||
views: [],
|
||||
};
|
||||
NoViews.storyName = 'No views';
|
||||
|
||||
export const InAGroupNoReplies = Template.bind({});
|
||||
InAGroupNoReplies.args = {
|
||||
isGroupStory: true,
|
||||
|
@ -182,6 +195,7 @@ export const InAGroup = Template.bind({});
|
|||
{
|
||||
const { views, replies } = getViewsAndReplies();
|
||||
InAGroup.args = {
|
||||
hasViewsCapability: true,
|
||||
isGroupStory: true,
|
||||
replies,
|
||||
views,
|
||||
|
@ -210,6 +224,7 @@ export const ReadReceiptsTurnedOff = Template.bind({});
|
|||
ReadReceiptsTurnedOff.args = {
|
||||
canReply: false,
|
||||
hasReadReceiptSetting: false,
|
||||
hasViewsCapability: true,
|
||||
views: getViewsAndReplies().views,
|
||||
};
|
||||
ReadReceiptsTurnedOff.storyName = 'Read receipts turned off';
|
||||
|
@ -219,6 +234,7 @@ export const GroupReadReceiptsOff = Template.bind({});
|
|||
const { views, replies } = getViewsAndReplies();
|
||||
GroupReadReceiptsOff.args = {
|
||||
hasReadReceiptSetting: false,
|
||||
hasViewsCapability: true,
|
||||
isGroupStory: true,
|
||||
replies,
|
||||
views,
|
||||
|
|
|
@ -88,6 +88,7 @@ export type PropsType = {
|
|||
canReply: boolean;
|
||||
getPreferredBadge: PreferredBadgeSelectorType;
|
||||
hasReadReceiptSetting: boolean;
|
||||
hasViewsCapability: boolean;
|
||||
i18n: LocalizerType;
|
||||
isGroupStory?: boolean;
|
||||
onClose: () => unknown;
|
||||
|
@ -115,6 +116,7 @@ export const StoryViewsNRepliesModal = ({
|
|||
canReply,
|
||||
getPreferredBadge,
|
||||
hasReadReceiptSetting,
|
||||
hasViewsCapability,
|
||||
i18n,
|
||||
isGroupStory,
|
||||
onClose,
|
||||
|
@ -353,7 +355,7 @@ export const StoryViewsNRepliesModal = ({
|
|||
}
|
||||
|
||||
let viewsElement: JSX.Element | undefined;
|
||||
if (!hasReadReceiptSetting) {
|
||||
if (hasViewsCapability && !hasReadReceiptSetting) {
|
||||
viewsElement = (
|
||||
<div className="StoryViewsNRepliesModal__read-receipts-off">
|
||||
{i18n('StoryViewsNRepliesModal__read-receipts-off')}
|
||||
|
@ -397,10 +399,16 @@ export const StoryViewsNRepliesModal = ({
|
|||
))}
|
||||
</div>
|
||||
);
|
||||
} else if (hasViewsCapability) {
|
||||
viewsElement = (
|
||||
<div className="StoryViewsNRepliesModal__replies--none">
|
||||
{i18n('StoryViewsNRepliesModal__no-views')}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const tabsElement =
|
||||
views.length && replies.length ? (
|
||||
viewsElement && repliesElement ? (
|
||||
<Tabs
|
||||
initialSelectedTab={Tab.Views}
|
||||
moduleClassName="StoryViewsNRepliesModal__tabs"
|
||||
|
|
|
@ -1667,7 +1667,9 @@ function canReplyOrReact(
|
|||
}
|
||||
|
||||
if (isStory(message)) {
|
||||
return Boolean(message.canReplyToStory);
|
||||
return (
|
||||
Boolean(message.canReplyToStory) && conversation.id !== ourConversationId
|
||||
);
|
||||
}
|
||||
|
||||
// Fail safe.
|
||||
|
|
|
@ -29,6 +29,7 @@ import {
|
|||
getConversationSelector,
|
||||
getMe,
|
||||
} from './conversations';
|
||||
import { getUserConversationId } from './user';
|
||||
import { getDistributionListSelector } from './storyDistributionLists';
|
||||
import { getStoriesEnabled } from './items';
|
||||
import { calculateExpirationTimestamp } from '../../util/expirationTimer';
|
||||
|
@ -126,6 +127,7 @@ function getAvatarData(
|
|||
|
||||
export function getStoryView(
|
||||
conversationSelector: GetConversationByIdType,
|
||||
ourConversationId: string | undefined,
|
||||
story: StoryDataType
|
||||
): StoryViewType {
|
||||
const sender = pick(conversationSelector(story.sourceUuid || story.source), [
|
||||
|
@ -176,7 +178,7 @@ export function getStoryView(
|
|||
|
||||
return {
|
||||
attachment,
|
||||
canReply: canReply(story, undefined, conversationSelector),
|
||||
canReply: canReply(story, ourConversationId, conversationSelector),
|
||||
isHidden: Boolean(sender.hideStory),
|
||||
isUnread: story.readStatus === ReadStatus.Unread,
|
||||
messageId: story.messageId,
|
||||
|
@ -193,6 +195,7 @@ export function getStoryView(
|
|||
|
||||
export function getConversationStory(
|
||||
conversationSelector: GetConversationByIdType,
|
||||
ourConversationId: string | undefined,
|
||||
story: StoryDataType
|
||||
): ConversationStoryType {
|
||||
const sender = pick(conversationSelector(story.sourceUuid || story.source), [
|
||||
|
@ -212,7 +215,11 @@ export function getConversationStory(
|
|||
'title',
|
||||
]);
|
||||
|
||||
const storyView = getStoryView(conversationSelector, story);
|
||||
const storyView = getStoryView(
|
||||
conversationSelector,
|
||||
ourConversationId,
|
||||
story
|
||||
);
|
||||
|
||||
return {
|
||||
conversationId: conversation.id,
|
||||
|
@ -292,10 +299,12 @@ export const getStories = createSelector(
|
|||
getConversationSelector,
|
||||
getDistributionListSelector,
|
||||
getStoriesState,
|
||||
getUserConversationId,
|
||||
(
|
||||
conversationSelector,
|
||||
distributionListSelector,
|
||||
{ stories }: Readonly<StoriesStateType>
|
||||
{ stories }: Readonly<StoriesStateType>,
|
||||
ourConversationId
|
||||
): {
|
||||
hiddenStories: Array<ConversationStoryType>;
|
||||
myStories: Array<MyStoryType>;
|
||||
|
@ -312,6 +321,7 @@ export const getStories = createSelector(
|
|||
|
||||
const conversationStory = getConversationStory(
|
||||
conversationSelector,
|
||||
ourConversationId,
|
||||
story
|
||||
);
|
||||
|
||||
|
@ -339,7 +349,11 @@ export const getStories = createSelector(
|
|||
return;
|
||||
}
|
||||
|
||||
const storyView = getStoryView(conversationSelector, story);
|
||||
const storyView = getStoryView(
|
||||
conversationSelector,
|
||||
ourConversationId,
|
||||
story
|
||||
);
|
||||
|
||||
const existingMyStory = myStoriesById.get(sentId) || { stories: [] };
|
||||
|
||||
|
@ -427,7 +441,8 @@ export const getHasStoriesSelector = createSelector(
|
|||
|
||||
export const getStoryByIdSelector = createSelector(
|
||||
getStoriesState,
|
||||
({ stories }) =>
|
||||
getUserConversationId,
|
||||
({ stories }, ourConversationId) =>
|
||||
(
|
||||
conversationSelector: GetConversationByIdType,
|
||||
messageId: string
|
||||
|
@ -441,8 +456,12 @@ export const getStoryByIdSelector = createSelector(
|
|||
}
|
||||
|
||||
return {
|
||||
conversationStory: getConversationStory(conversationSelector, story),
|
||||
storyView: getStoryView(conversationSelector, story),
|
||||
conversationStory: getConversationStory(
|
||||
conversationSelector,
|
||||
ourConversationId,
|
||||
story
|
||||
),
|
||||
storyView: getStoryView(conversationSelector, ourConversationId, story),
|
||||
};
|
||||
}
|
||||
);
|
||||
|
|
Loading…
Add table
Reference in a new issue