From f483ad541ab86bc7fb92fab62f158d143899e6f5 Mon Sep 17 00:00:00 2001 From: Cecilia Sanare <ceci@sanare.dev> Date: Wed, 6 Mar 2024 17:12:51 -0600 Subject: [PATCH] chore: migrated ui from db --- .editorconfig | 17 +++++++ .github/workflows/ci.yml | 59 ++++++++++++++++++++++ .gitignore | 8 +++ .postcssrc.json | 8 +++ .prettierrc | 7 +++ .vscode/settings.json | 23 +++++++++ .vscode/tailwind.json | 55 ++++++++++++++++++++ LICENSE | 7 +++ Makefile | 6 +++ README.md | 47 ++++++++++++++++++ app/App.tsx | 35 +++++++++++++ app/components/AppFooter.tsx | 47 ++++++++++++++++++ app/components/AppHeader.tsx | 77 ++++++++++++++++++++++++++++ app/components/AppImage.tsx | 25 ++++++++++ app/components/Button.tsx | 71 ++++++++++++++++++++++++++ app/components/Card.tsx | 11 ++++ app/components/Code.tsx | 33 ++++++++++++ app/components/Divider.tsx | 5 ++ app/components/Label.tsx | 15 ++++++ app/components/Pill.tsx | 9 ++++ app/context/search.ts | 5 ++ app/index.css | 11 ++++ app/index.tsx | 34 +++++++++++++ app/pages/Dashboard.tsx | 39 +++++++++++++++ app/pages/Tweak.tsx | 94 +++++++++++++++++++++++++++++++++++ app/utils/cn.ts | 6 +++ app/utils/fetch.ts | 12 +++++ bun.lockb | Bin 0 -> 136663 bytes flake.lock | 27 ++++++++++ flake.nix | 15 ++++++ index.html | 28 +++++++++++ nixpkgs.nix | 8 +++ package.json | 33 ++++++++++++ shell.nix | 15 ++++++ tailwind.config.ts | 7 +++ tsconfig.json | 27 ++++++++++ vite.config.ts | 31 ++++++++++++ 37 files changed, 957 insertions(+) create mode 100644 .editorconfig create mode 100644 .github/workflows/ci.yml create mode 100644 .gitignore create mode 100644 .postcssrc.json create mode 100644 .prettierrc create mode 100644 .vscode/settings.json create mode 100644 .vscode/tailwind.json create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100644 app/App.tsx create mode 100644 app/components/AppFooter.tsx create mode 100644 app/components/AppHeader.tsx create mode 100644 app/components/AppImage.tsx create mode 100644 app/components/Button.tsx create mode 100644 app/components/Card.tsx create mode 100644 app/components/Code.tsx create mode 100644 app/components/Divider.tsx create mode 100644 app/components/Label.tsx create mode 100644 app/components/Pill.tsx create mode 100644 app/context/search.ts create mode 100644 app/index.css create mode 100644 app/index.tsx create mode 100644 app/pages/Dashboard.tsx create mode 100644 app/pages/Tweak.tsx create mode 100644 app/utils/cn.ts create mode 100644 app/utils/fetch.ts create mode 100755 bun.lockb create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 index.html create mode 100644 nixpkgs.nix create mode 100644 package.json create mode 100644 shell.nix create mode 100644 tailwind.config.ts create mode 100644 tsconfig.json create mode 100644 vite.config.ts diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..d330a4c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,17 @@ +# http://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[Makefile] +indent_style = tab +indent_size = 4 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..5fb2562 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,59 @@ +name: Deploy tweaks to GitHub Pages + +on: + push: + branches: ['main'] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: write + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: 'pages' + cancel-in-progress: false + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - uses: oven-sh/setup-bun@v1 + with: + bun-version: latest + + - run: bun ci + + - name: Validate Tweaks + run: bun test + + - run: bun run build + + - name: Setup Pages + uses: actions/configure-pages@v4 + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: './dist' + + deploy: + needs: build + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Setup Pages + uses: actions/configure-pages@v4 + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c09d625 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +node_modules/ +tweaks/schema.json +tweaks/tweaks.json +tweaks/*.md +# Ignore any sub directories under tweaks +tweaks/*/ +dist/ +*.py diff --git a/.postcssrc.json b/.postcssrc.json new file mode 100644 index 0000000..9ac0be0 --- /dev/null +++ b/.postcssrc.json @@ -0,0 +1,8 @@ +{ + "plugins": { + "autoprefixer": {}, + "tailwindcss/nesting": {}, + "tailwindcss": {}, + "cssnano": {} + } +} diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..b088170 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "trailingComma": "es5", + "semi": true, + "singleQuote": true, + "editorconfig": true, + "printWidth": 120 +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..509f1b3 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,23 @@ +{ + "css.customData": [".vscode/tailwind.json"], + "nixEnvSelector.suggestion": false, + "editor.detectIndentation": false, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true, + "editor.codeActionsOnSave": ["source.addMissingImports", "source.fixAll.eslint"], + "[nix]": { + "editor.defaultFormatter": "jnoortheen.nix-ide" + }, + "nix.enableLanguageServer": true, + "nix.serverPath": "nixd", + "[toml]": { + "editor.defaultFormatter": "tamasfe.even-better-toml" + }, + "[rust]": { + "editor.defaultFormatter": "rust-lang.rust-analyzer" + }, + "nixEnvSelector.nixFile": "${workspaceFolder}/shell.nix", + "nixEnvSelector.args": "--impure", + "tailwindCSS.suggestions": true, + "tailwindCSS.experimental.classRegex": ["className: '(.*)'"] +} diff --git a/.vscode/tailwind.json b/.vscode/tailwind.json new file mode 100644 index 0000000..96a1f57 --- /dev/null +++ b/.vscode/tailwind.json @@ -0,0 +1,55 @@ +{ + "version": 1.1, + "atDirectives": [ + { + "name": "@tailwind", + "description": "Use the `@tailwind` directive to insert Tailwind's `base`, `components`, `utilities` and `screens` styles into your CSS.", + "references": [ + { + "name": "Tailwind Documentation", + "url": "https://tailwindcss.com/docs/functions-and-directives#tailwind" + } + ] + }, + { + "name": "@apply", + "description": "Use the `@apply` directive to inline any existing utility classes into your own custom CSS. This is useful when you find a common utility pattern in your HTML that you’d like to extract to a new component.", + "references": [ + { + "name": "Tailwind Documentation", + "url": "https://tailwindcss.com/docs/functions-and-directives#apply" + } + ] + }, + { + "name": "@responsive", + "description": "You can generate responsive variants of your own classes by wrapping their definitions in the `@responsive` directive:\n```css\n@responsive {\n .alert {\n background-color: #E53E3E;\n }\n}\n```\n", + "references": [ + { + "name": "Tailwind Documentation", + "url": "https://tailwindcss.com/docs/functions-and-directives#responsive" + } + ] + }, + { + "name": "@screen", + "description": "The `@screen` directive allows you to create media queries that reference your breakpoints by **name** instead of duplicating their values in your own CSS:\n```css\n@screen sm {\n /* ... */\n}\n```\n…gets transformed into this:\n```css\n@media (min-width: 640px) {\n /* ... */\n}\n```\n", + "references": [ + { + "name": "Tailwind Documentation", + "url": "https://tailwindcss.com/docs/functions-and-directives#screen" + } + ] + }, + { + "name": "@variants", + "description": "Generate `hover`, `focus`, `active` and other **variants** of your own utilities by wrapping their definitions in the `@variants` directive:\n```css\n@variants hover, focus {\n .btn-brand {\n background-color: #3182CE;\n }\n}\n```\n", + "references": [ + { + "name": "Tailwind Documentation", + "url": "https://tailwindcss.com/docs/functions-and-directives#variants" + } + ] + } + ] +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..df09573 --- /dev/null +++ b/LICENSE @@ -0,0 +1,7 @@ +Copyright 2023 Rainbow Café + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e9f5960 --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ +develop: +ifeq ($(shell printenv IN_NIX_SHELL),) + @nix develop --impure --command $(shell printenv SHELL) +else + $(info You are already running in a nix shell!) +endif diff --git a/README.md b/README.md new file mode 100644 index 0000000..8f09795 --- /dev/null +++ b/README.md @@ -0,0 +1,47 @@ +## Protontweaks DB + +> [!IMPORTANT] +> This is the Protontweaks DB repository, you can find the `protontweaks` cli [over here](https://github.com/rain-cafe/protontweaks) + +### Usage + +Its highly recommended that if you're planning on fetching tweaks from our api that you lock into a specific version. + +`https://tweaks.rains.cafe/api/v2/<app-id>.json` + +Old versions will get any new apps that are added, however if a feature isn't supported in the old api it won't get mapped. + +### Adding a tweak? + +- Lookup your the app id of your steam app. + +> [!TIP] +> You can discover the app id by using [https://steamdb.info](https://steamdb.info/apps/)! + +- Copy the contents of [template](./tweaks/.template.json) and create a json file with the name `[your-app-id].json` +- Add any dlls, fonts, etc. +- Create a PR with your changes! + +### Example Tweak File + +```ts +{ + "name": "They Are Billions", + "tweaks": { + // Specify any protontricks here + "tricks": ["gdiplus"], + // Set any environment variables here + "env": {}, + "settings": { + // Informs the client that ESync should be disabled + "esync": false, + // Informs the client that FSync should be disabled + "fsync": false + } + } +} +``` + +### TODO + +- Add support for gpu vendor specific configs diff --git a/app/App.tsx b/app/App.tsx new file mode 100644 index 0000000..5e17693 --- /dev/null +++ b/app/App.tsx @@ -0,0 +1,35 @@ +import { useState, type FC } from 'react'; +import { Outlet, useNavigate } from 'react-router-dom'; +import { AppHeader } from './components/AppHeader'; +import { SearchContext } from './context/search'; +import { Toaster } from 'sonner'; +import { AppFooter } from './components/AppFooter'; + +export const Component: FC = () => { + const navigate = useNavigate(); + const [search, setSearch] = useState(''); + + return ( + <SearchContext.Provider value={search}> + <AppHeader + onChange={(value) => { + navigate('/'); + setSearch(value); + }} + /> + <div className="flex flex-1 flex-col p-4 gap-4 w-screen max-w-screen-2xl mx-auto"> + <Outlet /> + <Toaster + toastOptions={{ + unstyled: true, + classNames: { + toast: 'overflow-hidden flex gap-4 items-center bg-black p-4 w-full rounded-md text-white', + title: 'text-lg', + }, + }} + /> + </div> + <AppFooter /> + </SearchContext.Provider> + ); +}; diff --git a/app/components/AppFooter.tsx b/app/components/AppFooter.tsx new file mode 100644 index 0000000..8dbfb3b --- /dev/null +++ b/app/components/AppFooter.tsx @@ -0,0 +1,47 @@ +import { type FC } from 'react'; +import { Link } from 'react-router-dom'; +import { Bug, Code2 } from 'lucide-react'; +import { Button } from './Button'; + +export const AppFooter: FC = () => { + return ( + <div className="flex gap-4 px-4 py-3 bg-zinc-900 items-center"> + <div className="flex flex-col gap-2 flex-1 text-white/70"> + <div> + Built with ❤️ by the{' '} + <Link className="underline" to="https://github.com/rain-cafe" target="_blank"> + Rainbow Cafe + </Link>{' '} + Team~ + </div> + <div> + This site uses data from Steam as well as data provided by{' '} + <Link className="underline" to="https://steamdb.info" target="_blank"> + SteamDB + </Link>{' '} + via{' '} + <Link + className="underline" + to="https://www.algolia.com/?utm_source=steamdb_search&utm_medium=link&utm_term=logo&utm_campaign=steamdb" + target="_blank" + > + Algolia + </Link> + . + </div> + <div> + This site has no affiliation with Valve Software. This site uses data from All game images and logos are + property of their respective owners. + </div> + </div> + <div className="flex flex-col gap-4"> + <Button to="https://github.com/rain-cafe/protontweaks-db/issues"> + <Bug /> + </Button> + <Button to="https://github.com/rain-cafe/protontweaks-db"> + <Code2 /> + </Button> + </div> + </div> + ); +}; diff --git a/app/components/AppHeader.tsx b/app/components/AppHeader.tsx new file mode 100644 index 0000000..7e6a097 --- /dev/null +++ b/app/components/AppHeader.tsx @@ -0,0 +1,77 @@ +import { useEffect, type FC, useState } from 'react'; +import { useSearch } from '../context/search'; +import { Link, useParams } from 'react-router-dom'; +import { ArrowUp, Edit } from 'lucide-react'; +import { cn } from '../utils/cn'; +import { Button } from './Button'; + +type Props = { + onChange?: (value: string) => void; +}; + +export const AppHeader: FC<Props> = ({ onChange }) => { + const search = useSearch(); + const [sticky, setSticky] = useState(false); + const { id } = useParams(); + + useEffect(() => { + const listener = () => { + setSticky(window.scrollY > 0); + }; + + window.addEventListener('scroll', listener, { passive: true }); + + return () => { + window.removeEventListener('scroll', listener); + }; + }); + + return ( + <> + <div + className={cn( + 'fixed inset-x-0 top-0 from-black from-30% to-transparent bg-gradient-to-b h-64 z-50 opacity-0 transition-opacity pointer-events-none', + sticky && 'opacity-100' + )} + ></div> + <div + className={cn( + 'flex flex-col sm:flex-row sm:items-center gap-4 px-3 sm:px-8 py-3 bg-zinc-900 sticky top-0 z-50 transition-all', + sticky && 'sm:mx-5 sm:top-5 sm:rounded-full' + )} + > + <Link to="/" className="text-2xl text-center hover:text-pink-300 transition-colors"> + Protontweaks DB + </Link> + <div className="flex flex-1 gap-4"> + <input + type="text" + className="flex-1 bg-white/10 rounded-md min-h-12 px-3 text-xl" + value={search} + placeholder="Search" + onChange={(e) => onChange?.(e.target.value)} + /> + <Button + to={ + id + ? `https://github.com/rain-cafe/protontweaks-db/edit/main/tweaks/${id}.json` + : 'https://github.com/rain-cafe/protontweaks-db/tree/main/tweaks' + } + > + <Edit /> + </Button> + </div> + </div> + <Button + className={cn( + 'fixed top-20 opacity-0 pointer-events-none left-1/2 -translate-x-1/2 z-50 transition-all rounded-full px-4 bg-white/80 text-black hover:bg-white', + sticky && 'top-36 sm:top-28 opacity-100 pointer-events-auto' + )} + to="#root" + > + Back to the Top! + <ArrowUp /> + </Button> + </> + ); +}; diff --git a/app/components/AppImage.tsx b/app/components/AppImage.tsx new file mode 100644 index 0000000..2b5fe70 --- /dev/null +++ b/app/components/AppImage.tsx @@ -0,0 +1,25 @@ +import { type FC } from 'react'; +import { Link } from 'react-router-dom'; +import { cn } from '../utils/cn'; + +type Props = { + className?: string; + id: string; + to?: string; +}; + +export const AppImage: FC<Props> = ({ className, id, to }) => { + return to ? ( + <Link + className={cn( + 'relative rounded-md hover:after:opacity-100 after:content-[""] after:pointer-events-none after:opacity-0 after:inset-0 after:absolute after:bg-black/20 after:transition-opacity', + className + )} + to={to} + > + <img className="rounded-md" src={`https://steamcdn-a.akamaihd.net/steam/apps/${id}/header.jpg`} /> + </Link> + ) : ( + <img className={cn('rounded-md', className)} src={`https://steamcdn-a.akamaihd.net/steam/apps/${id}/header.jpg`} /> + ); +}; diff --git a/app/components/Button.tsx b/app/components/Button.tsx new file mode 100644 index 0000000..47ccd51 --- /dev/null +++ b/app/components/Button.tsx @@ -0,0 +1,71 @@ +import { type ComponentProps, type FC, type ReactNode } from 'react'; +import { Link } from 'react-router-dom'; +import { cn } from '../utils/cn'; + +type SharedProps = { + children?: ReactNode; + className?: string; +}; + +type LinkProps = SharedProps & { + to: string; + target?: ComponentProps<'a'>['target']; +}; + +type ButtonProps = SharedProps & { + onClick?: () => void; +}; + +type Props = LinkProps | ButtonProps; + +const isLink = (props: Props): props is LinkProps => { + return Object.hasOwn(props, 'to'); +}; + +export const Button: FC<Props> = (props) => { + if (isLink(props)) { + if (props.to.startsWith('#')) { + return ( + <button + {...props} + onClick={() => { + const id = props.to.replace('#', ''); + + const element = document.getElementById(id); + + if (element) { + element.scrollIntoView({ behavior: 'smooth', block: 'start' }); + } else { + console.warn(`Unknown ID: "${id}"`); + } + }} + className={cn( + 'flex gap-2 items-center justify-center min-w-14 min-h-14 bg-white/10 hover:bg-transparent hover:border-white/10 border border-transparent px-3 rounded-md transition-all', + props.className + )} + /> + ); + } + + return ( + <Link + {...props} + target={props.to.startsWith('http') ? '_blank' : undefined} + className={cn( + 'flex gap-2 items-center justify-center min-w-14 min-h-14 bg-white/10 hover:bg-transparent hover:border-white/10 border border-transparent px-3 rounded-md transition-all', + props.className + )} + /> + ); + } + + return ( + <button + {...props} + className={cn( + 'flex gap-2 items-center justify-center min-w-14 min-h-14 bg-white/10 hover:bg-transparent hover:border-white/10 border border-transparent px-3 rounded-md transition-all', + props.className + )} + /> + ); +}; diff --git a/app/components/Card.tsx b/app/components/Card.tsx new file mode 100644 index 0000000..0af3f86 --- /dev/null +++ b/app/components/Card.tsx @@ -0,0 +1,11 @@ +import type { FC, ReactNode } from 'react'; +import { cn } from '../utils/cn'; + +type Props = { + className?: string; + children: ReactNode; +}; + +export const Card: FC<Props> = ({ className, children }) => { + return <div className={cn('flex flex-col gap-4 rounded-md bg-black/20 p-4', className)}>{children}</div>; +}; diff --git a/app/components/Code.tsx b/app/components/Code.tsx new file mode 100644 index 0000000..f39d1a3 --- /dev/null +++ b/app/components/Code.tsx @@ -0,0 +1,33 @@ +import type { FC, ReactNode } from 'react'; +import { cn } from '../utils/cn'; +import { toast } from 'sonner'; +import { delay } from '@rain-cafe/js-utils'; +import { Clipboard } from 'lucide-react'; + +type Props = { + className?: string; + children: ReactNode; + shell?: boolean; +}; + +export const Code: FC<Props> = ({ className, children, shell = false }) => { + return ( + <div + className={cn( + 'relative select-none whitespace-pre-wrap flex flex-row items-start gap-2 rounded-md bg-white/10 px-4 py-2 hover:bg-white/20 transition-colors cursor-pointer', + shell && "before:content-['$']", + className + )} + onClick={(e) => { + toast.promise(delay(window.navigator.clipboard.writeText(e.currentTarget.innerText)), { + loading: 'Copying...', + success: 'Copied to clipboard!', + error: 'Failed to copy to clipboard', + }); + }} + > + {children} + <Clipboard className="absolute right-2" /> + </div> + ); +}; diff --git a/app/components/Divider.tsx b/app/components/Divider.tsx new file mode 100644 index 0000000..39eedd1 --- /dev/null +++ b/app/components/Divider.tsx @@ -0,0 +1,5 @@ +import type { FC } from 'react'; + +export const Divider: FC = () => { + return <div className="flex flex-col gap-2 items-center rounded-md bg-black/20 p-4" />; +}; diff --git a/app/components/Label.tsx b/app/components/Label.tsx new file mode 100644 index 0000000..8bafa21 --- /dev/null +++ b/app/components/Label.tsx @@ -0,0 +1,15 @@ +import type { FC, ReactNode } from 'react'; + +type Props = { + label: string; + children?: ReactNode; +}; + +export const Label: FC<Props> = ({ label, children }) => { + return ( + <div className="flex gap-4 items-start justify-between"> + <div className="bg-white/20 p-2 rounded-md mr-auto">{label}</div> + <div className="flex flex-wrap gap-4 items-center justify-end h-full">{children}</div> + </div> + ); +}; diff --git a/app/components/Pill.tsx b/app/components/Pill.tsx new file mode 100644 index 0000000..6b739dd --- /dev/null +++ b/app/components/Pill.tsx @@ -0,0 +1,9 @@ +import type { FC, ReactNode } from 'react'; + +type Props = { + children: ReactNode; +}; + +export const Pill: FC<Props> = ({ children }) => { + return <div className="rounded-full bg-white/20 px-3 min-h-10 items-center inline-flex">{children}</div>; +}; diff --git a/app/context/search.ts b/app/context/search.ts new file mode 100644 index 0000000..bcd0230 --- /dev/null +++ b/app/context/search.ts @@ -0,0 +1,5 @@ +import { createContext, useContext } from 'react'; + +export const SearchContext = createContext(''); + +export const useSearch = () => useContext(SearchContext); diff --git a/app/index.css b/app/index.css new file mode 100644 index 0000000..af86409 --- /dev/null +++ b/app/index.css @@ -0,0 +1,11 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +body { + @apply flex flex-col bg-zinc-800 text-white bg-gradient-to-br h-dvh max-w-[100vw] overflow-x-hidden; +} + +#root { + @apply flex flex-1 flex-col gap-4; +} diff --git a/app/index.tsx b/app/index.tsx new file mode 100644 index 0000000..66e369c --- /dev/null +++ b/app/index.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import { createRoot } from 'react-dom/client'; +import { RouterProvider, createHashRouter } from 'react-router-dom'; +import { QueryClientProvider, QueryClient } from '@tanstack/react-query'; + +const container = document.getElementById('root'); +const root = createRoot(container!); + +const router = createHashRouter([ + { + path: '/', + lazy: () => import('./App'), + children: [ + { + path: '/', + lazy: () => import('./pages/Dashboard'), + }, + { + path: '/tweaks/:id', + lazy: () => import('./pages/Tweak'), + }, + ], + }, +]); + +const client = new QueryClient(); + +root.render( + <React.StrictMode> + <QueryClientProvider client={client}> + <RouterProvider router={router} /> + </QueryClientProvider> + </React.StrictMode> +); diff --git a/app/pages/Dashboard.tsx b/app/pages/Dashboard.tsx new file mode 100644 index 0000000..5b57ae9 --- /dev/null +++ b/app/pages/Dashboard.tsx @@ -0,0 +1,39 @@ +import { type FC, useMemo, useEffect } from 'react'; +import { fetch } from '../utils/fetch'; +import type { Tweaks } from '@/api/types'; +import { useLoaderData } from '@rain-cafe/react-utils/react-router'; +import { useSearch } from '../context/search'; +import { AppImage } from '../components/AppImage'; + +export async function loader() { + return { + tweaks: await fetch<Tweaks>('/api/tweaks.json'), + }; +} + +export const Component: FC = () => { + const { tweaks } = useLoaderData<typeof loader>(); + const search = useSearch(); + const filteredTweaks = useMemo(() => { + return tweaks.tweaks.filter((tweak) => tweak.name.toLowerCase().includes(search.toLowerCase())); + }, [tweaks, search]); + + useEffect(() => { + const listener = () => {}; + window.addEventListener('scroll', listener, { + passive: true, + }); + + return () => { + window.removeEventListener('scroll', listener); + }; + }, []); + + return ( + <div className="grid grid-cols-1 sm:grid-cols-2 2xl:grid-cols-3 gap-5 mx-auto"> + {filteredTweaks?.map((tweak) => ( + <AppImage key={tweak.id} id={tweak.id} to={`/tweaks/${tweak.id}`} /> + ))} + </div> + ); +}; diff --git a/app/pages/Tweak.tsx b/app/pages/Tweak.tsx new file mode 100644 index 0000000..c517fb1 --- /dev/null +++ b/app/pages/Tweak.tsx @@ -0,0 +1,94 @@ +import type { Tweak } from '@/api/types'; +import { type FC } from 'react'; +import type { LoaderFunctionArgs } from 'react-router-dom'; +import { fetch } from '../utils/fetch'; +import { useLoaderData } from '@rain-cafe/react-utils/react-router'; +import { AppImage } from '../components/AppImage'; +import { Label } from '../components/Label'; +import { Pill } from '../components/Pill'; +import { Card } from '../components/Card'; +import { Code } from '../components/Code'; + +const ALIASES: Record<string, string> = { + esync: 'PROTON_NO_ESYNC', + fsync: 'PROTON_NO_FSYNC', +}; + +export async function loader({ params }: LoaderFunctionArgs) { + return await fetch<Tweak>(`/api/${params.id}.json`); +} + +export const Component: FC = () => { + const tweak = useLoaderData<typeof loader>(); + const environmentVariables = Object.entries(tweak.tweaks.env); + const settings = Object.entries(tweak.tweaks.settings); + + return ( + <> + <div className="flex flex-col gap-2 items-center"> + <AppImage id={tweak.id} /> + <div className="text-md"> + {tweak.name} ({tweak.id}) + </div> + </div> + <Card> + <Label label="Protontricks Command" /> + <Code shell> + protontricks {tweak.id} {tweak.tweaks.tricks.join(' ')} + </Code> + <Label label="Launch Options" /> + <Code> + {environmentVariables.map(([key, value]) => `${key}=${value} `).join()} + {settings.map(([key, value]) => { + const finalKey = ALIASES[key] ?? key; + const finalValue = typeof value === 'boolean' ? (value ? '1' : '0') : value; + + return `${finalKey}=${finalValue}`; + })} + %command% + </Code> + </Card> + <Card> + <Label label="Tricks"> + {tweak.tweaks.tricks.map((trick, index) => ( + <Pill key={index}>{trick}</Pill> + ))} + </Label> + </Card> + <Card> + <Label label="Environment Variables"> + {environmentVariables.length === 0 + ? 'None' + : environmentVariables.map(([key, value]) => ( + <Pill key={key}> + {key} = {typeof value === 'boolean' ? value : `"${value}"`} + </Pill> + ))} + </Label> + <Label label="Settings"> + {settings.length === 0 + ? 'None' + : settings.map(([key, value]) => ( + <Pill key={key}> + {key} = {typeof value === 'boolean' ? value : '"value"'} + </Pill> + ))} + </Label> + </Card> + {/* <Card> + <Label label="API Info"> + <Pill>Version = V2</Pill> + </Label> + <Label label="HTTP"> + <Pill> + GET {location.origin}/api/{tweak.id}.json + </Pill> + </Label> + <Label label="RESPONSE"> + <Pill>JSON</Pill> + </Label> + <Code>{JSON.stringify(tweak, null, 8)}</Code> + </Card> */} + </> + ); +}; diff --git a/app/utils/cn.ts b/app/utils/cn.ts new file mode 100644 index 0000000..2819a83 --- /dev/null +++ b/app/utils/cn.ts @@ -0,0 +1,6 @@ +import { clsx, type ClassValue } from 'clsx'; +import { twMerge } from 'tailwind-merge'; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} diff --git a/app/utils/fetch.ts b/app/utils/fetch.ts new file mode 100644 index 0000000..77eb766 --- /dev/null +++ b/app/utils/fetch.ts @@ -0,0 +1,12 @@ +export async function fetch<T>(url: string, options?: RequestInit): Promise<T> { + const response = await window.fetch(url, options); + const content = response.headers.get('content-type')?.includes('application/json') + ? response.json() + : response.text(); + + if (response.status >= 400) { + throw content; + } + + return content; +} diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..795d069e6c6d87d8b7bb266dd9f7a6dfd3527a8a GIT binary patch literal 136663 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�g<eiN!n{Pic_udwAUG%O98zGa^ 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 literal 0 HcmV?d00001 diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..921dc8d --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1709479366, + "narHash": "sha256-n6F0n8UV6lnTZbYPl1A9q1BS0p4hduAv1mGAP17CVd0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b8697e57f10292a6165a20f03d2f42920dfaf973", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..c001c22 --- /dev/null +++ b/flake.nix @@ -0,0 +1,15 @@ +{ + description = "Orchestrator"; + + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + outputs = { nixpkgs, ... }: let + forAllSystems = nixpkgs.lib.genAttrs nixpkgs.lib.systems.flakeExposed; + in { + # Devshell for bootstrapping; acessible via 'nix develop' or 'nix-shell' (legacy) + devShells = forAllSystems (systems: + let pkgs = nixpkgs.legacyPackages.${systems}; + in import ./shell.nix { inherit pkgs; } + ); + }; +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..2f27e54 --- /dev/null +++ b/index.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <meta http-equiv="X-UA-Compatible" content="ie-edge" /> + <link rel="icon" type="image/png" href="../public/favicon.png" /> + <link rel="stylesheet" href="./app/index.css" /> + <title>Protontweaks DB</title> + + <script> + // This is here purely to get React to shut up about React DevTools + // https://github.com/facebook/react/issues/24283 + console.info = new Proxy(console.info, { + apply: (target, thisArg, args) => { + if (args?.[0]?.includes?.('React DevTools')) return; + return Reflect.apply(target, thisArg, args); + }, + }); + </script> + </head> + <body> + <noscript>Your browser does not support JavaScript!</noscript> + <div id="root"></div> + + <script type="module" src="./app/index.tsx"></script> + </body> +</html> diff --git a/nixpkgs.nix b/nixpkgs.nix new file mode 100644 index 0000000..e6e07cb --- /dev/null +++ b/nixpkgs.nix @@ -0,0 +1,8 @@ +# A nixpkgs instance that is grabbed from the pinned nixpkgs commit in the lock file +# Useful to avoid using channels when using legacy nix commands +let lock = (builtins.fromJSON (builtins.readFile ./flake.lock)).nodes.nixpkgs.locked; +in +import (fetchTarball { + url = "https://github.com/nixos/nixpkgs/archive/${lock.rev}.tar.gz"; + sha256 = lock.narHash; +}) diff --git a/package.json b/package.json new file mode 100644 index 0000000..795fbc0 --- /dev/null +++ b/package.json @@ -0,0 +1,33 @@ +{ + "name": "protontweaks-db", + "type": "module", + "scripts": { + "ci": "bun install --frozen-lockfile", + "dev": "vite dev", + "build": "vite build" + }, + "dependencies": { + "@rain-cafe/js-utils": "^1.0.0", + "@rain-cafe/react-utils": "^2.3.0", + "@tanstack/react-query": "^5.24.8", + "clsx": "^2.1.0", + "lucide-react": "^0.344.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^6.22.2", + "sonner": "^1.4.3", + "tailwind-merge": "^2.2.1" + }, + "devDependencies": { + "@types/bun": "^1.0.8", + "@types/react": "^18.2.62", + "@types/react-dom": "^18.2.19", + "@vitejs/plugin-react": "^4.2.1", + "autoprefixer": "^10.4.18", + "cssnano": "^6.0.5", + "postcss": "^8.4.35", + "tailwindcss": "^3.4.1", + "vite": "^5.1.5", + "vitest": "^1.3.1" + } +} diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..0a5bd48 --- /dev/null +++ b/shell.nix @@ -0,0 +1,15 @@ +# Shell for bootstrapping flake-enabled nix and home-manager +# Enter it through 'nix develop' or (legacy) 'nix-shell' + +{ pkgs ? (import ./nixpkgs.nix) { } }: { + default = pkgs.mkShell { + # Enable experimental features without having to specify the argument + NIX_CONFIG = "experimental-features = nix-command flakes"; + buildInputs = with pkgs; [ + nixpkgs-fmt + nixd + bun + nodejs_20 + ]; + }; +} diff --git a/tailwind.config.ts b/tailwind.config.ts new file mode 100644 index 0000000..abc1593 --- /dev/null +++ b/tailwind.config.ts @@ -0,0 +1,7 @@ +import type { Config } from 'tailwindcss'; + +export default { + content: ['./app/**/*.{html,js,mjs,ts,tsx}', './components/**/*.{html,js,mjs,ts,tsx}'], + theme: {}, + plugins: [], +} satisfies Config; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..46b5b5e --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "lib": ["ESNext", "dom"], + "target": "ESNext", + "module": "ESNext", + "moduleDetection": "force", + "jsx": "react-jsx", + "allowJs": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true, + + /* Linting */ + "skipLibCheck": true, + "strict": true, + "noFallthroughCasesInSwitch": true, + "forceConsistentCasingInFileNames": true, + "paths": { + "@/*": ["./*"] + } + }, + "include": ["**/*.ts", "**/*.tsx"], + "exclude": ["node_modules"] +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..d91029e --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,31 @@ +import react from '@vitejs/plugin-react'; +import path from 'path'; +import { defineConfig } from 'vitest/config'; + +// https://vitejs.dev/config/ +export default defineConfig({ + build: { + target: 'esnext', + }, + server: { + port: 3030, + hmr: true, + proxy: { + '/api': { + target: 'https://tweaks.rains.cafe/api', + // target: 'https://api.protontweaks.com/v2', + changeOrigin: true, + rewrite: (path) => path.replace(/^\/api/, ''), + }, + }, + }, + resolve: { + alias: { + '@': path.resolve(__dirname, './'), + }, + }, + test: { + environment: 'happy-dom', + }, + plugins: [react()], +});