From d9280bdead2f2428881aa7d3623c98150d99196f Mon Sep 17 00:00:00 2001 From: Project_IO Date: Sat, 15 Mar 2025 01:05:52 +0900 Subject: [PATCH] feat: add kuma icon --- .gitignore | 2 +- app.go | 11 +++++++++- bun.lock | 5 +++++ index.html | 1 + internal/routes/mod.go | 39 +++++++++++++++++++--------------- internal/service/worker.go | 4 ++-- package.json | 8 ++++--- public/favicon.ico | Bin 0 -> 99678 bytes src/App.scss | 42 ------------------------------------- src/App.tsx | 3 ++- src/assets/kuma.png | Bin 0 -> 4793 bytes src/main.tsx | 4 +++- vite.config.ts | 2 +- 13 files changed, 52 insertions(+), 69 deletions(-) create mode 100644 public/favicon.ico create mode 100644 src/assets/kuma.png diff --git a/.gitignore b/.gitignore index 136130e..b908d77 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,6 @@ dist-ssr *.sln *.sw? -public/ +web/ ka_data/ kuma-archive diff --git a/app.go b/app.go index 63ebb64..720c605 100644 --- a/app.go +++ b/app.go @@ -22,12 +22,17 @@ func main() { return err } + apiOnly, err := option.ParseBool(*n.MustGetOpt("api-only"), n) + if err != nil { + return err + } + if !debug { gin.SetMode(gin.ReleaseMode) } gin := gin.Default() - routes.New(gin) + routes.New(gin, apiOnly) if err := gin.Run(fmt.Sprintf(":%d", cnf.Port)); err != nil { return err @@ -39,6 +44,10 @@ func main() { Desc: "service debugging mode", Short: []string{"d"}, Type: types.BOOLEAN, + }, types.OptionData{ + Name: "api-only", + Desc: "no serve frontend service", + Type: types.BOOLEAN, }) if err := command.Execute(); err != nil { diff --git a/bun.lock b/bun.lock index ffb0ef5..9f58547 100644 --- a/bun.lock +++ b/bun.lock @@ -4,6 +4,7 @@ "": { "name": "kuma-archive", "dependencies": { + "bootstrap": "^5.3.3", "react": "^19.0.0", "react-dom": "^19.0.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=="], + "@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-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=="], + "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=="], "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], diff --git a/index.html b/index.html index 14b7eee..cbcb9a6 100644 --- a/index.html +++ b/index.html @@ -2,6 +2,7 @@ + Kuma Archive diff --git a/internal/routes/mod.go b/internal/routes/mod.go index 277e399..714c1e4 100644 --- a/internal/routes/mod.go +++ b/internal/routes/mod.go @@ -9,37 +9,26 @@ import ( "github.com/gin-gonic/gin" ) -func New(app *gin.Engine) { - 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") - }) - +func New(app *gin.Engine, apiOnly bool) { api := app.Group("/api") { api.GET("/path/*path", func(ctx *gin.Context) { worker := service.NewWorkerService() path := ctx.Param("path") - info, err := worker.Read(path) + data, err := worker.Read(path) if err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) ctx.Status(404) return } - if !info.IsDir { - ctx.FileAttachment(info.FullPath, info.Name) + if !data.IsDir { + ctx.FileAttachment(data.Path, data.Name) return } - raw, err := os.ReadDir(info.FullPath) + raw, err := os.ReadDir(data.Path) if err != nil { ctx.Status(500) return @@ -55,8 +44,8 @@ func New(app *gin.Engine) { entries = append(entries, service.DirEntry{ Name: entry.Name(), + Path: path, FileSize: uint64(finfo.Size()), - FullPath: path, 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") + }) + } diff --git a/internal/service/worker.go b/internal/service/worker.go index c24e3f1..3859d54 100644 --- a/internal/service/worker.go +++ b/internal/service/worker.go @@ -11,7 +11,7 @@ type WorkerService struct{} type DirEntry struct { Name string `json:"name"` - FullPath string `json:"path"` + Path string `json:"path"` FileSize uint64 `json:"file_size"` IsDir bool `json:"is_dir"` } @@ -29,7 +29,7 @@ func (sv *WorkerService) Read(path string) (*DirEntry, error) { ret := DirEntry{ Name: info.Name(), - FullPath: fullpath, + Path: fullpath, FileSize: uint64(info.Size()), } return &ret, nil diff --git a/package.json b/package.json index a0f256d..514e02a 100644 --- a/package.json +++ b/package.json @@ -5,14 +5,16 @@ "type": "module", "scripts": { "dev": "vite", - "build": "tsc -b && vite build", - "build-server": "go build -o kuma-archive", - "build:all": "bun run build && bun run build-server", + "dev:server": "go run ./app.go daemon -d --api-only", "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 .", "preview": "vite preview" }, "dependencies": { + "bootstrap": "^5.3.3", "react": "^19.0.0", "react-dom": "^19.0.0", "react-router": "^7.3.0", diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..6ba7e7838019823ffcde44f2752c1cd1a081c66f GIT binary patch literal 99678 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 literal 0 HcmV?d00001 diff --git a/src/App.scss b/src/App.scss index b9d355d..e69de29 100644 --- a/src/App.scss +++ b/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; -} diff --git a/src/App.tsx b/src/App.tsx index 92c4a3c..d653a1d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,7 +1,8 @@ import { BrowserRouter, Route, Routes } from "react-router"; -import "./App.scss"; import Dashboard from "./components/dashboard"; +import "./App.scss"; + function App() { return ( diff --git a/src/assets/kuma.png b/src/assets/kuma.png new file mode 100644 index 0000000000000000000000000000000000000000..9d3b59e36977a7cecaa278a79a7bc940e734fc4f GIT binary patch literal 4793 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 literal 0 HcmV?d00001 diff --git a/src/main.tsx b/src/main.tsx index 9a8e659..fca56b6 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,8 +1,10 @@ import { StrictMode } from "react"; import { createRoot } from "react-dom/client"; -import "./index.scss"; import App from "./App.tsx"; +import "bootstrap/dist/css/bootstrap.min.css"; +import "./index.scss"; + createRoot(document.getElementById("root")!).render( diff --git a/vite.config.ts b/vite.config.ts index 6eba899..18b7cd0 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -5,6 +5,6 @@ import react from "@vitejs/plugin-react-swc"; export default defineConfig({ plugins: [react()], build: { - outDir: "public/" + outDir: "web/" } });