Skip to content

Commit

Permalink
Merge pull request #2185 from Yidadaa/bugfix-0628
Browse files Browse the repository at this point in the history
feat: many ux improvments
  • Loading branch information
Yidadaa committed Jun 28, 2023
2 parents 64c4f51 + b044e27 commit 7748a98
Show file tree
Hide file tree
Showing 35 changed files with 391 additions and 166 deletions.
9 changes: 8 additions & 1 deletion app/client/platforms/openai.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { OpenaiPath, REQUEST_TIMEOUT_MS } from "@/app/constant";
import {
DEFAULT_API_HOST,
OpenaiPath,
REQUEST_TIMEOUT_MS,
} from "@/app/constant";
import { useAccessStore, useAppConfig, useChatStore } from "@/app/store";

import { ChatOptions, getHeaders, LLMApi, LLMUsage } from "../api";
Expand All @@ -12,6 +16,9 @@ import { prettyObject } from "@/app/utils/format";
export class ChatGPTApi implements LLMApi {
path(path: string): string {
let openaiUrl = useAccessStore.getState().openaiUrl;
if (openaiUrl.length === 0) {
openaiUrl = DEFAULT_API_HOST;
}
if (openaiUrl.endsWith("/")) {
openaiUrl = openaiUrl.slice(0, openaiUrl.length - 1);
}
Expand Down
29 changes: 24 additions & 5 deletions app/components/button.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,26 @@
fill: white !important;
}
}

&.danger {
color: rgba($color: red, $alpha: 0.8);
border-color: rgba($color: red, $alpha: 0.5);
background-color: rgba($color: red, $alpha: 0.05);

&:hover {
border-color: red;
background-color: rgba($color: red, $alpha: 0.1);
}

path {
fill: red !important;
}
}

&:hover,
&:focus {
border-color: var(--primary);
}
}

.shadow {
Expand All @@ -37,10 +57,6 @@
border: var(--border-in-light);
}

.icon-button:hover {
border-color: var(--primary);
}

.icon-button-icon {
width: 16px;
height: 16px;
Expand All @@ -56,9 +72,12 @@
}

.icon-button-text {
margin-left: 5px;
font-size: 12px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;

&:not(:first-child) {
margin-left: 5px;
}
}
8 changes: 7 additions & 1 deletion app/components/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,20 @@ import * as React from "react";

import styles from "./button.module.scss";

export type ButtonType = "primary" | "danger" | null;

