add conversation clean feature

This commit is contained in:
Zhang Minghan 2023-10-24 19:44:45 +08:00
parent 3b240aed58
commit aaf32d198e
9 changed files with 103 additions and 4 deletions

View File

@ -15,13 +15,14 @@ import {
useEffectAsync, useEffectAsync,
} from "../../utils.ts"; } from "../../utils.ts";
import { import {
deleteAllConversations,
deleteConversation, deleteConversation,
toggleConversation, toggleConversation,
updateConversationList, updateConversationList,
} from "../../conversation/history.ts"; } from "../../conversation/history.ts";
import { Button } from "../ui/button.tsx"; import { Button } from "../ui/button.tsx";
import { setMenu } from "../../store/menu.ts"; import { setMenu } from "../../store/menu.ts";
import { Copy, LogIn, Plus, RotateCw } from "lucide-react"; import {Copy, Eraser, LogIn, Plus, RotateCw} from "lucide-react";
import ConversationSegment from "./ConversationSegment.tsx"; import ConversationSegment from "./ConversationSegment.tsx";
import { import {
AlertDialog, AlertDialog,
@ -31,7 +32,7 @@ import {
AlertDialogDescription, AlertDialogDescription,
AlertDialogFooter, AlertDialogFooter,
AlertDialogHeader, AlertDialogHeader,
AlertDialogTitle, AlertDialogTitle, AlertDialogTrigger,
} from "../ui/alert-dialog.tsx"; } from "../ui/alert-dialog.tsx";
import { import {
getSharedLink, getSharedLink,
@ -54,6 +55,7 @@ function SideBar() {
const history: ConversationInstance[] = useSelector(selectHistory); const history: ConversationInstance[] = useSelector(selectHistory);
const refresh = useRef(null); const refresh = useRef(null);
const [shared, setShared] = useState<string>(""); const [shared, setShared] = useState<string>("");
const [removeAll, setRemoveAll] = useState<boolean>(false);
useEffectAsync(async () => { useEffectAsync(async () => {
await updateConversationList(dispatch); await updateConversationList(dispatch);
}, []); }, []);
@ -75,6 +77,47 @@ function SideBar() {
<Plus className={`h-4 w-4`} /> <Plus className={`h-4 w-4`} />
</Button> </Button>
<div className={`grow`} /> <div className={`grow`} />
<AlertDialog open={removeAll} onOpenChange={setRemoveAll}>
<AlertDialogTrigger asChild>
<Button variant={`ghost`} size={`icon`}>
<Eraser className={`h-4 w-4`} />
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>{t("conversation.remove-all-title")}</AlertDialogTitle>
<AlertDialogDescription>
{t("conversation.remove-all-description")}
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>
{t("conversation.cancel")}
</AlertDialogCancel>
<AlertDialogAction
onClick={async (e) => {
e.preventDefault();
e.stopPropagation();
if (await deleteAllConversations(dispatch))
toast({
title: t("conversation.delete-success"),
description: t("conversation.delete-success-prompt"),
});
else
toast({
title: t("conversation.delete-failed"),
description: t("conversation.delete-failed-prompt"),
});
setOperateConversation({ target: null, type: "" });
setRemoveAll(false);
}}
>
{t("conversation.delete")}
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
<Button <Button
className={`refresh-action`} className={`refresh-action`}
variant={`ghost`} variant={`ghost`}

View File

@ -1,7 +1,7 @@
import axios from "axios"; import axios from "axios";
import { Model } from "./conversation/types.ts"; import { Model } from "./conversation/types.ts";
export const version = "3.5.2"; export const version = "3.5.3";
export const dev: boolean = window.location.hostname === "localhost"; export const dev: boolean = window.location.hostname === "localhost";
export const deploy: boolean = true; export const deploy: boolean = true;
export let rest_api: string = "http://localhost:8094"; export let rest_api: string = "http://localhost:8094";

View File

@ -36,6 +36,15 @@ export async function deleteConversation(
return true; return true;
} }
export async function deleteAllConversations(
dispatch: AppDispatch,
): Promise<boolean> {
const resp = await axios.get("/conversation/clean");
if (!resp.data.status) return false;
await manager.deleteAll(dispatch);
return true;
}
export async function toggleConversation( export async function toggleConversation(
dispatch: AppDispatch, dispatch: AppDispatch,
id: number, id: number,

View File

@ -82,6 +82,13 @@ export class Manager {
if (this.conversations[id]) delete this.conversations[id]; if (this.conversations[id]) delete this.conversations[id];
} }
public async deleteAll(dispatch: AppDispatch): Promise<void> {
const ids = Object.keys(this.conversations).map((v) => parseInt(v));
for (const id of ids) await this.delete(dispatch, id);
await this.toggle(dispatch, -1);
}
public async send(t: any, auth: boolean, props: ChatProps): Promise<boolean> { public async send(t: any, auth: boolean, props: ChatProps): Promise<boolean> {
const id = this.getCurrent(); const id = this.getCurrent();
if (!this.conversations[id]) return false; if (!this.conversations[id]) return false;

View File

@ -54,7 +54,7 @@ function calc_prize(month: number): number {
return base * 0.9; return base * 0.9;
} }
return 8 * month; return base;
} }
type UpgradeProps = { type UpgradeProps = {

View File

@ -38,6 +38,9 @@ const resources = {
"remove-title": "Are you absolutely sure?", "remove-title": "Are you absolutely sure?",
"remove-description": "remove-description":
"This action cannot be undone. This will permanently delete the conversation ", "This action cannot be undone. This will permanently delete the conversation ",
"remove-all-title": "Clear History",
"remove-all-description":
"This action cannot be undone. This will permanently delete all conversations, continue?",
cancel: "Cancel", cancel: "Cancel",
delete: "Delete", delete: "Delete",
"delete-conversation": "Delete Conversation", "delete-conversation": "Delete Conversation",
@ -225,6 +228,8 @@ const resources = {
"refresh-failed-prompt": "请求出错,请重试。", "refresh-failed-prompt": "请求出错,请重试。",
"remove-title": "是否确定?", "remove-title": "是否确定?",
"remove-description": "此操作无法撤消。这将永久删除对话 ", "remove-description": "此操作无法撤消。这将永久删除对话 ",
"remove-all-title": "清除历史",
"remove-all-description": "此操作无法撤消。这将永久删除所有对话,是否继续?",
cancel: "取消", cancel: "取消",
delete: "删除", delete: "删除",
"delete-conversation": "删除对话", "delete-conversation": "删除对话",
@ -411,6 +416,9 @@ const resources = {
"remove-title": "Вы уверены?", "remove-title": "Вы уверены?",
"remove-description": "remove-description":
"Это действие нельзя отменить. Это навсегда удалит разговор ", "Это действие нельзя отменить. Это навсегда удалит разговор ",
"remove-all-title": "Очистить историю",
"remove-all-description":
"Это действие нельзя отменить. Это навсегда удалит все разговоры, продолжить?",
cancel: "Отмена", cancel: "Отмена",
delete: "Удалить", delete: "Удалить",
"delete-conversation": "Удалить разговор", "delete-conversation": "Удалить разговор",

View File

@ -101,6 +101,31 @@ func DeleteAPI(c *gin.Context) {
}) })
} }
func CleanAPI(c *gin.Context) {
user := auth.GetUser(c)
if user == nil {
c.JSON(http.StatusOK, gin.H{
"status": false,
"message": "user not found",
})
return
}
db := utils.GetDBFromContext(c)
if err := DeleteAllConversations(db, *user); err != nil {
c.JSON(http.StatusOK, gin.H{
"status": false,
"message": err.Error(),
})
return
}
c.JSON(http.StatusOK, gin.H{
"status": true,
"message": "",
})
}
func ShareAPI(c *gin.Context) { func ShareAPI(c *gin.Context) {
user := auth.GetUser(c) user := auth.GetUser(c)
if user == nil { if user == nil {

View File

@ -8,6 +8,7 @@ func Register(app *gin.Engine) {
router.GET("/list", ListAPI) router.GET("/list", ListAPI)
router.GET("/load", LoadAPI) router.GET("/load", LoadAPI)
router.GET("/delete", DeleteAPI) router.GET("/delete", DeleteAPI)
router.GET("/clean", CleanAPI)
// share // share
router.POST("/share", ShareAPI) router.POST("/share", ShareAPI)

View File

@ -1,6 +1,7 @@
package conversation package conversation
import ( import (
"chat/auth"
"chat/globals" "chat/globals"
"chat/utils" "chat/utils"
"database/sql" "database/sql"
@ -97,3 +98,8 @@ func (c *Conversation) DeleteConversation(db *sql.DB) bool {
} }
return true return true
} }
func DeleteAllConversations(db *sql.DB, user auth.User) error {
_, err := db.Exec("DELETE FROM conversation WHERE user_id = ?", user.GetID(db))
return err
}