feat: done
This commit is contained in:
parent
c90da29b09
commit
bcdd1e4a04
12 changed files with 110 additions and 110 deletions
12
app.go
12
app.go
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"git.wh64.net/devproje/kuma-archive/config"
|
||||
"git.wh64.net/devproje/kuma-archive/internal/routes"
|
||||
"git.wh64.net/devproje/kuma-archive/internal/service"
|
||||
"github.com/devproje/commando"
|
||||
"github.com/devproje/commando/option"
|
||||
"github.com/devproje/commando/types"
|
||||
|
@ -14,15 +15,17 @@ import (
|
|||
|
||||
var (
|
||||
hash = "unknown"
|
||||
branch = "unknown"
|
||||
version = "unknown"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Printf("Kuma Archive %s-%s\n", version, hash)
|
||||
command := commando.NewCommando(os.Args[1:])
|
||||
cnf := config.Get()
|
||||
|
||||
ver := service.NewVersion(version, branch, hash)
|
||||
command.Root("daemon", "run file server", func(n *commando.Node) error {
|
||||
fmt.Printf("Kuma Archive %s\n", version)
|
||||
debug, err := option.ParseBool(*n.MustGetOpt("debug"), n)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -38,7 +41,7 @@ func main() {
|
|||
}
|
||||
|
||||
gin := gin.Default()
|
||||
routes.New(gin, apiOnly)
|
||||
routes.New(gin, ver, apiOnly)
|
||||
|
||||
fmt.Fprintf(os.Stdout, "binding server at: http://0.0.0.0:%d\n", cnf.Port)
|
||||
if err := gin.Run(fmt.Sprintf(":%d", cnf.Port)); err != nil {
|
||||
|
@ -57,6 +60,11 @@ func main() {
|
|||
Type: types.BOOLEAN,
|
||||
})
|
||||
|
||||
command.Root("version", "show system version info", func(n *commando.Node) error {
|
||||
fmt.Printf("Kuma Archive version %s\n", ver.String())
|
||||
return nil
|
||||
})
|
||||
|
||||
if err := command.Execute(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||
os.Exit(1)
|
||||
|
|
|
@ -13,7 +13,7 @@ type ConfigRef struct {
|
|||
|
||||
var (
|
||||
ROOT_DIRECTORY string
|
||||
CONFIG_DIR string
|
||||
CONFIG_FILE string
|
||||
INDEX_DIR string
|
||||
)
|
||||
|
||||
|
@ -33,7 +33,7 @@ func init() {
|
|||
_ = os.WriteFile(filepath.Join(ROOT_DIRECTORY, "config.json"), []byte(buf), 0644)
|
||||
}
|
||||
|
||||
CONFIG_DIR = filepath.Join(ROOT_DIRECTORY, "config.json")
|
||||
CONFIG_FILE = filepath.Join(ROOT_DIRECTORY, "config.json")
|
||||
|
||||
INDEX_DIR = filepath.Join(ROOT_DIRECTORY, "index")
|
||||
if _, err := os.ReadDir(INDEX_DIR); err != nil {
|
||||
|
@ -42,7 +42,7 @@ func init() {
|
|||
}
|
||||
|
||||
func Get() *ConfigRef {
|
||||
buf, err := os.ReadFile(CONFIG_DIR)
|
||||
buf, err := os.ReadFile(CONFIG_FILE)
|
||||
if err != nil {
|
||||
_, _ = fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||
return nil
|
||||
|
|
2
go.mod
2
go.mod
|
@ -18,12 +18,12 @@ require (
|
|||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.25.0 // indirect
|
||||
github.com/goccy/go-json v0.10.5 // indirect
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.24 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
||||
|
|
2
go.sum
2
go.sum
|
@ -49,6 +49,8 @@ github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
|||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
|
||||
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func New(app *gin.Engine, apiOnly bool) {
|
||||
func New(app *gin.Engine, version *service.Version, apiOnly bool) {
|
||||
app.Use(middleware.CORS)
|
||||
|
||||
api := app.Group("/api")
|
||||
|
@ -105,6 +105,10 @@ func New(app *gin.Engine, apiOnly bool) {
|
|||
|
||||
ctx.FileAttachment(data.Path, data.Name)
|
||||
})
|
||||
|
||||
api.GET("/version", func(ctx *gin.Context) {
|
||||
ctx.String(200, "%s", version.String())
|
||||
})
|
||||
}
|
||||
|
||||
if apiOnly {
|
||||
|
|
12
internal/service/database.go
Normal file
12
internal/service/database.go
Normal file
|
@ -0,0 +1,12 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
"git.wh64.net/devproje/kuma-archive/config"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
func Open() (*sql.DB, error) {
|
||||
return sql.Open("sqlite3", (config.ROOT_DIRECTORY))
|
||||
}
|
21
internal/service/version.go
Normal file
21
internal/service/version.go
Normal file
|
@ -0,0 +1,21 @@
|
|||
package service
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Version struct {
|
||||
Version string `json:"version"`
|
||||
Branch string `json:"branch"`
|
||||
Hash string `json:"hash"`
|
||||
}
|
||||
|
||||
func NewVersion(version, branch, hash string) *Version {
|
||||
return &Version{
|
||||
Version: version,
|
||||
Branch: branch,
|
||||
Hash: hash,
|
||||
}
|
||||
}
|
||||
|
||||
func (v *Version) String() string {
|
||||
return fmt.Sprintf("%s-%s (%s)", v.Version, v.Branch, v.Hash)
|
||||
}
|
|
@ -5,11 +5,11 @@
|
|||
"license": "MIT",
|
||||
"scripts": {
|
||||
"build:view": "tsc -b && vite build",
|
||||
"build:server": "go build -ldflags \"-X main.version=$(jq -r .version package.json) -X main.hash=$(git rev-parse --short=6 HEAD)\" -o kuma-archive",
|
||||
"build:server": "go build -ldflags \"-X main.version=$(jq -r .version package.json) -X main.hash=$(git rev-parse --short=7 HEAD) -X main.branch=$(git rev-parse --abbrev-ref HEAD)\" -o kuma-archive",
|
||||
"build": "bun run build:view && bun run build:server",
|
||||
"dev:view": "vite",
|
||||
"dev:server": "go run ./app.go daemon -d --api-only",
|
||||
"dev": "bun run build:view && go run ./app.go daemon -d",
|
||||
"dev:server": "go run -ldflags \"-X main.version=$(jq -r .version package.json) -X main.hash=$(git rev-parse --short=7 HEAD) -X main.branch=$(git rev-parse --abbrev-ref HEAD)\" ./app.go daemon -d --api-only",
|
||||
"dev": "bun run build:view && go run -ldflags \"-X main.version=$(jq -r .version package.json) -X main.hash=$(git rev-parse --short=7 HEAD) -X main.branch=$(git rev-parse --abbrev-ref HEAD)\" ./app.go daemon -d",
|
||||
"package": "sh ./scripts/package.sh",
|
||||
"lint": "eslint .",
|
||||
"preview": "vite preview"
|
||||
|
|
52
src/App.scss
52
src/App.scss
|
@ -25,59 +25,15 @@
|
|||
margin: 0 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ka-menu {
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
position: fixed;
|
||||
min-width: 300px;
|
||||
flex-direction: column;
|
||||
transform: translateX(-100%);
|
||||
justify-content: space-between;
|
||||
background-color: var(--nav-color);
|
||||
transition: transform 0.3s ease-in-out;
|
||||
|
||||
&.open {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.ka-menu-group {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ka-menu-item {
|
||||
width: 100%;
|
||||
height: 45px;
|
||||
display: flex;
|
||||
padding: 0 0.5rem;
|
||||
align-items: center;
|
||||
|
||||
span {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--nav-hover);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
color: var(--focus);
|
||||
}
|
||||
}
|
||||
|
||||
.ka-menu-footer {
|
||||
.action-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
padding: 1rem 1.5rem;
|
||||
justify-content: space-between;
|
||||
justify-content: center;
|
||||
.link {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
70
src/App.tsx
70
src/App.tsx
|
@ -1,4 +1,6 @@
|
|||
import { useEffect, useState } from "react";
|
||||
import { useVersion } from "./store/version";
|
||||
import FileView from "./components/file-view";
|
||||
import Directory from "./components/directory";
|
||||
import { DirEntry, usePath } from "./store/path";
|
||||
import { DynamicIcon } from "lucide-react/dynamic";
|
||||
|
@ -6,7 +8,6 @@ import { BrowserRouter, Route, Routes, useLocation } from "react-router";
|
|||
|
||||
import "./App.scss";
|
||||
import kuma from "./assets/kuma.png";
|
||||
import FileView from "./components/file-view";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
|
@ -57,8 +58,6 @@ function Dashboard() {
|
|||
}
|
||||
|
||||
function Header() {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<nav className="ka-nav">
|
||||
<a className="title" href="/">
|
||||
|
@ -66,61 +65,26 @@ function Header() {
|
|||
<h4 className="title-content">Kuma Archive</h4>
|
||||
</a>
|
||||
|
||||
<a onClick={ev => {
|
||||
ev.preventDefault();
|
||||
setOpen(!open);
|
||||
}}>
|
||||
<DynamicIcon className="link" name="more-vertical" />
|
||||
<div className="action-row">
|
||||
<a className="link" href="https://git.wh64.net/devproje/kuma-archive">
|
||||
<DynamicIcon name="folder-git-2" size={15} />
|
||||
</a>
|
||||
<MenuView open={open} setOpen={setOpen} />
|
||||
<a className="link" href="https://projecttl.net">
|
||||
<DynamicIcon name="globe" size={15} />
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
|
||||
function MenuView({ open, setOpen }: { open: boolean; setOpen: (value: boolean) => void }) {
|
||||
return (
|
||||
<div className={`ka-menu ${open ? "open" : ""}`}>
|
||||
<div className="ka-menu-group"></div>
|
||||
<div className="ka-menu-group">
|
||||
<div className="ka-menu-footer">
|
||||
<a className="btn link" href="https://git.wh64.net/devproje/kuma-archive">
|
||||
<DynamicIcon name="git-fork" />
|
||||
</a>
|
||||
<a className="btn link" href="https://projecttl.net">
|
||||
<DynamicIcon name="globe" />
|
||||
</a>
|
||||
<a className="btn link" onClick={ev => {
|
||||
ev.preventDefault();
|
||||
setOpen(false);
|
||||
}}>
|
||||
<DynamicIcon name="panel-left-close" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// function MenuItem({ icon, name, block }: { icon: IconName, name: string, block?: () => void }) {
|
||||
// return (
|
||||
// <a className={"ka-menu-item link"} onClick={ev => {
|
||||
// ev.preventDefault();
|
||||
// if (typeof block === "undefined")
|
||||
// return;
|
||||
|
||||
// block();
|
||||
// }}>
|
||||
// <DynamicIcon name={icon} />
|
||||
// <span>{name}</span>
|
||||
// </a>
|
||||
// );
|
||||
// }
|
||||
|
||||
function Footer() {
|
||||
const path = usePath();
|
||||
let file = 0;
|
||||
let dir = 0;
|
||||
|
||||
const version = useVersion();
|
||||
const [load, setLoad] = useState(false);
|
||||
|
||||
if (typeof path.data !== "undefined") {
|
||||
if (path.data.is_dir) {
|
||||
path.data.entries.forEach((entry: DirEntry) => {
|
||||
|
@ -133,6 +97,15 @@ function Footer() {
|
|||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!load) {
|
||||
version.update().then(() => {
|
||||
setLoad(true);
|
||||
});
|
||||
return;
|
||||
}
|
||||
}, [load, version]);
|
||||
|
||||
return (
|
||||
<footer className="ka-footer">
|
||||
{path.data ? path.data.is_dir ? (
|
||||
|
@ -142,6 +115,7 @@ function Footer() {
|
|||
) : <></> : <></>}
|
||||
|
||||
<div className="footer">
|
||||
<span><b>Kuma Archive</b> {version.value}</span>
|
||||
<p>
|
||||
© 2020-2025 <a href="https://git.wh64.net/devproje">Project_IO</a>. All rights reserved for images.
|
||||
<br />
|
||||
|
|
|
@ -45,5 +45,6 @@
|
|||
}
|
||||
|
||||
.ka-readme {
|
||||
padding-top: 1rem;
|
||||
padding: 1rem 10px 0.5rem 10px;
|
||||
border-bottom: 1px solid var(--foreground);
|
||||
}
|
||||
|
|
22
src/store/version.ts
Normal file
22
src/store/version.ts
Normal file
|
@ -0,0 +1,22 @@
|
|||
import { create } from "zustand";
|
||||
|
||||
interface VersionState {
|
||||
value: string | undefined;
|
||||
update(): Promise<void>;
|
||||
}
|
||||
|
||||
export const useVersion = create<VersionState>((set) => ({
|
||||
value: undefined,
|
||||
update: async () => {
|
||||
const res = await fetch("/api/version", {
|
||||
cache: "no-cache"
|
||||
});
|
||||
if (res.status !== 200 && res.status !== 304) {
|
||||
set({ value: undefined });
|
||||
return;
|
||||
}
|
||||
|
||||
const text = await res.text();
|
||||
set({ value: text });
|
||||
}
|
||||
}));
|
Loading…
Reference in a new issue