feat: refresh api key feature and image file preview feature

This commit is contained in:
Zhang Minghan 2024-01-04 18:13:02 +08:00
parent e5755a000d
commit b6049e28ff
9 changed files with 50 additions and 10 deletions

View File

@ -32,5 +32,6 @@ func AnalysisRequest(model string, buffer *utils.Buffer, err error) {
return
}
IncrRequest(instance)
IncrModelRequest(instance, model, int64(buffer.CountToken()))
}

View File

@ -8,7 +8,7 @@
},
"package": {
"productName": "chatnio",
"version": "3.8.0"
"version": "3.8.1"
},
"tauri": {
"allowlist": {

View File

@ -5,8 +5,7 @@
.file-instance {
cursor: pointer;
display: flex;
flex-direction: row;
align-items: center;
flex-direction: column;
margin: 2px 0 !important;
margin-bottom: 4px !important;
padding: 6px 12px !important;
@ -14,6 +13,22 @@
background: hsla(var(--background-container)) !important;
border-radius: var(--radius);
.file-content {
background: none !important;
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
}
img {
max-width: 320px;
max-height: 240px;
object-fit: cover;
border-radius: var(--radius);
margin: 0.25rem 0;
}
@media (max-width: 668px) {
& {
white-space: pre-wrap;

View File

@ -1,5 +1,6 @@
import { File } from "lucide-react";
import { saveAsFile } from "@/utils/dom.ts";
import { useMemo } from "react";
/**
* file format:
@ -12,6 +13,13 @@ import { saveAsFile } from "@/utils/dom.ts";
export function parseFile(data: string) {
const filename = data.split("\n")[0].replace("[[", "").replace("]]", "");
const content = data.replace(`[[${filename}]]\n`, "");
const image = useMemo(() => {
// get image url from content (like: https://i.imgur.com/xxxxx.png)
const match = content
.toLowerCase()
.match(/(https?:\/\/.*\.(?:png|jpg|jpeg|gif))/);
return match ? match[0] : "";
}, [filename, content]);
return (
<div
@ -23,8 +31,11 @@ export function parseFile(data: string) {
saveAsFile(filename, content);
}}
>
<div className={`file-content`}>
<File className={`mr-1`} />
<span className={`name`}>{filename}</span>
</div>
{image && <img src={image} className={`file-image`} alt={""} />}
</div>
);
}

View File

@ -14,7 +14,7 @@ import React from "react";
import { syncSiteInfo } from "@/admin/api/info.ts";
import { loadPreferenceModels } from "@/utils/storage.ts";
export const version = "3.8.0-rc";
export const version = "3.8.1";
export const dev: boolean = getDev();
export const deploy: boolean = true;
export let rest_api: string = getRestApi(deploy);

View File

@ -18,7 +18,7 @@ import {
getApiKey,
} from "@/store/api.ts";
import { Input } from "@/components/ui/input.tsx";
import { Copy, ExternalLink } from "lucide-react";
import { Copy, ExternalLink, RotateCw } from "lucide-react";
import { useToast } from "@/components/ui/use-toast.ts";
import { copyClipboard } from "@/utils/dom.ts";
import { useEffectAsync } from "@/utils/hook.ts";
@ -53,6 +53,13 @@ function ApikeyDialog() {
<DialogDescription asChild>
<div className={`api-dialog`}>
<div className={`api-wrapper`}>
<Button
variant={`outline`}
size={`icon`}
onClick={() => getApiKey(dispatch)}
>
<RotateCw className={`h-4 w-4`} />
</Button>
<Input value={key} />
<Button variant={`default`} size={`icon`} onClick={copyKey}>
<Copy className={`h-4 w-4`} />

View File

@ -8,7 +8,9 @@ export async function copyClipboard(text: string) {
*/
try {
if (navigator.clipboard) return await navigator.clipboard.writeText(text);
if (navigator.clipboard && navigator.clipboard.writeText) {
return await navigator.clipboard.writeText(text);
}
const el = document.createElement("textarea");
el.value = text;

View File

@ -1,7 +1,6 @@
package middleware
import (
"chat/admin"
"chat/utils"
"fmt"
"github.com/gin-gonic/gin"
@ -62,7 +61,6 @@ func ThrottleMiddleware() gin.HandlerFunc {
ip := c.ClientIP()
path := c.Request.URL.Path
cache := utils.GetCacheFromContext(c)
admin.IncrRequest(cache)
limiter := GetPrefixMap[Limiter](path, limits)
if limiter != nil && limiter.RateLimit(cache, ip, path) {

View File

@ -58,5 +58,11 @@ func RegisterStaticRoute(engine *gin.Engine) {
c.File("./app/dist/index.html")
})
// redirect /v1 to /api/v1
engine.Any("/v1/*path", func(c *gin.Context) {
path := c.Param("path")
c.Redirect(301, fmt.Sprintf("/api/v1/%s", path))
})
fmt.Println(`[service] start serving static files from ~/app/dist`)
}