diff --git a/backend/open_webui/env.py b/backend/open_webui/env.py
index 77e632ccc..b589e9490 100644
--- a/backend/open_webui/env.py
+++ b/backend/open_webui/env.py
@@ -356,15 +356,16 @@ WEBUI_SECRET_KEY = os.environ.get(
), # DEPRECATED: remove at next major version
)
-WEBUI_SESSION_COOKIE_SAME_SITE = os.environ.get(
- "WEBUI_SESSION_COOKIE_SAME_SITE",
- os.environ.get("WEBUI_SESSION_COOKIE_SAME_SITE", "lax"),
-)
+WEBUI_SESSION_COOKIE_SAME_SITE = os.environ.get("WEBUI_SESSION_COOKIE_SAME_SITE", "lax")
-WEBUI_SESSION_COOKIE_SECURE = os.environ.get(
- "WEBUI_SESSION_COOKIE_SECURE",
- os.environ.get("WEBUI_SESSION_COOKIE_SECURE", "false").lower() == "true",
-)
+WEBUI_SESSION_COOKIE_SECURE = os.environ.get("WEBUI_SESSION_COOKIE_SECURE", "false").lower() == "true"
+
+WEBUI_AUTH_COOKIE_SAME_SITE = os.environ.get("WEBUI_AUTH_COOKIE_SAME_SITE", WEBUI_SESSION_COOKIE_SAME_SITE)
+
+WEBUI_AUTH_COOKIE_SECURE = os.environ.get(
+ "WEBUI_AUTH_COOKIE_SECURE",
+ os.environ.get("WEBUI_SESSION_COOKIE_SECURE", "false")
+).lower() == "true"
if WEBUI_AUTH and WEBUI_SECRET_KEY == "":
raise ValueError(ERROR_MESSAGES.ENV_VAR_NOT_FOUND)
diff --git a/backend/open_webui/routers/auths.py b/backend/open_webui/routers/auths.py
index 47baeb0ac..d7c4fa013 100644
--- a/backend/open_webui/routers/auths.py
+++ b/backend/open_webui/routers/auths.py
@@ -25,8 +25,8 @@ from open_webui.env import (
WEBUI_AUTH,
WEBUI_AUTH_TRUSTED_EMAIL_HEADER,
WEBUI_AUTH_TRUSTED_NAME_HEADER,
- WEBUI_SESSION_COOKIE_SAME_SITE,
- WEBUI_SESSION_COOKIE_SECURE,
+ WEBUI_AUTH_COOKIE_SAME_SITE,
+ WEBUI_AUTH_COOKIE_SECURE,
SRC_LOG_LEVELS,
)
from fastapi import APIRouter, Depends, HTTPException, Request, status
@@ -95,8 +95,8 @@ async def get_session_user(
value=token,
expires=datetime_expires_at,
httponly=True, # Ensures the cookie is not accessible via JavaScript
- samesite=WEBUI_SESSION_COOKIE_SAME_SITE,
- secure=WEBUI_SESSION_COOKIE_SECURE,
+ samesite=WEBUI_AUTH_COOKIE_SAME_SITE,
+ secure=WEBUI_AUTH_COOKIE_SECURE,
)
user_permissions = get_permissions(
@@ -378,8 +378,8 @@ async def signin(request: Request, response: Response, form_data: SigninForm):
value=token,
expires=datetime_expires_at,
httponly=True, # Ensures the cookie is not accessible via JavaScript
- samesite=WEBUI_SESSION_COOKIE_SAME_SITE,
- secure=WEBUI_SESSION_COOKIE_SECURE,
+ samesite=WEBUI_AUTH_COOKIE_SAME_SITE,
+ secure=WEBUI_AUTH_COOKIE_SECURE,
)
user_permissions = get_permissions(
@@ -473,8 +473,8 @@ async def signup(request: Request, response: Response, form_data: SignupForm):
value=token,
expires=datetime_expires_at,
httponly=True, # Ensures the cookie is not accessible via JavaScript
- samesite=WEBUI_SESSION_COOKIE_SAME_SITE,
- secure=WEBUI_SESSION_COOKIE_SECURE,
+ samesite=WEBUI_AUTH_COOKIE_SAME_SITE,
+ secure=WEBUI_AUTH_COOKIE_SECURE,
)
if request.app.state.config.WEBHOOK_URL:
diff --git a/backend/open_webui/routers/knowledge.py b/backend/open_webui/routers/knowledge.py
index cce3d6311..a85ccd05e 100644
--- a/backend/open_webui/routers/knowledge.py
+++ b/backend/open_webui/routers/knowledge.py
@@ -264,7 +264,10 @@ def add_file_to_knowledge_by_id(
detail=ERROR_MESSAGES.NOT_FOUND,
)
- if knowledge.user_id != user.id and user.role != "admin":
+ if (knowledge.user_id != user.id
+ and not has_access(user.id, "write", knowledge.access_control)
+ and user.role != "admin"
+ ):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=ERROR_MESSAGES.ACCESS_PROHIBITED,
@@ -342,7 +345,12 @@ def update_file_from_knowledge_by_id(
detail=ERROR_MESSAGES.NOT_FOUND,
)
- if knowledge.user_id != user.id and user.role != "admin":
+ if (
+ knowledge.user_id != user.id
+ and not has_access(user.id, "write", knowledge.access_control)
+ and user.role != "admin"
+ ):
+
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=ERROR_MESSAGES.ACCESS_PROHIBITED,
@@ -406,7 +414,11 @@ def remove_file_from_knowledge_by_id(
detail=ERROR_MESSAGES.NOT_FOUND,
)
- if knowledge.user_id != user.id and user.role != "admin":
+ if (
+ knowledge.user_id != user.id
+ and not has_access(user.id, "write", knowledge.access_control)
+ and user.role != "admin"
+ ):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=ERROR_MESSAGES.ACCESS_PROHIBITED,
@@ -484,7 +496,11 @@ async def delete_knowledge_by_id(id: str, user=Depends(get_verified_user)):
detail=ERROR_MESSAGES.NOT_FOUND,
)
- if knowledge.user_id != user.id and user.role != "admin":
+ if (
+ knowledge.user_id != user.id
+ and not has_access(user.id, "write", knowledge.access_control)
+ and user.role != "admin"
+ ):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=ERROR_MESSAGES.ACCESS_PROHIBITED,
@@ -543,7 +559,11 @@ async def reset_knowledge_by_id(id: str, user=Depends(get_verified_user)):
detail=ERROR_MESSAGES.NOT_FOUND,
)
- if knowledge.user_id != user.id and user.role != "admin":
+ if (
+ knowledge.user_id != user.id
+ and not has_access(user.id, "write", knowledge.access_control)
+ and user.role != "admin"
+ ):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=ERROR_MESSAGES.ACCESS_PROHIBITED,
@@ -582,7 +602,11 @@ def add_files_to_knowledge_batch(
detail=ERROR_MESSAGES.NOT_FOUND,
)
- if knowledge.user_id != user.id and user.role != "admin":
+ if (
+ knowledge.user_id != user.id
+ and not has_access(user.id, "write", knowledge.access_control)
+ and user.role != "admin"
+ ):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=ERROR_MESSAGES.ACCESS_PROHIBITED,
diff --git a/backend/open_webui/routers/models.py b/backend/open_webui/routers/models.py
index 6c8519b2c..a45814d32 100644
--- a/backend/open_webui/routers/models.py
+++ b/backend/open_webui/routers/models.py
@@ -183,7 +183,11 @@ async def delete_model_by_id(id: str, user=Depends(get_verified_user)):
detail=ERROR_MESSAGES.NOT_FOUND,
)
- if model.user_id != user.id and user.role != "admin":
+ if (
+ user.role == "admin"
+ or model.user_id == user.id
+ or has_access(user.id, "write", model.access_control)
+ ):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail=ERROR_MESSAGES.UNAUTHORIZED,
diff --git a/backend/open_webui/routers/prompts.py b/backend/open_webui/routers/prompts.py
index 014e5652e..9fb946c6e 100644
--- a/backend/open_webui/routers/prompts.py
+++ b/backend/open_webui/routers/prompts.py
@@ -147,7 +147,11 @@ async def delete_prompt_by_command(command: str, user=Depends(get_verified_user)
detail=ERROR_MESSAGES.NOT_FOUND,
)
- if prompt.user_id != user.id and user.role != "admin":
+ if (
+ prompt.user_id != user.id
+ and not has_access(user.id, "write", prompt.access_control)
+ and user.role != "admin"
+ ):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail=ERROR_MESSAGES.ACCESS_PROHIBITED,
diff --git a/backend/open_webui/routers/tools.py b/backend/open_webui/routers/tools.py
index 7b9144b4c..d6a5c5532 100644
--- a/backend/open_webui/routers/tools.py
+++ b/backend/open_webui/routers/tools.py
@@ -227,7 +227,11 @@ async def delete_tools_by_id(
detail=ERROR_MESSAGES.NOT_FOUND,
)
- if tools.user_id != user.id and user.role != "admin":
+ if (
+ tools.user_id != user.id
+ and not has_access(user.id, "write", tools.access_control)
+ and user.role != "admin"
+ ):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail=ERROR_MESSAGES.UNAUTHORIZED,
diff --git a/backend/open_webui/utils/misc.py b/backend/open_webui/utils/misc.py
index a83733d63..8792b1cfc 100644
--- a/backend/open_webui/utils/misc.py
+++ b/backend/open_webui/utils/misc.py
@@ -149,6 +149,7 @@ def openai_chat_chunk_message_template(
template["choices"][0]["delta"] = {"content": message}
else:
template["choices"][0]["finish_reason"] = "stop"
+ template["choices"][0]["delta"] = {}
if usage:
template["usage"] = usage
diff --git a/backend/open_webui/utils/oauth.py b/backend/open_webui/utils/oauth.py
index 1ae6d4aa7..b336f0631 100644
--- a/backend/open_webui/utils/oauth.py
+++ b/backend/open_webui/utils/oauth.py
@@ -35,7 +35,7 @@ from open_webui.config import (
AppConfig,
)
from open_webui.constants import ERROR_MESSAGES, WEBHOOK_MESSAGES
-from open_webui.env import WEBUI_SESSION_COOKIE_SAME_SITE, WEBUI_SESSION_COOKIE_SECURE
+from open_webui.env import WEBUI_AUTH_COOKIE_SAME_SITE, WEBUI_AUTH_COOKIE_SECURE
from open_webui.utils.misc import parse_duration
from open_webui.utils.auth import get_password_hash, create_token
from open_webui.utils.webhook import post_webhook
@@ -323,8 +323,8 @@ class OAuthManager:
key="token",
value=jwt_token,
httponly=True, # Ensures the cookie is not accessible via JavaScript
- samesite=WEBUI_SESSION_COOKIE_SAME_SITE,
- secure=WEBUI_SESSION_COOKIE_SECURE,
+ samesite=WEBUI_AUTH_COOKIE_SAME_SITE,
+ secure=WEBUI_AUTH_COOKIE_SECURE,
)
if ENABLE_OAUTH_SIGNUP.value:
@@ -333,8 +333,8 @@ class OAuthManager:
key="oauth_id_token",
value=oauth_id_token,
httponly=True,
- samesite=WEBUI_SESSION_COOKIE_SAME_SITE,
- secure=WEBUI_SESSION_COOKIE_SECURE,
+ samesite=WEBUI_AUTH_COOKIE_SAME_SITE,
+ secure=WEBUI_AUTH_COOKIE_SECURE,
)
# Redirect back to the frontend with the JWT token
redirect_url = f"{request.base_url}auth#token={jwt_token}"
diff --git a/src/lib/components/admin/Users/UserList.svelte b/src/lib/components/admin/Users/UserList.svelte
index 2ee4297a4..ce730571f 100644
--- a/src/lib/components/admin/Users/UserList.svelte
+++ b/src/lib/components/admin/Users/UserList.svelte
@@ -6,7 +6,9 @@
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
+ import localizedFormat from 'dayjs/plugin/localizedFormat';
dayjs.extend(relativeTime);
+ dayjs.extend(localizedFormat);
import { toast } from 'svelte-sonner';
@@ -364,7 +366,7 @@
- {dayjs(user.created_at * 1000).format($i18n.t('MMMM DD, YYYY'))}
+ {dayjs(user.created_at * 1000).format('LL')}
|
{user.oauth_sub ?? ''} |
diff --git a/src/lib/components/admin/Users/UserList/EditUserModal.svelte b/src/lib/components/admin/Users/UserList/EditUserModal.svelte
index 868951d57..9b2edb407 100644
--- a/src/lib/components/admin/Users/UserList/EditUserModal.svelte
+++ b/src/lib/components/admin/Users/UserList/EditUserModal.svelte
@@ -7,9 +7,11 @@
import { updateUserById } from '$lib/apis/users';
import Modal from '$lib/components/common/Modal.svelte';
+ import localizedFormat from 'dayjs/plugin/localizedFormat';
const i18n = getContext('i18n');
const dispatch = createEventDispatcher();
+ dayjs.extend(localizedFormat);
export let show = false;
export let selectedUser;
@@ -87,7 +89,7 @@
{$i18n.t('Created at')}
- {dayjs(selectedUser.created_at * 1000).format($i18n.t('MMMM DD, YYYY'))}
+ {dayjs(selectedUser.created_at * 1000).format('LL')}
diff --git a/src/lib/components/admin/Users/UserList/UserChatsModal.svelte b/src/lib/components/admin/Users/UserList/UserChatsModal.svelte
index 92970b658..a95df8291 100644
--- a/src/lib/components/admin/Users/UserList/UserChatsModal.svelte
+++ b/src/lib/components/admin/Users/UserList/UserChatsModal.svelte
@@ -2,8 +2,10 @@
import { toast } from 'svelte-sonner';
import dayjs from 'dayjs';
import { getContext, createEventDispatcher } from 'svelte';
+ import localizedFormat from 'dayjs/plugin/localizedFormat';
const dispatch = createEventDispatcher();
+ dayjs.extend(localizedFormat);
import { getChatListByUserId, deleteChatById, getArchivedChatList } from '$lib/apis/chats';
@@ -130,7 +132,7 @@
- {dayjs(chat.updated_at * 1000).format($i18n.t('MMMM DD, YYYY HH:mm'))}
+ {dayjs(chat.updated_at * 1000).format('LLL')}
|
diff --git a/src/lib/components/channel/Messages/Message.svelte b/src/lib/components/channel/Messages/Message.svelte
index ef17feb7f..a84077823 100644
--- a/src/lib/components/channel/Messages/Message.svelte
+++ b/src/lib/components/channel/Messages/Message.svelte
@@ -3,10 +3,12 @@
import relativeTime from 'dayjs/plugin/relativeTime';
import isToday from 'dayjs/plugin/isToday';
import isYesterday from 'dayjs/plugin/isYesterday';
+ import localizedFormat from 'dayjs/plugin/localizedFormat';
dayjs.extend(relativeTime);
dayjs.extend(isToday);
dayjs.extend(isYesterday);
+ dayjs.extend(localizedFormat);
import { getContext, onMount } from 'svelte';
const i18n = getContext>('i18n');
@@ -154,9 +156,9 @@
class="mt-1.5 flex flex-shrink-0 items-center text-xs self-center invisible group-hover:visible text-gray-500 font-medium first-letter:capitalize"
>
- {dayjs(message.created_at / 1000000).format('HH:mm')}
+ {dayjs(message.created_at / 1000000).format('LT')}
{/if}
@@ -175,7 +177,7 @@
class=" self-center text-xs invisible group-hover:visible text-gray-400 font-medium first-letter:capitalize ml-0.5 translate-y-[1px]"
>
{formatDate(message.created_at / 1000000)}
diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte
index bfd643c09..9c2a55b4f 100644
--- a/src/lib/components/chat/Chat.svelte
+++ b/src/lib/components/chat/Chat.svelte
@@ -82,10 +82,12 @@
import EventConfirmDialog from '../common/ConfirmDialog.svelte';
import Placeholder from './Placeholder.svelte';
import NotificationToast from '../NotificationToast.svelte';
+ import Spinner from '../common/Spinner.svelte';
export let chatIdProp = '';
- let loaded = false;
+ let loading = false;
+
const eventTarget = new EventTarget();
let controlPane;
let controlPaneComponent;
@@ -133,6 +135,7 @@
$: if (chatIdProp) {
(async () => {
+ loading = true;
console.log(chatIdProp);
prompt = '';
@@ -141,11 +144,9 @@
webSearchEnabled = false;
imageGenerationEnabled = false;
- loaded = false;
-
if (chatIdProp && (await loadChat())) {
await tick();
- loaded = true;
+ loading = false;
if (localStorage.getItem(`chat-input-${chatIdProp}`)) {
try {
@@ -1866,7 +1867,7 @@
: ' '} w-full max-w-full flex flex-col"
id="chat-container"
>
- {#if !chatIdProp || (loaded && chatIdProp)}
+ {#if chatIdProp === '' || (!loading && chatIdProp)}
{#if $settings?.backgroundImageUrl ?? null}
{/if}
diff --git a/src/lib/components/chat/MessageInput/InputMenu.svelte b/src/lib/components/chat/MessageInput/InputMenu.svelte
index 20b297eb3..3c8eaf008 100644
--- a/src/lib/components/chat/MessageInput/InputMenu.svelte
+++ b/src/lib/components/chat/MessageInput/InputMenu.svelte
@@ -48,6 +48,9 @@
init();
}
+ let fileUploadEnabled = true;
+ $: fileUploadEnabled = $user.role === 'admin' || $user?.permissions?.chat?.file_upload;
+
const init = async () => {
if ($_tools === null) {
await _tools.set(await getTools(localStorage.token));
@@ -166,26 +169,44 @@
{/if}
{#if !$mobile}
- {
- screenCaptureHandler();
- }}
+
-
- {$i18n.t('Capture')}
-
+ {
+ if (fileUploadEnabled) {
+ screenCaptureHandler();
+ }
+ }}
+ >
+
+ {$i18n.t('Capture')}
+
+
{/if}
- {
- uploadFilesHandler();
- }}
+
-
- {$i18n.t('Upload Files')}
-
+ {
+ if (fileUploadEnabled) {
+ uploadFilesHandler();
+ }
+ }}
+ >
+
+ {$i18n.t('Upload Files')}
+
+
{#if $config?.features?.enable_google_drive_integration}
- {dayjs(message.timestamp * 1000).format($i18n.t('h:mm a'))}
+ {dayjs(message.timestamp * 1000).format('LT')}
{/if}
diff --git a/src/lib/components/chat/Messages/ResponseMessage.svelte b/src/lib/components/chat/Messages/ResponseMessage.svelte
index 1768d584d..d6b31e6a0 100644
--- a/src/lib/components/chat/Messages/ResponseMessage.svelte
+++ b/src/lib/components/chat/Messages/ResponseMessage.svelte
@@ -500,7 +500,7 @@
-
+
{formatDate(message.timestamp * 1000)}
diff --git a/src/lib/components/chat/Messages/UserMessage.svelte b/src/lib/components/chat/Messages/UserMessage.svelte
index db1d31548..bf22e558a 100644
--- a/src/lib/components/chat/Messages/UserMessage.svelte
+++ b/src/lib/components/chat/Messages/UserMessage.svelte
@@ -13,8 +13,10 @@
import FileItem from '$lib/components/common/FileItem.svelte';
import Markdown from './Markdown.svelte';
import Image from '$lib/components/common/Image.svelte';
+ import localizedFormat from 'dayjs/plugin/localizedFormat';
const i18n = getContext('i18n');
+ dayjs.extend(localizedFormat);
export let user;
@@ -112,7 +114,7 @@
-
+
{formatDate(message.timestamp * 1000)}
diff --git a/src/lib/components/chat/Settings/Personalization/ManageModal.svelte b/src/lib/components/chat/Settings/Personalization/ManageModal.svelte
index e4613b5fe..a9f72ccbb 100644
--- a/src/lib/components/chat/Settings/Personalization/ManageModal.svelte
+++ b/src/lib/components/chat/Settings/Personalization/ManageModal.svelte
@@ -11,8 +11,10 @@
import Tooltip from '$lib/components/common/Tooltip.svelte';
import { error } from '@sveltejs/kit';
import EditMemoryModal from './EditMemoryModal.svelte';
+ import localizedFormat from 'dayjs/plugin/localizedFormat';
const i18n = getContext('i18n');
+ dayjs.extend(localizedFormat);
export let show = false;
@@ -84,9 +86,7 @@
- {dayjs(memory.updated_at * 1000).format(
- $i18n.t('MMMM DD, YYYY hh:mm:ss A')
- )}
+ {dayjs(memory.updated_at * 1000).format('LLL')}
|
diff --git a/src/lib/components/layout/Sidebar/ArchivedChatsModal.svelte b/src/lib/components/layout/Sidebar/ArchivedChatsModal.svelte
index 6626cfed7..7af0c6ded 100644
--- a/src/lib/components/layout/Sidebar/ArchivedChatsModal.svelte
+++ b/src/lib/components/layout/Sidebar/ArchivedChatsModal.svelte
@@ -4,6 +4,9 @@
import { toast } from 'svelte-sonner';
import dayjs from 'dayjs';
import { getContext, createEventDispatcher } from 'svelte';
+ import localizedFormat from 'dayjs/plugin/localizedFormat';
+
+ dayjs.extend(localizedFormat);
const dispatch = createEventDispatcher();
@@ -159,7 +162,7 @@
|
- {dayjs(chat.created_at * 1000).format($i18n.t('MMMM DD, YYYY HH:mm'))}
+ {dayjs(chat.created_at * 1000).format('LLL')}
|
diff --git a/src/lib/components/workspace/Knowledge/CreateKnowledgeBase.svelte b/src/lib/components/workspace/Knowledge/CreateKnowledgeBase.svelte
index 5d1e79808..8253c1f68 100644
--- a/src/lib/components/workspace/Knowledge/CreateKnowledgeBase.svelte
+++ b/src/lib/components/workspace/Knowledge/CreateKnowledgeBase.svelte
@@ -112,7 +112,10 @@
diff --git a/src/lib/components/workspace/Models/ModelEditor.svelte b/src/lib/components/workspace/Models/ModelEditor.svelte
index 58628f0d1..ae10c6eba 100644
--- a/src/lib/components/workspace/Models/ModelEditor.svelte
+++ b/src/lib/components/workspace/Models/ModelEditor.svelte
@@ -531,7 +531,10 @@
diff --git a/src/lib/i18n/locales/ja-JP/translation.json b/src/lib/i18n/locales/ja-JP/translation.json
index a4d1927b4..c0f170091 100644
--- a/src/lib/i18n/locales/ja-JP/translation.json
+++ b/src/lib/i18n/locales/ja-JP/translation.json
@@ -767,7 +767,7 @@
"Reset": "",
"Reset All Models": "",
"Reset Upload Directory": "アップロードディレクトリをリセット",
- "Reset Vector Storage/Knowledge": "ベクターストレージとナレッジべーうをリセット",
+ "Reset Vector Storage/Knowledge": "ベクターストレージとナレッジベースをリセット",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
"Response splitting": "応答の分割",
diff --git a/src/lib/i18n/locales/zh-TW/translation.json b/src/lib/i18n/locales/zh-TW/translation.json
index 9fd72430f..dfc20f6d6 100644
--- a/src/lib/i18n/locales/zh-TW/translation.json
+++ b/src/lib/i18n/locales/zh-TW/translation.json
@@ -935,7 +935,7 @@
"This will delete all models including custom models and cannot be undone.": "這將刪除所有模型,包括自訂模型,且無法復原。",
"This will reset the knowledge base and sync all files. Do you wish to continue?": "這將重設知識庫並同步所有檔案。您確定要繼續嗎?",
"Thorough explanation": "詳細解釋",
- "Thought for {{DURATION}}": "",
+ "Thought for {{DURATION}}": "{{DURATION}} 思考中",
"Tika": "Tika",
"Tika Server URL required.": "需要 Tika 伺服器 URL。",
"Tiktoken": "Tiktoken",
diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts
index 24d6f23b5..20f44f49b 100644
--- a/src/lib/utils/index.ts
+++ b/src/lib/utils/index.ts
@@ -5,10 +5,12 @@ import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
import isToday from 'dayjs/plugin/isToday';
import isYesterday from 'dayjs/plugin/isYesterday';
+import localizedFormat from 'dayjs/plugin/localizedFormat';
dayjs.extend(relativeTime);
dayjs.extend(isToday);
dayjs.extend(isYesterday);
+dayjs.extend(localizedFormat);
import { WEBUI_BASE_URL } from '$lib/constants';
import { TTS_RESPONSE_SPLIT } from '$lib/types';
@@ -295,11 +297,11 @@ export const formatDate = (inputDate) => {
const now = dayjs();
if (date.isToday()) {
- return `Today at ${date.format('HH:mm')}`;
+ return `Today at ${date.format('LT')}`;
} else if (date.isYesterday()) {
- return `Yesterday at ${date.format('HH:mm')}`;
+ return `Yesterday at ${date.format('LT')}`;
} else {
- return `${date.format('DD/MM/YYYY')} at ${date.format('HH:mm')}`;
+ return `${date.format('L')} at ${date.format('LT')}`;
}
};
diff --git a/src/routes/s/[id]/+page.svelte b/src/routes/s/[id]/+page.svelte
index dfef68513..36ea3541e 100644
--- a/src/routes/s/[id]/+page.svelte
+++ b/src/routes/s/[id]/+page.svelte
@@ -16,8 +16,10 @@
import { getUserById } from '$lib/apis/users';
import { getModels } from '$lib/apis';
import { toast } from 'svelte-sonner';
+ import localizedFormat from 'dayjs/plugin/localizedFormat';
const i18n = getContext('i18n');
+ dayjs.extend(localizedFormat);
let loaded = false;
@@ -138,7 +140,7 @@
- {dayjs(chat.chat.timestamp).format($i18n.t('MMMM DD, YYYY'))}
+ {dayjs(chat.chat.timestamp).format('LLL')}