mirror of
https://github.com/ReVanced/revanced-website.git
synced 2026-01-27 21:01:03 +00:00
refactor: restructure folder layout
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<script>
|
||||
<script lang="ts">
|
||||
// See: https://github.com/JonasKruckenberg/imagetools/blob/main/docs/directives.md#picture
|
||||
export let data;
|
||||
export let alt;
|
||||
export let alt: string;
|
||||
</script>
|
||||
|
||||
<picture>
|
||||
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
@@ -1,56 +0,0 @@
|
||||
<script lang="ts">
|
||||
import type { DocumentInfo } from '$lib/documentation.shared';
|
||||
export let info: DocumentInfo;
|
||||
import { page } from '$app/stores';
|
||||
</script>
|
||||
|
||||
<!-- Always part of a list -->
|
||||
<li>
|
||||
<a href="/docs/{info.slug}">
|
||||
<div class="doc-section item" class:selected={$page.url.pathname === `/docs/${info.slug}`}>
|
||||
<h5>{info.title}</h5>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<style>
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
}
|
||||
.item {
|
||||
padding: 0.6rem 1rem;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.6rem;
|
||||
width: 100%;
|
||||
user-select: none;
|
||||
transition: background-color 0.4s var(--bezier-one);
|
||||
}
|
||||
|
||||
.item h5 {
|
||||
color: var(--grey-five);
|
||||
transition: color 0.3s var(--bezier-one);
|
||||
}
|
||||
|
||||
.selected h5 {
|
||||
color: var(--grey-four);
|
||||
transition: color 0.3s var(--bezier-one);
|
||||
}
|
||||
|
||||
.selected {
|
||||
background-color: var(--accent-color);
|
||||
}
|
||||
.item:hover:not(.selected) {
|
||||
background-color: var(--grey-six);
|
||||
}
|
||||
|
||||
.item:not(.selected):hover h5 {
|
||||
color: var(--white);
|
||||
}
|
||||
</style>
|
||||
@@ -1,37 +0,0 @@
|
||||
<script>
|
||||
import Picture from './Picture.svelte';
|
||||
import manager_screenshot from '$images/manager_two.png?w=1233;822;411&format=avif;webp;png&picture';
|
||||
</script>
|
||||
|
||||
<div class="hero-img">
|
||||
<Picture data={manager_screenshot} alt="Screenshot of ReVanced Manager" />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.hero-img :global(img) {
|
||||
height: 100%;
|
||||
border-radius: 1.75rem;
|
||||
}
|
||||
|
||||
.hero-img {
|
||||
overflow: hidden;
|
||||
height: 70vh;
|
||||
max-height: 70rem;
|
||||
z-index: -1;
|
||||
width: auto;
|
||||
float: right;
|
||||
padding: 0.5rem 0.5rem;
|
||||
border-radius: 1.75rem;
|
||||
background-color: var(--grey-six);
|
||||
user-select: none;
|
||||
|
||||
}
|
||||
@media (max-width: 1700px) {
|
||||
.hero-img {
|
||||
position: fixed;
|
||||
height: 100vh;
|
||||
top: 115px;
|
||||
right: 6rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,72 +0,0 @@
|
||||
<script>
|
||||
import RouterEvents from '../../../data/RouterEvents';
|
||||
export let href = '/';
|
||||
export let is_selected = (target_url) => href === target_url;
|
||||
</script>
|
||||
|
||||
<a data-sveltekit-prefetch {href}>
|
||||
<li class:selected={is_selected($RouterEvents.target_url.pathname)}>
|
||||
<h5>
|
||||
<slot />
|
||||
</h5>
|
||||
</li>
|
||||
</a>
|
||||
|
||||
<style>
|
||||
li {
|
||||
border: var(--grey-six);
|
||||
text-align: center;
|
||||
list-style: none;
|
||||
position: relative;
|
||||
font-weight: 500;
|
||||
font-size: 1rem;
|
||||
align-items: center;
|
||||
border: var(--grey-six);
|
||||
transition-timing-function: var(--bezier-one);
|
||||
transition-duration: 0.25s;
|
||||
padding: 10px 16px;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
font-size: 1rem;
|
||||
user-select: none;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
li:hover {
|
||||
color: var(--white);
|
||||
background-color: var(--grey-one);
|
||||
}
|
||||
|
||||
li.selected {
|
||||
background-color: var(--grey-one);
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
li.selected h5 {
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
li {
|
||||
padding: 1rem 1.5rem;
|
||||
text-align: left;
|
||||
justify-content: left;
|
||||
border-radius: 16px;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
li.selected {
|
||||
background-color: var(--accent-color);
|
||||
}
|
||||
|
||||
li.selected h5 {
|
||||
color: var(--grey-four);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,43 +0,0 @@
|
||||
<script>
|
||||
export let src = 'github';
|
||||
export let href = '#';
|
||||
</script>
|
||||
|
||||
<a {href} rel="noreferrer" target="_blank">
|
||||
<div>
|
||||
<img src="socials/{src}.svg" alt={src} />
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<style>
|
||||
div {
|
||||
border: 0;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
padding: 14px;
|
||||
cursor: pointer;
|
||||
border-radius: 200px;
|
||||
transition: transform 0.4s var(--bezier-one);
|
||||
background-color: var(--grey-two);
|
||||
color: var(--white);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
div {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
img {
|
||||
transition: filter 0.4s var(--bezier-one);
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
div:hover {
|
||||
transform: translateY(-5%);
|
||||
}
|
||||
|
||||
div:hover img {
|
||||
filter: brightness(1.2);
|
||||
}
|
||||
</style>
|
||||
@@ -1,37 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { is_tree } from '$lib/documentation.shared';
|
||||
import type { DocsTree } from '$lib/documentation.shared';
|
||||
|
||||
import DocsNavNode from '$lib/components/atoms/DocsNavNode.svelte';
|
||||
|
||||
export let tree: DocsTree;
|
||||
// How deeply nested this is.
|
||||
export let nested = 0;
|
||||
</script>
|
||||
|
||||
{#if nested}
|
||||
<!-- The index should be part of the `ul` above us. -->
|
||||
<DocsNavNode info={tree.index} />
|
||||
{/if}
|
||||
|
||||
<ul>
|
||||
{#if !nested}
|
||||
<!-- There is no `ul` above us, so index should go here instead. -->
|
||||
<DocsNavNode info={tree.index} />
|
||||
{/if}
|
||||
|
||||
{#each tree.nodes as node}
|
||||
{#if is_tree(node)}
|
||||
<!-- Recursion here is fine. We are not dealing with a tree the size of a linux root file system. -->
|
||||
<svelte:self tree={node} nested={nested + 1} />
|
||||
{:else}
|
||||
<DocsNavNode info={node} />
|
||||
{/if}
|
||||
{/each}
|
||||
</ul>
|
||||
|
||||
<style>
|
||||
ul {
|
||||
padding-left: 1rem;
|
||||
}
|
||||
</style>
|
||||
@@ -1,17 +0,0 @@
|
||||
<script>
|
||||
import { slide } from 'svelte/transition';
|
||||
</script>
|
||||
|
||||
<div transition:slide>
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
div {
|
||||
position: fixed;
|
||||
width: 100vw;
|
||||
top: 70px;
|
||||
z-index: 999;
|
||||
background-color: var(--grey-seven);
|
||||
}
|
||||
</style>
|
||||
@@ -1,159 +0,0 @@
|
||||
<script lang="ts">
|
||||
import Navigation from '../atoms/NavButton.svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import RouterEvents from '../../../data/RouterEvents';
|
||||
import Svg from '../atoms/Svg.svelte';
|
||||
import Modal from '../atoms/Modal.svelte';
|
||||
|
||||
import * as settings from '../../../data/api/settings';
|
||||
import { clear_and_reload } from '../../../data/api/cache';
|
||||
import Button from '../atoms/Button.svelte';
|
||||
|
||||
let url = settings.api_base_url();
|
||||
|
||||
function save() {
|
||||
settings.set_api_base_url(url);
|
||||
clear_and_reload();
|
||||
}
|
||||
|
||||
function reset() {
|
||||
url = settings.default_base_url;
|
||||
}
|
||||
|
||||
let menuOpen = false;
|
||||
let modalOpen = false;
|
||||
let y: number;
|
||||
|
||||
onMount(() => {
|
||||
return RouterEvents.subscribe((event) => {
|
||||
if (event.navigating) {
|
||||
menuOpen = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- give me a bit, ill add back mobile nav -->
|
||||
<nav class:scrolled={y > 10}>
|
||||
<div id="left-side">
|
||||
<img src="/logo.svg" id="logo" alt="ReVanced Logo" />
|
||||
<div class="nav-buttons">
|
||||
<Navigation href="/">Home</Navigation>
|
||||
<Navigation href="/download">Download</Navigation>
|
||||
<Navigation href="/patches">Patches</Navigation>
|
||||
<div hidden>
|
||||
<!-- This is just temporary so the build doesn't fail -->
|
||||
<Navigation is_selected={(target) => target.startsWith('/docs')} href="/docs"
|
||||
>Docs</Navigation
|
||||
>
|
||||
</div>
|
||||
<Navigation href="/contributors">Contributors</Navigation>
|
||||
</div>
|
||||
</div>
|
||||
<div id="right-side">
|
||||
<button on:click={() => (modalOpen = !modalOpen)}>
|
||||
<Svg viewBoxHeight={24} svgHeight={20}>
|
||||
<path
|
||||
d="M19.43 12.98c.04-.32.07-.64.07-.98 0-.34-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.09-.16-.26-.25-.44-.25-.06 0-.12.01-.17.03l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.06-.02-.12-.03-.18-.03-.17 0-.34.09-.43.25l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98 0 .33.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.09.16.26.25.44.25.06 0 .12-.01.17-.03l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.06.02.12.03.18.03.17 0 .34-.09.43-.25l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zm-1.98-1.71c.04.31.05.52.05.73 0 .21-.02.43-.05.73l-.14 1.13.89.7 1.08.84-.7 1.21-1.27-.51-1.04-.42-.9.68c-.43.32-.84.56-1.25.73l-1.06.43-.16 1.13-.2 1.35h-1.4l-.19-1.35-.16-1.13-1.06-.43c-.43-.18-.83-.41-1.23-.71l-.91-.7-1.06.43-1.27.51-.7-1.21 1.08-.84.89-.7-.14-1.13c-.03-.31-.05-.54-.05-.74s.02-.43.05-.73l.14-1.13-.89-.7-1.08-.84.7-1.21 1.27.51 1.04.42.9-.68c.43-.32.84-.56 1.25-.73l1.06-.43.16-1.13.2-1.35h1.39l.19 1.35.16 1.13 1.06.43c.43.18.83.41 1.23.71l.91.7 1.06-.43 1.27-.51.7 1.21-1.07.85-.89.7.14 1.13zM12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 6c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"
|
||||
/>
|
||||
</Svg>
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- settings -->
|
||||
<Modal bind:modalOpen>
|
||||
<div class="settings-menu">
|
||||
<h3>Backend</h3>
|
||||
<h6>API URL</h6>
|
||||
<div id="content">
|
||||
<div class="input-wrapper">
|
||||
<input name="api-url" type="text" bind:value={url} />
|
||||
<button class="button-reset" on:click={reset}>
|
||||
<Svg viewBoxHeight={48} svgHeight={24}>
|
||||
<path
|
||||
d="M11.2 36.725C14.6667 40.2417 18.8833 42 23.85 42C26.35 42 28.7 41.525 30.9 40.575C33.1 39.625 35.025 38.3333 36.675 36.7C38.325 35.0667 39.625 33.15 40.575 30.95C41.525 28.75 42 26.4 42 23.9C42 21.4 41.525 19.0667 40.575 16.9C39.625 14.7333 38.325 12.8417 36.675 11.225C35.025 9.60833 33.1 8.33333 30.9 7.4C28.7 6.46667 26.35 6 23.85 6C21.1833 6 18.6583 6.58333 16.275 7.75C13.8917 8.91667 11.8333 10.5167 10.1 12.55V7.25H7.1V17.65H17.55V14.65H12.3C13.7667 12.95 15.4917 11.5833 17.475 10.55C19.4583 9.51667 21.5833 9 23.85 9C28.0167 9 31.5833 10.425 34.55 13.275C37.5167 16.125 39 19.6167 39 23.75C39 27.9833 37.5333 31.5833 34.6 34.55C31.6667 37.5167 28.0833 39 23.85 39C19.6833 39 16.1667 37.5333 13.3 34.6C10.4333 31.6667 9 28.1167 9 23.95H6C6 28.95 7.73333 33.2083 11.2 36.725Z"
|
||||
/>
|
||||
</Svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<Button kind="primary" on:click={save}>Save</Button>
|
||||
<Button on:click={clear_and_reload}>Clear Cache</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<svelte:window bind:scrollY={y} />
|
||||
|
||||
<style>
|
||||
path {
|
||||
fill: var(--grey-five);
|
||||
}
|
||||
button:hover path {
|
||||
fill: var(--accent-color-two);
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.settings-menu h3 {
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
.settings-menu h6 {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.input-wrapper {
|
||||
margin-bottom: 0.75rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
display: flex;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
input {
|
||||
width: 90%;
|
||||
}
|
||||
nav {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 1rem 2rem;
|
||||
z-index: 666;
|
||||
height: 70px;
|
||||
background-color: var(--grey-seven);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#left-side,
|
||||
#right-side {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
img {
|
||||
height: 24px;
|
||||
}
|
||||
.nav-buttons {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.scrolled {
|
||||
box-shadow: 0px 4px 5px 0px rgba(0, 0, 0, 0.14), 0px 1px 10px 0px rgba(0, 0, 0, 0.12),
|
||||
0px 2px 4px -1px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
</style>
|
||||
@@ -1,33 +0,0 @@
|
||||
<script>
|
||||
import SocialButton from '../atoms/SocialButton.svelte';
|
||||
</script>
|
||||
|
||||
<div class="social-host">
|
||||
<SocialButton src="github" href="https://revanced.app/github" />
|
||||
<SocialButton src="discord" href="http://revanced.app/discord" />
|
||||
<SocialButton src="reddit" href="https://revanced.app/reddit" />
|
||||
<SocialButton src="telegram" href="https://revanced.app/telegram" />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.social-host {
|
||||
width: min(87%, 100rem);
|
||||
padding: 0 max(6.5%, calc(50vw - 50rem));
|
||||
align-items: center;
|
||||
user-select: none;
|
||||
position: absolute;
|
||||
display: flex;
|
||||
bottom: 2rem;
|
||||
gap: 1rem;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
.social-host {
|
||||
left: 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,77 +0,0 @@
|
||||
<script>
|
||||
import Button from '$lib/components/atoms/Button.svelte';
|
||||
</script>
|
||||
|
||||
<section class="hero">
|
||||
<div class="hero-text">
|
||||
<h5>ANDROID APP PATCHER</h5>
|
||||
<h1>
|
||||
Continuing the <br />legacy of <span>Vanced.</span>
|
||||
</h1>
|
||||
<h4>
|
||||
Customize your mobile experience through ReVanced <br /> by applying patches to your applications.
|
||||
</h4>
|
||||
|
||||
<div class="hero-buttons">
|
||||
<Button icon="download" kind="primary" capitalize href="download">Download Manager</Button>
|
||||
<Button icon="docs" href="patches" capitalize>View patches</Button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<style>
|
||||
h1 {
|
||||
color: var(--white);
|
||||
font-weight: 700;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
h5 {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
h4 {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.hero {
|
||||
padding-bottom: 9rem;
|
||||
}
|
||||
|
||||
.hero-text {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.hero-buttons {
|
||||
display: flex;
|
||||
user-select: none;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
span {
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.hero {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: clamp(3rem, 10vw, 3rem);
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: clamp(1rem, 1.2rem, 1.5rem);
|
||||
}
|
||||
|
||||
br {
|
||||
content: ' ';
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
.hero-buttons {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,96 +0,0 @@
|
||||
#markup-content {
|
||||
/* Defaults for text */
|
||||
color: var(--accent-color-two);
|
||||
font-weight: 300;
|
||||
font-size: 1rem;
|
||||
line-height: 1.75rem;
|
||||
letter-spacing: 0.03rem !important;
|
||||
|
||||
|
||||
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: var(--accent-color);
|
||||
border-bottom: 1.5px solid var(--accent-low-opacity);
|
||||
padding: 0px ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
code {
|
||||
background-color: var(--grey-one);
|
||||
border-radius: 8px;
|
||||
padding: 0.2rem 0.5rem;
|
||||
font-size: 0.8rem;
|
||||
font-family: var(--mono-font);
|
||||
font-weight: 300;
|
||||
flex-wrap: wrap;
|
||||
line-height: 1.25rem;
|
||||
}
|
||||
|
||||
|
||||
|
||||
pre code {
|
||||
font-size: 0.75rem;
|
||||
background-color: var(--grey-six);
|
||||
white-space: pre;
|
||||
display: block;
|
||||
flex-wrap: wrap;
|
||||
padding: 0.5rem 1rem;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
h5 {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
h5 {
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5 {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.25rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.02rem;
|
||||
color: var(--accent-color-two);
|
||||
border-bottom: 1px solid var(--grey-three);
|
||||
padding-bottom: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.5rem;
|
||||
letter-spacing: -0.02rem;
|
||||
font-weight: 600;
|
||||
color: var(--accent-color-two);
|
||||
border-bottom: 1px solid var(--grey-three);
|
||||
padding-bottom: 1rem;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-left: 1rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
/* Markup processors output this for bold text, but css spec is goofy aah */
|
||||
strong {
|
||||
font-weight: bold;
|
||||
letter-spacing: 0.01rem;
|
||||
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 2rem;
|
||||
}
|
||||
}
|
||||
@@ -1,210 +0,0 @@
|
||||
import { is_tree } from './documentation.shared';
|
||||
import type { Document, DocsTree, DocsTreeNode, DocumentInfo } from './documentation.shared';
|
||||
|
||||
import { browser, prerendering } from '$app/environment';
|
||||
|
||||
import fs, { existsSync as exists } from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
|
||||
import { parse as parse_md } from 'marked';
|
||||
import AsciiDocProcessor from 'asciidoctor'
|
||||
|
||||
// This file does not work in a browser.
|
||||
if (browser) {
|
||||
throw Error('SvelteKit has skill issues');
|
||||
}
|
||||
|
||||
/// Constants
|
||||
|
||||
const supported_formats: Map<string, (markup: string) => Document> = new Map();
|
||||
|
||||
supported_formats.set("md", markup => {
|
||||
let lines = markup.split('\n');
|
||||
|
||||
// Get and remove the first line.
|
||||
const first_line = lines.splice(0, 1)[0];
|
||||
// Remove `# `.
|
||||
const title = first_line.substring(2);
|
||||
|
||||
// Convert the rest to html
|
||||
const content = parse_md(lines.join('\n'));
|
||||
|
||||
return { title, content };
|
||||
});
|
||||
|
||||
const asciidoctor = AsciiDocProcessor();
|
||||
const adoc_fn = markup => {
|
||||
// Get first line.
|
||||
const first_line = markup.split('\n')[0];
|
||||
// Remove `= `.
|
||||
const title = first_line.substring(2);
|
||||
|
||||
// Convert it to html. Unlike markdown, we do not need to remove the first title heading.
|
||||
// NOTE: Maybe consider change the safe mode value.
|
||||
const content = asciidoctor.convert(markup, { doctype: "book" })
|
||||
|
||||
return { title, content };
|
||||
}
|
||||
|
||||
supported_formats.set("adoc", adoc_fn)
|
||||
supported_formats.set("asciidoc", adoc_fn)
|
||||
|
||||
const supported_filetypes = [...supported_formats.keys()];
|
||||
|
||||
let docs_folder = process.env.REVANCED_DOCS_FOLDER;
|
||||
if (docs_folder === undefined) {
|
||||
if (prerendering) { console.warn("Using testing docs in production build") }
|
||||
docs_folder = "testing-docs";
|
||||
}
|
||||
|
||||
const ignored_items = ["assets"];
|
||||
|
||||
/// Utility functions
|
||||
|
||||
function is_directory(item: string) {
|
||||
return fs.lstatSync(item).isDirectory();
|
||||
}
|
||||
|
||||
function get_ext(fname: string) {
|
||||
// Get extname and remove the first dot.
|
||||
return path.extname(fname).substring(1);
|
||||
}
|
||||
|
||||
function get_slug_of_node(node: DocsTreeNode): string {
|
||||
if (is_tree(node)) {
|
||||
return node.index.slug;
|
||||
}
|
||||
|
||||
return node.slug;
|
||||
}
|
||||
|
||||
/// Important functions
|
||||
|
||||
// Get a document. Returns null if it does not exist.
|
||||
export function get(slug: string): Document|null {
|
||||
let target = path.join(docs_folder, slug);
|
||||
// Handle index (readme) file for folder.
|
||||
if (exists(target) && is_directory(target)) {
|
||||
target += "/README";
|
||||
}
|
||||
|
||||
const dir = path.dirname(target);
|
||||
if (!exists(dir)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let full_path, ext, found = false;
|
||||
// We are looking for the file `${target}.(any_supported_extension)`. Try to find it.
|
||||
for (const item of fs.readdirSync(dir)) {
|
||||
full_path = path.join(dir, item);
|
||||
// Get file extension
|
||||
ext = get_ext(item);
|
||||
|
||||
// Unsupported/unrelated file.
|
||||
if (!supported_formats.has(ext)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const desired_path = `${target}.${ext}`; // Don't grab some other random supported file.
|
||||
if (!is_directory(full_path) && desired_path == full_path) {
|
||||
// We found it.
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Process the file and return.
|
||||
return supported_formats.get(ext)(fs.readFileSync(full_path, 'utf-8'));
|
||||
}
|
||||
|
||||
// Get file information
|
||||
function process_file(fname: string): DocumentInfo {
|
||||
// Remove docs folder prefix and file extension suffix, then split it.
|
||||
const parts = fname
|
||||
.substring(`${docs_folder}/`.length, fname.length - (get_ext(fname).length + 1))
|
||||
.split("/");
|
||||
|
||||
// Remove `README` suffix if present.
|
||||
const last_part_index = parts.length - 1;
|
||||
if (parts[last_part_index] == "README") {
|
||||
parts.pop();
|
||||
}
|
||||
|
||||
const slug = parts.join("/");
|
||||
const title = get(slug).title;
|
||||
|
||||
return { slug, title };
|
||||
}
|
||||
|
||||
// Returns a document tree.
|
||||
function process_folder(dir: string): DocsTree|null {
|
||||
let tree: DocsTree = {
|
||||
index: null,
|
||||
nodes: []
|
||||
};
|
||||
|
||||
// List everything in the directory.
|
||||
const items = fs.readdirSync(dir);
|
||||
|
||||
for (const item of items) {
|
||||
if (ignored_items.includes(item) || [".", "_"].includes(item[0])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const itemPath = path.join(dir, item);
|
||||
|
||||
const is_dir = is_directory(itemPath);
|
||||
let is_index_file = false;
|
||||
|
||||
if (!is_dir) {
|
||||
// Ignore files we cannot process.
|
||||
if (!supported_formats.has(get_ext(item))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const ext of supported_filetypes) {
|
||||
if (item == `README.${ext}`) {
|
||||
is_index_file = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const node = is_dir ? process_folder(itemPath) : process_file(itemPath);
|
||||
if (node === null) {
|
||||
console.error(`The ${itemPath} directory does not have a README/index file! ignoring...`)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_index_file) {
|
||||
tree.index = node;
|
||||
} else {
|
||||
tree.nodes.push(node);
|
||||
}
|
||||
}
|
||||
|
||||
if (tree.index === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// `numeric: true` because we want to be able to specify
|
||||
// the order if necessary by prepending a number to the file name.
|
||||
tree.nodes.sort(
|
||||
(a, b) => get_slug_of_node(a).localeCompare(get_slug_of_node(b), "en", { numeric: true })
|
||||
);
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
// Returns the document tree.
|
||||
export function index_content(): DocsTree {
|
||||
const tree = process_folder(docs_folder);
|
||||
if (tree === null) {
|
||||
throw new Error("Root must have index (README) file.")
|
||||
}
|
||||
return tree;
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/// Types
|
||||
|
||||
export interface Document {
|
||||
title: string;
|
||||
// HTML
|
||||
content: string;
|
||||
}
|
||||
|
||||
export interface DocumentInfo {
|
||||
title: string;
|
||||
slug: string;
|
||||
}
|
||||
|
||||
// A tree representing the `docs` folder.
|
||||
export interface DocsTree {
|
||||
// index.whatever
|
||||
index: DocumentInfo;
|
||||
// Everything except index.whatever
|
||||
nodes: DocsTreeNode[];
|
||||
}
|
||||
|
||||
export type DocsTreeNode = DocsTree | DocumentInfo;
|
||||
|
||||
/// Functions
|
||||
|
||||
export function is_tree(node: DocsTreeNode) {
|
||||
return node.hasOwnProperty('nodes');
|
||||
}
|
||||
49
src/lib/types.ts
Normal file
49
src/lib/types.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
export interface Contributor {
|
||||
login: string;
|
||||
avatar_url: string;
|
||||
html_url: string;
|
||||
}
|
||||
|
||||
export interface Repository {
|
||||
name: string;
|
||||
contributors: Contributor[];
|
||||
}
|
||||
|
||||
export interface Patch {
|
||||
name: string;
|
||||
description: string;
|
||||
version: string;
|
||||
excluded: boolean;
|
||||
deprecated: boolean;
|
||||
dependencies: string[];
|
||||
options: PatchOption[];
|
||||
compatiblePackages: CompatiblePackage[];
|
||||
}
|
||||
|
||||
export interface CompatiblePackage {
|
||||
name: string;
|
||||
versions: string[];
|
||||
}
|
||||
|
||||
export interface PatchOption {
|
||||
key: string;
|
||||
title: string;
|
||||
description: string;
|
||||
required: boolean;
|
||||
choices: string[];
|
||||
}
|
||||
|
||||
export interface Asset {
|
||||
name: string;
|
||||
size: string|null;
|
||||
url: string;
|
||||
content_type: string;
|
||||
};
|
||||
|
||||
export interface Tool {
|
||||
repository: string;
|
||||
version: string;
|
||||
timestamp: string;
|
||||
assets: Asset[];
|
||||
};
|
||||
|
||||
@@ -1,8 +1,60 @@
|
||||
import { dev } from "$app/environment";
|
||||
import { dev } from '$app/environment';
|
||||
import { cubicOut } from 'svelte/easing';
|
||||
|
||||
// console.log, but only if in dev environment.
|
||||
export function dev_log(part: string, ...args) {
|
||||
if (dev) {
|
||||
console.log(`[${part}]:`, ...args);
|
||||
}
|
||||
if (dev) {
|
||||
console.log(`[${part}]:`, ...args);
|
||||
}
|
||||
}
|
||||
|
||||
export function friendlyName(text: string): string {
|
||||
return text
|
||||
.replace(/-/g, ' ')
|
||||
.replace(/revanced\/revanced/g, '')
|
||||
.replace(/revanced/g, 'ReVanced')
|
||||
.replace(/\bcli\b/g, 'CLI')
|
||||
.replace(/api/g, 'API')
|
||||
.replace(/microg/g, 'MicroG')
|
||||
.replace(/hdr/g, 'HDR')
|
||||
.replace(/sponsorblock/g, 'SponsorBlock')
|
||||
.replace(/tiktok/g, 'TikTok')
|
||||
.replace(/vr/g, 'VR')
|
||||
.replace(/(?:^|\s)\S/g, (x: string) => x.toUpperCase());
|
||||
}
|
||||
|
||||
// stolen from https://svelte.dev/repl/6d5239f09b0b4dc6aafeb70606a0fe94?version=3.46.4
|
||||
// please add this svelte thanks ily <3
|
||||
export function horizontalSlide(
|
||||
node,
|
||||
{ delay = 0, duration = 400, easing = cubicOut, direction = 'block' } = {}
|
||||
) {
|
||||
const style = getComputedStyle(node);
|
||||
const opacity = +style.opacity;
|
||||
const capitalized_logical_property = `${direction[0].toUpperCase()}${direction.slice(1)}`;
|
||||
const size_value = parseFloat(style[`${direction}Size`]);
|
||||
const padding_start_value = parseFloat(style[`padding${capitalized_logical_property}Start`]);
|
||||
const padding_end_value = parseFloat(style[`padding${capitalized_logical_property}End`]);
|
||||
const margin_start_value = parseFloat(style[`margin${capitalized_logical_property}Start`]);
|
||||
const margin_end_value = parseFloat(style[`margin${capitalized_logical_property}End`]);
|
||||
const border_width_start_value = parseFloat(
|
||||
style[`border${capitalized_logical_property}StartWidth`]
|
||||
);
|
||||
const border_width_end_value = parseFloat(style[`border${capitalized_logical_property}EndWidth`]);
|
||||
|
||||
return {
|
||||
delay,
|
||||
duration,
|
||||
easing,
|
||||
css: (t) =>
|
||||
'overflow: hidden;' +
|
||||
`opacity: ${Math.min(t * 20, 1) * opacity};` +
|
||||
`${direction}-size: ${t * size_value}px;` +
|
||||
`padding-${direction}-start: ${t * padding_start_value}px;` +
|
||||
`padding-${direction}-end: ${t * padding_end_value}px;` +
|
||||
`margin-${direction}-start: ${t * margin_start_value}px;` +
|
||||
`margin-${direction}-end: ${t * margin_end_value}px;` +
|
||||
`border-${direction}-start-width: ${t * border_width_start_value}px;` +
|
||||
`border-${direction}-start-width: ${t * border_width_end_value}px;`
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user