diff --git a/web/src/ChatMenu.js b/web/src/ChatMenu.js
index dfc40907..d85e12ce 100644
--- a/web/src/ChatMenu.js
+++ b/web/src/ChatMenu.js
@@ -13,8 +13,8 @@
// limitations under the License.
import React from "react";
-import {Menu} from "antd";
-import {LayoutOutlined} from "@ant-design/icons";
+import {Button, Menu} from "antd";
+import {DeleteOutlined, LayoutOutlined, PlusOutlined} from "@ant-design/icons";
class ChatMenu extends React.Component {
constructor(props) {
@@ -38,6 +38,7 @@ class ChatMenu extends React.Component {
categories[chat.category].push(chat);
});
+ const selectedKeys = this.state === undefined ? [] : this.state.selectedKeys;
return Object.keys(categories).map((category, index) => {
return {
key: `${index}`,
@@ -45,10 +46,50 @@ class ChatMenu extends React.Component {
label: category,
children: categories[category].map((chat, chatIndex) => {
const globalChatIndex = chats.indexOf(chat);
+ const isSelected = selectedKeys.includes(`${index}-${chatIndex}`);
return {
key: `${index}-${chatIndex}`,
index: globalChatIndex,
- label: chat.displayName,
+ label: (
+
+ {chat.displayName}
+ {isSelected && (
+ {
+ e.currentTarget.style.color = "rgba(89,54,213,0.6)";
+ }}
+ onMouseLeave={(e) => {
+ e.currentTarget.style.color = "inherit";
+ }}
+ onMouseDown={(e) => {
+ e.currentTarget.style.color = "rgba(89,54,213,0.4)";
+ }}
+ onMouseUp={(e) => {
+ e.currentTarget.style.color = "rgba(89,54,213,0.6)";
+ }}
+ onClick={(e) => {
+ e.stopPropagation();
+ if (this.props.onDelete) {
+ this.props.onDelete(globalChatIndex);
+ }
+ }}
+ />
+ )}
+
+ ),
};
}),
};
@@ -85,14 +126,40 @@ class ChatMenu extends React.Component {
const items = this.chatsToItems(this.props.chats);
return (
-
+ <>
+ }
+ style={{
+ width: "calc(100% - 8px)",
+ height: "40px",
+ margin: "4px",
+ borderColor: "rgb(229,229,229)",
+ }}
+ onMouseEnter={(e) => {
+ e.currentTarget.style.borderColor = "rgba(89,54,213,0.6)";
+ }}
+ onMouseLeave={(e) => {
+ e.currentTarget.style.borderColor = "rgba(0, 0, 0, 0.1)";
+ }}
+ onMouseDown={(e) => {
+ e.currentTarget.style.borderColor = "rgba(89,54,213,0.4)";
+ }}
+ onMouseUp={(e) => {
+ e.currentTarget.style.borderColor = "rgba(89,54,213,0.6)";
+ }}
+ onClick={this.props.onNewChat}
+ >
+ New Chat
+
+
+ >
);
}
}
diff --git a/web/src/ProviderEditPage.js b/web/src/ProviderEditPage.js
index d764c534..5cb85a9e 100644
--- a/web/src/ProviderEditPage.js
+++ b/web/src/ProviderEditPage.js
@@ -125,6 +125,8 @@ class ProviderEditPage extends React.Component {
} else {
return Setting.getLabel(i18next.t("provider:Secret key"), i18next.t("provider:Secret key - Tooltip"));
}
+ case "AI":
+ return Setting.getLabel(i18next.t("provider:Secret key"), i18next.t("provider:Secret key - Tooltip"));
default:
return Setting.getLabel(i18next.t("provider:Client secret"), i18next.t("provider:Client secret - Tooltip"));
}
@@ -278,17 +280,20 @@ class ProviderEditPage extends React.Component {
this.updateProviderField("type", "Alipay");
} else if (value === "Captcha") {
this.updateProviderField("type", "Default");
+ } else if (value === "AI") {
+ this.updateProviderField("type", "OpenAI API - GPT");
}
})}>
{
[
- {id: "OAuth", name: "OAuth"},
+ {id: "AI", name: "AI"},
+ {id: "Captcha", name: "Captcha"},
{id: "Email", name: "Email"},
+ {id: "OAuth", name: "OAuth"},
+ {id: "Payment", name: "Payment"},
+ {id: "SAML", name: "SAML"},
{id: "SMS", name: "SMS"},
{id: "Storage", name: "Storage"},
- {id: "SAML", name: "SAML"},
- {id: "Payment", name: "Payment"},
- {id: "Captcha", name: "Captcha"},
]
.sort((a, b) => a.name.localeCompare(b.name))
.map((providerCategory, index) => )
@@ -437,16 +442,20 @@ class ProviderEditPage extends React.Component {
{
this.state.provider.category === "Captcha" && this.state.provider.type === "Default" ? null : (
-
-
- {this.getClientIdLabel(this.state.provider)}
-
-
- {
- this.updateProviderField("clientId", e.target.value);
- }} />
-
-
+ {
+ this.state.provider.category === "AI" ? null : (
+
+
+ {this.getClientIdLabel(this.state.provider)}
+
+
+ {
+ this.updateProviderField("clientId", e.target.value);
+ }} />
+
+
+ )
+ }
{this.getClientSecretLabel(this.state.provider)}
diff --git a/web/src/Setting.js b/web/src/Setting.js
index 0791f5e9..4f4cdef9 100644
--- a/web/src/Setting.js
+++ b/web/src/Setting.js
@@ -204,6 +204,12 @@ export const OtherProviderInfo = {
url: "https://www.cloudflare.com/products/turnstile/",
},
},
+ AI: {
+ "OpenAI API - GPT": {
+ logo: `${StaticBaseUrl}/img/social_openai.svg`,
+ url: "https://platform.openai.com",
+ },
+ },
};
export function initCountries() {
@@ -855,6 +861,10 @@ export function getProviderTypeOptions(category) {
{id: "GEETEST", name: "GEETEST"},
{id: "Cloudflare Turnstile", name: "Cloudflare Turnstile"},
]);
+ } else if (category === "AI") {
+ return ([
+ {id: "OpenAI API - GPT", name: "OpenAI API - GPT"},
+ ]);
} else {
return [];
}