+14
-12
index.html
+14
-12
index.html
···
10
10
font-src 'self';
11
11
script-src-attr 'none';
12
12
style-src-attr 'none';
13
-
connect-src https:;
13
+
connect-src https: http://localhost:3000;
14
14
base-uri 'none';
15
15
form-action 'none';">
16
16
···
166
166
<div id="private_search_page">
167
167
<h2>Archive search *Beta*</h2>
168
168
169
-
<form>
170
-
<p>
171
-
Fetch timeline posts: <input type="range" min="1" max="60" value="7"> <label>7 days</label>
172
-
</p>
169
+
<div class="timeline-search">
170
+
<form>
171
+
<p>
172
+
Fetch timeline posts: <input type="range" min="1" max="60" value="7"> <label>7 days</label>
173
+
</p>
173
174
174
-
<p>
175
-
<input type="submit" value="Fetch timeline"> <progress></progress>
176
-
</p>
177
-
</form>
175
+
<p>
176
+
<input type="submit" value="Fetch timeline"> <progress></progress>
177
+
</p>
178
+
</form>
178
179
179
-
<p class="archive-status"></p>
180
+
<p class="archive-status"></p>
180
181
181
-
<hr>
182
+
<hr>
183
+
</div>
182
184
183
-
<p class="search">Search: <input type="text" class="search-query"></p>
185
+
<p class="search">Search: <input type="text" class="search-query" autocomplete="off"></p>
184
186
185
187
<div class="results">
186
188
</div>
+55
-6
private_search_page.js
+55
-6
private_search_page.js
···
18
18
this.timelinePosts = [];
19
19
20
20
this.setupEvents();
21
+
22
+
let params = new URLSearchParams(location.search);
23
+
this.mode = params.get('mode');
24
+
this.lycanMode = params.get('lycan');
25
+
26
+
if (this.lycanMode == 'local') {
27
+
this.lycan = new BlueskyAPI('http://localhost:3000', false);
28
+
}
21
29
}
22
30
23
31
setupEvents() {
···
37
45
label.innerText = (days == 1) ? '1 day' : `${days} days`;
38
46
});
39
47
40
-
this.searchField.addEventListener('input', (e) => {
41
-
let query = this.searchField.value.trim().toLowerCase();
48
+
this.searchField.addEventListener('keydown', (e) => {
49
+
if (e.key == 'Enter') {
50
+
e.preventDefault();
42
51
43
-
if (this.searchTimer) {
44
-
clearTimeout(this.searchTimer);
52
+
let query = this.searchField.value.trim().toLowerCase();
53
+
54
+
if (this.mode == 'likes') {
55
+
this.searchInLycan(query);
56
+
} else {
57
+
this.searchInTimeline(query);
58
+
}
45
59
}
46
-
47
-
this.searchTimer = setTimeout(() => this.searchInTimeline(query), 100);
48
60
});
49
61
}
50
62
···
56
68
57
69
show() {
58
70
this.pageElement.style.display = 'block';
71
+
72
+
if (this.mode == 'likes') {
73
+
this.pageElement.querySelector('.timeline-search').style.display = 'none';
74
+
this.searchLine.style.display = 'block';
75
+
} else {
76
+
this.pageElement.querySelector('.timeline-search').style.display = 'block';
77
+
}
59
78
}
60
79
61
80
/** @returns {Promise<void>} */
···
120
139
for (let post of matching) {
121
140
let postView = new PostComponent(post, 'feed').buildElement();
122
141
this.results.appendChild(postView);
142
+
}
143
+
}
144
+
145
+
/** @param {string} query */
146
+
147
+
async searchInLycan(query) {
148
+
if (query.length == 0) {
149
+
this.results.innerHTML = '';
150
+
return;
151
+
}
152
+
153
+
this.results.innerHTML = '...';
154
+
155
+
if (this.lycanMode == 'local') {
156
+
let response = await this.lycan.getRequest('blue.feeds.lycan.searchPosts', { query: query, user: window.accountAPI.user.did });
157
+
158
+
if (response.posts.length == 0) {
159
+
this.results.innerHTML = "No results.";
160
+
return;
161
+
}
162
+
163
+
let records = await window.accountAPI.loadPosts(response.posts);
164
+
let posts = records.map(x => new Post(x));
165
+
166
+
this.results.innerHTML = '';
167
+
168
+
for (let post of posts) {
169
+
let postView = new PostComponent(post, 'feed').buildElement();
170
+
this.results.appendChild(postView);
171
+
}
123
172
}
124
173
}
125
174