mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 08:50:15 +01:00
🚀 feat: Shared Links (#2772)
* ✨ feat(types): add necessary types for shared link feature * ✨ feat: add shared links functions to data service Added functions for retrieving, creating, updating, and deleting shared links and shared messages. * ✨ feat: Add useGetSharedMessages hook to fetch shared messages by shareId Adds a new hook `useGetSharedMessages` which fetches shared messages based on the provided shareId. * ✨ feat: Add share schema and data access functions to API models * ✨ feat: Add share endpoint to API The GET /api/share/${shareId} is exposed to the public, so authentication is not required. Other paths require authentication. * ♻️ refactor(utils): generalize react-query cache manipulation functions Introduces generic functions for manipulating react-query cache entries, marking a refinement in how query cache data is managed. It aims to enhance the flexibility and reusability of the cache interaction patterns within our application. - Replaced specific index names with more generic terms in queries.ts, enhancing consistency across data handling functions. - Introduced new utility functions in collection.ts for adding, updating, and deleting data entries in an InfiniteData<TCollection>. These utility functions (`addData`, `updateData`, `deleteData`, `findPage`) are designed to be re-usable across different data types and collections. - Adapted existing conversation utility functions in convos.ts to leverage these new generic utilities. * ✨ feat(shared-link): add functions to manipulate shared link cache list implemented new utility functions to handle additions, updates, and deletions in the shared link cache list. * ✨ feat: Add mutations and queries for shared links * ✨ feat(shared-link): add `Share` button to conversation list - Added a share button in each conversation in the conversation list. - Implemented functionality where clicking the share button triggers a POST request to the API. - The API checks if a share link was already created for the conversation today; if so, it returns the existing link. - If no link was created for today, the API will create a new share link and return it. - Each click on the share button results in a new API request, following the specification similar to ChatGPT's share link feature. * ♻️ refactor(hooks): generalize useNavScrolling for broader use - Modified `useNavScrolling` to accept a generic type parameter `TData`, allowing it to be used with different data structures besides `ConversationListResponse`. - Updated instances in `Nav.tsx` and `ArchivedChatsTable.tsx` to explicitly specify `ConversationListResponse` as the type argument when invoking `useNavScrolling`. * ✨ feat(settings): add shared links listing table with delete functionality in settings - Integrated a delete button for each shared link in the table, allowing users to remove links as needed. * ♻️ refactor(components): separate `EndpointIcon` from `Icon` component for standalone use * ♻️ refactor: update useGetSharedMessages to return TSharedLink - Modified the useGetSharedMessages hook to return not only a list of TMessage but also the TSharedLink itself. - This change was necessary to support displaying the title and date in the Shared Message UI, which requires data from TSharedLink. * ✨ feat(shared link): add UI for displaying shared conversations without authentication - Implemented a new UI component to display shared conversations, designed to be accessible without requiring authentication. - Reused components from the authenticated Messages module where possible. Copied and adapted components that could not be directly reused to fit the non-authenticated context. * 🔧 chore: Add translations Translate labels only. Messages remain in English as they are possibly subject to change. * ♻️ refactor: add icon and tooltip props to EditMenuButton component * moved icon and popover to arguments so that EditMenuButton can be reused. * modified so that when a ShareButton is closed, the parent DropdownMenu is also closed. * ♻️irefactor: added DropdownMenu for Export and Share * ♻️ refactor: renamed component names more intuitive * More accurate naming of the dropdown menu. * When the export button is closed, the parent dropdown menu is also closed. * 🌍 chore: updated translations * 🐞 Fix: OpenID Profile Image Download (#2757) * Add fetch requirement Fixes - error: [openidStrategy] downloadImage: Error downloading image at URL "https://graph.microsoft.com/v1.0/me/photo/$value": TypeError: response.buffer is not a function * Update openidStrategy.js --------- Co-authored-by: Danny Avila <danacordially@gmail.com> * 🚑 fix(export): Issue exporting Conversation with Assistants (#2769) * 🚑 fix(export): use content as text if content is present in the message If the endpoint is assistants, the text of the message goes into content, not message.text. * refactor(ExportModel): TypeScript, remove unused code --------- Co-authored-by: Yuichi Ohneda <ohneda@gmail.com> * 📤style: export button icon (#2752) * refactor(ShareDialog): logic and styling * refactor(ExportAndShareMenu): imports order and icon update * chore: imports * chore: imports/render logic * feat: message branching * refactor: add optional config to useGetStartupConfig * refactor: disable endpoints query * chore: fix search view styling gradient in light mode * style: ShareView gradient styling * refactor(Share): use select queries * style: shared link table buttons * localization and dark text styling * style: fix clipboard button layout shift app-wide and add localization for copy code * support assistants message content in shared links, add useCopyToClipboard, add copy buttons to Search Messages and Shared Link Messages * add localizations * comparisons --------- Co-authored-by: Yuichi Ohneda <ohneda@gmail.com> Co-authored-by: bsu3338 <bsu3338@users.noreply.github.com> Co-authored-by: Fuegovic <32828263+fuegovic@users.noreply.github.com>
This commit is contained in:
parent
38ad36c1c5
commit
f0e8cca5df
78 changed files with 4683 additions and 317 deletions
89
api/models/Share.js
Normal file
89
api/models/Share.js
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
const crypto = require('crypto');
|
||||||
|
const { getMessages } = require('./Message');
|
||||||
|
const SharedLink = require('./schema/shareSchema');
|
||||||
|
const logger = require('~/config/winston');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
SharedLink,
|
||||||
|
getSharedMessages: async (shareId) => {
|
||||||
|
try {
|
||||||
|
const share = await SharedLink.findOne({ shareId })
|
||||||
|
.populate({
|
||||||
|
path: 'messages',
|
||||||
|
select: '-_id -__v -user',
|
||||||
|
})
|
||||||
|
.select('-_id -__v -user')
|
||||||
|
.lean();
|
||||||
|
|
||||||
|
if (!share || !share.conversationId || !share.isPublic) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return share;
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('[getShare] Error getting share link', error);
|
||||||
|
return { message: 'Error getting share link' };
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getSharedLinks: async (user, pageNumber = 1, pageSize = 25, isPublic = true) => {
|
||||||
|
const query = { user, isPublic };
|
||||||
|
try {
|
||||||
|
const totalConvos = (await SharedLink.countDocuments(query)) || 1;
|
||||||
|
const totalPages = Math.ceil(totalConvos / pageSize);
|
||||||
|
const shares = await SharedLink.find(query)
|
||||||
|
.sort({ updatedAt: -1 })
|
||||||
|
.skip((pageNumber - 1) * pageSize)
|
||||||
|
.limit(pageSize)
|
||||||
|
.select('-_id -__v -user')
|
||||||
|
.lean();
|
||||||
|
|
||||||
|
return { sharedLinks: shares, pages: totalPages, pageNumber, pageSize };
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('[getShareByPage] Error getting shares', error);
|
||||||
|
return { message: 'Error getting shares' };
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
createSharedLink: async (user, { conversationId, ...shareData }) => {
|
||||||
|
const share = await SharedLink.findOne({ conversationId }).select('-_id -__v -user').lean();
|
||||||
|
if (share) {
|
||||||
|
return share;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const shareId = crypto.randomUUID();
|
||||||
|
const messages = await getMessages({ conversationId });
|
||||||
|
const update = { ...shareData, shareId, messages, user };
|
||||||
|
return await SharedLink.findOneAndUpdate({ conversationId: conversationId, user }, update, {
|
||||||
|
new: true,
|
||||||
|
upsert: true,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('[saveShareMessage] Error saving conversation', error);
|
||||||
|
return { message: 'Error saving conversation' };
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
updateSharedLink: async (user, { conversationId, ...shareData }) => {
|
||||||
|
const share = await SharedLink.findOne({ conversationId }).select('-_id -__v -user').lean();
|
||||||
|
if (!share) {
|
||||||
|
return { message: 'Share not found' };
|
||||||
|
}
|
||||||
|
// update messages to the latest
|
||||||
|
const messages = await getMessages({ conversationId });
|
||||||
|
const update = { ...shareData, messages, user };
|
||||||
|
return await SharedLink.findOneAndUpdate({ conversationId: conversationId, user }, update, {
|
||||||
|
new: true,
|
||||||
|
upsert: false,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteSharedLink: async (user, { shareId }) => {
|
||||||
|
const share = await SharedLink.findOne({ shareId, user });
|
||||||
|
if (!share) {
|
||||||
|
return { message: 'Share not found' };
|
||||||
|
}
|
||||||
|
return await SharedLink.findOneAndDelete({ shareId, user });
|
||||||
|
},
|
||||||
|
};
|
||||||
38
api/models/schema/shareSchema.js
Normal file
38
api/models/schema/shareSchema.js
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
const mongoose = require('mongoose');
|
||||||
|
|
||||||
|
const shareSchema = mongoose.Schema(
|
||||||
|
{
|
||||||
|
conversationId: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
index: true,
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
type: String,
|
||||||
|
index: true,
|
||||||
|
},
|
||||||
|
messages: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Message' }],
|
||||||
|
shareId: {
|
||||||
|
type: String,
|
||||||
|
index: true,
|
||||||
|
},
|
||||||
|
isPublic: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
isVisible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
isAnonymous: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ timestamps: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
module.exports = mongoose.model('SharedLink', shareSchema);
|
||||||
|
|
@ -85,6 +85,7 @@ const startServer = async () => {
|
||||||
app.use('/api/assistants', routes.assistants);
|
app.use('/api/assistants', routes.assistants);
|
||||||
app.use('/api/files', await routes.files.initialize());
|
app.use('/api/files', await routes.files.initialize());
|
||||||
app.use('/images/', validateImageRequest, routes.staticRoute);
|
app.use('/images/', validateImageRequest, routes.staticRoute);
|
||||||
|
app.use('/api/share', routes.share);
|
||||||
|
|
||||||
app.use((req, res) => {
|
app.use((req, res) => {
|
||||||
res.status(404).sendFile(path.join(app.locals.paths.dist, 'index.html'));
|
res.status(404).sendFile(path.join(app.locals.paths.dist, 'index.html'));
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ const config = require('./config');
|
||||||
const assistants = require('./assistants');
|
const assistants = require('./assistants');
|
||||||
const files = require('./files');
|
const files = require('./files');
|
||||||
const staticRoute = require('./static');
|
const staticRoute = require('./static');
|
||||||
|
const share = require('./share');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
search,
|
search,
|
||||||
|
|
@ -40,4 +41,5 @@ module.exports = {
|
||||||
assistants,
|
assistants,
|
||||||
files,
|
files,
|
||||||
staticRoute,
|
staticRoute,
|
||||||
|
share,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
75
api/server/routes/share.js
Normal file
75
api/server/routes/share.js
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
const express = require('express');
|
||||||
|
|
||||||
|
const {
|
||||||
|
getSharedMessages,
|
||||||
|
createSharedLink,
|
||||||
|
updateSharedLink,
|
||||||
|
getSharedLinks,
|
||||||
|
deleteSharedLink,
|
||||||
|
} = require('~/models/Share');
|
||||||
|
const requireJwtAuth = require('~/server/middleware/requireJwtAuth');
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shared messages
|
||||||
|
* this route does not require authentication
|
||||||
|
*/
|
||||||
|
router.get('/:shareId', async (req, res) => {
|
||||||
|
const share = await getSharedMessages(req.params.shareId);
|
||||||
|
|
||||||
|
if (share) {
|
||||||
|
res.status(200).json(share);
|
||||||
|
} else {
|
||||||
|
res.status(404).end();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shared links
|
||||||
|
*/
|
||||||
|
router.get('/', requireJwtAuth, async (req, res) => {
|
||||||
|
let pageNumber = req.query.pageNumber || 1;
|
||||||
|
pageNumber = parseInt(pageNumber, 10);
|
||||||
|
|
||||||
|
if (isNaN(pageNumber) || pageNumber < 1) {
|
||||||
|
return res.status(400).json({ error: 'Invalid page number' });
|
||||||
|
}
|
||||||
|
|
||||||
|
let pageSize = req.query.pageSize || 25;
|
||||||
|
pageSize = parseInt(pageSize, 10);
|
||||||
|
|
||||||
|
if (isNaN(pageSize) || pageSize < 1) {
|
||||||
|
return res.status(400).json({ error: 'Invalid page size' });
|
||||||
|
}
|
||||||
|
const isPublic = req.query.isPublic === 'true';
|
||||||
|
res.status(200).send(await getSharedLinks(req.user.id, pageNumber, pageSize, isPublic));
|
||||||
|
});
|
||||||
|
|
||||||
|
router.post('/', requireJwtAuth, async (req, res) => {
|
||||||
|
const created = await createSharedLink(req.user.id, req.body);
|
||||||
|
if (created) {
|
||||||
|
res.status(200).json(created);
|
||||||
|
} else {
|
||||||
|
res.status(404).end();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
router.patch('/', requireJwtAuth, async (req, res) => {
|
||||||
|
const updated = await updateSharedLink(req.user.id, req.body);
|
||||||
|
if (updated) {
|
||||||
|
res.status(200).json(updated);
|
||||||
|
} else {
|
||||||
|
res.status(404).end();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
router.delete('/:shareId', requireJwtAuth, async (req, res) => {
|
||||||
|
const deleted = await deleteSharedLink(req.user.id, { shareId: req.params.shareId });
|
||||||
|
if (deleted) {
|
||||||
|
res.status(200).json(deleted);
|
||||||
|
} else {
|
||||||
|
res.status(404).end();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
5
client/src/Providers/ShareContext.tsx
Normal file
5
client/src/Providers/ShareContext.tsx
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { createContext, useContext } from 'react';
|
||||||
|
type TShareContext = { isSharedConvo?: boolean };
|
||||||
|
|
||||||
|
export const ShareContext = createContext<TShareContext>({} as TShareContext);
|
||||||
|
export const useShareContext = () => useContext(ShareContext);
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
export { default as ToastProvider } from './ToastContext';
|
export { default as ToastProvider } from './ToastContext';
|
||||||
export { default as AssistantsProvider } from './AssistantsContext';
|
export { default as AssistantsProvider } from './AssistantsContext';
|
||||||
export * from './ChatContext';
|
export * from './ChatContext';
|
||||||
|
export * from './ShareContext';
|
||||||
export * from './ToastContext';
|
export * from './ToastContext';
|
||||||
export * from './SearchContext';
|
export * from './SearchContext';
|
||||||
export * from './FileMapContext';
|
export * from './FileMapContext';
|
||||||
|
|
|
||||||
63
client/src/components/Chat/ExportAndShareMenu.tsx
Normal file
63
client/src/components/Chat/ExportAndShareMenu.tsx
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { Upload } from 'lucide-react';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
import { useLocation } from 'react-router-dom';
|
||||||
|
import type { TConversation } from 'librechat-data-provider';
|
||||||
|
import DropDownMenu from '../Conversations/DropDownMenu';
|
||||||
|
import ShareButton from '../Conversations/ShareButton';
|
||||||
|
import HoverToggle from '../Conversations/HoverToggle';
|
||||||
|
import ExportButton from './ExportButton';
|
||||||
|
import store from '~/store';
|
||||||
|
|
||||||
|
export default function ExportAndShareMenu() {
|
||||||
|
const location = useLocation();
|
||||||
|
|
||||||
|
const activeConvo = useRecoilValue(store.conversationByIndex(0));
|
||||||
|
const globalConvo = useRecoilValue(store.conversation) ?? ({} as TConversation);
|
||||||
|
const [isPopoverActive, setIsPopoverActive] = useState(false);
|
||||||
|
let conversation: TConversation | null | undefined;
|
||||||
|
if (location.state?.from?.pathname.includes('/chat')) {
|
||||||
|
conversation = globalConvo;
|
||||||
|
} else {
|
||||||
|
conversation = activeConvo;
|
||||||
|
}
|
||||||
|
|
||||||
|
const exportable =
|
||||||
|
conversation &&
|
||||||
|
conversation.conversationId &&
|
||||||
|
conversation.conversationId !== 'new' &&
|
||||||
|
conversation.conversationId !== 'search';
|
||||||
|
|
||||||
|
if (!exportable) {
|
||||||
|
return <></>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isActiveConvo = exportable;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<HoverToggle
|
||||||
|
isActiveConvo={!!isActiveConvo}
|
||||||
|
isPopoverActive={isPopoverActive}
|
||||||
|
setIsPopoverActive={setIsPopoverActive}
|
||||||
|
>
|
||||||
|
<DropDownMenu
|
||||||
|
icon={<Upload />}
|
||||||
|
tooltip="Export/Share"
|
||||||
|
className="pointer-cursor relative z-50 flex h-[40px] min-w-4 flex-none flex-col items-center justify-center rounded-md border border-gray-100 bg-white px-3 text-left hover:bg-gray-50 focus:outline-none focus:ring-0 focus:ring-offset-0 radix-state-open:bg-gray-50 dark:border-gray-700 dark:bg-gray-800 dark:hover:bg-gray-700 dark:radix-state-open:bg-gray-700 sm:text-sm"
|
||||||
|
>
|
||||||
|
{conversation && conversation.conversationId && (
|
||||||
|
<>
|
||||||
|
<ExportButton conversation={conversation} setPopoverActive={setIsPopoverActive} />
|
||||||
|
<ShareButton
|
||||||
|
conversationId={conversation.conversationId}
|
||||||
|
title={conversation.title ?? ''}
|
||||||
|
appendLabel={true}
|
||||||
|
className="mb-[3.5px]"
|
||||||
|
setPopoverActive={setIsPopoverActive}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</DropDownMenu>
|
||||||
|
</HoverToggle>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -1,68 +1,41 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useLocation } from 'react-router-dom';
|
|
||||||
import type { TConversation } from 'librechat-data-provider';
|
import type { TConversation } from 'librechat-data-provider';
|
||||||
import { Upload } from 'lucide-react';
|
import { Upload } from 'lucide-react';
|
||||||
import { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent } from '~/components/ui';
|
|
||||||
import { useLocalize } from '~/hooks';
|
import { useLocalize } from '~/hooks';
|
||||||
import { ExportModal } from '../Nav';
|
import { ExportModal } from '../Nav';
|
||||||
import { useRecoilValue } from 'recoil';
|
|
||||||
import store from '~/store';
|
|
||||||
|
|
||||||
function ExportButton() {
|
function ExportButton({
|
||||||
|
conversation,
|
||||||
|
setPopoverActive,
|
||||||
|
}: {
|
||||||
|
conversation: TConversation;
|
||||||
|
setPopoverActive: (value: boolean) => void;
|
||||||
|
}) {
|
||||||
const localize = useLocalize();
|
const localize = useLocalize();
|
||||||
const location = useLocation();
|
|
||||||
|
|
||||||
const [showExports, setShowExports] = useState(false);
|
const [showExports, setShowExports] = useState(false);
|
||||||
|
|
||||||
const activeConvo = useRecoilValue(store.conversationByIndex(0));
|
|
||||||
const globalConvo = useRecoilValue(store.conversation) ?? ({} as TConversation);
|
|
||||||
|
|
||||||
let conversation: TConversation | null | undefined;
|
|
||||||
if (location.state?.from?.pathname.includes('/chat')) {
|
|
||||||
conversation = globalConvo;
|
|
||||||
} else {
|
|
||||||
conversation = activeConvo;
|
|
||||||
}
|
|
||||||
|
|
||||||
const clickHandler = () => {
|
const clickHandler = () => {
|
||||||
if (exportable) {
|
|
||||||
setShowExports(true);
|
setShowExports(true);
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const exportable =
|
const onOpenChange = (value: boolean) => {
|
||||||
conversation &&
|
setShowExports(value);
|
||||||
conversation.conversationId &&
|
setPopoverActive(value);
|
||||||
conversation.conversationId !== 'new' &&
|
};
|
||||||
conversation.conversationId !== 'search';
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{exportable && (
|
|
||||||
<div className="flex gap-1 gap-2 pr-1">
|
|
||||||
<TooltipProvider delayDuration={50}>
|
|
||||||
<Tooltip>
|
|
||||||
<TooltipTrigger asChild>
|
|
||||||
<button
|
<button
|
||||||
className="btn btn-neutral btn-small relative flex h-9 w-9 items-center justify-center whitespace-nowrap rounded-lg"
|
|
||||||
onClick={clickHandler}
|
onClick={clickHandler}
|
||||||
|
className="group m-1.5 flex w-full cursor-pointer items-center gap-2 rounded p-2.5 text-sm hover:bg-gray-200 focus-visible:bg-gray-200 focus-visible:outline-0 radix-disabled:pointer-events-none radix-disabled:opacity-50 dark:hover:bg-gray-600 dark:focus-visible:bg-gray-600"
|
||||||
>
|
>
|
||||||
<div className="flex w-full items-center justify-center gap-2">
|
<Upload size={16} /> {localize('com_nav_export')}
|
||||||
<Upload size={16} />
|
|
||||||
</div>
|
|
||||||
</button>
|
</button>
|
||||||
</TooltipTrigger>
|
|
||||||
<TooltipContent side="right" sideOffset={5}>
|
|
||||||
{localize('com_nav_export_conversation')}
|
|
||||||
</TooltipContent>
|
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{showExports && (
|
{showExports && (
|
||||||
<ExportModal open={showExports} onOpenChange={setShowExports} conversation={conversation} />
|
<ExportModal open={showExports} onOpenChange={onOpenChange} conversation={conversation} />
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { Constants } from 'librechat-data-provider';
|
||||||
import { useGetStartupConfig } from 'librechat-data-provider/react-query';
|
import { useGetStartupConfig } from 'librechat-data-provider/react-query';
|
||||||
import { useLocalize } from '~/hooks';
|
import { useLocalize } from '~/hooks';
|
||||||
|
|
||||||
export default function Footer() {
|
export default function Footer({ className }: { className?: string }) {
|
||||||
const { data: config } = useGetStartupConfig();
|
const { data: config } = useGetStartupConfig();
|
||||||
const localize = useLocalize();
|
const localize = useLocalize();
|
||||||
|
|
||||||
|
|
@ -52,7 +52,12 @@ export default function Footer() {
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative flex items-center justify-center gap-2 px-2 py-2 text-xs text-gray-600 dark:text-gray-300 md:px-[60px]">
|
<div
|
||||||
|
className={
|
||||||
|
className ||
|
||||||
|
'relative flex items-center justify-center gap-2 px-2 py-2 text-xs text-gray-600 dark:text-gray-300 md:px-[60px]'
|
||||||
|
}
|
||||||
|
>
|
||||||
{footerElements.map((contentRender, index) => {
|
{footerElements.map((contentRender, index) => {
|
||||||
const isLastElement = index === footerElements.length - 1;
|
const isLastElement = index === footerElements.length - 1;
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import type { ContextType } from '~/common';
|
||||||
import { EndpointsMenu, ModelSpecsMenu, PresetsMenu, HeaderNewChat } from './Menus';
|
import { EndpointsMenu, ModelSpecsMenu, PresetsMenu, HeaderNewChat } from './Menus';
|
||||||
import HeaderOptions from './Input/HeaderOptions';
|
import HeaderOptions from './Input/HeaderOptions';
|
||||||
import ExportButton from './ExportButton';
|
import ExportButton from './ExportButton';
|
||||||
|
import ExportAndShareMenu from './ExportAndShareMenu';
|
||||||
|
|
||||||
const defaultInterface = getConfigDefaults().interface;
|
const defaultInterface = getConfigDefaults().interface;
|
||||||
|
|
||||||
|
|
@ -28,7 +29,7 @@ export default function Header() {
|
||||||
{<HeaderOptions interfaceConfig={interfaceConfig} />}
|
{<HeaderOptions interfaceConfig={interfaceConfig} />}
|
||||||
{interfaceConfig.presets && <PresetsMenu />}
|
{interfaceConfig.presets && <PresetsMenu />}
|
||||||
</div>
|
</div>
|
||||||
<ExportButton />
|
<ExportAndShareMenu />
|
||||||
</div>
|
</div>
|
||||||
{/* Empty div for spacing */}
|
{/* Empty div for spacing */}
|
||||||
<div />
|
<div />
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ export default function HoverButtons({
|
||||||
isCopied ? localize('com_ui_copied_to_clipboard') : localize('com_ui_copy_to_clipboard')
|
isCopied ? localize('com_ui_copied_to_clipboard') : localize('com_ui_copy_to_clipboard')
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{isCopied ? <CheckMark /> : <Clipboard />}
|
{isCopied ? <CheckMark className="h-[18px] w-[18px]" /> : <Clipboard />}
|
||||||
</button>
|
</button>
|
||||||
{regenerateEnabled ? (
|
{regenerateEnabled ? (
|
||||||
<button
|
<button
|
||||||
|
|
|
||||||
29
client/src/components/Chat/Messages/MinimalHoverButtons.tsx
Normal file
29
client/src/components/Chat/Messages/MinimalHoverButtons.tsx
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
import { useState } from 'react';
|
||||||
|
import type { TMessage } from 'librechat-data-provider';
|
||||||
|
import { useLocalize, useCopyToClipboard } from '~/hooks';
|
||||||
|
import { Clipboard, CheckMark } from '~/components/svg';
|
||||||
|
|
||||||
|
type THoverButtons = {
|
||||||
|
message: TMessage;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function MinimalHoverButtons({ message }: THoverButtons) {
|
||||||
|
const localize = useLocalize();
|
||||||
|
const [isCopied, setIsCopied] = useState(false);
|
||||||
|
const copyToClipboard = useCopyToClipboard({ text: message.text, content: message.content });
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="visible mt-0 flex justify-center gap-1 self-end text-gray-400 lg:justify-start">
|
||||||
|
<button
|
||||||
|
className="ml-0 flex items-center gap-1.5 rounded-md p-1 text-xs hover:text-gray-900 dark:text-gray-400/70 dark:hover:text-gray-200 disabled:dark:hover:text-gray-400 md:group-hover:visible md:group-[.final-completion]:visible"
|
||||||
|
onClick={() => copyToClipboard(setIsCopied)}
|
||||||
|
type="button"
|
||||||
|
title={
|
||||||
|
isCopied ? localize('com_ui_copied_to_clipboard') : localize('com_ui_copy_to_clipboard')
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{isCopied ? <CheckMark className="h-[18px] w-[18px]" /> : <Clipboard />}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
import { useAuthContext, useLocalize } from '~/hooks';
|
import { useAuthContext, useLocalize } from '~/hooks';
|
||||||
import type { TMessageProps } from '~/common';
|
import type { TMessageProps } from '~/common';
|
||||||
|
import MinimalHoverButtons from '~/components/Chat/Messages/MinimalHoverButtons';
|
||||||
import Icon from '~/components/Chat/Messages/MessageIcon';
|
import Icon from '~/components/Chat/Messages/MessageIcon';
|
||||||
import SearchContent from './Content/SearchContent';
|
import SearchContent from './Content/SearchContent';
|
||||||
import SearchButtons from './SearchButtons';
|
import SearchButtons from './SearchButtons';
|
||||||
|
|
@ -50,6 +51,7 @@ export default function Message({ message }: Pick<TMessageProps, 'message'>) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<SubRow classes="text-xs">
|
<SubRow classes="text-xs">
|
||||||
|
<MinimalHoverButtons message={message} />
|
||||||
<SearchButtons message={message} />
|
<SearchButtons message={message} />
|
||||||
</SubRow>
|
</SubRow>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,14 @@ import { useConversations, useNavigateToConvo } from '~/hooks';
|
||||||
import { NotificationSeverity } from '~/common';
|
import { NotificationSeverity } from '~/common';
|
||||||
import { ArchiveIcon } from '~/components/svg';
|
import { ArchiveIcon } from '~/components/svg';
|
||||||
import { useToastContext } from '~/Providers';
|
import { useToastContext } from '~/Providers';
|
||||||
import EditMenuButton from './EditMenuButton';
|
import DropDownMenu from './DropDownMenu';
|
||||||
import ArchiveButton from './ArchiveButton';
|
import ArchiveButton from './ArchiveButton';
|
||||||
import DeleteButton from './DeleteButton';
|
import DeleteButton from './DeleteButton';
|
||||||
import RenameButton from './RenameButton';
|
import RenameButton from './RenameButton';
|
||||||
import HoverToggle from './HoverToggle';
|
import HoverToggle from './HoverToggle';
|
||||||
import { cn } from '~/utils';
|
import { cn } from '~/utils';
|
||||||
import store from '~/store';
|
import store from '~/store';
|
||||||
|
import ShareButton from './ShareButton';
|
||||||
|
|
||||||
type KeyEvent = KeyboardEvent<HTMLInputElement>;
|
type KeyEvent = KeyboardEvent<HTMLInputElement>;
|
||||||
|
|
||||||
|
|
@ -124,7 +125,15 @@ export default function Conversation({ conversation, retainView, toggleNav, isLa
|
||||||
isPopoverActive={isPopoverActive}
|
isPopoverActive={isPopoverActive}
|
||||||
setIsPopoverActive={setIsPopoverActive}
|
setIsPopoverActive={setIsPopoverActive}
|
||||||
>
|
>
|
||||||
<EditMenuButton>
|
<DropDownMenu>
|
||||||
|
<ShareButton
|
||||||
|
conversationId={conversationId}
|
||||||
|
title={title}
|
||||||
|
appendLabel={true}
|
||||||
|
className="mb-[3.5px]"
|
||||||
|
setPopoverActive={setIsPopoverActive}
|
||||||
|
/>
|
||||||
|
|
||||||
<RenameButton
|
<RenameButton
|
||||||
renaming={renaming}
|
renaming={renaming}
|
||||||
onRename={onRename}
|
onRename={onRename}
|
||||||
|
|
@ -140,7 +149,7 @@ export default function Conversation({ conversation, retainView, toggleNav, isLa
|
||||||
appendLabel={true}
|
appendLabel={true}
|
||||||
className="group m-1.5 mt-[3.5px] flex w-full cursor-pointer items-center gap-2 rounded p-2.5 text-sm hover:bg-gray-200 focus-visible:bg-gray-200 focus-visible:outline-0 radix-disabled:pointer-events-none radix-disabled:opacity-50 dark:hover:bg-gray-600 dark:focus-visible:bg-gray-600"
|
className="group m-1.5 mt-[3.5px] flex w-full cursor-pointer items-center gap-2 rounded p-2.5 text-sm hover:bg-gray-200 focus-visible:bg-gray-200 focus-visible:outline-0 radix-disabled:pointer-events-none radix-disabled:opacity-50 dark:hover:bg-gray-600 dark:focus-visible:bg-gray-600"
|
||||||
/>
|
/>
|
||||||
</EditMenuButton>
|
</DropDownMenu>
|
||||||
<ArchiveButton
|
<ArchiveButton
|
||||||
className="z-50 hover:text-black dark:hover:text-white"
|
className="z-50 hover:text-black dark:hover:text-white"
|
||||||
conversationId={conversationId}
|
conversationId={conversationId}
|
||||||
|
|
@ -156,7 +165,7 @@ export default function Conversation({ conversation, retainView, toggleNav, isLa
|
||||||
onClick={clickHandler}
|
onClick={clickHandler}
|
||||||
className={cn(
|
className={cn(
|
||||||
isActiveConvo || isPopoverActive
|
isActiveConvo || isPopoverActive
|
||||||
? 'group relative mt-2 flex cursor-pointer items-center gap-2 break-all rounded-lg rounded-lg bg-gray-200 px-2 py-2 active:opacity-50 dark:bg-gray-700'
|
? 'group relative mt-2 flex cursor-pointer items-center gap-2 break-all rounded-lg bg-gray-200 px-2 py-2 active:opacity-50 dark:bg-gray-700'
|
||||||
: 'group relative mt-2 flex grow cursor-pointer items-center gap-2 overflow-hidden whitespace-nowrap break-all rounded-lg rounded-lg px-2 py-2 hover:bg-gray-200 active:opacity-50 dark:hover:bg-gray-700',
|
: 'group relative mt-2 flex grow cursor-pointer items-center gap-2 overflow-hidden whitespace-nowrap break-all rounded-lg rounded-lg px-2 py-2 hover:bg-gray-200 active:opacity-50 dark:hover:bg-gray-700',
|
||||||
!isActiveConvo && !renaming ? 'peer-hover:bg-gray-200 dark:peer-hover:bg-gray-800' : '',
|
!isActiveConvo && !renaming ? 'peer-hover:bg-gray-200 dark:peer-hover:bg-gray-800' : '',
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import type { FC } from 'react';
|
import { cloneElement, type FC } from 'react';
|
||||||
import { DotsIcon } from '~/components/svg';
|
import { DotsIcon } from '~/components/svg';
|
||||||
import { Content, Portal, Root, Trigger } from '@radix-ui/react-popover';
|
import { Content, Portal, Root, Trigger } from '@radix-ui/react-popover';
|
||||||
import { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent } from '~/components/ui';
|
import { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent } from '~/components/ui';
|
||||||
|
|
@ -6,15 +6,23 @@ import { useToggle } from './ToggleContext';
|
||||||
import { useLocalize } from '~/hooks';
|
import { useLocalize } from '~/hooks';
|
||||||
import { cn } from '~/utils';
|
import { cn } from '~/utils';
|
||||||
|
|
||||||
type EditMenuButtonProps = {
|
type DropDownMenuProps = {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
|
icon?: React.ReactElement;
|
||||||
|
tooltip?: string;
|
||||||
|
className?: string;
|
||||||
};
|
};
|
||||||
const EditMenuButton: FC<EditMenuButtonProps> = ({ children }: EditMenuButtonProps) => {
|
const DropDownMenu: FC<DropDownMenuProps> = ({
|
||||||
|
children,
|
||||||
|
icon = <DotsIcon />,
|
||||||
|
tooltip = 'More',
|
||||||
|
className,
|
||||||
|
}: DropDownMenuProps) => {
|
||||||
const localize = useLocalize();
|
const localize = useLocalize();
|
||||||
const { setPopoverActive } = useToggle();
|
const { isPopoverActive, setPopoverActive } = useToggle();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Root onOpenChange={(open) => setPopoverActive(open)}>
|
<Root open={isPopoverActive} onOpenChange={(open) => setPopoverActive(open)}>
|
||||||
<Trigger asChild>
|
<Trigger asChild>
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
|
|
@ -29,12 +37,15 @@ const EditMenuButton: FC<EditMenuButtonProps> = ({ children }: EditMenuButtonPro
|
||||||
<TooltipProvider delayDuration={500}>
|
<TooltipProvider delayDuration={500}>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button type="button" className="">
|
<button type="button" className={className}>
|
||||||
<DotsIcon className="h-[18px] w-[18px] flex-shrink-0 text-gray-500 hover:text-gray-400 dark:text-gray-300 dark:hover:text-gray-400" />
|
{cloneElement(icon, {
|
||||||
|
className:
|
||||||
|
'h-[18px] w-[18px] flex-shrink-0 text-gray-500 hover:text-gray-400 dark:text-gray-300 dark:hover:text-gray-400',
|
||||||
|
})}
|
||||||
</button>
|
</button>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent side="top" sideOffset={0}>
|
<TooltipContent side="top" sideOffset={0}>
|
||||||
{localize('com_ui_more_options')}
|
{tooltip}
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
|
|
@ -57,4 +68,4 @@ const EditMenuButton: FC<EditMenuButtonProps> = ({ children }: EditMenuButtonPro
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default EditMenuButton;
|
export default DropDownMenu;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useState } from 'react';
|
import React from 'react';
|
||||||
import { ToggleContext } from './ToggleContext';
|
import { ToggleContext } from './ToggleContext';
|
||||||
import { cn } from '~/utils';
|
import { cn } from '~/utils';
|
||||||
|
|
||||||
|
|
@ -15,7 +15,7 @@ const HoverToggle = ({
|
||||||
}) => {
|
}) => {
|
||||||
const setPopoverActive = (value: boolean) => setIsPopoverActive(value);
|
const setPopoverActive = (value: boolean) => setIsPopoverActive(value);
|
||||||
return (
|
return (
|
||||||
<ToggleContext.Provider value={{ setPopoverActive }}>
|
<ToggleContext.Provider value={{ isPopoverActive, setPopoverActive }}>
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
'peer absolute bottom-0 right-0 top-0 items-center gap-1.5 rounded-r-lg from-gray-500 from-gray-900 pl-2 pr-2 dark:text-white',
|
'peer absolute bottom-0 right-0 top-0 items-center gap-1.5 rounded-r-lg from-gray-500 from-gray-900 pl-2 pr-2 dark:text-white',
|
||||||
|
|
|
||||||
113
client/src/components/Conversations/ShareButton.tsx
Normal file
113
client/src/components/Conversations/ShareButton.tsx
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
import { useState } from 'react';
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
Tooltip,
|
||||||
|
DialogTrigger,
|
||||||
|
TooltipContent,
|
||||||
|
TooltipTrigger,
|
||||||
|
TooltipProvider,
|
||||||
|
} from '~/components/ui';
|
||||||
|
import { Share2Icon } from 'lucide-react';
|
||||||
|
import type { TSharedLink } from 'librechat-data-provider';
|
||||||
|
import DialogTemplate from '~/components/ui/DialogTemplate';
|
||||||
|
import SharedLinkButton from './SharedLinkButton';
|
||||||
|
import ShareDialog from './ShareDialog';
|
||||||
|
import { useLocalize } from '~/hooks';
|
||||||
|
import { cn } from '~/utils';
|
||||||
|
|
||||||
|
export default function ShareButton({
|
||||||
|
conversationId,
|
||||||
|
title,
|
||||||
|
className,
|
||||||
|
appendLabel = false,
|
||||||
|
setPopoverActive,
|
||||||
|
}: {
|
||||||
|
conversationId: string;
|
||||||
|
title: string;
|
||||||
|
className?: string;
|
||||||
|
appendLabel?: boolean;
|
||||||
|
setPopoverActive: (isActive: boolean) => void;
|
||||||
|
}) {
|
||||||
|
const localize = useLocalize();
|
||||||
|
const [share, setShare] = useState<TSharedLink | null>(null);
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const [isUpdated, setIsUpdated] = useState(false);
|
||||||
|
|
||||||
|
const classProp: { className?: string } = {
|
||||||
|
className: 'p-1 hover:text-black dark:hover:text-white',
|
||||||
|
};
|
||||||
|
if (className) {
|
||||||
|
classProp.className = className;
|
||||||
|
}
|
||||||
|
const renderShareButton = () => {
|
||||||
|
if (appendLabel) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Share2Icon className="h-4 w-4" /> {localize('com_ui_share')}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<TooltipProvider delayDuration={250}>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<span>
|
||||||
|
<Share2Icon />
|
||||||
|
</span>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent side="top" sideOffset={0}>
|
||||||
|
{localize('com_ui_share')}
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const buttons = share && (
|
||||||
|
<SharedLinkButton
|
||||||
|
share={share}
|
||||||
|
conversationId={conversationId}
|
||||||
|
setShare={setShare}
|
||||||
|
isUpdated={isUpdated}
|
||||||
|
setIsUpdated={setIsUpdated}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const onOpenChange = (open: boolean) => {
|
||||||
|
setPopoverActive(open);
|
||||||
|
setOpen(open);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||||
|
<DialogTrigger asChild>
|
||||||
|
<button
|
||||||
|
className={cn(
|
||||||
|
'group m-1.5 flex w-full cursor-pointer items-center gap-2 rounded p-2.5 text-sm hover:bg-gray-200 focus-visible:bg-gray-200 focus-visible:outline-0 radix-disabled:pointer-events-none radix-disabled:opacity-50 dark:hover:bg-gray-600 dark:focus-visible:bg-gray-600',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{renderShareButton()}
|
||||||
|
</button>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogTemplate
|
||||||
|
buttons={buttons}
|
||||||
|
showCloseButton={true}
|
||||||
|
showCancelButton={false}
|
||||||
|
title={localize('com_ui_share_link_to_chat')}
|
||||||
|
className="max-w-[550px]"
|
||||||
|
main={
|
||||||
|
<>
|
||||||
|
<ShareDialog
|
||||||
|
setDialogOpen={setOpen}
|
||||||
|
conversationId={conversationId}
|
||||||
|
title={title}
|
||||||
|
share={share}
|
||||||
|
setShare={setShare}
|
||||||
|
isUpdated={isUpdated}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
80
client/src/components/Conversations/ShareDialog.tsx
Normal file
80
client/src/components/Conversations/ShareDialog.tsx
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
import { useLocalize } from '~/hooks';
|
||||||
|
|
||||||
|
import { useCreateSharedLinkMutation } from '~/data-provider';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import { TSharedLink } from 'librechat-data-provider';
|
||||||
|
import { useToastContext } from '~/Providers';
|
||||||
|
import { NotificationSeverity } from '~/common';
|
||||||
|
import { Spinner } from '~/components/svg';
|
||||||
|
|
||||||
|
export default function ShareDialog({
|
||||||
|
conversationId,
|
||||||
|
title,
|
||||||
|
share,
|
||||||
|
setShare,
|
||||||
|
setDialogOpen,
|
||||||
|
isUpdated,
|
||||||
|
}: {
|
||||||
|
conversationId: string;
|
||||||
|
title: string;
|
||||||
|
share: TSharedLink | null;
|
||||||
|
setShare: (share: TSharedLink | null) => void;
|
||||||
|
setDialogOpen: (open: boolean) => void;
|
||||||
|
isUpdated: boolean;
|
||||||
|
}) {
|
||||||
|
const localize = useLocalize();
|
||||||
|
const { showToast } = useToastContext();
|
||||||
|
const { mutate, isLoading } = useCreateSharedLinkMutation();
|
||||||
|
const [isNewSharedLink, setIsNewSharedLink] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isLoading || share) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const data = {
|
||||||
|
conversationId,
|
||||||
|
title,
|
||||||
|
isAnonymous: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
mutate(data, {
|
||||||
|
onSuccess: (result) => {
|
||||||
|
setShare(result);
|
||||||
|
setIsNewSharedLink(!result.isPublic);
|
||||||
|
},
|
||||||
|
onError: () => {
|
||||||
|
showToast({
|
||||||
|
message: localize('com_ui_share_error'),
|
||||||
|
severity: NotificationSeverity.ERROR,
|
||||||
|
showIcon: true,
|
||||||
|
});
|
||||||
|
setDialogOpen(false);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// mutation.mutate should only be called once
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="h-full py-2 text-gray-400 dark:text-gray-200">
|
||||||
|
{(() => {
|
||||||
|
if (isLoading) {
|
||||||
|
return <Spinner className="m-auto h-14 animate-spin" />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isUpdated) {
|
||||||
|
return isNewSharedLink
|
||||||
|
? localize('com_ui_share_created_message')
|
||||||
|
: localize('com_ui_share_updated_message');
|
||||||
|
}
|
||||||
|
|
||||||
|
return share?.isPublic
|
||||||
|
? localize('com_ui_share_update_message')
|
||||||
|
: localize('com_ui_share_create_message');
|
||||||
|
})()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
115
client/src/components/Conversations/SharedLinkButton.tsx
Normal file
115
client/src/components/Conversations/SharedLinkButton.tsx
Normal file
|
|
@ -0,0 +1,115 @@
|
||||||
|
import { useState } from 'react';
|
||||||
|
import copy from 'copy-to-clipboard';
|
||||||
|
import { Copy, Link } from 'lucide-react';
|
||||||
|
import { useUpdateSharedLinkMutation } from '~/data-provider';
|
||||||
|
import type { TSharedLink } from 'librechat-data-provider';
|
||||||
|
import { Spinner } from '~/components/svg';
|
||||||
|
import { Button } from '~/components/ui';
|
||||||
|
import { useLocalize } from '~/hooks';
|
||||||
|
|
||||||
|
export default function SharedLinkButton({
|
||||||
|
conversationId,
|
||||||
|
share,
|
||||||
|
setShare,
|
||||||
|
isUpdated,
|
||||||
|
setIsUpdated,
|
||||||
|
}: {
|
||||||
|
conversationId: string;
|
||||||
|
share: TSharedLink;
|
||||||
|
setShare: (share: TSharedLink) => void;
|
||||||
|
isUpdated: boolean;
|
||||||
|
setIsUpdated: (isUpdated: boolean) => void;
|
||||||
|
}) {
|
||||||
|
const localize = useLocalize();
|
||||||
|
const [isCopying, setIsCopying] = useState(false);
|
||||||
|
const { mutateAsync, isLoading } = useUpdateSharedLinkMutation();
|
||||||
|
|
||||||
|
const copyLink = () => {
|
||||||
|
if (!share) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setIsCopying(true);
|
||||||
|
const sharedLink =
|
||||||
|
window.location.protocol + '//' + window.location.host + '/share/' + share.shareId;
|
||||||
|
copy(sharedLink);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsCopying(false);
|
||||||
|
}, 1500);
|
||||||
|
};
|
||||||
|
const updateSharedLink = async () => {
|
||||||
|
if (!share) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const result = await mutateAsync({
|
||||||
|
shareId: share.shareId,
|
||||||
|
conversationId: conversationId,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
isAnonymous: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
setShare(result);
|
||||||
|
setIsUpdated(true);
|
||||||
|
copyLink();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const getHandler = () => {
|
||||||
|
if (isUpdated) {
|
||||||
|
return {
|
||||||
|
handler: () => {
|
||||||
|
copyLink();
|
||||||
|
},
|
||||||
|
label: (
|
||||||
|
<>
|
||||||
|
<Copy className="mr-2 h-4 w-4" />
|
||||||
|
{localize('com_ui_copy_link')}
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (share?.isPublic) {
|
||||||
|
return {
|
||||||
|
handler: async () => {
|
||||||
|
await updateSharedLink();
|
||||||
|
},
|
||||||
|
|
||||||
|
label: (
|
||||||
|
<>
|
||||||
|
<Link className="mr-2 h-4 w-4" />
|
||||||
|
{localize('com_ui_update_link')}
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
handler: updateSharedLink,
|
||||||
|
label: (
|
||||||
|
<>
|
||||||
|
<Link className="mr-2 h-4 w-4" />
|
||||||
|
{localize('com_ui_create_link')}
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlers = getHandler();
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
disabled={isLoading || isCopying}
|
||||||
|
onClick={() => {
|
||||||
|
handlers.handler();
|
||||||
|
}}
|
||||||
|
className="min-w-32 whitespace-nowrap bg-green-500 text-white hover:bg-green-600 dark:bg-green-600 dark:text-white dark:hover:bg-green-800"
|
||||||
|
>
|
||||||
|
{isCopying && (
|
||||||
|
<>
|
||||||
|
<Copy className="mr-2 h-4 w-4" />
|
||||||
|
{localize('com_ui_copied')}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{!isCopying && !isLoading && handlers.label}
|
||||||
|
{!isCopying && isLoading && <Spinner className="h-4 w-4" />}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ import { createContext, useContext } from 'react';
|
||||||
const defaultFunction: (value: boolean) => void = () => ({});
|
const defaultFunction: (value: boolean) => void = () => ({});
|
||||||
export const ToggleContext = createContext({
|
export const ToggleContext = createContext({
|
||||||
setPopoverActive: defaultFunction,
|
setPopoverActive: defaultFunction,
|
||||||
|
isPopoverActive: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const useToggle = () => useContext(ToggleContext);
|
export const useToggle = () => useContext(ToggleContext);
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,14 @@
|
||||||
import { EModelEndpoint } from 'librechat-data-provider';
|
import { UserIcon } from '~/components/svg';
|
||||||
import UnknownIcon from '~/components/Chat/Menus/Endpoints/UnknownIcon';
|
|
||||||
import {
|
|
||||||
Plugin,
|
|
||||||
GPTIcon,
|
|
||||||
UserIcon,
|
|
||||||
PaLMIcon,
|
|
||||||
CodeyIcon,
|
|
||||||
GeminiIcon,
|
|
||||||
AssistantIcon,
|
|
||||||
AnthropicIcon,
|
|
||||||
AzureMinimalIcon,
|
|
||||||
CustomMinimalIcon,
|
|
||||||
} from '~/components/svg';
|
|
||||||
import { useAuthContext } from '~/hooks/AuthContext';
|
import { useAuthContext } from '~/hooks/AuthContext';
|
||||||
import useAvatar from '~/hooks/Messages/useAvatar';
|
import useAvatar from '~/hooks/Messages/useAvatar';
|
||||||
import useLocalize from '~/hooks/useLocalize';
|
import useLocalize from '~/hooks/useLocalize';
|
||||||
import { IconProps } from '~/common';
|
import { IconProps } from '~/common';
|
||||||
import { cn } from '~/utils';
|
import { cn } from '~/utils';
|
||||||
|
import MessageEndpointIcon from './MessageEndpointIcon';
|
||||||
|
|
||||||
const Icon: React.FC<IconProps> = (props) => {
|
const Icon: React.FC<IconProps> = (props) => {
|
||||||
const { user } = useAuthContext();
|
const { user } = useAuthContext();
|
||||||
const {
|
const { size = 30, isCreatedByUser } = props;
|
||||||
error,
|
|
||||||
button,
|
|
||||||
iconURL,
|
|
||||||
endpoint,
|
|
||||||
jailbreak,
|
|
||||||
size = 30,
|
|
||||||
model = '',
|
|
||||||
assistantName,
|
|
||||||
isCreatedByUser,
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
const avatarSrc = useAvatar(user);
|
const avatarSrc = useAvatar(user);
|
||||||
const localize = useLocalize();
|
const localize = useLocalize();
|
||||||
|
|
@ -65,141 +43,7 @@ const Icon: React.FC<IconProps> = (props) => {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
return <MessageEndpointIcon {...props} />;
|
||||||
const endpointIcons = {
|
|
||||||
[EModelEndpoint.assistants]: {
|
|
||||||
icon: props.iconURL ? (
|
|
||||||
<div className="relative flex h-6 w-6 items-center justify-center">
|
|
||||||
<div
|
|
||||||
title={assistantName}
|
|
||||||
style={{
|
|
||||||
width: size,
|
|
||||||
height: size,
|
|
||||||
}}
|
|
||||||
className={cn('overflow-hidden rounded-full', props.className ?? '')}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
className="shadow-stroke h-full w-full object-cover"
|
|
||||||
src={props.iconURL}
|
|
||||||
alt={assistantName}
|
|
||||||
style={{ height: '80', width: '80' }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div className="h-6 w-6">
|
|
||||||
<div className="shadow-stroke flex h-6 w-6 items-center justify-center overflow-hidden rounded-full">
|
|
||||||
<AssistantIcon className="h-2/3 w-2/3 text-gray-400" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
name: endpoint,
|
|
||||||
},
|
|
||||||
[EModelEndpoint.azureOpenAI]: {
|
|
||||||
icon: <AzureMinimalIcon size={size * 0.5555555555555556} />,
|
|
||||||
bg: 'linear-gradient(0.375turn, #61bde2, #4389d0)',
|
|
||||||
name: 'ChatGPT',
|
|
||||||
},
|
|
||||||
[EModelEndpoint.openAI]: {
|
|
||||||
icon: <GPTIcon size={size * 0.5555555555555556} />,
|
|
||||||
bg:
|
|
||||||
typeof model === 'string' && model.toLowerCase().includes('gpt-4') ? '#AB68FF' : '#19C37D',
|
|
||||||
name: 'ChatGPT',
|
|
||||||
},
|
|
||||||
[EModelEndpoint.gptPlugins]: {
|
|
||||||
icon: <Plugin size={size * 0.7} />,
|
|
||||||
bg: `rgba(69, 89, 164, ${button ? 0.75 : 1})`,
|
|
||||||
name: 'Plugins',
|
|
||||||
},
|
|
||||||
[EModelEndpoint.google]: {
|
|
||||||
icon: model?.toLowerCase()?.includes('code') ? (
|
|
||||||
<CodeyIcon size={size * 0.75} />
|
|
||||||
) : model?.toLowerCase()?.includes('gemini') ? (
|
|
||||||
<GeminiIcon size={size * 0.7} />
|
|
||||||
) : (
|
|
||||||
<PaLMIcon size={size * 0.7} />
|
|
||||||
),
|
|
||||||
name: model?.toLowerCase()?.includes('code')
|
|
||||||
? 'Codey'
|
|
||||||
: model?.toLowerCase()?.includes('gemini')
|
|
||||||
? 'Gemini'
|
|
||||||
: 'PaLM2',
|
|
||||||
},
|
|
||||||
[EModelEndpoint.anthropic]: {
|
|
||||||
icon: <AnthropicIcon size={size * 0.5555555555555556} />,
|
|
||||||
bg: '#d09a74',
|
|
||||||
name: 'Claude',
|
|
||||||
},
|
|
||||||
[EModelEndpoint.bingAI]: {
|
|
||||||
icon: jailbreak ? (
|
|
||||||
<img src="/assets/bingai-jb.png" alt="Bing Icon" />
|
|
||||||
) : (
|
|
||||||
<img src="/assets/bingai.png" alt="Sydney Icon" />
|
|
||||||
),
|
|
||||||
name: jailbreak ? 'Sydney' : 'BingAI',
|
|
||||||
},
|
|
||||||
[EModelEndpoint.chatGPTBrowser]: {
|
|
||||||
icon: <GPTIcon size={size * 0.5555555555555556} />,
|
|
||||||
bg:
|
|
||||||
typeof model === 'string' && model.toLowerCase().includes('gpt-4')
|
|
||||||
? '#AB68FF'
|
|
||||||
: `rgba(0, 163, 255, ${button ? 0.75 : 1})`,
|
|
||||||
name: 'ChatGPT',
|
|
||||||
},
|
|
||||||
[EModelEndpoint.custom]: {
|
|
||||||
icon: <CustomMinimalIcon size={size * 0.7} />,
|
|
||||||
name: 'Custom',
|
|
||||||
},
|
|
||||||
null: { icon: <GPTIcon size={size * 0.7} />, bg: 'grey', name: 'N/A' },
|
|
||||||
default: {
|
|
||||||
icon: (
|
|
||||||
<div className="h-6 w-6">
|
|
||||||
<div className="overflow-hidden rounded-full">
|
|
||||||
<UnknownIcon
|
|
||||||
iconURL={props.iconURL}
|
|
||||||
endpoint={endpoint ?? ''}
|
|
||||||
className="h-full w-full object-contain"
|
|
||||||
context="message"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
name: endpoint,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let { icon, bg, name } =
|
|
||||||
endpoint && endpointIcons[endpoint] ? endpointIcons[endpoint] : endpointIcons.default;
|
|
||||||
|
|
||||||
if (iconURL && endpointIcons[iconURL]) {
|
|
||||||
({ icon, bg, name } = endpointIcons[iconURL]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (endpoint === EModelEndpoint.assistants) {
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
title={name}
|
|
||||||
style={{
|
|
||||||
background: bg || 'transparent',
|
|
||||||
width: size,
|
|
||||||
height: size,
|
|
||||||
}}
|
|
||||||
className={cn(
|
|
||||||
'relative flex h-9 w-9 items-center justify-center rounded-sm p-1 text-white',
|
|
||||||
props.className || '',
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{icon}
|
|
||||||
{error && (
|
|
||||||
<span className="absolute right-0 top-[20px] -mr-2 flex h-3 w-3 items-center justify-center rounded-full border border-white bg-red-500 text-[10px] text-white">
|
|
||||||
!
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Icon;
|
export default Icon;
|
||||||
|
|
|
||||||
166
client/src/components/Endpoints/MessageEndpointIcon.tsx
Normal file
166
client/src/components/Endpoints/MessageEndpointIcon.tsx
Normal file
|
|
@ -0,0 +1,166 @@
|
||||||
|
import { EModelEndpoint } from 'librechat-data-provider';
|
||||||
|
import UnknownIcon from '~/components/Chat/Menus/Endpoints/UnknownIcon';
|
||||||
|
import {
|
||||||
|
Plugin,
|
||||||
|
GPTIcon,
|
||||||
|
PaLMIcon,
|
||||||
|
CodeyIcon,
|
||||||
|
GeminiIcon,
|
||||||
|
AssistantIcon,
|
||||||
|
AnthropicIcon,
|
||||||
|
AzureMinimalIcon,
|
||||||
|
CustomMinimalIcon,
|
||||||
|
} from '~/components/svg';
|
||||||
|
|
||||||
|
import { IconProps } from '~/common';
|
||||||
|
import { cn } from '~/utils';
|
||||||
|
|
||||||
|
const MessageEndpointIcon: React.FC<IconProps> = (props) => {
|
||||||
|
const {
|
||||||
|
error,
|
||||||
|
button,
|
||||||
|
iconURL,
|
||||||
|
endpoint,
|
||||||
|
jailbreak,
|
||||||
|
size = 30,
|
||||||
|
model = '',
|
||||||
|
assistantName,
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
const endpointIcons = {
|
||||||
|
[EModelEndpoint.assistants]: {
|
||||||
|
icon: props.iconURL ? (
|
||||||
|
<div className="relative flex h-6 w-6 items-center justify-center">
|
||||||
|
<div
|
||||||
|
title={assistantName}
|
||||||
|
style={{
|
||||||
|
width: size,
|
||||||
|
height: size,
|
||||||
|
}}
|
||||||
|
className={cn('overflow-hidden rounded-full', props.className ?? '')}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
className="shadow-stroke h-full w-full object-cover"
|
||||||
|
src={props.iconURL}
|
||||||
|
alt={assistantName}
|
||||||
|
style={{ height: '80', width: '80' }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="h-6 w-6">
|
||||||
|
<div className="shadow-stroke flex h-6 w-6 items-center justify-center overflow-hidden rounded-full">
|
||||||
|
<AssistantIcon className="h-2/3 w-2/3 text-gray-400" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
name: endpoint,
|
||||||
|
},
|
||||||
|
[EModelEndpoint.azureOpenAI]: {
|
||||||
|
icon: <AzureMinimalIcon size={size * 0.5555555555555556} />,
|
||||||
|
bg: 'linear-gradient(0.375turn, #61bde2, #4389d0)',
|
||||||
|
name: 'ChatGPT',
|
||||||
|
},
|
||||||
|
[EModelEndpoint.openAI]: {
|
||||||
|
icon: <GPTIcon size={size * 0.5555555555555556} />,
|
||||||
|
bg:
|
||||||
|
typeof model === 'string' && model.toLowerCase().includes('gpt-4') ? '#AB68FF' : '#19C37D',
|
||||||
|
name: 'ChatGPT',
|
||||||
|
},
|
||||||
|
[EModelEndpoint.gptPlugins]: {
|
||||||
|
icon: <Plugin size={size * 0.7} />,
|
||||||
|
bg: `rgba(69, 89, 164, ${button ? 0.75 : 1})`,
|
||||||
|
name: 'Plugins',
|
||||||
|
},
|
||||||
|
[EModelEndpoint.google]: {
|
||||||
|
icon: model?.toLowerCase()?.includes('code') ? (
|
||||||
|
<CodeyIcon size={size * 0.75} />
|
||||||
|
) : model?.toLowerCase()?.includes('gemini') ? (
|
||||||
|
<GeminiIcon size={size * 0.7} />
|
||||||
|
) : (
|
||||||
|
<PaLMIcon size={size * 0.7} />
|
||||||
|
),
|
||||||
|
name: model?.toLowerCase()?.includes('code')
|
||||||
|
? 'Codey'
|
||||||
|
: model?.toLowerCase()?.includes('gemini')
|
||||||
|
? 'Gemini'
|
||||||
|
: 'PaLM2',
|
||||||
|
},
|
||||||
|
[EModelEndpoint.anthropic]: {
|
||||||
|
icon: <AnthropicIcon size={size * 0.5555555555555556} />,
|
||||||
|
bg: '#d09a74',
|
||||||
|
name: 'Claude',
|
||||||
|
},
|
||||||
|
[EModelEndpoint.bingAI]: {
|
||||||
|
icon: jailbreak ? (
|
||||||
|
<img src="/assets/bingai-jb.png" alt="Bing Icon" />
|
||||||
|
) : (
|
||||||
|
<img src="/assets/bingai.png" alt="Sydney Icon" />
|
||||||
|
),
|
||||||
|
name: jailbreak ? 'Sydney' : 'BingAI',
|
||||||
|
},
|
||||||
|
[EModelEndpoint.chatGPTBrowser]: {
|
||||||
|
icon: <GPTIcon size={size * 0.5555555555555556} />,
|
||||||
|
bg:
|
||||||
|
typeof model === 'string' && model.toLowerCase().includes('gpt-4')
|
||||||
|
? '#AB68FF'
|
||||||
|
: `rgba(0, 163, 255, ${button ? 0.75 : 1})`,
|
||||||
|
name: 'ChatGPT',
|
||||||
|
},
|
||||||
|
[EModelEndpoint.custom]: {
|
||||||
|
icon: <CustomMinimalIcon size={size * 0.7} />,
|
||||||
|
name: 'Custom',
|
||||||
|
},
|
||||||
|
null: { icon: <GPTIcon size={size * 0.7} />, bg: 'grey', name: 'N/A' },
|
||||||
|
default: {
|
||||||
|
icon: (
|
||||||
|
<div className="h-6 w-6">
|
||||||
|
<div className="overflow-hidden rounded-full">
|
||||||
|
<UnknownIcon
|
||||||
|
iconURL={props.iconURL}
|
||||||
|
endpoint={endpoint ?? ''}
|
||||||
|
className="h-full w-full object-contain"
|
||||||
|
context="message"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
name: endpoint,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let { icon, bg, name } =
|
||||||
|
endpoint && endpointIcons[endpoint] ? endpointIcons[endpoint] : endpointIcons.default;
|
||||||
|
|
||||||
|
if (iconURL && endpointIcons[iconURL]) {
|
||||||
|
({ icon, bg, name } = endpointIcons[iconURL]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endpoint === EModelEndpoint.assistants) {
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
title={name}
|
||||||
|
style={{
|
||||||
|
background: bg || 'transparent',
|
||||||
|
width: size,
|
||||||
|
height: size,
|
||||||
|
}}
|
||||||
|
className={cn(
|
||||||
|
'relative flex h-9 w-9 items-center justify-center rounded-sm p-1 text-white',
|
||||||
|
props.className || '',
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{icon}
|
||||||
|
{error && (
|
||||||
|
<span className="absolute right-0 top-[20px] -mr-2 flex h-3 w-3 items-center justify-center rounded-full border border-white bg-red-500 text-[10px] text-white">
|
||||||
|
!
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MessageEndpointIcon;
|
||||||
|
|
@ -3,6 +3,7 @@ import { InfoIcon } from 'lucide-react';
|
||||||
import React, { useRef, useState, RefObject } from 'react';
|
import React, { useRef, useState, RefObject } from 'react';
|
||||||
import Clipboard from '~/components/svg/Clipboard';
|
import Clipboard from '~/components/svg/Clipboard';
|
||||||
import CheckMark from '~/components/svg/CheckMark';
|
import CheckMark from '~/components/svg/CheckMark';
|
||||||
|
import useLocalize from '~/hooks/useLocalize';
|
||||||
import cn from '~/utils/cn';
|
import cn from '~/utils/cn';
|
||||||
|
|
||||||
type CodeBarProps = {
|
type CodeBarProps = {
|
||||||
|
|
@ -18,6 +19,7 @@ type CodeBlockProps = Pick<CodeBarProps, 'lang' | 'plugin' | 'error'> & {
|
||||||
};
|
};
|
||||||
|
|
||||||
const CodeBar: React.FC<CodeBarProps> = React.memo(({ lang, codeRef, error, plugin = null }) => {
|
const CodeBar: React.FC<CodeBarProps> = React.memo(({ lang, codeRef, error, plugin = null }) => {
|
||||||
|
const localize = useLocalize();
|
||||||
const [isCopied, setIsCopied] = useState(false);
|
const [isCopied, setIsCopied] = useState(false);
|
||||||
return (
|
return (
|
||||||
<div className="relative flex items-center rounded-tl-md rounded-tr-md bg-gray-700 px-4 py-2 font-sans text-xs text-gray-200 dark:bg-gray-700">
|
<div className="relative flex items-center rounded-tl-md rounded-tr-md bg-gray-700 px-4 py-2 font-sans text-xs text-gray-200 dark:bg-gray-700">
|
||||||
|
|
@ -41,13 +43,13 @@ const CodeBar: React.FC<CodeBarProps> = React.memo(({ lang, codeRef, error, plug
|
||||||
>
|
>
|
||||||
{isCopied ? (
|
{isCopied ? (
|
||||||
<>
|
<>
|
||||||
<CheckMark />
|
<CheckMark className="h-[18px] w-[18px]" />
|
||||||
{error ? '' : 'Copied!'}
|
{error ? '' : localize('com_ui_copied')}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<Clipboard />
|
<Clipboard />
|
||||||
{error ? '' : 'Copy code'}
|
{error ? '' : localize('com_ui_copy_code')}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { useCallback, memo, ReactNode } from 'react';
|
||||||
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
||||||
import type { TResPlugin, TInput } from 'librechat-data-provider';
|
import type { TResPlugin, TInput } from 'librechat-data-provider';
|
||||||
import { ChevronDownIcon, LucideProps } from 'lucide-react';
|
import { ChevronDownIcon, LucideProps } from 'lucide-react';
|
||||||
|
import { useShareContext } from '~/Providers';
|
||||||
import { cn, formatJSON } from '~/utils';
|
import { cn, formatJSON } from '~/utils';
|
||||||
import { Spinner } from '~/components';
|
import { Spinner } from '~/components';
|
||||||
import CodeBlock from './CodeBlock';
|
import CodeBlock from './CodeBlock';
|
||||||
|
|
@ -31,7 +32,9 @@ type PluginProps = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const Plugin: React.FC<PluginProps> = ({ plugin }) => {
|
const Plugin: React.FC<PluginProps> = ({ plugin }) => {
|
||||||
|
const { isSharedConvo } = useShareContext();
|
||||||
const { data: plugins = {} } = useGetEndpointsQuery({
|
const { data: plugins = {} } = useGetEndpointsQuery({
|
||||||
|
enabled: !isSharedConvo,
|
||||||
select: (data) => data?.gptPlugins?.plugins,
|
select: (data) => data?.gptPlugins?.plugins,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ import NavToggle from './NavToggle';
|
||||||
import NavLinks from './NavLinks';
|
import NavLinks from './NavLinks';
|
||||||
import NewChat from './NewChat';
|
import NewChat from './NewChat';
|
||||||
import { cn } from '~/utils';
|
import { cn } from '~/utils';
|
||||||
|
import { ConversationListResponse } from 'librechat-data-provider';
|
||||||
import store from '~/store';
|
import store from '~/store';
|
||||||
|
|
||||||
const Nav = ({ navVisible, setNavVisible }) => {
|
const Nav = ({ navVisible, setNavVisible }) => {
|
||||||
|
|
@ -59,7 +60,7 @@ const Nav = ({ navVisible, setNavVisible }) => {
|
||||||
{ enabled: isAuthenticated },
|
{ enabled: isAuthenticated },
|
||||||
);
|
);
|
||||||
|
|
||||||
const { containerRef, moveToTop } = useNavScrolling({
|
const { containerRef, moveToTop } = useNavScrolling<ConversationListResponse>({
|
||||||
setShowLoading,
|
setShowLoading,
|
||||||
hasNextPage: searchQuery ? searchQueryRes.hasNextPage : hasNextPage,
|
hasNextPage: searchQuery ? searchQueryRes.hasNextPage : hasNextPage,
|
||||||
fetchNextPage: searchQuery ? searchQueryRes.fetchNextPage : fetchNextPage,
|
fetchNextPage: searchQuery ? searchQueryRes.fetchNextPage : fetchNextPage,
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import { useConversation, useConversations, useOnClickOutside } from '~/hooks';
|
||||||
import ImportConversations from './ImportConversations';
|
import ImportConversations from './ImportConversations';
|
||||||
import { ClearChatsButton } from './ClearChats';
|
import { ClearChatsButton } from './ClearChats';
|
||||||
import DangerButton from '../DangerButton';
|
import DangerButton from '../DangerButton';
|
||||||
|
import SharedLinks from './SharedLinks';
|
||||||
|
|
||||||
export const RevokeKeysButton = ({
|
export const RevokeKeysButton = ({
|
||||||
showText = true,
|
showText = true,
|
||||||
|
|
@ -107,6 +108,9 @@ function Data() {
|
||||||
<div className="border-b pb-3 last-of-type:border-b-0 dark:border-gray-600">
|
<div className="border-b pb-3 last-of-type:border-b-0 dark:border-gray-600">
|
||||||
<ImportConversations />
|
<ImportConversations />
|
||||||
</div>
|
</div>
|
||||||
|
<div className="border-b pb-3 last-of-type:border-b-0 dark:border-gray-600">
|
||||||
|
<SharedLinks />
|
||||||
|
</div>
|
||||||
<div className="border-b pb-3 last-of-type:border-b-0 dark:border-gray-600">
|
<div className="border-b pb-3 last-of-type:border-b-0 dark:border-gray-600">
|
||||||
<RevokeKeysButton all={true} />
|
<RevokeKeysButton all={true} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
178
client/src/components/Nav/SettingsTabs/Data/SharedLinkTable.tsx
Normal file
178
client/src/components/Nav/SettingsTabs/Data/SharedLinkTable.tsx
Normal file
|
|
@ -0,0 +1,178 @@
|
||||||
|
import { useAuthContext, useLocalize, useNavScrolling } from '~/hooks';
|
||||||
|
import { MessageSquare, Link as LinkIcon } from 'lucide-react';
|
||||||
|
import { useMemo, useState, MouseEvent } from 'react';
|
||||||
|
import { useDeleteSharedLinkMutation, useSharedLinksInfiniteQuery } from '~/data-provider';
|
||||||
|
|
||||||
|
import { cn } from '~/utils';
|
||||||
|
import {
|
||||||
|
Spinner,
|
||||||
|
Tooltip,
|
||||||
|
TooltipContent,
|
||||||
|
TooltipProvider,
|
||||||
|
TooltipTrigger,
|
||||||
|
TrashIcon,
|
||||||
|
} from '~/components';
|
||||||
|
import { SharedLinksResponse, TSharedLink } from 'librechat-data-provider';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
function SharedLinkDeleteButton({
|
||||||
|
shareId,
|
||||||
|
setIsDeleting,
|
||||||
|
}: {
|
||||||
|
shareId: string;
|
||||||
|
setIsDeleting: (isDeleting: boolean) => void;
|
||||||
|
}) {
|
||||||
|
const localize = useLocalize();
|
||||||
|
const mutation = useDeleteSharedLinkMutation();
|
||||||
|
|
||||||
|
const handleDelete = async (e: MouseEvent<HTMLButtonElement>) => {
|
||||||
|
e.preventDefault();
|
||||||
|
if (mutation.isLoading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setIsDeleting(true);
|
||||||
|
await mutation.mutateAsync({ shareId });
|
||||||
|
setIsDeleting(false);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<TooltipProvider delayDuration={250}>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<span onClick={handleDelete}>
|
||||||
|
<TrashIcon />
|
||||||
|
</span>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent side="top" sideOffset={0}>
|
||||||
|
{localize('com_ui_delete')}
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
function SourceChatButton({ conversationId }: { conversationId: string }) {
|
||||||
|
const localize = useLocalize();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TooltipProvider delayDuration={250}>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<Link to={`/c/${conversationId}`} target="_blank" rel="noreferrer">
|
||||||
|
<MessageSquare className="h-4 w-4 hover:text-gray-300" />
|
||||||
|
</Link>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent side="top" sideOffset={0}>
|
||||||
|
{localize('com_nav_source_chat')}
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ShareLinkRow({ sharedLink }: { sharedLink: TSharedLink }) {
|
||||||
|
const [isDeleting, setIsDeleting] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<tr
|
||||||
|
key={sharedLink.conversationId}
|
||||||
|
className="border-b border-gray-200 text-sm font-normal dark:border-white/10"
|
||||||
|
>
|
||||||
|
<td
|
||||||
|
className={cn(
|
||||||
|
'flex items-center py-3 text-blue-800/70 dark:text-blue-500',
|
||||||
|
isDeleting && 'opacity-50',
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<Link to={`/share/${sharedLink.shareId}`} target="_blank" rel="noreferrer" className="flex">
|
||||||
|
<LinkIcon className="mr-1 h-5 w-5" />
|
||||||
|
{sharedLink.title}
|
||||||
|
</Link>
|
||||||
|
</td>
|
||||||
|
<td className="p-3">
|
||||||
|
<div className="flex justify-between">
|
||||||
|
<div className={cn('flex justify-start dark:text-gray-200', isDeleting && 'opacity-50')}>
|
||||||
|
{new Date(sharedLink.createdAt).toLocaleDateString('en-US', {
|
||||||
|
month: 'long',
|
||||||
|
day: 'numeric',
|
||||||
|
year: 'numeric',
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
'flex items-center justify-end gap-3 text-gray-400',
|
||||||
|
isDeleting && 'opacity-50',
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{sharedLink.conversationId && (
|
||||||
|
<>
|
||||||
|
<SourceChatButton conversationId={sharedLink.conversationId} />
|
||||||
|
<div className={cn('h-4 w-4 cursor-pointer', !isDeleting && 'hover:text-gray-300')}>
|
||||||
|
<SharedLinkDeleteButton
|
||||||
|
shareId={sharedLink.shareId}
|
||||||
|
setIsDeleting={setIsDeleting}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default function ShareLinkTable({ className }: { className?: string }) {
|
||||||
|
const localize = useLocalize();
|
||||||
|
const { isAuthenticated } = useAuthContext();
|
||||||
|
const [showLoading, setShowLoading] = useState(false);
|
||||||
|
|
||||||
|
const { data, fetchNextPage, hasNextPage, isFetchingNextPage } = useSharedLinksInfiniteQuery(
|
||||||
|
{ pageNumber: '1', isPublic: true },
|
||||||
|
{ enabled: isAuthenticated },
|
||||||
|
);
|
||||||
|
|
||||||
|
const { containerRef } = useNavScrolling<SharedLinksResponse>({
|
||||||
|
setShowLoading,
|
||||||
|
hasNextPage: hasNextPage,
|
||||||
|
fetchNextPage: fetchNextPage,
|
||||||
|
isFetchingNextPage: isFetchingNextPage,
|
||||||
|
});
|
||||||
|
|
||||||
|
const sharedLinks = useMemo(() => data?.pages.flatMap((page) => page.sharedLinks) || [], [data]);
|
||||||
|
const classProp: { className?: string } = {
|
||||||
|
className: 'p-1 hover:text-black dark:hover:text-white',
|
||||||
|
};
|
||||||
|
if (className) {
|
||||||
|
classProp.className = className;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sharedLinks || sharedLinks.length === 0) {
|
||||||
|
return <div className="text-gray-300">{localize('com_nav_shared_links_empty')}</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
'grid w-full gap-2',
|
||||||
|
'-mr-2 flex-1 flex-col overflow-y-auto pr-2 transition-opacity duration-500',
|
||||||
|
'max-h-[350px]',
|
||||||
|
)}
|
||||||
|
ref={containerRef}
|
||||||
|
>
|
||||||
|
<table className="table-fixed text-left">
|
||||||
|
<thead className="sticky top-0 bg-white dark:bg-gray-700">
|
||||||
|
<tr className="border-b border-gray-200 text-sm font-semibold text-gray-500 dark:border-white/10 dark:text-gray-200">
|
||||||
|
<th className="p-3">{localize('com_nav_shared_links_name')}</th>
|
||||||
|
<th className="p-3">{localize('com_nav_shared_links_date_shared')}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{sharedLinks.map((sharedLink) => (
|
||||||
|
<ShareLinkRow key={sharedLink.shareId} sharedLink={sharedLink} />
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{(isFetchingNextPage || showLoading) && (
|
||||||
|
<Spinner className={cn('m-1 mx-auto mb-4 h-4 w-4 text-black dark:text-white')} />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
29
client/src/components/Nav/SettingsTabs/Data/SharedLinks.tsx
Normal file
29
client/src/components/Nav/SettingsTabs/Data/SharedLinks.tsx
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
import { useLocalize } from '~/hooks';
|
||||||
|
import { Dialog, DialogTrigger } from '~/components/ui';
|
||||||
|
import DialogTemplate from '~/components/ui/DialogTemplate';
|
||||||
|
|
||||||
|
import ShareLinkTable from './SharedLinkTable';
|
||||||
|
|
||||||
|
export default function SharedLinks() {
|
||||||
|
const localize = useLocalize();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div> {localize('com_nav_shared_links')} </div>
|
||||||
|
|
||||||
|
<Dialog>
|
||||||
|
<DialogTrigger asChild>
|
||||||
|
<button className="btn btn-neutral relative ">
|
||||||
|
{localize('com_nav_shared_links_manage')}
|
||||||
|
</button>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogTemplate
|
||||||
|
title={localize('com_nav_shared_links')}
|
||||||
|
className="max-w-[1000px]"
|
||||||
|
showCancelButton={false}
|
||||||
|
main={<ShareLinkTable />}
|
||||||
|
/>
|
||||||
|
</Dialog>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -6,6 +6,7 @@ import ArchiveButton from '~/components/Conversations/ArchiveButton';
|
||||||
import DeleteButton from '~/components/Conversations/DeleteButton';
|
import DeleteButton from '~/components/Conversations/DeleteButton';
|
||||||
import { Spinner } from '~/components/svg';
|
import { Spinner } from '~/components/svg';
|
||||||
import { cn } from '~/utils';
|
import { cn } from '~/utils';
|
||||||
|
import { ConversationListResponse } from 'librechat-data-provider';
|
||||||
|
|
||||||
export default function ArchivedChatsTable({ className }: { className?: string }) {
|
export default function ArchivedChatsTable({ className }: { className?: string }) {
|
||||||
const localize = useLocalize();
|
const localize = useLocalize();
|
||||||
|
|
@ -17,7 +18,7 @@ export default function ArchivedChatsTable({ className }: { className?: string }
|
||||||
{ enabled: isAuthenticated },
|
{ enabled: isAuthenticated },
|
||||||
);
|
);
|
||||||
|
|
||||||
const { containerRef, moveToTop } = useNavScrolling({
|
const { containerRef, moveToTop } = useNavScrolling<ConversationListResponse>({
|
||||||
setShowLoading,
|
setShowLoading,
|
||||||
hasNextPage: hasNextPage,
|
hasNextPage: hasNextPage,
|
||||||
fetchNextPage: fetchNextPage,
|
fetchNextPage: fetchNextPage,
|
||||||
|
|
|
||||||
100
client/src/components/Share/Message.tsx
Normal file
100
client/src/components/Share/Message.tsx
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
import type { TMessageProps } from '~/common';
|
||||||
|
import MinimalHoverButtons from '~/components/Chat/Messages/MinimalHoverButtons';
|
||||||
|
import MessageContent from '~/components/Chat/Messages/Content/MessageContent';
|
||||||
|
import SearchContent from '~/components/Chat/Messages/Content/SearchContent';
|
||||||
|
import SiblingSwitch from '~/components/Chat/Messages/SiblingSwitch';
|
||||||
|
import { Plugin } from '~/components/Messages/Content';
|
||||||
|
import SubRow from '~/components/Chat/Messages/SubRow';
|
||||||
|
// eslint-disable-next-line import/no-cycle
|
||||||
|
import MultiMessage from './MultiMessage';
|
||||||
|
import { cn } from '~/utils';
|
||||||
|
|
||||||
|
import Icon from './MessageIcon';
|
||||||
|
export default function Message(props: TMessageProps) {
|
||||||
|
const {
|
||||||
|
message,
|
||||||
|
siblingIdx,
|
||||||
|
siblingCount,
|
||||||
|
conversation,
|
||||||
|
setSiblingIdx,
|
||||||
|
currentEditId,
|
||||||
|
setCurrentEditId,
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
if (!message) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { text, children, messageId = null, isCreatedByUser, error, unfinished } = message ?? {};
|
||||||
|
|
||||||
|
let messageLabel = '';
|
||||||
|
if (isCreatedByUser) {
|
||||||
|
messageLabel = 'anonymous';
|
||||||
|
} else {
|
||||||
|
messageLabel = message.sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="text-token-text-primary w-full border-0 bg-transparent dark:border-0 dark:bg-transparent">
|
||||||
|
<div className="m-auto justify-center p-4 py-2 text-base md:gap-6 ">
|
||||||
|
<div className="final-completion group mx-auto flex flex-1 gap-3 text-base md:max-w-3xl md:px-5 lg:max-w-[40rem] lg:px-1 xl:max-w-[48rem] xl:px-5">
|
||||||
|
<div className="relative flex flex-shrink-0 flex-col items-end">
|
||||||
|
<div>
|
||||||
|
<div className="pt-0.5">
|
||||||
|
<div className="flex h-6 w-6 items-center justify-center overflow-hidden rounded-full">
|
||||||
|
<Icon message={message} conversation={conversation} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={cn('relative flex w-11/12 flex-col', isCreatedByUser ? '' : 'agent-turn')}
|
||||||
|
>
|
||||||
|
<div className="select-none font-semibold">{messageLabel}</div>
|
||||||
|
<div className="flex-col gap-1 md:gap-3">
|
||||||
|
<div className="flex max-w-full flex-grow flex-col gap-0">
|
||||||
|
{/* Legacy Plugins */}
|
||||||
|
{message?.plugin && <Plugin plugin={message?.plugin} />}
|
||||||
|
{message?.content ? (
|
||||||
|
<SearchContent message={message} />
|
||||||
|
) : (
|
||||||
|
<MessageContent
|
||||||
|
edit={false}
|
||||||
|
error={error}
|
||||||
|
isLast={false}
|
||||||
|
ask={() => ({})}
|
||||||
|
text={text ?? ''}
|
||||||
|
message={message}
|
||||||
|
isSubmitting={false}
|
||||||
|
enterEdit={() => ({})}
|
||||||
|
unfinished={!!unfinished}
|
||||||
|
isCreatedByUser={isCreatedByUser ?? true}
|
||||||
|
siblingIdx={siblingIdx ?? 0}
|
||||||
|
setSiblingIdx={setSiblingIdx ?? (() => ({}))}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<SubRow classes="text-xs">
|
||||||
|
<SiblingSwitch
|
||||||
|
siblingIdx={siblingIdx}
|
||||||
|
siblingCount={siblingCount}
|
||||||
|
setSiblingIdx={setSiblingIdx}
|
||||||
|
/>
|
||||||
|
<MinimalHoverButtons message={message} />
|
||||||
|
</SubRow>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<MultiMessage
|
||||||
|
key={messageId}
|
||||||
|
messageId={messageId}
|
||||||
|
messagesTree={children ?? []}
|
||||||
|
currentEditId={currentEditId}
|
||||||
|
setCurrentEditId={setCurrentEditId}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
71
client/src/components/Share/MessageIcon.tsx
Normal file
71
client/src/components/Share/MessageIcon.tsx
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
import type { TMessage, TPreset, Assistant } from 'librechat-data-provider';
|
||||||
|
import type { TMessageProps } from '~/common';
|
||||||
|
import MessageEndpointIcon from '../Endpoints/MessageEndpointIcon';
|
||||||
|
import ConvoIconURL from '~/components/Endpoints/ConvoIconURL';
|
||||||
|
import { getIconEndpoint } from '~/utils';
|
||||||
|
import { UserIcon } from '../svg';
|
||||||
|
|
||||||
|
export default function MessageIcon(
|
||||||
|
props: Pick<TMessageProps, 'message' | 'conversation'> & {
|
||||||
|
assistant?: false | Assistant;
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
const { message, conversation, assistant } = props;
|
||||||
|
|
||||||
|
const assistantName = assistant ? (assistant.name as string | undefined) : '';
|
||||||
|
const assistantAvatar = assistant ? (assistant.metadata?.avatar as string | undefined) : '';
|
||||||
|
|
||||||
|
const messageSettings = useMemo(
|
||||||
|
() => ({
|
||||||
|
...(conversation ?? {}),
|
||||||
|
...({
|
||||||
|
...message,
|
||||||
|
iconURL: message?.iconURL ?? '',
|
||||||
|
} as TMessage),
|
||||||
|
}),
|
||||||
|
[conversation, message],
|
||||||
|
);
|
||||||
|
|
||||||
|
const iconURL = messageSettings?.iconURL;
|
||||||
|
let endpoint = messageSettings?.endpoint;
|
||||||
|
endpoint = getIconEndpoint({ endpointsConfig: undefined, iconURL, endpoint });
|
||||||
|
|
||||||
|
if (!message?.isCreatedByUser && iconURL && iconURL.includes('http')) {
|
||||||
|
return (
|
||||||
|
<ConvoIconURL
|
||||||
|
preset={messageSettings as typeof messageSettings & TPreset}
|
||||||
|
context="message"
|
||||||
|
assistantAvatar={assistantAvatar}
|
||||||
|
assistantName={assistantName}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message?.isCreatedByUser) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
backgroundColor: 'rgb(121, 137, 255)',
|
||||||
|
width: '20px',
|
||||||
|
height: '20px',
|
||||||
|
boxShadow: 'rgba(240, 246, 252, 0.1) 0px 0px 0px 1px',
|
||||||
|
}}
|
||||||
|
className="relative flex h-9 w-9 items-center justify-center rounded-sm p-1 text-white"
|
||||||
|
>
|
||||||
|
<UserIcon />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MessageEndpointIcon
|
||||||
|
{...messageSettings}
|
||||||
|
endpoint={endpoint}
|
||||||
|
iconURL={!assistant ? undefined : assistantAvatar}
|
||||||
|
model={message?.model ?? conversation?.model}
|
||||||
|
assistantName={assistantName}
|
||||||
|
size={28.8}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
47
client/src/components/Share/MessagesView.tsx
Normal file
47
client/src/components/Share/MessagesView.tsx
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
import { useState } from 'react';
|
||||||
|
import type { TMessage } from 'librechat-data-provider';
|
||||||
|
import MultiMessage from './MultiMessage';
|
||||||
|
|
||||||
|
export default function MessagesView({
|
||||||
|
messagesTree: _messagesTree,
|
||||||
|
conversationId,
|
||||||
|
}: {
|
||||||
|
messagesTree?: TMessage[] | null;
|
||||||
|
conversationId: string;
|
||||||
|
}) {
|
||||||
|
const [currentEditId, setCurrentEditId] = useState<number | string | null>(-1);
|
||||||
|
return (
|
||||||
|
<div className="flex-1 pb-[50px]">
|
||||||
|
<div className="dark:gpt-dark-gray relative h-full">
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: '100%',
|
||||||
|
overflowY: 'auto',
|
||||||
|
width: '100%',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="flex flex-col pb-9 text-sm dark:bg-transparent">
|
||||||
|
{(_messagesTree && _messagesTree?.length == 0) || _messagesTree === null ? (
|
||||||
|
<div className="flex w-full items-center justify-center gap-1 bg-gray-50 p-3 text-sm text-gray-500 dark:border-gray-800/50 dark:bg-gray-800 dark:text-gray-300">
|
||||||
|
Nothing found
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<div>
|
||||||
|
<MultiMessage
|
||||||
|
key={conversationId} // avoid internal state mixture
|
||||||
|
messagesTree={_messagesTree}
|
||||||
|
messageId={conversationId ?? null}
|
||||||
|
setCurrentEditId={setCurrentEditId}
|
||||||
|
currentEditId={currentEditId ?? null}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
<div className="dark:gpt-dark-gray group h-0 w-full flex-shrink-0 dark:border-gray-800/50" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
54
client/src/components/Share/MultiMessage.tsx
Normal file
54
client/src/components/Share/MultiMessage.tsx
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useRecoilState } from 'recoil';
|
||||||
|
import type { TMessageProps } from '~/common';
|
||||||
|
// eslint-disable-next-line import/no-cycle
|
||||||
|
import Message from './Message';
|
||||||
|
import store from '~/store';
|
||||||
|
|
||||||
|
export default function MultiMessage({
|
||||||
|
// messageId is used recursively here
|
||||||
|
messageId,
|
||||||
|
messagesTree,
|
||||||
|
currentEditId,
|
||||||
|
setCurrentEditId,
|
||||||
|
}: TMessageProps) {
|
||||||
|
const [siblingIdx, setSiblingIdx] = useRecoilState(store.messagesSiblingIdxFamily(messageId));
|
||||||
|
|
||||||
|
const setSiblingIdxRev = (value: number) => {
|
||||||
|
setSiblingIdx((messagesTree?.length ?? 0) - value - 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// reset siblingIdx when the tree changes, mostly when a new message is submitting.
|
||||||
|
setSiblingIdx(0);
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [messagesTree?.length]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (messagesTree?.length && siblingIdx >= messagesTree?.length) {
|
||||||
|
setSiblingIdx(0);
|
||||||
|
}
|
||||||
|
}, [siblingIdx, messagesTree?.length, setSiblingIdx]);
|
||||||
|
|
||||||
|
if (!(messagesTree && messagesTree?.length)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const message = messagesTree[messagesTree.length - siblingIdx - 1];
|
||||||
|
|
||||||
|
if (!message) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Message
|
||||||
|
key={message.messageId}
|
||||||
|
message={message}
|
||||||
|
currentEditId={currentEditId}
|
||||||
|
setCurrentEditId={setCurrentEditId}
|
||||||
|
siblingIdx={messagesTree.length - siblingIdx - 1}
|
||||||
|
siblingCount={messagesTree.length}
|
||||||
|
setSiblingIdx={setSiblingIdxRev}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
60
client/src/components/Share/ShareView.tsx
Normal file
60
client/src/components/Share/ShareView.tsx
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
import { memo } from 'react';
|
||||||
|
import { useParams } from 'react-router-dom';
|
||||||
|
import { useGetSharedMessages } from 'librechat-data-provider/react-query';
|
||||||
|
import { ShareContext } from '~/Providers';
|
||||||
|
import { Spinner } from '~/components/svg';
|
||||||
|
import MessagesView from './MessagesView';
|
||||||
|
import { useLocalize } from '~/hooks';
|
||||||
|
import { buildTree } from '~/utils';
|
||||||
|
import Footer from '../Chat/Footer';
|
||||||
|
|
||||||
|
function SharedView() {
|
||||||
|
const localize = useLocalize();
|
||||||
|
const { shareId } = useParams();
|
||||||
|
const { data, isLoading } = useGetSharedMessages(shareId ?? '');
|
||||||
|
const dataTree = data && buildTree({ messages: data.messages });
|
||||||
|
const messagesTree = dataTree?.length === 0 ? null : dataTree ?? null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ShareContext.Provider value={{ isSharedConvo: true }}>
|
||||||
|
<div
|
||||||
|
className="relative flex w-full grow overflow-hidden bg-white dark:bg-gray-800"
|
||||||
|
style={{ paddingBottom: '50px' }}
|
||||||
|
>
|
||||||
|
<div className="transition-width relative flex h-full w-full flex-1 flex-col items-stretch overflow-hidden bg-white pt-0 dark:bg-gray-800">
|
||||||
|
<div className="flex h-full flex-col" role="presentation" tabIndex={0}>
|
||||||
|
{isLoading ? (
|
||||||
|
<div className="flex h-screen items-center justify-center">
|
||||||
|
<Spinner className="" />
|
||||||
|
</div>
|
||||||
|
) : data && messagesTree && messagesTree.length !== 0 ? (
|
||||||
|
<>
|
||||||
|
<div className="final-completion group mx-auto flex min-w-[40rem] flex-col gap-3 pb-6 pt-4 md:max-w-3xl md:px-5 lg:max-w-[40rem] lg:px-1 xl:max-w-[48rem] xl:px-5">
|
||||||
|
<h1 className="text-4xl font-bold dark:text-white">{data.title}</h1>
|
||||||
|
<div className="border-b pb-6 text-base text-gray-300">
|
||||||
|
{new Date(data.createdAt).toLocaleDateString('en-US', {
|
||||||
|
month: 'long',
|
||||||
|
day: 'numeric',
|
||||||
|
year: 'numeric',
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<MessagesView messagesTree={messagesTree} conversationId={data.conversationId} />
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<div className="flex h-screen items-center justify-center">
|
||||||
|
{localize('com_ui_shared_link_not_found')}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="w-full border-t-0 pl-0 pt-2 dark:border-white/20 md:w-[calc(100%-.5rem)] md:border-t-0 md:border-transparent md:pl-0 md:pt-0 md:dark:border-transparent">
|
||||||
|
<Footer className="fixed bottom-0 left-0 right-0 z-50 flex items-center justify-center gap-2 bg-gradient-to-t from-gray-50 to-transparent px-2 pb-2 pt-8 text-xs text-gray-600 dark:from-gray-800 dark:text-gray-300 md:px-[60px]" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ShareContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default memo(SharedView);
|
||||||
|
|
@ -7,6 +7,8 @@ import {
|
||||||
updateConversation,
|
updateConversation,
|
||||||
deleteConversation,
|
deleteConversation,
|
||||||
updateConvoFields,
|
updateConvoFields,
|
||||||
|
deleteSharedLink,
|
||||||
|
addSharedLink,
|
||||||
} from '~/utils';
|
} from '~/utils';
|
||||||
import { dataService, MutationKeys, QueryKeys, defaultOrderQuery } from 'librechat-data-provider';
|
import { dataService, MutationKeys, QueryKeys, defaultOrderQuery } from 'librechat-data-provider';
|
||||||
import { useSetRecoilState } from 'recoil';
|
import { useSetRecoilState } from 'recoil';
|
||||||
|
|
@ -117,6 +119,96 @@ export const useArchiveConversationMutation = (
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useCreateSharedLinkMutation = (
|
||||||
|
options?: t.CreateSharedLinkOptions,
|
||||||
|
): UseMutationResult<t.TSharedLinkResponse, unknown, t.TSharedLinkRequest, unknown> => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const { onSuccess, ..._options } = options || {};
|
||||||
|
return useMutation((payload: t.TSharedLinkRequest) => dataService.createSharedLink(payload), {
|
||||||
|
onSuccess: (_data, vars, context) => {
|
||||||
|
if (!vars.conversationId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
queryClient.setQueryData<t.SharedLinkListData>([QueryKeys.sharedLinks], (sharedLink) => {
|
||||||
|
if (!sharedLink) {
|
||||||
|
return sharedLink;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the shared link is public, add it to the shared links cache list
|
||||||
|
if (vars.isPublic) {
|
||||||
|
return addSharedLink(sharedLink, _data);
|
||||||
|
} else {
|
||||||
|
return deleteSharedLink(sharedLink, _data.shareId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
queryClient.setQueryData([QueryKeys.sharedLinks, _data.shareId], _data);
|
||||||
|
|
||||||
|
onSuccess?.(_data, vars, context);
|
||||||
|
},
|
||||||
|
...(_options || {}),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useUpdateSharedLinkMutation = (
|
||||||
|
options?: t.UpdateSharedLinkOptions,
|
||||||
|
): UseMutationResult<t.TSharedLinkResponse, unknown, t.TSharedLinkRequest, unknown> => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const { onSuccess, ..._options } = options || {};
|
||||||
|
return useMutation((payload: t.TSharedLinkRequest) => dataService.updateSharedLink(payload), {
|
||||||
|
onSuccess: (_data, vars, context) => {
|
||||||
|
if (!vars.conversationId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
queryClient.setQueryData<t.SharedLinkListData>([QueryKeys.sharedLinks], (sharedLink) => {
|
||||||
|
if (!sharedLink) {
|
||||||
|
return sharedLink;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the shared link is public, add it to the shared links cache list.
|
||||||
|
if (vars.isPublic) {
|
||||||
|
// Even if the SharedLink data exists in the database, it is not registered in the cache when isPublic is false.
|
||||||
|
// Therefore, when isPublic is true, use addSharedLink instead of updateSharedLink.
|
||||||
|
return addSharedLink(sharedLink, _data);
|
||||||
|
} else {
|
||||||
|
return deleteSharedLink(sharedLink, _data.shareId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
queryClient.setQueryData([QueryKeys.sharedLinks, _data.shareId], _data);
|
||||||
|
|
||||||
|
onSuccess?.(_data, vars, context);
|
||||||
|
},
|
||||||
|
...(_options || {}),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useDeleteSharedLinkMutation = (
|
||||||
|
options?: t.DeleteSharedLinkOptions,
|
||||||
|
): UseMutationResult<t.TDeleteSharedLinkResponse, unknown, { shareId: string }, unknown> => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const { onSuccess, ..._options } = options || {};
|
||||||
|
return useMutation(({ shareId }) => dataService.deleteSharedLink(shareId), {
|
||||||
|
onSuccess: (_data, vars, context) => {
|
||||||
|
if (!vars.shareId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
queryClient.setQueryData([QueryKeys.sharedMessages, vars.shareId], null);
|
||||||
|
queryClient.setQueryData<t.SharedLinkListData>([QueryKeys.sharedLinks], (data) => {
|
||||||
|
if (!data) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
return deleteSharedLink(data, vars.shareId);
|
||||||
|
});
|
||||||
|
onSuccess?.(_data, vars, context);
|
||||||
|
},
|
||||||
|
...(_options || {}),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export const useDeleteConversationMutation = (
|
export const useDeleteConversationMutation = (
|
||||||
options?: t.DeleteConversationOptions,
|
options?: t.DeleteConversationOptions,
|
||||||
): UseMutationResult<
|
): UseMutationResult<
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@ import type {
|
||||||
AssistantDocument,
|
AssistantDocument,
|
||||||
TEndpointsConfig,
|
TEndpointsConfig,
|
||||||
TCheckUserKeyResponse,
|
TCheckUserKeyResponse,
|
||||||
|
SharedLinkListParams,
|
||||||
|
SharedLinksResponse,
|
||||||
} from 'librechat-data-provider';
|
} from 'librechat-data-provider';
|
||||||
import { findPageForConversation, addFileToCache } from '~/utils';
|
import { findPageForConversation, addFileToCache } from '~/utils';
|
||||||
|
|
||||||
|
|
@ -92,10 +94,10 @@ export const useGetConvoIdQuery = (
|
||||||
return defaultQuery();
|
return defaultQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
const { pageIndex, convIndex } = findPageForConversation(convosQuery, { conversationId: id });
|
const { pageIndex, index } = findPageForConversation(convosQuery, { conversationId: id });
|
||||||
|
|
||||||
if (pageIndex > -1 && convIndex > -1) {
|
if (pageIndex > -1 && index > -1) {
|
||||||
return convosQuery.pages[pageIndex].conversations[convIndex];
|
return convosQuery.pages[pageIndex].conversations[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
return defaultQuery();
|
return defaultQuery();
|
||||||
|
|
@ -158,6 +160,33 @@ export const useConversationsInfiniteQuery = (
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useSharedLinksInfiniteQuery = (
|
||||||
|
params?: SharedLinkListParams,
|
||||||
|
config?: UseInfiniteQueryOptions<SharedLinksResponse, unknown>,
|
||||||
|
) => {
|
||||||
|
return useInfiniteQuery<SharedLinksResponse, unknown>(
|
||||||
|
[QueryKeys.sharedLinks],
|
||||||
|
({ pageParam = '' }) =>
|
||||||
|
dataService.listSharedLinks({
|
||||||
|
...params,
|
||||||
|
pageNumber: pageParam?.toString(),
|
||||||
|
isPublic: params?.isPublic || true,
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
getNextPageParam: (lastPage) => {
|
||||||
|
const currentPageNumber = Number(lastPage.pageNumber);
|
||||||
|
const totalPages = Number(lastPage.pages); // Convert totalPages to a number
|
||||||
|
// If the current page number is less than total pages, return the next page number
|
||||||
|
return currentPageNumber < totalPages ? currentPageNumber + 1 : undefined;
|
||||||
|
},
|
||||||
|
refetchOnWindowFocus: false,
|
||||||
|
refetchOnReconnect: false,
|
||||||
|
refetchOnMount: false,
|
||||||
|
...config,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ASSISTANTS
|
* ASSISTANTS
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
export { default as useAvatar } from './useAvatar';
|
export { default as useAvatar } from './useAvatar';
|
||||||
export { default as useProgress } from './useProgress';
|
export { default as useProgress } from './useProgress';
|
||||||
export { default as useMessageHelpers } from './useMessageHelpers';
|
export { default as useMessageHelpers } from './useMessageHelpers';
|
||||||
|
export { default as useCopyToClipboard } from './useCopyToClipboard';
|
||||||
export { default as useMessageScrolling } from './useMessageScrolling';
|
export { default as useMessageScrolling } from './useMessageScrolling';
|
||||||
|
|
|
||||||
32
client/src/hooks/Messages/useCopyToClipboard.ts
Normal file
32
client/src/hooks/Messages/useCopyToClipboard.ts
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
import copy from 'copy-to-clipboard';
|
||||||
|
import { ContentTypes } from 'librechat-data-provider';
|
||||||
|
import type { TMessage } from 'librechat-data-provider';
|
||||||
|
|
||||||
|
export default function useCopyToClipboard({
|
||||||
|
text,
|
||||||
|
content,
|
||||||
|
}: Partial<Pick<TMessage, 'text' | 'content'>>) {
|
||||||
|
const copyToClipboard = useCallback(
|
||||||
|
(setIsCopied: React.Dispatch<React.SetStateAction<boolean>>) => {
|
||||||
|
setIsCopied(true);
|
||||||
|
let messageText = text ?? '';
|
||||||
|
if (content) {
|
||||||
|
messageText = content.reduce((acc, curr, i) => {
|
||||||
|
if (curr.type === ContentTypes.TEXT) {
|
||||||
|
return acc + curr.text.value + (i === content.length - 1 ? '' : '\n');
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, '');
|
||||||
|
}
|
||||||
|
copy(messageText ?? '');
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsCopied(false);
|
||||||
|
}, 3000);
|
||||||
|
},
|
||||||
|
[text, content],
|
||||||
|
);
|
||||||
|
|
||||||
|
return copyToClipboard;
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import copy from 'copy-to-clipboard';
|
|
||||||
import { useEffect, useRef, useCallback } from 'react';
|
import { useEffect, useRef, useCallback } from 'react';
|
||||||
import { EModelEndpoint, ContentTypes } from 'librechat-data-provider';
|
import { EModelEndpoint } from 'librechat-data-provider';
|
||||||
import type { TMessageProps } from '~/common';
|
import type { TMessageProps } from '~/common';
|
||||||
import { useChatContext, useAssistantsMapContext } from '~/Providers';
|
import { useChatContext, useAssistantsMapContext } from '~/Providers';
|
||||||
|
import useCopyToClipboard from './useCopyToClipboard';
|
||||||
|
|
||||||
export default function useMessageHelpers(props: TMessageProps) {
|
export default function useMessageHelpers(props: TMessageProps) {
|
||||||
const latestText = useRef<string | number>('');
|
const latestText = useRef<string | number>('');
|
||||||
|
|
@ -65,26 +65,7 @@ export default function useMessageHelpers(props: TMessageProps) {
|
||||||
regenerate(message);
|
regenerate(message);
|
||||||
};
|
};
|
||||||
|
|
||||||
const copyToClipboard = useCallback(
|
const copyToClipboard = useCopyToClipboard({ text, content });
|
||||||
(setIsCopied: React.Dispatch<React.SetStateAction<boolean>>) => {
|
|
||||||
setIsCopied(true);
|
|
||||||
let messageText = text ?? '';
|
|
||||||
if (content) {
|
|
||||||
messageText = content.reduce((acc, curr, i) => {
|
|
||||||
if (curr.type === ContentTypes.TEXT) {
|
|
||||||
return acc + curr.text.value + (i === content.length - 1 ? '' : '\n');
|
|
||||||
}
|
|
||||||
return acc;
|
|
||||||
}, '');
|
|
||||||
}
|
|
||||||
copy(messageText ?? '');
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
setIsCopied(false);
|
|
||||||
}, 3000);
|
|
||||||
},
|
|
||||||
[text, content],
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ask,
|
ask,
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import React, { useCallback, useEffect, useRef } from 'react';
|
||||||
import type { FetchNextPageOptions, InfiniteQueryObserverResult } from '@tanstack/react-query';
|
import type { FetchNextPageOptions, InfiniteQueryObserverResult } from '@tanstack/react-query';
|
||||||
import type { ConversationListResponse } from 'librechat-data-provider';
|
import type { ConversationListResponse } from 'librechat-data-provider';
|
||||||
|
|
||||||
export default function useNavScrolling({
|
export default function useNavScrolling<TData>({
|
||||||
hasNextPage,
|
hasNextPage,
|
||||||
isFetchingNextPage,
|
isFetchingNextPage,
|
||||||
setShowLoading,
|
setShowLoading,
|
||||||
|
|
@ -14,7 +14,7 @@ export default function useNavScrolling({
|
||||||
setShowLoading: React.Dispatch<React.SetStateAction<boolean>>;
|
setShowLoading: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
fetchNextPage: (
|
fetchNextPage: (
|
||||||
options?: FetchNextPageOptions | undefined,
|
options?: FetchNextPageOptions | undefined,
|
||||||
) => Promise<InfiniteQueryObserverResult<ConversationListResponse, unknown>>;
|
) => Promise<InfiniteQueryObserverResult<TData, unknown>>;
|
||||||
}) {
|
}) {
|
||||||
const scrollPositionRef = useRef<number | null>(null);
|
const scrollPositionRef = useRef<number | null>(null);
|
||||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,17 @@ export default {
|
||||||
com_ui_import_conversation_error: 'حدث خطأ أثناء استيراد محادثاتك',
|
com_ui_import_conversation_error: 'حدث خطأ أثناء استيراد محادثاتك',
|
||||||
com_ui_confirm_action: 'تأكيد الإجراء',
|
com_ui_confirm_action: 'تأكيد الإجراء',
|
||||||
com_ui_chats: 'الدردشات',
|
com_ui_chats: 'الدردشات',
|
||||||
|
com_ui_share: 'Share',
|
||||||
|
com_ui_share_link_to_chat: 'Share link to chat',
|
||||||
|
com_ui_share_error: 'There was an error sharing the chat link',
|
||||||
|
com_ui_share_create_message: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_created_message:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_share_update_message:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_updated_message:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_shared_link_not_found: 'Shared link not found',
|
||||||
com_ui_delete: 'حذف',
|
com_ui_delete: 'حذف',
|
||||||
com_ui_delete_conversation: 'حذف الدردشة؟',
|
com_ui_delete_conversation: 'حذف الدردشة؟',
|
||||||
com_ui_delete_conversation_confirm: 'سيتم حذف هذا',
|
com_ui_delete_conversation_confirm: 'سيتم حذف هذا',
|
||||||
|
|
@ -254,6 +265,12 @@ export default {
|
||||||
com_nav_export_recursive_or_sequential: 'التراجع أو التسلسل؟',
|
com_nav_export_recursive_or_sequential: 'التراجع أو التسلسل؟',
|
||||||
com_nav_export_recursive: 'تكراري',
|
com_nav_export_recursive: 'تكراري',
|
||||||
com_nav_export_conversation: 'تصدير المحادثة',
|
com_nav_export_conversation: 'تصدير المحادثة',
|
||||||
|
com_nav_export: 'تصدير',
|
||||||
|
com_nav_shared_links: 'روابط مشتركة',
|
||||||
|
com_nav_shared_links_manage: 'الإدارة',
|
||||||
|
com_nav_shared_links_empty: 'ليس لديك أي روابط مشتركة.',
|
||||||
|
com_nav_shared_links_name: 'الاسم',
|
||||||
|
com_nav_shared_links_date_shared: 'تاريخ المشترك',
|
||||||
com_nav_theme: 'المظهر',
|
com_nav_theme: 'المظهر',
|
||||||
com_nav_theme_system: 'النظام',
|
com_nav_theme_system: 'النظام',
|
||||||
com_nav_theme_dark: 'داكن',
|
com_nav_theme_dark: 'داكن',
|
||||||
|
|
@ -280,6 +297,12 @@ export default {
|
||||||
com_nav_setting_general: 'عام',
|
com_nav_setting_general: 'عام',
|
||||||
com_nav_setting_data: 'تحكم في البيانات',
|
com_nav_setting_data: 'تحكم في البيانات',
|
||||||
/* The following are AI translated */
|
/* The following are AI translated */
|
||||||
|
com_ui_copied: 'تم النسخ',
|
||||||
|
com_ui_copy_code: 'نسخ الكود',
|
||||||
|
com_ui_copy_link: 'نسخ الرابط',
|
||||||
|
com_ui_update_link: 'رابط التحديث',
|
||||||
|
com_ui_create_link: 'إنشاء رابط',
|
||||||
|
com_nav_source_chat: 'عرض محادثة المصدر',
|
||||||
com_ui_date_today: 'اليوم',
|
com_ui_date_today: 'اليوم',
|
||||||
com_ui_date_yesterday: 'أمس',
|
com_ui_date_yesterday: 'أمس',
|
||||||
com_ui_date_previous_7_days: 'الأيام السبعة السابقة',
|
com_ui_date_previous_7_days: 'الأيام السبعة السابقة',
|
||||||
|
|
@ -736,6 +759,43 @@ export const comparisons = {
|
||||||
english: 'chats',
|
english: 'chats',
|
||||||
translated: 'الدردشات',
|
translated: 'الدردشات',
|
||||||
},
|
},
|
||||||
|
com_ui_share: {
|
||||||
|
english: 'Share',
|
||||||
|
translated: 'Share',
|
||||||
|
},
|
||||||
|
com_ui_share_link_to_chat: {
|
||||||
|
english: 'Share link to chat',
|
||||||
|
translated: 'Share link to chat',
|
||||||
|
},
|
||||||
|
com_ui_share_error: {
|
||||||
|
english: 'There was an error sharing the chat link',
|
||||||
|
translated: 'There was an error sharing the chat link',
|
||||||
|
},
|
||||||
|
com_ui_share_create_message: {
|
||||||
|
english: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
translated: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_created_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_share_update_message: {
|
||||||
|
english: 'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
translated:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_updated_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_shared_link_not_found: {
|
||||||
|
english: 'Shared link not found',
|
||||||
|
translated: 'Shared link not found',
|
||||||
|
},
|
||||||
com_ui_delete: {
|
com_ui_delete: {
|
||||||
english: 'Delete',
|
english: 'Delete',
|
||||||
translated: 'حذف',
|
translated: 'حذف',
|
||||||
|
|
@ -1456,6 +1516,30 @@ export const comparisons = {
|
||||||
english: 'Export conversation',
|
english: 'Export conversation',
|
||||||
translated: 'تصدير المحادثة',
|
translated: 'تصدير المحادثة',
|
||||||
},
|
},
|
||||||
|
com_nav_export: {
|
||||||
|
english: 'Export',
|
||||||
|
translated: 'تصدير',
|
||||||
|
},
|
||||||
|
com_nav_shared_links: {
|
||||||
|
english: 'Shared links',
|
||||||
|
translated: 'روابط مشتركة',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_manage: {
|
||||||
|
english: 'Manage',
|
||||||
|
translated: 'الإدارة',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_empty: {
|
||||||
|
english: 'You have no shared links.',
|
||||||
|
translated: 'ليس لديك أي روابط مشتركة.',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_name: {
|
||||||
|
english: 'Name',
|
||||||
|
translated: 'الاسم',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_date_shared: {
|
||||||
|
english: 'Date shared',
|
||||||
|
translated: 'تاريخ المشترك',
|
||||||
|
},
|
||||||
com_nav_theme: {
|
com_nav_theme: {
|
||||||
english: 'Theme',
|
english: 'Theme',
|
||||||
translated: 'المظهر',
|
translated: 'المظهر',
|
||||||
|
|
@ -1552,6 +1636,30 @@ export const comparisons = {
|
||||||
english: 'Data controls',
|
english: 'Data controls',
|
||||||
translated: 'تحكم في البيانات',
|
translated: 'تحكم في البيانات',
|
||||||
},
|
},
|
||||||
|
com_ui_copied: {
|
||||||
|
english: 'Copied!',
|
||||||
|
translated: 'تم النسخ',
|
||||||
|
},
|
||||||
|
com_ui_copy_code: {
|
||||||
|
english: 'Copy code',
|
||||||
|
translated: 'نسخ الكود',
|
||||||
|
},
|
||||||
|
com_ui_copy_link: {
|
||||||
|
english: 'Copy link',
|
||||||
|
translated: 'نسخ الرابط',
|
||||||
|
},
|
||||||
|
com_ui_update_link: {
|
||||||
|
english: 'Update link',
|
||||||
|
translated: 'رابط التحديث',
|
||||||
|
},
|
||||||
|
com_ui_create_link: {
|
||||||
|
english: 'Create link',
|
||||||
|
translated: 'إنشاء رابط',
|
||||||
|
},
|
||||||
|
com_nav_source_chat: {
|
||||||
|
english: 'View source chat',
|
||||||
|
translated: 'عرض محادثة المصدر',
|
||||||
|
},
|
||||||
com_ui_date_today: {
|
com_ui_date_today: {
|
||||||
english: 'Today',
|
english: 'Today',
|
||||||
translated: 'اليوم',
|
translated: 'اليوم',
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,17 @@ export default {
|
||||||
com_ui_assistants_output: 'Saída dos Assistentes',
|
com_ui_assistants_output: 'Saída dos Assistentes',
|
||||||
com_ui_delete: 'Excluir',
|
com_ui_delete: 'Excluir',
|
||||||
com_ui_create: 'Criar',
|
com_ui_create: 'Criar',
|
||||||
|
com_ui_share: 'Share',
|
||||||
|
com_ui_share_link_to_chat: 'Share link to chat',
|
||||||
|
com_ui_share_error: 'There was an error sharing the chat link',
|
||||||
|
com_ui_share_create_message: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_created_message:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_share_update_message:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_updated_message:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_shared_link_not_found: 'Shared link not found',
|
||||||
com_ui_delete_conversation: 'Excluir conversa?',
|
com_ui_delete_conversation: 'Excluir conversa?',
|
||||||
com_ui_delete_conversation_confirm: 'Isso excluirá',
|
com_ui_delete_conversation_confirm: 'Isso excluirá',
|
||||||
com_ui_delete_assistant_confirm:
|
com_ui_delete_assistant_confirm:
|
||||||
|
|
@ -417,6 +428,12 @@ export default {
|
||||||
com_nav_export_recursive_or_sequential: 'Recursivo ou sequencial?',
|
com_nav_export_recursive_or_sequential: 'Recursivo ou sequencial?',
|
||||||
com_nav_export_recursive: 'Recursivo',
|
com_nav_export_recursive: 'Recursivo',
|
||||||
com_nav_export_conversation: 'Exportar conversa',
|
com_nav_export_conversation: 'Exportar conversa',
|
||||||
|
com_nav_export: 'Exportar',
|
||||||
|
com_nav_shared_links: 'Links Compartilhados',
|
||||||
|
com_nav_shared_links_manage: 'Gerenciar',
|
||||||
|
com_nav_shared_links_empty: 'Você não tem nenhum link compartilhado.',
|
||||||
|
com_nav_shared_links_name: 'Nome',
|
||||||
|
com_nav_shared_links_date_shared: 'Data compartilhada',
|
||||||
com_nav_my_files: 'Meus arquivos',
|
com_nav_my_files: 'Meus arquivos',
|
||||||
com_nav_theme: 'Tema',
|
com_nav_theme: 'Tema',
|
||||||
com_nav_theme_system: 'Sistema',
|
com_nav_theme_system: 'Sistema',
|
||||||
|
|
@ -963,6 +980,43 @@ export const comparisons = {
|
||||||
english: 'Create',
|
english: 'Create',
|
||||||
translated: 'Criar',
|
translated: 'Criar',
|
||||||
},
|
},
|
||||||
|
com_ui_share: {
|
||||||
|
english: 'Share',
|
||||||
|
translated: 'Share',
|
||||||
|
},
|
||||||
|
com_ui_share_link_to_chat: {
|
||||||
|
english: 'Share link to chat',
|
||||||
|
translated: 'Share link to chat',
|
||||||
|
},
|
||||||
|
com_ui_share_error: {
|
||||||
|
english: 'There was an error sharing the chat link',
|
||||||
|
translated: 'There was an error sharing the chat link',
|
||||||
|
},
|
||||||
|
com_ui_share_create_message: {
|
||||||
|
english: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
translated: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_created_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_share_update_message: {
|
||||||
|
english: 'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
translated:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_updated_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_shared_link_not_found: {
|
||||||
|
english: 'Shared link not found',
|
||||||
|
translated: 'Shared link not found',
|
||||||
|
},
|
||||||
com_ui_delete_conversation: {
|
com_ui_delete_conversation: {
|
||||||
english: 'Delete chat?',
|
english: 'Delete chat?',
|
||||||
translated: 'Excluir conversa?',
|
translated: 'Excluir conversa?',
|
||||||
|
|
@ -1951,6 +2005,30 @@ export const comparisons = {
|
||||||
english: 'Export conversation',
|
english: 'Export conversation',
|
||||||
translated: 'Exportar conversa',
|
translated: 'Exportar conversa',
|
||||||
},
|
},
|
||||||
|
com_nav_export: {
|
||||||
|
english: 'Export',
|
||||||
|
translated: 'Exportar',
|
||||||
|
},
|
||||||
|
com_nav_shared_links: {
|
||||||
|
english: 'Shared links',
|
||||||
|
translated: 'Links Compartilhados',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_manage: {
|
||||||
|
english: 'Manage',
|
||||||
|
translated: 'Gerenciar',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_empty: {
|
||||||
|
english: 'You have no shared links.',
|
||||||
|
translated: 'Você não tem nenhum link compartilhado.',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_name: {
|
||||||
|
english: 'Name',
|
||||||
|
translated: 'Nome',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_date_shared: {
|
||||||
|
english: 'Date shared',
|
||||||
|
translated: 'Data compartilhada',
|
||||||
|
},
|
||||||
com_nav_my_files: {
|
com_nav_my_files: {
|
||||||
english: 'My Files',
|
english: 'My Files',
|
||||||
translated: 'Meus arquivos',
|
translated: 'Meus arquivos',
|
||||||
|
|
|
||||||
|
|
@ -148,6 +148,17 @@ export default {
|
||||||
com_ui_assistants_output: 'Assistenten Ausgabe',
|
com_ui_assistants_output: 'Assistenten Ausgabe',
|
||||||
com_ui_delete: 'Löschen',
|
com_ui_delete: 'Löschen',
|
||||||
com_ui_create: 'Erstellen',
|
com_ui_create: 'Erstellen',
|
||||||
|
com_ui_share: 'Share',
|
||||||
|
com_ui_share_link_to_chat: 'Share link to chat',
|
||||||
|
com_ui_share_error: 'There was an error sharing the chat link',
|
||||||
|
com_ui_share_create_message: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_created_message:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_share_update_message:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_updated_message:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_shared_link_not_found: 'Shared link not found',
|
||||||
com_ui_delete_conversation: 'Chat löschen?',
|
com_ui_delete_conversation: 'Chat löschen?',
|
||||||
com_ui_delete_conversation_confirm: 'Damit wird gelöscht',
|
com_ui_delete_conversation_confirm: 'Damit wird gelöscht',
|
||||||
com_ui_delete_assistant_confirm:
|
com_ui_delete_assistant_confirm:
|
||||||
|
|
@ -431,6 +442,12 @@ export default {
|
||||||
com_nav_export_recursive_or_sequential: 'Rekursiv oder sequentiell?',
|
com_nav_export_recursive_or_sequential: 'Rekursiv oder sequentiell?',
|
||||||
com_nav_export_recursive: 'Rekursiv',
|
com_nav_export_recursive: 'Rekursiv',
|
||||||
com_nav_export_conversation: 'Konversation exportieren',
|
com_nav_export_conversation: 'Konversation exportieren',
|
||||||
|
com_nav_export: 'Exportieren',
|
||||||
|
com_nav_shared_links: 'Gemeinsame Links',
|
||||||
|
com_nav_shared_links_manage: 'Verwalten',
|
||||||
|
com_nav_shared_links_empty: 'Sie haben keine gemeinsam genutzten Links.',
|
||||||
|
com_nav_shared_links_name: 'Name',
|
||||||
|
com_nav_shared_links_date_shared: 'Datum geteilt',
|
||||||
com_nav_my_files: 'Meine Dateien',
|
com_nav_my_files: 'Meine Dateien',
|
||||||
com_nav_theme: 'Farbschema',
|
com_nav_theme: 'Farbschema',
|
||||||
com_nav_theme_system: 'System',
|
com_nav_theme_system: 'System',
|
||||||
|
|
@ -464,6 +481,12 @@ export default {
|
||||||
com_nav_setting_account: 'Konto',
|
com_nav_setting_account: 'Konto',
|
||||||
com_nav_language: 'Sprache',
|
com_nav_language: 'Sprache',
|
||||||
/* The following are AI Translated */
|
/* The following are AI Translated */
|
||||||
|
com_ui_copied: 'Kopiert',
|
||||||
|
com_ui_copy_code: 'Code kopieren',
|
||||||
|
com_ui_copy_link: 'Link kopieren',
|
||||||
|
com_ui_update_link: 'Link aktualisieren',
|
||||||
|
com_ui_create_link: 'Link erstellen',
|
||||||
|
com_nav_source_chat: 'Quellchat anzeigen',
|
||||||
com_ui_date_today: 'Heute',
|
com_ui_date_today: 'Heute',
|
||||||
com_ui_date_yesterday: 'Gestern',
|
com_ui_date_yesterday: 'Gestern',
|
||||||
com_ui_date_previous_7_days: 'Letzte 7 Tage',
|
com_ui_date_previous_7_days: 'Letzte 7 Tage',
|
||||||
|
|
@ -1102,6 +1125,43 @@ export const comparisons = {
|
||||||
english: 'Create',
|
english: 'Create',
|
||||||
translated: 'Erstellen',
|
translated: 'Erstellen',
|
||||||
},
|
},
|
||||||
|
com_ui_share: {
|
||||||
|
english: 'Share',
|
||||||
|
translated: 'Share',
|
||||||
|
},
|
||||||
|
com_ui_share_link_to_chat: {
|
||||||
|
english: 'Share link to chat',
|
||||||
|
translated: 'Share link to chat',
|
||||||
|
},
|
||||||
|
com_ui_share_error: {
|
||||||
|
english: 'There was an error sharing the chat link',
|
||||||
|
translated: 'There was an error sharing the chat link',
|
||||||
|
},
|
||||||
|
com_ui_share_create_message: {
|
||||||
|
english: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
translated: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_created_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_share_update_message: {
|
||||||
|
english: 'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
translated:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_updated_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_shared_link_not_found: {
|
||||||
|
english: 'Shared link not found',
|
||||||
|
translated: 'Shared link not found',
|
||||||
|
},
|
||||||
com_ui_delete_conversation: {
|
com_ui_delete_conversation: {
|
||||||
english: 'Delete chat?',
|
english: 'Delete chat?',
|
||||||
translated: 'Chat löschen?',
|
translated: 'Chat löschen?',
|
||||||
|
|
@ -2097,6 +2157,30 @@ export const comparisons = {
|
||||||
english: 'Export conversation',
|
english: 'Export conversation',
|
||||||
translated: 'Konversation exportieren',
|
translated: 'Konversation exportieren',
|
||||||
},
|
},
|
||||||
|
com_nav_export: {
|
||||||
|
english: 'Export',
|
||||||
|
translated: 'Exportieren',
|
||||||
|
},
|
||||||
|
com_nav_shared_links: {
|
||||||
|
english: 'Shared links',
|
||||||
|
translated: 'Gemeinsame Links',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_manage: {
|
||||||
|
english: 'Manage',
|
||||||
|
translated: 'Verwalten',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_empty: {
|
||||||
|
english: 'You have no shared links.',
|
||||||
|
translated: 'Sie haben keine gemeinsam genutzten Links.',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_name: {
|
||||||
|
english: 'Name',
|
||||||
|
translated: 'Name',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_date_shared: {
|
||||||
|
english: 'Date shared',
|
||||||
|
translated: 'Datum geteilt',
|
||||||
|
},
|
||||||
com_nav_my_files: {
|
com_nav_my_files: {
|
||||||
english: 'My Files',
|
english: 'My Files',
|
||||||
translated: 'Meine Dateien',
|
translated: 'Meine Dateien',
|
||||||
|
|
@ -2221,6 +2305,30 @@ export const comparisons = {
|
||||||
english: 'Language',
|
english: 'Language',
|
||||||
translated: 'Sprache',
|
translated: 'Sprache',
|
||||||
},
|
},
|
||||||
|
com_ui_copied: {
|
||||||
|
english: 'Copied!',
|
||||||
|
translated: 'Kopiert',
|
||||||
|
},
|
||||||
|
com_ui_copy_code: {
|
||||||
|
english: 'Copy code',
|
||||||
|
translated: 'Code kopieren',
|
||||||
|
},
|
||||||
|
com_ui_copy_link: {
|
||||||
|
english: 'Copy link',
|
||||||
|
translated: 'Link kopieren',
|
||||||
|
},
|
||||||
|
com_ui_update_link: {
|
||||||
|
english: 'Update link',
|
||||||
|
translated: 'Link aktualisieren',
|
||||||
|
},
|
||||||
|
com_ui_create_link: {
|
||||||
|
english: 'Create link',
|
||||||
|
translated: 'Link erstellen',
|
||||||
|
},
|
||||||
|
com_nav_source_chat: {
|
||||||
|
english: 'View source chat',
|
||||||
|
translated: 'Quellchat anzeigen',
|
||||||
|
},
|
||||||
com_ui_date_today: {
|
com_ui_date_today: {
|
||||||
english: 'Today',
|
english: 'Today',
|
||||||
translated: 'Heute',
|
translated: 'Heute',
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,8 @@ export default {
|
||||||
com_ui_save: 'Save',
|
com_ui_save: 'Save',
|
||||||
com_ui_save_submit: 'Save & Submit',
|
com_ui_save_submit: 'Save & Submit',
|
||||||
com_user_message: 'You',
|
com_user_message: 'You',
|
||||||
|
com_ui_copied: 'Copied!',
|
||||||
|
com_ui_copy_code: 'Copy code',
|
||||||
com_ui_copy_to_clipboard: 'Copy to clipboard',
|
com_ui_copy_to_clipboard: 'Copy to clipboard',
|
||||||
com_ui_copied_to_clipboard: 'Copied to clipboard',
|
com_ui_copied_to_clipboard: 'Copied to clipboard',
|
||||||
com_ui_fork: 'Fork',
|
com_ui_fork: 'Fork',
|
||||||
|
|
@ -199,6 +201,20 @@ export default {
|
||||||
com_ui_assistants_output: 'Assistants Output',
|
com_ui_assistants_output: 'Assistants Output',
|
||||||
com_ui_delete: 'Delete',
|
com_ui_delete: 'Delete',
|
||||||
com_ui_create: 'Create',
|
com_ui_create: 'Create',
|
||||||
|
com_ui_share: 'Share',
|
||||||
|
com_ui_copy_link: 'Copy link',
|
||||||
|
com_ui_update_link: 'Update link',
|
||||||
|
com_ui_create_link: 'Create link',
|
||||||
|
com_ui_share_link_to_chat: 'Share link to chat',
|
||||||
|
com_ui_share_error: 'There was an error sharing the chat link',
|
||||||
|
com_ui_share_create_message: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_created_message:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_share_update_message:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_updated_message:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_shared_link_not_found: 'Shared link not found',
|
||||||
com_ui_delete_conversation: 'Delete chat?',
|
com_ui_delete_conversation: 'Delete chat?',
|
||||||
com_ui_delete_conversation_confirm: 'This will delete',
|
com_ui_delete_conversation_confirm: 'This will delete',
|
||||||
com_ui_delete_assistant_confirm:
|
com_ui_delete_assistant_confirm:
|
||||||
|
|
@ -480,6 +496,13 @@ export default {
|
||||||
com_nav_export_recursive_or_sequential: 'Recursive or sequential?',
|
com_nav_export_recursive_or_sequential: 'Recursive or sequential?',
|
||||||
com_nav_export_recursive: 'Recursive',
|
com_nav_export_recursive: 'Recursive',
|
||||||
com_nav_export_conversation: 'Export conversation',
|
com_nav_export_conversation: 'Export conversation',
|
||||||
|
com_nav_export: 'Export',
|
||||||
|
com_nav_shared_links: 'Shared links',
|
||||||
|
com_nav_shared_links_manage: 'Manage',
|
||||||
|
com_nav_shared_links_empty: 'You have no shared links.',
|
||||||
|
com_nav_shared_links_name: 'Name',
|
||||||
|
com_nav_shared_links_date_shared: 'Date shared',
|
||||||
|
com_nav_source_chat: 'View source chat',
|
||||||
com_nav_my_files: 'My Files',
|
com_nav_my_files: 'My Files',
|
||||||
com_nav_theme: 'Theme',
|
com_nav_theme: 'Theme',
|
||||||
com_nav_theme_system: 'System',
|
com_nav_theme_system: 'System',
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,17 @@ export default {
|
||||||
com_ui_assistants_output: 'Salida de Asistentes',
|
com_ui_assistants_output: 'Salida de Asistentes',
|
||||||
com_ui_delete: 'Eliminar',
|
com_ui_delete: 'Eliminar',
|
||||||
com_ui_create: 'Crear',
|
com_ui_create: 'Crear',
|
||||||
|
com_ui_share: 'Share',
|
||||||
|
com_ui_share_link_to_chat: 'Share link to chat',
|
||||||
|
com_ui_share_error: 'There was an error sharing the chat link',
|
||||||
|
com_ui_share_create_message: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_created_message:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_share_update_message:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_updated_message:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_shared_link_not_found: 'Shared link not found',
|
||||||
com_ui_delete_conversation: '¿Eliminar Chat?',
|
com_ui_delete_conversation: '¿Eliminar Chat?',
|
||||||
com_ui_delete_conversation_confirm: 'Esto eliminará',
|
com_ui_delete_conversation_confirm: 'Esto eliminará',
|
||||||
com_ui_delete_assistant_confirm:
|
com_ui_delete_assistant_confirm:
|
||||||
|
|
@ -423,6 +434,12 @@ export default {
|
||||||
com_nav_export_recursive_or_sequential: '¿Recursivo o secuencial?',
|
com_nav_export_recursive_or_sequential: '¿Recursivo o secuencial?',
|
||||||
com_nav_export_recursive: 'Recursivo',
|
com_nav_export_recursive: 'Recursivo',
|
||||||
com_nav_export_conversation: 'Exportar conversación',
|
com_nav_export_conversation: 'Exportar conversación',
|
||||||
|
com_nav_export: 'Exportar',
|
||||||
|
com_nav_shared_links: 'Links Compartidos',
|
||||||
|
com_nav_shared_links_manage: 'Gerenciar',
|
||||||
|
com_nav_shared_links_empty: 'Você não tem nenhum link compartilhado.',
|
||||||
|
com_nav_shared_links_name: 'Nome',
|
||||||
|
com_nav_shared_links_date_shared: 'Data compartilhada',
|
||||||
com_nav_my_files: 'Mis archivos',
|
com_nav_my_files: 'Mis archivos',
|
||||||
com_nav_theme: 'Tema',
|
com_nav_theme: 'Tema',
|
||||||
com_nav_theme_system: 'Sistema',
|
com_nav_theme_system: 'Sistema',
|
||||||
|
|
@ -458,6 +475,12 @@ export default {
|
||||||
com_nav_lang_auto: 'Detección automática',
|
com_nav_lang_auto: 'Detección automática',
|
||||||
com_nav_lang_spanish: 'Español',
|
com_nav_lang_spanish: 'Español',
|
||||||
/* The following are AI Translated */
|
/* The following are AI Translated */
|
||||||
|
com_ui_copied: '¡Copiado!',
|
||||||
|
com_ui_copy_code: 'Copiar código',
|
||||||
|
com_ui_copy_link: 'Copiar enlace',
|
||||||
|
com_ui_update_link: 'Actualizar enlace',
|
||||||
|
com_ui_create_link: 'Crear enlace',
|
||||||
|
com_nav_source_chat: 'Ver chat de origen',
|
||||||
com_ui_date_today: 'Hoy',
|
com_ui_date_today: 'Hoy',
|
||||||
com_ui_date_yesterday: 'Ayer',
|
com_ui_date_yesterday: 'Ayer',
|
||||||
com_ui_date_previous_7_days: 'Últimos 7 días',
|
com_ui_date_previous_7_days: 'Últimos 7 días',
|
||||||
|
|
@ -1073,6 +1096,43 @@ export const comparisons = {
|
||||||
english: 'Create',
|
english: 'Create',
|
||||||
translated: 'Crear',
|
translated: 'Crear',
|
||||||
},
|
},
|
||||||
|
com_ui_share: {
|
||||||
|
english: 'Share',
|
||||||
|
translated: 'Share',
|
||||||
|
},
|
||||||
|
com_ui_share_link_to_chat: {
|
||||||
|
english: 'Share link to chat',
|
||||||
|
translated: 'Share link to chat',
|
||||||
|
},
|
||||||
|
com_ui_share_error: {
|
||||||
|
english: 'There was an error sharing the chat link',
|
||||||
|
translated: 'There was an error sharing the chat link',
|
||||||
|
},
|
||||||
|
com_ui_share_create_message: {
|
||||||
|
english: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
translated: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_created_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_share_update_message: {
|
||||||
|
english: 'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
translated:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_updated_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_shared_link_not_found: {
|
||||||
|
english: 'Shared link not found',
|
||||||
|
translated: 'Shared link not found',
|
||||||
|
},
|
||||||
com_ui_delete_conversation: {
|
com_ui_delete_conversation: {
|
||||||
english: 'Delete chat?',
|
english: 'Delete chat?',
|
||||||
translated: '¿Eliminar Chat?',
|
translated: '¿Eliminar Chat?',
|
||||||
|
|
@ -2069,6 +2129,30 @@ export const comparisons = {
|
||||||
english: 'Export conversation',
|
english: 'Export conversation',
|
||||||
translated: 'Exportar conversación',
|
translated: 'Exportar conversación',
|
||||||
},
|
},
|
||||||
|
com_nav_export: {
|
||||||
|
english: 'Export',
|
||||||
|
translated: 'Exportar',
|
||||||
|
},
|
||||||
|
com_nav_shared_links: {
|
||||||
|
english: 'Shared links',
|
||||||
|
translated: 'Links Compartidos',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_manage: {
|
||||||
|
english: 'Manage',
|
||||||
|
translated: 'Gerenciar',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_empty: {
|
||||||
|
english: 'You have no shared links.',
|
||||||
|
translated: 'Você não tem nenhum link compartilhado.',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_name: {
|
||||||
|
english: 'Name',
|
||||||
|
translated: 'Nome',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_date_shared: {
|
||||||
|
english: 'Date shared',
|
||||||
|
translated: 'Data compartilhada',
|
||||||
|
},
|
||||||
com_nav_my_files: {
|
com_nav_my_files: {
|
||||||
english: 'My Files',
|
english: 'My Files',
|
||||||
translated: 'Mis archivos',
|
translated: 'Mis archivos',
|
||||||
|
|
@ -2202,6 +2286,30 @@ export const comparisons = {
|
||||||
english: 'Español',
|
english: 'Español',
|
||||||
translated: 'Español',
|
translated: 'Español',
|
||||||
},
|
},
|
||||||
|
com_ui_copied: {
|
||||||
|
english: 'Copied!',
|
||||||
|
translated: '¡Copiado!',
|
||||||
|
},
|
||||||
|
com_ui_copy_code: {
|
||||||
|
english: 'Copy code',
|
||||||
|
translated: 'Copiar código',
|
||||||
|
},
|
||||||
|
com_ui_copy_link: {
|
||||||
|
english: 'Copy link',
|
||||||
|
translated: 'Copiar enlace',
|
||||||
|
},
|
||||||
|
com_ui_update_link: {
|
||||||
|
english: 'Update link',
|
||||||
|
translated: 'Actualizar enlace',
|
||||||
|
},
|
||||||
|
com_ui_create_link: {
|
||||||
|
english: 'Create link',
|
||||||
|
translated: 'Crear enlace',
|
||||||
|
},
|
||||||
|
com_nav_source_chat: {
|
||||||
|
english: 'View source chat',
|
||||||
|
translated: 'Ver chat de origen',
|
||||||
|
},
|
||||||
com_ui_date_today: {
|
com_ui_date_today: {
|
||||||
english: 'Today',
|
english: 'Today',
|
||||||
translated: 'Hoy',
|
translated: 'Hoy',
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,17 @@ export default {
|
||||||
'Une erreur s’est produite lors de l’importation de vos conversations',
|
'Une erreur s’est produite lors de l’importation de vos conversations',
|
||||||
com_ui_confirm_action: 'Confirmer l\'action',
|
com_ui_confirm_action: 'Confirmer l\'action',
|
||||||
com_ui_chats: 'discussions',
|
com_ui_chats: 'discussions',
|
||||||
|
com_ui_share: 'Share',
|
||||||
|
com_ui_share_link_to_chat: 'Share link to chat',
|
||||||
|
com_ui_share_error: 'There was an error sharing the chat link',
|
||||||
|
com_ui_share_create_message: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_created_message:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_share_update_message:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_updated_message:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_shared_link_not_found: 'Shared link not found',
|
||||||
com_ui_delete: 'Supprimer',
|
com_ui_delete: 'Supprimer',
|
||||||
com_ui_delete_conversation: 'Supprimer la discussions?',
|
com_ui_delete_conversation: 'Supprimer la discussions?',
|
||||||
com_ui_delete_conversation_confirm: 'Cela supprimera',
|
com_ui_delete_conversation_confirm: 'Cela supprimera',
|
||||||
|
|
@ -318,6 +329,12 @@ export default {
|
||||||
com_nav_export_recursive_or_sequential: 'Récursif ou séquentiel ?',
|
com_nav_export_recursive_or_sequential: 'Récursif ou séquentiel ?',
|
||||||
com_nav_export_recursive: 'Récursif',
|
com_nav_export_recursive: 'Récursif',
|
||||||
com_nav_export_conversation: 'Exporter la conversation',
|
com_nav_export_conversation: 'Exporter la conversation',
|
||||||
|
com_nav_export: 'Exporter',
|
||||||
|
com_nav_shared_links: 'Liens partagés',
|
||||||
|
com_nav_shared_links_manage: 'Gerenciar',
|
||||||
|
com_nav_shared_links_empty: 'Você não tem nenhum link compartilhado.',
|
||||||
|
com_nav_shared_links_name: 'Nome',
|
||||||
|
com_nav_shared_links_date_shared: 'Data compartilhada',
|
||||||
com_nav_theme: 'Thème',
|
com_nav_theme: 'Thème',
|
||||||
com_nav_theme_system: 'Système',
|
com_nav_theme_system: 'Système',
|
||||||
com_nav_theme_dark: 'Sombre',
|
com_nav_theme_dark: 'Sombre',
|
||||||
|
|
@ -347,6 +364,12 @@ export default {
|
||||||
com_nav_setting_data: 'Contrôles des données',
|
com_nav_setting_data: 'Contrôles des données',
|
||||||
com_nav_setting_account: 'Compte',
|
com_nav_setting_account: 'Compte',
|
||||||
/* The following are AI Translated */
|
/* The following are AI Translated */
|
||||||
|
com_ui_copied: 'Copié !',
|
||||||
|
com_ui_copy_code: 'Copier le code',
|
||||||
|
com_ui_copy_link: 'Copier le lien',
|
||||||
|
com_ui_update_link: 'Mettre à jour le lien',
|
||||||
|
com_ui_create_link: 'Créer un lien',
|
||||||
|
com_nav_source_chat: 'Afficher la conversation source',
|
||||||
com_ui_date_today: 'Aujourd\'hui',
|
com_ui_date_today: 'Aujourd\'hui',
|
||||||
com_ui_date_yesterday: 'Hier',
|
com_ui_date_yesterday: 'Hier',
|
||||||
com_ui_date_previous_7_days: '7 derniers jours',
|
com_ui_date_previous_7_days: '7 derniers jours',
|
||||||
|
|
@ -788,6 +811,43 @@ export const comparisons = {
|
||||||
english: 'chats',
|
english: 'chats',
|
||||||
translated: 'discussions',
|
translated: 'discussions',
|
||||||
},
|
},
|
||||||
|
com_ui_share: {
|
||||||
|
english: 'Share',
|
||||||
|
translated: 'Share',
|
||||||
|
},
|
||||||
|
com_ui_share_link_to_chat: {
|
||||||
|
english: 'Share link to chat',
|
||||||
|
translated: 'Share link to chat',
|
||||||
|
},
|
||||||
|
com_ui_share_error: {
|
||||||
|
english: 'There was an error sharing the chat link',
|
||||||
|
translated: 'There was an error sharing the chat link',
|
||||||
|
},
|
||||||
|
com_ui_share_create_message: {
|
||||||
|
english: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
translated: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_created_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_share_update_message: {
|
||||||
|
english: 'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
translated:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_updated_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_shared_link_not_found: {
|
||||||
|
english: 'Shared link not found',
|
||||||
|
translated: 'Shared link not found',
|
||||||
|
},
|
||||||
com_ui_delete: {
|
com_ui_delete: {
|
||||||
english: 'Delete',
|
english: 'Delete',
|
||||||
translated: 'Supprimer',
|
translated: 'Supprimer',
|
||||||
|
|
@ -1670,6 +1730,30 @@ export const comparisons = {
|
||||||
english: 'Export conversation',
|
english: 'Export conversation',
|
||||||
translated: 'Exporter la conversation',
|
translated: 'Exporter la conversation',
|
||||||
},
|
},
|
||||||
|
com_nav_export: {
|
||||||
|
english: 'Export',
|
||||||
|
translated: 'Exporter',
|
||||||
|
},
|
||||||
|
com_nav_shared_links: {
|
||||||
|
english: 'Shared links',
|
||||||
|
translated: 'Liens partagés',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_manage: {
|
||||||
|
english: 'Manage',
|
||||||
|
translated: 'Gerenciar',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_empty: {
|
||||||
|
english: 'You have no shared links.',
|
||||||
|
translated: 'Você não tem nenhum link compartilhado.',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_name: {
|
||||||
|
english: 'Name',
|
||||||
|
translated: 'Nome',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_date_shared: {
|
||||||
|
english: 'Date shared',
|
||||||
|
translated: 'Data compartilhada',
|
||||||
|
},
|
||||||
com_nav_theme: {
|
com_nav_theme: {
|
||||||
english: 'Theme',
|
english: 'Theme',
|
||||||
translated: 'Thème',
|
translated: 'Thème',
|
||||||
|
|
@ -1779,6 +1863,30 @@ export const comparisons = {
|
||||||
english: 'Account',
|
english: 'Account',
|
||||||
translated: 'Compte',
|
translated: 'Compte',
|
||||||
},
|
},
|
||||||
|
com_ui_copied: {
|
||||||
|
english: 'Copied!',
|
||||||
|
translated: 'Copié !',
|
||||||
|
},
|
||||||
|
com_ui_copy_code: {
|
||||||
|
english: 'Copy code',
|
||||||
|
translated: 'Copier le code',
|
||||||
|
},
|
||||||
|
com_ui_copy_link: {
|
||||||
|
english: 'Copy link',
|
||||||
|
translated: 'Copier le lien',
|
||||||
|
},
|
||||||
|
com_ui_update_link: {
|
||||||
|
english: 'Update link',
|
||||||
|
translated: 'Mettre à jour le lien',
|
||||||
|
},
|
||||||
|
com_ui_create_link: {
|
||||||
|
english: 'Create link',
|
||||||
|
translated: 'Créer un lien',
|
||||||
|
},
|
||||||
|
com_nav_source_chat: {
|
||||||
|
english: 'View source chat',
|
||||||
|
translated: 'Afficher la conversation source',
|
||||||
|
},
|
||||||
com_ui_date_today: {
|
com_ui_date_today: {
|
||||||
english: 'Today',
|
english: 'Today',
|
||||||
translated: 'Aujourd\'hui',
|
translated: 'Aujourd\'hui',
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,17 @@ export default {
|
||||||
com_ui_assistant: 'סייען',
|
com_ui_assistant: 'סייען',
|
||||||
com_ui_delete: 'מחק',
|
com_ui_delete: 'מחק',
|
||||||
com_ui_create: 'צור',
|
com_ui_create: 'צור',
|
||||||
|
com_ui_share: 'Share',
|
||||||
|
com_ui_share_link_to_chat: 'Share link to chat',
|
||||||
|
com_ui_share_error: 'There was an error sharing the chat link',
|
||||||
|
com_ui_share_create_message: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_created_message:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_share_update_message:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_updated_message:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_shared_link_not_found: 'Shared link not found',
|
||||||
com_ui_delete_conversation: 'למחוק את השיחה (צאט)?',
|
com_ui_delete_conversation: 'למחוק את השיחה (צאט)?',
|
||||||
com_ui_delete_conversation_confirm: 'זה ימחק',
|
com_ui_delete_conversation_confirm: 'זה ימחק',
|
||||||
com_ui_delete_assistant_confirm:
|
com_ui_delete_assistant_confirm:
|
||||||
|
|
@ -345,6 +356,12 @@ export default {
|
||||||
com_nav_export_recursive_or_sequential: 'רקורסיבי או רציף?',
|
com_nav_export_recursive_or_sequential: 'רקורסיבי או רציף?',
|
||||||
com_nav_export_recursive: 'רקורסיבי',
|
com_nav_export_recursive: 'רקורסיבי',
|
||||||
com_nav_export_conversation: 'ייצא שיחה',
|
com_nav_export_conversation: 'ייצא שיחה',
|
||||||
|
com_nav_export: 'ייצא',
|
||||||
|
com_nav_shared_links: 'קישורים משותפים',
|
||||||
|
com_nav_shared_links_manage: 'ניהול',
|
||||||
|
com_nav_shared_links_empty: 'אין לך קישורים משותפים.',
|
||||||
|
com_nav_shared_links_name: 'שם',
|
||||||
|
com_nav_shared_links_date_shared: 'תאריך שיתוף',
|
||||||
com_nav_theme: 'נושא',
|
com_nav_theme: 'נושא',
|
||||||
com_nav_theme_system: 'מערכת',
|
com_nav_theme_system: 'מערכת',
|
||||||
com_nav_theme_dark: 'כהה',
|
com_nav_theme_dark: 'כהה',
|
||||||
|
|
@ -723,6 +740,43 @@ export const comparisons = {
|
||||||
english: 'Create',
|
english: 'Create',
|
||||||
translated: 'צור',
|
translated: 'צור',
|
||||||
},
|
},
|
||||||
|
com_ui_share: {
|
||||||
|
english: 'Share',
|
||||||
|
translated: 'Share',
|
||||||
|
},
|
||||||
|
com_ui_share_link_to_chat: {
|
||||||
|
english: 'Share link to chat',
|
||||||
|
translated: 'Share link to chat',
|
||||||
|
},
|
||||||
|
com_ui_share_error: {
|
||||||
|
english: 'There was an error sharing the chat link',
|
||||||
|
translated: 'There was an error sharing the chat link',
|
||||||
|
},
|
||||||
|
com_ui_share_create_message: {
|
||||||
|
english: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
translated: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_created_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_share_update_message: {
|
||||||
|
english: 'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
translated:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_updated_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_shared_link_not_found: {
|
||||||
|
english: 'Shared link not found',
|
||||||
|
translated: 'Shared link not found',
|
||||||
|
},
|
||||||
com_ui_delete_conversation: {
|
com_ui_delete_conversation: {
|
||||||
english: 'Delete chat?',
|
english: 'Delete chat?',
|
||||||
translated: 'למחוק את השיחה (צאט)?',
|
translated: 'למחוק את השיחה (צאט)?',
|
||||||
|
|
@ -1659,6 +1713,30 @@ export const comparisons = {
|
||||||
english: 'Export conversation',
|
english: 'Export conversation',
|
||||||
translated: 'ייצא שיחה',
|
translated: 'ייצא שיחה',
|
||||||
},
|
},
|
||||||
|
com_nav_export: {
|
||||||
|
english: 'Export',
|
||||||
|
translated: 'ייצא',
|
||||||
|
},
|
||||||
|
com_nav_shared_links: {
|
||||||
|
english: 'Shared links',
|
||||||
|
translated: 'קישורים משותפים',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_manage: {
|
||||||
|
english: 'Manage',
|
||||||
|
translated: 'ניהול',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_empty: {
|
||||||
|
english: 'You have no shared links.',
|
||||||
|
translated: 'אין לך קישורים משותפים.',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_name: {
|
||||||
|
english: 'Name',
|
||||||
|
translated: 'שם',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_date_shared: {
|
||||||
|
english: 'Date shared',
|
||||||
|
translated: 'תאריך שיתוף',
|
||||||
|
},
|
||||||
com_nav_theme: {
|
com_nav_theme: {
|
||||||
english: 'Theme',
|
english: 'Theme',
|
||||||
translated: 'נושא',
|
translated: 'נושא',
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,17 @@ export default {
|
||||||
com_ui_import_conversation_error: 'Terjadi kesalahan saat mengimpor percakapan Anda',
|
com_ui_import_conversation_error: 'Terjadi kesalahan saat mengimpor percakapan Anda',
|
||||||
com_ui_confirm_action: 'Konfirmasi Aksi',
|
com_ui_confirm_action: 'Konfirmasi Aksi',
|
||||||
com_ui_chats: 'chat',
|
com_ui_chats: 'chat',
|
||||||
|
com_ui_share: 'Share',
|
||||||
|
com_ui_share_link_to_chat: 'Share link to chat',
|
||||||
|
com_ui_share_error: 'There was an error sharing the chat link',
|
||||||
|
com_ui_share_create_message: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_created_message:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_share_update_message:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_updated_message:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_shared_link_not_found: 'Shared link not found',
|
||||||
com_ui_delete: 'Hapus',
|
com_ui_delete: 'Hapus',
|
||||||
com_ui_delete_conversation: 'Hapus chat?',
|
com_ui_delete_conversation: 'Hapus chat?',
|
||||||
com_ui_delete_conversation_confirm: 'Ini akan menghapus',
|
com_ui_delete_conversation_confirm: 'Ini akan menghapus',
|
||||||
|
|
@ -304,6 +315,12 @@ export default {
|
||||||
com_nav_export_recursive_or_sequential: 'Rekursif atau berurutan?',
|
com_nav_export_recursive_or_sequential: 'Rekursif atau berurutan?',
|
||||||
com_nav_export_recursive: 'Rekursif',
|
com_nav_export_recursive: 'Rekursif',
|
||||||
com_nav_export_conversation: 'Ekspor percakapan',
|
com_nav_export_conversation: 'Ekspor percakapan',
|
||||||
|
com_nav_export: 'Ekspor',
|
||||||
|
com_nav_shared_links: 'Link berbagi',
|
||||||
|
com_nav_shared_links_manage: 'Pengeluaran',
|
||||||
|
com_nav_shared_links_empty: 'Anda tidak memiliki link berbagi.',
|
||||||
|
com_nav_shared_links_name: 'Nama',
|
||||||
|
com_nav_shared_links_date_shared: 'Tanggal berbagi',
|
||||||
com_nav_theme: 'Tema',
|
com_nav_theme: 'Tema',
|
||||||
com_nav_theme_system: 'Sistem',
|
com_nav_theme_system: 'Sistem',
|
||||||
com_nav_theme_dark: 'Gelap',
|
com_nav_theme_dark: 'Gelap',
|
||||||
|
|
@ -576,6 +593,43 @@ export const comparisons = {
|
||||||
english: 'chats',
|
english: 'chats',
|
||||||
translated: 'chat',
|
translated: 'chat',
|
||||||
},
|
},
|
||||||
|
com_ui_share: {
|
||||||
|
english: 'Share',
|
||||||
|
translated: 'Share',
|
||||||
|
},
|
||||||
|
com_ui_share_link_to_chat: {
|
||||||
|
english: 'Share link to chat',
|
||||||
|
translated: 'Share link to chat',
|
||||||
|
},
|
||||||
|
com_ui_share_error: {
|
||||||
|
english: 'There was an error sharing the chat link',
|
||||||
|
translated: 'There was an error sharing the chat link',
|
||||||
|
},
|
||||||
|
com_ui_share_create_message: {
|
||||||
|
english: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
translated: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_created_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_share_update_message: {
|
||||||
|
english: 'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
translated:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_updated_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_shared_link_not_found: {
|
||||||
|
english: 'Shared link not found',
|
||||||
|
translated: 'Shared link not found',
|
||||||
|
},
|
||||||
com_ui_delete: {
|
com_ui_delete: {
|
||||||
english: 'Delete',
|
english: 'Delete',
|
||||||
translated: 'Hapus',
|
translated: 'Hapus',
|
||||||
|
|
@ -1457,6 +1511,30 @@ export const comparisons = {
|
||||||
english: 'Export conversation',
|
english: 'Export conversation',
|
||||||
translated: 'Ekspor percakapan',
|
translated: 'Ekspor percakapan',
|
||||||
},
|
},
|
||||||
|
com_nav_export: {
|
||||||
|
english: 'Export',
|
||||||
|
translated: 'Ekspor',
|
||||||
|
},
|
||||||
|
com_nav_shared_links: {
|
||||||
|
english: 'Shared links',
|
||||||
|
translated: 'Link berbagi',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_manage: {
|
||||||
|
english: 'Manage',
|
||||||
|
translated: 'Pengeluaran',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_empty: {
|
||||||
|
english: 'You have no shared links.',
|
||||||
|
translated: 'Anda tidak memiliki link berbagi.',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_name: {
|
||||||
|
english: 'Name',
|
||||||
|
translated: 'Nama',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_date_shared: {
|
||||||
|
english: 'Date shared',
|
||||||
|
translated: 'Tanggal berbagi',
|
||||||
|
},
|
||||||
com_nav_theme: {
|
com_nav_theme: {
|
||||||
english: 'Theme',
|
english: 'Theme',
|
||||||
translated: 'Tema',
|
translated: 'Tema',
|
||||||
|
|
|
||||||
|
|
@ -188,6 +188,17 @@ export default {
|
||||||
com_ui_assistants_output: 'Output Assistenti',
|
com_ui_assistants_output: 'Output Assistenti',
|
||||||
com_ui_delete: 'Elimina',
|
com_ui_delete: 'Elimina',
|
||||||
com_ui_create: 'Crea',
|
com_ui_create: 'Crea',
|
||||||
|
com_ui_share: 'Share',
|
||||||
|
com_ui_share_link_to_chat: 'Share link to chat',
|
||||||
|
com_ui_share_error: 'There was an error sharing the chat link',
|
||||||
|
com_ui_share_create_message: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_created_message:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_share_update_message:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_updated_message:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_shared_link_not_found: 'Shared link not found',
|
||||||
com_ui_delete_conversation: 'Eliminare la chat?',
|
com_ui_delete_conversation: 'Eliminare la chat?',
|
||||||
com_ui_delete_conversation_confirm: 'Questo eliminerà',
|
com_ui_delete_conversation_confirm: 'Questo eliminerà',
|
||||||
com_ui_rename: 'Rinominare',
|
com_ui_rename: 'Rinominare',
|
||||||
|
|
@ -475,6 +486,12 @@ export default {
|
||||||
com_nav_export_recursive_or_sequential: 'Ricorsivo o sequenziale?',
|
com_nav_export_recursive_or_sequential: 'Ricorsivo o sequenziale?',
|
||||||
com_nav_export_recursive: 'Ricorsivo',
|
com_nav_export_recursive: 'Ricorsivo',
|
||||||
com_nav_export_conversation: 'Esporta conversazione',
|
com_nav_export_conversation: 'Esporta conversazione',
|
||||||
|
com_nav_export: 'Esporta',
|
||||||
|
com_nav_shared_links: 'Link condivisi',
|
||||||
|
com_nav_shared_links_manage: 'Gestisci',
|
||||||
|
com_nav_shared_links_empty: 'Non hai link condivisi.',
|
||||||
|
com_nav_shared_links_name: 'Nome',
|
||||||
|
com_nav_shared_links_date_shared: 'Data condivisione',
|
||||||
com_nav_my_files: 'I miei file',
|
com_nav_my_files: 'I miei file',
|
||||||
com_nav_theme: 'Tema',
|
com_nav_theme: 'Tema',
|
||||||
com_nav_theme_system: 'Sistema',
|
com_nav_theme_system: 'Sistema',
|
||||||
|
|
@ -508,6 +525,12 @@ export default {
|
||||||
com_nav_setting_data: 'Controlli dati',
|
com_nav_setting_data: 'Controlli dati',
|
||||||
com_nav_setting_account: 'Account',
|
com_nav_setting_account: 'Account',
|
||||||
/* The following are AI Translated */
|
/* The following are AI Translated */
|
||||||
|
com_ui_copied: 'Copiato!',
|
||||||
|
com_ui_copy_code: 'Copia codice',
|
||||||
|
com_ui_copy_link: 'Copia link',
|
||||||
|
com_ui_update_link: 'Aggiorna link',
|
||||||
|
com_ui_create_link: 'Crea link',
|
||||||
|
com_nav_source_chat: 'Visualizza chat sorgente',
|
||||||
com_ui_date_today: 'Oggi',
|
com_ui_date_today: 'Oggi',
|
||||||
com_ui_date_yesterday: 'Ieri',
|
com_ui_date_yesterday: 'Ieri',
|
||||||
com_ui_date_previous_7_days: 'Ultimi 7 giorni',
|
com_ui_date_previous_7_days: 'Ultimi 7 giorni',
|
||||||
|
|
@ -1222,6 +1245,43 @@ export const comparisons = {
|
||||||
english: 'Create',
|
english: 'Create',
|
||||||
translated: 'Crea',
|
translated: 'Crea',
|
||||||
},
|
},
|
||||||
|
com_ui_share: {
|
||||||
|
english: 'Share',
|
||||||
|
translated: 'Share',
|
||||||
|
},
|
||||||
|
com_ui_share_link_to_chat: {
|
||||||
|
english: 'Share link to chat',
|
||||||
|
translated: 'Share link to chat',
|
||||||
|
},
|
||||||
|
com_ui_share_error: {
|
||||||
|
english: 'There was an error sharing the chat link',
|
||||||
|
translated: 'There was an error sharing the chat link',
|
||||||
|
},
|
||||||
|
com_ui_share_create_message: {
|
||||||
|
english: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
translated: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_created_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_share_update_message: {
|
||||||
|
english: 'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
translated:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_updated_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_shared_link_not_found: {
|
||||||
|
english: 'Shared link not found',
|
||||||
|
translated: 'Shared link not found',
|
||||||
|
},
|
||||||
com_ui_delete_conversation: {
|
com_ui_delete_conversation: {
|
||||||
english: 'Delete chat?',
|
english: 'Delete chat?',
|
||||||
translated: 'Eliminare la chat?',
|
translated: 'Eliminare la chat?',
|
||||||
|
|
@ -2234,6 +2294,30 @@ export const comparisons = {
|
||||||
english: 'Export conversation',
|
english: 'Export conversation',
|
||||||
translated: 'Esporta conversazione',
|
translated: 'Esporta conversazione',
|
||||||
},
|
},
|
||||||
|
com_nav_export: {
|
||||||
|
english: 'Export',
|
||||||
|
translated: 'Esporta',
|
||||||
|
},
|
||||||
|
com_nav_shared_links: {
|
||||||
|
english: 'Shared links',
|
||||||
|
translated: 'Link condivisi',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_manage: {
|
||||||
|
english: 'Manage',
|
||||||
|
translated: 'Gestisci',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_empty: {
|
||||||
|
english: 'You have no shared links.',
|
||||||
|
translated: 'Non hai link condivisi.',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_name: {
|
||||||
|
english: 'Name',
|
||||||
|
translated: 'Nome',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_date_shared: {
|
||||||
|
english: 'Date shared',
|
||||||
|
translated: 'Data condivisione',
|
||||||
|
},
|
||||||
com_nav_my_files: {
|
com_nav_my_files: {
|
||||||
english: 'My Files',
|
english: 'My Files',
|
||||||
translated: 'I miei file',
|
translated: 'I miei file',
|
||||||
|
|
@ -2359,6 +2443,30 @@ export const comparisons = {
|
||||||
english: 'Account',
|
english: 'Account',
|
||||||
translated: 'Account',
|
translated: 'Account',
|
||||||
},
|
},
|
||||||
|
com_ui_copied: {
|
||||||
|
english: 'Copied!',
|
||||||
|
translated: 'Copiato!',
|
||||||
|
},
|
||||||
|
com_ui_copy_code: {
|
||||||
|
english: 'Copy code',
|
||||||
|
translated: 'Copia codice',
|
||||||
|
},
|
||||||
|
com_ui_copy_link: {
|
||||||
|
english: 'Copy link',
|
||||||
|
translated: 'Copia link',
|
||||||
|
},
|
||||||
|
com_ui_update_link: {
|
||||||
|
english: 'Update link',
|
||||||
|
translated: 'Aggiorna link',
|
||||||
|
},
|
||||||
|
com_ui_create_link: {
|
||||||
|
english: 'Create link',
|
||||||
|
translated: 'Crea link',
|
||||||
|
},
|
||||||
|
com_nav_source_chat: {
|
||||||
|
english: 'View source chat',
|
||||||
|
translated: 'Visualizza chat sorgente',
|
||||||
|
},
|
||||||
com_ui_date_today: {
|
com_ui_date_today: {
|
||||||
english: 'Today',
|
english: 'Today',
|
||||||
translated: 'Oggi',
|
translated: 'Oggi',
|
||||||
|
|
|
||||||
|
|
@ -147,6 +147,18 @@ export default {
|
||||||
com_ui_assistants_output: 'Assistantsの出力',
|
com_ui_assistants_output: 'Assistantsの出力',
|
||||||
com_ui_delete: '削除',
|
com_ui_delete: '削除',
|
||||||
com_ui_create: '作成',
|
com_ui_create: '作成',
|
||||||
|
com_ui_share: '共有',
|
||||||
|
com_ui_share_link_to_chat: 'チャットへの共有リンク',
|
||||||
|
com_ui_share_error: 'チャットの共有リンクの共有中にエラーが発生しました',
|
||||||
|
com_ui_share_create_message:
|
||||||
|
'あなたの名前と共有リンクを作成した後のメッセージは、共有されません。',
|
||||||
|
com_ui_share_created_message:
|
||||||
|
'チャットへの公開された共有リンクが作成されました。設定から以前共有したチャットを管理できます。',
|
||||||
|
com_ui_share_update_message:
|
||||||
|
'あなたの名前、カスタム指示、共有リンクを作成した後のメッセージは、共有されません。',
|
||||||
|
com_ui_share_updated_message:
|
||||||
|
'チャットへの公開された共有リンクが更新されました。設定から以前共有したチャットを管理できます。',
|
||||||
|
com_ui_shared_link_not_found: '共有リンクが見つかりません',
|
||||||
com_ui_delete_conversation: 'チャットを削除しますか?',
|
com_ui_delete_conversation: 'チャットを削除しますか?',
|
||||||
com_ui_delete_conversation_confirm: 'このチャットは削除されます。',
|
com_ui_delete_conversation_confirm: 'このチャットは削除されます。',
|
||||||
com_ui_delete_assistant_confirm: 'このアシスタントを削除しますか? この操作は元に戻せません。',
|
com_ui_delete_assistant_confirm: 'このアシスタントを削除しますか? この操作は元に戻せません。',
|
||||||
|
|
@ -422,6 +434,12 @@ export default {
|
||||||
com_nav_export_recursive_or_sequential: '再帰的? or 順次的?',
|
com_nav_export_recursive_or_sequential: '再帰的? or 順次的?',
|
||||||
com_nav_export_recursive: '再帰的',
|
com_nav_export_recursive: '再帰的',
|
||||||
com_nav_export_conversation: '会話をエクスポートする',
|
com_nav_export_conversation: '会話をエクスポートする',
|
||||||
|
com_nav_export: 'エクスポート',
|
||||||
|
com_nav_shared_links: '共有リンク',
|
||||||
|
com_nav_shared_links_manage: '管理',
|
||||||
|
com_nav_shared_links_empty: '共有リンクはありません。',
|
||||||
|
com_nav_shared_links_name: 'タイトル',
|
||||||
|
com_nav_shared_links_date_shared: '共有日',
|
||||||
com_nav_my_files: 'My Files',
|
com_nav_my_files: 'My Files',
|
||||||
com_nav_theme: 'テーマ',
|
com_nav_theme: 'テーマ',
|
||||||
com_nav_theme_system: 'システム',
|
com_nav_theme_system: 'システム',
|
||||||
|
|
@ -455,6 +473,12 @@ export default {
|
||||||
com_nav_setting_data: 'データ管理',
|
com_nav_setting_data: 'データ管理',
|
||||||
com_nav_setting_account: 'アカウント',
|
com_nav_setting_account: 'アカウント',
|
||||||
/* The following are AI translated */
|
/* The following are AI translated */
|
||||||
|
com_ui_copied: 'コピーしました',
|
||||||
|
com_ui_copy_code: 'コードをコピーする',
|
||||||
|
com_ui_copy_link: 'リンクをコピー',
|
||||||
|
com_ui_update_link: 'リンクを更新する',
|
||||||
|
com_ui_create_link: 'リンクを作成する',
|
||||||
|
com_nav_source_chat: 'ソースチャットを表示する',
|
||||||
com_ui_date_today: '今日',
|
com_ui_date_today: '今日',
|
||||||
com_ui_date_yesterday: '昨日',
|
com_ui_date_yesterday: '昨日',
|
||||||
com_ui_date_previous_7_days: '過去7日間',
|
com_ui_date_previous_7_days: '過去7日間',
|
||||||
|
|
@ -1098,6 +1122,43 @@ export const comparisons = {
|
||||||
english: 'Create',
|
english: 'Create',
|
||||||
translated: '作成',
|
translated: '作成',
|
||||||
},
|
},
|
||||||
|
com_ui_share: {
|
||||||
|
english: 'Share',
|
||||||
|
translated: '共有',
|
||||||
|
},
|
||||||
|
com_ui_share_link_to_chat: {
|
||||||
|
english: 'Share link to chat',
|
||||||
|
translated: 'チャットへの共有リンク',
|
||||||
|
},
|
||||||
|
com_ui_share_error: {
|
||||||
|
english: 'There was an error sharing the chat link',
|
||||||
|
translated: 'チャットの共有リンクの共有中にエラーが発生しました',
|
||||||
|
},
|
||||||
|
com_ui_share_create_message: {
|
||||||
|
english: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
translated: 'あなたの名前と共有リンクを作成した後のメッセージは、共有されません。',
|
||||||
|
},
|
||||||
|
com_ui_share_created_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'チャットへの公開された共有リンクが作成されました。設定から以前共有したチャットを管理できます。',
|
||||||
|
},
|
||||||
|
com_ui_share_update_message: {
|
||||||
|
english: 'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
translated:
|
||||||
|
'あなたの名前、カスタム指示、共有リンクを作成した後のメッセージは、共有されません。',
|
||||||
|
},
|
||||||
|
com_ui_share_updated_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'チャットへの公開された共有リンクが更新されました。設定から以前共有したチャットを管理できます。',
|
||||||
|
},
|
||||||
|
com_ui_shared_link_not_found: {
|
||||||
|
english: 'Shared link not found',
|
||||||
|
translated: '共有リンクが見つかりません',
|
||||||
|
},
|
||||||
com_ui_delete_conversation: {
|
com_ui_delete_conversation: {
|
||||||
english: 'Delete chat?',
|
english: 'Delete chat?',
|
||||||
translated: 'チャットを削除しますか?',
|
translated: 'チャットを削除しますか?',
|
||||||
|
|
@ -2087,6 +2148,30 @@ export const comparisons = {
|
||||||
english: 'Export conversation',
|
english: 'Export conversation',
|
||||||
translated: '会話をエクスポートする',
|
translated: '会話をエクスポートする',
|
||||||
},
|
},
|
||||||
|
com_nav_export: {
|
||||||
|
english: 'Export',
|
||||||
|
translated: 'エクスポート',
|
||||||
|
},
|
||||||
|
com_nav_shared_links: {
|
||||||
|
english: 'Shared links',
|
||||||
|
translated: '共有リンク',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_manage: {
|
||||||
|
english: 'Manage',
|
||||||
|
translated: '管理',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_empty: {
|
||||||
|
english: 'You have no shared links.',
|
||||||
|
translated: '共有リンクはありません。',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_name: {
|
||||||
|
english: 'Name',
|
||||||
|
translated: 'タイトル',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_date_shared: {
|
||||||
|
english: 'Date shared',
|
||||||
|
translated: '共有日',
|
||||||
|
},
|
||||||
com_nav_my_files: {
|
com_nav_my_files: {
|
||||||
english: 'My Files',
|
english: 'My Files',
|
||||||
translated: 'My Files',
|
translated: 'My Files',
|
||||||
|
|
@ -2211,6 +2296,30 @@ export const comparisons = {
|
||||||
english: 'Account',
|
english: 'Account',
|
||||||
translated: 'アカウント',
|
translated: 'アカウント',
|
||||||
},
|
},
|
||||||
|
com_ui_copied: {
|
||||||
|
english: 'Copied!',
|
||||||
|
translated: 'コピーしました',
|
||||||
|
},
|
||||||
|
com_ui_copy_code: {
|
||||||
|
english: 'Copy code',
|
||||||
|
translated: 'コードをコピーする',
|
||||||
|
},
|
||||||
|
com_ui_copy_link: {
|
||||||
|
english: 'Copy link',
|
||||||
|
translated: 'リンクをコピー',
|
||||||
|
},
|
||||||
|
com_ui_update_link: {
|
||||||
|
english: 'Update link',
|
||||||
|
translated: 'リンクを更新する',
|
||||||
|
},
|
||||||
|
com_ui_create_link: {
|
||||||
|
english: 'Create link',
|
||||||
|
translated: 'リンクを作成する',
|
||||||
|
},
|
||||||
|
com_nav_source_chat: {
|
||||||
|
english: 'View source chat',
|
||||||
|
translated: 'ソースチャットを表示する',
|
||||||
|
},
|
||||||
com_ui_date_today: {
|
com_ui_date_today: {
|
||||||
english: 'Today',
|
english: 'Today',
|
||||||
translated: '今日',
|
translated: '今日',
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,17 @@ export default {
|
||||||
com_ui_import_conversation_error: '대화를 가져오는 동안 오류가 발생했습니다',
|
com_ui_import_conversation_error: '대화를 가져오는 동안 오류가 발생했습니다',
|
||||||
com_ui_confirm_action: '작업 확인',
|
com_ui_confirm_action: '작업 확인',
|
||||||
com_ui_chats: '채팅',
|
com_ui_chats: '채팅',
|
||||||
|
com_ui_share: 'Share',
|
||||||
|
com_ui_share_link_to_chat: 'Share link to chat',
|
||||||
|
com_ui_share_error: 'There was an error sharing the chat link',
|
||||||
|
com_ui_share_create_message: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_created_message:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_share_update_message:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_updated_message:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_shared_link_not_found: 'Shared link not found',
|
||||||
com_ui_delete: '삭제',
|
com_ui_delete: '삭제',
|
||||||
com_ui_delete_conversation: '채팅을 삭제하시겠습니까?',
|
com_ui_delete_conversation: '채팅을 삭제하시겠습니까?',
|
||||||
com_ui_delete_conversation_confirm: '이 채팅이 삭제됩니다',
|
com_ui_delete_conversation_confirm: '이 채팅이 삭제됩니다',
|
||||||
|
|
@ -234,6 +245,12 @@ export default {
|
||||||
com_nav_export_recursive_or_sequential: '재귀적 또는 순차적?',
|
com_nav_export_recursive_or_sequential: '재귀적 또는 순차적?',
|
||||||
com_nav_export_recursive: '재귀적',
|
com_nav_export_recursive: '재귀적',
|
||||||
com_nav_export_conversation: '대화 내보내기',
|
com_nav_export_conversation: '대화 내보내기',
|
||||||
|
com_nav_export: '내보내기',
|
||||||
|
com_nav_shared_links: '공유 링크',
|
||||||
|
com_nav_shared_links_manage: '관리',
|
||||||
|
com_nav_shared_links_empty: '공유 링크가 없습니다.',
|
||||||
|
com_nav_shared_links_name: '이름',
|
||||||
|
com_nav_shared_links_date_shared: '공유 날짜',
|
||||||
com_nav_theme: '테마',
|
com_nav_theme: '테마',
|
||||||
com_nav_theme_system: '시스템',
|
com_nav_theme_system: '시스템',
|
||||||
com_nav_theme_dark: '다크',
|
com_nav_theme_dark: '다크',
|
||||||
|
|
@ -261,6 +278,12 @@ export default {
|
||||||
com_nav_setting_general: '일반',
|
com_nav_setting_general: '일반',
|
||||||
com_nav_setting_data: '데이터 제어',
|
com_nav_setting_data: '데이터 제어',
|
||||||
/* The following are AI Translated */
|
/* The following are AI Translated */
|
||||||
|
com_ui_copied: '복사됨',
|
||||||
|
com_ui_copy_code: '코드 복사',
|
||||||
|
com_ui_copy_link: '링크 복사',
|
||||||
|
com_ui_update_link: '링크 업데이트',
|
||||||
|
com_ui_create_link: '링크 만들기',
|
||||||
|
com_nav_source_chat: '소스 채팅 보기',
|
||||||
com_ui_date_today: '오늘',
|
com_ui_date_today: '오늘',
|
||||||
com_ui_date_yesterday: '어제',
|
com_ui_date_yesterday: '어제',
|
||||||
com_ui_date_previous_7_days: '지난 7일',
|
com_ui_date_previous_7_days: '지난 7일',
|
||||||
|
|
@ -729,6 +752,43 @@ export const comparisons = {
|
||||||
english: 'chats',
|
english: 'chats',
|
||||||
translated: '채팅',
|
translated: '채팅',
|
||||||
},
|
},
|
||||||
|
com_ui_share: {
|
||||||
|
english: 'Share',
|
||||||
|
translated: 'Share',
|
||||||
|
},
|
||||||
|
com_ui_share_link_to_chat: {
|
||||||
|
english: 'Share link to chat',
|
||||||
|
translated: 'Share link to chat',
|
||||||
|
},
|
||||||
|
com_ui_share_error: {
|
||||||
|
english: 'There was an error sharing the chat link',
|
||||||
|
translated: 'There was an error sharing the chat link',
|
||||||
|
},
|
||||||
|
com_ui_share_create_message: {
|
||||||
|
english: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
translated: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_created_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_share_update_message: {
|
||||||
|
english: 'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
translated:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_updated_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_shared_link_not_found: {
|
||||||
|
english: 'Shared link not found',
|
||||||
|
translated: 'Shared link not found',
|
||||||
|
},
|
||||||
com_ui_delete: {
|
com_ui_delete: {
|
||||||
english: 'Delete',
|
english: 'Delete',
|
||||||
translated: '삭제',
|
translated: '삭제',
|
||||||
|
|
@ -1397,6 +1457,30 @@ export const comparisons = {
|
||||||
english: 'Export conversation',
|
english: 'Export conversation',
|
||||||
translated: '대화 내보내기',
|
translated: '대화 내보내기',
|
||||||
},
|
},
|
||||||
|
com_nav_export: {
|
||||||
|
english: 'Export',
|
||||||
|
translated: '내보내기',
|
||||||
|
},
|
||||||
|
com_nav_shared_links: {
|
||||||
|
english: 'Shared links',
|
||||||
|
translated: '공유 링크',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_manage: {
|
||||||
|
english: 'Manage',
|
||||||
|
translated: '관리',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_empty: {
|
||||||
|
english: 'You have no shared links.',
|
||||||
|
translated: '공유 링크가 없습니다.',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_name: {
|
||||||
|
english: 'Name',
|
||||||
|
translated: '이름',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_date_shared: {
|
||||||
|
english: 'Date shared',
|
||||||
|
translated: '공유 날짜',
|
||||||
|
},
|
||||||
com_nav_theme: {
|
com_nav_theme: {
|
||||||
english: 'Theme',
|
english: 'Theme',
|
||||||
translated: '테마',
|
translated: '테마',
|
||||||
|
|
@ -1497,6 +1581,30 @@ export const comparisons = {
|
||||||
english: 'Data controls',
|
english: 'Data controls',
|
||||||
translated: '데이터 제어',
|
translated: '데이터 제어',
|
||||||
},
|
},
|
||||||
|
com_ui_copied: {
|
||||||
|
english: 'Copied!',
|
||||||
|
translated: '복사됨',
|
||||||
|
},
|
||||||
|
com_ui_copy_code: {
|
||||||
|
english: 'Copy code',
|
||||||
|
translated: '코드 복사',
|
||||||
|
},
|
||||||
|
com_ui_copy_link: {
|
||||||
|
english: 'Copy link',
|
||||||
|
translated: '링크 복사',
|
||||||
|
},
|
||||||
|
com_ui_update_link: {
|
||||||
|
english: 'Update link',
|
||||||
|
translated: '링크 업데이트',
|
||||||
|
},
|
||||||
|
com_ui_create_link: {
|
||||||
|
english: 'Create link',
|
||||||
|
translated: '링크 만들기',
|
||||||
|
},
|
||||||
|
com_nav_source_chat: {
|
||||||
|
english: 'View source chat',
|
||||||
|
translated: '소스 채팅 보기',
|
||||||
|
},
|
||||||
com_ui_date_today: {
|
com_ui_date_today: {
|
||||||
english: 'Today',
|
english: 'Today',
|
||||||
translated: '오늘',
|
translated: '오늘',
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,17 @@ export default {
|
||||||
'Er is een fout opgetreden bij het importeren van je gesprekken',
|
'Er is een fout opgetreden bij het importeren van je gesprekken',
|
||||||
com_ui_confirm_action: 'Bevestig actie',
|
com_ui_confirm_action: 'Bevestig actie',
|
||||||
com_ui_chats: 'chats',
|
com_ui_chats: 'chats',
|
||||||
|
com_ui_share: 'Share',
|
||||||
|
com_ui_share_link_to_chat: 'Share link to chat',
|
||||||
|
com_ui_share_error: 'There was an error sharing the chat link',
|
||||||
|
com_ui_share_create_message: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_created_message:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_share_update_message:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_updated_message:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_shared_link_not_found: 'Shared link not found',
|
||||||
com_ui_delete: 'Verwijderen',
|
com_ui_delete: 'Verwijderen',
|
||||||
com_ui_delete_conversation: 'Chat verwijderen?',
|
com_ui_delete_conversation: 'Chat verwijderen?',
|
||||||
com_ui_delete_conversation_confirm: 'Hiermee wordt',
|
com_ui_delete_conversation_confirm: 'Hiermee wordt',
|
||||||
|
|
@ -261,6 +272,12 @@ export default {
|
||||||
com_nav_export_recursive_or_sequential: 'Recursief of sequentieel?',
|
com_nav_export_recursive_or_sequential: 'Recursief of sequentieel?',
|
||||||
com_nav_export_recursive: 'Recursief',
|
com_nav_export_recursive: 'Recursief',
|
||||||
com_nav_export_conversation: 'Conversatie exporteren',
|
com_nav_export_conversation: 'Conversatie exporteren',
|
||||||
|
com_nav_export: 'Exporteren',
|
||||||
|
com_nav_shared_links: 'Gedeelde links',
|
||||||
|
com_nav_shared_links_manage: 'Beheren',
|
||||||
|
com_nav_shared_links_empty: 'U hebt geen gedeeld links.',
|
||||||
|
com_nav_shared_links_name: 'Naam',
|
||||||
|
com_nav_shared_links_date_shared: 'Datum gedeeld',
|
||||||
com_nav_theme: 'Thema',
|
com_nav_theme: 'Thema',
|
||||||
com_nav_theme_system: 'Systeem',
|
com_nav_theme_system: 'Systeem',
|
||||||
com_nav_theme_dark: 'Donker',
|
com_nav_theme_dark: 'Donker',
|
||||||
|
|
@ -494,6 +511,43 @@ export const comparisons = {
|
||||||
english: 'chats',
|
english: 'chats',
|
||||||
translated: 'chats',
|
translated: 'chats',
|
||||||
},
|
},
|
||||||
|
com_ui_share: {
|
||||||
|
english: 'Share',
|
||||||
|
translated: 'Share',
|
||||||
|
},
|
||||||
|
com_ui_share_link_to_chat: {
|
||||||
|
english: 'Share link to chat',
|
||||||
|
translated: 'Share link to chat',
|
||||||
|
},
|
||||||
|
com_ui_share_error: {
|
||||||
|
english: 'There was an error sharing the chat link',
|
||||||
|
translated: 'There was an error sharing the chat link',
|
||||||
|
},
|
||||||
|
com_ui_share_create_message: {
|
||||||
|
english: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
translated: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_created_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_share_update_message: {
|
||||||
|
english: 'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
translated:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_updated_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_shared_link_not_found: {
|
||||||
|
english: 'Shared link not found',
|
||||||
|
translated: 'Shared link not found',
|
||||||
|
},
|
||||||
com_ui_delete: {
|
com_ui_delete: {
|
||||||
english: 'Delete',
|
english: 'Delete',
|
||||||
translated: 'Verwijderen',
|
translated: 'Verwijderen',
|
||||||
|
|
@ -1220,6 +1274,30 @@ export const comparisons = {
|
||||||
english: 'Export conversation',
|
english: 'Export conversation',
|
||||||
translated: 'Conversatie exporteren',
|
translated: 'Conversatie exporteren',
|
||||||
},
|
},
|
||||||
|
com_nav_export: {
|
||||||
|
english: 'Export',
|
||||||
|
translated: 'Exporteren',
|
||||||
|
},
|
||||||
|
com_nav_shared_links: {
|
||||||
|
english: 'Shared links',
|
||||||
|
translated: 'Gedeelde links',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_manage: {
|
||||||
|
english: 'Manage',
|
||||||
|
translated: 'Beheren',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_empty: {
|
||||||
|
english: 'You have no shared links.',
|
||||||
|
translated: 'U hebt geen gedeeld links.',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_name: {
|
||||||
|
english: 'Name',
|
||||||
|
translated: 'Naam',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_date_shared: {
|
||||||
|
english: 'Date shared',
|
||||||
|
translated: 'Datum gedeeld',
|
||||||
|
},
|
||||||
com_nav_theme: {
|
com_nav_theme: {
|
||||||
english: 'Theme',
|
english: 'Theme',
|
||||||
translated: 'Thema',
|
translated: 'Thema',
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,17 @@ export default {
|
||||||
com_ui_entries: 'wpisów',
|
com_ui_entries: 'wpisów',
|
||||||
com_ui_pay_per_call:
|
com_ui_pay_per_call:
|
||||||
'Wszystkie rozmowy z AI w jednym miejscu. Płatność za połączenie, a nie za miesiąc',
|
'Wszystkie rozmowy z AI w jednym miejscu. Płatność za połączenie, a nie za miesiąc',
|
||||||
|
com_ui_share: 'Share',
|
||||||
|
com_ui_share_link_to_chat: 'Share link to chat',
|
||||||
|
com_ui_share_error: 'There was an error sharing the chat link',
|
||||||
|
com_ui_share_create_message: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_created_message:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_share_update_message:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_updated_message:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_shared_link_not_found: 'Shared link not found',
|
||||||
com_ui_rename: 'Zmień nazwę',
|
com_ui_rename: 'Zmień nazwę',
|
||||||
com_ui_archive: 'Archiwum',
|
com_ui_archive: 'Archiwum',
|
||||||
com_ui_archive_error: 'Nie udało się archiwizować rozmowy',
|
com_ui_archive_error: 'Nie udało się archiwizować rozmowy',
|
||||||
|
|
@ -192,6 +203,11 @@ export default {
|
||||||
com_nav_export_recursive_or_sequential: 'Rekurencyjny czy sekwencyjny?',
|
com_nav_export_recursive_or_sequential: 'Rekurencyjny czy sekwencyjny?',
|
||||||
com_nav_export_recursive: 'Rekurencyjny',
|
com_nav_export_recursive: 'Rekurencyjny',
|
||||||
com_nav_export_conversation: 'Eksportuj konwersację',
|
com_nav_export_conversation: 'Eksportuj konwersację',
|
||||||
|
com_nav_shared_links: 'Linki udostępnione',
|
||||||
|
com_nav_shared_links_manage: 'Beheren',
|
||||||
|
com_nav_shared_links_empty: 'U hebt geen gedeeld links.',
|
||||||
|
com_nav_shared_links_name: 'Naam',
|
||||||
|
com_nav_shared_links_date_shared: 'Datum gedeeld',
|
||||||
com_nav_theme: 'Motyw',
|
com_nav_theme: 'Motyw',
|
||||||
com_nav_theme_system: 'Domyślny',
|
com_nav_theme_system: 'Domyślny',
|
||||||
com_nav_theme_dark: 'Ciemny',
|
com_nav_theme_dark: 'Ciemny',
|
||||||
|
|
@ -321,6 +337,43 @@ export const comparisons = {
|
||||||
english: 'All AI conversations in one place. Pay per call and not per month',
|
english: 'All AI conversations in one place. Pay per call and not per month',
|
||||||
translated: 'Wszystkie rozmowy z AI w jednym miejscu. Płatność za połączenie, a nie za miesiąc',
|
translated: 'Wszystkie rozmowy z AI w jednym miejscu. Płatność za połączenie, a nie za miesiąc',
|
||||||
},
|
},
|
||||||
|
com_ui_share: {
|
||||||
|
english: 'Share',
|
||||||
|
translated: 'Share',
|
||||||
|
},
|
||||||
|
com_ui_share_link_to_chat: {
|
||||||
|
english: 'Share link to chat',
|
||||||
|
translated: 'Share link to chat',
|
||||||
|
},
|
||||||
|
com_ui_share_error: {
|
||||||
|
english: 'There was an error sharing the chat link',
|
||||||
|
translated: 'There was an error sharing the chat link',
|
||||||
|
},
|
||||||
|
com_ui_share_create_message: {
|
||||||
|
english: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
translated: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_created_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_share_update_message: {
|
||||||
|
english: 'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
translated:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_updated_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_shared_link_not_found: {
|
||||||
|
english: 'Shared link not found',
|
||||||
|
translated: 'Shared link not found',
|
||||||
|
},
|
||||||
com_ui_rename: {
|
com_ui_rename: {
|
||||||
english: 'Rename',
|
english: 'Rename',
|
||||||
translated: 'Zmień nazwę',
|
translated: 'Zmień nazwę',
|
||||||
|
|
@ -898,6 +951,26 @@ export const comparisons = {
|
||||||
english: 'Export conversation',
|
english: 'Export conversation',
|
||||||
translated: 'Eksportuj konwersację',
|
translated: 'Eksportuj konwersację',
|
||||||
},
|
},
|
||||||
|
com_nav_shared_links: {
|
||||||
|
english: 'Shared links',
|
||||||
|
translated: 'Linki udostępnione',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_manage: {
|
||||||
|
english: 'Manage',
|
||||||
|
translated: 'Beheren',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_empty: {
|
||||||
|
english: 'You have no shared links.',
|
||||||
|
translated: 'U hebt geen gedeeld links.',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_name: {
|
||||||
|
english: 'Name',
|
||||||
|
translated: 'Naam',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_date_shared: {
|
||||||
|
english: 'Date shared',
|
||||||
|
translated: 'Datum gedeeld',
|
||||||
|
},
|
||||||
com_nav_theme: {
|
com_nav_theme: {
|
||||||
english: 'Theme',
|
english: 'Theme',
|
||||||
translated: 'Motyw',
|
translated: 'Motyw',
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,17 @@ export default {
|
||||||
com_ui_preview: 'Предпросмотр',
|
com_ui_preview: 'Предпросмотр',
|
||||||
com_ui_upload: 'Загрузить',
|
com_ui_upload: 'Загрузить',
|
||||||
com_ui_connect: 'Подключить',
|
com_ui_connect: 'Подключить',
|
||||||
|
com_ui_share: 'Share',
|
||||||
|
com_ui_share_link_to_chat: 'Share link to chat',
|
||||||
|
com_ui_share_error: 'There was an error sharing the chat link',
|
||||||
|
com_ui_share_create_message: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_created_message:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_share_update_message:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_updated_message:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_shared_link_not_found: 'Shared link not found',
|
||||||
com_ui_delete_conversation: 'Удалить чат?',
|
com_ui_delete_conversation: 'Удалить чат?',
|
||||||
com_ui_delete_conversation_confirm: 'Будет удален следующий чат: ',
|
com_ui_delete_conversation_confirm: 'Будет удален следующий чат: ',
|
||||||
com_ui_rename: 'Переименовать',
|
com_ui_rename: 'Переименовать',
|
||||||
|
|
@ -302,6 +313,12 @@ export default {
|
||||||
com_nav_export_recursive_or_sequential: 'Рекурсивно или последовательно?',
|
com_nav_export_recursive_or_sequential: 'Рекурсивно или последовательно?',
|
||||||
com_nav_export_recursive: 'Рекурсивно',
|
com_nav_export_recursive: 'Рекурсивно',
|
||||||
com_nav_export_conversation: 'Экспортировать разговор',
|
com_nav_export_conversation: 'Экспортировать разговор',
|
||||||
|
com_nav_export: 'Экспорт',
|
||||||
|
com_nav_shared_links: 'Связываемые ссылки',
|
||||||
|
com_nav_shared_links_manage: 'Управление',
|
||||||
|
com_nav_shared_links_empty: 'У вас нет связываемых ссылок.',
|
||||||
|
com_nav_shared_links_name: 'Naam',
|
||||||
|
com_nav_shared_links_date_shared: 'Datum gedeeld',
|
||||||
com_nav_my_files: 'Мои файлы',
|
com_nav_my_files: 'Мои файлы',
|
||||||
com_nav_theme: 'Тема',
|
com_nav_theme: 'Тема',
|
||||||
com_nav_theme_system: 'Системная',
|
com_nav_theme_system: 'Системная',
|
||||||
|
|
@ -364,6 +381,12 @@ export default {
|
||||||
com_ui_upload_error: 'Произошла ошибка при загрузке вашего файла',
|
com_ui_upload_error: 'Произошла ошибка при загрузке вашего файла',
|
||||||
com_user_message: 'Вы',
|
com_user_message: 'Вы',
|
||||||
/* The following are AI Translated */
|
/* The following are AI Translated */
|
||||||
|
com_ui_copied: 'Скопировано',
|
||||||
|
com_ui_copy_code: 'Копировать код',
|
||||||
|
com_ui_copy_link: 'Копировать ссылку',
|
||||||
|
com_ui_update_link: 'Обновить ссылку',
|
||||||
|
com_ui_create_link: 'Создать ссылку',
|
||||||
|
com_nav_source_chat: 'Просмотреть исходный чат',
|
||||||
com_ui_date_today: 'Сегодня',
|
com_ui_date_today: 'Сегодня',
|
||||||
com_ui_date_yesterday: 'Вчера',
|
com_ui_date_yesterday: 'Вчера',
|
||||||
com_ui_date_previous_7_days: 'Предыдущие 7 дней',
|
com_ui_date_previous_7_days: 'Предыдущие 7 дней',
|
||||||
|
|
@ -800,6 +823,43 @@ export const comparisons = {
|
||||||
english: 'Connect',
|
english: 'Connect',
|
||||||
translated: 'Подключить',
|
translated: 'Подключить',
|
||||||
},
|
},
|
||||||
|
com_ui_share: {
|
||||||
|
english: 'Share',
|
||||||
|
translated: 'Share',
|
||||||
|
},
|
||||||
|
com_ui_share_link_to_chat: {
|
||||||
|
english: 'Share link to chat',
|
||||||
|
translated: 'Share link to chat',
|
||||||
|
},
|
||||||
|
com_ui_share_error: {
|
||||||
|
english: 'There was an error sharing the chat link',
|
||||||
|
translated: 'There was an error sharing the chat link',
|
||||||
|
},
|
||||||
|
com_ui_share_create_message: {
|
||||||
|
english: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
translated: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_created_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_share_update_message: {
|
||||||
|
english: 'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
translated:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_updated_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_shared_link_not_found: {
|
||||||
|
english: 'Shared link not found',
|
||||||
|
translated: 'Shared link not found',
|
||||||
|
},
|
||||||
com_ui_delete_conversation: {
|
com_ui_delete_conversation: {
|
||||||
english: 'Delete chat?',
|
english: 'Delete chat?',
|
||||||
translated: 'Удалить чат?',
|
translated: 'Удалить чат?',
|
||||||
|
|
@ -1635,6 +1695,30 @@ export const comparisons = {
|
||||||
english: 'Export conversation',
|
english: 'Export conversation',
|
||||||
translated: 'Экспортировать разговор',
|
translated: 'Экспортировать разговор',
|
||||||
},
|
},
|
||||||
|
com_nav_export: {
|
||||||
|
english: 'Export',
|
||||||
|
translated: 'Экспорт',
|
||||||
|
},
|
||||||
|
com_nav_shared_links: {
|
||||||
|
english: 'Shared links',
|
||||||
|
translated: 'Связываемые ссылки',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_manage: {
|
||||||
|
english: 'Manage',
|
||||||
|
translated: 'Управление',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_empty: {
|
||||||
|
english: 'You have no shared links.',
|
||||||
|
translated: 'У вас нет связываемых ссылок.',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_name: {
|
||||||
|
english: 'Name',
|
||||||
|
translated: 'Naam',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_date_shared: {
|
||||||
|
english: 'Date shared',
|
||||||
|
translated: 'Datum gedeeld',
|
||||||
|
},
|
||||||
com_nav_my_files: {
|
com_nav_my_files: {
|
||||||
english: 'My Files',
|
english: 'My Files',
|
||||||
translated: 'Мои файлы',
|
translated: 'Мои файлы',
|
||||||
|
|
@ -1864,6 +1948,30 @@ export const comparisons = {
|
||||||
english: 'You',
|
english: 'You',
|
||||||
translated: 'Вы',
|
translated: 'Вы',
|
||||||
},
|
},
|
||||||
|
com_ui_copied: {
|
||||||
|
english: 'Copied!',
|
||||||
|
translated: 'Скопировано',
|
||||||
|
},
|
||||||
|
com_ui_copy_code: {
|
||||||
|
english: 'Copy code',
|
||||||
|
translated: 'Копировать код',
|
||||||
|
},
|
||||||
|
com_ui_copy_link: {
|
||||||
|
english: 'Copy link',
|
||||||
|
translated: 'Копировать ссылку',
|
||||||
|
},
|
||||||
|
com_ui_update_link: {
|
||||||
|
english: 'Update link',
|
||||||
|
translated: 'Обновить ссылку',
|
||||||
|
},
|
||||||
|
com_ui_create_link: {
|
||||||
|
english: 'Create link',
|
||||||
|
translated: 'Создать ссылку',
|
||||||
|
},
|
||||||
|
com_nav_source_chat: {
|
||||||
|
english: 'View source chat',
|
||||||
|
translated: 'Просмотреть исходный чат',
|
||||||
|
},
|
||||||
com_ui_date_today: {
|
com_ui_date_today: {
|
||||||
english: 'Today',
|
english: 'Today',
|
||||||
translated: 'Сегодня',
|
translated: 'Сегодня',
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,17 @@ export default {
|
||||||
com_ui_import_conversation_error: 'Det uppstod ett fel vid import av dina konversationer',
|
com_ui_import_conversation_error: 'Det uppstod ett fel vid import av dina konversationer',
|
||||||
com_ui_confirm_action: 'Bekräfta åtgärd',
|
com_ui_confirm_action: 'Bekräfta åtgärd',
|
||||||
com_ui_chats: 'chattar',
|
com_ui_chats: 'chattar',
|
||||||
|
com_ui_share: 'Share',
|
||||||
|
com_ui_share_link_to_chat: 'Share link to chat',
|
||||||
|
com_ui_share_error: 'There was an error sharing the chat link',
|
||||||
|
com_ui_share_create_message: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_created_message:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_share_update_message:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_updated_message:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_shared_link_not_found: 'Shared link not found',
|
||||||
com_ui_delete: 'Radera',
|
com_ui_delete: 'Radera',
|
||||||
com_ui_delete_conversation: 'Radera chatt?',
|
com_ui_delete_conversation: 'Radera chatt?',
|
||||||
com_ui_delete_conversation_confirm: 'Detta kommer att radera',
|
com_ui_delete_conversation_confirm: 'Detta kommer att radera',
|
||||||
|
|
@ -249,6 +260,12 @@ export default {
|
||||||
com_nav_export_recursive_or_sequential: 'Rekursiv eller sekventiell?',
|
com_nav_export_recursive_or_sequential: 'Rekursiv eller sekventiell?',
|
||||||
com_nav_export_recursive: 'Rekursiv',
|
com_nav_export_recursive: 'Rekursiv',
|
||||||
com_nav_export_conversation: 'Exportera konversation',
|
com_nav_export_conversation: 'Exportera konversation',
|
||||||
|
com_nav_export: 'Exportera',
|
||||||
|
com_nav_shared_links: 'Delade länkar',
|
||||||
|
com_nav_shared_links_manage: 'Hantera',
|
||||||
|
com_nav_shared_links_empty: 'Du har inga delade länkar.',
|
||||||
|
com_nav_shared_links_name: 'Namn',
|
||||||
|
com_nav_shared_links_date_shared: 'Datum delad',
|
||||||
com_nav_theme: 'Tema',
|
com_nav_theme: 'Tema',
|
||||||
com_nav_theme_system: 'System',
|
com_nav_theme_system: 'System',
|
||||||
com_nav_theme_dark: 'Mörkt',
|
com_nav_theme_dark: 'Mörkt',
|
||||||
|
|
@ -474,6 +491,43 @@ export const comparisons = {
|
||||||
english: 'chats',
|
english: 'chats',
|
||||||
translated: 'chattar',
|
translated: 'chattar',
|
||||||
},
|
},
|
||||||
|
com_ui_share: {
|
||||||
|
english: 'Share',
|
||||||
|
translated: 'Share',
|
||||||
|
},
|
||||||
|
com_ui_share_link_to_chat: {
|
||||||
|
english: 'Share link to chat',
|
||||||
|
translated: 'Share link to chat',
|
||||||
|
},
|
||||||
|
com_ui_share_error: {
|
||||||
|
english: 'There was an error sharing the chat link',
|
||||||
|
translated: 'There was an error sharing the chat link',
|
||||||
|
},
|
||||||
|
com_ui_share_create_message: {
|
||||||
|
english: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
translated: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_created_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_share_update_message: {
|
||||||
|
english: 'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
translated:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_updated_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_shared_link_not_found: {
|
||||||
|
english: 'Shared link not found',
|
||||||
|
translated: 'Shared link not found',
|
||||||
|
},
|
||||||
com_ui_delete: {
|
com_ui_delete: {
|
||||||
english: 'Delete',
|
english: 'Delete',
|
||||||
translated: 'Radera',
|
translated: 'Radera',
|
||||||
|
|
@ -1185,6 +1239,30 @@ export const comparisons = {
|
||||||
english: 'Export conversation',
|
english: 'Export conversation',
|
||||||
translated: 'Exportera konversation',
|
translated: 'Exportera konversation',
|
||||||
},
|
},
|
||||||
|
com_nav_export: {
|
||||||
|
english: 'Export',
|
||||||
|
translated: 'Exportera',
|
||||||
|
},
|
||||||
|
com_nav_shared_links: {
|
||||||
|
english: 'Shared links',
|
||||||
|
translated: 'Delade länkar',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_manage: {
|
||||||
|
english: 'Manage',
|
||||||
|
translated: 'Hantera',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_empty: {
|
||||||
|
english: 'You have no shared links.',
|
||||||
|
translated: 'Du har inga delade länkar.',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_name: {
|
||||||
|
english: 'Name',
|
||||||
|
translated: 'Namn',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_date_shared: {
|
||||||
|
english: 'Date shared',
|
||||||
|
translated: 'Datum delad',
|
||||||
|
},
|
||||||
com_nav_theme: {
|
com_nav_theme: {
|
||||||
english: 'Theme',
|
english: 'Theme',
|
||||||
translated: 'Tema',
|
translated: 'Tema',
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,17 @@ export default {
|
||||||
com_ui_import_conversation_error: 'Sohbetlerinizi içe aktarırken bir hata oluştu',
|
com_ui_import_conversation_error: 'Sohbetlerinizi içe aktarırken bir hata oluştu',
|
||||||
com_ui_confirm_action: 'İşlemi Onayla',
|
com_ui_confirm_action: 'İşlemi Onayla',
|
||||||
com_ui_chats: 'sohbetler',
|
com_ui_chats: 'sohbetler',
|
||||||
|
com_ui_share: 'Share',
|
||||||
|
com_ui_share_link_to_chat: 'Share link to chat',
|
||||||
|
com_ui_share_error: 'There was an error sharing the chat link',
|
||||||
|
com_ui_share_create_message: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_created_message:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_share_update_message:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_updated_message:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_shared_link_not_found: 'Shared link not found',
|
||||||
com_ui_delete: 'Sil',
|
com_ui_delete: 'Sil',
|
||||||
com_ui_delete_conversation: 'Sohbet silinecek?',
|
com_ui_delete_conversation: 'Sohbet silinecek?',
|
||||||
com_ui_delete_conversation_confirm: 'Bu silinecek',
|
com_ui_delete_conversation_confirm: 'Bu silinecek',
|
||||||
|
|
@ -277,6 +288,12 @@ export default {
|
||||||
com_nav_export_recursive_or_sequential: 'Yinelemeli mi yoksa sıralı mı?',
|
com_nav_export_recursive_or_sequential: 'Yinelemeli mi yoksa sıralı mı?',
|
||||||
com_nav_export_recursive: 'Yinelemeli',
|
com_nav_export_recursive: 'Yinelemeli',
|
||||||
com_nav_export_conversation: 'Konuşmayı dışa aktar',
|
com_nav_export_conversation: 'Konuşmayı dışa aktar',
|
||||||
|
com_nav_export: 'Dışa Aktar',
|
||||||
|
com_nav_shared_links: 'Paylaşılan linkler',
|
||||||
|
com_nav_shared_links_manage: 'Ynetmek',
|
||||||
|
com_nav_shared_links_empty: 'Paylaşılan linkleriniz yok.',
|
||||||
|
com_nav_shared_links_name: 'İsim',
|
||||||
|
com_nav_shared_links_date_shared: 'Paylaşılan tarih',
|
||||||
com_nav_theme: 'Tema',
|
com_nav_theme: 'Tema',
|
||||||
com_nav_theme_system: 'Sistem',
|
com_nav_theme_system: 'Sistem',
|
||||||
com_nav_theme_dark: 'Koyu',
|
com_nav_theme_dark: 'Koyu',
|
||||||
|
|
@ -510,6 +527,43 @@ export const comparisons = {
|
||||||
english: 'chats',
|
english: 'chats',
|
||||||
translated: 'sohbetler',
|
translated: 'sohbetler',
|
||||||
},
|
},
|
||||||
|
com_ui_share: {
|
||||||
|
english: 'Share',
|
||||||
|
translated: 'Share',
|
||||||
|
},
|
||||||
|
com_ui_share_link_to_chat: {
|
||||||
|
english: 'Share link to chat',
|
||||||
|
translated: 'Share link to chat',
|
||||||
|
},
|
||||||
|
com_ui_share_error: {
|
||||||
|
english: 'There was an error sharing the chat link',
|
||||||
|
translated: 'There was an error sharing the chat link',
|
||||||
|
},
|
||||||
|
com_ui_share_create_message: {
|
||||||
|
english: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
translated: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_created_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_share_update_message: {
|
||||||
|
english: 'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
translated:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_updated_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_shared_link_not_found: {
|
||||||
|
english: 'Shared link not found',
|
||||||
|
translated: 'Shared link not found',
|
||||||
|
},
|
||||||
com_ui_delete: {
|
com_ui_delete: {
|
||||||
english: 'Delete',
|
english: 'Delete',
|
||||||
translated: 'Sil',
|
translated: 'Sil',
|
||||||
|
|
@ -1302,6 +1356,30 @@ export const comparisons = {
|
||||||
english: 'Export conversation',
|
english: 'Export conversation',
|
||||||
translated: 'Konuşmayı dışa aktar',
|
translated: 'Konuşmayı dışa aktar',
|
||||||
},
|
},
|
||||||
|
com_nav_export: {
|
||||||
|
english: 'Export',
|
||||||
|
translated: 'Dışa Aktar',
|
||||||
|
},
|
||||||
|
com_nav_shared_links: {
|
||||||
|
english: 'Shared links',
|
||||||
|
translated: 'Paylaşılan linkler',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_manage: {
|
||||||
|
english: 'Manage',
|
||||||
|
translated: 'Ynetmek',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_empty: {
|
||||||
|
english: 'You have no shared links.',
|
||||||
|
translated: 'Paylaşılan linkleriniz yok.',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_name: {
|
||||||
|
english: 'Name',
|
||||||
|
translated: 'İsim',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_date_shared: {
|
||||||
|
english: 'Date shared',
|
||||||
|
translated: 'Paylaşılan tarih',
|
||||||
|
},
|
||||||
com_nav_theme: {
|
com_nav_theme: {
|
||||||
english: 'Theme',
|
english: 'Theme',
|
||||||
translated: 'Tema',
|
translated: 'Tema',
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,17 @@ export default {
|
||||||
com_ui_import_conversation_error: 'Đã xảy ra lỗi khi nhập khẩu cuộc trò chuyện của bạn',
|
com_ui_import_conversation_error: 'Đã xảy ra lỗi khi nhập khẩu cuộc trò chuyện của bạn',
|
||||||
com_ui_confirm_action: 'Xác nhận hành động',
|
com_ui_confirm_action: 'Xác nhận hành động',
|
||||||
com_ui_chats: 'cuộc trò chuyện',
|
com_ui_chats: 'cuộc trò chuyện',
|
||||||
|
com_ui_share: 'Share',
|
||||||
|
com_ui_share_link_to_chat: 'Share link to chat',
|
||||||
|
com_ui_share_error: 'There was an error sharing the chat link',
|
||||||
|
com_ui_share_create_message: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_created_message:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_share_update_message:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_updated_message:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_shared_link_not_found: 'Shared link not found',
|
||||||
com_ui_delete: 'Xóa',
|
com_ui_delete: 'Xóa',
|
||||||
com_ui_delete_conversation: 'Xóa cuộc trò chuyện?',
|
com_ui_delete_conversation: 'Xóa cuộc trò chuyện?',
|
||||||
com_ui_delete_conversation_confirm: 'Điều này sẽ xóa',
|
com_ui_delete_conversation_confirm: 'Điều này sẽ xóa',
|
||||||
|
|
@ -254,6 +265,12 @@ export default {
|
||||||
com_nav_export_recursive_or_sequential: 'Đệ quy hay tuần tự?',
|
com_nav_export_recursive_or_sequential: 'Đệ quy hay tuần tự?',
|
||||||
com_nav_export_recursive: 'Đệ quy',
|
com_nav_export_recursive: 'Đệ quy',
|
||||||
com_nav_export_conversation: 'Xuất cuộc trò chuyện',
|
com_nav_export_conversation: 'Xuất cuộc trò chuyện',
|
||||||
|
com_nav_export: 'Xuất',
|
||||||
|
com_nav_shared_links: 'Liên kết được chia sẻ',
|
||||||
|
com_nav_shared_links_manage: 'Quản l',
|
||||||
|
com_nav_shared_links_empty: 'Bạn không có link được chia sẻ.',
|
||||||
|
com_nav_shared_links_name: 'Tên',
|
||||||
|
com_nav_shared_links_date_shared: 'Ngày chia sẻ',
|
||||||
com_nav_theme: 'Chủ đề',
|
com_nav_theme: 'Chủ đề',
|
||||||
com_nav_theme_system: 'Hệ thống',
|
com_nav_theme_system: 'Hệ thống',
|
||||||
com_nav_theme_dark: 'Tối',
|
com_nav_theme_dark: 'Tối',
|
||||||
|
|
@ -473,6 +490,43 @@ export const comparisons = {
|
||||||
english: 'chats',
|
english: 'chats',
|
||||||
translated: 'cuộc trò chuyện',
|
translated: 'cuộc trò chuyện',
|
||||||
},
|
},
|
||||||
|
com_ui_share: {
|
||||||
|
english: 'Share',
|
||||||
|
translated: 'Share',
|
||||||
|
},
|
||||||
|
com_ui_share_link_to_chat: {
|
||||||
|
english: 'Share link to chat',
|
||||||
|
translated: 'Share link to chat',
|
||||||
|
},
|
||||||
|
com_ui_share_error: {
|
||||||
|
english: 'There was an error sharing the chat link',
|
||||||
|
translated: 'There was an error sharing the chat link',
|
||||||
|
},
|
||||||
|
com_ui_share_create_message: {
|
||||||
|
english: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
translated: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_created_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_share_update_message: {
|
||||||
|
english: 'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
translated:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_updated_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_shared_link_not_found: {
|
||||||
|
english: 'Shared link not found',
|
||||||
|
translated: 'Shared link not found',
|
||||||
|
},
|
||||||
com_ui_delete: {
|
com_ui_delete: {
|
||||||
english: 'Delete',
|
english: 'Delete',
|
||||||
translated: 'Xóa',
|
translated: 'Xóa',
|
||||||
|
|
@ -1193,6 +1247,30 @@ export const comparisons = {
|
||||||
english: 'Export conversation',
|
english: 'Export conversation',
|
||||||
translated: 'Xuất cuộc trò chuyện',
|
translated: 'Xuất cuộc trò chuyện',
|
||||||
},
|
},
|
||||||
|
com_nav_export: {
|
||||||
|
english: 'Export',
|
||||||
|
translated: 'Xuất',
|
||||||
|
},
|
||||||
|
com_nav_shared_links: {
|
||||||
|
english: 'Shared links',
|
||||||
|
translated: 'Liên kết được chia sẻ',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_manage: {
|
||||||
|
english: 'Manage',
|
||||||
|
translated: 'Quản l',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_empty: {
|
||||||
|
english: 'You have no shared links.',
|
||||||
|
translated: 'Bạn không có link được chia sẻ.',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_name: {
|
||||||
|
english: 'Name',
|
||||||
|
translated: 'Tên',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_date_shared: {
|
||||||
|
english: 'Date shared',
|
||||||
|
translated: 'Ngày chia sẻ',
|
||||||
|
},
|
||||||
com_nav_theme: {
|
com_nav_theme: {
|
||||||
english: 'Theme',
|
english: 'Theme',
|
||||||
translated: 'Chủ đề',
|
translated: 'Chủ đề',
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,17 @@ export default {
|
||||||
com_ui_assistants_output: '助手输出',
|
com_ui_assistants_output: '助手输出',
|
||||||
com_ui_delete: '删除',
|
com_ui_delete: '删除',
|
||||||
com_ui_create: '创建',
|
com_ui_create: '创建',
|
||||||
|
com_ui_share: 'Share',
|
||||||
|
com_ui_share_link_to_chat: 'Share link to chat',
|
||||||
|
com_ui_share_error: 'There was an error sharing the chat link',
|
||||||
|
com_ui_share_create_message: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_created_message:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_share_update_message:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_updated_message:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_shared_link_not_found: 'Shared link not found',
|
||||||
com_ui_delete_conversation: '删除对话?',
|
com_ui_delete_conversation: '删除对话?',
|
||||||
com_ui_delete_conversation_confirm: '这将删除',
|
com_ui_delete_conversation_confirm: '这将删除',
|
||||||
com_ui_delete_assistant_confirm: '确定要删除此助手吗?该操作无法撤销。',
|
com_ui_delete_assistant_confirm: '确定要删除此助手吗?该操作无法撤销。',
|
||||||
|
|
@ -386,6 +397,12 @@ export default {
|
||||||
com_nav_export_recursive_or_sequential: '递归或顺序?',
|
com_nav_export_recursive_or_sequential: '递归或顺序?',
|
||||||
com_nav_export_recursive: '递归',
|
com_nav_export_recursive: '递归',
|
||||||
com_nav_export_conversation: '导出对话',
|
com_nav_export_conversation: '导出对话',
|
||||||
|
com_nav_export: '导出',
|
||||||
|
com_nav_shared_links: '共享链接',
|
||||||
|
com_nav_shared_links_manage: '管理',
|
||||||
|
com_nav_shared_links_empty: '您没有共享链接。',
|
||||||
|
com_nav_shared_links_name: '名称',
|
||||||
|
com_nav_shared_links_date_shared: '共享日期',
|
||||||
com_nav_my_files: '我的文件',
|
com_nav_my_files: '我的文件',
|
||||||
com_nav_theme: '主题',
|
com_nav_theme: '主题',
|
||||||
com_nav_theme_system: '跟随系统设置',
|
com_nav_theme_system: '跟随系统设置',
|
||||||
|
|
@ -417,6 +434,15 @@ export default {
|
||||||
com_nav_setting_data: '数据管理',
|
com_nav_setting_data: '数据管理',
|
||||||
com_nav_setting_account: '账户',
|
com_nav_setting_account: '账户',
|
||||||
/* The following are AI Translated */
|
/* The following are AI Translated */
|
||||||
|
com_ui_date_october: '十月',
|
||||||
|
com_ui_date_november: '十一月',
|
||||||
|
com_ui_date_december: '十二月',
|
||||||
|
com_ui_copied: '已复制!',
|
||||||
|
com_ui_copy_code: '复制代码',
|
||||||
|
com_ui_copy_link: '复制链接',
|
||||||
|
com_ui_update_link: '更新链接',
|
||||||
|
com_ui_create_link: '创建链接',
|
||||||
|
com_nav_source_chat: '查看源代码对话',
|
||||||
com_ui_date_today: '今天',
|
com_ui_date_today: '今天',
|
||||||
com_ui_date_yesterday: '昨天',
|
com_ui_date_yesterday: '昨天',
|
||||||
com_ui_date_previous_7_days: '过去7天',
|
com_ui_date_previous_7_days: '过去7天',
|
||||||
|
|
@ -1022,6 +1048,43 @@ export const comparisons = {
|
||||||
english: 'Create',
|
english: 'Create',
|
||||||
translated: '创建',
|
translated: '创建',
|
||||||
},
|
},
|
||||||
|
com_ui_share: {
|
||||||
|
english: 'Share',
|
||||||
|
translated: 'Share',
|
||||||
|
},
|
||||||
|
com_ui_share_link_to_chat: {
|
||||||
|
english: 'Share link to chat',
|
||||||
|
translated: 'Share link to chat',
|
||||||
|
},
|
||||||
|
com_ui_share_error: {
|
||||||
|
english: 'There was an error sharing the chat link',
|
||||||
|
translated: 'There was an error sharing the chat link',
|
||||||
|
},
|
||||||
|
com_ui_share_create_message: {
|
||||||
|
english: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
translated: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_created_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_share_update_message: {
|
||||||
|
english: 'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
translated:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_updated_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_shared_link_not_found: {
|
||||||
|
english: 'Shared link not found',
|
||||||
|
translated: 'Shared link not found',
|
||||||
|
},
|
||||||
com_ui_delete_conversation: {
|
com_ui_delete_conversation: {
|
||||||
english: 'Delete chat?',
|
english: 'Delete chat?',
|
||||||
translated: '删除对话?',
|
translated: '删除对话?',
|
||||||
|
|
@ -1991,6 +2054,30 @@ export const comparisons = {
|
||||||
english: 'Export conversation',
|
english: 'Export conversation',
|
||||||
translated: '导出对话',
|
translated: '导出对话',
|
||||||
},
|
},
|
||||||
|
com_nav_export: {
|
||||||
|
english: 'Export',
|
||||||
|
translated: '导出',
|
||||||
|
},
|
||||||
|
com_nav_shared_links: {
|
||||||
|
english: 'Shared links',
|
||||||
|
translated: '共享链接',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_manage: {
|
||||||
|
english: 'Manage',
|
||||||
|
translated: '管理',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_empty: {
|
||||||
|
english: 'You have no shared links.',
|
||||||
|
translated: '您没有共享链接。',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_name: {
|
||||||
|
english: 'Name',
|
||||||
|
translated: '名称',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_date_shared: {
|
||||||
|
english: 'Date shared',
|
||||||
|
translated: '共享日期',
|
||||||
|
},
|
||||||
com_nav_my_files: {
|
com_nav_my_files: {
|
||||||
english: 'My Files',
|
english: 'My Files',
|
||||||
translated: '我的文件',
|
translated: '我的文件',
|
||||||
|
|
@ -2111,6 +2198,42 @@ export const comparisons = {
|
||||||
english: 'Account',
|
english: 'Account',
|
||||||
translated: '账户',
|
translated: '账户',
|
||||||
},
|
},
|
||||||
|
com_ui_date_october: {
|
||||||
|
english: 'October',
|
||||||
|
translated: '十月',
|
||||||
|
},
|
||||||
|
com_ui_date_november: {
|
||||||
|
english: 'November',
|
||||||
|
translated: '十一月',
|
||||||
|
},
|
||||||
|
com_ui_date_december: {
|
||||||
|
english: 'December',
|
||||||
|
translated: '十二月',
|
||||||
|
},
|
||||||
|
com_ui_copied: {
|
||||||
|
english: 'Copied!',
|
||||||
|
translated: '已复制!',
|
||||||
|
},
|
||||||
|
com_ui_copy_code: {
|
||||||
|
english: 'Copy code',
|
||||||
|
translated: '复制代码',
|
||||||
|
},
|
||||||
|
com_ui_copy_link: {
|
||||||
|
english: 'Copy link',
|
||||||
|
translated: '复制链接',
|
||||||
|
},
|
||||||
|
com_ui_update_link: {
|
||||||
|
english: 'Update link',
|
||||||
|
translated: '更新链接',
|
||||||
|
},
|
||||||
|
com_ui_create_link: {
|
||||||
|
english: 'Create link',
|
||||||
|
translated: '创建链接',
|
||||||
|
},
|
||||||
|
com_nav_source_chat: {
|
||||||
|
english: 'View source chat',
|
||||||
|
translated: '查看源代码对话',
|
||||||
|
},
|
||||||
com_ui_date_today: {
|
com_ui_date_today: {
|
||||||
english: 'Today',
|
english: 'Today',
|
||||||
translated: '今天',
|
translated: '今天',
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,17 @@ export default {
|
||||||
com_ui_import_conversation_error: '導入對話時發生錯誤',
|
com_ui_import_conversation_error: '導入對話時發生錯誤',
|
||||||
com_ui_confirm_action: '確認操作',
|
com_ui_confirm_action: '確認操作',
|
||||||
com_ui_chats: '對話',
|
com_ui_chats: '對話',
|
||||||
|
com_ui_share: 'Share',
|
||||||
|
com_ui_share_link_to_chat: 'Share link to chat',
|
||||||
|
com_ui_share_error: 'There was an error sharing the chat link',
|
||||||
|
com_ui_share_create_message: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_created_message:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_share_update_message:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
com_ui_share_updated_message:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
com_ui_shared_link_not_found: 'Shared link not found',
|
||||||
com_ui_delete: '刪除',
|
com_ui_delete: '刪除',
|
||||||
com_ui_delete_conversation: '刪除對話?',
|
com_ui_delete_conversation: '刪除對話?',
|
||||||
com_ui_delete_conversation_confirm: '這將刪除',
|
com_ui_delete_conversation_confirm: '這將刪除',
|
||||||
|
|
@ -240,6 +251,12 @@ export default {
|
||||||
com_nav_export_recursive_or_sequential: '遞迴還是序列?',
|
com_nav_export_recursive_or_sequential: '遞迴還是序列?',
|
||||||
com_nav_export_recursive: '遞迴',
|
com_nav_export_recursive: '遞迴',
|
||||||
com_nav_export_conversation: '匯出對話',
|
com_nav_export_conversation: '匯出對話',
|
||||||
|
com_nav_export: '匯出',
|
||||||
|
com_nav_shared_links: '共享連結',
|
||||||
|
com_nav_shared_links_manage: '管理',
|
||||||
|
com_nav_shared_links_empty: '您沒有任何共享連結。',
|
||||||
|
com_nav_shared_links_name: '名称',
|
||||||
|
com_nav_shared_links_date_shared: '共享日期',
|
||||||
com_nav_theme: '主題',
|
com_nav_theme: '主題',
|
||||||
com_nav_theme_system: '跟隨系統設定',
|
com_nav_theme_system: '跟隨系統設定',
|
||||||
com_nav_theme_dark: '深色',
|
com_nav_theme_dark: '深色',
|
||||||
|
|
@ -266,6 +283,12 @@ export default {
|
||||||
com_nav_setting_general: '一般',
|
com_nav_setting_general: '一般',
|
||||||
com_nav_setting_data: '資料控制',
|
com_nav_setting_data: '資料控制',
|
||||||
/* The following are AI translated */
|
/* The following are AI translated */
|
||||||
|
com_ui_copied: '已複製!',
|
||||||
|
com_ui_copy_code: '複製程式碼',
|
||||||
|
com_ui_copy_link: '複製連結',
|
||||||
|
com_ui_update_link: '更新連結',
|
||||||
|
com_ui_create_link: '創建連結',
|
||||||
|
com_nav_source_chat: '檢視原始對話',
|
||||||
com_ui_date_today: '今天',
|
com_ui_date_today: '今天',
|
||||||
com_ui_date_yesterday: '昨天',
|
com_ui_date_yesterday: '昨天',
|
||||||
com_ui_date_previous_7_days: '前 7 天',
|
com_ui_date_previous_7_days: '前 7 天',
|
||||||
|
|
@ -711,6 +734,43 @@ export const comparisons = {
|
||||||
english: 'chats',
|
english: 'chats',
|
||||||
translated: '對話',
|
translated: '對話',
|
||||||
},
|
},
|
||||||
|
com_ui_share: {
|
||||||
|
english: 'Share',
|
||||||
|
translated: 'Share',
|
||||||
|
},
|
||||||
|
com_ui_share_link_to_chat: {
|
||||||
|
english: 'Share link to chat',
|
||||||
|
translated: 'Share link to chat',
|
||||||
|
},
|
||||||
|
com_ui_share_error: {
|
||||||
|
english: 'There was an error sharing the chat link',
|
||||||
|
translated: 'There was an error sharing the chat link',
|
||||||
|
},
|
||||||
|
com_ui_share_create_message: {
|
||||||
|
english: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
translated: 'Your name and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_created_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been created. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_share_update_message: {
|
||||||
|
english: 'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
translated:
|
||||||
|
'Your name, custom instructions, and any messages you add after sharing stay private.',
|
||||||
|
},
|
||||||
|
com_ui_share_updated_message: {
|
||||||
|
english:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
translated:
|
||||||
|
'A public link to your chat has been updated. Manage previously shared chats at any time via Settings.',
|
||||||
|
},
|
||||||
|
com_ui_shared_link_not_found: {
|
||||||
|
english: 'Shared link not found',
|
||||||
|
translated: 'Shared link not found',
|
||||||
|
},
|
||||||
com_ui_delete: {
|
com_ui_delete: {
|
||||||
english: 'Delete',
|
english: 'Delete',
|
||||||
translated: '刪除',
|
translated: '刪除',
|
||||||
|
|
@ -1427,6 +1487,30 @@ export const comparisons = {
|
||||||
english: 'Export conversation',
|
english: 'Export conversation',
|
||||||
translated: '匯出對話',
|
translated: '匯出對話',
|
||||||
},
|
},
|
||||||
|
com_nav_export: {
|
||||||
|
english: 'Export',
|
||||||
|
translated: '匯出',
|
||||||
|
},
|
||||||
|
com_nav_shared_links: {
|
||||||
|
english: 'Shared links',
|
||||||
|
translated: '共享連結',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_manage: {
|
||||||
|
english: 'Manage',
|
||||||
|
translated: '管理',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_empty: {
|
||||||
|
english: 'You have no shared links.',
|
||||||
|
translated: '您沒有任何共享連結。',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_name: {
|
||||||
|
english: 'Name',
|
||||||
|
translated: '名称',
|
||||||
|
},
|
||||||
|
com_nav_shared_links_date_shared: {
|
||||||
|
english: 'Date shared',
|
||||||
|
translated: '共享日期',
|
||||||
|
},
|
||||||
com_nav_theme: {
|
com_nav_theme: {
|
||||||
english: 'Theme',
|
english: 'Theme',
|
||||||
translated: '主題',
|
translated: '主題',
|
||||||
|
|
@ -1527,6 +1611,30 @@ export const comparisons = {
|
||||||
english: 'Data controls',
|
english: 'Data controls',
|
||||||
translated: '資料控制',
|
translated: '資料控制',
|
||||||
},
|
},
|
||||||
|
com_ui_copied: {
|
||||||
|
english: 'Copied!',
|
||||||
|
translated: '已複製!',
|
||||||
|
},
|
||||||
|
com_ui_copy_code: {
|
||||||
|
english: 'Copy code',
|
||||||
|
translated: '複製程式碼',
|
||||||
|
},
|
||||||
|
com_ui_copy_link: {
|
||||||
|
english: 'Copy link',
|
||||||
|
translated: '複製連結',
|
||||||
|
},
|
||||||
|
com_ui_update_link: {
|
||||||
|
english: 'Update link',
|
||||||
|
translated: '更新連結',
|
||||||
|
},
|
||||||
|
com_ui_create_link: {
|
||||||
|
english: 'Create link',
|
||||||
|
translated: '創建連結',
|
||||||
|
},
|
||||||
|
com_nav_source_chat: {
|
||||||
|
english: 'View source chat',
|
||||||
|
translated: '檢視原始對話',
|
||||||
|
},
|
||||||
com_ui_date_today: {
|
com_ui_date_today: {
|
||||||
english: 'Today',
|
english: 'Today',
|
||||||
translated: '今天',
|
translated: '今天',
|
||||||
|
|
|
||||||
|
|
@ -30,13 +30,13 @@ export default function Search() {
|
||||||
return (
|
return (
|
||||||
<MinimalMessagesWrapper ref={containerRef} className="pt-4">
|
<MinimalMessagesWrapper ref={containerRef} className="pt-4">
|
||||||
{(messages && messages?.length == 0) || messages === null ? (
|
{(messages && messages?.length == 0) || messages === null ? (
|
||||||
<div className="my-auto flex h-full w-full items-center justify-center gap-1 bg-gray-50 p-3 text-lg text-gray-500 dark:border-gray-800/50 dark:bg-gray-800 dark:text-gray-300">
|
<div className="my-auto flex h-full w-full items-center justify-center gap-1 bg-white p-3 text-lg text-gray-500 dark:border-gray-800/50 dark:bg-gray-800 dark:text-gray-300">
|
||||||
{localize('com_ui_nothing_found')}
|
{localize('com_ui_nothing_found')}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
messages?.map((message) => <SearchMessage key={message.messageId} message={message} />)
|
messages?.map((message) => <SearchMessage key={message.messageId} message={message} />)
|
||||||
)}
|
)}
|
||||||
<div className="absolute bottom-0 left-0 right-0 h-[5%] bg-gradient-to-t from-gray-800 to-transparent" />
|
<div className="absolute bottom-0 left-0 right-0 h-[5%] bg-gradient-to-t from-gray-50 to-transparent dark:from-gray-800" />
|
||||||
</MinimalMessagesWrapper>
|
</MinimalMessagesWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
5
client/src/routes/ShareRoute.tsx
Normal file
5
client/src/routes/ShareRoute.tsx
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
import ShareView from '~/components/Share/ShareView';
|
||||||
|
|
||||||
|
export default function ShareRoute() {
|
||||||
|
return <ShareView />;
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,7 @@ import {
|
||||||
ApiErrorWatcher,
|
ApiErrorWatcher,
|
||||||
} from '~/components/Auth';
|
} from '~/components/Auth';
|
||||||
import { AuthContextProvider } from '~/hooks/AuthContext';
|
import { AuthContextProvider } from '~/hooks/AuthContext';
|
||||||
|
import ShareRoute from './ShareRoute';
|
||||||
import ChatRoute from './ChatRoute';
|
import ChatRoute from './ChatRoute';
|
||||||
import Search from './Search';
|
import Search from './Search';
|
||||||
import Root from './Root';
|
import Root from './Root';
|
||||||
|
|
@ -31,6 +32,10 @@ export const router = createBrowserRouter([
|
||||||
path: 'reset-password',
|
path: 'reset-password',
|
||||||
element: <ResetPassword />,
|
element: <ResetPassword />,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'share/:shareId',
|
||||||
|
element: <ShareRoute />,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
element: <AuthLayout />,
|
element: <AuthLayout />,
|
||||||
children: [
|
children: [
|
||||||
|
|
|
||||||
70
client/src/utils/collection.ts
Normal file
70
client/src/utils/collection.ts
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
import { InfiniteData } from '@tanstack/react-query';
|
||||||
|
|
||||||
|
export const addData = <TCollection, TData>(
|
||||||
|
data: InfiniteData<TCollection>,
|
||||||
|
collectionName: string,
|
||||||
|
newData: TData,
|
||||||
|
findIndex: (page: TCollection) => number,
|
||||||
|
) => {
|
||||||
|
const dataJson = JSON.parse(JSON.stringify(data)) as InfiniteData<TCollection>;
|
||||||
|
const { pageIndex, index } = findPage<TCollection>(data, findIndex);
|
||||||
|
|
||||||
|
if (pageIndex !== -1 && index !== -1) {
|
||||||
|
return updateData(data, collectionName, newData, findIndex);
|
||||||
|
}
|
||||||
|
dataJson.pages[0][collectionName].unshift({
|
||||||
|
...newData,
|
||||||
|
updatedAt: new Date().toISOString(),
|
||||||
|
});
|
||||||
|
|
||||||
|
return dataJson;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function findPage<TData>(data: InfiniteData<TData>, findIndex: (page: TData) => number) {
|
||||||
|
for (let pageIndex = 0; pageIndex < data.pages.length; pageIndex++) {
|
||||||
|
const page = data.pages[pageIndex];
|
||||||
|
const index = findIndex(page);
|
||||||
|
if (index !== -1) {
|
||||||
|
return { pageIndex, index };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { pageIndex: -1, index: -1 }; // Not found
|
||||||
|
}
|
||||||
|
|
||||||
|
export const updateData = <TCollection, TData>(
|
||||||
|
data: InfiniteData<TCollection>,
|
||||||
|
collectionName: string,
|
||||||
|
updatedData: TData,
|
||||||
|
findIndex: (page: TCollection) => number,
|
||||||
|
) => {
|
||||||
|
const newData = JSON.parse(JSON.stringify(data)) as InfiniteData<TCollection>;
|
||||||
|
const { pageIndex, index } = findPage<TCollection>(data, findIndex);
|
||||||
|
|
||||||
|
if (pageIndex !== -1 && index !== -1) {
|
||||||
|
// Remove the data from its current position
|
||||||
|
newData.pages[pageIndex][collectionName].splice(index, 1);
|
||||||
|
// Add the updated data to the top of the first page
|
||||||
|
newData.pages[0][collectionName].unshift({
|
||||||
|
...updatedData,
|
||||||
|
updatedAt: new Date().toISOString(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return newData;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteData = <TCollection, TData>(
|
||||||
|
data: TData,
|
||||||
|
collectionName: string,
|
||||||
|
findIndex: (page: TCollection) => number,
|
||||||
|
): TData => {
|
||||||
|
const newData = JSON.parse(JSON.stringify(data));
|
||||||
|
const { pageIndex, index } = findPage<TCollection>(newData, findIndex);
|
||||||
|
|
||||||
|
if (pageIndex !== -1 && index !== -1) {
|
||||||
|
// Delete the data from its current page
|
||||||
|
newData.pages[pageIndex][collectionName].splice(index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newData;
|
||||||
|
};
|
||||||
|
|
@ -146,11 +146,11 @@ describe('Conversation Utilities', () => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
const { pageIndex, convIndex } = findPageForConversation(data as ConversationData, {
|
const { pageIndex, index } = findPageForConversation(data as ConversationData, {
|
||||||
conversationId: '2',
|
conversationId: '2',
|
||||||
});
|
});
|
||||||
expect(pageIndex).toBe(0);
|
expect(pageIndex).toBe(0);
|
||||||
expect(convIndex).toBe(1);
|
expect(index).toBe(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -219,11 +219,11 @@ describe('Conversation Utilities with Fake Data', () => {
|
||||||
describe('findPageForConversation', () => {
|
describe('findPageForConversation', () => {
|
||||||
it('finds the correct page and index for a given conversation in fake data', () => {
|
it('finds the correct page and index for a given conversation in fake data', () => {
|
||||||
const targetConversation = convoData.pages[0].conversations[0];
|
const targetConversation = convoData.pages[0].conversations[0];
|
||||||
const { pageIndex, convIndex } = findPageForConversation(convoData, {
|
const { pageIndex, index } = findPageForConversation(convoData, {
|
||||||
conversationId: targetConversation.conversationId as string,
|
conversationId: targetConversation.conversationId as string,
|
||||||
});
|
});
|
||||||
expect(pageIndex).toBeGreaterThanOrEqual(0);
|
expect(pageIndex).toBeGreaterThanOrEqual(0);
|
||||||
expect(convIndex).toBeGreaterThanOrEqual(0);
|
expect(index).toBeGreaterThanOrEqual(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,12 @@ import type {
|
||||||
ConversationData,
|
ConversationData,
|
||||||
ConversationUpdater,
|
ConversationUpdater,
|
||||||
GroupedConversations,
|
GroupedConversations,
|
||||||
|
ConversationListResponse,
|
||||||
} from 'librechat-data-provider';
|
} from 'librechat-data-provider';
|
||||||
|
|
||||||
|
import { addData, deleteData, updateData, findPage } from './collection';
|
||||||
|
import { InfiniteData } from '@tanstack/react-query';
|
||||||
|
|
||||||
export const dateKeys = {
|
export const dateKeys = {
|
||||||
today: 'com_ui_date_today',
|
today: 'com_ui_date_today',
|
||||||
yesterday: 'com_ui_date_yesterday',
|
yesterday: 'com_ui_date_yesterday',
|
||||||
|
|
@ -105,52 +109,39 @@ export const groupConversationsByDate = (conversations: TConversation[]): Groupe
|
||||||
return Object.entries(sortedGroups);
|
return Object.entries(sortedGroups);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const addConversation: ConversationUpdater = (data, newConversation) => {
|
export const addConversation = (
|
||||||
const newData = JSON.parse(JSON.stringify(data)) as ConversationData;
|
data: InfiniteData<ConversationListResponse>,
|
||||||
const { pageIndex, convIndex } = findPageForConversation(newData, newConversation);
|
newConversation: TConversation,
|
||||||
|
): ConversationData => {
|
||||||
if (pageIndex !== -1 && convIndex !== -1) {
|
return addData<ConversationListResponse, TConversation>(
|
||||||
return updateConversation(data, newConversation);
|
data,
|
||||||
}
|
'conversations',
|
||||||
newData.pages[0].conversations.unshift({
|
newConversation,
|
||||||
...newConversation,
|
(page) =>
|
||||||
updatedAt: new Date().toISOString(),
|
page.conversations.findIndex((c) => c.conversationId === newConversation.conversationId),
|
||||||
});
|
);
|
||||||
|
|
||||||
return newData;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export function findPageForConversation(
|
export function findPageForConversation(
|
||||||
data: ConversationData,
|
data: ConversationData,
|
||||||
conversation: TConversation | { conversationId: string },
|
conversation: TConversation | { conversationId: string },
|
||||||
) {
|
) {
|
||||||
for (let pageIndex = 0; pageIndex < data.pages.length; pageIndex++) {
|
return findPage<ConversationListResponse>(data, (page) =>
|
||||||
const page = data.pages[pageIndex];
|
page.conversations.findIndex((c) => c.conversationId === conversation.conversationId),
|
||||||
const convIndex = page.conversations.findIndex(
|
|
||||||
(c) => c.conversationId === conversation.conversationId,
|
|
||||||
);
|
);
|
||||||
if (convIndex !== -1) {
|
|
||||||
return { pageIndex, convIndex };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return { pageIndex: -1, convIndex: -1 }; // Not found
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const updateConversation: ConversationUpdater = (data, updatedConversation) => {
|
export const updateConversation = (
|
||||||
const newData = JSON.parse(JSON.stringify(data));
|
data: InfiniteData<ConversationListResponse>,
|
||||||
const { pageIndex, convIndex } = findPageForConversation(newData, updatedConversation);
|
newConversation: TConversation,
|
||||||
|
): ConversationData => {
|
||||||
if (pageIndex !== -1 && convIndex !== -1) {
|
return updateData<ConversationListResponse, TConversation>(
|
||||||
// Remove the conversation from its current position
|
data,
|
||||||
newData.pages[pageIndex].conversations.splice(convIndex, 1);
|
'conversations',
|
||||||
// Add the updated conversation to the top of the first page
|
newConversation,
|
||||||
newData.pages[0].conversations.unshift({
|
(page) =>
|
||||||
...updatedConversation,
|
page.conversations.findIndex((c) => c.conversationId === newConversation.conversationId),
|
||||||
updatedAt: new Date().toISOString(),
|
);
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return newData;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updateConvoFields: ConversationUpdater = (
|
export const updateConvoFields: ConversationUpdater = (
|
||||||
|
|
@ -158,13 +149,13 @@ export const updateConvoFields: ConversationUpdater = (
|
||||||
updatedConversation: Partial<TConversation> & Pick<TConversation, 'conversationId'>,
|
updatedConversation: Partial<TConversation> & Pick<TConversation, 'conversationId'>,
|
||||||
): ConversationData => {
|
): ConversationData => {
|
||||||
const newData = JSON.parse(JSON.stringify(data));
|
const newData = JSON.parse(JSON.stringify(data));
|
||||||
const { pageIndex, convIndex } = findPageForConversation(
|
const { pageIndex, index } = findPageForConversation(
|
||||||
newData,
|
newData,
|
||||||
updatedConversation as { conversationId: string },
|
updatedConversation as { conversationId: string },
|
||||||
);
|
);
|
||||||
|
|
||||||
if (pageIndex !== -1 && convIndex !== -1) {
|
if (pageIndex !== -1 && index !== -1) {
|
||||||
const deleted = newData.pages[pageIndex].conversations.splice(convIndex, 1);
|
const deleted = newData.pages[pageIndex].conversations.splice(index, 1);
|
||||||
const oldConversation = deleted[0] as TConversation;
|
const oldConversation = deleted[0] as TConversation;
|
||||||
|
|
||||||
newData.pages[0].conversations.unshift({
|
newData.pages[0].conversations.unshift({
|
||||||
|
|
@ -181,15 +172,9 @@ export const deleteConversation = (
|
||||||
data: ConversationData,
|
data: ConversationData,
|
||||||
conversationId: string,
|
conversationId: string,
|
||||||
): ConversationData => {
|
): ConversationData => {
|
||||||
const newData = JSON.parse(JSON.stringify(data));
|
return deleteData<ConversationListResponse, ConversationData>(data, 'conversations', (page) =>
|
||||||
const { pageIndex, convIndex } = findPageForConversation(newData, { conversationId });
|
page.conversations.findIndex((c) => c.conversationId === conversationId),
|
||||||
|
);
|
||||||
if (pageIndex !== -1 && convIndex !== -1) {
|
|
||||||
// Delete the conversation from its current page
|
|
||||||
newData.pages[pageIndex].conversations.splice(convIndex, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return newData;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getConversationById = (
|
export const getConversationById = (
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ export * from './presets';
|
||||||
export * from './textarea';
|
export * from './textarea';
|
||||||
export * from './languages';
|
export * from './languages';
|
||||||
export * from './endpoints';
|
export * from './endpoints';
|
||||||
|
export * from './sharedLink';
|
||||||
export { default as cn } from './cn';
|
export { default as cn } from './cn';
|
||||||
export { default as buildTree } from './buildTree';
|
export { default as buildTree } from './buildTree';
|
||||||
export { default as getLoginError } from './getLoginError';
|
export { default as getLoginError } from './getLoginError';
|
||||||
|
|
|
||||||
955
client/src/utils/sharedLink.fakeData.ts
Normal file
955
client/src/utils/sharedLink.fakeData.ts
Normal file
|
|
@ -0,0 +1,955 @@
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-nocheck
|
||||||
|
import type { SharedLinkListData } from 'librechat-data-provider';
|
||||||
|
|
||||||
|
const today = new Date();
|
||||||
|
today.setDate(today.getDate() - 3);
|
||||||
|
|
||||||
|
export const sharedLinkData: SharedLinkListData = {
|
||||||
|
pages: [
|
||||||
|
{
|
||||||
|
sharedLinks: [
|
||||||
|
{
|
||||||
|
conversationId: '7a327f49-0850-4741-b5da-35373e751256',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-03-04T04:31:04.897Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'b3c2e29b131c464182b483c4',
|
||||||
|
'6dc217152a134ac1826fc46c',
|
||||||
|
'483658114d104691b2501fbf',
|
||||||
|
'cfb8467cfd30438e8268cf92',
|
||||||
|
],
|
||||||
|
shareId: '62f850ad-a0d8-48a5-b439-2d1dbaba291c',
|
||||||
|
title: 'Test Shared Link 1',
|
||||||
|
updatedAt: '2024-04-11T11:10:42.329Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '1777ad5f-5e53-4847-be49-86f66c649ac6',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-04-05T05:59:31.571Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'bc53fda136ba46fb965260b8',
|
||||||
|
'138b83d659c84250904feb53',
|
||||||
|
'1c750ffab31546bd85b81360',
|
||||||
|
'7db87f183e4d489fae0b5161',
|
||||||
|
'64ee2004479644b7b5ffd2ea',
|
||||||
|
'4dd2b9a0704c4ae79688292e',
|
||||||
|
'25394c2bb2ee40feaf67836f',
|
||||||
|
'838ed537d9054780a3d9f272',
|
||||||
|
'300728390f8c4021a6c066ca',
|
||||||
|
'ea30b637cb8f463192523919',
|
||||||
|
],
|
||||||
|
shareId: '1f43f69f-0562-4129-b181-3c37df0df43e',
|
||||||
|
title: 'Test Shared Link 2',
|
||||||
|
updatedAt: '2024-04-16T17:52:40.250Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: 'a9682067-a7c9-4375-8efb-6b8fa1c71def',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-03-03T08:23:35.147Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'bb4fe223548b480eae6d64af',
|
||||||
|
'420ef02293d0470b96980e7b',
|
||||||
|
'ae0ffbb27e13418fbd63e7c2',
|
||||||
|
'43df3ea55cfb4219b1630518',
|
||||||
|
'c4fb3be788404058a4c9780d',
|
||||||
|
'6ee6a5833b1d4849a95be890',
|
||||||
|
'0b8a3ecf5ca5449b9bdc0ed8',
|
||||||
|
'a3daed97f0e5432a8b6031c0',
|
||||||
|
'6a7d10c55c9a46cfbd08d6d2',
|
||||||
|
'216d40fa813a44059bd01ab6',
|
||||||
|
],
|
||||||
|
shareId: 'e84d2642-9b3a-4e20-b92a-11a37eebe33f',
|
||||||
|
title: 'Test Shared Link 3',
|
||||||
|
updatedAt: '2024-02-06T04:21:17.065Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: 'b61f9a0a-6d5d-4d0e-802b-4c1866428816',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-04-06T19:25:45.708Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: ['00aad718514044dda8e044ec', '8cb3b67fccd64b8c8ac0abbb'],
|
||||||
|
shareId: '9011e12a-b2fe-4003-9623-bf1b5f80396b',
|
||||||
|
title: 'Test Shared Link 4',
|
||||||
|
updatedAt: '2024-03-21T22:37:32.704Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '4ac3fd9e-437b-4988-b870-29cacf28abef',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-04-03T15:45:11.220Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'6b05f825ca7747f294f2ac64',
|
||||||
|
'871ee06fb6a141879ca1cb25',
|
||||||
|
'47b05821c6134a3b9f21072e',
|
||||||
|
],
|
||||||
|
shareId: '51d3ab25-195e-47d0-a5e3-d0694ece776a',
|
||||||
|
title: 'Test Shared Link 5',
|
||||||
|
updatedAt: '2024-04-03T23:20:11.213Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '6ed26de8-3310-4abb-b561-4bdae9400aac',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-03-22T19:12:14.995Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'ac2929efa82b4cd78aae02d6',
|
||||||
|
'4266450abc7b41a59887e99d',
|
||||||
|
'95df3c7c802c40e0b643bb96',
|
||||||
|
'f21038af46074e51a2c4bd87',
|
||||||
|
'3f064bc8589c435786a92bcb',
|
||||||
|
],
|
||||||
|
shareId: 'c3bc13ed-190a-4ffa-8a05-50f8dad3c83e',
|
||||||
|
title: 'Test Shared Link 6',
|
||||||
|
updatedAt: '2024-04-25T19:55:25.785Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: 'b3c0aaca-ee76-42a2-b53b-5e85baca2f91',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-03-04T00:37:12.929Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'5a44ebd0bf05418e98cc9e5d',
|
||||||
|
'88b93127aef74bfb94666ac1',
|
||||||
|
'bf654993c34743c9a5a1b76c',
|
||||||
|
'2514259bd702491e924da475',
|
||||||
|
'60dbbf91a6734aa081e082cd',
|
||||||
|
'11efabaa3a8f4df8bf85410b',
|
||||||
|
'3f5bbf38abdb42efa65a8740',
|
||||||
|
'5b9dd8246dde41ae9ebd57c4',
|
||||||
|
],
|
||||||
|
shareId: '871d41fe-fb8a-41d4-8460-8bb93fb8aa98',
|
||||||
|
title: 'Test Shared Link 7',
|
||||||
|
updatedAt: '2024-03-13T14:34:26.790Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '2071122a-57cc-4f16-baa8-1e8af3e23522',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-01-24T03:22:58.012Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'8c94aad21caa45d6acb863c8',
|
||||||
|
'c10e4e0bfe554a94920093ba',
|
||||||
|
'2e4c2e2238f24f63b08440bc',
|
||||||
|
'05bacd00320342298f9f439f',
|
||||||
|
'c8b7750a7d8a4e2fbdc2630b',
|
||||||
|
'a84573fea668476a87207979',
|
||||||
|
'6ab15a1b96c24798b1bddd6f',
|
||||||
|
'b699d8e42324493eae95ca44',
|
||||||
|
],
|
||||||
|
shareId: 'f90f738a-b0ac-4dba-bb39-ad3d77919a21',
|
||||||
|
title: 'Test Shared Link 8',
|
||||||
|
updatedAt: '2024-01-22T11:09:51.834Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: 'ee06374d-4452-4fbe-a1c0-5dbc327638f9',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-03-03T19:24:21.281Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'297d0827c81a4da0a881561a',
|
||||||
|
'3131ef1b3c484542b0db1f92',
|
||||||
|
'e8879a50340c49449e970dbc',
|
||||||
|
'fe598327a93b4b0399055edd',
|
||||||
|
'acc7a2a24e204325befffbcd',
|
||||||
|
'6ec3c6450e124cbf808c8839',
|
||||||
|
'714e3443f62045aaaff17f93',
|
||||||
|
'014be593aaad41cab54a1c44',
|
||||||
|
],
|
||||||
|
shareId: '0fc91bab-083d-449f-add3-1e32146b6c4a',
|
||||||
|
title: 'Test Shared Link 9',
|
||||||
|
updatedAt: '2024-03-14T00:52:52.345Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '0d2f6880-cacf-4f7b-930e-35881df1cdea',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-02-14T03:18:45.587Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: ['1d045c1cf37742a6a979e21b'],
|
||||||
|
shareId: 'd87deb62-b993-476c-b520-104b08fd7445',
|
||||||
|
title: 'Test Shared Link 10',
|
||||||
|
updatedAt: '2024-03-26T18:38:41.222Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '1fe437fd-68f0-4e3e-81a9-ca9a0fa8220a',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-02-16T19:55:23.412Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'a28b5f27c95e4700bcd158dc',
|
||||||
|
'6e85f0a8b6ae4107a5819317',
|
||||||
|
'fa5b863c91224a0098aebd64',
|
||||||
|
'b73811a510e54acebe348371',
|
||||||
|
'f3f7f7d7b69a485da727f9c2',
|
||||||
|
'81d82df3098c4e359d29703f',
|
||||||
|
],
|
||||||
|
shareId: '704a1a9c-5366-4f55-b69e-670a374f4326',
|
||||||
|
title: 'Test Shared Link 11',
|
||||||
|
updatedAt: '2024-04-11T05:00:25.349Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '50465c8e-102f-4f94-88c2-9cf607a6c336',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-02-05T21:57:52.289Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'a64886199ab641c29eb6fdaf',
|
||||||
|
'9c16497010354cf385d4cc1d',
|
||||||
|
'36cdeb4d1e4f45078edfe28a',
|
||||||
|
'a11f4ea78fa44f57bfc5bfc6',
|
||||||
|
'dea42fcfe7a544feb5debc26',
|
||||||
|
'ece0d630cd89420ca80ffe25',
|
||||||
|
'719165a5d80644ae8fae9498',
|
||||||
|
'f27111921a10470982f522b2',
|
||||||
|
'10b78255f7a24b6192e67693',
|
||||||
|
],
|
||||||
|
shareId: 'e47eaf30-c1ed-4cc2-b2b8-8cdec4b1ea2f',
|
||||||
|
title: 'Test Shared Link 12',
|
||||||
|
updatedAt: '2024-02-07T15:43:21.110Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '1834f551-0a68-4bc7-a66a-21a234462d24',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-04-23T02:58:52.653Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'cb5d19d986194f779a6f47fd',
|
||||||
|
'72159d6668f347f99398aec9',
|
||||||
|
'cbe535213d664a6280d9a19e',
|
||||||
|
'8dccceadcb3a44148962ba47',
|
||||||
|
],
|
||||||
|
shareId: '976b55cb-d305-40f8-ae06-ae516f4e49f5',
|
||||||
|
title: 'Test Shared Link 13',
|
||||||
|
updatedAt: '2024-05-02T10:21:05.190Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: 'd8175b2f-f7c0-4f61-850d-f524bf8a84df',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-03-09T09:04:10.576Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'0f3708fc670d46998b1294d5',
|
||||||
|
'794520b9cee84c23bff01d5a',
|
||||||
|
'b05d2af2d37c426a970d8326',
|
||||||
|
'bd4239e379284d01acb9aaf4',
|
||||||
|
'e6265cfbbd88420781b27248',
|
||||||
|
'5262193aef7c426cafe2ee85',
|
||||||
|
'848569e2ca4843beaf64efc4',
|
||||||
|
'99f3b438241c4454a6784ac2',
|
||||||
|
'111d346fbeae4806bdf23490',
|
||||||
|
'fe4bde34e1a143f1a12fa628',
|
||||||
|
],
|
||||||
|
shareId: '928eb0a8-e0ea-470d-8b6a-92e0981d61b0',
|
||||||
|
title: 'Test Shared Link 14',
|
||||||
|
updatedAt: '2024-04-15T18:00:13.094Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '281984c0-fed0-4428-8e50-c7c93cba4ae0',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-03-23T23:26:41.956Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'7e781fd08408426795c243e7',
|
||||||
|
'3c6d729fd3524a65a7b2a5e3',
|
||||||
|
'53bdbec6ee6148e78795d6e1',
|
||||||
|
'46f8170f28684ccc8ee56f33',
|
||||||
|
'3350d9aa7c814c89af6d3640',
|
||||||
|
],
|
||||||
|
shareId: '7a251af6-1ad3-4b24-830c-21b38124f325',
|
||||||
|
title: 'Test Shared Link 15',
|
||||||
|
updatedAt: '2024-03-18T16:33:35.498Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '09610b11-6087-4d15-b163-e1bc958f2e82',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-02-05T20:00:36.159Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: ['6dce61720af24c70926efe87'],
|
||||||
|
shareId: '2b389d5e-eb24-4b29-a8e1-c0545cdfa1fc',
|
||||||
|
title: 'Test Shared Link 16',
|
||||||
|
updatedAt: '2024-02-23T05:49:50.020Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '0c388322-905c-4c57-948c-1ba9614fdc2f',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-04-05T00:03:20.078Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'e3755ff2cf9f403c9d20901f',
|
||||||
|
'e32733b8da1440ec9d9dc2df',
|
||||||
|
'e2870d0361634d4f867e1e57',
|
||||||
|
'2e504afb8675434bb9f58cb5',
|
||||||
|
'ea38d76735c54f94bf378ed3',
|
||||||
|
'8712cda1bfc8480eba6c65aa',
|
||||||
|
'3f43a655706f4032a9e1efb4',
|
||||||
|
'3f890f8279f4436da2a7d767',
|
||||||
|
'4ca7616c04404391a7cfc94f',
|
||||||
|
'd3e176a831ff48e49debabce',
|
||||||
|
],
|
||||||
|
shareId: '2866400b-bcb9-43a4-8cbf-6597959f8c55',
|
||||||
|
title: 'Test Shared Link 17',
|
||||||
|
updatedAt: '2024-03-16T02:53:06.642Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '5ac2b90a-63f8-4388-919b-40a1c1fea874',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-01-21T15:30:37.893Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'734a0427c6224fca87e2a89d',
|
||||||
|
'6af13387ddf0495d9c6ebad9',
|
||||||
|
'02a93d5659f343678b12b932',
|
||||||
|
'8af2f028c5114286a3339075',
|
||||||
|
'3a8bec13fc574fb9a9f938e2',
|
||||||
|
'6f4aa482286548b7b42668e6',
|
||||||
|
'c1d4f94a2eaf4e44b94c5834',
|
||||||
|
'442d9491b51d49fcab60366d',
|
||||||
|
'82a115a84b2a4457942ca6cf',
|
||||||
|
'152d8c2894a0454d9248c9f5',
|
||||||
|
],
|
||||||
|
shareId: 'e76f6a90-06f3-4846-8e3d-987d37af27b5',
|
||||||
|
title: 'Test Shared Link 18',
|
||||||
|
updatedAt: '2024-01-27T06:25:27.032Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '01521fef-aa0b-4670-857d-f19bfc0ce664',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-03-01T21:46:40.674Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'222cf562d8e24b1b954395c2',
|
||||||
|
'c6f299f588c24905b771e623',
|
||||||
|
'f023f30fd4d9472c9bf60b84',
|
||||||
|
'e4929e3f14d748a18656f1be',
|
||||||
|
'a01f453fcb0a49b5b488a22c',
|
||||||
|
'4ceee6b365ab4386bacb4d27',
|
||||||
|
'c2cab81da0be4c6e97f11f92',
|
||||||
|
'644c32d10f2f4e2086d5e04d',
|
||||||
|
'5225d1286db14cc6a47fdea5',
|
||||||
|
'c821ebb220ae495b98f2e17f',
|
||||||
|
],
|
||||||
|
shareId: '1b2d8bf5-ff90-478a-bdf6-ea622fb4875a',
|
||||||
|
title: 'Test Shared Link 19',
|
||||||
|
updatedAt: '2024-02-25T15:52:56.189Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '54f5d332-efc7-4062-9e1d-c70c3dbbc964',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-01-29T15:57:22.808Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'49771038e2dd4de0a28b19f2',
|
||||||
|
'0debd4ad13de4db9a65fe589',
|
||||||
|
'a9c8e6e34c34486ca27b7c88',
|
||||||
|
'd7b0ace0438146789e8b1899',
|
||||||
|
],
|
||||||
|
shareId: '4f5eea7d-b3a8-4b72-ad1e-a4d516c582c2',
|
||||||
|
title: 'Test Shared Link 20',
|
||||||
|
updatedAt: '2024-03-18T13:12:10.828Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '99dabf25-46a5-43bb-8274-715c64e56032',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-03-05T03:35:11.327Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: ['965a55515727404eb70dec8f'],
|
||||||
|
shareId: '2360b7c1-20d7-46b9-919d-65576a899ab9',
|
||||||
|
title: 'Test Shared Link 21',
|
||||||
|
updatedAt: '2024-04-17T11:22:12.800Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '1e2ffc1a-3546-460e-819c-689eb88940c6',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-04-22T08:40:32.663Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'131f4b03ad3d4e90803a203d',
|
||||||
|
'7f55262c554f4d97a8fef0ec',
|
||||||
|
'341e8fea28e241fc8b5a2398',
|
||||||
|
],
|
||||||
|
shareId: 'f3e370ed-420c-4579-a033-e18743b49485',
|
||||||
|
title: 'Test Shared Link 22',
|
||||||
|
updatedAt: '2024-04-07T22:06:07.162Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '14510a0c-01cc-4bfb-8336-3388573ac4d8',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-03-08T08:20:28.619Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'022f87b1bf0d4e4688970daa',
|
||||||
|
'42519e8f3603496faae0969c',
|
||||||
|
'abc29ac88d66485aa11e4b58',
|
||||||
|
],
|
||||||
|
shareId: '0f46f1fd-95d3-4a6f-a5aa-ae5338dc5337',
|
||||||
|
title: 'Test Shared Link 23',
|
||||||
|
updatedAt: '2024-03-06T12:05:33.679Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '2475594e-10dc-4d6a-aa58-5ce727a36271',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-03-04T07:43:46.952Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'5d0cd8bef4c241aba5d822a8',
|
||||||
|
'a19669a364d84ab5bbafbe0c',
|
||||||
|
'336686022ea6456b9a63879d',
|
||||||
|
'3323c9b85acc4ffba35aad04',
|
||||||
|
'bf15e8860a01474cb4744842',
|
||||||
|
'5a055eb825ed4173910fffd5',
|
||||||
|
'36a5e683ad144ec68c2a8ce0',
|
||||||
|
'8bc1d5590a594fa1afc18ee1',
|
||||||
|
'f86444b60bea437ba0d0ef8e',
|
||||||
|
'5be768788d984723aef5c9a0',
|
||||||
|
],
|
||||||
|
shareId: 'b742f35c-e6a3-4fa4-b35d-abab4528d7d6',
|
||||||
|
title: 'Test Shared Link 24',
|
||||||
|
updatedAt: '2024-03-27T15:31:10.930Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: 'ddb5a61c-82fe-4cc7-a2b0-c34b8c393b28',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-02-15T02:06:45.901Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'059d7ae5405a42af9c52171d',
|
||||||
|
'303efd2e676e4fe7aa9fa9d0',
|
||||||
|
'9f459c2e6a23411ea4a3e153',
|
||||||
|
'6036a3785adc4b7caa7ea22b',
|
||||||
|
'65251979d0c64d1f8821b3d9',
|
||||||
|
'25fdeb5ed99d42cca3041e08',
|
||||||
|
'61baa25e4e3d42a3aefd6c16',
|
||||||
|
'91dc4578fee749aeb352b5ea',
|
||||||
|
'd52daca5afb84e7890d5d9ad',
|
||||||
|
],
|
||||||
|
shareId: '13106e5f-1b5f-4ed4-963d-790e61c1f4c8',
|
||||||
|
title: 'Test Shared Link 25',
|
||||||
|
updatedAt: '2024-02-05T08:39:45.847Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: 'df09c89b-0b0d-429c-9c93-b5f4d51ef1ec',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-03-28T07:50:10.724Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'7f007af305ee4f2197c125d3',
|
||||||
|
'318b26abfe864dbf9f557bf9',
|
||||||
|
'0c4709b489ac4211b9f22874',
|
||||||
|
'8940f9ab45f44b56911819d5',
|
||||||
|
'b47ec3aa0cf7413fa446f19b',
|
||||||
|
'3857f85f492f4e11aa0ea377',
|
||||||
|
],
|
||||||
|
shareId: '31bbafa4-2051-4a20-883b-2f8557c46116',
|
||||||
|
title: 'Test Shared Link 26',
|
||||||
|
updatedAt: '2024-02-01T19:52:32.986Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '856a4d54-54f7-483f-9b4e-7b798920be25',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-04-14T08:57:03.592Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'b5afc1f3569d44378bc7539d',
|
||||||
|
'e54804329577443d8685d3b1',
|
||||||
|
'7b10204ad48c464aac2b752a',
|
||||||
|
'8e96d562d33b4d6b85f2269e',
|
||||||
|
'cd844644f15d4dbdb5772a3b',
|
||||||
|
'91f5159278ca420c8a0097b2',
|
||||||
|
'5f8cf34736df4cca962635c1',
|
||||||
|
'96e2169ddcf5408fb793aeb6',
|
||||||
|
'988d96959afb4ec08cd3cec4',
|
||||||
|
'173398cdf05d4838aeb5ad9f',
|
||||||
|
],
|
||||||
|
shareId: '88c159a0-0273-4798-9d21-f95bd650bd30',
|
||||||
|
title: 'Test Shared Link 27',
|
||||||
|
updatedAt: '2024-05-08T20:07:46.345Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '41ee3f3f-36a5-4139-993a-1c4d7d055ccb',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-02-26T10:08:29.943Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: ['883cc3286240405ba558f322', '7ca7809f471e481fa9944795'],
|
||||||
|
shareId: '97dc26aa-c909-4a9c-91be-b605d25b9cf3',
|
||||||
|
title: 'Test Shared Link 28',
|
||||||
|
updatedAt: '2024-04-06T17:36:05.767Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '79e30f91-9b87-484c-8a12-6e4c6e8973d4',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-05-07T05:28:58.595Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'a8ac347785504b51bdad7ea7',
|
||||||
|
'ce85321aecf64355b0362f8c',
|
||||||
|
'21a462895f37474d8d6acdfd',
|
||||||
|
'095d9104011e4534bda93294',
|
||||||
|
'503b6e27677c457289366a8d',
|
||||||
|
'1738d52a60004c9ba6f0c9ec',
|
||||||
|
'a157fe44a67f4882a507941b',
|
||||||
|
'40e30dc275394eb4b9921db0',
|
||||||
|
'f4ed9f2fb08640fcbacaa6a7',
|
||||||
|
'bbac358328864dc2bfaa39da',
|
||||||
|
],
|
||||||
|
shareId: 'aa36fc45-2a73-4fa2-a500-2a9148fca67d',
|
||||||
|
title: 'Test Shared Link 29',
|
||||||
|
updatedAt: '2024-01-26T16:45:59.269Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: 'f5eaa000-3657-43d4-bc55-538108723b83',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-02-22T15:51:31.330Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'a87cfce565844b4ba9230dc5',
|
||||||
|
'426723bc4c22425e9bdf4b7b',
|
||||||
|
'73be5795469a444b8f1eca88',
|
||||||
|
'75a87212574a4cfc80d7d4e3',
|
||||||
|
'80f982dfc3e94535aed6e7d4',
|
||||||
|
'86d036c912c142ca8ec0f45a',
|
||||||
|
'e3435fbbd4d2443eba30e97d',
|
||||||
|
'e451e124aa964398b596af5d',
|
||||||
|
'1a13913f55e9442e8b5d7816',
|
||||||
|
],
|
||||||
|
shareId: 'fe0f7ea2-74d2-40ba-acb2-437e61fc3bef',
|
||||||
|
title: 'Test Shared Link 30',
|
||||||
|
updatedAt: '2024-02-27T13:29:04.060Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: 'a1ad92b4-6fac-44be-bad6-7648aeeba7af',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-04-10T09:32:22.242Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'5931cd94fbcd4fbcbaa20b91',
|
||||||
|
'0bc5f38ccc4f4b88afa42aed',
|
||||||
|
'7b4375d65f3f4524a79cb5f0',
|
||||||
|
'd2ce098360ce4d19b6961017',
|
||||||
|
'847f5ee8d2df49a0ba1fd8a7',
|
||||||
|
'6164a71770c745ea8142a37c',
|
||||||
|
'e98a0f1e15c846ac9b113608',
|
||||||
|
'5297d7df09b44d088cf80da5',
|
||||||
|
'62260b3f62ba423aa5c1962c',
|
||||||
|
'21fffc89d1d54e0190819384',
|
||||||
|
],
|
||||||
|
shareId: 'ee5ae35d-540d-4a01-a938-ee7ee97b15ce',
|
||||||
|
title: 'Test Shared Link 31',
|
||||||
|
updatedAt: '2024-02-26T03:37:24.862Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '1e502d46-c710-4848-9bf2-674c08e51d9c',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-04-09T08:37:01.082Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'adb4bfb7657d4d7d92e82edf',
|
||||||
|
'70bdd81466e0408399b415d3',
|
||||||
|
'ef99511981dc4c3baa18d372',
|
||||||
|
],
|
||||||
|
shareId: 'b4fd8b63-7265-4825-89a4-9cebcbaadeee',
|
||||||
|
title: 'Test Shared Link 32',
|
||||||
|
updatedAt: '2024-02-27T04:32:40.654Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: 'd1a43c39-f05e-4c6e-a8c2-0fcca9cb8928',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-04-26T15:03:25.546Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'07c070ab8a7541fea96b131c',
|
||||||
|
'eb89cc57bcbb47ecb497cd5f',
|
||||||
|
'651999e46e734837b24c2500',
|
||||||
|
'608f9fbbbbb645e6b32d7d46',
|
||||||
|
],
|
||||||
|
shareId: '5a4cf7d0-0abb-48c1-8e70-9f4ee3220dc4',
|
||||||
|
title: 'Test Shared Link 33',
|
||||||
|
updatedAt: '2024-04-06T21:39:51.521Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: 'e549be2b-2623-42a3-8315-a8e35a7776b3',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-02-23T21:40:32.151Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'aa4e0b65650544589afb5961',
|
||||||
|
'160841178c0944e88de83956',
|
||||||
|
'234ac16af26d48a7875ee643',
|
||||||
|
],
|
||||||
|
shareId: 'b083f048-2803-407e-b54a-89261db87ade',
|
||||||
|
title: 'Test Shared Link 34',
|
||||||
|
updatedAt: '2024-03-14T12:16:32.984Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '39f415ea-48f2-4bb2-b6f8-c2cf2d5fe42a',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-04-08T19:02:27.141Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'c77e79bb92b64d36a72d5a4d',
|
||||||
|
'ea236310a9ba4b27a2217f09',
|
||||||
|
'b25c46f2d23542f6b9d94de9',
|
||||||
|
],
|
||||||
|
shareId: 'a9871169-7012-4206-b35c-7d207309a0f5',
|
||||||
|
title: 'Test Shared Link 35',
|
||||||
|
updatedAt: '2024-04-21T04:00:58.151Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: 'c0d00265-12c4-45d0-a8bd-95d6e1bda769',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-03-14T09:50:55.476Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'63cdf78acd0449cf90237b29',
|
||||||
|
'b93d82d7612b49fc98f0c211',
|
||||||
|
'e56afe7e6e1e478d858a96d0',
|
||||||
|
'09344c8d22e74ce9b1d615cc',
|
||||||
|
],
|
||||||
|
shareId: 'aa1262ab-54c9-406a-a97f-e2636266cf3e',
|
||||||
|
title: 'Test Shared Link 36',
|
||||||
|
updatedAt: '2024-03-24T15:53:36.021Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '5114b13d-8050-4e29-a2fd-85c776aec055',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-01-20T20:39:54.322Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'd397dc5c136a4c7da44e2fb9',
|
||||||
|
'a3cd29243629450b87852a85',
|
||||||
|
'9dd1e0e918844a37ba8dc955',
|
||||||
|
'ec2a73f7efe344fe85709c22',
|
||||||
|
'4d4702651869476b8ae397fd',
|
||||||
|
'8447430fd4f34aab82921018',
|
||||||
|
'8d804ee086734d6192b59995',
|
||||||
|
'29d6ccba37234bb8bd280977',
|
||||||
|
'31ec4f8c28cc4c21828ecef8',
|
||||||
|
'8ea630045b5847ec92651f4a',
|
||||||
|
],
|
||||||
|
shareId: '2021fcab-7000-4840-9a8c-f0a1cb1ce8fa',
|
||||||
|
title: 'Test Shared Link 37',
|
||||||
|
updatedAt: '2024-04-08T02:09:33.732Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: 'afa796fe-c8c1-411d-98d1-a8c8c8550412',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-01-16T23:58:11.179Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'8f54ee5871494f1b9f13f314',
|
||||||
|
'7778849398db40eb950952fb',
|
||||||
|
'65977e5d9e12445cb1cd9a54',
|
||||||
|
'8dba76884b09490a91b1aff9',
|
||||||
|
'2f6cc465171742b8a529daa3',
|
||||||
|
'1775b24fe2e94cd89dd6164e',
|
||||||
|
'780d980e59274240837c0bff',
|
||||||
|
],
|
||||||
|
shareId: '9bb78460-0a26-4df7-be54-99b904b8084a',
|
||||||
|
title: 'Test Shared Link 38',
|
||||||
|
updatedAt: '2024-04-22T00:33:47.525Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: 'c70fc447-acfc-4b57-84aa-2d8abcc3c5a5',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-04-24T11:39:14.696Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'b659ff86f9284ae1a40bee94',
|
||||||
|
'35bce7b6b2124db491f116c4',
|
||||||
|
'cf0bad6c2623413babb33e65',
|
||||||
|
'26c6ce4d46614c86941d5429',
|
||||||
|
'fba6517fc3434c188d8e1471',
|
||||||
|
'3e37398cc2ea4e50920d6271',
|
||||||
|
'fd8584b1cf8145c88697b89d',
|
||||||
|
'8e433df0ada34e2280d4bd91',
|
||||||
|
'fc52f80a6df24df5baccb657',
|
||||||
|
'95cdf9b05b8f4a81a70a37e9',
|
||||||
|
],
|
||||||
|
shareId: '0664b078-8f29-41ff-8c1c-85172c659195',
|
||||||
|
title: 'Test Shared Link 39',
|
||||||
|
updatedAt: '2024-03-29T10:22:50.815Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '32ccaa36-cc46-4c84-888d-a86bf9b1d79c',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-02-04T03:13:19.399Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'8a0cfa8f5e874cf089f91b2e',
|
||||||
|
'e9a72907ac9b4e88a8cfa737',
|
||||||
|
'aa328aaf978944e18727a967',
|
||||||
|
'8786577a76b24415920d87a0',
|
||||||
|
'ee05127d35ec415a85554406',
|
||||||
|
],
|
||||||
|
shareId: 'a0018d28-52a8-4d31-8884-037cf9037eb7',
|
||||||
|
title: 'Test Shared Link 40',
|
||||||
|
updatedAt: '2024-01-30T03:26:15.920Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '2d8f1f40-b0e8-4629-937a-dee5036cb0bb',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-03-18T15:32:59.697Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'64475ed4f6234326a1104ca2',
|
||||||
|
'db0db3ee92e14afaba6db75b',
|
||||||
|
'1f28a30501a94e3d896c261b',
|
||||||
|
'de2eb08823db401d8262d3f3',
|
||||||
|
'254c32efae97476b954d8dc4',
|
||||||
|
'dda42e4e74144cb69e395392',
|
||||||
|
'85bfe89de9e643fb8d5fa8ff',
|
||||||
|
'2f52e060a8b645928d0bf594',
|
||||||
|
],
|
||||||
|
shareId: '9740b59b-cd84-461d-9fd7-2e1903b844b2',
|
||||||
|
title: 'Test Shared Link 41',
|
||||||
|
updatedAt: '2024-04-23T15:48:54.690Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '5180353f-23a9-48af-8ed0-b05983ef87d1',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-02-15T10:45:51.373Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'012b97e2df45475b93ad1e37',
|
||||||
|
'23d5042117a142f5a12762d5',
|
||||||
|
'8eb8cbca953d4ec18108f6d8',
|
||||||
|
'ba506914203442339cd81d25',
|
||||||
|
'88c3b40cd0ae43d2b670ee41',
|
||||||
|
'0dd8fe241f5c4ea88730652c',
|
||||||
|
'80e3d1d7c26c489c9c8741fe',
|
||||||
|
'317a47a138c6499db73679f0',
|
||||||
|
'6497260d6a174f799cb56fd5',
|
||||||
|
],
|
||||||
|
shareId: 'a6eaf23e-6e99-4e96-8222-82149c48803b',
|
||||||
|
title: 'Test Shared Link 42',
|
||||||
|
updatedAt: '2024-02-24T12:08:27.344Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: 'cf3f2919-1840-4f6a-b350-f73f02ba6e90',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-02-14T06:20:45.439Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'ba3b939f8a3443f99f37b296',
|
||||||
|
'b2039c988b3841c6b4ccb436',
|
||||||
|
'89ea6e1d4b3f440bb867d740',
|
||||||
|
'270210838a724aeb87e9bbe9',
|
||||||
|
'02dd6b2f185247d9888d5be1',
|
||||||
|
'6458fe13ee1c470ba33fb931',
|
||||||
|
],
|
||||||
|
shareId: '765042c0-144d-4f7b-9953-0553ed438717',
|
||||||
|
title: 'Test Shared Link 43',
|
||||||
|
updatedAt: '2024-04-11T05:23:05.750Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '8efb71ee-7984-409a-b27c-aeb2650d78ba',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-01-28T16:41:04.100Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'cc60d9e2cbb7494481138833',
|
||||||
|
'1fb8d220b888475ba6c59fd3',
|
||||||
|
'5fd97817ab25451bb7ac22f5',
|
||||||
|
'9e8f7765a1bc4ab495da9081',
|
||||||
|
'4d5997d3c8744aaeb8c96964',
|
||||||
|
'd438acb0f7704201857d6916',
|
||||||
|
'b5106745d89f4a3fada8cd11',
|
||||||
|
'3b41562ce727411a83f44cdf',
|
||||||
|
'627f8f77feb843848145fc5f',
|
||||||
|
'6bee635eb10443ae9eef20ab',
|
||||||
|
],
|
||||||
|
shareId: 'ed0fe440-479d-4c79-a494-0f461612c474',
|
||||||
|
title: 'Test Shared Link 44',
|
||||||
|
updatedAt: '2024-04-15T12:41:00.324Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '7cdd42a6-67bb-48c8-b8c3-bb55cbaa3905',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-04-24T23:13:42.892Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'a944f461ca094d1c80bea677',
|
||||||
|
'bd4b516b51a84285846343b4',
|
||||||
|
'442f6b4c27f647199279e49c',
|
||||||
|
'e672974b3cf74cd3b85537f9',
|
||||||
|
],
|
||||||
|
shareId: '9439972e-226c-4386-910a-e629eb7019c3',
|
||||||
|
title: 'Test Shared Link 45',
|
||||||
|
updatedAt: '2024-01-17T07:42:21.103Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '595bab25-e5c1-4bd0-99c1-a099391adb87',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-04-13T05:58:33.171Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'c39942615fdf435cb22369b5',
|
||||||
|
'0ec24a7328424a78b7dcecaf',
|
||||||
|
'335373a769fd43a5833eac16',
|
||||||
|
'22905090a44f4bf8b6f415f8',
|
||||||
|
],
|
||||||
|
shareId: '18501e23-3fc5-436d-a9aa-ccde7c5c9074',
|
||||||
|
title: 'Test Shared Link 46',
|
||||||
|
updatedAt: '2024-02-05T04:34:42.323Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '822a650b-2971-441a-9cb0-b2ecabf7b3ba',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-03-20T10:29:20.771Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'ed566d1ffd51494e9a069f32',
|
||||||
|
'3ca9a8bbfb7c43e49e4898d7',
|
||||||
|
'6534186966784f0fba45c1ab',
|
||||||
|
'8a9e394dda8542d4a4db1140',
|
||||||
|
'002d883a1c344de0beb794b3',
|
||||||
|
'61e9e872aa854288a4ac9694',
|
||||||
|
'11e465cb875746aaa5894327',
|
||||||
|
'ead6b00c855f4907ac5070af',
|
||||||
|
],
|
||||||
|
shareId: 'aaaf89e4-eb3d-45f8-9e24-f370d777d8f7',
|
||||||
|
title: 'Test Shared Link 47',
|
||||||
|
updatedAt: '2024-04-29T03:11:47.109Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: 'ce68ce26-07fc-4448-9239-f1925cfaaa72',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-03-15T15:04:08.691Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'a1851d231ee748e59ed43494',
|
||||||
|
'363372c828d8443b81abffd4',
|
||||||
|
'0b2e97210bd14e229ddb6641',
|
||||||
|
],
|
||||||
|
shareId: 'f4de7c43-c058-43f5-bdab-0854d939dfb9',
|
||||||
|
title: 'Test Shared Link 48',
|
||||||
|
updatedAt: '2024-03-05T11:43:00.177Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: '3fafe417-b5f8-4cc8-ac8e-897ebef836bd',
|
||||||
|
user: '662dbe728ca96f444c6f69f4',
|
||||||
|
createdAt: '2024-04-20T05:34:57.880Z',
|
||||||
|
isAnonymous: true,
|
||||||
|
isPublic: true,
|
||||||
|
isVisible: true,
|
||||||
|
messages: [
|
||||||
|
'876337c495ca40c080b65c1d',
|
||||||
|
'b5e914ac15ff439a9836a9ea',
|
||||||
|
'cb6379d0a9ad442291d78c14',
|
||||||
|
'529424b650a4478ba012cf40',
|
||||||
|
'99ff1ed49cb2483bbd970730',
|
||||||
|
'0f0e215e179f4cfba56c7b03',
|
||||||
|
'210940fbe4c745d183358ed1',
|
||||||
|
'99246c796c7a44c2ae85a549',
|
||||||
|
'a2b967556867499eb437674a',
|
||||||
|
],
|
||||||
|
shareId: '79ec3716-ea2e-4045-8a82-056d63ebc939',
|
||||||
|
title: 'Test Shared Link 49',
|
||||||
|
updatedAt: '2024-03-19T08:01:13.445Z',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
pages: 49,
|
||||||
|
pageNumber: '1',
|
||||||
|
pageSize: 25,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
pageParams: [null],
|
||||||
|
};
|
||||||
149
client/src/utils/sharedLink.spec.ts
Normal file
149
client/src/utils/sharedLink.spec.ts
Normal file
|
|
@ -0,0 +1,149 @@
|
||||||
|
import { sharedLinkData } from './sharedLink.fakeData';
|
||||||
|
import { addSharedLink, updateSharedLink, deleteSharedLink } from './sharedLink';
|
||||||
|
|
||||||
|
import type { TSharedLink, SharedLinkListData } from 'librechat-data-provider';
|
||||||
|
|
||||||
|
describe('Shared Link Utilities', () => {
|
||||||
|
describe('addSharedLink', () => {
|
||||||
|
it('adds a new shared link to the top of the list', () => {
|
||||||
|
const data = { pages: [{ sharedLinks: [] }] };
|
||||||
|
const newSharedLink = { shareId: 'new', updatedAt: '2023-04-02T12:00:00Z' };
|
||||||
|
const newData = addSharedLink(
|
||||||
|
data as unknown as SharedLinkListData,
|
||||||
|
newSharedLink as TSharedLink,
|
||||||
|
);
|
||||||
|
expect(newData.pages[0].sharedLinks).toHaveLength(1);
|
||||||
|
expect(newData.pages[0].sharedLinks[0].shareId).toBe('new');
|
||||||
|
});
|
||||||
|
it('does not add a shared link but updates it if it already exists', () => {
|
||||||
|
const data = {
|
||||||
|
pages: [
|
||||||
|
{
|
||||||
|
sharedLinks: [
|
||||||
|
{ shareId: '1', updatedAt: '2023-04-01T12:00:00Z' },
|
||||||
|
{ shareId: '2', updatedAt: '2023-04-01T13:00:00Z' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const newSharedLink = { shareId: '2', updatedAt: '2023-04-02T12:00:00Z' };
|
||||||
|
const newData = addSharedLink(
|
||||||
|
data as unknown as SharedLinkListData,
|
||||||
|
newSharedLink as TSharedLink,
|
||||||
|
);
|
||||||
|
expect(newData.pages[0].sharedLinks).toHaveLength(2);
|
||||||
|
expect(newData.pages[0].sharedLinks[0].shareId).toBe('2');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('updateSharedLink', () => {
|
||||||
|
it('updates an existing shared link and moves it to the top', () => {
|
||||||
|
const initialData = {
|
||||||
|
pages: [
|
||||||
|
{
|
||||||
|
sharedLinks: [
|
||||||
|
{ shareId: '1', updatedAt: '2023-04-01T12:00:00Z' },
|
||||||
|
{ shareId: '2', updatedAt: '2023-04-01T13:00:00Z' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const updatedSharedLink = { shareId: '1', updatedAt: '2023-04-02T12:00:00Z' };
|
||||||
|
const newData = updateSharedLink(
|
||||||
|
initialData as unknown as SharedLinkListData,
|
||||||
|
updatedSharedLink as TSharedLink,
|
||||||
|
);
|
||||||
|
expect(newData.pages[0].sharedLinks).toHaveLength(2);
|
||||||
|
expect(newData.pages[0].sharedLinks[0].shareId).toBe('1');
|
||||||
|
});
|
||||||
|
it('does not update a shared link if it does not exist', () => {
|
||||||
|
const initialData = {
|
||||||
|
pages: [
|
||||||
|
{
|
||||||
|
sharedLinks: [
|
||||||
|
{ shareId: '1', updatedAt: '2023-04-01T12:00:00Z' },
|
||||||
|
{ shareId: '2', updatedAt: '2023-04-01T13:00:00Z' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const updatedSharedLink = { shareId: '3', updatedAt: '2023-04-02T12:00:00Z' };
|
||||||
|
const newData = updateSharedLink(
|
||||||
|
initialData as unknown as SharedLinkListData,
|
||||||
|
updatedSharedLink as TSharedLink,
|
||||||
|
);
|
||||||
|
expect(newData.pages[0].sharedLinks).toHaveLength(2);
|
||||||
|
expect(newData.pages[0].sharedLinks[0].shareId).toBe('1');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('deleteSharedLink', () => {
|
||||||
|
it('removes a shared link by id', () => {
|
||||||
|
const initialData = {
|
||||||
|
pages: [
|
||||||
|
{
|
||||||
|
sharedLinks: [
|
||||||
|
{ shareId: '1', updatedAt: '2023-04-01T12:00:00Z' },
|
||||||
|
{ shareId: '2', updatedAt: '2023-04-01T13:00:00Z' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const newData = deleteSharedLink(initialData as unknown as SharedLinkListData, '1');
|
||||||
|
expect(newData.pages[0].sharedLinks).toHaveLength(1);
|
||||||
|
expect(newData.pages[0].sharedLinks[0].shareId).not.toBe('1');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not remove a shared link if it does not exist', () => {
|
||||||
|
const initialData = {
|
||||||
|
pages: [
|
||||||
|
{
|
||||||
|
sharedLinks: [
|
||||||
|
{ shareId: '1', updatedAt: '2023-04-01T12:00:00Z' },
|
||||||
|
{ shareId: '2', updatedAt: '2023-04-01T13:00:00Z' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const newData = deleteSharedLink(initialData as unknown as SharedLinkListData, '3');
|
||||||
|
expect(newData.pages[0].sharedLinks).toHaveLength(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Shared Link Utilities with Fake Data', () => {
|
||||||
|
describe('addSharedLink', () => {
|
||||||
|
it('adds a new shared link to the existing fake data', () => {
|
||||||
|
const newSharedLink = {
|
||||||
|
shareId: 'new',
|
||||||
|
updatedAt: new Date().toISOString(),
|
||||||
|
} as TSharedLink;
|
||||||
|
const initialLength = sharedLinkData.pages[0].sharedLinks.length;
|
||||||
|
const newData = addSharedLink(sharedLinkData, newSharedLink);
|
||||||
|
expect(newData.pages[0].sharedLinks.length).toBe(initialLength + 1);
|
||||||
|
expect(newData.pages[0].sharedLinks[0].shareId).toBe('new');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('updateSharedLink', () => {
|
||||||
|
it('updates an existing shared link within fake data', () => {
|
||||||
|
const updatedSharedLink = {
|
||||||
|
...sharedLinkData.pages[0].sharedLinks[0],
|
||||||
|
title: 'Updated Title',
|
||||||
|
};
|
||||||
|
const newData = updateSharedLink(sharedLinkData, updatedSharedLink);
|
||||||
|
expect(newData.pages[0].sharedLinks[0].title).toBe('Updated Title');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('deleteSharedLink', () => {
|
||||||
|
it('removes a shared link by id from fake data', () => {
|
||||||
|
const shareIdToDelete = sharedLinkData.pages[0].sharedLinks[0].shareId as string;
|
||||||
|
const newData = deleteSharedLink(sharedLinkData, shareIdToDelete);
|
||||||
|
const deletedDataExists = newData.pages[0].sharedLinks.some(
|
||||||
|
(c) => c.shareId === shareIdToDelete,
|
||||||
|
);
|
||||||
|
expect(deletedDataExists).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
30
client/src/utils/sharedLink.ts
Normal file
30
client/src/utils/sharedLink.ts
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
import { SharedLinkListData, SharedLinkListResponse, TSharedLink } from 'librechat-data-provider';
|
||||||
|
import { addData, deleteData, updateData } from './collection';
|
||||||
|
import { InfiniteData } from '@tanstack/react-query';
|
||||||
|
|
||||||
|
export const addSharedLink = (
|
||||||
|
data: InfiniteData<SharedLinkListResponse>,
|
||||||
|
newSharedLink: TSharedLink,
|
||||||
|
): SharedLinkListData => {
|
||||||
|
return addData<SharedLinkListResponse, TSharedLink>(data, 'sharedLinks', newSharedLink, (page) =>
|
||||||
|
page.sharedLinks.findIndex((c) => c.shareId === newSharedLink.shareId),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateSharedLink = (
|
||||||
|
data: InfiniteData<SharedLinkListResponse>,
|
||||||
|
newSharedLink: TSharedLink,
|
||||||
|
): SharedLinkListData => {
|
||||||
|
return updateData<SharedLinkListResponse, TSharedLink>(
|
||||||
|
data,
|
||||||
|
'sharedLinks',
|
||||||
|
newSharedLink,
|
||||||
|
(page) => page.sharedLinks.findIndex((c) => c.shareId === newSharedLink.shareId),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteSharedLink = (data: SharedLinkListData, shareId: string): SharedLinkListData => {
|
||||||
|
return deleteData<SharedLinkListResponse, SharedLinkListData>(data, 'sharedLinks', (page) =>
|
||||||
|
page.sharedLinks.findIndex((c) => c.shareId === shareId),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -7,6 +7,13 @@ export const userPlugins = () => '/api/user/plugins';
|
||||||
export const messages = (conversationId: string, messageId?: string) =>
|
export const messages = (conversationId: string, messageId?: string) =>
|
||||||
`/api/messages/${conversationId}${messageId ? `/${messageId}` : ''}`;
|
`/api/messages/${conversationId}${messageId ? `/${messageId}` : ''}`;
|
||||||
|
|
||||||
|
const shareRoot = '/api/share';
|
||||||
|
export const shareMessages = (shareId: string) => `${shareRoot}/${shareId}`;
|
||||||
|
export const getSharedLinks = (pageNumber: string, isPublic: boolean) =>
|
||||||
|
`${shareRoot}?pageNumber=${pageNumber}&isPublic=${isPublic}`;
|
||||||
|
export const createSharedLink = shareRoot;
|
||||||
|
export const updateSharedLink = shareRoot;
|
||||||
|
|
||||||
const keysEndpoint = '/api/keys';
|
const keysEndpoint = '/api/keys';
|
||||||
|
|
||||||
export const keys = () => keysEndpoint;
|
export const keys = () => keysEndpoint;
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,34 @@ export function getMessagesByConvoId(conversationId: string): Promise<s.TMessage
|
||||||
return request.get(endpoints.messages(conversationId));
|
return request.get(endpoints.messages(conversationId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getSharedMessages(shareId: string): Promise<t.TSharedMessagesResponse> {
|
||||||
|
return request.get(endpoints.shareMessages(shareId));
|
||||||
|
}
|
||||||
|
|
||||||
|
export const listSharedLinks = (
|
||||||
|
params?: q.SharedLinkListParams,
|
||||||
|
): Promise<q.SharedLinksResponse> => {
|
||||||
|
const pageNumber = params?.pageNumber || '1'; // Default to page 1 if not provided
|
||||||
|
const isPublic = params?.isPublic || true; // Default to true if not provided
|
||||||
|
return request.get(endpoints.getSharedLinks(pageNumber, isPublic));
|
||||||
|
};
|
||||||
|
|
||||||
|
export function getSharedLink(shareId: string): Promise<t.TSharedLinkResponse> {
|
||||||
|
return request.get(endpoints.shareMessages(shareId));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createSharedLink(payload: t.TSharedLinkRequest): Promise<t.TSharedLinkResponse> {
|
||||||
|
return request.post(endpoints.createSharedLink, payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateSharedLink(payload: t.TSharedLinkRequest): Promise<t.TSharedLinkResponse> {
|
||||||
|
return request.patch(endpoints.updateSharedLink, payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function deleteSharedLink(shareId: string): Promise<t.TDeleteSharedLinkResponse> {
|
||||||
|
return request.delete(endpoints.shareMessages(shareId));
|
||||||
|
}
|
||||||
|
|
||||||
export function updateMessage(payload: t.TUpdateMessageRequest): Promise<unknown> {
|
export function updateMessage(payload: t.TUpdateMessageRequest): Promise<unknown> {
|
||||||
const { conversationId, messageId, text } = payload;
|
const { conversationId, messageId, text } = payload;
|
||||||
if (!conversationId) {
|
if (!conversationId) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
export enum QueryKeys {
|
export enum QueryKeys {
|
||||||
messages = 'messages',
|
messages = 'messages',
|
||||||
|
sharedMessages = 'sharedMessages',
|
||||||
|
sharedLinks = 'sharedLinks',
|
||||||
allConversations = 'allConversations',
|
allConversations = 'allConversations',
|
||||||
archivedConversations = 'archivedConversations',
|
archivedConversations = 'archivedConversations',
|
||||||
searchConversations = 'searchConversations',
|
searchConversations = 'searchConversations',
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,22 @@ export const useGetMessagesByConvoId = <TData = s.TMessage[]>(
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useGetSharedMessages = (
|
||||||
|
shareId: string,
|
||||||
|
config?: UseQueryOptions<t.TSharedMessagesResponse>,
|
||||||
|
): QueryObserverResult<t.TSharedMessagesResponse> => {
|
||||||
|
return useQuery<t.TSharedMessagesResponse>(
|
||||||
|
[QueryKeys.sharedMessages, shareId],
|
||||||
|
() => dataService.getSharedMessages(shareId),
|
||||||
|
{
|
||||||
|
refetchOnWindowFocus: false,
|
||||||
|
refetchOnReconnect: false,
|
||||||
|
refetchOnMount: false,
|
||||||
|
...config,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const useGetUserBalance = (
|
export const useGetUserBalance = (
|
||||||
config?: UseQueryOptions<string>,
|
config?: UseQueryOptions<string>,
|
||||||
): QueryObserverResult<string> => {
|
): QueryObserverResult<string> => {
|
||||||
|
|
@ -398,7 +414,9 @@ export const useUpdateUserPluginsMutation = (): UseMutationResult<
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetStartupConfig = (): QueryObserverResult<t.TStartupConfig> => {
|
export const useGetStartupConfig = (
|
||||||
|
config?: UseQueryOptions<t.TStartupConfig>,
|
||||||
|
): QueryObserverResult<t.TStartupConfig> => {
|
||||||
return useQuery<t.TStartupConfig>(
|
return useQuery<t.TStartupConfig>(
|
||||||
[QueryKeys.startupConfig],
|
[QueryKeys.startupConfig],
|
||||||
() => dataService.getStartupConfig(),
|
() => dataService.getStartupConfig(),
|
||||||
|
|
@ -406,6 +424,7 @@ export const useGetStartupConfig = (): QueryObserverResult<t.TStartupConfig> =>
|
||||||
refetchOnWindowFocus: false,
|
refetchOnWindowFocus: false,
|
||||||
refetchOnReconnect: false,
|
refetchOnReconnect: false,
|
||||||
refetchOnMount: false,
|
refetchOnMount: false,
|
||||||
|
...config,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -381,6 +381,19 @@ export type TConversation = z.infer<typeof tConversationSchema> & {
|
||||||
presetOverride?: Partial<TPreset>;
|
presetOverride?: Partial<TPreset>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const tSharedLinkSchema = z.object({
|
||||||
|
conversationId: z.string(),
|
||||||
|
shareId: z.string(),
|
||||||
|
messages: z.array(z.string()),
|
||||||
|
isAnonymous: z.boolean(),
|
||||||
|
isPublic: z.boolean(),
|
||||||
|
isVisible: z.boolean(),
|
||||||
|
title: z.string(),
|
||||||
|
createdAt: z.string(),
|
||||||
|
updatedAt: z.string(),
|
||||||
|
});
|
||||||
|
export type TSharedLink = z.infer<typeof tSharedLinkSchema>;
|
||||||
|
|
||||||
export const openAISchema = tConversationSchema
|
export const openAISchema = tConversationSchema
|
||||||
.pick({
|
.pick({
|
||||||
model: true,
|
model: true,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,12 @@
|
||||||
import OpenAI from 'openai';
|
import OpenAI from 'openai';
|
||||||
import type { TResPlugin, TMessage, TConversation, EModelEndpoint, ImageDetail } from './schemas';
|
import type {
|
||||||
|
TResPlugin,
|
||||||
|
TMessage,
|
||||||
|
TConversation,
|
||||||
|
EModelEndpoint,
|
||||||
|
ImageDetail,
|
||||||
|
TSharedLink,
|
||||||
|
} from './schemas';
|
||||||
import type { TSpecsConfig } from './models';
|
import type { TSpecsConfig } from './models';
|
||||||
export type TOpenAIMessage = OpenAI.Chat.ChatCompletionMessageParam;
|
export type TOpenAIMessage = OpenAI.Chat.ChatCompletionMessageParam;
|
||||||
export type TOpenAIFunction = OpenAI.Chat.ChatCompletionCreateParams.Function;
|
export type TOpenAIFunction = OpenAI.Chat.ChatCompletionCreateParams.Function;
|
||||||
|
|
@ -133,6 +140,19 @@ export type TArchiveConversationRequest = {
|
||||||
|
|
||||||
export type TArchiveConversationResponse = TConversation;
|
export type TArchiveConversationResponse = TConversation;
|
||||||
|
|
||||||
|
export type TSharedMessagesResponse = Omit<TSharedLink, 'messages'> & {
|
||||||
|
messages: TMessage[];
|
||||||
|
};
|
||||||
|
export type TSharedLinkRequest = Partial<
|
||||||
|
Omit<TSharedLink, 'messages' | 'createdAt' | 'updatedAt'>
|
||||||
|
> & {
|
||||||
|
conversationId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TSharedLinkResponse = TSharedLink;
|
||||||
|
export type TSharedLinksResponse = TSharedLink[];
|
||||||
|
export type TDeleteSharedLinkResponse = TSharedLink;
|
||||||
|
|
||||||
export type TForkConvoRequest = {
|
export type TForkConvoRequest = {
|
||||||
messageId: string;
|
messageId: string;
|
||||||
conversationId: string;
|
conversationId: string;
|
||||||
|
|
|
||||||
|
|
@ -90,3 +90,13 @@ export type DeleteConversationOptions = MutationOptions<
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export type ForkConvoOptions = MutationOptions<types.TForkConvoResponse, types.TForkConvoRequest>;
|
export type ForkConvoOptions = MutationOptions<types.TForkConvoResponse, types.TForkConvoRequest>;
|
||||||
|
|
||||||
|
export type CreateSharedLinkOptions = MutationOptions<
|
||||||
|
types.TSharedLink,
|
||||||
|
Partial<types.TSharedLink>
|
||||||
|
>;
|
||||||
|
export type UpdateSharedLinkOptions = MutationOptions<
|
||||||
|
types.TSharedLink,
|
||||||
|
Partial<types.TSharedLink>
|
||||||
|
>;
|
||||||
|
export type DeleteSharedLinkOptions = MutationOptions<types.TSharedLink, { shareId: string }>;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import type { InfiniteData } from '@tanstack/react-query';
|
import type { InfiniteData } from '@tanstack/react-query';
|
||||||
import type { TMessage, TConversation } from '../schemas';
|
import type { TMessage, TConversation, TSharedLink } from '../schemas';
|
||||||
export type Conversation = {
|
export type Conversation = {
|
||||||
id: string;
|
id: string;
|
||||||
createdAt: number;
|
createdAt: number;
|
||||||
|
|
@ -16,7 +16,7 @@ export type ConversationListParams = {
|
||||||
order?: 'asc' | 'desc';
|
order?: 'asc' | 'desc';
|
||||||
pageNumber: string; // Add this line
|
pageNumber: string; // Add this line
|
||||||
conversationId?: string;
|
conversationId?: string;
|
||||||
isArchived: boolean;
|
isArchived?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Type for the response from the conversation list API
|
// Type for the response from the conversation list API
|
||||||
|
|
@ -33,3 +33,24 @@ export type ConversationUpdater = (
|
||||||
data: ConversationData,
|
data: ConversationData,
|
||||||
conversation: TConversation,
|
conversation: TConversation,
|
||||||
) => ConversationData;
|
) => ConversationData;
|
||||||
|
|
||||||
|
export type SharedMessagesResponse = Omit<TSharedLink, 'messages'> & {
|
||||||
|
messages: TMessage[];
|
||||||
|
};
|
||||||
|
export type SharedLinkListParams = Omit<ConversationListParams, 'isArchived' | 'conversationId'> & {
|
||||||
|
isPublic?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SharedLinksResponse = Omit<ConversationListResponse, 'conversations' | 'messages'> & {
|
||||||
|
sharedLinks: TSharedLink[];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Type for the response from the conversation list API
|
||||||
|
export type SharedLinkListResponse = {
|
||||||
|
sharedLinks: TSharedLink[];
|
||||||
|
pageNumber: string;
|
||||||
|
pageSize: string | number;
|
||||||
|
pages: string | number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SharedLinkListData = InfiniteData<SharedLinkListResponse>;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue