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