Compare commits
10 commits
522e9b1dd7
...
df07435874
Author | SHA1 | Date | |
---|---|---|---|
|
df07435874 | ||
|
8d9683b17d | ||
|
6ec8a041ff | ||
|
0907a9bba8 | ||
|
ad25845ba9 | ||
|
d2072b47f2 | ||
|
d0d93e5587 | ||
|
073e286ad9 | ||
|
e5c49baa11 | ||
|
b2f1e23328 |
11 changed files with 258 additions and 21 deletions
|
@ -0,0 +1,43 @@
|
||||||
|
---
|
||||||
|
// Configuration
|
||||||
|
import {
|
||||||
|
version
|
||||||
|
} from "@root/package.json"
|
||||||
|
---
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
<div class="footer-start">
|
||||||
|
<p style="color: gray;">v{version}</p>
|
||||||
|
<p>Zarro Search, a search engine by SudoVanilla</p>
|
||||||
|
</div>
|
||||||
|
<div class="footer-end">
|
||||||
|
<a href="#">About</a>
|
||||||
|
<a href="#">Instances</a>
|
||||||
|
<a href="#">Settings</a>
|
||||||
|
<a href="#">News</a>
|
||||||
|
<a href="#">API</a>
|
||||||
|
<a href="#">Source Code</a>
|
||||||
|
<a href="#">Report Issue</a>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
footer {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
.footer-start {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
.footer-end {
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
margin-left: 12px;
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
// Properties
|
// Properties
|
||||||
const {Query} = Astro.props
|
const {Query, QueryText} = Astro.props
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
import { HalfMoon, Menu } from "@iconoir/vue";
|
import { HalfMoon, Menu } from "@iconoir/vue";
|
||||||
|
@ -8,10 +8,10 @@ import { HalfMoon, Menu } from "@iconoir/vue";
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
<div class="header-start">
|
<div class="header-start">
|
||||||
<img width="18px" src="https://md.sudovanilla.org/images/Union.png" />
|
<a href="/"><img width="18px" src="https://md.sudovanilla.org/images/Union.png"/></a>
|
||||||
<div class="search-box">
|
<form class="search-box" onsubmit="return Search()">
|
||||||
<input value={Query} placeholder="Search" />
|
<input type="search" value={QueryText} placeholder="Search" />
|
||||||
</div>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="header-end">
|
<div class="header-end">
|
||||||
<button>English</button>
|
<button>English</button>
|
||||||
|
@ -76,4 +76,44 @@ header {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<!-- Search Scripts -->
|
||||||
|
<!-- From https://ark.sudovanilla.org/MinPluto/MinPluto/src/branch/master/source/src/components/Search.astro#L18-L94 as of writing -->
|
||||||
|
<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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Focus input
|
||||||
|
function FocusSearch() {
|
||||||
|
document.querySelector('input[type="search"]').focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trigger Search
|
||||||
|
function Search() {
|
||||||
|
var SearchQuery = document.querySelector('form > input[type="search"]').value;
|
||||||
|
location.href = `/web?=${SearchQuery}`;
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
<style lang="scss" is:global>
|
<style lang="scss" is:global>
|
||||||
.related-search-tags {
|
.related-search-tags {
|
||||||
line-height: 32px;
|
line-height: 12px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
a {
|
a {
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
border-radius: 3rem;
|
border-radius: 3rem;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
padding: 6px 12px;
|
padding: 6px 8px;
|
||||||
color: black;
|
color: black;
|
||||||
text-wrap: nowrap;
|
text-wrap: nowrap;
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
|
|
|
@ -32,11 +32,15 @@ const {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
a {
|
a {
|
||||||
|
text-decoration: none;
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
|
color: black;
|
||||||
}
|
}
|
||||||
p {
|
p {
|
||||||
font-size: 14px;
|
font-size: 12px;
|
||||||
|
text-decoration: underline;
|
||||||
|
color: rgb(82, 82, 82);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
54
source/src/components/search/WebLinkSkeleton.astro
Normal file
54
source/src/components/search/WebLinkSkeleton.astro
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
---
|
||||||
|
// Properties
|
||||||
|
const {
|
||||||
|
Title,
|
||||||
|
Description,
|
||||||
|
Link
|
||||||
|
} = Astro.props
|
||||||
|
---
|
||||||
|
|
||||||
|
<div class="fade-up">
|
||||||
|
<div class="search-result-web-skeleton"></div>
|
||||||
|
<div class="search-result-web-skeleton"></div>
|
||||||
|
<div class="search-result-web-skeleton"></div>
|
||||||
|
<div class="search-result-web-skeleton"></div>
|
||||||
|
<div class="search-result-web-skeleton"></div>
|
||||||
|
<div class="search-result-web-skeleton"></div>
|
||||||
|
<div class="search-result-web-skeleton"></div>
|
||||||
|
<div class="search-result-web-skeleton"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@keyframes wave-lines {
|
||||||
|
0% {
|
||||||
|
background-position: -468px 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-position: 468px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes wave-squares {
|
||||||
|
0% {
|
||||||
|
background-position: -468px 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-position: 468px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.fade-up {
|
||||||
|
mask-image: linear-gradient(white, transparent);
|
||||||
|
}
|
||||||
|
.search-result-web-skeleton {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 6px;
|
||||||
|
background: white;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 64px 12px;
|
||||||
|
box-shadow: 0px 4px 10px 0px #0000000a;
|
||||||
|
background: linear-gradient(to right,rgba(164, 164, 164, 0.2) 8%,rgba(241, 238, 238, 0.3) 18%,rgba(155, 155, 155, 0.2) 33%);
|
||||||
|
background-size: 1500px 1px;
|
||||||
|
animation: wave-lines 0.8s infinite ease-out;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
// Properties
|
// Properties
|
||||||
const {Title, Query} = Astro.props
|
const {Title, Query, QueryText} = Astro.props
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import Head from "@components/global/Head.astro";
|
import Head from "@components/global/Head.astro";
|
||||||
|
@ -13,6 +13,6 @@ import '@styles/mobile.scss'
|
||||||
---
|
---
|
||||||
|
|
||||||
<Head/>
|
<Head/>
|
||||||
<Header Query={Query}/>
|
<Header QueryText={QueryText}/>
|
||||||
<slot/>
|
<slot/>
|
||||||
<Footer/>
|
<Footer/>
|
|
@ -3,13 +3,13 @@
|
||||||
import Base from "./Base.astro"
|
import Base from "./Base.astro"
|
||||||
|
|
||||||
// Properties
|
// Properties
|
||||||
const {Type, Title, Query} = Astro.props
|
const {Type, Title, Query, QueryText} = Astro.props
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import SearchMenu from "@components/global/SearchMenu.astro"
|
import SearchMenu from "@components/global/SearchMenu.astro"
|
||||||
---
|
---
|
||||||
|
|
||||||
<Base Title={Title} Query={Query}>
|
<Base Title={Title} QueryText={QueryText}>
|
||||||
<SearchMenu Type={Type}/>
|
<SearchMenu Type={Type}/>
|
||||||
<div class="search-results">
|
<div class="search-results">
|
||||||
<div class="search-results-start">
|
<div class="search-results-start">
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
---
|
||||||
|
// Layout
|
||||||
|
import Base from "@layouts/Base.astro";
|
||||||
|
---
|
||||||
|
|
||||||
|
<Base>
|
||||||
|
<a href="http://localhost:1550/web?=Queen%20Band">Example Search</a>
|
||||||
|
<br class="full"/>
|
||||||
|
</Base>
|
||||||
|
<style is:global>
|
||||||
|
footer {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0px;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 1200px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -2,30 +2,85 @@
|
||||||
// Layout
|
// Layout
|
||||||
import Search from "@layouts/Search.astro";
|
import Search from "@layouts/Search.astro";
|
||||||
|
|
||||||
|
// Configuration
|
||||||
|
import {
|
||||||
|
DEFAULT_API
|
||||||
|
} from "@utils/GetConfig"
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import WebLink from "@components/search/WebLink.astro";
|
|
||||||
import RelatedSearches from "@components/search/RelatedSearches.astro";
|
import RelatedSearches from "@components/search/RelatedSearches.astro";
|
||||||
|
import WebLink from "@components/search/WebLink.astro";
|
||||||
|
import WebLinkSkeleton from "@components/search/WebLinkSkeleton.astro";
|
||||||
|
|
||||||
// Fetch
|
// Fetch
|
||||||
const QueryText = Astro.url.href.split("web?=").pop()
|
const QueryString = Astro.url.href.split("web?=").pop() // Get user's search query from URL
|
||||||
const Query = await fetch("https://4get.sudovanilla.org" + "/api/v1/web?s=" + QueryText).then((response) => response.json());
|
const QueryText = `${QueryString}`.replaceAll("%20", " ") // Replace "%20" with a space
|
||||||
|
const Query = await fetch(DEFAULT_API + "/api/v1/web?s=" + QueryString).then((response) => response.json()); // Response
|
||||||
---
|
---
|
||||||
|
|
||||||
<Search Query={QueryText} Type="Web">
|
<Search QueryText={QueryText} Type="Web">
|
||||||
<slot slot="search">
|
<slot slot="search">
|
||||||
{Query.web.map((query) => (
|
{Query.web.map((query) => (
|
||||||
<WebLink
|
<WebLink
|
||||||
|
server:defer
|
||||||
Title={query.title}
|
Title={query.title}
|
||||||
Description={query.description}
|
Description={query.description}
|
||||||
Link={query.url}
|
Link={query.url}
|
||||||
/>
|
>
|
||||||
|
<WebLinkSkeleton slot="fallback"/>
|
||||||
|
</WebLink>
|
||||||
))}
|
))}
|
||||||
</slot>
|
</slot>
|
||||||
<slot slot="rich-panel">
|
<slot slot="rich-panel">
|
||||||
<RelatedSearches>
|
<RelatedSearches server:defer>
|
||||||
{Query.related.map((related) => (
|
{Query.related.map((related) => (
|
||||||
<a href={'/web?=' + related}>{related}</a>
|
<a href={'/web?=' + related}>{related}</a>
|
||||||
))}
|
))}
|
||||||
|
<slot slot="fallback">
|
||||||
|
<div class="fade-up small-grid-related">
|
||||||
|
<a class="related-sk"></a>
|
||||||
|
<a class="related-sk"></a>
|
||||||
|
<a class="related-sk"></a>
|
||||||
|
<a class="related-sk"></a>
|
||||||
|
<a class="related-sk"></a>
|
||||||
|
</div>
|
||||||
|
</slot>
|
||||||
</RelatedSearches>
|
</RelatedSearches>
|
||||||
|
<a style="font-size: 12px;" href={DEFAULT_API + "/api/v1/web?s=" + QueryString} target="_blank">JSON Response</a>
|
||||||
</slot>
|
</slot>
|
||||||
</Search>
|
</Search>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@keyframes wave-lines {
|
||||||
|
0% {
|
||||||
|
background-position: -468px 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-position: 468px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes wave-squares {
|
||||||
|
0% {
|
||||||
|
background-position: -468px 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-position: 468px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.small-grid-related {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.fade-up {
|
||||||
|
mask-image: linear-gradient(white, transparent);
|
||||||
|
}
|
||||||
|
.related-sk {
|
||||||
|
box-shadow: 0px 4px 10px 0px #0000000a;
|
||||||
|
background: linear-gradient(to right,rgba(164, 164, 164, 0.2) 8%,rgba(241, 238, 238, 0.3) 18%,rgba(155, 155, 155, 0.2) 33%);
|
||||||
|
background-size: 150px 1px;
|
||||||
|
animation: wave-lines 10s infinite ease-out;
|
||||||
|
padding: 12px 64px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,8 +1,12 @@
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
background: #e5e5e5;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
max-width: 1200px;
|
max-width: 1200px;
|
||||||
font-family: arial;
|
font-family: arial;
|
||||||
background: #e5e5e5;
|
|
||||||
padding: 0px 12px;
|
padding: 0px 12px;
|
||||||
.disabled-items {
|
.disabled-items {
|
||||||
opacity: 0.3;
|
opacity: 0.3;
|
||||||
|
|
20
source/src/tools/utilities/GetConfig.js
Normal file
20
source/src/tools/utilities/GetConfig.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
export var SERVER_ADMIN = import.meta.env.SERVER_ADMIN
|
||||||
|
export var SERVER_LOCATION = import.meta.env.SERVER_LOCATION
|
||||||
|
export var SERVER_DOMAIN = import.meta.env.SERVER_DOMAIN
|
||||||
|
export var FOOTER_VERSION = import.meta.env.FOOTER_VERSION
|
||||||
|
export var MODIFIED = import.meta.env.MODIFIED
|
||||||
|
export var CUSTOM_SOURCE_CODE = import.meta.env.CUSTOM_SOURCE_CODE
|
||||||
|
export var DEFAULT_LANGUAGE = import.meta.env.DEFAULT_LANGUAGE
|
||||||
|
export var DEFAULT_THEME = import.meta.env.DEFAULT_THEME
|
||||||
|
export var DEFAULT_API = import.meta.env.DEFAULT_API
|
||||||
|
export var DEFAULT_IMAGE_PROXY = import.meta.env.DEFAULT_IMAGE_PROXY
|
||||||
|
export var DEFAULT_IMAGE_PROXY_ENABLED = import.meta.env.DEFAULT_IMAGE_PROXY_ENABLED
|
||||||
|
export var DEFAULT_SEARCH_WEB = import.meta.env.DEFAULT_SEARCH_WEB
|
||||||
|
export var DEFAULT_SEARCH_IMAGE = import.meta.env.DEFAULT_SEARCH_IMAGE
|
||||||
|
export var DEFAULT_SEARCH_VIDEO = import.meta.env.DEFAULT_SEARCH_VIDEO
|
||||||
|
export var DEFAULT_SEARCH_MUSIC = import.meta.env.DEFAULT_SEARCH_MUSIC
|
||||||
|
export var DEFAULT_SEARCH_NEWS = import.meta.env.DEFAULT_SEARCH_NEWS
|
||||||
|
export var DEFAULT_FRONTEND_YOUTUBE = import.meta.env.DEFAULT_FRONTEND_YOUTUBE
|
||||||
|
export var DEFAULT_FRONTEND_YOUTUBEMUSIC = import.meta.env.DEFAULT_FRONTEND_YOUTUBEMUSIC
|
||||||
|
export var DEFAULT_FRONTEND_STACKOVERFLOW = import.meta.env.DEFAULT_FRONTEND_STACKOVERFLOW
|
||||||
|
export var DEFAULT_FRONTEND_MEDIUM = import.meta.env.DEFAULT_FRONTEND_MEDIUM
|
Reference in a new issue