feat: add kuma icon
This commit is contained in:
parent
ce1fd7987f
commit
d9280bdead
13 changed files with 52 additions and 69 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -23,6 +23,6 @@ dist-ssr
|
||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
|
|
||||||
public/
|
web/
|
||||||
ka_data/
|
ka_data/
|
||||||
kuma-archive
|
kuma-archive
|
||||||
|
|
11
app.go
11
app.go
|
@ -22,12 +22,17 @@ func main() {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
apiOnly, err := option.ParseBool(*n.MustGetOpt("api-only"), n)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if !debug {
|
if !debug {
|
||||||
gin.SetMode(gin.ReleaseMode)
|
gin.SetMode(gin.ReleaseMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
gin := gin.Default()
|
gin := gin.Default()
|
||||||
routes.New(gin)
|
routes.New(gin, apiOnly)
|
||||||
|
|
||||||
if err := gin.Run(fmt.Sprintf(":%d", cnf.Port)); err != nil {
|
if err := gin.Run(fmt.Sprintf(":%d", cnf.Port)); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -39,6 +44,10 @@ func main() {
|
||||||
Desc: "service debugging mode",
|
Desc: "service debugging mode",
|
||||||
Short: []string{"d"},
|
Short: []string{"d"},
|
||||||
Type: types.BOOLEAN,
|
Type: types.BOOLEAN,
|
||||||
|
}, types.OptionData{
|
||||||
|
Name: "api-only",
|
||||||
|
Desc: "no serve frontend service",
|
||||||
|
Type: types.BOOLEAN,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err := command.Execute(); err != nil {
|
if err := command.Execute(); err != nil {
|
||||||
|
|
5
bun.lock
5
bun.lock
|
@ -4,6 +4,7 @@
|
||||||
"": {
|
"": {
|
||||||
"name": "kuma-archive",
|
"name": "kuma-archive",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"bootstrap": "^5.3.3",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
"react-router": "^7.3.0",
|
"react-router": "^7.3.0",
|
||||||
|
@ -136,6 +137,8 @@
|
||||||
|
|
||||||
"@parcel/watcher-win32-x64": ["@parcel/watcher-win32-x64@2.5.1", "", { "os": "win32", "cpu": "x64" }, "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA=="],
|
"@parcel/watcher-win32-x64": ["@parcel/watcher-win32-x64@2.5.1", "", { "os": "win32", "cpu": "x64" }, "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA=="],
|
||||||
|
|
||||||
|
"@popperjs/core": ["@popperjs/core@2.11.8", "", {}, "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A=="],
|
||||||
|
|
||||||
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.35.0", "", { "os": "android", "cpu": "arm" }, "sha512-uYQ2WfPaqz5QtVgMxfN6NpLD+no0MYHDBywl7itPYd3K5TjjSghNKmX8ic9S8NU8w81NVhJv/XojcHptRly7qQ=="],
|
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.35.0", "", { "os": "android", "cpu": "arm" }, "sha512-uYQ2WfPaqz5QtVgMxfN6NpLD+no0MYHDBywl7itPYd3K5TjjSghNKmX8ic9S8NU8w81NVhJv/XojcHptRly7qQ=="],
|
||||||
|
|
||||||
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.35.0", "", { "os": "android", "cpu": "arm64" }, "sha512-FtKddj9XZudurLhdJnBl9fl6BwCJ3ky8riCXjEw3/UIbjmIY58ppWwPEvU3fNu+W7FUsAsB1CdH+7EQE6CXAPA=="],
|
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.35.0", "", { "os": "android", "cpu": "arm64" }, "sha512-FtKddj9XZudurLhdJnBl9fl6BwCJ3ky8riCXjEw3/UIbjmIY58ppWwPEvU3fNu+W7FUsAsB1CdH+7EQE6CXAPA=="],
|
||||||
|
@ -240,6 +243,8 @@
|
||||||
|
|
||||||
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||||
|
|
||||||
|
"bootstrap": ["bootstrap@5.3.3", "", { "peerDependencies": { "@popperjs/core": "^2.11.8" } }, "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg=="],
|
||||||
|
|
||||||
"brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="],
|
"brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="],
|
||||||
|
|
||||||
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
|
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/x-icon" src="/public/favicon.ico" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Kuma Archive</title>
|
<title>Kuma Archive</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
|
@ -9,37 +9,26 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func New(app *gin.Engine) {
|
func New(app *gin.Engine, apiOnly bool) {
|
||||||
app.Use(static.Serve("/", static.LocalFile("./public", true)))
|
|
||||||
app.Use(static.Serve("/assets", static.LocalFile("./assets", false)))
|
|
||||||
|
|
||||||
app.NoRoute(func(ctx *gin.Context) {
|
|
||||||
ctx.File("./public/index.html")
|
|
||||||
})
|
|
||||||
|
|
||||||
app.GET("favicon.ico", func(ctx *gin.Context) {
|
|
||||||
ctx.File("/assets/favicon.ico")
|
|
||||||
})
|
|
||||||
|
|
||||||
api := app.Group("/api")
|
api := app.Group("/api")
|
||||||
{
|
{
|
||||||
api.GET("/path/*path", func(ctx *gin.Context) {
|
api.GET("/path/*path", func(ctx *gin.Context) {
|
||||||
worker := service.NewWorkerService()
|
worker := service.NewWorkerService()
|
||||||
|
|
||||||
path := ctx.Param("path")
|
path := ctx.Param("path")
|
||||||
info, err := worker.Read(path)
|
data, err := worker.Read(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||||
ctx.Status(404)
|
ctx.Status(404)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !info.IsDir {
|
if !data.IsDir {
|
||||||
ctx.FileAttachment(info.FullPath, info.Name)
|
ctx.FileAttachment(data.Path, data.Name)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
raw, err := os.ReadDir(info.FullPath)
|
raw, err := os.ReadDir(data.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Status(500)
|
ctx.Status(500)
|
||||||
return
|
return
|
||||||
|
@ -55,8 +44,8 @@ func New(app *gin.Engine) {
|
||||||
|
|
||||||
entries = append(entries, service.DirEntry{
|
entries = append(entries, service.DirEntry{
|
||||||
Name: entry.Name(),
|
Name: entry.Name(),
|
||||||
|
Path: path,
|
||||||
FileSize: uint64(finfo.Size()),
|
FileSize: uint64(finfo.Size()),
|
||||||
FullPath: path,
|
|
||||||
IsDir: finfo.IsDir(),
|
IsDir: finfo.IsDir(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -68,4 +57,20 @@ func New(app *gin.Engine) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if apiOnly {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
app.Use(static.Serve("/", static.LocalFile("./web", true)))
|
||||||
|
app.Use(static.Serve("/assets", static.LocalFile("./assets", false)))
|
||||||
|
|
||||||
|
app.NoRoute(func(ctx *gin.Context) {
|
||||||
|
ctx.File("./web/index.html")
|
||||||
|
})
|
||||||
|
|
||||||
|
app.GET("favicon.ico", func(ctx *gin.Context) {
|
||||||
|
ctx.File("/web/assets/favicon.ico")
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ type WorkerService struct{}
|
||||||
|
|
||||||
type DirEntry struct {
|
type DirEntry struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
FullPath string `json:"path"`
|
Path string `json:"path"`
|
||||||
FileSize uint64 `json:"file_size"`
|
FileSize uint64 `json:"file_size"`
|
||||||
IsDir bool `json:"is_dir"`
|
IsDir bool `json:"is_dir"`
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ func (sv *WorkerService) Read(path string) (*DirEntry, error) {
|
||||||
|
|
||||||
ret := DirEntry{
|
ret := DirEntry{
|
||||||
Name: info.Name(),
|
Name: info.Name(),
|
||||||
FullPath: fullpath,
|
Path: fullpath,
|
||||||
FileSize: uint64(info.Size()),
|
FileSize: uint64(info.Size()),
|
||||||
}
|
}
|
||||||
return &ret, nil
|
return &ret, nil
|
||||||
|
|
|
@ -5,14 +5,16 @@
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "tsc -b && vite build",
|
"dev:server": "go run ./app.go daemon -d --api-only",
|
||||||
"build-server": "go build -o kuma-archive",
|
|
||||||
"build:all": "bun run build && bun run build-server",
|
|
||||||
"dev:all": "bun run build && go run ./app.go daemon -d",
|
"dev:all": "bun run build && go run ./app.go daemon -d",
|
||||||
|
"build": "tsc -b && vite build",
|
||||||
|
"build:server": "go build -o kuma-archive",
|
||||||
|
"build:all": "bun run build && bun run build-server",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"bootstrap": "^5.3.3",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
"react-router": "^7.3.0",
|
"react-router": "^7.3.0",
|
||||||
|
|
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 97 KiB |
42
src/App.scss
42
src/App.scss
|
@ -1,42 +0,0 @@
|
||||||
#root {
|
|
||||||
max-width: 1280px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 2rem;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
height: 6em;
|
|
||||||
padding: 1.5em;
|
|
||||||
will-change: filter;
|
|
||||||
transition: filter 300ms;
|
|
||||||
}
|
|
||||||
.logo:hover {
|
|
||||||
filter: drop-shadow(0 0 2em #646cffaa);
|
|
||||||
}
|
|
||||||
.logo.react:hover {
|
|
||||||
filter: drop-shadow(0 0 2em #61dafbaa);
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes logo-spin {
|
|
||||||
from {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-reduced-motion: no-preference) {
|
|
||||||
a:nth-of-type(2) .logo {
|
|
||||||
animation: logo-spin infinite 20s linear;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
padding: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.read-the-docs {
|
|
||||||
color: #888;
|
|
||||||
}
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { BrowserRouter, Route, Routes } from "react-router";
|
import { BrowserRouter, Route, Routes } from "react-router";
|
||||||
import "./App.scss";
|
|
||||||
import Dashboard from "./components/dashboard";
|
import Dashboard from "./components/dashboard";
|
||||||
|
|
||||||
|
import "./App.scss";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
|
|
BIN
src/assets/kuma.png
Normal file
BIN
src/assets/kuma.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.7 KiB |
|
@ -1,8 +1,10 @@
|
||||||
import { StrictMode } from "react";
|
import { StrictMode } from "react";
|
||||||
import { createRoot } from "react-dom/client";
|
import { createRoot } from "react-dom/client";
|
||||||
import "./index.scss";
|
|
||||||
import App from "./App.tsx";
|
import App from "./App.tsx";
|
||||||
|
|
||||||
|
import "bootstrap/dist/css/bootstrap.min.css";
|
||||||
|
import "./index.scss";
|
||||||
|
|
||||||
createRoot(document.getElementById("root")!).render(
|
createRoot(document.getElementById("root")!).render(
|
||||||
<StrictMode>
|
<StrictMode>
|
||||||
<App />
|
<App />
|
||||||
|
|
|
@ -5,6 +5,6 @@ import react from "@vitejs/plugin-react-swc";
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react()],
|
plugins: [react()],
|
||||||
build: {
|
build: {
|
||||||
outDir: "public/"
|
outDir: "web/"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue