1
Fork 0
This commit is contained in:
Korbs 2024-06-23 04:29:06 -04:00
parent ffc3614d87
commit 88800a938e
No known key found for this signature in database
10 changed files with 299 additions and 203 deletions

View file

@ -14,8 +14,13 @@ This repo is only a proof of concept to see how Poke will run in Astro. A lot of
- [ ] Dedicated Redirect Page - [ ] Dedicated Redirect Page
- [ ] Should pull from instances list (git.poketube.fun, not Codeberg) - [ ] Should pull from instances list (git.poketube.fun, not Codeberg)
- [ ] Search - [ ] Search
- Revamp Experience
- Filters - Filters
- Auto Complete - Auto Complete
- [ ] Video Page
- [ ] Toggle:
- [ ] Audio Only
- [ ] Autoplay
- [ ] User Settings - [ ] User Settings
- [ ] Invidious Server Selection - [ ] Invidious Server Selection
- [ ] SafeTwitch Backend Server Selection - [ ] SafeTwitch Backend Server Selection
@ -23,12 +28,10 @@ This repo is only a proof of concept to see how Poke will run in Astro. A lot of
- [ ] Video Player - [ ] Video Player
- [ ] Toggle: - [ ] Toggle:
- [ ] Proxy - [ ] Proxy
- [ ] Audio Only
- [ ] Autoplay
- [ ] Theme - [ ] Theme
- [ ] Preferred Language (For audio track on YouTube) - [ ] Preferred Language (For audio track on YouTube)
- [ ] Custom CSS/JS - [ ] Custom CSS/JS
- [ ] Import/Export YouTube Subscription - [ ] Import/Export YouTube Subscription (Use local session, no database crap)
- [ ] Import/Export Poke User Settings - [ ] Import/Export Poke User Settings
- [x] Add Twitch Support, use [SafeTwitch Backend](https://codeberg.org/SafeTwitch/safetwitch-backend) - [x] Add Twitch Support, use [SafeTwitch Backend](https://codeberg.org/SafeTwitch/safetwitch-backend)

View file

@ -1,169 +0,0 @@
---
// Properties
const {
Icon
} = Astro.props
// i18n
import i18next, { t } from "i18next";
import { Trans, HeadHrefLangs } from "astro-i18next/components";
// Icons
import {
Menu,
Settings,
ProfileCircle,
CircleSpark,
Youtube,
OpenNewWindow,
ViewGrid,
Arcade,
InfoCircle,
PrivacyPolicy,
Code,
Language,
NavArrowLeft,
NavArrowRight,
List
} from '@iconoir/vue'
// Check URL
if (Astro.url.pathname.startsWith('/watch')) {
var WatchPage = true
} else {
var WatchPage = false
}
---
<button class="dropdown-button" onclick="ToggleHeaderDropdown()"><Menu/></button>
<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>
</div>
<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 ToggleHeaderDropdown() {
var HeaderDropdown = document.querySelector(".header-dropdown#primary");
if (HeaderDropdown.style.display === "flex") {
HeaderDropdown.style.display = "none";
} else {
HeaderDropdown.style.display = "flex";
}
}
function ToggleHeaderLanguageDropdown() {
var HeaderLanguageDropdown = document.querySelector(".header-dropdown#language");
if (HeaderLanguageDropdown.style.display === "flex") {
HeaderLanguageDropdown.style.display = "none";
} else {
HeaderLanguageDropdown.style.display = "flex";
}
}
</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);
}
svg {
width: 18px;
pointer-events: none;
}
}
.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);
}
div {
display: flex;
align-items: center;
gap: 12px;
}
}
}
</style>

View file

