Skip to content

Commit 315f976

Browse files
committed
trying to compine all search into one
1 parent 80bf0cc commit 315f976

10 files changed

Lines changed: 231 additions & 22 deletions

File tree

assets/css/modern-dark-theme.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,16 @@
500500
color: rgb(253 230 138);
501501
}
502502

503+
[data-theme="dark"] body.home-page .search-palette__badge--blog {
504+
background-color: rgb(49 46 129 / 0.4);
505+
color: rgb(165 180 252);
506+
}
507+
508+
[data-theme="dark"] body.home-page .search-palette__badge--updates {
509+
background-color: rgb(136 19 55 / 0.4);
510+
color: rgb(251 113 133);
511+
}
512+
503513
[data-theme="dark"] body.home-page .search-palette__footer {
504514
background-color: rgb(15 23 42 / 0.8);
505515
border-color: rgb(51 65 85);

assets/css/tailwind-input.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,14 @@
349349
@apply bg-amber-100 text-amber-800;
350350
}
351351

352+
.search-palette__badge--blog {
353+
@apply bg-indigo-100 text-indigo-700;
354+
}
355+
356+
.search-palette__badge--updates {
357+
@apply bg-rose-100 text-rose-700;
358+
}
359+
352360
.search-palette__result-arrow {
353361
@apply text-slate-300 shrink-0 text-sm;
354362
}

i18n/en.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,10 @@
139139
translation: "🎨 Design Lab"
140140
- id: search_chip_browse
141141
translation: "⊞ Browse"
142+
- id: search_remote_blog
143+
translation: "CFD blog"
144+
- id: search_remote_updates
145+
translation: "Updates"
142146

143147
- id: hub_search_designlab
144148
translation: "Search design tools and creative resources..."

i18n/fr.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,10 @@
139139
translation: "🎨 Design Lab"
140140
- id: search_chip_browse
141141
translation: "⊞ Parcourir"
142+
- id: search_remote_blog
143+
translation: "Blog CFD"
144+
- id: search_remote_updates
145+
translation: "Mises à jour"
142146

143147
- id: hub_search_designlab
144148
translation: "Rechercher des outils design et ressources créatives…"

i18n/hi.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,10 @@
139139
translation: "🎨 डिज़ाइन लैब"
140140
- id: search_chip_browse
141141
translation: "⊞ ब्राउज़"
142+
- id: search_remote_blog
143+
translation: "CFD ब्लॉग"
144+
- id: search_remote_updates
145+
translation: "अपडेट"
142146

143147
- id: hub_search_designlab
144148
translation: "डिज़ाइन टूल और क्रिएटिव संसाधन खोजें…"

i18n/ja.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,10 @@
139139
translation: "🎨 デザインラボ"
140140
- id: search_chip_browse
141141
translation: "⊞ 閲覧"
142+
- id: search_remote_blog
143+
translation: "CFDブログ"
144+
- id: search_remote_updates
145+
translation: "Updates"
142146

143147
- id: hub_search_designlab
144148
translation: "デザインツールとクリエイティブリソースを検索…"

layouts/partials/home/search-palette.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@
107107
"designlab" $data.designlab
108108
"store" $data.store
109109
)
110+
"remoteSources" (slice
111+
(dict "id" "blog" "url" "/blog/index.json" "category" (i18n "search_remote_blog") "type" "blog" "icon" "article")
112+
(dict "id" "updates" "url" "/Updates/index.json" "category" (i18n "search_remote_updates") "type" "updates" "icon" "code")
113+
)
110114
| jsonify | safeJS -}};
111115
</script>
112116
<script src="/js/search-palette.min.js" defer></script>

static/css/modern-dark-theme.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,16 @@
495495
color: rgb(253 230 138);
496496
}
497497

498+
[data-theme="dark"] body.home-page .search-palette__badge--blog {
499+
background-color: rgb(49 46 129 / 0.4);
500+
color: rgb(165 180 252);
501+
}
502+
503+
[data-theme="dark"] body.home-page .search-palette__badge--updates {
504+
background-color: rgb(136 19 55 / 0.4);
505+
color: rgb(251 113 133);
506+
}
507+
498508
[data-theme="dark"] body.home-page .search-palette__footer {
499509
background-color: rgb(15 23 42 / 0.8);
500510
border-color: rgb(51 65 85);

static/js/search-palette.js

Lines changed: 181 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ import Fuse from 'fuse.js';
1919
var RECENT_KEY = 'cfd_recent_searches';
2020
var RECENT_MAX = 5;
2121
var SUGGEST_SCORE_THRESHOLD = 0.35;
22+
var REMOTE_CACHE_KEY = 'cfd_remote_search_v1';
23+
var REMOTE_CACHE_VERSION = 1;
24+
var REMOTE_CACHE_TTL_MS = 30 * 60 * 1000;
25+
var REMOTE_DESCRIPTION_MAX = 200;
26+
var REMOTE_CONTENT_EXCERPT = 300;
27+
var indexByUrl = new Map();
28+
var remoteLoadStarted = false;
2229

2330
var FUSE_OPTIONS = {
2431
keys: [
@@ -171,51 +178,200 @@ import Fuse from 'fuse.js';
171178
return item;
172179
}
173180

174-
function buildIndex(data) {
175-
var items = [];
176-
var indexByUrl = new Map();
177-
178-
function push(item) {
179-
if (item.hidden) return;
180-
var key = normalizeUrl(item.url);
181-
if (!key) return;
182-
if (indexByUrl.has(key)) {
183-
mergeItemMetadata(indexByUrl.get(key), item);
184-
return;
185-
}
186-
indexByUrl.set(key, item);
187-
items.push(item);
181+
function pushItem(item) {
182+
if (!item || item.hidden) return;
183+
var key = normalizeUrl(item.url);
184+
if (!key) return;
185+
if (indexByUrl.has(key)) {
186+
mergeItemMetadata(indexByUrl.get(key), item);
187+
return;
188188
}
189+
indexByUrl.set(key, item);
190+
allItems.push(item);
191+
}
192+
193+
function stripHtml(html) {
194+
return String(html || '')
195+
.replace(/<[^>]+>/g, ' ')
196+
.replace(/&(?:#x?[\da-f]+|\w+);/gi, ' ')
197+
.replace(/\s+/g, ' ')
198+
.trim();
199+
}
200+
201+
function mapRemotePost(post, source) {
202+
if (!post || !post.title || !post.permalink) return null;
203+
var summary = stripHtml(post.summary || '');
204+
var excerpt = summary || stripHtml(post.content || '').slice(0, REMOTE_CONTENT_EXCERPT);
205+
var description = excerpt.slice(0, REMOTE_DESCRIPTION_MAX);
206+
return mapItem(
207+
{
208+
name: post.title,
209+
url: post.permalink,
210+
description: description,
211+
phosphorIcon: source.icon || 'article',
212+
external: false,
213+
},
214+
source.category,
215+
source.type
216+
);
217+
}
218+
219+
function itemFromCache(raw) {
220+
var item = {
221+
name: raw.name,
222+
url: raw.url,
223+
category: raw.category,
224+
type: raw.type,
225+
description: raw.description || '',
226+
phosphorIcon: raw.phosphorIcon || 'article',
227+
external: false,
228+
aliases: raw.aliases || [],
229+
searchText: raw.searchText || '',
230+
};
231+
if (!item.searchText) item.searchText = buildSearchText(item);
232+
return item;
233+
}
234+
235+
function slimRemoteItem(item) {
236+
return {
237+
name: item.name,
238+
url: item.url,
239+
category: item.category,
240+
type: item.type,
241+
description: item.description,
242+
phosphorIcon: item.phosphorIcon,
243+
aliases: item.aliases,
244+
searchText: item.searchText,
245+
};
246+
}
247+
248+
function readRemoteCache() {
249+
try {
250+
var raw = sessionStorage.getItem(REMOTE_CACHE_KEY);
251+
if (!raw) return null;
252+
var parsed = JSON.parse(raw);
253+
if (!parsed || parsed.v !== REMOTE_CACHE_VERSION) return null;
254+
if (Date.now() - parsed.fetchedAt > REMOTE_CACHE_TTL_MS) return null;
255+
if (!Array.isArray(parsed.items)) return null;
256+
return parsed.items;
257+
} catch (e) {
258+
return null;
259+
}
260+
}
261+
262+
function writeRemoteCache(items) {
263+
try {
264+
sessionStorage.setItem(
265+
REMOTE_CACHE_KEY,
266+
JSON.stringify({
267+
v: REMOTE_CACHE_VERSION,
268+
fetchedAt: Date.now(),
269+
items: items.map(slimRemoteItem),
270+
})
271+
);
272+
} catch (e) {
273+
/* ignore quota errors */
274+
}
275+
}
276+
277+
function rebuildFuse() {
278+
fuse = allItems.length ? buildFuseIndex(allItems) : null;
279+
}
280+
281+
function refreshSearchIfOpen() {
282+
if (isOpen && input && input.value.trim()) {
283+
runSearch(input.value);
284+
}
285+
}
286+
287+
function mergeRemoteItems(items) {
288+
if (!items || !items.length) return;
289+
items.forEach(function (item) {
290+
pushItem(item);
291+
});
292+
rebuildFuse();
293+
refreshSearchIfOpen();
294+
}
295+
296+
function fetchRemoteSource(source) {
297+
return fetch(source.url, { credentials: 'same-origin' })
298+
.then(function (response) {
299+
return response.ok ? response.json() : [];
300+
})
301+
.then(function (rows) {
302+
return (rows || [])
303+
.map(function (post) {
304+
return mapRemotePost(post, source);
305+
})
306+
.filter(Boolean);
307+
})
308+
.catch(function () {
309+
return [];
310+
});
311+
}
312+
313+
function loadRemoteSources(sources) {
314+
if (!sources || !sources.length || remoteLoadStarted) return;
315+
remoteLoadStarted = true;
316+
317+
var cached = readRemoteCache();
318+
if (cached && cached.length) {
319+
mergeRemoteItems(
320+
cached.map(function (raw) {
321+
return itemFromCache(raw);
322+
})
323+
);
324+
}
325+
326+
Promise.all(
327+
sources.map(function (source) {
328+
return fetchRemoteSource(source);
329+
})
330+
).then(function (groups) {
331+
var remoteItems = [];
332+
groups.forEach(function (group) {
333+
remoteItems = remoteItems.concat(group);
334+
});
335+
if (remoteItems.length) {
336+
writeRemoteCache(remoteItems);
337+
mergeRemoteItems(remoteItems);
338+
}
339+
});
340+
}
341+
342+
function buildIndex(data) {
343+
allItems = [];
344+
indexByUrl = new Map();
189345

190346
if (data.home && data.home.categories) {
191347
data.home.categories.forEach(function (cat) {
192348
(cat.items || []).forEach(function (item) {
193-
push(mapItem(item, cat.name, 'tool'));
349+
pushItem(mapItem(item, cat.name, 'tool'));
194350
});
195351
});
196352
}
197353
if (data.ai && data.ai.data) {
198354
data.ai.data.forEach(function (item) {
199-
push(mapItem(item, 'AI Tools', 'ai'));
355+
pushItem(mapItem(item, 'AI Tools', 'ai'));
200356
});
201357
}
202358
if (data.games && data.games.data) {
203359
data.games.data.forEach(function (item) {
204-
push(mapItem(item, 'Games', 'game'));
360+
pushItem(mapItem(item, 'Games', 'game'));
205361
});
206362
}
207363
if (data.designlab && data.designlab.data) {
208364
data.designlab.data.forEach(function (item) {
209-
push(mapItem(item, 'Design Lab', 'design'));
365+
pushItem(mapItem(item, 'Design Lab', 'design'));
210366
});
211367
}
212368
if (data.store && data.store.data) {
213369
data.store.data.forEach(function (item) {
214-
push(mapItem(item, 'Store', 'store'));
370+
pushItem(mapItem(item, 'Store', 'store'));
215371
});
216372
}
217373

218-
return items;
374+
return allItems;
219375
}
220376

221377
function buildFuseIndex(items) {
@@ -746,13 +902,16 @@ import Fuse from 'fuse.js';
746902
}
747903

748904
if (window.CFD_SEARCH && window.CFD_SEARCH.data) {
749-
allItems = buildIndex(window.CFD_SEARCH.data);
750-
fuse = buildFuseIndex(allItems);
905+
buildIndex(window.CFD_SEARCH.data);
906+
rebuildFuse();
751907
} else {
752908
allItems = [];
909+
indexByUrl = new Map();
753910
fuse = null;
754911
}
755912

913+
loadRemoteSources(window.CFD_SEARCH && window.CFD_SEARCH.remoteSources);
914+
756915
mountPaletteToBody();
757916
initialized = true;
758917

tailwind.config.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ module.exports = {
8484
'search-palette__badge--game',
8585
'search-palette__badge--design',
8686
'search-palette__badge--store',
87+
'search-palette__badge--blog',
88+
'search-palette__badge--updates',
8789
'nav-mega',
8890
'nav-mega__panel',
8991
'nav-mega__grid',

0 commit comments

Comments
 (0)