export function IconButton(props: {
onClick?: () => void;
icon?: JSX.Element;
type?: "primary" | "danger";
type?: ButtonType;
text?: string;
bordered?: boolean;
shadow?: boolean;
className?: string;
title?: string;
disabled?: boolean;
tabIndex?: number;
autoFocus?: boolean;
}) {
return (
<button
Expand All @@ -25,6 +29,8 @@ export function IconButton(props: {
title={props.title}
disabled={props.disabled}
role="button"
tabIndex={props.tabIndex}
autoFocus={props.autoFocus}
>
{props.icon && (
<div
Expand Down
8 changes: 6 additions & 2 deletions app/components/chat-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { Path } from "../constant";
import { MaskAvatar } from "./mask";
import { Mask } from "../store/mask";
import { useRef, useEffect } from "react";
import { showConfirm } from "./ui-lib";

export function ChatItem(props: {
onClick?: () => void;
Expand Down Expand Up @@ -139,8 +140,11 @@ export function ChatList(props: { narrow?: boolean }) {
navigate(Path.Chat);
selectSession(i);
}}
onDelete={() => {
if (!props.narrow || confirm(Locale.Home.DeleteChat)) {
onDelete={async () => {
if (
!props.narrow ||
(await showConfirm(Locale.Home.DeleteChat))
) {
chatStore.deleteSession(i);
}
}}
Expand Down
23 changes: 23 additions & 0 deletions app/components/chat.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,12 @@
display: flex;
flex-direction: column;
align-items: flex-start;

&:hover {
.chat-message-edit {
opacity: 0.9;
}
}
}

.chat-message-user > .chat-message-container {
Expand All @@ -259,6 +265,23 @@

.chat-message-avatar {
margin-top: 20px;
position: relative;

.chat-message-edit {
position: absolute;
height: 100%;
width: 100%;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
transition: all ease 0.3s;

button {
padding: 7px;
}
}
}

.chat-message-status {
Expand Down
37 changes: 30 additions & 7 deletions app/components/chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import BreakIcon from "../icons/break.svg";
import SettingsIcon from "../icons/chat-settings.svg";
import DeleteIcon from "../icons/clear.svg";
import PinIcon from "../icons/pin.svg";
import EditIcon from "../icons/rename.svg";

import LightIcon from "../icons/light.svg";
import DarkIcon from "../icons/dark.svg";
Expand Down Expand Up @@ -61,7 +62,7 @@ import Locale from "../locales";
import { IconButton } from "./button";
import styles from "./chat.module.scss";

import { ListItem, Modal, showToast } from "./ui-lib";
import { ListItem, Modal, showConfirm, showPrompt, showToast } from "./ui-lib";
import { useLocation, useNavigate } from "react-router-dom";
import { LAST_INPUT_KEY, Path, REQUEST_TIMEOUT_MS } from "../constant";
import { Avatar } from "./emoji";
Expand Down Expand Up @@ -93,8 +94,8 @@ export function SessionConfigModel(props: { onClose: () => void }) {
icon={<ResetIcon />}
bordered
text={Locale.Chat.Config.Reset}
onClick={() => {
if (confirm(Locale.Memory.ResetConfirm)) {
onClick={async () => {
if (await showConfirm(Locale.Memory.ResetConfirm)) {
chatStore.updateCurrentSession(
(session) => (session.memoryPrompt = ""),
);
Expand Down Expand Up @@ -778,10 +779,13 @@ export function Chat() {
const [showPromptModal, setShowPromptModal] = useState(false);

const renameSession = () => {
const newTopic = prompt(Locale.Chat.Rename, session.topic);
if (newTopic && newTopic !== session.topic) {
chatStore.updateCurrentSession((session) => (session.topic = newTopic!));
}
showPrompt(Locale.Chat.Rename, session.topic).then((newTopic) => {
if (newTopic && newTopic !== session.topic) {
chatStore.updateCurrentSession(
(session) => (session.topic = newTopic!),
);
}
});
};

const clientConfig = useMemo(() => getClientConfig(), []);
Expand Down Expand Up @@ -899,6 +903,25 @@ export function Chat() {
>
<div className={styles["chat-message-container"]}>
<div className={styles["chat-message-avatar"]}>
<div className={styles["chat-message-edit"]}>
<IconButton
icon={<EditIcon />}
onClick={async () => {
const newMessage = await showPrompt(
Locale.Chat.Actions.Edit,
message.content,
);
chatStore.updateCurrentSession((session) => {
const m = session.messages.find(
(m) => m.id === message.id,
);
if (m) {
m.content = newMessage;
}
});
}}
></IconButton>
</div>
{message.role === "user" ? (
<Avatar avatar={config.avatar} />
) : (
Expand Down
10 changes: 6 additions & 4 deletions app/components/error.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import ResetIcon from "../icons/reload.svg";
import { ISSUE_URL } from "../constant";
import Locale from "../locales";
import { downloadAs } from "../utils";
import { showConfirm } from "./ui-lib";

interface IErrorBoundaryState {
hasError: boolean;
Expand Down Expand Up @@ -57,10 +58,11 @@ export class ErrorBoundary extends React.Component<any, IErrorBoundaryState> {
<IconButton
icon={<ResetIcon />}
text="Clear All Data"
onClick={() =>
confirm(Locale.Settings.Actions.ConfirmClearAll) &&
this.clearAndSaveData()
}
onClick={async () => {
if (await showConfirm(Locale.Settings.Danger.Reset.Confirm)) {
this.clearAndSaveData();
}
}}
bordered
/>
</div>
Expand Down
18 changes: 13 additions & 5 deletions app/components/mask.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,15 @@ import CopyIcon from "../icons/copy.svg";
import { DEFAULT_MASK_AVATAR, Mask, useMaskStore } from "../store/mask";
import { ChatMessage, ModelConfig, useAppConfig, useChatStore } from "../store";
import { ROLES } from "../client/api";
import { Input, List, ListItem, Modal, Popover, Select } from "./ui-lib";
import {
Input,
List,
ListItem,
Modal,
Popover,
Select,
showConfirm,
} from "./ui-lib";
import { Avatar, AvatarPicker } from "./emoji";
import Locale, { AllLangs, ALL_LANG_OPTIONS, Lang } from "../locales";
import { useNavigate } from "react-router-dom";
Expand Down Expand Up @@ -125,10 +133,10 @@ export function MaskConfig(props: {
<input
type="checkbox"
checked={props.mask.syncGlobalConfig}
onChange={(e) => {
onChange={async (e) => {
if (
e.currentTarget.checked &&
confirm(Locale.Mask.Config.Sync.Confirm)
(await showConfirm(Locale.Mask.Config.Sync.Confirm))
) {
props.updateMask((mask) => {
mask.syncGlobalConfig = e.currentTarget.checked;
Expand Down Expand Up @@ -439,8 +447,8 @@ export function MaskPage() {
<IconButton
icon={<DeleteIcon />}
text={Locale.Mask.Item.Delete}
onClick={() => {
if (confirm(Locale.Mask.Item.DeleteConfirm)) {
onClick={async () => {
if (await showConfirm(Locale.Mask.Item.DeleteConfirm)) {
maskStore.delete(m.id);
}
}}
Expand Down
5 changes: 3 additions & 2 deletions app/components/new-chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import Locale from "../locales";
import { useAppConfig, useChatStore } from "../store";
import { MaskAvatar } from "./mask";
import { useCommand } from "../command";
import { showConfirm } from "./ui-lib";

function getIntersectionArea(aRect: DOMRect, bRect: DOMRect) {
const xmin = Math.max(aRect.x, bRect.x);
Expand Down Expand Up @@ -125,8 +126,8 @@ export function NewChat() {
{!state?.fromHome && (
<IconButton
text={Locale.NewChat.NotShow}
onClick={() => {
if (confirm(Locale.NewChat.ConfirmNoShow)) {
onClick={async () => {
if (await showConfirm(Locale.NewChat.ConfirmNoShow)) {
startChat();
config.update(
(config) => (config.dontShowMaskSplashScreen = true),
Expand Down

0 comments on commit 7748a98

Please sign in to comment.