may share prompt
This commit is contained in:
@@ -335,5 +335,7 @@
|
||||
"shareAudio": "Share audio",
|
||||
"areYouSureToShareThisAudioToCommunity": "Are you sure to share this audio to community?",
|
||||
"shareVideo": "Share video",
|
||||
"areYouSureToShareThisVideoToCommunity": "Are you sure to share this video to community?"
|
||||
"areYouSureToShareThisVideoToCommunity": "Are you sure to share this video to community?",
|
||||
"sharePrompt": "Share prompt",
|
||||
"areYouSureToShareThisPromptToCommunity": "Are you sure to share this prompt to community?"
|
||||
}
|
||||
|
||||
@@ -335,5 +335,7 @@
|
||||
"shareAudio": "分享音频",
|
||||
"areYouSureToShareThisAudioToCommunity": "您确定要分享此音频到社区吗?",
|
||||
"shareVideo": "分享视频",
|
||||
"areYouSureToShareThisVideoToCommunity": "您确定要分享此视频到社区吗?"
|
||||
"areYouSureToShareThisVideoToCommunity": "您确定要分享此视频到社区吗?",
|
||||
"sharePrompt": "分享提示语",
|
||||
"areYouSureToShareThisPromptToCommunity": "您确定要分享此提示语到社区吗?"
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ export class Transcription extends Model<Transcription> {
|
||||
|
||||
@AfterFind
|
||||
static expireProcessingState(transcription: Transcription) {
|
||||
if (transcription.state !== "processing") return;
|
||||
if (transcription?.state !== "processing") return;
|
||||
|
||||
if (transcription.updatedAt.getTime() + PROCESS_TIMEOUT < Date.now()) {
|
||||
if (transcription.result) {
|
||||
|
||||
@@ -94,14 +94,14 @@ export const AssistantMessageComponent = (props: {
|
||||
<AvatarImage></AvatarImage>
|
||||
<AvatarFallback className="bg-white">AI</AvatarFallback>
|
||||
</Avatar>
|
||||
<div className="flex flex-col gap-2 px-4 py-2 bg-white border rounded-lg shadow-sm w-full prose max-w-prose">
|
||||
<div className="flex flex-col gap-2 px-4 py-2 bg-white border rounded-lg shadow-sm w-full">
|
||||
{configuration?.autoSpeech && speeching ? (
|
||||
<div className="p-4">
|
||||
<LoaderIcon className="w-8 h-8 animate-spin" />
|
||||
</div>
|
||||
) : (
|
||||
<Markdown
|
||||
className="select-text"
|
||||
className="select-text prose"
|
||||
components={{
|
||||
a({ node, children, ...props }) {
|
||||
try {
|
||||
|
||||
@@ -8,8 +8,9 @@ export const MessageComponent = (props: {
|
||||
configuration: { [key: string]: any };
|
||||
onResend?: () => void;
|
||||
onRemove?: () => void;
|
||||
onShare?: () => void;
|
||||
}) => {
|
||||
const { message, configuration, onResend, onRemove } = props;
|
||||
const { message, configuration, onResend, onRemove, onShare } = props;
|
||||
if (message.role === "assistant") {
|
||||
return (
|
||||
<AssistantMessageComponent
|
||||
@@ -24,6 +25,7 @@ export const MessageComponent = (props: {
|
||||
configuration={configuration}
|
||||
onResend={onResend}
|
||||
onRemove={onRemove}
|
||||
onShare={onShare}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
AlertCircleIcon,
|
||||
CopyIcon,
|
||||
CheckIcon,
|
||||
Share2Icon,
|
||||
} from "lucide-react";
|
||||
import { useCopyToClipboard } from "@uidotdev/usehooks";
|
||||
import { t } from "i18next";
|
||||
@@ -27,8 +28,9 @@ export const UserMessageComponent = (props: {
|
||||
configuration?: { [key: string]: any };
|
||||
onResend?: () => void;
|
||||
onRemove?: () => void;
|
||||
onShare?: () => void;
|
||||
}) => {
|
||||
const { message, onResend, onRemove } = props;
|
||||
const { message, onResend, onRemove, onShare } = props;
|
||||
const speech = message.speeches?.[0];
|
||||
const { user } = useContext(AppSettingsProviderContext);
|
||||
const [_, copyToClipboard] = useCopyToClipboard();
|
||||
@@ -41,7 +43,7 @@ export const UserMessageComponent = (props: {
|
||||
>
|
||||
<DropdownMenu>
|
||||
<div className="flex flex-col gap-2 px-4 py-2 bg-sky-500/30 border-sky-500 rounded-lg shadow-sm w-full">
|
||||
<Markdown className="select-text">{message.content}</Markdown>
|
||||
<Markdown className="select-text prose">{message.content}</Markdown>
|
||||
|
||||
{Boolean(speech) && <SpeechPlayer speech={speech} />}
|
||||
|
||||
@@ -81,6 +83,15 @@ export const UserMessageComponent = (props: {
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{message.createdAt && (
|
||||
<Share2Icon
|
||||
data-tooltip-id="global-tooltip"
|
||||
data-tooltip-content={t("share")}
|
||||
className="w-3 h-3 cursor-pointer"
|
||||
onClick={onShare}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<DropdownMenuContent>
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
DefaultVideoLayout,
|
||||
defaultLayoutIcons,
|
||||
} from "@vidstack/react/player/layouts/default";
|
||||
import Markdown from "react-markdown";
|
||||
|
||||
export const Posts = () => {
|
||||
const { webApi } = useContext(AppSettingsProviderContext);
|
||||
@@ -16,7 +17,6 @@ export const Posts = () => {
|
||||
const fetchPosts = async () => {
|
||||
webApi.posts().then(
|
||||
(res) => {
|
||||
console.log(res);
|
||||
setPosts(res.posts);
|
||||
},
|
||||
(err) => {
|
||||
@@ -60,7 +60,9 @@ const PostCard = (props: { post: PostType }) => {
|
||||
<div className="">{post.user.name}</div>
|
||||
</div>
|
||||
</div>
|
||||
{post.content && <div className="mb-4">{post.content}</div>}
|
||||
{post.content && (
|
||||
<Markdown className="prose select-text mb-4">{post.content}</Markdown>
|
||||
)}
|
||||
{post.targetType == "Medium" && <PostMedium medium={post.target} />}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
import { useState, useEffect, useReducer, useContext, useRef } from "react";
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogHeader,
|
||||
AlertDialogDescription,
|
||||
AlertDialogTitle,
|
||||
AlertDialogContent,
|
||||
AlertDialogFooter,
|
||||
AlertDialogCancel,
|
||||
Button,
|
||||
ScrollArea,
|
||||
Textarea,
|
||||
@@ -8,11 +15,7 @@ import {
|
||||
SheetTrigger,
|
||||
useToast,
|
||||
} from "@renderer/components/ui";
|
||||
import {
|
||||
MessageComponent,
|
||||
ConversationForm,
|
||||
SpeechForm,
|
||||
} from "@renderer/components";
|
||||
import { MessageComponent, ConversationForm } from "@renderer/components";
|
||||
import { SendIcon, BotIcon, LoaderIcon, SettingsIcon } from "lucide-react";
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
import { t } from "i18next";
|
||||
@@ -29,9 +32,11 @@ export default () => {
|
||||
const [editting, setEditting] = useState<boolean>(false);
|
||||
const [conversation, setConversation] = useState<ConversationType>();
|
||||
const { addDblistener, removeDbListener } = useContext(DbProviderContext);
|
||||
const { EnjoyApp } = useContext(AppSettingsProviderContext);
|
||||
const { EnjoyApp, webApi } = useContext(AppSettingsProviderContext);
|
||||
const [content, setConent] = useState<string>("");
|
||||
const [submitting, setSubmitting] = useState<boolean>(false);
|
||||
const [sharing, setSharing] = useState<MessageType>();
|
||||
|
||||
const { toast } = useToast();
|
||||
|
||||
const [messages, dispatchMessages] = useReducer(messagesReducer, []);
|
||||
@@ -169,6 +174,28 @@ export default () => {
|
||||
}, 500);
|
||||
};
|
||||
|
||||
const handleShare = async (message: MessageType) => {
|
||||
if (message.role === "user") {
|
||||
const content = message.content;
|
||||
webApi
|
||||
.createPost({
|
||||
content,
|
||||
})
|
||||
.then(() => {
|
||||
toast({
|
||||
description: t("sharedSuccessfully"),
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
toast({
|
||||
title: t("shareFailed"),
|
||||
description: err.message,
|
||||
});
|
||||
});
|
||||
setSharing(null);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchConversation();
|
||||
fetchMessages();
|
||||
@@ -258,6 +285,7 @@ export default () => {
|
||||
|
||||
dispatchMessages({ type: "destroy", record: message });
|
||||
}}
|
||||
onShare={() => setSharing(message)}
|
||||
/>
|
||||
))}
|
||||
{offset > -1 && (
|
||||
@@ -278,6 +306,26 @@ export default () => {
|
||||
</div>
|
||||
</ScrollArea>
|
||||
|
||||
<AlertDialog
|
||||
open={Boolean(sharing)}
|
||||
onOpenChange={() => setSharing(null)}
|
||||
>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>{t("sharePrompt")}</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
{t("areYouSureToShareThisPromptToCommunity")}
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>{t("cancel")}</AlertDialogCancel>
|
||||
<Button variant="default" onClick={() => handleShare(sharing)}>
|
||||
{t("share")}
|
||||
</Button>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
|
||||
<div className="px-4 absolute w-full bottom-0 left-0 h-14 bg-muted z-50">
|
||||
<div className="focus-within:bg-white px-4 py-2 flex items-center space-x-4 rounded-lg border">
|
||||
<Textarea
|
||||
|
||||
Reference in New Issue
Block a user