1
Fork 0

Add mobile support and update dropdown

This commit is contained in:
Korbs 2024-06-23 22:32:23 -04:00
parent e312dc0cae
commit 9cfc165035
No known key found for this signature in database

View file

@ -5,100 +5,41 @@ import { Trans, HeadHrefLangs } from "astro-i18next/components";
// Components
import { Image } from 'astro:assets';
import Button from '@components/generic/Button.astro'
import Dropdown from '@components/global/HeaderDropdown.astro'
// Images
import Poke from '@assets/poke-text.svg'
// Icons
import {
LogIn,
Gamepad,
Settings,
RefreshDouble,
Search,
ProfileCircle,
CircleSpark,
Youtube,
OpenNewWindow,
ViewGrid,
Arcade,
InfoCircle,
PrivacyPolicy,
Code,
Language,
NavArrowLeft,
NavArrowRight,
List
Menu
} from '@iconoir/vue'
import { Menu } from "@iconoir/vue";
// Check URL
if (Astro.url.pathname.startsWith('/watch')) {
var WatchPage = true
} else {
var WatchPage = false
}
---
<header>
<header id="header-desktop">
<div class="header-content">
<div class="header-start">
<a href={'/'}><Image src={Poke} alt="Poke Logo" height={24} /></a>
</div>
<div class="header-center"></div>
<div class="header-end">
<Button
BackDrop="blur(6px) brightness(1)"
Background="transparent"
BorderColor="transparent"
Color="white"
BorderRadius="3rem"
><Search width={16}/> Search</Button>
<Button
BackDrop="blur(6px) brightness(1)"
Background="transparent"
BorderColor="transparent"
Color="white"
BorderRadius="3rem"
Onclick="ToggleHeaderDropdown()"
><Menu width={16}/> Menu</Button>
</div>
<div id="primary" class="header-dropdown">
<p>{t('dropdown.Options')}</p>
<a onclick="ToggleHeaderDropdown(); ToggleHeaderLanguageDropdown()" style="justify-content: space-between;"><div><Language/> {t('dropdown.Language')}</div> <NavArrowRight/></a>
<a href=""><ProfileCircle/> {t('dropdown.Account')}</a>
<a href=""><Settings/> {t('dropdown.Settings')}</a>
<a href=""><List/> {t('dropdown.Instances')}</a>
<p>{t('dropdown.Hub')}</p>
<a data-astro-prefetch href=""><ViewGrid/> {t('dropdown.Apps')}</a>
<a data-astro-prefetch href=""><Arcade/> {t('dropdown.Games')}</a>
<!-- Only show this if the end-user is watching a video -->
{WatchPage ?
<p>{t('dropdown.Openin')}</p>
<a href=""><CircleSpark/> {t('dropdown.LiteMode')}</a>
<a href=""><Youtube/> {t('dropdown.YouTube')}</a>
<a href=""><OpenNewWindow/> {t('dropdown.Invidious')}</a>
<a href=""><OpenNewWindow/> {t('dropdown.Pipe')}</a>
:
null
}
<p>{t('dropdown.Other')}</p>
<a data-astro-prefetch href="/about/"><InfoCircle/> {t('dropdown.About')}</a>
<a data-astro-prefetch href=""><PrivacyPolicy/> {t('dropdown.Privacy')}</a>
<a data-astro-prefetch href=""><Code/> {t('dropdown.SourceCode')}</a>
</div>
<div id="language" class="header-dropdown">
<p>{t('dropdown.Language')}</p>
<a onclick="ToggleHeaderDropdown(); ToggleHeaderLanguageDropdown()"><NavArrowLeft/> {t("dropdown.GoBack")}</a>
<a href="/api/language/en/">English</a>
<a href="/api/language/jp/">日本語</a>
<button onclick="FocusSearch()" transition:persist="searchbar">
<RefreshDouble style="display: none;" id="search-header-load"/>
<Search id="search-header-icon"/>
<form onsubmit="return Search()">
<input type="search" placeholder="Search"/>
</form>
</button>
<button onclick="ToggleHeaderDropdown()"><Menu/> Menu</button>
<div class="suggestions"></div>
</div>
<Dropdown/>
</div>
</header>
<!-- Search Scripts -->
<script is:inline>
/*
@licstart The following is the entire license notice for the
@ -125,184 +66,208 @@ through which recipients can access the Corresponding Source.
for the JavaScript code in this page.
*/
// Dismiss when the end-user clicks else where
document.body.addEventListener("click", function (evt) {
document.querySelector(".header-dropdown#primary").style.display = "none";
});
// Toggle Primary Dropdown
function ToggleHeaderDropdown() {
var HeaderDropdown = document.querySelector(".header-dropdown#primary");
if (HeaderDropdown.style.display === "flex") {
setTimeout(() => {
HeaderDropdown.style.display = "none";
}, 0o100);
} else {
setTimeout(() => {
HeaderDropdown.style.display = "flex";
}, 0o100);
}
// Focus input
function FocusSearch() {
document.querySelector('input[type="search"]').focus()
}
// Toggle Language Dropdown
function ToggleHeaderLanguageDropdown() {
var HeaderLanguageDropdown = document.querySelector(".header-dropdown#language");
if (HeaderLanguageDropdown.style.display === "flex") {
HeaderLanguageDropdown.style.display = "none";
} else {
HeaderLanguageDropdown.style.display = "flex";
}
// Trigger Search
function Search() {
var SearchIcon = document.getElementById('search-header-icon')
SearchIcon.style.display = 'none'
var SearchLoading = document.getElementById('search-header-load')
SearchLoading.style.display = 'inherit'
var SearchQuery = document.querySelector('input[type="search"]').value
location.href = `/search?q=${SearchQuery}`
}
///// Suggestions /////
// Dismiss when the end-user clicks else where
document.body.addEventListener("click", function (evt) {
document.querySelector('.suggestions').style.opacity = '0'
});
// When the end-user starts typing, trigget the fetch function
document.querySelector('input[type="search"]').addEventListener('input', function(e) {
if (e.target.value !== '') {
document.querySelector('.suggestions').style.opacity = '1'
GetResults()
}
else {null}
});
// Fetch
function GetResults() {
var SearchValue = document.querySelector('input[type="search"]').value
var YouTubeSuggestions = document.querySelector('.suggestions')
fetch(`https://yt.sudovanilla.org/api/v1/search/suggestions?q=${SearchValue}`)
.then(response => response.json())
.then(data => {YouTubeSuggestions.innerHTML = ListOfSuggestionsYT(data)})
}
// Create List
function ListOfSuggestionsYT(data) {
const text = data.suggestions.map(data => `<a href="/search?query=${data}">${data}</a>`).join("\n")
return `${text}`
}
</script>
<style lang="scss">
.dropdown-button {
color: white;
background: transparent;
border: none;
border-radius: 6px;
aspect-ratio: 1;
padding: 4px 6px;
&:hover {
background: rgba(255,255,255,0.1);
<style is:global lang="scss">
@media only screen and (max-width: 820px) {
:root {
--MaxSearchbarWidth: 100% !important;
}
svg {
width: 18px;
pointer-events: none;
.content {
margin-top: 0px !important;
padding-bottom: 92px !important;
}
}
.header-dropdown {
display: none;
flex-direction: column;
position: absolute;
top: 70px;
right: 24px;
background: transparent;
border-radius: 12px;
gap: 6px;
padding: 12px 6px 8px 6px;
backdrop-filter: blur(24px) brightness(0.1) contrast(0.9);
z-index: 5;
p {
margin: 0px 0px 0px 12px;
color: gray;
font-size: 12px;
}
a {
display: flex;
align-items: center;
gap: 12px;
font-size: 14px;
text-decoration: none;
padding: 6px 12px !important;
aspect-ratio: inherit !important;
min-width: 200px;
border-radius: 6px;
&:hover {
background: rgba(255,255,255,0.1);
.landing {
margin-top: 40px !important;
img:nth-child(1) {
display: none;
}
div {
display: flex;
align-items: center;
gap: 12px;
img:nth-child(1) {
height: inherit;
width: 100%;
}
}
header {
top: inherit !important;
bottom: 18px;
padding-bottom: env(safe-area-inset-bottom);
background: transparent !important;
border: none !important;
}
.header-content {
background: rgba(0,0,0,0.5);
width: calc(100% - 96px) !important;
border-radius: 42px;
border: 1px #222 solid;
backdrop-filter: blur(22px) contrast(0.9);
}
.suggestions, .header-dropdown {
top: inherit !important;
bottom: 80px;
}
// Search
.channel {
min-width: 180px !important;
}
.tc-info {
flex-direction: column;
padding: 24px 0px 50px 0px !important;
h2 {
font-size: 14px !important;
}
p {
display: none;
}
}
}
</style>
<script is:inline>
/*
@licstart The following is the entire license notice for the
JavaScript code in this page.
Copyright (C) 2024 SudoVanilla
The JavaScript code in this page is free software: you can
redistribute it and/or modify it under the terms of the GNU
General Public License (GNU GPL) as published by the Free Software
Foundation, either version 3 of the License, or (at your option)
any later version. The code is distributed WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
As additional permission under GNU GPL version 3 section 7, you
may distribute non-source (e.g., minimized or compacted) forms of
that code without the copy of the GNU GPL normally required by
section 4, provided you include this license notice and a URL
through which recipients can access the Corresponding Source.
@licend The above is the entire license notice
for the JavaScript code in this page.
*/
function Search() {
var SearchQuery = document.querySelector('input[type="search"]').value
location.href = `/search?q=${SearchQuery}`
}
</script>
<style lang="scss">
header {
position: fixed;
top: 0px;
left: 0px;
width: 100%;
background: #161616;
border-bottom: 2px #232323 solid;
z-index: 5;
.header-content {
display: flex;
justify-content: space-between;
padding: 12px 24px;
align-items: center;
margin: auto;
max-width: 1200px;
position: relative;
.header-center {
form {
display: flex;
align-items: center;
input {
color: white;
background: black;
border: 2px #333 solid;
border-right-color: transparent;
border-right-width: 0px;
border-radius: 3rem 0px 0px 3rem;
padding: 6px 12px;
width: 160px;
transition: width 0.6s, border 0.3s, transform 0.2s;
&:focus {
border-radius: 4px;
transform: scale(1.2);
width: 260px;
border-width: 1px;
border-right-color: #333;
border-right-width: 1px;
font-size: 12px;
transition: width 0.6s, border 0.3s, transform 0.2s;
}
}
button {
color: white;
background: black;
border: 2px #333 solid;
border-left: 0px;
border-radius: 0px 3rem 3rem 0px;
padding: 1px 8px 0px 0px;
cursor: var(--pointer-cursor);
svg {
width: 16px;
pointer-events: none;
}
}
}
}
.header-end {
display: flex;
gap: 6px;
}
}
:root {
--MaxSearchbarWidth: 300px !important;
}
header {
position: fixed;
top: 0px;
left: 0px;
width: 100%;
background: #161616;
border-bottom: 2px #232323 solid;
z-index: 5;
.header-content {
display: flex;
justify-content: space-between;
padding: 12px 24px;
align-items: center;
margin: auto;
max-width: 1200px;
width: 100%;
position: relative;
.header-end {
display: flex;
gap: 6px;
button {
background: transparent;
color: white;
display: flex;
align-items: center;
gap: 6px;
border-radius: 3rem;
padding: 6px 12px;
border: 2px rgba(255, 255, 255, 0) solid;
backdrop-filter: blur(24px);
transition: 0.3s backdrop-filter;
svg {
width: 16px;
}
&:hover, &:focus {
backdrop-filter: blur(12px) brightness(0.8);
transition: 0.3s backdrop-filter;
}
input {
background: transparent;
color: white;
border: none;
cursor: text;
width: 54px;
transition: 1s width;
&:hover {
width: 64px;
transition: 0.3s width;
}
&:focus {
width: var(--MaxSearchbarWidth);
transition: 0.3s width;
}
}
}
button[onclick="FocusSearch()"] {
cursor: text !important;
* {
cursor: text !important;
}
}
.suggestions {
opacity: 0;
position: absolute;
right: 0px;
width: 450px;
display: grid;
gap: 2px;
top: 70px;
border-radius: 6px;
padding: 4px;
backdrop-filter: blur(24px) brightness(0.5) contrast(0.7);
.suggestions a {
text-decoration: none !important;
padding: 4px 12px !important;
border-radius: 4px !important;
&:hover {
background: #ffffff1f !important;
text-decoration: underline !important;
}
}
}
}
}
}
@keyframes SpinMeRoundBaby {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg)
}
}
#search-header-load {
animation: 1s SpinMeRoundBaby infinite linear;
}
</style>