| 327 | } |
| 328 | |
| 329 | function createAndInsertMessage(id, timestamp) { |
| 330 | const container = document.createElement('div'); |
| 331 | container.innerHTML = MESSAGE_TEMPLATE; |
| 332 | const div = container.firstChild; |
| 333 | div.setAttribute('id', id); |
| 334 | |
| 335 | // If timestamp is null, assume we've gotten a brand new message. |
| 336 | // https://stackoverflow.com/a/47781432/4816918 |
| 337 | timestamp = timestamp ? timestamp.toMillis() : Date.now(); |
| 338 | div.setAttribute('timestamp', timestamp); |
| 339 | |
| 340 | // figure out where to insert new message |
| 341 | const existingMessages = messageListElement.children; |
| 342 | if (existingMessages.length === 0) { |
| 343 | messageListElement.appendChild(div); |
| 344 | } else { |
| 345 | let messageListNode = existingMessages[0]; |
| 346 | |
| 347 | while (messageListNode) { |
| 348 | const messageListNodeTime = messageListNode.getAttribute('timestamp'); |
| 349 | |
| 350 | if (!messageListNodeTime) { |
| 351 | throw new Error( |
| 352 | `Child ${messageListNode.id} has no 'timestamp' attribute` |
| 353 | ); |
| 354 | } |
| 355 | |
| 356 | if (messageListNodeTime > timestamp) { |
| 357 | break; |
| 358 | } |
| 359 | |
| 360 | messageListNode = messageListNode.nextSibling; |
| 361 | } |
| 362 | |
| 363 | messageListElement.insertBefore(div, messageListNode); |
| 364 | } |
| 365 | |
| 366 | return div; |
| 367 | } |
| 368 | |
| 369 | // Displays a Message in the UI. |
| 370 | function displayMessage(id, timestamp, name, text, picUrl, imageUrl) { |