mirror of
https://github.com/Drop-OSS/drop.git
synced 2025-11-10 04:22:09 +10:00
starting docs infra
This commit is contained in:
6
.vscode/settings.json
vendored
Normal file
6
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"spellchecker.ignoreWordsList": [
|
||||
"mTLS",
|
||||
"Wireguard"
|
||||
]
|
||||
}
|
||||
50
components/DocsSidebar.vue
Normal file
50
components/DocsSidebar.vue
Normal file
@ -0,0 +1,50 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="user"
|
||||
class="flex grow flex-col gap-y-5 overflow-y-auto bg-zinc-900 px-6 pb-4 ring-1 ring-white/10"
|
||||
>
|
||||
<div class="flex h-16 shrink-0 items-center">
|
||||
<Wordmark />
|
||||
</div>
|
||||
|
||||
<nav class="flex flex-1 flex-col">
|
||||
<ul role="list" class="flex flex-1 flex-col gap-y-7">
|
||||
<li>
|
||||
<ul role="list" class="-mx-2 space-y-1">
|
||||
<DocsSidebarNavItem
|
||||
v-for="item in unwrappedNavigation ?? navigation"
|
||||
:key="item.name"
|
||||
:nav="item"
|
||||
/>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="mt-auto flex items-center">
|
||||
<div class="inline-flex items-center w-full text-zinc-300">
|
||||
<img
|
||||
:src="useObject(user.profilePicture)"
|
||||
class="w-5 h-5 rounded-sm"
|
||||
/>
|
||||
<span class="ml-3 text-sm font-bold">{{
|
||||
user.displayName
|
||||
}}</span>
|
||||
</div>
|
||||
<NuxtLink
|
||||
href="/"
|
||||
class="ml-auto rounded bg-blue-600 px-2 py-1 text-sm font-semibold text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600"
|
||||
>
|
||||
← Home
|
||||
</NuxtLink>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { fetchContentNavigation, useObject, useUser } from "#imports";
|
||||
|
||||
const user = useUser();
|
||||
|
||||
const navigation = await fetchContentNavigation();
|
||||
const unwrappedNavigation = navigation[0]?.children;
|
||||
</script>
|
||||
30
components/DocsSidebarNavItem.vue
Normal file
30
components/DocsSidebarNavItem.vue
Normal file
@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<NuxtLink
|
||||
:href="props.nav._path"
|
||||
:class="[
|
||||
current
|
||||
? 'text-zinc-100'
|
||||
: 'text-zinc-400 hover:text-zinc-100 hover:bg-zinc-900',
|
||||
' group flex gap-x-3 rounded-md px-2 text-sm font-semibold leading-6',
|
||||
]"
|
||||
>
|
||||
{{ props.nav.title }}
|
||||
</NuxtLink>
|
||||
<ul class="pl-3 flex flex-col" v-if="children">
|
||||
<li v-for="child in children" class="inline-flex items-center">
|
||||
<ChevronDownIcon class="w-4 h-4 text-zinc-600 rotate-45" />
|
||||
<DocsSidebarNavItem :nav="child" :key="child._path" />
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ChevronDownIcon } from "@heroicons/vue/24/solid";
|
||||
|
||||
type NavItem = { title: string; _path: string; children?: NavItem[] };
|
||||
const props = defineProps<{ nav: NavItem }>();
|
||||
const children = props.nav.children?.filter((e) => e._path != props.nav._path);
|
||||
|
||||
const route = useRoute();
|
||||
const current = computed(() => route.path.trim() == props.nav._path.trim());
|
||||
</script>
|
||||
@ -1,6 +1,7 @@
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:14-alpine
|
||||
user: "1000:1000"
|
||||
ports:
|
||||
- 5432:5432
|
||||
volumes:
|
||||
@ -20,4 +21,4 @@ services:
|
||||
environment:
|
||||
- MINIO_ROOT_USER=drop
|
||||
- MINIO_ROOT_PASSWORD=drop
|
||||
command: server /data --console-address ":9001"
|
||||
command: server /data --console-address ":9001"
|
||||
|
||||
1
docs/.about.txt
Normal file
1
docs/.about.txt
Normal file
@ -0,0 +1 @@
|
||||
These docs are automatically compiled in the Drop UI and are designed for admins and users to understand how Drop works.
|
||||
3
docs/1.index.md
Normal file
3
docs/1.index.md
Normal file
@ -0,0 +1,3 @@
|
||||
# Home
|
||||
|
||||
This page is intentionally left blank, as it should be replaced with a custom home page.
|
||||
23
docs/about/1.API.md
Normal file
23
docs/about/1.API.md
Normal file
@ -0,0 +1,23 @@
|
||||
# API
|
||||
|
||||
All Drop components communicate through HTTP-based APIs. However, due to the different use-cases they differ in how they are used.
|
||||
|
||||
## Frontend APIs
|
||||
|
||||
Frontend APIs run on the server, and are found under `/api/v1/`. They are used to render the web frontend, and are focused around user-based control of Drop systems.
|
||||
|
||||
For example, frontend APIs are responsible for uploading profile pictures, customizing your profile and adding friends.
|
||||
|
||||
The frontend, however, does not have access to some Drop features, namely downloading content. That feature is reserved for the client APIs, where it is actually used.
|
||||
|
||||
## Client APIs
|
||||
|
||||
Client APIs run on the server, and are found under `/api/v1/client/`. They are used by Drop clients (namely the desktop client) to manage, download and communicate with other Drop clients. They have a very specific feature set, and are limited in how they can change user profiles.
|
||||
|
||||
For example, client APIs have the ability to download content, setup P2P connections and report game activity. However, they do not have access to user profile management or administrator controls.
|
||||
|
||||
## P2P APIs
|
||||
|
||||
P2P APIs run on Drop clients, and are found at the root of the HTTP server. They are used by other Drop clients to download content and negotiate P2P features. They use mTLS authentication as a lightweight and efficient way to do peer to peer authentication.
|
||||
|
||||
For example, P2P APIs would be used to negotiate a Wireguard tunnel to do Remote LAN play.
|
||||
11
docs/about/clients.md
Normal file
11
docs/about/clients.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Clients
|
||||
|
||||
Drop clients connected to a given Drop server can access:
|
||||
|
||||
- Game content and files (to download)
|
||||
- User data
|
||||
- Game metadata and images
|
||||
- Information about other clients connected to the same Drop server
|
||||
|
||||
**It is important that you trust the client that you grant access to your Drop account.**
|
||||
|
||||
5
docs/about/index.md
Normal file
5
docs/about/index.md
Normal file
@ -0,0 +1,5 @@
|
||||
# About
|
||||
|
||||
This section is about what Drop does, and how it works. For users interested in the inner workings of Drop, this will go through many of the design decisions, why they were made and more!
|
||||
|
||||
For users that don't care how Drop works, and want help using Drop, look under other sections. This section is purely technical and theoretical.
|
||||
124
layouts/docs.vue
Normal file
124
layouts/docs.vue
Normal file
@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<div class="bg-zinc-950 min-h-screen">
|
||||
<TransitionRoot as="template" :show="sidebarOpen">
|
||||
<Dialog
|
||||
class="relative z-50 lg:hidden"
|
||||
@close="sidebarOpen = false"
|
||||
>
|
||||
<TransitionChild
|
||||
as="template"
|
||||
enter="transition-opacity ease-linear duration-300"
|
||||
enter-from="opacity-0"
|
||||
enter-to="opacity-100"
|
||||
leave="transition-opacity ease-linear duration-300"
|
||||
leave-from="opacity-100"
|
||||
leave-to="opacity-0"
|
||||
>
|
||||
<div class="fixed inset-0 bg-gray-900/80" />
|
||||
</TransitionChild>
|
||||
|
||||
<div class="fixed inset-0 flex">
|
||||
<TransitionChild
|
||||
as="template"
|
||||
enter="transition ease-in-out duration-300 transform"
|
||||
enter-from="-translate-x-full"
|
||||
enter-to="translate-x-0"
|
||||
leave="transition ease-in-out duration-300 transform"
|
||||
leave-from="translate-x-0"
|
||||
leave-to="-translate-x-full"
|
||||
>
|
||||
<DialogPanel
|
||||
class="relative mr-16 flex w-full max-w-xs flex-1"
|
||||
>
|
||||
<TransitionChild
|
||||
as="template"
|
||||
enter="ease-in-out duration-300"
|
||||
enter-from="opacity-0"
|
||||
enter-to="opacity-100"
|
||||
leave="ease-in-out duration-300"
|
||||
leave-from="opacity-100"
|
||||
leave-to="opacity-0"
|
||||
>
|
||||
<div
|
||||
class="absolute left-full top-0 flex w-16 justify-center pt-5"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="-m-2.5 p-2.5"
|
||||
@click="sidebarOpen = false"
|
||||
>
|
||||
<span class="sr-only"
|
||||
>Close sidebar</span
|
||||
>
|
||||
<XMarkIcon
|
||||
class="h-6 w-6 text-white"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</TransitionChild>
|
||||
<!-- Sidebar component, swap this element with another sidebar if you like -->
|
||||
<DocsSidebar />
|
||||
</DialogPanel>
|
||||
</TransitionChild>
|
||||
</div>
|
||||
</Dialog>
|
||||
</TransitionRoot>
|
||||
|
||||
<!-- Static sidebar for desktop -->
|
||||
<div
|
||||
class="hidden lg:fixed lg:inset-y-0 lg:z-50 lg:flex lg:w-72 lg:flex-col"
|
||||
>
|
||||
<!-- Sidebar component, swap this element with another sidebar if you like -->
|
||||
<DocsSidebar />
|
||||
</div>
|
||||
|
||||
<div class="lg:pl-72">
|
||||
<div
|
||||
class="flex sticky top-0 z-40 lg:hidden h-16 shrink-0 items-center gap-x-4 border-b border-zinc-700 bg-zinc-950 px-4 shadow-sm sm:gap-x-6 sm:px-6 lg:px-8"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="-m-2.5 p-2.5 text-zinc-300 lg:hidden"
|
||||
@click="sidebarOpen = true"
|
||||
>
|
||||
<span class="sr-only">Open sidebar</span>
|
||||
<Bars3Icon class="h-6 w-6" aria-hidden="true" />
|
||||
</button>
|
||||
|
||||
<Wordmark class="mb-[0.5px]" />
|
||||
|
||||
<NuxtLink
|
||||
href="/"
|
||||
class="ml-auto rounded bg-blue-600 px-2 py-1 text-sm font-semibold text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600"
|
||||
>
|
||||
Home →
|
||||
</NuxtLink>
|
||||
</div>
|
||||
<main class="py-10">
|
||||
<div class="px-4 sm:px-6 lg:px-8">
|
||||
<slot />
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import {
|
||||
Dialog,
|
||||
DialogPanel,
|
||||
TransitionChild,
|
||||
TransitionRoot,
|
||||
} from "@headlessui/vue";
|
||||
import { Bars3Icon, XMarkIcon } from "@heroicons/vue/24/outline";
|
||||
import { ChevronDownIcon, MagnifyingGlassIcon } from "@heroicons/vue/20/solid";
|
||||
|
||||
const sidebarOpen = ref(false);
|
||||
|
||||
useHead({
|
||||
titleTemplate: (title) =>
|
||||
title ? `${title} | Drop Documentation` : "Drop Documentation",
|
||||
});
|
||||
</script>
|
||||
@ -1,9 +1,12 @@
|
||||
import path from "path";
|
||||
|
||||
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||
export default defineNuxtConfig({
|
||||
// Nuxt-only config
|
||||
compatibilityDate: "2024-04-03",
|
||||
devtools: { enabled: false },
|
||||
|
||||
css: ["~/assets/core.scss"],
|
||||
|
||||
postcss: {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
@ -22,4 +25,29 @@ export default defineNuxtConfig({
|
||||
websocket: true,
|
||||
},
|
||||
},
|
||||
|
||||
watchers: {
|
||||
chokidar: {
|
||||
ignored: ".data",
|
||||
},
|
||||
},
|
||||
|
||||
// Module config from here down
|
||||
modules: ["@nuxt/content"],
|
||||
|
||||
content: {
|
||||
api: {
|
||||
baseURL: "/api/v1/_content",
|
||||
},
|
||||
markdown: {
|
||||
anchorLinks: false,
|
||||
},
|
||||
sources: {
|
||||
content: {
|
||||
driver: "fs",
|
||||
prefix: "/docs",
|
||||
base: path.resolve(__dirname, "docs"),
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
"@drop/droplet": "^0.5.1",
|
||||
"@headlessui/vue": "^1.7.23",
|
||||
"@heroicons/vue": "^2.1.5",
|
||||
"@nuxt/content": "^2.13.4",
|
||||
"@prisma/client": "5.20.0",
|
||||
"axios": "^1.7.7",
|
||||
"bcrypt": "^5.1.1",
|
||||
|
||||
91
pages/docs/[...id].vue
Normal file
91
pages/docs/[...id].vue
Normal file
@ -0,0 +1,91 @@
|
||||
<template>
|
||||
<div class="py-10 px-8 w-full">
|
||||
<ContentDoc>
|
||||
<template #not-found>
|
||||
<main
|
||||
class="mx-auto w-full max-w-7xl px-6 pb-16 pt-10 sm:pb-24 lg:px-8"
|
||||
>
|
||||
<img
|
||||
class="mx-auto h-10 w-auto sm:h-12"
|
||||
src="https://tailwindui.com/plus/img/logos/mark.svg?color=indigo&shade=600"
|
||||
alt="Your Company"
|
||||
/>
|
||||
<div class="mx-auto mt-20 max-w-2xl text-center sm:mt-24">
|
||||
<p class="text-base font-semibold leading-8 text-indigo-600">404</p>
|
||||
<h1
|
||||
class="mt-4 text-balance text-5xl font-semibold tracking-tight text-gray-900 sm:text-6xl"
|
||||
>
|
||||
This page does not exist
|
||||
</h1>
|
||||
<p
|
||||
class="mt-6 text-pretty text-lg font-medium text-gray-500 sm:text-xl/8"
|
||||
>
|
||||
Sorry, we couldn’t find the page you’re looking for.
|
||||
</p>
|
||||
</div>
|
||||
<div class="mx-auto mt-16 flow-root max-w-lg sm:mt-20">
|
||||
<h2 class="sr-only">Popular pages</h2>
|
||||
<ul
|
||||
role="list"
|
||||
class="-mt-6 divide-y divide-gray-900/5 border-b border-gray-900/5"
|
||||
>
|
||||
<li
|
||||
v-for="(link, linkIdx) in links"
|
||||
:key="linkIdx"
|
||||
class="relative flex gap-x-6 py-6"
|
||||
>
|
||||
<div
|
||||
class="flex h-10 w-10 flex-none items-center justify-center rounded-lg shadow-sm ring-1 ring-gray-900/10"
|
||||
>
|
||||
<component
|
||||
:is="link.icon"
|
||||
class="h-6 w-6 text-indigo-600"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex-auto">
|
||||
<h3 class="text-sm font-semibold leading-6 text-gray-900">
|
||||
<a :href="link.href">
|
||||
<span class="absolute inset-0" aria-hidden="true" />
|
||||
{{ link.name }}
|
||||
</a>
|
||||
</h3>
|
||||
<p class="mt-2 text-sm leading-6 text-gray-600">
|
||||
{{ link.description }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex-none self-center">
|
||||
<ChevronRightIcon
|
||||
class="h-5 w-5 text-gray-400"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="mt-10 flex justify-center">
|
||||
<a
|
||||
href="#"
|
||||
class="text-sm font-semibold leading-6 text-indigo-600"
|
||||
>
|
||||
<span aria-hidden="true">←</span>
|
||||
Back to home
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<template v-slot="{ doc }">
|
||||
<article class="prose prose-invert prose-blue">
|
||||
<ContentRenderer :value="doc" />
|
||||
</article>
|
||||
</template>
|
||||
</ContentDoc>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
layout: "docs",
|
||||
});
|
||||
</script>
|
||||
@ -1,16 +1,20 @@
|
||||
<template>
|
||||
<div class="px-12 py-4">
|
||||
<h1 class="text-zinc-100 text-2xl font-bold font-display">Newly added</h1>
|
||||
<NuxtLink class="text-blue-600 font-semibold">Explore more →</NuxtLink>
|
||||
<div class="mt-4 grid grid-cols-8 gap-8">
|
||||
<GamePanel v-for="i in 8" :game="games[i - 1]" />
|
||||
<div class="px-12 py-4">
|
||||
<h1 class="text-zinc-100 text-2xl font-bold font-display">
|
||||
Newly added
|
||||
</h1>
|
||||
<NuxtLink class="text-blue-600 font-semibold"
|
||||
>Explore more →</NuxtLink
|
||||
>
|
||||
<div class="mt-4 grid grid-cols-8 gap-x-8 w-max">
|
||||
<GamePanel v-for="i in 8" :game="games[i - 1]" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
useHead({
|
||||
title: "Home",
|
||||
title: "Home",
|
||||
});
|
||||
|
||||
const headers = useRequestHeaders(["cookie"]);
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
</div>
|
||||
<!-- main page -->
|
||||
<div
|
||||
class="max-w-7xl w-full min-h-screen mx-auto bg-zinc-900 px-16 py-12 rounded-md"
|
||||
class="max-w-7xl w-full min-h-screen mx-auto bg-zinc-900 px-5 py-4 sm:px-16 sm:py-12 rounded-md"
|
||||
>
|
||||
<h1
|
||||
class="text-3xl md:text-5xl font-bold font-display text-zinc-100 pb-4 border-b border-zinc-800"
|
||||
|
||||
Reference in New Issue
Block a user