-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
316 lines (277 loc) · 8.07 KB
/
index.js
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
304
305
306
307
308
309
310
311
312
313
314
315
316
const photoForm = document.querySelector('#add-photo-form')
const cardHold = document.querySelector('.card-holder')
const tagsContainer = document.querySelector('.tags-container')
const searchForm = document.querySelector('#tag-search')
const windowPic = document.querySelector('.window-photo')
const commentUl = document.querySelector('.comment-list')
const commentForm = document.querySelector('#comment-form')
const datalist = document.querySelector('#tags')
const popup2 = document.querySelector('#popup2')
const popup1 = document.querySelector('#popup1')
const state = {
pichas: [],
currentPichaId: 0
}
const uniqTags = []
// Initial page load of pre-existing photos
getPhotos().then(data => {
state.pichas = data
renderPhotos(state.pichas)
searchDatalist()
})
// Predictive search
function searchDatalist() {
toUniqTags()
uniqTags.forEach(tag => {
const option = document.createElement('option')
option.value = tag.description
datalist.append(option)
})
}
// Renders a single photo
function renderPhoto(photo) {
const aTag = document.createElement('a')
const imgTag = document.createElement('img')
imgTag.src = photo.url
imgTag.className = 'photo-card'
aTag.append(imgTag)
cardHold.append(aTag)
aTag.addEventListener('click', () => {
togglePopup2()
state.currentPichaId = photo.id
windowPic.src = photo.url
tagsContainer.innerHTML = ''
renderTags(photo.id)
})
}
// Renders individual comment
function renderComment(comment) {
const commentLi = document.createElement('li')
const commentP = document.createElement('p')
commentLi.className = 'comment-li'
commentP.className = 'comment-p'
commentP.innerText = comment.content
commentLi.append(commentP)
commentUl.append(commentLi)
}
// Toggles between image and comments on popup2
function toggleComments() {
windowPic.parentNode.querySelector('.comment-window').classList.toggle("visible")
commentUl.innerHTML = ""
getPhotoById(state.currentPichaId).then(json => {
json.comments.forEach(comment => renderComment(comment))
})
}
// Renders the photo's tags on popup2
function renderTags(id) {
state.pichas.find(pic => pic.id === id).tags
.forEach(tag => {
const tagBtn = document.createElement('button')
const tagSpan = document.createElement('span')
tagBtn.className = 'tag-button'
tagSpan.innerText = tag.description
// Filters the images on clicking tag
tagBtn.addEventListener('click', event => {
event.preventDefault()
cardHold.innerHTML = ''
renderPhotos(filtered(tag.description))
togglePopup2()
})
tagBtn.append(tagSpan)
tagsContainer.append(tagBtn)
})
}
// Renders all existing photos
function renderPhotos(photos) {
photos.forEach(photo => renderPhoto(photo))
}
// Updates page with new data
function updatePage() {
cardHold.innerHTML = ''
renderPhotos(state.pichas)
}
// Creates 5 tags to photo passed in
function createTags(photo) {
const lastPic = state.pichas[state.pichas.length - 1]
getLabels(photo.url).then(data => {
data.responses[0].labelAnnotations.forEach(tag => {
saveTag(tag).then(tagData => {
lastPic.tags.push(tagData)
saveRelevance(tagData.id, photo.id)
})
})
})
}
// Filters photos by tag
function filtered(value) {
return state.pichas.filter(photo => {
return !!photo.tags.find(tag => {
return tag.description.toLowerCase() === value.toLowerCase()
})
})
}
// Hides duplicate tags
function toUniqTags() {
const temp = []
uniqTags.length = 0
state.pichas.forEach(photo => {
photo.tags.forEach(tag => {
if (!temp.includes(tag.description)) {
temp.push(tag.description)
uniqTags.push(tag)
}
})
})
}
// Deletes photo from API, closes popup and updates page
function removePhoto(id) {
if (confirm('Are you sure you want to delete this Picha?')) {
deletePhoto(id)
deletePhotoFromState(id)
hideComments()
updatePage()
togglePopup2()
};
};
// Deletes photo from state
function deletePhotoFromState(id) {
const toDelete = state.pichas.find(picha => picha.id === id)
const deleteIndex = state.pichas.indexOf(toDelete)
state.pichas.splice(deleteIndex, 1)
}
// Hides comments - displays image on popup2
function hideComments() {
if (windowPic.parentNode.querySelector('.comment-window').classList.value.includes('visible')) {
toggleComments()
}
}
// Opens/closes popup1
function togglePopup1() {
popup1.classList.toggle('visible')
}
// Opens/closes popup2
function togglePopup2() {
popup2.classList.toggle('visible')
}
// Sorts unique tags alphabetically
function sortUniqTags() {
toUniqTags()
uniqTags.sort((a, b) => {
if (a.description < b.description) {
return -1
}
if (a.description > b.description) {
return 1
}
return 0
})
}
// Shows comments on clicking image in popup2
windowPic.addEventListener('click', toggleComments)
// Hides comments on clicking 'back' button
document.querySelector('.close-comment-window').addEventListener('click', toggleComments)
// Adds a new comment
commentForm.addEventListener('submit', event => {
event.preventDefault()
const newComment = {
picha_id: state.currentPichaId,
content: document.querySelector('#comment-content').value
}
saveComment(newComment)
renderComment(newComment)
commentForm.reset()
})
// Closes popup2 and hides comments
document.querySelector('.close2').addEventListener('click', () => {
hideComments()
togglePopup2()
})
// Opens new image form on clicking logo
document.querySelector('.logo-anchor').addEventListener('click', () => {
togglePopup1()
})
// Closes popup1
document.querySelector('.close').addEventListener('click', () => {
togglePopup1()
})
// Deletes photo
document.querySelector('.delete-image').addEventListener('click', (event) => {
event.preventDefault()
removePhoto(state.currentPichaId)
});
// Closes popups on pressing esc
window.addEventListener('keyup', event => {
if (event.which === 27 && popup2.classList.contains('visible')) {
hideComments()
togglePopup2()
} else if (event.which === 27 && popup1.classList.contains('visible')) {
togglePopup1()
}
})
// Makes popup1 div an exception to close on click
document.querySelector('.popup').addEventListener('click', event => {
event.stopPropagation()
})
// Clicking anywhere closes popup1
popup1.addEventListener('click', (event) => {
togglePopup1()
})
// Makes popup2 div an exception to close on click
document.querySelector('.popup2').addEventListener('click', event => {
event.stopPropagation()
})
// Clicking anywhere closes popup2
popup2.addEventListener('click', (event) => {
hideComments()
togglePopup2()
})
// Listener for creating uploading new photo
photoForm.addEventListener('submit', (event) => {
event.preventDefault()
const newPhoto = {
title: document.querySelector('#title').value,
url: document.querySelector('#url').value
}
savePicha(newPhoto).then(photo => {
state.pichas.push(photo)
createTags(photo)
updatePage()
})
photoForm.reset()
togglePopup1()
})
// renders all tags
document.querySelector('#tag-tab').addEventListener('click', event => {
event.preventDefault()
cardHold.innerHTML = ''
sortUniqTags()
uniqTags.forEach(tag => {
const tagBtn = document.createElement('button')
tagBtn.className = 'tag-button'
tagBtn.innerText = tag.description
// renders the images for the clicked tag
tagBtn.addEventListener('click', event => {
event.preventDefault()
cardHold.innerHTML = ''
renderPhotos(filtered(tag.description))
})
cardHold.append(tagBtn)
})
})
// renders home page showing all pics
document.querySelector('#home-tab').addEventListener('click', event => {
event.preventDefault()
updatePage()
})
// filters images by search input
searchForm.addEventListener('submit', event => {
event.preventDefault()
const searchInput = document.querySelector('#search-item')
if (filtered(searchInput.value).length > 0) {
cardHold.innerHTML = ''
renderPhotos(filtered(searchInput.value))
} else {
cardHold.innerText = "No Images Found"
}
searchForm.reset()
})