Feat: Add Frontend Pages

新增网易云、随机动漫音乐和 404 页面,修改其他页面,引入 PrismJS 实现代码高亮
This commit is contained in:
奇趣保罗 2022-04-13 23:28:50 +08:00
parent 07e8976250
commit d70e7da0b1
10 changed files with 455 additions and 27 deletions

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<html class="font-auto" lang="zh-cmn-hans">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/src/images/icon.png" />

View File

@ -16,6 +16,7 @@
"ahooks": "^3.3.0",
"isomorphic-unfetch": "^3.1.0",
"lodash": "^4.17.21",
"prismjs": "^1.27.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-router-dom": "^6.3.0",
@ -24,6 +25,7 @@
"devDependencies": {
"@midwayjs/mock": "^3.3.0",
"@types/lodash": "^4.14.181",
"@types/prismjs": "^1.26.0",
"@types/react": "^17.0.44",
"@types/react-dom": "^17.0.15",
"@vitejs/plugin-react": "^1.3.0",

View File

@ -38,6 +38,16 @@ button{
font-style: normal;
}
.btn-group{
row-gap: .5em;
display: flex;
align-items: center;
}
.btn-group .btn{
margin-right: .5em;
}
/* 1 - 页眉
-------------------------------- */
.sidebar{
@ -168,7 +178,7 @@ button{
-------------------------------- */
main, footer{
margin: auto;
max-width: 45em;
max-width: 50em;
}
main .header{

View File

@ -8,8 +8,11 @@ import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Aside from "./components/Layout/Aside";
import Home from "./pages/index";
import Netease from "./pages/netease";
import Wallpaper from "./pages/wallpaper";
import ACGM from "./pages/acgm";
import Bing from "./pages/bing";
import NoMatch from "./pages/404";
function App() {
return (
@ -17,9 +20,11 @@ function App() {
<Aside />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/netease" element={<Netease />} />
<Route path="/wallpaper" element={<Wallpaper />} />
<Route path="/acgm" element={<ACGM />} />
<Route path="/bing" element={<Bing />} />
<Route path="*" element={<div>404</div>} />
<Route path="*" element={<NoMatch />} />
</Routes>
</Router>
);

14
src/pages/404.tsx Normal file
View File

@ -0,0 +1,14 @@
// React
import React from "react";
// Components
function NoMatch() {
return (
<main>
<h1>404</h1>
</main>
)
}
export default NoMatch;

200
src/pages/acgm.tsx Normal file
View File

@ -0,0 +1,200 @@
// React
import React, { useEffect, useRef } from "react";
// UI
import prism from "prismjs";
import ArticleHead from "@/components/Layout/ArticleHead";
// Interface
import { ChangeEvent } from "react";
// Components
function ACGM() {
let autoSwitch = false;
const audioRef = useRef<HTMLAudioElement>(null);
const onAudioEnded = () => {
console.log("ended", autoSwitch);
autoSwitch && onToggleSwitchSong();
}
useEffect(() => {
if (!audioRef.current) return;
audioRef.current.addEventListener("ended", onAudioEnded);
return () => {
if (!audioRef.current) return;
audioRef.current.removeEventListener("ended", onAudioEnded);
}
}, []);
useEffect(() => {
prism.highlightAll();
}, []);
const onToggleSwitchSong = () => {
if (!audioRef.current) return;
audioRef.current.src = audioRef.current.src;
audioRef.current.play();
}
const onSwitchChange = (ev: ChangeEvent<HTMLInputElement>) => {
autoSwitch = ev.target.checked;
}
return (
<main>
<ArticleHead title="随机动漫音乐" desc="输出一首随机的动漫音乐及信息,基于网易云 API" />
<article className="post">
<h3>使</h3>
<p> <code>https://api.paugram.com/acgm/</code>,即可获得一段歌曲 <code>JSON</code> 信息。</p>
<p>使 API <a href="https://api.paugram.com/notice"></a></p>
<p> API </p>
<p>使 <code>Cookie</code> </p>
<h3></h3>
<div className="ks-table text-nowrap">
<table>
<thead>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</thead>
<tbody>
<tr>
<td>list</td>
<td> <code></code> <code></code></td>
<td></td>
</tr>
<tr>
<td>play</td>
<td> <code>true</code> </td>
<td></td>
</tr>
</tbody>
</table>
</div>
<h3></h3>
<div className="ks-table text-nowrap">
<table>
<thead>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td><em className="green"></em></td>
<td></td>
</tr>
<tr>
<td>2</td>
<td><em className="green"></em></td>
<td></td>
</tr>
</tbody>
</table>
</div>
<h3></h3>
<div className="ks-table text-nowrap">
<table>
<thead>
<tr>
<td></td>
<td></td>
</tr>
</thead>
<tbody>
<tr>
<td>id</td>
<td> ID</td>
</tr>
<tr>
<td>title</td>
<td></td>
</tr>
<tr>
<td>artist</td>
<td></td>
</tr>
<tr>
<td>album</td>
<td></td>
</tr>
<tr>
<td>cover</td>
<td>https</td>
</tr>
<tr>
<td>link</td>
<td>https</td>
</tr>
</tbody>
</table>
</div>
<h3></h3>
<p></p>
<pre className="language-javascript"><code>{`https://api.paugram.com/acgm/
// 返回的是:
{
"id": 517567145,
"title": "初登校",
"artist": "橋本由香利",
"album": "ひなこのーと COMPLETE SOUNDTRACK",
"cover": ,
"link":
}
`}</code></pre>
<p> <code>List</code> </p>
<pre><code>https://api.paugram.com/acgm/?list=1&play=true</code></pre>
<p> <code>Audio</code> 使 API</p>
<pre className="language-html"><code>&lt;audio src="https://api.paugram.com/acgm/?play=true" controls&gt;&lt;/audio&gt;</code></pre>
<h3></h3>
<p></p>
<p>
<audio ref={audioRef} src={`//${location.host}/api/acgm/?play=true`} controls></audio>
</p>
<p className="btn-group">
<button className="btn green" onClick={onToggleSwitchSong}></button>
<label>
<input type="checkbox" className="switch" onChange={onSwitchChange} />
</label>
</p>
<h3></h3>
<p> http 绿</p>
<p> <code>head</code> <code>http</code> <code>https</code></p>
<pre className="language-html"><code>&lt;meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"/&gt;</code></pre>
<p></p>
<p></p>
<p> API </p>
<p><a href="http://music.163.com/playlist?id=78694173&userid=7041859" target="_blank"></a></p>
<h3></h3>
<ul>
<li><a href="http://music.163.com" rel="nofollow" target="_blank"></a></li>
</ul>
</article>
</main>
)
}
export default ACGM;

View File

@ -1,15 +1,21 @@
// React
import React from "react";
import React, { useEffect } from "react";
// UI
import prism from "prismjs";
import ArticleHead from "@/components/Layout/ArticleHead";
// Components
function Bing() {
useEffect(() => {
prism.highlightAll();
}, []);
return (
<main>
<section className="header">
<h1></h1>
<h2></h2>
</section>
<ArticleHead title="必应每日壁纸" desc="每日更新,尽享乐趣" />
<article className="post">
<h3>使</h3>
<p> <code>https://api.paugram.com/bing/</code> 可自动跳转到对应的壁纸</p>
@ -43,25 +49,25 @@ function Bing() {
// 返回的是:
{
"link":"https://cn.bing.com/th?id=OHR.QatarMuseum_EN-US2624327100_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=hp",
"copyright":"National Museum of Qatar in Doha, Qatar (© Hasan Zaidi/Shutterstock)",
}</code></pre>
"link":"https://cn.bing.com/th?id=OHR.QatarMuseum_EN-US2624327100_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=hp",
"copyright":"National Museum of Qatar in Doha, Qatar (© Hasan Zaidi/Shutterstock)",
}`}</code></pre>
<p>使 API</p>
<pre className="language-css"><code>body{
background: url("https://api.paugram.com/bing/") center/cover no-repeat;
<pre className="language-css"><code>{`body{
background: url("https://api.paugram.com/bing/") center/cover no-repeat;
}`}
</code></pre>
<p>使 API</p>
<pre className="language-css"><code>{`body:before{
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: .3;
z-index: -1;
content: "";
position: fixed;
background: url(https://api.paugram.com/bing/) center/cover;
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: .3;
z-index: -1;
content: "";
position: fixed;
background: url(https://api.paugram.com/bing/) center/cover;
}`}
</code></pre>

176
src/pages/netease.tsx Normal file
View File

@ -0,0 +1,176 @@
// React
import React, { useEffect } from "react";
// UI
import prism from "prismjs";
import ArticleHead from "@/components/Layout/ArticleHead";
// Components
function Netease() {
useEffect(() => {
prism.highlightAll();
}, []);
return (
<main>
<ArticleHead title="网易云解析" desc="解析音乐并精简输出,配合 Kico Player 使用更佳" />
<article className="post">
<h3>使</h3>
<p> <code>https://api.paugram.com/netease/</code> 并输入参数 <code>id</code> 或 <code>title</code>,即可获得一段歌曲 <code>JSON</code> 信息。</p>
<p>使 API <a href="https://api.paugram.com/notice"></a></p>
<p> API </p>
<h3></h3>
<p>使 <code>id</code> </p>
<div className="ks-table text-nowrap">
<table>
<thead>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</thead>
<tbody>
<tr>
<td>id</td>
<td> ID<code>517567145</code></td>
<td> ID</td>
</tr>
<tr>
<td>playlist</td>
<td></td>
<td></td>
</tr>
<tr>
<td>play</td>
<td> <code>true</code> </td>
<td></td>
</tr>
</tbody>
</table>
</div>
<h3></h3>
<div className="ks-table text-nowrap">
<table>
<thead>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</thead>
<tbody>
<tr>
<td>id</td>
<td> ID</td>
<td><code>string</code></td>
</tr>
<tr>
<td>title</td>
<td></td>
<td><code>string</code></td>
</tr>
<tr>
<td>artist</td>
<td></td>
<td><code>string</code></td>
</tr>
<tr>
<td>album</td>
<td></td>
<td><code>string</code></td>
</tr>
<tr>
<td>cover</td>
<td>https</td>
<td><code>string</code></td>
</tr>
<tr>
<td>link</td>
<td></td>
<td><code>string</code></td>
</tr>
<tr>
<td>lyric</td>
<td> LRC </td>
<td><code>string</code></td>
</tr>
<tr>
<td>sub_lyric</td>
<td> LRC </td>
<td><code>string</code></td>
</tr>
<tr>
<td>served</td>
<td> VIP </td>
<td><code>true</code> <code>false</code></td>
</tr>
</tbody>
</table>
</div>
<h3></h3>
<p> ID </p>
<pre className="language-javascript"><code>{`https://api.paugram.com/netease/?id=517567145
// 返回的是:
{
"code": 1,
"msg": "Success",
"data": {
"id": 517567145,
"title": "初登校",
"artist": "橋本由香利",
"album": "ひなこのーと COMPLETE SOUNDTRACK",
"cover": ,
"lyric": ,
"sub_lyric": ,
"link":
}
}
`}</code></pre>
<p> ID </p>
<pre><code>https://api.paugram.com/netease/?id=517567145&play=true</code></pre>
<p> Kico Style Kico Player 使 API</p>
<pre className="language-javascript"><code>{`ks.ajax({
method: "GET",
url: \`https://api.paugram.com/netease/?id=\${id}\`,
success: (req) => {
const item = JSON.parse(req.response);
.add([item]);
},
failed: (req) => {
ks.notice("获取音乐信息错误了!", {color: "red"});
}
});`}</code></pre>
<h3></h3>
<p>使 Kico Player </p>
<div id="kico-player"></div>
<div className="btn-group">
<button id="add-music" className="btn green"></button>
<button id="remove-music" className="btn red"></button>
</div>
<h3></h3>
<p> http 绿</p>
<p> <code>head</code> <code>http</code> <code>https</code></p>
<pre className="language-html"><code>&lt;meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"/&gt;</code></pre>
<h3></h3>
<ul>
<li><a href="http://music.163.com" rel="nofollow" target="_blank"></a></li>
<li><a href="https://works.paugram.com/player" target="_blank">Kico Player</a></li>
<li><a href="https://github.com/metowolf/Meting" target="_blank">Meting</a> </li>
</ul>
</article>
</main>
)
}
export default Netease;

View File

@ -1,20 +1,25 @@
// React
import React from "react";
import React, { useEffect } from "react";
// UI
import prism from "prismjs";
import ArticleHead from "@/components/Layout/ArticleHead";
import HelpExample from "../images/help/wallpaper-pr-example.jpg";
import HelpRequire from "../images/help/wallpaper-pr-require.jpg";
// Components
function Wallpaper() {
useEffect(() => {
prism.highlightAll();
}, []);
return (
<main>
<section className="header">
<h1></h1>
<h2> Single </h2>
</section>
<ArticleHead title="随机动漫壁纸" desc="生成适合 Single 主题的白底动漫壁纸" />
<article className="post">
<h3></h3>
<p> API <a href="https://github.com/Dreamer-Paul/Anime-Wallpaper" target="_blank">Anime-Wallpaper</a> PRCommit </p>

View File

@ -912,6 +912,11 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.23.tgz#3b41a6e643589ac6442bdbd7a4a3ded62f33f7da"
integrity sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==
"@types/prismjs@^1.26.0":
version "1.26.0"
resolved "https://registry.yarnpkg.com/@types/prismjs/-/prismjs-1.26.0.tgz#a1c3809b0ad61c62cac6d4e0c56d610c910b7654"
integrity sha512-ZTaqn/qSqUuAq1YwvOFQfVW1AR/oQJlLSZVustdjwI+GZ8kr0MSHBj0tsXPW1EqHubx50gtBEjbPGsdZwQwCjQ==
"@types/prop-types@*":
version "15.7.5"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf"
@ -2414,6 +2419,11 @@ prisma@^3.12.0:
dependencies:
"@prisma/engines" "3.12.0-37.22b822189f46ef0dc5c5b503368d1bee01213980"
prismjs@^1.27.0:
version "1.27.0"
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.27.0.tgz#bb6ee3138a0b438a3653dd4d6ce0cc6510a45057"
integrity sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==
proper-url-join@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/proper-url-join/-/proper-url-join-2.1.1.tgz#ee4146edc08f512a0ee1053a355e06950691d06f"