mirror of
https://github.com/NebulaServices/Nebula.git
synced 2025-05-17 13:30:00 -04:00
Tab cloaking
This commit is contained in:
parent
78635d2671
commit
4d7c8449d8
13 changed files with 150 additions and 36 deletions
|
@ -2,10 +2,8 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/logo.png" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<meta name="color-scheme" content="light dark" />
|
<meta name="color-scheme" content="light dark" />
|
||||||
<title>Nebula</title>
|
|
||||||
<script src="/uv/uv.bundle.js"></script>
|
<script src="/uv/uv.bundle.js"></script>
|
||||||
<script src="/uv/uv.config.js"></script>
|
<script src="/uv/uv.config.js"></script>
|
||||||
<script src="/dynamic/dynamic.config.js"></script>
|
<script src="/dynamic/dynamic.config.js"></script>
|
||||||
|
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
@ -44,6 +44,10 @@
|
||||||
"embed": "Embed",
|
"embed": "Embed",
|
||||||
"direct": "Direct",
|
"direct": "Direct",
|
||||||
"aboutblank": "About:Blank"
|
"aboutblank": "About:Blank"
|
||||||
|
},
|
||||||
|
"cloaking": {
|
||||||
|
"title": "Cloaking",
|
||||||
|
"subtitle": "Choose how your tab looks"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"titles": {
|
"titles": {
|
||||||
|
|
|
@ -44,6 +44,10 @@
|
||||||
"embed": "Incrustar",
|
"embed": "Incrustar",
|
||||||
"direct": "Directo",
|
"direct": "Directo",
|
||||||
"aboutblank": "About:Blank"
|
"aboutblank": "About:Blank"
|
||||||
|
},
|
||||||
|
"cloaking": {
|
||||||
|
"title": "Encubrimiento",
|
||||||
|
"subtitle": "Elige cómo se ve tu pestaña"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"titles": {
|
"titles": {
|
||||||
|
|
|
@ -44,6 +44,10 @@
|
||||||
"embed": "埋め込む",
|
"embed": "埋め込む",
|
||||||
"direct": "直接",
|
"direct": "直接",
|
||||||
"aboutblank": "About:Blank"
|
"aboutblank": "About:Blank"
|
||||||
|
},
|
||||||
|
"cloaking": {
|
||||||
|
"title": "クローキング",
|
||||||
|
"subtitle": "タブの見た目を選択する"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"titles": {
|
"titles": {
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import { useState } from "preact/hooks";
|
import { useState } from "preact/hooks";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { HeaderRoute } from "../components/HeaderRoute";
|
import { HeaderRoute } from "../components/HeaderRoute";
|
||||||
import { Helmet } from "react-helmet";
|
import CloakedHead from "../util/CloakedHead";
|
||||||
|
|
||||||
export function Home() {
|
export function Home() {
|
||||||
const [isFocused, setIsFocused] = useState(false);
|
const [isFocused, setIsFocused] = useState(false);
|
||||||
const [inputValue, setInputValue] = useState("");
|
const [inputValue, setInputValue] = useState("");
|
||||||
|
@ -15,9 +14,10 @@ export function Home() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HeaderRoute>
|
<HeaderRoute>
|
||||||
<Helmet>
|
<CloakedHead
|
||||||
<title>{t("titles.home")}</title>
|
originalTitle={t("titles.home")}
|
||||||
</Helmet>
|
originalFavicon="/logo.png"
|
||||||
|
/>
|
||||||
<div class="flex h-full flex-col items-center justify-center">
|
<div class="flex h-full flex-col items-center justify-center">
|
||||||
<div class="font-inter absolute bottom-0 left-0 p-4 text-sm italic text-input-text">
|
<div class="font-inter absolute bottom-0 left-0 p-4 text-sm italic text-input-text">
|
||||||
Nebula © Nebula Services {new Date().getUTCFullYear()}
|
Nebula © Nebula Services {new Date().getUTCFullYear()}
|
||||||
|
|
|
@ -3,8 +3,9 @@ import { searchUtil } from "../util/searchUtil";
|
||||||
import { useEffect, useState } from "preact/hooks";
|
import { useEffect, useState } from "preact/hooks";
|
||||||
//import our Iframe component
|
//import our Iframe component
|
||||||
import { Iframe } from "../components/iframe/Iframe";
|
import { Iframe } from "../components/iframe/Iframe";
|
||||||
|
import CloakedHead from "../util/CloakedHead";
|
||||||
import SiteSupport from "../util/SiteSupport.json";
|
import SiteSupport from "../util/SiteSupport.json";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
|
@ -14,6 +15,7 @@ declare global {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ProxyFrame(props: { url: string }) {
|
export function ProxyFrame(props: { url: string }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
// pass the URL encoded with encodeURIcomponent
|
// pass the URL encoded with encodeURIcomponent
|
||||||
const localProxy = localStorage.getItem("proxy") || "automatic";
|
const localProxy = localStorage.getItem("proxy") || "automatic";
|
||||||
const proxyMode = localStorage.getItem("proxyMode") || "embed";
|
const proxyMode = localStorage.getItem("proxyMode") || "embed";
|
||||||
|
@ -104,6 +106,10 @@ export function ProxyFrame(props: { url: string }) {
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div class="h-screen w-screen bg-primary">
|
<div class="h-screen w-screen bg-primary">
|
||||||
|
<CloakedHead
|
||||||
|
originalTitle={t("titles.home")}
|
||||||
|
originalFavicon="/logo.png"
|
||||||
|
/>
|
||||||
{proxyMode === "direct" && <h1>Loading {localProxy}...</h1>}
|
{proxyMode === "direct" && <h1>Loading {localProxy}...</h1>}
|
||||||
{proxyMode === "aboutblank" && <h1>Loading {localProxy}...</h1>}
|
{proxyMode === "aboutblank" && <h1>Loading {localProxy}...</h1>}
|
||||||
{proxyMode === "embed" && <Iframe url={ProxiedUrl} />}
|
{proxyMode === "embed" && <Iframe url={ProxiedUrl} />}
|
||||||
|
|
30
src/pages/Settings/CloakPreset.tsx
Normal file
30
src/pages/Settings/CloakPreset.tsx
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
import { useState, useEffect } from "preact/hooks";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
faviconUrl: string;
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CloakPreset = (props: Props) => {
|
||||||
|
const cloak = (event: any) => {
|
||||||
|
event.preventDefault();
|
||||||
|
console.log(props.faviconUrl);
|
||||||
|
localStorage.setItem("cloakFavicon", props.faviconUrl);
|
||||||
|
localStorage.setItem("cloakTitle", props.title);
|
||||||
|
window.location.reload();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
onClick={cloak}
|
||||||
|
class="cursor-pointer rounded-full border border-input-border-color bg-lighter"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={props.faviconUrl === "none" ? "/logo.png" : props.faviconUrl}
|
||||||
|
class="h-16 w-16 p-4"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CloakPreset;
|
|
@ -1,20 +1,47 @@
|
||||||
import { motion } from "framer-motion";
|
import { motion } from "framer-motion";
|
||||||
import { tabContentVariant, settingsPageVariant } from "./Variants";
|
import { tabContentVariant, settingsPageVariant } from "./Variants";
|
||||||
|
import CloakPreset from "./CloakPreset";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
const TabSettings = ({ id, active }) => (
|
const TabSettings = ({ id, active }) => {
|
||||||
<motion.div
|
const { t } = useTranslation();
|
||||||
role="tabpanel"
|
|
||||||
id={id}
|
return (
|
||||||
className="tab-content"
|
<motion.div
|
||||||
variants={tabContentVariant}
|
role="tabpanel"
|
||||||
animate={active ? "active" : "inactive"}
|
id={id}
|
||||||
initial="inactive"
|
className="tab-content"
|
||||||
>
|
variants={tabContentVariant}
|
||||||
<motion.div variants={settingsPageVariant} className="content-card text-center w-full flex flex-col justify-center items-center">
|
animate={active ? "active" : "inactive"}
|
||||||
<img src="/comingsoonsnake.png" class="h-72 w-72"></img>
|
initial="inactive"
|
||||||
<h1 class="font-roboto text-3xl">Coming soon!</h1>
|
>
|
||||||
|
<motion.div
|
||||||
|
variants={settingsPageVariant}
|
||||||
|
className="content-card flex w-full flex-col items-center justify-center text-center"
|
||||||
|
>
|
||||||
|
<div class="text-3xl">{t("settings.cloaking.title")}</div>
|
||||||
|
<div class="text-md pb-5">{t("settings.cloaking.subtitle")}</div>
|
||||||
|
<div class="flex flex-row space-x-4">
|
||||||
|
<CloakPreset faviconUrl="none" title="none" />
|
||||||
|
<CloakPreset
|
||||||
|
faviconUrl="https://t1.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url=http://google.com&size=32"
|
||||||
|
title="Google"
|
||||||
|
/>
|
||||||
|
<CloakPreset
|
||||||
|
faviconUrl="https://www.wikipedia.org/static/favicon/wikipedia.ico"
|
||||||
|
title="Wikipedia"
|
||||||
|
/>
|
||||||
|
<CloakPreset
|
||||||
|
faviconUrl="https://du11hjcvx0uqb.cloudfront.net/dist/images/favicon-e10d657a73.ico"
|
||||||
|
title="Dashboard"
|
||||||
|
/>
|
||||||
|
<CloakPreset
|
||||||
|
faviconUrl="https://ssl.gstatic.com/classroom/ic_product_classroom_144.png"
|
||||||
|
title="Home"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</motion.div>
|
);
|
||||||
);
|
};
|
||||||
|
|
||||||
export default TabSettings;
|
export default TabSettings;
|
||||||
|
|
|
@ -1,17 +1,18 @@
|
||||||
import TabComponent from "./TabComponent";
|
import TabComponent from "./TabComponent";
|
||||||
import { HeaderRoute } from "../../components/HeaderRoute";
|
import { HeaderRoute } from "../../components/HeaderRoute";
|
||||||
import tabs from "./tabs";
|
import tabs from "./tabs";
|
||||||
import { Helmet } from "react-helmet";
|
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
import CloakedHead from "../../util/CloakedHead";
|
||||||
|
|
||||||
export function Settings() {
|
export function Settings() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HeaderRoute>
|
<HeaderRoute>
|
||||||
<Helmet>
|
<CloakedHead
|
||||||
<title>{t("titles.settings")}</title>
|
originalTitle={t("titles.settings")}
|
||||||
</Helmet>
|
originalFavicon="/logo.png"
|
||||||
|
/>
|
||||||
<TabComponent tabs={tabs} />
|
<TabComponent tabs={tabs} />
|
||||||
</HeaderRoute>
|
</HeaderRoute>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Link } from "preact-router";
|
import { Link } from "preact-router";
|
||||||
import { HeaderRoute } from "../components/HeaderRoute";
|
import { HeaderRoute } from "../components/HeaderRoute";
|
||||||
import { Helmet } from "react-helmet";
|
import CloakedHead from "../util/CloakedHead";
|
||||||
|
|
||||||
export function NotFound() {
|
export function NotFound() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HeaderRoute>
|
<HeaderRoute>
|
||||||
<Helmet>
|
<CloakedHead
|
||||||
<title>{t("titles.404")}</title>
|
originalTitle={t("titles.404")}
|
||||||
</Helmet>
|
originalFavicon="/logo.png"
|
||||||
|
/>
|
||||||
<section class="h-full">
|
<section class="h-full">
|
||||||
<div class="flex h-full flex-col items-center justify-center">
|
<div class="flex h-full flex-col items-center justify-center">
|
||||||
<img src="/404.png" class="h-72"></img>
|
<img src="/404.png" class="h-72"></img>
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { HeaderRoute } from "../components/HeaderRoute";
|
import { HeaderRoute } from "../components/HeaderRoute";
|
||||||
import { Helmet } from "react-helmet";
|
import CloakedHead from "../util/CloakedHead";
|
||||||
|
|
||||||
export function DiscordPage() {
|
export function DiscordPage() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HeaderRoute>
|
<HeaderRoute>
|
||||||
<Helmet>
|
<CloakedHead
|
||||||
<title>{t("titles.discord")}</title>
|
originalTitle={t("titles.discord")}
|
||||||
</Helmet>
|
originalFavicon="/logo.png"
|
||||||
|
/>
|
||||||
<section class="h-full">
|
<section class="h-full">
|
||||||
<div class="flex h-full flex-col items-center justify-center">
|
<div class="flex h-full flex-col items-center justify-center">
|
||||||
<img src="/discord.png" class="h-72 w-72"></img>
|
<img src="/services.png" class="h-72 w-72"></img>
|
||||||
<div class="flex flex-col items-center p-6">
|
<div class="flex flex-col items-center p-6">
|
||||||
<p class="font-roboto text-4xl font-bold">{t("discord.title")}</p>
|
<p class="font-roboto text-4xl font-bold">{t("discord.title")}</p>
|
||||||
<span class="font-roboto text-3xl">{t("discord.sub")}</span>
|
<span class="font-roboto text-3xl">{t("discord.sub")}</span>
|
||||||
|
|
38
src/util/CloakedHead.tsx
Normal file
38
src/util/CloakedHead.tsx
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import { Helmet } from "react-helmet";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
originalTitle: string;
|
||||||
|
originalFavicon: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CloakedHead = (props: Props) => {
|
||||||
|
var isTitleCloaked =
|
||||||
|
localStorage.getItem("cloakTitle") !== null
|
||||||
|
? localStorage.getItem("cloakTitle") !== "none"
|
||||||
|
: false;
|
||||||
|
|
||||||
|
var isFaviconCloaked =
|
||||||
|
localStorage.getItem("cloakFavicon") !== null
|
||||||
|
? localStorage.getItem("cloakFavicon") !== "none"
|
||||||
|
: false;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Helmet>
|
||||||
|
<title>
|
||||||
|
{isTitleCloaked
|
||||||
|
? localStorage.getItem("cloakTitle")
|
||||||
|
: props.originalTitle}
|
||||||
|
</title>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
href={
|
||||||
|
isFaviconCloaked
|
||||||
|
? localStorage.getItem("cloakFavicon")
|
||||||
|
: props.originalFavicon
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Helmet>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CloakedHead;
|
Loading…
Add table
Add a link
Reference in a new issue