-
Notifications
You must be signed in to change notification settings - Fork 44
Expand file tree
/
Copy pathIterableInboxDataModel.ts
More file actions
280 lines (257 loc) · 9.79 KB
/
IterableInboxDataModel.ts
File metadata and controls
280 lines (257 loc) · 9.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
import { IterableApi } from '../../core/classes/IterableApi';
import {
IterableHtmlInAppContent,
IterableInAppDeleteSource,
IterableInAppLocation,
IterableInAppMessage,
type IterableHtmlInAppContentRaw,
} from '../../inApp';
import type {
IterableInboxImpressionRowInfo,
IterableInboxRowViewModel,
} from '../types';
/**
* The `IterableInboxDataModel` class provides methods to manage and manipulate
* inbox messages.
*/
export class IterableInboxDataModel {
/**
* Optional function to filter messages.
*
* This function takes an `IterableInAppMessage` as an argument and returns a boolean value.
* It is used to determine whether a given message should be included based on custom criteria.
*
* @param message - The in-app message to be evaluated.
* @returns A boolean indicating whether the message meets the filter criteria.
*/
filterFn?: (message: IterableInAppMessage) => boolean;
/**
* Optional comparator function to determine the order of messages.
*
* @param message1 - The first message to compare.
* @param message2 - The second message to compare.
* @returns A negative number if `message1` should come before `message2`,
* a positive number if `message1` should come after `message2`,
* or 0 if they are considered equal.
*/
comparatorFn?: (
message1: IterableInAppMessage,
message2: IterableInAppMessage
) => number;
/**
* Optional function to map an IterableInAppMessage to a date string or undefined.
* This function can be used to extract and format the date from a message.
*
* @param message - The IterableInAppMessage object to be mapped.
* @returns A string representing the date or undefined if no date is available.
*/
dateMapperFn?: (message: IterableInAppMessage) => string | undefined;
/**
* Sets the filter, comparator, and date mapper functions for the inbox data model.
*
* @param filter - A function to filter messages. It takes an `IterableInAppMessage` as an argument and returns a boolean indicating whether the message should be included.
* @param comparator - A function to compare two messages. It takes two `IterableInAppMessage` objects as arguments and returns a number indicating their relative order.
* @param dateMapper - A function to map a message to a date string. It takes an `IterableInAppMessage` as an argument and returns a string representing the date, or undefined if no date is applicable.
*/
set(
filter?: (message: IterableInAppMessage) => boolean,
comparator?: (
message1: IterableInAppMessage,
message2: IterableInAppMessage
) => number,
dateMapper?: (message: IterableInAppMessage) => string | undefined
) {
this.filterFn = filter;
this.comparatorFn = comparator;
this.dateMapperFn = dateMapper;
}
/**
* Formats the creation date of an in-app message.
*
* @param message - The in-app message object containing the creation date.
* @returns The formatted date string. Returns an empty string if the creation date is undefined.
*/
getFormattedDate(message: IterableInAppMessage) {
if (message.createdAt === undefined) {
return '';
}
if (this.dateMapperFn) {
return this.dateMapperFn(message);
} else {
return this.defaultDateMapper(message);
}
}
/**
* Retrieves the HTML content for a given message ID.
*
* @param id - The ID of the message to retrieve HTML content for.
* @returns A promise that resolves to the HTML content of the specified message.
*/
getHtmlContentForMessageId(id: string): Promise<IterableHtmlInAppContent> {
return IterableApi.getHtmlInAppContentForMessage(id).then(
(content: IterableHtmlInAppContentRaw) => {
return IterableHtmlInAppContent.fromDict(content);
}
);
}
/**
* Marks a message as read in the Iterable inbox.
*
* @param id - The unique identifier of the message to be marked as read.
*/
setMessageAsRead(id: string) {
return IterableApi.setReadForMessage(id, true);
}
/**
* Deletes an item from the inbox by its ID.
*
* @param id - The unique identifier of the item to be deleted.
* @param deleteSource - The source from which the delete action is initiated.
*/
deleteItemById(id: string, deleteSource: IterableInAppDeleteSource) {
return IterableApi.removeMessage(
id,
IterableInAppLocation.inbox,
deleteSource
);
}
/**
* Refreshes the inbox data by fetching the latest messages from Iterable.
*
* @returns A promise that resolves to an array of processed inbox row view models.
* If the fetch operation fails, the promise resolves to an empty array.
*/
async refresh(): Promise<IterableInboxRowViewModel[]> {
return IterableApi.getInboxMessages().then(
(messages: IterableInAppMessage[]) => {
return this.processMessages(messages);
},
() => {
return [];
}
);
}
/**
* Starts a tracking session for the inbox with the given visible rows.
*
* @param visibleRows - An array of `IterableInboxImpressionRowInfo` objects representing the rows that are currently visible.
*/
startSession(visibleRows: IterableInboxImpressionRowInfo[] = []) {
return IterableApi.startSession(visibleRows);
}
/**
* Ends the current tracking session and updates the visible rows.
*
* @param visibleRows - An array of `IterableInboxImpressionRowInfo` objects representing the rows that are currently visible. Defaults to an empty array.
* @returns A promise that resolves when the session has ended and the visible rows have been updated.
*/
async endSession(visibleRows: IterableInboxImpressionRowInfo[] = []) {
await this.updateVisibleRows(visibleRows);
return IterableApi.endSession();
}
/**
* Updates the visible rows in the inbox.
*
* This method takes an array of `IterableInboxImpressionRowInfo` objects
* representing the rows that are currently visible and updates the
* visibility status. (REVIEW: Where does it update it? In Iterable or in the
* interface?)
*
* @param visibleRows - An array of `IterableInboxImpressionRowInfo` objects
* representing the rows that are currently visible.
* Defaults to an empty array if not provided.
*/
updateVisibleRows(visibleRows: IterableInboxImpressionRowInfo[] = []) {
return IterableApi.updateVisibleRows(visibleRows);
}
/**
* A comparator function to sort `IterableInAppMessage` objects by their creation date in descending order.
*
* @param message1 - The first `IterableInAppMessage` object to compare.
* @param message2 - The second `IterableInAppMessage` object to compare.
* @returns A number indicating the sort order:
* - `1` if `message1` was created after `message2`
* - `-1` if `message1` was created before `message2`
* - `0` if both messages were created at the same time
*/
private static sortByMostRecent = (
message1: IterableInAppMessage,
message2: IterableInAppMessage
) => {
const createdAt1 = message1.createdAt ?? new Date(0);
const createdAt2 = message2.createdAt ?? new Date(0);
if (createdAt1 < createdAt2) return 1;
if (createdAt1 > createdAt2) return -1;
return 0;
};
/**
* Maps the creation date of an IterableInAppMessage to a formatted string.
*
* @param message - The message object containing the creation date.
* @returns A formatted string representing the creation date and time of the
* message. If the creation date is undefined, returns an empty string.
*/
private defaultDateMapper(message: IterableInAppMessage): string {
if (message.createdAt === undefined) {
return '';
}
const defaultDateString = `${message.createdAt.toLocaleDateString()} at ${message.createdAt.toLocaleTimeString()}`;
return defaultDateString;
}
/**
* Processes a list of in-app messages by sorting and filtering them,
* and then mapping each message to an inbox row view model.
*
* @param messages - An array of `IterableInAppMessage` objects to be processed.
* @returns An array of `IterableInboxRowViewModel` objects representing the processed messages.
*/
private processMessages(
messages: IterableInAppMessage[]
): IterableInboxRowViewModel[] {
return this.sortAndFilter(messages).map(
IterableInboxDataModel.getInboxRowViewModelForMessage
);
}
/**
* Sorts and filters an array of `IterableInAppMessage` objects.
*
* @param messages - The array of messages to be sorted and filtered.
* @returns The sorted and filtered array of messages.
*/
private sortAndFilter(
messages: IterableInAppMessage[]
): IterableInAppMessage[] {
let sortedFilteredMessages = messages.slice();
// MOB-10424: Figure out if this is purposeful
// eslint-disable-next-line eqeqeq
if (this.filterFn != undefined) {
sortedFilteredMessages = sortedFilteredMessages.filter(this.filterFn);
}
// MOB-10424: Figure out if this is purposeful
// eslint-disable-next-line eqeqeq
if (this.comparatorFn != undefined) {
sortedFilteredMessages.sort(this.comparatorFn);
} else {
sortedFilteredMessages.sort(IterableInboxDataModel.sortByMostRecent);
}
return sortedFilteredMessages;
}
/**
* Converts an `IterableInAppMessage` into an `IterableInboxRowViewModel`.
*
* @param message - The in-app message to convert.
* @returns An object representing the inbox row view model.
*/
private static getInboxRowViewModelForMessage(
message: IterableInAppMessage
): IterableInboxRowViewModel {
return {
title: message.inboxMetadata?.title ?? '',
subtitle: message.inboxMetadata?.subtitle,
imageUrl: message.inboxMetadata?.icon,
createdAt: message.createdAt,
read: message.read,
inAppMessage: message,
};
}
}