@lobehub/chat 1.26.21 → 1.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/locales/ar/chat.json +1 -21
- package/locales/ar/error.json +4 -1
- package/locales/ar/topic.json +37 -0
- package/locales/bg-BG/chat.json +1 -21
- package/locales/bg-BG/error.json +4 -1
- package/locales/bg-BG/topic.json +37 -0
- package/locales/de-DE/chat.json +1 -21
- package/locales/de-DE/error.json +4 -1
- package/locales/de-DE/topic.json +37 -0
- package/locales/en-US/chat.json +1 -21
- package/locales/en-US/error.json +4 -1
- package/locales/en-US/topic.json +37 -0
- package/locales/es-ES/chat.json +1 -21
- package/locales/es-ES/error.json +4 -1
- package/locales/es-ES/topic.json +37 -0
- package/locales/fa-IR/chat.json +1 -21
- package/locales/fa-IR/components.json +1 -0
- package/locales/fa-IR/error.json +4 -1
- package/locales/fa-IR/topic.json +37 -0
- package/locales/fr-FR/chat.json +1 -21
- package/locales/fr-FR/error.json +4 -1
- package/locales/fr-FR/topic.json +37 -0
- package/locales/it-IT/chat.json +1 -21
- package/locales/it-IT/error.json +4 -1
- package/locales/it-IT/topic.json +37 -0
- package/locales/ja-JP/chat.json +1 -21
- package/locales/ja-JP/error.json +4 -1
- package/locales/ja-JP/topic.json +37 -0
- package/locales/ko-KR/chat.json +1 -21
- package/locales/ko-KR/error.json +4 -1
- package/locales/ko-KR/topic.json +37 -0
- package/locales/nl-NL/chat.json +1 -21
- package/locales/nl-NL/error.json +4 -1
- package/locales/nl-NL/topic.json +37 -0
- package/locales/pl-PL/chat.json +1 -21
- package/locales/pl-PL/error.json +4 -1
- package/locales/pl-PL/topic.json +37 -0
- package/locales/pt-BR/chat.json +1 -21
- package/locales/pt-BR/error.json +4 -1
- package/locales/pt-BR/topic.json +37 -0
- package/locales/ru-RU/chat.json +1 -21
- package/locales/ru-RU/error.json +4 -1
- package/locales/ru-RU/topic.json +37 -0
- package/locales/tr-TR/chat.json +1 -21
- package/locales/tr-TR/error.json +4 -1
- package/locales/tr-TR/topic.json +37 -0
- package/locales/vi-VN/chat.json +1 -21
- package/locales/vi-VN/error.json +4 -1
- package/locales/vi-VN/topic.json +37 -0
- package/locales/zh-CN/chat.json +1 -21
- package/locales/zh-CN/topic.json +37 -0
- package/locales/zh-TW/chat.json +1 -21
- package/locales/zh-TW/error.json +4 -1
- package/locales/zh-TW/topic.json +37 -0
- package/package.json +1 -1
- package/src/app/(main)/@nav/_layout/Desktop/TopActions.tsx +3 -2
- package/src/app/(main)/@nav/_layout/Desktop/index.tsx +4 -1
- package/src/app/(main)/chat/(workspace)/@topic/features/Header.tsx +27 -9
- package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/ByTimeMode/GroupItem.tsx +30 -0
- package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/ByTimeMode/index.tsx +72 -0
- package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/DefaultContent.tsx +2 -2
- package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/FlatMode/index.tsx +60 -0
- package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/TopicContent.tsx +7 -7
- package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/index.tsx +17 -53
- package/src/app/(main)/chat/(workspace)/@topic/features/TopicSearchBar/index.tsx +2 -2
- package/src/app/(main)/chat/(workspace)/_layout/Mobile/ChatHeader/ChatHeaderTitle.tsx +2 -2
- package/src/app/(main)/chat/(workspace)/_layout/Mobile/TopicModal.tsx +5 -2
- package/src/const/user.ts +2 -0
- package/src/hooks/useFetchTopics.ts +11 -0
- package/src/locales/default/chat.ts +0 -20
- package/src/locales/default/index.ts +3 -1
- package/src/locales/default/topic.ts +37 -0
- package/src/store/chat/slices/topic/action.test.ts +1 -1
- package/src/store/chat/slices/topic/action.ts +4 -4
- package/src/store/chat/slices/topic/selectors.test.ts +78 -1
- package/src/store/chat/slices/topic/selectors.ts +28 -1
- package/src/store/user/slices/preference/selectors.ts +4 -0
- package/src/types/topic.ts +24 -0
- package/src/types/user/index.ts +2 -0
- package/src/utils/client/topic.test.ts +142 -0
- package/src/utils/client/topic.ts +86 -0
@@ -0,0 +1,37 @@
|
|
1
|
+
{
|
2
|
+
"actions": {
|
3
|
+
"autoRename": "Умное переименование",
|
4
|
+
"confirmRemoveAll": "Вы собираетесь удалить все темы. После удаления их нельзя будет восстановить, пожалуйста, будьте осторожны.",
|
5
|
+
"confirmRemoveTopic": "Вы собираетесь удалить эту тему. После удаления её нельзя будет восстановить, пожалуйста, будьте осторожны.",
|
6
|
+
"confirmRemoveUnstarred": "Вы собираетесь удалить неотмеченные темы. После удаления их нельзя будет восстановить, пожалуйста, будьте осторожны.",
|
7
|
+
"duplicate": "Создать копию",
|
8
|
+
"export": "Экспортировать тему",
|
9
|
+
"removeAll": "Удалить все темы",
|
10
|
+
"removeUnstarred": "Удалить неотмеченные темы"
|
11
|
+
},
|
12
|
+
"defaultTitle": "Тема по умолчанию",
|
13
|
+
"duplicateLoading": "Копирование темы...",
|
14
|
+
"duplicateSuccess": "Тема успешно скопирована",
|
15
|
+
"favorite": "Избранное",
|
16
|
+
"groupMode": {
|
17
|
+
"ascMessages": "По возрастанию общего числа сообщений",
|
18
|
+
"byTime": "Группировка по времени",
|
19
|
+
"descMessages": "По убыванию общего числа сообщений",
|
20
|
+
"flat": "Без группировки"
|
21
|
+
},
|
22
|
+
"groupTitle": {
|
23
|
+
"byTime": {
|
24
|
+
"month": "Этот месяц",
|
25
|
+
"today": "Сегодня",
|
26
|
+
"week": "Эта неделя",
|
27
|
+
"yesterday": "Вчера"
|
28
|
+
}
|
29
|
+
},
|
30
|
+
"guide": {
|
31
|
+
"desc": "Нажмите кнопку слева от отправки, чтобы сохранить текущий разговор как историческую тему и начать новый разговор.",
|
32
|
+
"title": "Список тем"
|
33
|
+
},
|
34
|
+
"searchPlaceholder": "Поиск тем...",
|
35
|
+
"temp": "Временный",
|
36
|
+
"title": "Тема"
|
37
|
+
}
|
package/locales/tr-TR/chat.json
CHANGED
@@ -115,7 +115,6 @@
|
|
115
115
|
"loading": "Tanımlanıyor...",
|
116
116
|
"prettifying": "İyileştiriliyor..."
|
117
117
|
},
|
118
|
-
"temp": "Geçici",
|
119
118
|
"tokenDetails": {
|
120
119
|
"chats": "Sohbetler",
|
121
120
|
"rest": "Kalan",
|
@@ -131,29 +130,10 @@
|
|
131
130
|
"used": "Kullanılan"
|
132
131
|
},
|
133
132
|
"topic": {
|
134
|
-
"actions": {
|
135
|
-
"autoRename": "Akıllı Yeniden Adlandırma",
|
136
|
-
"duplicate": "Kopya Oluştur",
|
137
|
-
"export": "Konuyu Dışa Aktar"
|
138
|
-
},
|
139
133
|
"checkOpenNewTopic": "Yeni bir konu açılsın mı?",
|
140
134
|
"checkSaveCurrentMessages": "Mevcut sohbeti konu olarak kaydetmek istiyor musunuz?",
|
141
|
-
"confirmRemoveAll": "Tüm konuları silmek üzeresiniz. Bir kere silindiğinde, geri alınamazlar. Lütfen dikkatli bir şekilde devam edin.",
|
142
|
-
"confirmRemoveTopic": "Bu konuyu silmek üzeresiniz. Bir kere silindiğinde, geri alınamaz. Lütfen dikkatli bir şekilde devam edin.",
|
143
|
-
"confirmRemoveUnstarred": "Yıldızlanmamış konuları silmek üzeresiniz. Bir kere silindiğinde, geri alınamazlar. Lütfen dikkatli bir şekilde devam edin.",
|
144
|
-
"defaultTitle": "Konu",
|
145
|
-
"duplicateLoading": "Konu kopyalanıyor...",
|
146
|
-
"duplicateSuccess": "Konu başarıyla kopyalandı",
|
147
|
-
"guide": {
|
148
|
-
"desc": "Mevcut oturumu geçmiş konu olarak kaydetmek ve yeni bir oturum başlatmak için sol taraftaki düğmeye tıklayın",
|
149
|
-
"title": "Konu Listesi"
|
150
|
-
},
|
151
135
|
"openNewTopic": "Yeni Konu",
|
152
|
-
"
|
153
|
-
"removeUnstarred": "Tüm Yıldızlanmamış Konuları Sil",
|
154
|
-
"saveCurrentMessages": "Mevcut oturumu konu olarak kaydet",
|
155
|
-
"searchPlaceholder": "Konuları ara...",
|
156
|
-
"title": "Konular"
|
136
|
+
"saveCurrentMessages": "Mevcut oturumu konu olarak kaydet"
|
157
137
|
},
|
158
138
|
"translate": {
|
159
139
|
"action": "Çeviri",
|
package/locales/tr-TR/error.json
CHANGED
@@ -12,7 +12,10 @@
|
|
12
12
|
"retry": "Yeniden Yükle",
|
13
13
|
"title": "Sayfa bir sorunla karşılaştı.."
|
14
14
|
},
|
15
|
-
"fetchError":
|
15
|
+
"fetchError": {
|
16
|
+
"detail": "Hata Detayı",
|
17
|
+
"title": "İstek Başarısız"
|
18
|
+
},
|
16
19
|
"loginRequired": {
|
17
20
|
"desc": "Otomatik olarak giriş sayfasına yönlendirileceksiniz",
|
18
21
|
"title": "Lütfen bu özelliği kullanmadan önce giriş yapın"
|
@@ -0,0 +1,37 @@
|
|
1
|
+
{
|
2
|
+
"actions": {
|
3
|
+
"autoRename": "Akıllı Yeniden Adlandırma",
|
4
|
+
"confirmRemoveAll": "Tüm konular silinecek, silindikten sonra geri alınamaz, lütfen dikkatli olun.",
|
5
|
+
"confirmRemoveTopic": "Bu konu silinecek, silindikten sonra geri alınamaz, lütfen dikkatli olun.",
|
6
|
+
"confirmRemoveUnstarred": "Favori olmayan konular silinecek, silindikten sonra geri alınamaz, lütfen dikkatli olun.",
|
7
|
+
"duplicate": "Kopya Oluştur",
|
8
|
+
"export": "Konuları Dışa Aktar",
|
9
|
+
"removeAll": "Tüm Konuları Sil",
|
10
|
+
"removeUnstarred": "Favori Olmayan Konuları Sil"
|
11
|
+
},
|
12
|
+
"defaultTitle": "Varsayılan Konu",
|
13
|
+
"duplicateLoading": "Konu Kopyalanıyor...",
|
14
|
+
"duplicateSuccess": "Konu Başarıyla Kopyalandı",
|
15
|
+
"favorite": "Favori",
|
16
|
+
"groupMode": {
|
17
|
+
"ascMessages": "Mesaj Sayısına Göre Artan Sıra",
|
18
|
+
"byTime": "Zamana Göre Grupla",
|
19
|
+
"descMessages": "Mesaj Sayısına Göre Azalan Sıra",
|
20
|
+
"flat": "Gruplandırma Yok"
|
21
|
+
},
|
22
|
+
"groupTitle": {
|
23
|
+
"byTime": {
|
24
|
+
"month": "Bu Ay",
|
25
|
+
"today": "Bugün",
|
26
|
+
"week": "Bu Hafta",
|
27
|
+
"yesterday": "Dün"
|
28
|
+
}
|
29
|
+
},
|
30
|
+
"guide": {
|
31
|
+
"desc": "Mevcut sohbeti tarihsel konu olarak kaydetmek ve yeni bir sohbet başlatmak için sol taraftaki gönder butonuna tıklayın.",
|
32
|
+
"title": "Konu Listesi"
|
33
|
+
},
|
34
|
+
"searchPlaceholder": "Konuları Ara...",
|
35
|
+
"temp": "Geçici",
|
36
|
+
"title": "Konu"
|
37
|
+
}
|
package/locales/vi-VN/chat.json
CHANGED
@@ -115,7 +115,6 @@
|
|
115
115
|
"loading": "Đang nhận dạng...",
|
116
116
|
"prettifying": "Đang tinh chỉnh..."
|
117
117
|
},
|
118
|
-
"temp": "Tạm thời",
|
119
118
|
"tokenDetails": {
|
120
119
|
"chats": "Tin nhắn trò chuyện",
|
121
120
|
"rest": "Còn lại",
|
@@ -131,29 +130,10 @@
|
|
131
130
|
"used": "Đã sử dụng"
|
132
131
|
},
|
133
132
|
"topic": {
|
134
|
-
"actions": {
|
135
|
-
"autoRename": "Đổi tên tự động",
|
136
|
-
"duplicate": "Tạo bản sao",
|
137
|
-
"export": "Xuất chủ đề"
|
138
|
-
},
|
139
133
|
"checkOpenNewTopic": "Có muốn mở chủ đề mới không?",
|
140
134
|
"checkSaveCurrentMessages": "Bạn có muốn lưu cuộc trò chuyện hiện tại thành chủ đề không?",
|
141
|
-
"confirmRemoveAll": "Bạn sắp xóa tất cả chủ đề. Hành động này không thể hoàn tác, vui lòng xác nhận.",
|
142
|
-
"confirmRemoveTopic": "Bạn sắp xóa chủ đề này. Hành động này không thể hoàn tác, vui lòng xác nhận.",
|
143
|
-
"confirmRemoveUnstarred": "Bạn sắp xóa các chủ đề chưa được đánh dấu. Hành động này không thể hoàn tác, vui lòng xác nhận.",
|
144
|
-
"defaultTitle": "Chủ đề mặc định",
|
145
|
-
"duplicateLoading": "Đang sao chép chủ đề...",
|
146
|
-
"duplicateSuccess": "Chủ đề đã được sao chép thành công",
|
147
|
-
"guide": {
|
148
|
-
"desc": "Nhấn vào nút bên trái để lưu cuộc trò chuyện hiện tại như một chủ đề lịch sử và bắt đầu một cuộc trò chuyện mới",
|
149
|
-
"title": "Danh sách chủ đề"
|
150
|
-
},
|
151
135
|
"openNewTopic": "Mở chủ đề mới",
|
152
|
-
"
|
153
|
-
"removeUnstarred": "Xóa chủ đề chưa được đánh dấu",
|
154
|
-
"saveCurrentMessages": "Lưu cuộc trò chuyện hiện tại thành chủ đề",
|
155
|
-
"searchPlaceholder": "Tìm kiếm chủ đề...",
|
156
|
-
"title": "Danh sách chủ đề"
|
136
|
+
"saveCurrentMessages": "Lưu cuộc trò chuyện hiện tại thành chủ đề"
|
157
137
|
},
|
158
138
|
"translate": {
|
159
139
|
"action": "Dịch",
|
package/locales/vi-VN/error.json
CHANGED
@@ -12,7 +12,10 @@
|
|
12
12
|
"retry": "Thử lại",
|
13
13
|
"title": "Trang gặp một chút vấn đề.."
|
14
14
|
},
|
15
|
-
"fetchError":
|
15
|
+
"fetchError": {
|
16
|
+
"detail": "Chi tiết lỗi",
|
17
|
+
"title": "Yêu cầu thất bại"
|
18
|
+
},
|
16
19
|
"loginRequired": {
|
17
20
|
"desc": "Sẽ tự động chuyển hướng đến trang đăng nhập",
|
18
21
|
"title": "Vui lòng đăng nhập để sử dụng tính năng này"
|
@@ -0,0 +1,37 @@
|
|
1
|
+
{
|
2
|
+
"actions": {
|
3
|
+
"autoRename": "Đặt tên tự động",
|
4
|
+
"confirmRemoveAll": "Sắp xóa tất cả các chủ đề, sau khi xóa sẽ không thể khôi phục, xin hãy cẩn thận.",
|
5
|
+
"confirmRemoveTopic": "Sắp xóa chủ đề này, sau khi xóa sẽ không thể khôi phục, xin hãy cẩn thận.",
|
6
|
+
"confirmRemoveUnstarred": "Sắp xóa các chủ đề chưa được đánh dấu, sau khi xóa sẽ không thể khôi phục, xin hãy cẩn thận.",
|
7
|
+
"duplicate": "Tạo bản sao",
|
8
|
+
"export": "Xuất chủ đề",
|
9
|
+
"removeAll": "Xóa tất cả các chủ đề",
|
10
|
+
"removeUnstarred": "Xóa các chủ đề chưa được đánh dấu"
|
11
|
+
},
|
12
|
+
"defaultTitle": "Chủ đề mặc định",
|
13
|
+
"duplicateLoading": "Đang sao chép chủ đề...",
|
14
|
+
"duplicateSuccess": "Sao chép chủ đề thành công",
|
15
|
+
"favorite": "Yêu thích",
|
16
|
+
"groupMode": {
|
17
|
+
"ascMessages": "Theo thứ tự tổng số tin nhắn",
|
18
|
+
"byTime": "Theo thời gian",
|
19
|
+
"descMessages": "Theo thứ tự tổng số tin nhắn giảm dần",
|
20
|
+
"flat": "Không phân nhóm"
|
21
|
+
},
|
22
|
+
"groupTitle": {
|
23
|
+
"byTime": {
|
24
|
+
"month": "Tháng này",
|
25
|
+
"today": "Hôm nay",
|
26
|
+
"week": "Tuần này",
|
27
|
+
"yesterday": "Hôm qua"
|
28
|
+
}
|
29
|
+
},
|
30
|
+
"guide": {
|
31
|
+
"desc": "Nhấn nút bên trái để lưu cuộc trò chuyện hiện tại thành chủ đề lịch sử và bắt đầu một cuộc trò chuyện mới.",
|
32
|
+
"title": "Danh sách chủ đề"
|
33
|
+
},
|
34
|
+
"searchPlaceholder": "Tìm kiếm chủ đề...",
|
35
|
+
"temp": "Tạm thời",
|
36
|
+
"title": "Chủ đề"
|
37
|
+
}
|
package/locales/zh-CN/chat.json
CHANGED
@@ -115,7 +115,6 @@
|
|
115
115
|
"loading": "识别中...",
|
116
116
|
"prettifying": "润色中..."
|
117
117
|
},
|
118
|
-
"temp": "临时",
|
119
118
|
"tokenDetails": {
|
120
119
|
"chats": "会话消息",
|
121
120
|
"rest": "剩余可用",
|
@@ -131,29 +130,10 @@
|
|
131
130
|
"used": "使用"
|
132
131
|
},
|
133
132
|
"topic": {
|
134
|
-
"actions": {
|
135
|
-
"autoRename": "智能重命名",
|
136
|
-
"duplicate": "创建副本",
|
137
|
-
"export": "导出话题"
|
138
|
-
},
|
139
133
|
"checkOpenNewTopic": "是否开启新话题?",
|
140
134
|
"checkSaveCurrentMessages": "是否保存当前会话为话题?",
|
141
|
-
"confirmRemoveAll": "即将删除全部话题,删除后将不可恢复,请谨慎操作。",
|
142
|
-
"confirmRemoveTopic": "即将删除该话题,删除后将不可恢复,请谨慎操作。",
|
143
|
-
"confirmRemoveUnstarred": "即将删除未收藏话题,删除后将不可恢复,请谨慎操作。",
|
144
|
-
"defaultTitle": "默认话题",
|
145
|
-
"duplicateLoading": "话题复制中...",
|
146
|
-
"duplicateSuccess": "话题复制成功",
|
147
|
-
"guide": {
|
148
|
-
"desc": "点击发送左侧按钮可将当前会话保存为历史话题,并开启新一轮会话",
|
149
|
-
"title": "话题列表"
|
150
|
-
},
|
151
135
|
"openNewTopic": "开启新话题",
|
152
|
-
"
|
153
|
-
"removeUnstarred": "删除未收藏话题",
|
154
|
-
"saveCurrentMessages": "将当前会话保存为话题",
|
155
|
-
"searchPlaceholder": "搜索话题...",
|
156
|
-
"title": "话题"
|
136
|
+
"saveCurrentMessages": "将当前会话保存为话题"
|
157
137
|
},
|
158
138
|
"translate": {
|
159
139
|
"action": "翻译",
|
@@ -0,0 +1,37 @@
|
|
1
|
+
{
|
2
|
+
"actions": {
|
3
|
+
"autoRename": "智能重命名",
|
4
|
+
"confirmRemoveAll": "即将删除全部话题,删除后将不可恢复,请谨慎操作。",
|
5
|
+
"confirmRemoveTopic": "即将删除该话题,删除后将不可恢复,请谨慎操作。",
|
6
|
+
"confirmRemoveUnstarred": "即将删除未收藏话题,删除后将不可恢复,请谨慎操作。",
|
7
|
+
"duplicate": "创建副本",
|
8
|
+
"export": "导出话题",
|
9
|
+
"removeAll": "删除全部话题",
|
10
|
+
"removeUnstarred": "删除未收藏话题"
|
11
|
+
},
|
12
|
+
"defaultTitle": "默认话题",
|
13
|
+
"duplicateLoading": "话题复制中...",
|
14
|
+
"duplicateSuccess": "话题复制成功",
|
15
|
+
"favorite": "收藏",
|
16
|
+
"groupMode": {
|
17
|
+
"ascMessages": "按消息总数顺序",
|
18
|
+
"byTime": "按时间分组",
|
19
|
+
"descMessages": "按消息总数倒序",
|
20
|
+
"flat": "不分组"
|
21
|
+
},
|
22
|
+
"groupTitle": {
|
23
|
+
"byTime": {
|
24
|
+
"month": "本月",
|
25
|
+
"today": "今天",
|
26
|
+
"week": "本周",
|
27
|
+
"yesterday": "昨天"
|
28
|
+
}
|
29
|
+
},
|
30
|
+
"guide": {
|
31
|
+
"desc": "点击发送左侧按钮可将当前会话保存为历史话题,并开启新一轮会话",
|
32
|
+
"title": "话题列表"
|
33
|
+
},
|
34
|
+
"searchPlaceholder": "搜索话题...",
|
35
|
+
"temp": "临时",
|
36
|
+
"title": "话题"
|
37
|
+
}
|
package/locales/zh-TW/chat.json
CHANGED
@@ -115,7 +115,6 @@
|
|
115
115
|
"loading": "識別中...",
|
116
116
|
"prettifying": "潤色中..."
|
117
117
|
},
|
118
|
-
"temp": "臨時",
|
119
118
|
"tokenDetails": {
|
120
119
|
"chats": "聊天訊息",
|
121
120
|
"rest": "剩餘可用",
|
@@ -131,29 +130,10 @@
|
|
131
130
|
"used": "使用"
|
132
131
|
},
|
133
132
|
"topic": {
|
134
|
-
"actions": {
|
135
|
-
"autoRename": "智能重新命名",
|
136
|
-
"duplicate": "建立副本",
|
137
|
-
"export": "匯出主題"
|
138
|
-
},
|
139
133
|
"checkOpenNewTopic": "是否開啟新主題?",
|
140
134
|
"checkSaveCurrentMessages": "是否將當前對話保存為話題?",
|
141
|
-
"confirmRemoveAll": "即將刪除全部話題,刪除後將不可恢復,請謹慎操作。",
|
142
|
-
"confirmRemoveTopic": "即將刪除該話題,刪除後將不可恢復,請謹慎操作。",
|
143
|
-
"confirmRemoveUnstarred": "即將刪除未收藏話題,刪除後將不可恢復,請謹慎操作。",
|
144
|
-
"defaultTitle": "默認話題",
|
145
|
-
"duplicateLoading": "話題複製中...",
|
146
|
-
"duplicateSuccess": "話題複製成功",
|
147
|
-
"guide": {
|
148
|
-
"desc": "點擊發送左側按鈕可將當前對話保存為歷史話題,並開啟新一輪對話",
|
149
|
-
"title": "話題列表"
|
150
|
-
},
|
151
135
|
"openNewTopic": "開啟新話題",
|
152
|
-
"
|
153
|
-
"removeUnstarred": "刪除未收藏話題",
|
154
|
-
"saveCurrentMessages": "將當前對話保存為話題",
|
155
|
-
"searchPlaceholder": "搜索話題...",
|
156
|
-
"title": "話題列表"
|
136
|
+
"saveCurrentMessages": "將當前對話保存為話題"
|
157
137
|
},
|
158
138
|
"translate": {
|
159
139
|
"action": "翻譯",
|
package/locales/zh-TW/error.json
CHANGED
@@ -0,0 +1,37 @@
|
|
1
|
+
{
|
2
|
+
"actions": {
|
3
|
+
"autoRename": "智能重命名",
|
4
|
+
"confirmRemoveAll": "即將刪除全部話題,刪除後將不可恢復,請謹慎操作。",
|
5
|
+
"confirmRemoveTopic": "即將刪除該話題,刪除後將不可恢復,請謹慎操作。",
|
6
|
+
"confirmRemoveUnstarred": "即將刪除未收藏話題,刪除後將不可恢復,請謹慎操作。",
|
7
|
+
"duplicate": "創建副本",
|
8
|
+
"export": "匯出話題",
|
9
|
+
"removeAll": "刪除全部話題",
|
10
|
+
"removeUnstarred": "刪除未收藏話題"
|
11
|
+
},
|
12
|
+
"defaultTitle": "預設話題",
|
13
|
+
"duplicateLoading": "話題複製中...",
|
14
|
+
"duplicateSuccess": "話題複製成功",
|
15
|
+
"favorite": "收藏",
|
16
|
+
"groupMode": {
|
17
|
+
"ascMessages": "按消息總數順序",
|
18
|
+
"byTime": "按時間分組",
|
19
|
+
"descMessages": "按消息總數倒序",
|
20
|
+
"flat": "不分組"
|
21
|
+
},
|
22
|
+
"groupTitle": {
|
23
|
+
"byTime": {
|
24
|
+
"month": "本月",
|
25
|
+
"today": "今天",
|
26
|
+
"week": "本週",
|
27
|
+
"yesterday": "昨天"
|
28
|
+
}
|
29
|
+
},
|
30
|
+
"guide": {
|
31
|
+
"desc": "點擊發送左側按鈕可將當前會話保存為歷史話題,並開啟新一輪會話",
|
32
|
+
"title": "話題列表"
|
33
|
+
},
|
34
|
+
"searchPlaceholder": "搜尋話題...",
|
35
|
+
"temp": "臨時",
|
36
|
+
"title": "話題"
|
37
|
+
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@lobehub/chat",
|
3
|
-
"version": "1.
|
3
|
+
"version": "1.27.0",
|
4
4
|
"description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
|
5
5
|
"keywords": [
|
6
6
|
"framework",
|
@@ -10,10 +10,11 @@ import { featureFlagsSelectors, useServerConfigStore } from '@/store/serverConfi
|
|
10
10
|
import { useSessionStore } from '@/store/session';
|
11
11
|
|
12
12
|
export interface TopActionProps {
|
13
|
+
isPinned?: boolean | null;
|
13
14
|
tab?: SidebarTabKey;
|
14
15
|
}
|
15
16
|
|
16
|
-
const TopActions = memo<TopActionProps>(({ tab }) => {
|
17
|
+
const TopActions = memo<TopActionProps>(({ tab, isPinned }) => {
|
17
18
|
const { t } = useTranslation('common');
|
18
19
|
const switchBackToChat = useGlobalStore((s) => s.switchBackToChat);
|
19
20
|
const { showMarket, enableKnowledgeBase } = useServerConfigStore(featureFlagsSelectors);
|
@@ -29,7 +30,7 @@ const TopActions = memo<TopActionProps>(({ tab }) => {
|
|
29
30
|
}}
|
30
31
|
>
|
31
32
|
<ActionIcon
|
32
|
-
active={tab === SidebarTabKey.Chat}
|
33
|
+
active={tab === SidebarTabKey.Chat && !isPinned}
|
33
34
|
icon={MessageSquare}
|
34
35
|
placement={'right'}
|
35
36
|
size="large"
|
@@ -1,6 +1,7 @@
|
|
1
1
|
'use client';
|
2
2
|
|
3
3
|
import { SideNav } from '@lobehub/ui';
|
4
|
+
import { parseAsBoolean, useQueryState } from 'nuqs';
|
4
5
|
import { memo } from 'react';
|
5
6
|
|
6
7
|
import { useActiveTabKey } from '@/hooks/useActiveTabKey';
|
@@ -17,6 +18,8 @@ const Nav = memo(() => {
|
|
17
18
|
const sidebarKey = useActiveTabKey();
|
18
19
|
const inZenMode = useGlobalStore(systemStatusSelectors.inZenMode);
|
19
20
|
const { showPinList } = useServerConfigStore(featureFlagsSelectors);
|
21
|
+
const [isPinned] = useQueryState('pinned', parseAsBoolean);
|
22
|
+
|
20
23
|
return (
|
21
24
|
!inZenMode && (
|
22
25
|
<SideNav
|
@@ -25,7 +28,7 @@ const Nav = memo(() => {
|
|
25
28
|
style={{ height: '100%', zIndex: 100 }}
|
26
29
|
topActions={
|
27
30
|
<>
|
28
|
-
<TopActions tab={sidebarKey} />
|
31
|
+
<TopActions isPinned={isPinned} tab={sidebarKey} />
|
29
32
|
{showPinList && <PinList />}
|
30
33
|
</>
|
31
34
|
}
|
@@ -2,7 +2,8 @@
|
|
2
2
|
|
3
3
|
import { ActionIcon, Icon } from '@lobehub/ui';
|
4
4
|
import { App, Dropdown, MenuProps } from 'antd';
|
5
|
-
import {
|
5
|
+
import type { ItemType } from 'antd/es/menu/interface';
|
6
|
+
import { LucideCheck, MoreHorizontal, Search, Trash } from 'lucide-react';
|
6
7
|
import { memo, useMemo, useState } from 'react';
|
7
8
|
import { useTranslation } from 'react-i18next';
|
8
9
|
import { Flexbox } from 'react-layout-kit';
|
@@ -10,32 +11,49 @@ import { Flexbox } from 'react-layout-kit';
|
|
10
11
|
import SidebarHeader from '@/components/SidebarHeader';
|
11
12
|
import { useChatStore } from '@/store/chat';
|
12
13
|
import { topicSelectors } from '@/store/chat/selectors';
|
14
|
+
import { useUserStore } from '@/store/user';
|
15
|
+
import { preferenceSelectors } from '@/store/user/selectors';
|
16
|
+
import { TopicDisplayMode } from '@/types/topic';
|
13
17
|
|
14
18
|
import TopicSearchBar from './TopicSearchBar';
|
15
19
|
|
16
20
|
const Header = memo(() => {
|
17
|
-
const { t } = useTranslation('
|
21
|
+
const { t } = useTranslation('topic');
|
18
22
|
const [topicLength, removeUnstarredTopic, removeAllTopic] = useChatStore((s) => [
|
19
23
|
topicSelectors.currentTopicLength(s),
|
20
24
|
s.removeUnstarredTopic,
|
21
25
|
s.removeSessionTopics,
|
22
26
|
]);
|
23
|
-
|
27
|
+
const [topicDisplayMode, updatePreference] = useUserStore((s) => [
|
28
|
+
preferenceSelectors.topicDisplayMode(s),
|
29
|
+
s.updatePreference,
|
30
|
+
]);
|
24
31
|
const [showSearch, setShowSearch] = useState(false);
|
25
32
|
const { modal } = App.useApp();
|
26
33
|
|
27
34
|
const items = useMemo<MenuProps['items']>(
|
28
35
|
() => [
|
36
|
+
...(Object.values(TopicDisplayMode).map((mode) => ({
|
37
|
+
icon: topicDisplayMode === mode ? <Icon icon={LucideCheck} /> : <div />,
|
38
|
+
key: mode,
|
39
|
+
label: t(`groupMode.${mode}`),
|
40
|
+
onClick: () => {
|
41
|
+
updatePreference({ topicDisplayMode: mode });
|
42
|
+
},
|
43
|
+
})) as ItemType[]),
|
44
|
+
{
|
45
|
+
type: 'divider',
|
46
|
+
},
|
29
47
|
{
|
30
48
|
icon: <Icon icon={Trash} />,
|
31
49
|
key: 'deleteUnstarred',
|
32
|
-
label: t('
|
50
|
+
label: t('actions.removeUnstarred'),
|
33
51
|
onClick: () => {
|
34
52
|
modal.confirm({
|
35
53
|
centered: true,
|
36
54
|
okButtonProps: { danger: true },
|
37
55
|
onOk: removeUnstarredTopic,
|
38
|
-
title: t('
|
56
|
+
title: t('actions.confirmRemoveUnstarred'),
|
39
57
|
});
|
40
58
|
},
|
41
59
|
},
|
@@ -43,18 +61,18 @@ const Header = memo(() => {
|
|
43
61
|
danger: true,
|
44
62
|
icon: <Icon icon={Trash} />,
|
45
63
|
key: 'deleteAll',
|
46
|
-
label: t('
|
64
|
+
label: t('actions.removeAll'),
|
47
65
|
onClick: () => {
|
48
66
|
modal.confirm({
|
49
67
|
centered: true,
|
50
68
|
okButtonProps: { danger: true },
|
51
69
|
onOk: removeAllTopic,
|
52
|
-
title: t('
|
70
|
+
title: t('actions.confirmRemoveAll'),
|
53
71
|
});
|
54
72
|
},
|
55
73
|
},
|
56
74
|
],
|
57
|
-
[],
|
75
|
+
[topicDisplayMode],
|
58
76
|
);
|
59
77
|
|
60
78
|
return showSearch ? (
|
@@ -80,7 +98,7 @@ const Header = memo(() => {
|
|
80
98
|
</Dropdown>
|
81
99
|
</>
|
82
100
|
}
|
83
|
-
title={`${t('
|
101
|
+
title={`${t('title')} ${topicLength > 1 ? topicLength + 1 : ''}`}
|
84
102
|
/>
|
85
103
|
);
|
86
104
|
});
|
package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/ByTimeMode/GroupItem.tsx
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
import { createStyles } from 'antd-style';
|
2
|
+
import dayjs from 'dayjs';
|
3
|
+
import React, { memo } from 'react';
|
4
|
+
import { useTranslation } from 'react-i18next';
|
5
|
+
import { Flexbox } from 'react-layout-kit';
|
6
|
+
|
7
|
+
import { GroupedTopic } from '@/types/topic';
|
8
|
+
|
9
|
+
const preformat = (id: string) =>
|
10
|
+
id.startsWith('20') ? (id.includes('-') ? dayjs(id).format('MMMM') : id) : undefined;
|
11
|
+
|
12
|
+
const useStyles = createStyles(({ css, token, stylish }) => ({
|
13
|
+
container: css`
|
14
|
+
color: ${token.colorTextQuaternary};
|
15
|
+
${stylish.blur}
|
16
|
+
`,
|
17
|
+
}));
|
18
|
+
|
19
|
+
const TopicGroupItem = memo<Omit<GroupedTopic, 'children'>>(({ id, title }) => {
|
20
|
+
const { t } = useTranslation('topic');
|
21
|
+
const { styles } = useStyles();
|
22
|
+
const timeTitle = preformat(id) ?? t(`groupTitle.byTime.${id}` as any);
|
23
|
+
|
24
|
+
return (
|
25
|
+
<Flexbox className={styles.container} paddingBlock={8} paddingInline={12}>
|
26
|
+
{title ? title : timeTitle}
|
27
|
+
</Flexbox>
|
28
|
+
);
|
29
|
+
});
|
30
|
+
export default TopicGroupItem;
|
@@ -0,0 +1,72 @@
|
|
1
|
+
'use client';
|
2
|
+
|
3
|
+
import isEqual from 'fast-deep-equal';
|
4
|
+
import React, { memo, useCallback, useMemo, useRef } from 'react';
|
5
|
+
import { useTranslation } from 'react-i18next';
|
6
|
+
import { GroupedVirtuoso, VirtuosoHandle } from 'react-virtuoso';
|
7
|
+
|
8
|
+
import { useChatStore } from '@/store/chat';
|
9
|
+
import { topicSelectors } from '@/store/chat/selectors';
|
10
|
+
import { ChatTopic } from '@/types/topic';
|
11
|
+
|
12
|
+
import TopicItem from '../TopicItem';
|
13
|
+
import TopicGroupItem from './GroupItem';
|
14
|
+
|
15
|
+
const ByTimeMode = memo(() => {
|
16
|
+
const { t } = useTranslation('topic');
|
17
|
+
const virtuosoRef = useRef<VirtuosoHandle>(null);
|
18
|
+
const [activeTopicId] = useChatStore((s) => [s.activeTopicId]);
|
19
|
+
const groupTopics = useChatStore(topicSelectors.groupedTopicsSelector, isEqual);
|
20
|
+
|
21
|
+
const { groups, groupCounts, topics } = useMemo(() => {
|
22
|
+
return {
|
23
|
+
groupCounts: [1, ...groupTopics.map((group) => group.children.length)],
|
24
|
+
groups: [
|
25
|
+
{ id: 'default' },
|
26
|
+
...groupTopics.map((group) => ({ id: group.id, title: group.title })),
|
27
|
+
],
|
28
|
+
topics: [
|
29
|
+
{ favorite: false, id: 'default', title: t('defaultTitle') } as ChatTopic,
|
30
|
+
...groupTopics.flatMap((group) => group.children),
|
31
|
+
],
|
32
|
+
};
|
33
|
+
}, [groupTopics]);
|
34
|
+
|
35
|
+
const itemContent = useCallback(
|
36
|
+
(index: number) => {
|
37
|
+
const { id, favorite, title } = topics[index];
|
38
|
+
|
39
|
+
return index === 0 ? (
|
40
|
+
<TopicItem active={!activeTopicId} fav={favorite} title={title} />
|
41
|
+
) : (
|
42
|
+
<TopicItem active={activeTopicId === id} fav={favorite} id={id} key={id} title={title} />
|
43
|
+
);
|
44
|
+
},
|
45
|
+
[activeTopicId, topics],
|
46
|
+
);
|
47
|
+
|
48
|
+
const groupContent = useCallback(
|
49
|
+
(index: number) => {
|
50
|
+
if (index === 0) return undefined;
|
51
|
+
|
52
|
+
const topicGroup = groups[index];
|
53
|
+
return <TopicGroupItem {...topicGroup} />;
|
54
|
+
},
|
55
|
+
[groups],
|
56
|
+
);
|
57
|
+
|
58
|
+
// const activeIndex = topics.findIndex((topic) => topic.id === activeTopicId);
|
59
|
+
|
60
|
+
return (
|
61
|
+
<GroupedVirtuoso
|
62
|
+
groupContent={groupContent}
|
63
|
+
groupCounts={groupCounts}
|
64
|
+
itemContent={itemContent}
|
65
|
+
ref={virtuosoRef}
|
66
|
+
/>
|
67
|
+
);
|
68
|
+
});
|
69
|
+
|
70
|
+
ByTimeMode.displayName = 'ByTimeMode';
|
71
|
+
|
72
|
+
export default ByTimeMode;
|
@@ -9,7 +9,7 @@ import { Flexbox } from 'react-layout-kit';
|
|
9
9
|
const { Paragraph } = Typography;
|
10
10
|
|
11
11
|
const DefaultContent = memo(() => {
|
12
|
-
const { t } = useTranslation('
|
12
|
+
const { t } = useTranslation('topic');
|
13
13
|
|
14
14
|
const theme = useTheme();
|
15
15
|
|
@@ -19,7 +19,7 @@ const DefaultContent = memo(() => {
|
|
19
19
|
<Icon color={theme.colorTextDescription} icon={MessageSquareDashed} />
|
20
20
|
</Flexbox>
|
21
21
|
<Paragraph ellipsis={{ rows: 1 }} style={{ margin: 0 }}>
|
22
|
-
{t('
|
22
|
+
{t('defaultTitle')}
|
23
23
|
</Paragraph>
|
24
24
|
<Tag>{t('temp')}</Tag>
|
25
25
|
</Flexbox>
|