@ -10,6 +10,7 @@ const {
BorderColor = "#222222", BorderColor = "#222222",
BorderWidth = "1px", BorderWidth = "1px",
BorderRadius = "4px", BorderRadius = "4px",
BackDrop,
// Optionals Options // Optionals Options
Target = "_self", Target = "_self",
@ -28,12 +29,13 @@ const {
+ '; border-color: ' + BorderColor + '; border-color: ' + BorderColor
+ '; border-width: ' + BorderWidth + '; border-width: ' + BorderWidth
+ '; border-radius: ' + BorderRadius + '; border-radius: ' + BorderRadius
+ '; backdrop-filter: ' + BackDrop
} }
> >
<slot/> <slot/>
</a> </a>
<style lang="scss" is:global> <style lang="scss" is:global define:vars={{ BorderRadius }}>
.generic-button { .generic-button {
display: flex; display: flex;
align-items: center; align-items: center;
@ -42,12 +44,15 @@ const {
border-style: solid; border-style: solid;
text-decoration: none; text-decoration: none;
max-width: max-content; max-width: max-content;
&:hover {
filter: brightness(0.75);
}
svg { svg {
background: rgba(255,255,255,0.1); // background: rgba(255,255,255,0.1);
border-radius: 4px 0px 0px 4px; border-radius: var(--BorderRadius) 0px 0px var(--BorderRadius);
padding: 6px; padding: 6px;
margin: -1px; margin: -1px;
margin-right: 6px; margin-left: 6px;
} }
} }
</style> </style>

View file

@ -23,13 +23,13 @@ const {
// Components // Components
import { ViewTransitions } from 'astro:transitions'; import { ViewTransitions } from 'astro:transitions';
import { fade } from "astro/virtual-modules/transitions.js"; import { slide } from "astro/virtual-modules/transitions.js";
--- ---
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<ViewTransitions transition:animate={fade} /> <ViewTransitions transition:animate={slide} />
<title>{Title}</title> <title>{Title}</title>
<link href=/favicon.ico rel=icon> <link href=/favicon.ico rel=icon>
<link rel="manifest" href="/manifest.json"> <link rel="manifest" href="/manifest.json">

View file

@ -5,8 +5,7 @@ import { Trans, HeadHrefLangs } from "astro-i18next/components";
// Components // Components
import { Image } from 'astro:assets'; import { Image } from 'astro:assets';
import { actions } from "astro:actions"; import Button from '@components/generic/Button.astro'
import Dropdown from '@components/Dropdown.astro'
// Images // Images
import Poke from '@assets/poke-text.svg' import Poke from '@assets/poke-text.svg'
@ -17,8 +16,28 @@ import {
Gamepad, Gamepad,
Settings, Settings,
Search, Search,
Language ProfileCircle,
CircleSpark,
Youtube,
OpenNewWindow,
ViewGrid,
Arcade,
InfoCircle,
PrivacyPolicy,
Code,
Language,
NavArrowLeft,
NavArrowRight,
List
} from '@iconoir/vue' } 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>
@ -26,15 +45,56 @@ import {
<div class="header-start"> <div class="header-start">
<a href={'/'}><Image src={Poke} alt="Poke Logo" height={24} /></a> <a href={'/'}><Image src={Poke} alt="Poke Logo" height={24} /></a>
</div> </div>
<div class="header-center"> <div class="header-center"></div>
<form>
<input type="search" placeholder={t('header.search')}/>
<button onclick="Search()"><Search/></button>
</form>
<!-- <div id="results"></div> -->
</div>
<div class="header-end"> <div class="header-end">
<Dropdown/> <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>
</div> </div>
</div> </div>
</header> </header>
@ -61,6 +121,117 @@ section 4, provided you include this license notice and a URL
through which recipients can access the Corresponding Source. through which recipients can access the Corresponding Source.
@licend The above is the entire license notice
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);
}
}
// 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";
}
}
</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);
}
svg {
width: 18px;
pointer-events: none;
}
}
.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);
}
div {
display: flex;
align-items: center;
gap: 12px;
}
}
}
</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 @licend The above is the entire license notice
for the JavaScript code in this page. for the JavaScript code in this page.
*/ */

View file

