Notification for failed story sends
This commit is contained in:
parent
4c2f169783
commit
e11f961d7a
7 changed files with 67 additions and 3 deletions
|
@ -6315,6 +6315,14 @@
|
|||
"message": "Add a link for viewers of your story",
|
||||
"description": "Empty state for the link preview"
|
||||
},
|
||||
"icu:Stories__failed-send--full": {
|
||||
"messageformat": "Story failed to send",
|
||||
"description": "Notification text whenever a story fails to send"
|
||||
},
|
||||
"icu:Stories__failed-send--partial": {
|
||||
"messageformat": "Story couldn't be sent to all recipients",
|
||||
"description": "Notification text whenever a story partially fails to send"
|
||||
},
|
||||
"TextAttachment__placeholder": {
|
||||
"message": "Add text",
|
||||
"description": "Placeholder for the add text input"
|
||||
|
|
|
@ -28,6 +28,7 @@ export type PropsType = {
|
|||
profileName?: string;
|
||||
theme: ThemeType;
|
||||
title: string;
|
||||
hasFailedStorySends?: boolean;
|
||||
unreadStoriesCount: number;
|
||||
|
||||
showArchivedConversations: () => void;
|
||||
|
@ -149,6 +150,7 @@ export class MainHeader extends React.Component<PropsType, StateType> {
|
|||
avatarPath,
|
||||
badge,
|
||||
color,
|
||||
hasFailedStorySends,
|
||||
hasPendingUpdate,
|
||||
i18n,
|
||||
name,
|
||||
|
@ -251,7 +253,10 @@ export class MainHeader extends React.Component<PropsType, StateType> {
|
|||
title={i18n('stories')}
|
||||
type="button"
|
||||
>
|
||||
{unreadStoriesCount ? (
|
||||
{hasFailedStorySends && (
|
||||
<span className="module-main-header__stories-badge">!</span>
|
||||
)}
|
||||
{!hasFailedStorySends && unreadStoriesCount ? (
|
||||
<span className="module-main-header__stories-badge">
|
||||
{unreadStoriesCount}
|
||||
</span>
|
||||
|
|
|
@ -440,6 +440,8 @@ export async function sendStory(
|
|||
const oldSendStateByConversationId =
|
||||
message.get('sendStateByConversationId') || {};
|
||||
|
||||
let hasFailedSends = false;
|
||||
|
||||
const newSendStateByConversationId = Object.keys(
|
||||
oldSendStateByConversationId
|
||||
).reduce((acc, conversationId) => {
|
||||
|
@ -481,6 +483,8 @@ export async function sendStory(
|
|||
};
|
||||
}
|
||||
|
||||
hasFailedSends = true;
|
||||
|
||||
return {
|
||||
...acc,
|
||||
[conversationId]: sendStateReducer(oldSendState, {
|
||||
|
@ -490,6 +494,10 @@ export async function sendStory(
|
|||
};
|
||||
}, {} as SendStateByConversationId);
|
||||
|
||||
if (hasFailedSends) {
|
||||
message.notifyStorySendFailed();
|
||||
}
|
||||
|
||||
if (isEqual(oldSendStateByConversationId, newSendStateByConversationId)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1467,6 +1467,26 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
})
|
||||
)
|
||||
);
|
||||
|
||||
this.notifyStorySendFailed();
|
||||
}
|
||||
|
||||
public notifyStorySendFailed(): void {
|
||||
if (!isStory(this.attributes)) {
|
||||
return;
|
||||
}
|
||||
|
||||
notificationService.add({
|
||||
conversationId: this.get('conversationId'),
|
||||
storyId: this.id,
|
||||
messageId: this.id,
|
||||
senderTitle:
|
||||
this.getConversation()?.getTitle() ?? window.i18n('Stories__mine'),
|
||||
message: this.hasSuccessfulDelivery()
|
||||
? window.i18n('icu:Stories__failed-send--partial')
|
||||
: window.i18n('icu:Stories__failed-send--full'),
|
||||
isExpiringMessage: false,
|
||||
});
|
||||
}
|
||||
|
||||
removeOutgoingErrors(incomingIdentifier: string): CustomError {
|
||||
|
@ -1619,6 +1639,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
updatedAt: Date.now(),
|
||||
}
|
||||
);
|
||||
this.notifyStorySendFailed();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import * as log from '../../logging/log';
|
|||
import { SIGNAL_ACI } from '../../types/SignalConversation';
|
||||
import dataInterface from '../../sql/Client';
|
||||
import { ReadStatus } from '../../messages/MessageReadStatus';
|
||||
import { SendStatus } from '../../messages/MessageSendState';
|
||||
import { SafetyNumberChangeSource } from '../../components/SafetyNumberChangeDialog';
|
||||
import { StoryViewDirectionType, StoryViewModeType } from '../../types/Stories';
|
||||
import { assertDev, strictAssert } from '../../util/assert';
|
||||
|
@ -987,6 +988,10 @@ const viewStory: ViewStoryActionCreatorType = (
|
|||
|
||||
// Go directly to the storyId selected
|
||||
if (!viewDirection) {
|
||||
const hasFailedSend = Object.values(
|
||||
story.sendStateByConversationId || {}
|
||||
).some(({ status }) => status === SendStatus.Failed);
|
||||
|
||||
dispatch({
|
||||
type: VIEW_STORY,
|
||||
payload: {
|
||||
|
@ -995,7 +1000,7 @@ const viewStory: ViewStoryActionCreatorType = (
|
|||
numStories,
|
||||
storyViewMode,
|
||||
unviewedStoryConversationIdsSorted,
|
||||
viewTarget,
|
||||
viewTarget: hasFailedSend ? undefined : viewTarget,
|
||||
},
|
||||
});
|
||||
return;
|
||||
|
|
|
@ -576,3 +576,16 @@ export const getHasAllStoriesUnmuted = createSelector(
|
|||
getStoriesState,
|
||||
({ hasAllStoriesUnmuted }): boolean => hasAllStoriesUnmuted
|
||||
);
|
||||
|
||||
export const getHasAnyFailedStorySends = createSelector(
|
||||
getStoriesState,
|
||||
({ lastOpenedAtTimestamp, stories }): boolean => {
|
||||
return stories.some(
|
||||
story =>
|
||||
story.timestamp > (lastOpenedAtTimestamp || 0) &&
|
||||
Object.values(story.sendStateByConversationId || {}).some(
|
||||
({ status }) => status === SendStatus.Failed
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
|
|
@ -17,7 +17,10 @@ import {
|
|||
} from '../selectors/user';
|
||||
import { getMe } from '../selectors/conversations';
|
||||
import { getStoriesEnabled } from '../selectors/items';
|
||||
import { getStoriesNotificationCount } from '../selectors/stories';
|
||||
import {
|
||||
getStoriesNotificationCount,
|
||||
getHasAnyFailedStorySends,
|
||||
} from '../selectors/stories';
|
||||
|
||||
const mapStateToProps = (state: StateType) => {
|
||||
const me = getMe(state);
|
||||
|
@ -32,6 +35,7 @@ const mapStateToProps = (state: StateType) => {
|
|||
badge: getPreferredBadgeSelector(state)(me.badges),
|
||||
theme: getTheme(state),
|
||||
i18n: getIntl(state),
|
||||
hasFailedStorySends: getHasAnyFailedStorySends(state),
|
||||
unreadStoriesCount: getStoriesNotificationCount(state),
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue