feat: harden billing verification and add browse route parity
This commit is contained in:
@@ -176,6 +176,10 @@
|
||||
<script>
|
||||
(() => {
|
||||
const state = { page: 1, limit: 32, total: 0, items: [], categories: {} };
|
||||
const initialQuery = @json($initialQuery ?? '');
|
||||
const initialCategory = @json($initialCategory ?? '');
|
||||
const initialSubcategory = @json($initialSubcategory ?? '');
|
||||
const initialPath = @json($canonicalPath ?? '/');
|
||||
const qEl = document.getElementById('q');
|
||||
const catEl = document.getElementById('category');
|
||||
const subEl = document.getElementById('subcategory');
|
||||
@@ -191,8 +195,60 @@
|
||||
const heroOptional1 = document.getElementById('hero-optional-1');
|
||||
const heroOptional2 = document.getElementById('hero-optional-2');
|
||||
|
||||
const initParams = new URLSearchParams(window.location.search);
|
||||
if (initParams.get('q')) qEl.value = initParams.get('q');
|
||||
if (initialQuery) qEl.value = initialQuery;
|
||||
|
||||
function slugify(text) {
|
||||
return String(text || '')
|
||||
.toLowerCase()
|
||||
.replaceAll('&', 'and')
|
||||
.replace(/[^a-z0-9]+/g, '-')
|
||||
.replace(/^-+|-+$/g, '');
|
||||
}
|
||||
|
||||
function categoryLabelToSlug(label) {
|
||||
const map = {
|
||||
'Smileys & Emotion': 'smileys',
|
||||
'People & Body': 'people',
|
||||
'Animals & Nature': 'animals',
|
||||
'Food & Drink': 'food',
|
||||
'Travel & Places': 'travel',
|
||||
'Activities': 'activities',
|
||||
'Objects': 'objects',
|
||||
'Symbols': 'symbols',
|
||||
'Flags': 'flags',
|
||||
};
|
||||
return map[String(label || '')] || '';
|
||||
}
|
||||
|
||||
function syncUrl() {
|
||||
const q = qEl.value.trim();
|
||||
const cat = catEl.value;
|
||||
const sub = subEl.value;
|
||||
const params = new URLSearchParams();
|
||||
let path = '/';
|
||||
|
||||
if (q !== '') {
|
||||
params.set('q', q);
|
||||
if (cat) params.set('category', cat);
|
||||
if (sub) params.set('subcategory', sub);
|
||||
path = '/';
|
||||
} else if (cat) {
|
||||
const catSlug = categoryLabelToSlug(cat);
|
||||
if (catSlug) {
|
||||
path = '/' + catSlug;
|
||||
if (sub) path += '/' + slugify(sub);
|
||||
} else {
|
||||
params.set('category', cat);
|
||||
if (sub) params.set('subcategory', sub);
|
||||
}
|
||||
} else {
|
||||
path = initialPath === '/browse' ? '/browse' : '/';
|
||||
}
|
||||
|
||||
const query = params.toString();
|
||||
const target = query ? `${path}?${query}` : path;
|
||||
window.history.replaceState({}, '', target);
|
||||
}
|
||||
|
||||
function esc(s) {
|
||||
return String(s || '').replace(/[&<>"']/g, (c) => ({ '&':'&','<':'<','>':'>','"':'"',"'":''' }[c]));
|
||||
@@ -338,6 +394,7 @@
|
||||
incoming.forEach((item) => state.items.push(item));
|
||||
renderGrid(incoming, reset);
|
||||
updateStats();
|
||||
syncUrl();
|
||||
}
|
||||
|
||||
function renderGrid(items, reset) {
|
||||
@@ -399,6 +456,14 @@
|
||||
|
||||
(async () => {
|
||||
await loadCategories();
|
||||
if (initialCategory && state.categories[initialCategory]) {
|
||||
catEl.value = initialCategory;
|
||||
renderSubcategories();
|
||||
if (initialSubcategory) {
|
||||
const hasInitialSub = Array.from(subEl.options).some((opt) => opt.value === initialSubcategory);
|
||||
if (hasInitialSub) subEl.value = initialSubcategory;
|
||||
}
|
||||
}
|
||||
await fetchEmojis(true);
|
||||
renderTrendingFromItems(state.items);
|
||||
renderRecent();
|
||||
|
||||
Reference in New Issue
Block a user