diff options
Diffstat (limited to 'template/script.js')
| -rwxr-xr-x | template/script.js | 145 |
1 files changed, 77 insertions, 68 deletions
diff --git a/template/script.js b/template/script.js index 0e1291c..3c58403 100755 --- a/template/script.js +++ b/template/script.js | |||
| @@ -25,79 +25,88 @@ window.addEventListener('load', async () => { | |||
| 25 | }); | 25 | }); |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | // comments code | 28 | // Search functionality |
| 29 | const commentsEndpoint = 'https://mitjafelicijan.com/comments-api'; | 29 | |
| 30 | const commentsPlaceholder = document.querySelector('.comments'); | 30 | window.index = null; |
| 31 | 31 | ||
| 32 | if (commentsPlaceholder) { | 32 | const response = await fetch('/feed.json'); |
| 33 | const guid = commentsPlaceholder.dataset.guid; | 33 | const feed = await response.json(); |
| 34 | const name = commentsPlaceholder.querySelector('input'); | 34 | |
| 35 | const comment = commentsPlaceholder.querySelector('textarea'); | 35 | window.index = elasticlunr(function () { |
| 36 | const submit = commentsPlaceholder.querySelector('button'); | 36 | this.addField('title'); |
| 37 | const comments = commentsPlaceholder.querySelector('ul'); | 37 | this.addField('body'); |
| 38 | 38 | this.setRef('id'); | |
| 39 | if (guid) { | 39 | }); |
| 40 | await readAndRenderComments(guid, comments); | 40 | |
| 41 | 41 | for (const item of feed.items) { | |
| 42 | submit.addEventListener('click', async() => { | 42 | item.id = item.url; |
| 43 | submit.disabled = true; | 43 | window.index.addDoc({ |
| 44 | await writeComments(guid, name.value, comment.value); | 44 | id: item.url, |
| 45 | 45 | title: item.title, | |
| 46 | submit.disabled = false; | 46 | body: item.content_html, |
| 47 | name.value = ''; | 47 | url: item.url, |
| 48 | comment.value = ''; | 48 | }); |
| 49 | |||
| 50 | await readAndRenderComments(guid, comments); | ||
| 51 | }); | ||
| 52 | } | ||
| 53 | } | 49 | } |
| 54 | 50 | ||
| 55 | async function writeComments(guid, name, comment) { | 51 | const blur = document.querySelector('.blur'); |
| 56 | const response = await fetch(commentsEndpoint, { | 52 | const searchForm = document.querySelector('.search-form'); |
| 57 | method: 'POST', | 53 | const searchResultsList = document.querySelector('.search-form ul'); |
| 58 | headers: { | 54 | |
| 59 | 'Accept': 'application/json', | 55 | function showSearchModal() { |
| 60 | 'Content-Type': 'application/json' | 56 | blur.classList.remove('hidden'); |
| 61 | }, | 57 | searchForm.classList.remove('hidden'); |
| 62 | body: JSON.stringify({ | 58 | |
| 63 | action: 'write', | 59 | // Clear search input. |
| 64 | guid, | 60 | searchForm.querySelector('input').value = ''; |
| 65 | name, | 61 | |
| 66 | comment, | 62 | // We need to clear the list before opening modal. |
| 67 | }) | 63 | searchResultsList.innerHTML = ''; |
| 68 | }); | 64 | |
| 65 | // Focus on search input. | ||
| 66 | searchForm.querySelector('input').focus(); | ||
| 69 | } | 67 | } |
| 70 | 68 | ||
| 71 | async function readAndRenderComments(guid, commentsPlaceholder) { | 69 | document.querySelector('.search-trigger').addEventListener('click', async (evt) => { |
| 72 | const response = await fetch(commentsEndpoint, { | 70 | showSearchModal(); |
| 73 | method: 'POST', | 71 | }); |
| 74 | headers: { | 72 | |
| 75 | 'Accept': 'application/json', | 73 | document.onkeydown = function (e) { |
| 76 | 'Content-Type': 'application/json' | 74 | // Show search modal on F key. |
| 77 | }, | 75 | if (blur.classList.contains('hidden')) { |
| 78 | body: JSON.stringify({ | 76 | if (e.key === 'f') { |
| 79 | action: 'read', | 77 | setTimeout(() => { |
| 80 | guid, | 78 | showSearchModal(); |
| 81 | }) | 79 | }, 100); |
| 82 | }); | 80 | } |
| 81 | } | ||
| 83 | 82 | ||
| 84 | // remove all existing comments from list | 83 | // Hide search modal on escape key. |
| 85 | commentsPlaceholder.innerHTML = ''; | 84 | if (!blur.classList.contains('hidden')) { |
| 86 | 85 | if (e.key === 'Escape') { | |
| 87 | const commentList = await response.json(); | 86 | blur.classList.add('hidden'); |
| 88 | for (const comment of commentList.reverse()) { | 87 | searchForm.classList.add('hidden'); |
| 89 | const date = new Date(comment.date).toLocaleDateString('en-US', { | 88 | } |
| 90 | year: 'numeric', | ||
| 91 | month: 'long', | ||
| 92 | day: 'numeric', | ||
| 93 | hour: 'numeric', | ||
| 94 | minute: 'numeric' | ||
| 95 | }); | ||
| 96 | |||
| 97 | const commentElement = document.createElement('li'); | ||
| 98 | commentElement.innerHTML = `<p><b>${comment.name}</b> - ${date}<p><p>${comment.comment}<p><hr>`; | ||
| 99 | commentsPlaceholder.appendChild(commentElement); | ||
| 100 | } | 89 | } |
| 101 | } | 90 | }; |
| 91 | |||
| 92 | blur.addEventListener('click', async (evt) => { | ||
| 93 | evt.target.classList.add('hidden'); | ||
| 94 | searchForm.classList.add('hidden'); | ||
| 95 | }); | ||
| 96 | |||
| 97 | document.querySelector('.search-form input').addEventListener('keyup', async (evt) => { | ||
| 98 | // Perform search. | ||
| 99 | const searchResults = window.index.search(evt.target.value); | ||
| 100 | |||
| 101 | // We need to clear the list before adding new results. | ||
| 102 | searchResultsList.innerHTML = ''; | ||
| 103 | |||
| 104 | // Loop through the results and add them to the list. | ||
| 105 | for (const result of searchResults.slice(0, 9)) { | ||
| 106 | const listItem = document.createElement('li'); | ||
| 107 | listItem.innerHTML = `<a href="${result.doc.url}">${result.doc.title}</a>`; | ||
| 108 | searchResultsList.appendChild(listItem); | ||
| 109 | } | ||
| 110 | }); | ||
| 102 | 111 | ||
| 103 | }); | 112 | }); |