@ -19,7 +19,7 @@ import Chan from '@assets/chan/v2.png'
<Base Title="Poke" Description="▶▶ Poke - The privacy app of your dreams!"> <Base Title="Poke" Description="▶▶ Poke - The privacy app of your dreams!">
<video playsinline autoplay muted loop class="landing-background" src="/flurry-background.webm" type="video/webm"/> <video playsinline autoplay muted loop class="landing-background" src="/flurry-background.webm" type="video/webm"/>
<div class="landing"> <div class="landing">
<h1>{t("landing.heading")}</h1> <h1><span style="-webkit-text-stroke: 1px white; color: transparent;">{t("landing.heading1")}</span> {t("landing.heading2")}</h1>
<p style="max-width: 800px;">{t("landing.description")}</p> <p style="max-width: 800px;">{t("landing.description")}</p>
<div style="display: flex; gap: 12px;"> <div style="display: flex; gap: 12px;">
@ -122,6 +122,20 @@ video {
opacity: .27; opacity: .27;
pointer-events: none; pointer-events: none;
} }
.inline-it {
position: fixed;
top: 64px;
left: inherit;
width: 404px !important;
height: max-content;
object-fit: cover;
z-index: 1;
opacity: 1;
border-radius: 14px;
}
.landing { .landing {
margin: auto; margin: auto;
position: relative; position: relative;

View file

@ -0,0 +1,71 @@
---
// Layout
import Base from "@layouts/Default.astro";
// i18n
import i18next, { t } from "i18next";
import { Trans, HeadHrefLangs } from "astro-i18next/components";
// Fetch Suggestions
---
<Base Title="Poke" Description="▶▶ Poke - The privacy app of your dreams!">
<input type="search" placeholder="Poke Search..."/>
<div class="suggestions">
<p style="display: none" id="yt-text">YouTube Suggestions:</p>
<div id="suggestions-for-youtube"></div>
</div>
</Base>
<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.
*/
// When the end-user starts typing, trigget the fetch function
document.querySelector('input[type="search"]').addEventListener('input', function(e) {
if (e.target.value !== '') {
document.getElementById('yt-text').style.display = 'inherit'
GetResults()
}
else {null}
});
// Fetch
function GetResults() {
var SearchValue = document.querySelector('input[type="search"]').value
var YouTubeSuggestions = document.getElementById('suggestions-for-youtube')
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 => `<li><a href="/search?query=${data}">${data}</a></li>`).join("\n")
return `<ul class="suggestions">${text}</ul>`
}
</script>

View file

@ -14,8 +14,8 @@ const comments = await fetch('https://' + DEFAULT_INVIDIOUS_INSTANCE + "/api/v1/
--- ---
<Base Title={video.title}> <Base Title={video.title}>
<div class="video-container">
<video <video
class="inline-it"
autoplay autoplay
controls controls
poster={'https://i.ytimg.com/vi/' + video.videoId + '/maxresdefault.jpg'} poster={'https://i.ytimg.com/vi/' + video.videoId + '/maxresdefault.jpg'}
@ -24,5 +24,4 @@ const comments = await fetch('https://' + DEFAULT_INVIDIOUS_INSTANCE + "/api/v1/
src={'https://' + DEFAULT_INVIDIOUS_INSTANCE + '/latest_version?id=' + video.videoId} src={'https://' + DEFAULT_INVIDIOUS_INSTANCE + '/latest_version?id=' + video.videoId}
> >
</video> </video>
</div>
</Base> </Base>

View file

@ -23,7 +23,8 @@
"GoBack": "Go Back" "GoBack": "Go Back"
}, },
"landing": { "landing": {
"heading": "PRIVACY APP OF YOUR DREAMS", "heading1": "PRIVACY APP",
"heading2": "OF YOUR DREAMS",
"description": "Poke is a free software youtube front-end, search engine, translator, map app and even more!!1!! Watch silly videos, search stuff on the internet and do all of that and more anonymously in this all-in-one privacy app!!!1! :3", "description": "Poke is a free software youtube front-end, search engine, translator, map app and even more!!1!! Watch silly videos, search stuff on the internet and do all of that and more anonymously in this all-in-one privacy app!!!1! :3",
"why": "Why Choose Poke?", "why": "Why Choose Poke?",
"Card1Title": "No Tracking and Ads", "Card1Title": "No Tracking and Ads",

View file

@ -23,7 +23,8 @@
"GoBack": "戻る" "GoBack": "戻る"
}, },
"landing": { "landing": {
"heading": "あなたの夢のプライバシーアプリ", "heading1": "のプライバシーアプリ",
"heading2": "君の夢の",
"description": "Pokeは、無料のソフトウェアyoutubeフロントエンド、検索エンジン、翻訳者、マップアプリなどです!!1!! サイレント動画を見ると、インターネット上のものを検索し、このオールインワンのプライバシーアプリで、そのすべてを匿名で行います!", "description": "Pokeは、無料のソフトウェアyoutubeフロントエンド、検索エンジン、翻訳者、マップアプリなどです!!1!! サイレント動画を見ると、インターネット上のものを検索し、このオールインワンのプライバシーアプリで、そのすべてを匿名で行います!",
"why": "ポケモンを選ぶ理由?", "why": "ポケモンを選ぶ理由?",
"Card1Title": "追跡および広告無し", "Card1Title": "追跡および広告無し",