summaryrefslogtreecommitdiff
blob: 790e43e5c05a80514ceee1da5c01969411652a20 (plain)
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
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
( function () {
	/* global moment:false */
	/**
	 * Notification item data structure.
	 *
	 * @class
	 * @mixins OO.EventEmitter
	 * @mixins OO.SortedEmitterList
	 *
	 * @constructor
	 * @param {number} id Notification id,
	 * @param {Object} [config] Configuration object
	 * @cfg {string} [iconUrl] A URL for the given icon.
	 * @cfg {string} [iconType] A string noting the icon type.
	 * @cfg {Object} [content] The message object defining the text for the header and,
	 *  optionally, the body of the notification.
	 * @cfg {string} [content.header=''] The header text of the notification
	 * @cfg {string} [content.body=''] The body text of the notification
	 * @cfg {string} [category] The category of this notification. The category identifies
	 *  where the notification originates from.
	 * @cfg {string} [type='message'] The notification type 'message' or 'alert'
	 * @cfg {boolean} [read=false] State the read state of the option
	 * @cfg {boolean} [seen=false] State the seen state of the option
	 * @cfg {string} [timestamp] Notification timestamp in ISO 8601 format
	 * @cfg {string} [primaryUrl] Notification primary link in raw url format
	 * @cfg {boolean} [foreign=false] This notification is from a foreign source
	 * @cfg {boolean} [bundled=false] This notification is part of a bundle
	 * @cfg {number[]} [bundledIds] IDs of notifications bundled with this one
	 * @cfg {string} [modelName='local'] The name of the model this item belongs to
	 * @cfg {string} [source] The source this notification is coming from, if it is foreign
	 * @cfg {Object[]} [secondaryUrls] An array of objects defining the secondary URLs
	 *  for this notification. The secondary URLs are expected to have this structure:
	 *    {
	 *      "iconType": "userAvatar", // A symbolic name for the icon.
	 *                                // Will render as oo-ui-icon-* class.
	 *      "label": "", // The label for the link
	 *      "prioritized": true/false, // Prioritized links are outside of the popup
	 *                                 // menu, whenever possible.
	 *      "url": "..." // The url for the secondary link
	 *    }
	 */
	mw.echo.dm.NotificationItem = function MwEchoDmNotificationItem( id, config ) {
		var fallbackDate = moment.utc().format( 'YYYY-MM-DD[T]HH:mm:ss[Z]' );

		config = config || {};

		// Mixin constructor
		OO.EventEmitter.call( this );

		// Properties
		this.id = id;
		this.modelName = config.modelName || 'local';
		this.content = $.extend( { header: '', body: '' }, config.content );
		this.category = config.category || '';
		this.type = config.type || 'message';
		this.foreign = !!config.foreign;
		this.bundled = !!config.bundled;
		this.source = config.source || '';
		this.iconType = config.iconType;
		this.iconURL = config.iconURL;

		this.read = !!config.read;
		this.seen = !!config.seen;

		this.timestamp = config.timestamp || fallbackDate;
		this.setPrimaryUrl( config.primaryUrl );
		this.setSecondaryUrls( config.secondaryUrls );
		this.bundledIds = config.bundledIds;
	};

	/* Initialization */

	OO.initClass( mw.echo.dm.NotificationItem );
	OO.mixinClass( mw.echo.dm.NotificationItem, OO.EventEmitter );

	/* Events */

	/**
	 * @event update
	 *
	 * Item details have changed or were updated
	 */

	/* Methods */

	/**
	 * Get NotificationItem id
	 *
	 * @return {string} NotificationItem Id
	 */
	mw.echo.dm.NotificationItem.prototype.getId = function () {
		return this.id;
	};

	/**
	 * Get NotificationItem content header
	 *
	 * @return {string} NotificationItem content
	 */
	mw.echo.dm.NotificationItem.prototype.getContentHeader = function () {
		return this.content.header;
	};

	/**
	 * Get NotificationItem content body
	 *
	 * @return {string} NotificationItem content body
	 */
	mw.echo.dm.NotificationItem.prototype.getContentBody = function () {
		return this.content.body;
	};

	/**
	 * Get NotificationItem category
	 *
	 * @return {string} NotificationItem category
	 */
	mw.echo.dm.NotificationItem.prototype.getCategory = function () {
		return this.category;
	};

	/**
	 * Get NotificationItem type
	 *
	 * @return {string} NotificationItem type
	 */
	mw.echo.dm.NotificationItem.prototype.getType = function () {
		return this.type;
	};

	/**
	 * Check whether this notification item is read
	 *
	 * @return {boolean} Notification item is read
	 */
	mw.echo.dm.NotificationItem.prototype.isRead = function () {
		return this.read;
	};

	/**
	 * Check whether this notification item is seen
	 *
	 * @return {boolean} Notification item is seen
	 */
	mw.echo.dm.NotificationItem.prototype.isSeen = function () {
		return this.seen;
	};

	/**
	 * Check whether this notification item is foreign
	 *
	 * @return {boolean} Notification item is foreign
	 */
	mw.echo.dm.NotificationItem.prototype.isForeign = function () {
		return this.foreign;
	};

	/**
	 * Check whether this notification item is part of a bundle
	 *
	 * @return {boolean} Notification item is part of a bundle
	 */
	mw.echo.dm.NotificationItem.prototype.isBundled = function () {
		return this.bundled;
	};

	/**
	 * Set this notification item as foreign
	 *
	 * @param {boolean} isForeign Notification item is foreign
	 */
	mw.echo.dm.NotificationItem.prototype.setForeign = function ( isForeign ) {
		this.foreign = isForeign;
	};

	/**
	 * Toggle the read state of the widget
	 *
	 * @param {boolean} [read] The current read state. If not given, the state will
	 *  become the opposite of its current state.
	 * @fires update
	 */
	mw.echo.dm.NotificationItem.prototype.toggleRead = function ( read ) {
		read = read !== undefined ? read : !this.read;
		if ( this.read !== read ) {
			this.read = read;
			this.emit( 'update' );
			this.emit( 'sortChange' );
		}
	};

	/**
	 * Toggle the seen state of the widget
	 *
	 * @param {boolean} [seen] The current seen state. If not given, the state will
	 *  become the opposite of its current state.
	 * @fires update
	 */
	mw.echo.dm.NotificationItem.prototype.toggleSeen = function ( seen ) {
		seen = seen !== undefined ? seen : !this.seen;
		if (
			this.seen !== seen &&
			// Do not change the state of a read item, since its
			// seen state (never 'unseen') never changes
			!this.isRead()
		) {
			this.seen = seen;
			this.emit( 'update' );
		}
	};

	/**
	 * Get the notification timestamp
	 *
	 * @return {number} Notification timestamp in Mediawiki timestamp format
	 */
	mw.echo.dm.NotificationItem.prototype.getTimestamp = function () {
		return this.timestamp;
	};

	/**
	 * Set the notification link
	 *
	 * @param {string} link Notification url
	 */
	mw.echo.dm.NotificationItem.prototype.setPrimaryUrl = function ( link ) {
		this.primaryUrl = link;
	};

	/**
	 * Get the notification link
	 *
	 * @return {string} Notification url
	 */
	mw.echo.dm.NotificationItem.prototype.getPrimaryUrl = function () {
		return this.primaryUrl;
	};

	/**
	 * Get the notification icon URL
	 *
	 * @return {string} Notification icon URL
	 */
	mw.echo.dm.NotificationItem.prototype.getIconURL = function () {
		return this.iconURL;
	};

	/**
	 * Get the notification icon type
	 *
	 * @return {string} Notification icon type
	 */
	mw.echo.dm.NotificationItem.prototype.getIconType = function () {
		return this.iconType;
	};

	/**
	 * Set the notification's secondary links
	 * See constructor documentation for the structure of these links objects.
	 *
	 * @param {Object[]} links Secondary url definitions
	 */
	mw.echo.dm.NotificationItem.prototype.setSecondaryUrls = function ( links ) {
		this.secondaryUrls = links || [];
	};

	/**
	 * Get the notification's secondary links
	 *
	 * @return {Object[]} Secondary url definitions
	 */
	mw.echo.dm.NotificationItem.prototype.getSecondaryUrls = function () {
		return this.secondaryUrls;
	};

	/**
	 * Get the notification's source
	 *
	 * @return {string} Notification source
	 */
	mw.echo.dm.NotificationItem.prototype.getSource = function () {
		return this.source;
	};

	/**
	 * Get the notification's model name
	 *
	 * @return {string} Notification model name
	 */
	mw.echo.dm.NotificationItem.prototype.getModelName = function () {
		return this.modelName;
	};

	/**
	 * Get the all ids contained in this notification
	 *
	 * @return {number[]}
	 */
	mw.echo.dm.NotificationItem.prototype.getAllIds = function () {
		return [ this.getId() ].concat( this.bundledIds || [] );
	};

}() );