feat: ship creator journey v2 and profile updates
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
@php
|
||||
$gridVersion = request()->query('grid') === 'v2' ? 'v2' : 'v1';
|
||||
$deferToolbarSearch = request()->routeIs('index');
|
||||
$deferFontAwesome = request()->routeIs('index');
|
||||
$deferWebManifest = request()->routeIs('index');
|
||||
$isInertiaPage = isset($page) && is_array($page);
|
||||
$shouldRenderBladeSeo = ($useUnifiedSeo ?? false) && (($renderBladeSeo ?? false) || ! $isInertiaPage);
|
||||
$novaViteEntries = [
|
||||
@@ -27,60 +29,148 @@
|
||||
{{-- Global RSS feed discovery --}}
|
||||
<link rel="alternate" type="application/rss+xml" title="Skinbase Latest Artworks" href="{{ url('/rss') }}">
|
||||
|
||||
<!-- Icons (kept for now to preserve current visual output) -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css" />
|
||||
<!-- Icons: keep CDN delivery, but keep homepage webfonts out of the initial critical path -->
|
||||
@if(!$deferFontAwesome)
|
||||
<link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin>
|
||||
<link rel="dns-prefetch" href="//cdnjs.cloudflare.com">
|
||||
<link rel="preload" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css" as="style" crossorigin>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css" media="print" onload="this.media='all'" crossorigin>
|
||||
<noscript>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css" crossorigin>
|
||||
</noscript>
|
||||
@endif
|
||||
|
||||
<link rel="icon" type="image/png" href="/favicon/favicon-96x96.png" sizes="96x96" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon/favicon.svg" />
|
||||
<link rel="shortcut icon" href="/favicon/favicon.ico" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png" />
|
||||
<link rel="manifest" href="/favicon/site.webmanifest" />
|
||||
@if(!$deferWebManifest)
|
||||
<link rel="manifest" href="/favicon/site.webmanifest" />
|
||||
@endif
|
||||
@vite($novaViteEntries)
|
||||
<script>
|
||||
window.SKINBASE_LIMITS = Object.assign({}, window.SKINBASE_LIMITS || {}, {
|
||||
tags: Object.assign({}, (window.SKINBASE_LIMITS && window.SKINBASE_LIMITS.tags) || {}, {
|
||||
max_user_tags: @json((int) config('tags.max_user_tags', 30)),
|
||||
}),
|
||||
});
|
||||
</script>
|
||||
@stack('head')
|
||||
|
||||
@if($deferToolbarSearch)
|
||||
<script type="module">
|
||||
(() => {
|
||||
const searchEntryUrl = @js(Vite::asset('resources/js/entry-search.jsx'));
|
||||
const triggerEvents = ['pointerdown', 'touchstart', 'focusin'];
|
||||
let searchLoaded = false;
|
||||
|
||||
const loadSearch = () => {
|
||||
const loadSearch = (intent = null) => {
|
||||
if (searchLoaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (intent) {
|
||||
window.__sbSearchIntent = intent;
|
||||
}
|
||||
|
||||
searchLoaded = true;
|
||||
cleanup();
|
||||
import(searchEntryUrl);
|
||||
};
|
||||
|
||||
const resolveIntent = (eventTarget) => {
|
||||
return eventTarget?.closest?.('[data-search-intent]')?.getAttribute('data-search-intent') || null;
|
||||
};
|
||||
|
||||
const handlePointerEnter = () => {
|
||||
loadSearch();
|
||||
};
|
||||
|
||||
const handleActivate = (event) => {
|
||||
const intent = resolveIntent(event.target);
|
||||
loadSearch(intent);
|
||||
};
|
||||
|
||||
const handleShortcut = (event) => {
|
||||
if (!((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === 'k')) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
loadSearch(window.matchMedia('(max-width: 767px)').matches ? 'mobile' : 'desktop');
|
||||
};
|
||||
|
||||
const onReady = () => {
|
||||
const searchRoot = document.getElementById('topbar-search-root');
|
||||
if (!searchRoot) {
|
||||
return;
|
||||
}
|
||||
|
||||
triggerEvents.forEach((eventName) => {
|
||||
searchRoot.addEventListener(eventName, loadSearch, { once: true, passive: true });
|
||||
});
|
||||
|
||||
if ('requestIdleCallback' in window) {
|
||||
window.requestIdleCallback(loadSearch, { timeout: 2000 });
|
||||
} else {
|
||||
window.setTimeout(loadSearch, 1500);
|
||||
}
|
||||
searchRoot.addEventListener('pointerenter', handlePointerEnter, { once: true, passive: true });
|
||||
searchRoot.addEventListener('click', handleActivate, { passive: true });
|
||||
searchRoot.addEventListener('touchstart', handleActivate, { passive: true });
|
||||
document.addEventListener('keydown', handleShortcut);
|
||||
};
|
||||
|
||||
const cleanup = () => {
|
||||
const searchRoot = document.getElementById('topbar-search-root');
|
||||
if (!searchRoot) {
|
||||
if (searchRoot) {
|
||||
searchRoot.removeEventListener('pointerenter', handlePointerEnter);
|
||||
searchRoot.removeEventListener('click', handleActivate);
|
||||
searchRoot.removeEventListener('touchstart', handleActivate);
|
||||
}
|
||||
document.removeEventListener('keydown', handleShortcut);
|
||||
};
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', onReady, { once: true });
|
||||
} else {
|
||||
onReady();
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
@endif
|
||||
|
||||
@if($deferFontAwesome)
|
||||
<script>
|
||||
(() => {
|
||||
const href = 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css';
|
||||
const linkId = 'deferred-font-awesome';
|
||||
let loaded = false;
|
||||
|
||||
const loadFontAwesome = () => {
|
||||
if (loaded || document.getElementById(linkId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
triggerEvents.forEach((eventName) => {
|
||||
searchRoot.removeEventListener(eventName, loadSearch);
|
||||
});
|
||||
loaded = true;
|
||||
cleanup();
|
||||
|
||||
const link = document.createElement('link');
|
||||
link.id = linkId;
|
||||
link.rel = 'stylesheet';
|
||||
link.href = href;
|
||||
link.crossOrigin = 'anonymous';
|
||||
document.head.appendChild(link);
|
||||
};
|
||||
|
||||
const onReady = () => {
|
||||
const toolbar = document.getElementById('nova-toolbar');
|
||||
|
||||
if (toolbar) {
|
||||
toolbar.addEventListener('pointerenter', loadFontAwesome, { once: true, passive: true });
|
||||
toolbar.addEventListener('focusin', loadFontAwesome, { once: true, passive: true });
|
||||
toolbar.addEventListener('pointerdown', loadFontAwesome, { once: true, passive: true });
|
||||
}
|
||||
};
|
||||
|
||||
const cleanup = () => {
|
||||
const toolbar = document.getElementById('nova-toolbar');
|
||||
|
||||
if (toolbar) {
|
||||
toolbar.removeEventListener('pointerenter', loadFontAwesome);
|
||||
toolbar.removeEventListener('focusin', loadFontAwesome);
|
||||
toolbar.removeEventListener('pointerdown', loadFontAwesome);
|
||||
}
|
||||
};
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
|
||||
Reference in New Issue
Block a user