a mini social media app for small communities
1@include 'partial/header.html'
2
3<script src="/static/js/user_utils.js"></script>
4<script src="/static/js/search.js"></script>
5
6<h1>search</h1>
7
8<div>
9 <input type="text" name="query" id="query">
10 <div>
11 <p>search for:</p>
12 <input type="radio" name="search-for" id="search-for-posts" value="posts" checked aria-checked>
13 <label for="search-for-posts">posts</label>
14 <input type="radio" name="search-for" id="search-for-users" value="users">
15 <label for="search-for-users">users</label>
16 </div>
17 <br>
18 <button id="search">search</button>
19</div>
20
21<br>
22
23<div id="pages">
24</div>
25
26<div id="results">
27</div>
28
29<script>
30 const params = new URLSearchParams(window.location.search)
31
32 const pages = document.getElementById('pages')
33 const results = document.getElementById('results')
34
35 const query = document.getElementById('query')
36 if (query.value == '' && params.get('q')) {
37 query.value = params.get('q')
38 }
39
40 let limit = params.get('limit')
41 if (!limit) {
42 limit = 10
43 }
44
45 let offset = params.get('offset')
46 if (!limit) {
47 offset = 0
48 }
49
50 const add_post_result = result => {
51 // same as components/post_mini.html except js
52 const element = document.createElement('div')
53 element.classList.add('post', 'post-mini')
54 const p = document.createElement('p')
55
56 const user_link = document.createElement('a')
57 user_link.href = '/user/' + result.author.username
58 const user_text = document.createElement('strong')
59 user_text.innerText = get_display_name(result.author)
60 user_link.appendChild(user_text)
61 p.appendChild(user_link)
62
63 p.innerHTML += ': '
64
65 const post_link = document.createElement('a')
66 post_link.href = '/post/' + result.post.id
67 post_link.innerText = result.post.title
68 p.appendChild(post_link)
69
70 if (result.post.nsfw)
71 {
72 const nsfw_indicator = document.createElement('span')
73 nsfw_indicator.classList.add('nsfw-indicator')
74 nsfw_indicator.innerHTML = '(<em>nsfw</em>)';
75 p.appendChild(nsfw_indicator)
76 }
77
78 element.appendChild(p)
79 results.appendChild(element)
80 }
81
82 const add_user_result = user => {
83 const element = document.createElement('div')
84 const p = document.createElement('p')
85 const user_link = document.createElement('a')
86 user_link.href = '/user/' + user.username
87 user_link.innerText = get_display_name(user)
88 p.appendChild(user_link)
89 element.appendChild(p)
90 results.appendChild(element)
91 }
92
93 const add_pages = () => {
94 // creates a separator
95 const sep = () => {
96 const span = document.createElement('span')
97 span.innerText = ' - '
98 pages.appendChild(span)
99 }
100
101 const first_link = document.createElement('a')
102 // we escape the $ here because otherwise V will try to perform replacements at compile-time.
103 //todo: report this, this behaviour should be changed or at least looked into further.
104 first_link.href = '/search?q=' + query.value + '&limit=' + limit + '&offset=0'
105 first_link.innerText = '0'
106 pages.appendChild(first_link)
107
108 sep()
109
110 const back_link = document.createElement('a')
111 back_link.href = '/search?q=' + query.value + '&limit=' + limit + '&offset=' + Math.min(0, offset - 10)
112 back_link.innerText = '<'
113 pages.appendChild(back_link)
114
115 sep()
116
117 const next_link = document.createElement('a')
118 next_link.href = '/search?q=' + query.value + '&limit=' + limit + '&offset=' + (offset + 10)
119 next_link.innerText = '>'
120 pages.appendChild(next_link)
121 }
122
123 document.getElementById('search').addEventListener('click', async () => {
124 results.innerHTML = '' // yeet the children!
125 pages.innerHTML = '' // yeet more children!
126
127 var search_for
128 for (const radio of document.getElementsByName('search-for')) {
129 if (radio.checked) {
130 search_for = radio.value
131 break
132 }
133 }
134 if (search_for == undefined) {
135 alert('please select either "users" or "posts" to search for.')
136 return
137 }
138
139 console.log('search: ', query.value, limit, offset)
140
141 var search_results
142 if (search_for == 'users') {
143 search_results = await search_users(query.value, limit, offset)
144 } else if (search_for == 'posts') {
145 search_results = await search_posts(query.value, limit, offset)
146 } else {
147 // this should never happen
148 alert('something wrong occured while searching, please report this (01)')
149 return
150 }
151
152 console.log(search_results)
153
154 if (search_results.length >= 0) {
155 // i iterate inside the if statements so that i do not have to perform a redundant
156 // string comparison for every single result.
157 if (search_for == 'users') {
158 for (result of search_results) {
159 add_user_result(result)
160 }
161 } else if (search_for == 'posts') {
162 for (result of search_results) {
163 add_post_result(result)
164 }
165 } else {
166 // this should never happen
167 alert('something wrong occured while searching, please report this (02)')
168 return
169 }
170
171 // set up pagination, but only if we actually have pages to display
172 if (offset > 0) {
173 add_pages()
174 }
175 } else {
176 results.innerText = 'no results!'
177 }
178 })
179</script>
180
181@include 'partial/footer.html'