├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── .eslintrc.json ├── assets ├── logo.png ├── banner.png ├── favicon.png ├── logo-192.png ├── logo_large.png └── placeholder.svg ├── public ├── favicon.ico ├── icons │ └── logo-192.png ├── robots.txt ├── manifest.webmanifest ├── opensearchdescription.xml ├── ads.txt └── offline.html ├── pages ├── about.js ├── changelog.mdx ├── api │ ├── omnisearch.js │ └── opensearch.js ├── privacy-policy.mdx ├── opensearch.js ├── sitemap-2.xml.js ├── skinlines │ ├── index.js │ └── [skinlineId] │ │ ├── skins │ │ └── [skinId].js │ │ └── index.js ├── champions │ └── [champId] │ │ ├── skins │ │ └── [skinId].js │ │ └── index.js ├── shortcuts.mdx ├── universes │ ├── [universeId] │ │ ├── skins │ │ │ └── [skinId].js │ │ └── index.js │ └── index.js ├── _document.js ├── index.js └── _app.js ├── data ├── constants.js ├── contexts.js ├── patch.js ├── store.js ├── _precache.mjs └── helpers.js ├── components ├── loading │ ├── index.js │ └── styles.module.scss ├── new-additions │ ├── helpers.js │ ├── index.js │ └── style.module.scss ├── image.js ├── fallback.js ├── index.js ├── footer │ ├── styles.module.scss │ └── index.js ├── nav │ └── index.js ├── styles.module.scss ├── venatus │ ├── styles.module.scss │ └── index.js ├── skin-viewer │ ├── helpers.js │ ├── popup.js │ ├── styles.module.scss │ └── index.js ├── skin-grid │ ├── index.js │ └── styles.module.scss ├── omnisearch │ ├── styles.module.scss │ └── index.js └── header │ ├── index.js │ └── styles.module.scss ├── .gitignore ├── next.config.js ├── package.json ├── README.md ├── styles ├── globals.scss ├── static.module.scss ├── collection.module.scss └── index.module.scss ├── CHANGELOG.md └── pwa.cache.js /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | ko_fi: preyneyv 2 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/preyneyv/lol-skin-explorer/HEAD/assets/logo.png -------------------------------------------------------------------------------- /assets/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/preyneyv/lol-skin-explorer/HEAD/assets/banner.png -------------------------------------------------------------------------------- /assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/preyneyv/lol-skin-explorer/HEAD/assets/favicon.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/preyneyv/lol-skin-explorer/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /assets/logo-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/preyneyv/lol-skin-explorer/HEAD/assets/logo-192.png -------------------------------------------------------------------------------- /assets/logo_large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/preyneyv/lol-skin-explorer/HEAD/assets/logo_large.png -------------------------------------------------------------------------------- /pages/about.js: -------------------------------------------------------------------------------- 1 | export default function Page() { 2 | return
About info goes here.
; 3 | } 4 | -------------------------------------------------------------------------------- /public/icons/logo-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/preyneyv/lol-skin-explorer/HEAD/public/icons/logo-192.png -------------------------------------------------------------------------------- /data/constants.js: -------------------------------------------------------------------------------- 1 | /* URLs */ 2 | export const CDRAGON = "https://raw.communitydragon.org"; 3 | export const ROOT = "https://www.skinexplorer.lol"; 4 | -------------------------------------------------------------------------------- /data/contexts.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const PropsContext = React.createContext({}); 4 | PropsContext.displayName = "PropsContext"; 5 | 6 | export const PropsProvider = PropsContext.Provider; 7 | export const useProps = () => React.useContext(PropsContext); 8 | -------------------------------------------------------------------------------- /components/loading/index.js: -------------------------------------------------------------------------------- 1 | import styles from "./styles.module.scss"; 2 | 3 | export function Loading() { 4 | return ( 5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /pages/changelog.mdx: -------------------------------------------------------------------------------- 1 | import { Layout } from "../components"; 2 | import styles from "../styles/static.module.scss"; 3 | import Changelog from "../CHANGELOG.md"; 4 | 5 | 6 | 7 | export default ({ children }) => ( 8 | 9 |
{children}
10 |
11 | ); 12 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # * 2 | User-agent: * 3 | Allow: /_next/static/ 4 | Allow: /_next/image 5 | Disallow: /_next/ 6 | Disallow: /api/ 7 | Disallow: /lol-game-data/ 8 | Disallow: /opensearch 9 | Allow: / 10 | 11 | # Host 12 | Host: https://www.skinexplorer.lol 13 | 14 | # Sitemaps 15 | Sitemap: https://www.skinexplorer.lol/sitemap-2.xml 16 | -------------------------------------------------------------------------------- /public/manifest.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "background_color": "#0C0F13", 3 | "description": "Browse through League of Legends skins from the comfort of your browser!", 4 | "display": "fullscreen", 5 | "icons": [ 6 | { 7 | "src": "icons/logo-192.png", 8 | "sizes": "192x192", 9 | "type": "image/png" 10 | } 11 | ], 12 | "name": "Skin Explorer", 13 | "start_url": "/" 14 | } 15 | -------------------------------------------------------------------------------- /pages/api/omnisearch.js: -------------------------------------------------------------------------------- 1 | import { store } from "../../data/store"; 2 | 3 | export default async function handler(req, res) { 4 | const query = req.query.query ? req.query.query.trim() : ""; 5 | 6 | let results; 7 | if (query.length) { 8 | results = store.fuse.search(query, { limit: 10 }).map((i) => i.item); 9 | } else { 10 | results = []; 11 | } 12 | 13 | res.status(200).send(results); 14 | } 15 | -------------------------------------------------------------------------------- /components/new-additions/helpers.js: -------------------------------------------------------------------------------- 1 | import { store } from "../../data/store"; 2 | import { splitId } from "../../data/helpers"; 3 | 4 | export async function prepareAdditions() { 5 | const { added, skins, champions } = store.patch; 6 | 7 | return added.skins 8 | .map((id) => skins[id]) 9 | .sort((a, b) => (a.name > b.name ? 1 : -1)) 10 | .map((skin) => { 11 | const cId = splitId(skin.id)[0]; 12 | const champ = champions.find((c) => c.id === cId); 13 | return { ...skin, $$key: champ.key }; 14 | }); 15 | } 16 | -------------------------------------------------------------------------------- /pages/api/opensearch.js: -------------------------------------------------------------------------------- 1 | import { store } from "../../data/store"; 2 | 3 | export default async function handler(req, res) { 4 | const query = req.query.query ? req.query.query.trim() : ""; 5 | 6 | let results; 7 | if (query.length) { 8 | results = store.fuse.search(query, { limit: 10 }).map((i) => i.item); 9 | } else { 10 | results = []; 11 | } 12 | 13 | let unique = []; 14 | results.map((r) => !unique.includes(r.name) && unique.push(r.name)); 15 | 16 | res.status(200).send([req.query.query ?? "", unique]); 17 | } 18 | -------------------------------------------------------------------------------- /components/image.js: -------------------------------------------------------------------------------- 1 | import NextImage from "next/image"; 2 | import { useState, useEffect } from "react"; 3 | import placeholder from "../assets/placeholder.svg"; 4 | 5 | export default function Image({ src, objectFit, ...props }) { 6 | const [exists, setExists] = useState(true); 7 | useEffect(() => setExists(true), [src]); 8 | 9 | let actualSrc = exists ? src : placeholder; 10 | 11 | return ( 12 | setExists(false)} 17 | /> 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /assets/placeholder.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /components/fallback.js: -------------------------------------------------------------------------------- 1 | import Head from "next/head"; 2 | import { useRouter } from "next/router"; 3 | import { makeTitle } from "../data/helpers"; 4 | import { Footer, FooterContainer } from "./footer"; 5 | import { Header } from "./header"; 6 | import { Loading } from "./loading"; 7 | 8 | export function Fallback({ children }) { 9 | const router = useRouter(); 10 | if (router.isFallback) 11 | return ( 12 | <> 13 | {makeTitle("Loading...")} 14 | 15 |
16 | 17 |