@lobehub/chat 1.27.3 → 1.28.1
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 +50 -0
- package/locales/ar/chat.json +7 -1
- package/locales/ar/models.json +3 -0
- package/locales/bg-BG/chat.json +7 -1
- package/locales/bg-BG/models.json +3 -0
- package/locales/de-DE/chat.json +7 -1
- package/locales/de-DE/models.json +3 -0
- package/locales/en-US/chat.json +7 -1
- package/locales/en-US/models.json +3 -0
- package/locales/es-ES/chat.json +7 -1
- package/locales/es-ES/models.json +3 -0
- package/locales/fa-IR/chat.json +7 -1
- package/locales/fa-IR/models.json +3 -0
- package/locales/fr-FR/chat.json +7 -1
- package/locales/fr-FR/models.json +3 -0
- package/locales/it-IT/chat.json +7 -1
- package/locales/it-IT/models.json +3 -0
- package/locales/ja-JP/chat.json +7 -1
- package/locales/ja-JP/models.json +3 -0
- package/locales/ko-KR/chat.json +7 -1
- package/locales/ko-KR/models.json +3 -0
- package/locales/nl-NL/chat.json +7 -1
- package/locales/nl-NL/models.json +3 -0
- package/locales/pl-PL/chat.json +7 -1
- package/locales/pl-PL/models.json +3 -0
- package/locales/pt-BR/chat.json +7 -1
- package/locales/pt-BR/models.json +3 -0
- package/locales/ru-RU/chat.json +7 -1
- package/locales/ru-RU/models.json +3 -0
- package/locales/tr-TR/chat.json +7 -1
- package/locales/tr-TR/models.json +3 -0
- package/locales/vi-VN/chat.json +7 -1
- package/locales/vi-VN/models.json +3 -0
- package/locales/zh-CN/chat.json +7 -1
- package/locales/zh-CN/models.json +3 -0
- package/locales/zh-TW/chat.json +7 -1
- package/locales/zh-TW/models.json +3 -0
- package/package.json +1 -1
- package/src/app/(main)/chat/(workspace)/features/ShareButton/index.tsx +2 -1
- package/src/database/server/migrations/0010_add_accessed_at_and_clean_tables.sql +26 -0
- package/src/database/server/migrations/meta/0010_snapshot.json +3184 -0
- package/src/database/server/migrations/meta/_journal.json +7 -0
- package/src/database/server/models/__tests__/session.test.ts +0 -2
- package/src/database/server/models/__tests__/topic.test.ts +2 -0
- package/src/database/server/schemas/lobechat/_helpers.ts +8 -0
- package/src/database/server/schemas/lobechat/agent.ts +6 -7
- package/src/database/server/schemas/lobechat/asyncTask.ts +2 -3
- package/src/database/server/schemas/lobechat/file.ts +5 -5
- package/src/database/server/schemas/lobechat/index.ts +0 -1
- package/src/database/server/schemas/lobechat/message.ts +2 -3
- package/src/database/server/schemas/lobechat/rag.ts +4 -6
- package/src/database/server/schemas/lobechat/ragEvals.ts +5 -7
- package/src/database/server/schemas/lobechat/relations.ts +0 -33
- package/src/database/server/schemas/lobechat/session.ts +3 -5
- package/src/database/server/schemas/lobechat/topic.ts +7 -8
- package/src/database/server/schemas/lobechat/user.ts +3 -5
- package/src/{app/(main)/chat/(workspace)/features/ShareButton → features/ShareModal/ShareImage}/Preview.tsx +5 -3
- package/src/features/ShareModal/ShareImage/index.tsx +103 -0
- package/src/{app/(main)/chat/(workspace)/features/ShareButton → features/ShareModal/ShareImage}/style.ts +1 -23
- package/src/features/ShareModal/ShareJSON/Preview.tsx +18 -0
- package/src/features/ShareModal/ShareJSON/generateMessages.test.ts +135 -0
- package/src/features/ShareModal/ShareJSON/generateMessages.ts +35 -0
- package/src/features/ShareModal/ShareJSON/index.tsx +99 -0
- package/src/features/ShareModal/ShareJSON/type.ts +4 -0
- package/src/features/ShareModal/ShareText/Preview.tsx +16 -0
- package/src/features/ShareModal/ShareText/index.tsx +119 -0
- package/src/features/ShareModal/ShareText/template.test.ts +178 -0
- package/src/features/ShareModal/ShareText/template.ts +79 -0
- package/src/features/ShareModal/ShareText/type.ts +6 -0
- package/src/features/ShareModal/index.tsx +69 -0
- package/src/features/ShareModal/style.ts +30 -0
- package/src/locales/default/chat.ts +7 -1
- package/src/services/__tests__/share.test.ts +35 -105
- package/src/services/share.ts +0 -30
- package/src/store/chat/slices/share/action.test.ts +7 -198
- package/src/store/chat/slices/share/action.ts +9 -113
- package/src/utils/client/exportFile.ts +20 -0
- package/src/app/(main)/chat/(workspace)/features/ShareButton/ShareModal.tsx +0 -164
- package/src/database/server/schemas/lobechat/discover.ts +0 -84
- /package/src/{app/(main)/chat/(workspace)/features/ShareButton → features/ShareModal/ShareImage}/type.ts +0 -0
- /package/src/{app/(main)/chat/(workspace)/features/ShareButton → features/ShareModal/ShareImage}/useScreenshot.ts +0 -0
@@ -70,6 +70,13 @@
|
|
70
70
|
"when": 1729699958471,
|
71
71
|
"tag": "0009_remove_unused_user_tables",
|
72
72
|
"breakpoints": true
|
73
|
+
},
|
74
|
+
{
|
75
|
+
"idx": 10,
|
76
|
+
"version": "7",
|
77
|
+
"when": 1730900133049,
|
78
|
+
"tag": "0010_add_accessed_at_and_clean_tables",
|
79
|
+
"breakpoints": true
|
73
80
|
}
|
74
81
|
],
|
75
82
|
"version": "6"
|
@@ -9,7 +9,6 @@ import {
|
|
9
9
|
agents,
|
10
10
|
agentsToSessions,
|
11
11
|
messages,
|
12
|
-
plugins,
|
13
12
|
sessionGroups,
|
14
13
|
sessions,
|
15
14
|
topics,
|
@@ -30,7 +29,6 @@ const userId = 'session-user';
|
|
30
29
|
const sessionModel = new SessionModel(userId);
|
31
30
|
|
32
31
|
beforeEach(async () => {
|
33
|
-
await serverDB.delete(plugins);
|
34
32
|
await serverDB.delete(users);
|
35
33
|
// 并创建初始用户
|
36
34
|
await serverDB.insert(users).values({ id: userId });
|
@@ -430,6 +430,7 @@ describe('TopicModel', () => {
|
|
430
430
|
clientId: null,
|
431
431
|
createdAt: expect.any(Date),
|
432
432
|
updatedAt: expect.any(Date),
|
433
|
+
accessedAt: expect.any(Date),
|
433
434
|
});
|
434
435
|
|
435
436
|
// 断言 topic 已在数据库中创建
|
@@ -476,6 +477,7 @@ describe('TopicModel', () => {
|
|
476
477
|
userId,
|
477
478
|
createdAt: expect.any(Date),
|
478
479
|
updatedAt: expect.any(Date),
|
480
|
+
accessedAt: expect.any(Date),
|
479
481
|
});
|
480
482
|
|
481
483
|
// 断言 topic 已在数据库中创建
|
@@ -4,3 +4,11 @@ export const timestamptz = (name: string) => timestamp(name, { withTimezone: tru
|
|
4
4
|
|
5
5
|
export const createdAt = () => timestamptz('created_at').notNull().defaultNow();
|
6
6
|
export const updatedAt = () => timestamptz('updated_at').notNull().defaultNow();
|
7
|
+
export const accessedAt = () => timestamptz('accessed_at').notNull().defaultNow();
|
8
|
+
|
9
|
+
// columns.helpers.ts
|
10
|
+
export const timestamps = {
|
11
|
+
accessedAt: accessedAt(),
|
12
|
+
createdAt: createdAt(),
|
13
|
+
updatedAt: updatedAt(),
|
14
|
+
};
|
@@ -5,7 +5,7 @@ import { createInsertSchema } from 'drizzle-zod';
|
|
5
5
|
import { LobeAgentChatConfig, LobeAgentTTSConfig } from '@/types/agent';
|
6
6
|
|
7
7
|
import { idGenerator, randomSlug } from '../../utils/idGenerator';
|
8
|
-
import {
|
8
|
+
import { timestamps } from './_helpers';
|
9
9
|
import { files, knowledgeBases } from './file';
|
10
10
|
import { users } from './user';
|
11
11
|
|
@@ -41,8 +41,7 @@ export const agents = pgTable('agents', {
|
|
41
41
|
systemRole: text('system_role'),
|
42
42
|
tts: jsonb('tts').$type<LobeAgentTTSConfig>(),
|
43
43
|
|
44
|
-
|
45
|
-
updatedAt: updatedAt(),
|
44
|
+
...timestamps,
|
46
45
|
});
|
47
46
|
|
48
47
|
export const insertAgentSchema = createInsertSchema(agents);
|
@@ -63,8 +62,8 @@ export const agentsKnowledgeBases = pgTable(
|
|
63
62
|
.references(() => users.id, { onDelete: 'cascade' })
|
64
63
|
.notNull(),
|
65
64
|
enabled: boolean('enabled').default(true),
|
66
|
-
|
67
|
-
|
65
|
+
|
66
|
+
...timestamps,
|
68
67
|
},
|
69
68
|
(t) => ({
|
70
69
|
pk: primaryKey({ columns: [t.agentId, t.knowledgeBaseId] }),
|
@@ -84,8 +83,8 @@ export const agentsFiles = pgTable(
|
|
84
83
|
userId: text('user_id')
|
85
84
|
.references(() => users.id, { onDelete: 'cascade' })
|
86
85
|
.notNull(),
|
87
|
-
|
88
|
-
|
86
|
+
|
87
|
+
...timestamps,
|
89
88
|
},
|
90
89
|
(t) => ({
|
91
90
|
pk: primaryKey({ columns: [t.fileId, t.agentId, t.userId] }),
|
@@ -1,7 +1,7 @@
|
|
1
1
|
/* eslint-disable sort-keys-fix/sort-keys-fix */
|
2
2
|
import { integer, jsonb, pgTable, text, uuid } from 'drizzle-orm/pg-core';
|
3
3
|
|
4
|
-
import {
|
4
|
+
import { timestamps } from './_helpers';
|
5
5
|
import { users } from './user';
|
6
6
|
|
7
7
|
export const asyncTasks = pgTable('async_tasks', {
|
@@ -16,8 +16,7 @@ export const asyncTasks = pgTable('async_tasks', {
|
|
16
16
|
.notNull(),
|
17
17
|
duration: integer('duration'),
|
18
18
|
|
19
|
-
|
20
|
-
updatedAt: updatedAt(),
|
19
|
+
...timestamps,
|
21
20
|
});
|
22
21
|
|
23
22
|
export type NewAsyncTaskItem = typeof asyncTasks.$inferInsert;
|
@@ -12,7 +12,7 @@ import {
|
|
12
12
|
import { createInsertSchema } from 'drizzle-zod';
|
13
13
|
|
14
14
|
import { idGenerator } from '../../utils/idGenerator';
|
15
|
-
import { createdAt,
|
15
|
+
import { accessedAt, createdAt, timestamps } from './_helpers';
|
16
16
|
import { asyncTasks } from './asyncTask';
|
17
17
|
import { chunks } from './rag';
|
18
18
|
import { users } from './user';
|
@@ -23,7 +23,9 @@ export const globalFiles = pgTable('global_files', {
|
|
23
23
|
size: integer('size').notNull(),
|
24
24
|
url: text('url').notNull(),
|
25
25
|
metadata: jsonb('metadata'),
|
26
|
+
|
26
27
|
createdAt: createdAt(),
|
28
|
+
accessedAt: accessedAt(),
|
27
29
|
});
|
28
30
|
|
29
31
|
export type NewGlobalFile = typeof globalFiles.$inferInsert;
|
@@ -51,8 +53,7 @@ export const files = pgTable('files', {
|
|
51
53
|
onDelete: 'set null',
|
52
54
|
}),
|
53
55
|
|
54
|
-
|
55
|
-
updatedAt: updatedAt(),
|
56
|
+
...timestamps,
|
56
57
|
});
|
57
58
|
|
58
59
|
export type NewFile = typeof files.$inferInsert;
|
@@ -91,8 +92,7 @@ export const knowledgeBases = pgTable('knowledge_bases', {
|
|
91
92
|
|
92
93
|
settings: jsonb('settings'),
|
93
94
|
|
94
|
-
|
95
|
-
updatedAt: updatedAt(),
|
95
|
+
...timestamps,
|
96
96
|
});
|
97
97
|
|
98
98
|
export const insertKnowledgeBasesSchema = createInsertSchema(knowledgeBases);
|
@@ -13,7 +13,7 @@ import {
|
|
13
13
|
import { createSelectSchema } from 'drizzle-zod';
|
14
14
|
|
15
15
|
import { idGenerator } from '../../utils/idGenerator';
|
16
|
-
import {
|
16
|
+
import { timestamps } from './_helpers';
|
17
17
|
import { agents } from './agent';
|
18
18
|
import { files } from './file';
|
19
19
|
import { chunks, embeddings } from './rag';
|
@@ -58,8 +58,7 @@ export const messages = pgTable(
|
|
58
58
|
// used for group chat
|
59
59
|
agentId: text('agent_id').references(() => agents.id, { onDelete: 'set null' }),
|
60
60
|
|
61
|
-
|
62
|
-
updatedAt: updatedAt(),
|
61
|
+
...timestamps,
|
63
62
|
},
|
64
63
|
(table) => ({
|
65
64
|
createdAtIdx: index('messages_created_at_idx').on(table.createdAt),
|
@@ -1,7 +1,7 @@
|
|
1
1
|
/* eslint-disable sort-keys-fix/sort-keys-fix */
|
2
2
|
import { integer, jsonb, pgTable, text, uuid, varchar, vector } from 'drizzle-orm/pg-core';
|
3
3
|
|
4
|
-
import {
|
4
|
+
import { timestamps } from './_helpers';
|
5
5
|
import { files } from './file';
|
6
6
|
import { users } from './user';
|
7
7
|
|
@@ -13,10 +13,9 @@ export const chunks = pgTable('chunks', {
|
|
13
13
|
index: integer('index'),
|
14
14
|
type: varchar('type'),
|
15
15
|
|
16
|
-
createdAt: createdAt(),
|
17
|
-
updatedAt: updatedAt(),
|
18
|
-
|
19
16
|
userId: text('user_id').references(() => users.id, { onDelete: 'cascade' }),
|
17
|
+
|
18
|
+
...timestamps,
|
20
19
|
});
|
21
20
|
|
22
21
|
export type NewChunkItem = typeof chunks.$inferInsert & { fileId?: string };
|
@@ -28,8 +27,7 @@ export const unstructuredChunks = pgTable('unstructured_chunks', {
|
|
28
27
|
index: integer('index'),
|
29
28
|
type: varchar('type'),
|
30
29
|
|
31
|
-
|
32
|
-
updatedAt: updatedAt(),
|
30
|
+
...timestamps,
|
33
31
|
|
34
32
|
parentId: varchar('parent_id'),
|
35
33
|
compositeId: uuid('composite_id').references(() => chunks.id, { onDelete: 'cascade' }),
|
@@ -4,7 +4,7 @@ import { integer, jsonb, pgTable, text, uuid } from 'drizzle-orm/pg-core';
|
|
4
4
|
import { DEFAULT_EMBEDDING_MODEL, DEFAULT_MODEL } from '@/const/settings';
|
5
5
|
import { EvalEvaluationStatus } from '@/types/eval';
|
6
6
|
|
7
|
-
import {
|
7
|
+
import { timestamps } from './_helpers';
|
8
8
|
import { knowledgeBases } from './file';
|
9
9
|
import { embeddings } from './rag';
|
10
10
|
import { users } from './user';
|
@@ -20,8 +20,7 @@ export const evalDatasets = pgTable('rag_eval_datasets', {
|
|
20
20
|
}),
|
21
21
|
userId: text('user_id').references(() => users.id, { onDelete: 'cascade' }),
|
22
22
|
|
23
|
-
|
24
|
-
createdAt: createdAt(),
|
23
|
+
...timestamps,
|
25
24
|
});
|
26
25
|
|
27
26
|
export type NewEvalDatasetsItem = typeof evalDatasets.$inferInsert;
|
@@ -39,7 +38,7 @@ export const evalDatasetRecords = pgTable('rag_eval_dataset_records', {
|
|
39
38
|
metadata: jsonb('metadata'),
|
40
39
|
|
41
40
|
userId: text('user_id').references(() => users.id, { onDelete: 'cascade' }),
|
42
|
-
|
41
|
+
...timestamps,
|
43
42
|
});
|
44
43
|
|
45
44
|
export type NewEvalDatasetRecordsItem = typeof evalDatasetRecords.$inferInsert;
|
@@ -64,8 +63,7 @@ export const evalEvaluation = pgTable('rag_eval_evaluations', {
|
|
64
63
|
embeddingModel: text('embedding_model').$defaultFn(() => DEFAULT_EMBEDDING_MODEL),
|
65
64
|
|
66
65
|
userId: text('user_id').references(() => users.id, { onDelete: 'cascade' }),
|
67
|
-
|
68
|
-
updatedAt: updatedAt(),
|
66
|
+
...timestamps,
|
69
67
|
});
|
70
68
|
|
71
69
|
export type NewEvalEvaluationItem = typeof evalEvaluation.$inferInsert;
|
@@ -98,7 +96,7 @@ export const evaluationRecords = pgTable('rag_eval_evaluation_records', {
|
|
98
96
|
.notNull(),
|
99
97
|
|
100
98
|
userId: text('user_id').references(() => users.id, { onDelete: 'cascade' }),
|
101
|
-
|
99
|
+
...timestamps,
|
102
100
|
});
|
103
101
|
|
104
102
|
export type NewEvaluationRecordsItem = typeof evaluationRecords.$inferInsert;
|
@@ -4,7 +4,6 @@ import { pgTable, primaryKey, text } from 'drizzle-orm/pg-core';
|
|
4
4
|
|
5
5
|
import { agents, agentsFiles, agentsKnowledgeBases } from './agent';
|
6
6
|
import { asyncTasks } from './asyncTask';
|
7
|
-
import { agentsTags, plugins, pluginsTags, tags } from './discover';
|
8
7
|
import { files, knowledgeBases } from './file';
|
9
8
|
import { messages, messagesFiles } from './message';
|
10
9
|
import { unstructuredChunks } from './rag';
|
@@ -48,26 +47,6 @@ export const topicRelations = relations(topics, ({ one }) => ({
|
|
48
47
|
}),
|
49
48
|
}));
|
50
49
|
|
51
|
-
export const pluginsRelations = relations(plugins, ({ many }) => ({
|
52
|
-
pluginsTags: many(pluginsTags),
|
53
|
-
}));
|
54
|
-
|
55
|
-
export const pluginsTagsRelations = relations(pluginsTags, ({ one }) => ({
|
56
|
-
plugin: one(plugins, {
|
57
|
-
fields: [pluginsTags.pluginId],
|
58
|
-
references: [plugins.id],
|
59
|
-
}),
|
60
|
-
tag: one(tags, {
|
61
|
-
fields: [pluginsTags.tagId],
|
62
|
-
references: [tags.id],
|
63
|
-
}),
|
64
|
-
}));
|
65
|
-
|
66
|
-
export const tagsRelations = relations(tags, ({ many }) => ({
|
67
|
-
agentsTags: many(agentsTags),
|
68
|
-
pluginsTags: many(pluginsTags),
|
69
|
-
}));
|
70
|
-
|
71
50
|
export const messagesRelations = relations(messages, ({ many, one }) => ({
|
72
51
|
filesToMessages: many(messagesFiles),
|
73
52
|
|
@@ -91,7 +70,6 @@ export const agentsRelations = relations(agents, ({ many }) => ({
|
|
91
70
|
agentsToSessions: many(agentsToSessions),
|
92
71
|
knowledgeBases: many(agentsKnowledgeBases),
|
93
72
|
files: many(agentsFiles),
|
94
|
-
agentsTags: many(agentsTags),
|
95
73
|
}));
|
96
74
|
|
97
75
|
export const agentsToSessionsRelations = relations(agentsToSessions, ({ one }) => ({
|
@@ -116,17 +94,6 @@ export const agentsKnowledgeBasesRelations = relations(agentsKnowledgeBases, ({
|
|
116
94
|
}),
|
117
95
|
}));
|
118
96
|
|
119
|
-
export const agentsTagsRelations = relations(agentsTags, ({ one }) => ({
|
120
|
-
agent: one(agents, {
|
121
|
-
fields: [agentsTags.agentId],
|
122
|
-
references: [agents.id],
|
123
|
-
}),
|
124
|
-
tag: one(tags, {
|
125
|
-
fields: [agentsTags.tagId],
|
126
|
-
references: [tags.id],
|
127
|
-
}),
|
128
|
-
}));
|
129
|
-
|
130
97
|
export const sessionsRelations = relations(sessions, ({ many, one }) => ({
|
131
98
|
filesToSessions: many(filesToSessions),
|
132
99
|
agentsToSessions: many(agentsToSessions),
|
@@ -3,7 +3,7 @@ import { boolean, integer, pgTable, text, unique, uniqueIndex, varchar } from 'd
|
|
3
3
|
import { createInsertSchema } from 'drizzle-zod';
|
4
4
|
|
5
5
|
import { idGenerator, randomSlug } from '../../utils/idGenerator';
|
6
|
-
import {
|
6
|
+
import { timestamps } from './_helpers';
|
7
7
|
import { users } from './user';
|
8
8
|
|
9
9
|
// ======= sessionGroups ======= //
|
@@ -22,8 +22,7 @@ export const sessionGroups = pgTable(
|
|
22
22
|
.notNull(),
|
23
23
|
|
24
24
|
clientId: text('client_id'),
|
25
|
-
|
26
|
-
updatedAt: updatedAt(),
|
25
|
+
...timestamps,
|
27
26
|
},
|
28
27
|
(table) => ({
|
29
28
|
clientIdUnique: unique('session_group_client_id_user_unique').on(table.clientId, table.userId),
|
@@ -60,8 +59,7 @@ export const sessions = pgTable(
|
|
60
59
|
clientId: text('client_id'),
|
61
60
|
pinned: boolean('pinned').default(false),
|
62
61
|
|
63
|
-
|
64
|
-
updatedAt: updatedAt(),
|
62
|
+
...timestamps,
|
65
63
|
},
|
66
64
|
(t) => ({
|
67
65
|
slugUserIdUnique: uniqueIndex('slug_user_id_unique').on(t.slug, t.userId),
|
@@ -1,27 +1,26 @@
|
|
1
|
-
|
1
|
+
/* eslint-disable sort-keys-fix/sort-keys-fix */
|
2
2
|
import { boolean, pgTable, text, unique } from 'drizzle-orm/pg-core';
|
3
3
|
|
4
4
|
import { idGenerator } from '../../utils/idGenerator';
|
5
|
-
import {
|
5
|
+
import { timestamps } from './_helpers';
|
6
6
|
import { sessions } from './session';
|
7
7
|
import { users } from './user';
|
8
8
|
|
9
9
|
export const topics = pgTable(
|
10
10
|
'topics',
|
11
11
|
{
|
12
|
-
clientId: text('client_id'),
|
13
|
-
createdAt: createdAt(),
|
14
|
-
favorite: boolean('favorite').default(false),
|
15
12
|
id: text('id')
|
16
13
|
.$defaultFn(() => idGenerator('topics'))
|
17
14
|
.primaryKey(),
|
18
|
-
sessionId: text('session_id').references(() => sessions.id, { onDelete: 'cascade' }),
|
19
15
|
title: text('title'),
|
20
|
-
|
21
|
-
|
16
|
+
favorite: boolean('favorite').default(false),
|
17
|
+
sessionId: text('session_id').references(() => sessions.id, { onDelete: 'cascade' }),
|
22
18
|
userId: text('user_id')
|
23
19
|
.references(() => users.id, { onDelete: 'cascade' })
|
24
20
|
.notNull(),
|
21
|
+
clientId: text('client_id'),
|
22
|
+
|
23
|
+
...timestamps,
|
25
24
|
},
|
26
25
|
(t) => ({
|
27
26
|
clientIdUnique: unique('topic_client_id_user_id_unique').on(t.clientId, t.userId),
|
@@ -5,7 +5,7 @@ import { boolean, jsonb, pgTable, primaryKey, text } from 'drizzle-orm/pg-core';
|
|
5
5
|
import { DEFAULT_PREFERENCE } from '@/const/user';
|
6
6
|
import { CustomPluginParams } from '@/types/tool/plugin';
|
7
7
|
|
8
|
-
import {
|
8
|
+
import { timestamps, timestamptz } from './_helpers';
|
9
9
|
|
10
10
|
export const users = pgTable('users', {
|
11
11
|
id: text('id').primaryKey().notNull(),
|
@@ -27,8 +27,7 @@ export const users = pgTable('users', {
|
|
27
27
|
|
28
28
|
preference: jsonb('preference').$defaultFn(() => DEFAULT_PREFERENCE),
|
29
29
|
|
30
|
-
|
31
|
-
updatedAt: updatedAt(),
|
30
|
+
...timestamps,
|
32
31
|
});
|
33
32
|
|
34
33
|
export type NewUser = typeof users.$inferInsert;
|
@@ -61,8 +60,7 @@ export const installedPlugins = pgTable(
|
|
61
60
|
settings: jsonb('settings'),
|
62
61
|
customParams: jsonb('custom_params').$type<CustomPluginParams>(),
|
63
62
|
|
64
|
-
|
65
|
-
updatedAt: updatedAt(),
|
63
|
+
...timestamps,
|
66
64
|
},
|
67
65
|
(self) => ({
|
68
66
|
id: primaryKey({ columns: [self.userId, self.identifier] }),
|
@@ -4,7 +4,7 @@ import { memo } from 'react';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
5
5
|
import { Flexbox } from 'react-layout-kit';
|
6
6
|
|
7
|
-
import
|
7
|
+
import PluginTag from '@/app/(main)/chat/(workspace)/features/PluginTag';
|
8
8
|
import { ProductLogo } from '@/components/Branding';
|
9
9
|
import ChatList from '@/features/Conversation/components/ChatList';
|
10
10
|
import { useAgentStore } from '@/store/agent';
|
@@ -12,7 +12,8 @@ import { agentSelectors } from '@/store/agent/selectors';
|
|
12
12
|
import { useSessionStore } from '@/store/session';
|
13
13
|
import { sessionMetaSelectors, sessionSelectors } from '@/store/session/selectors';
|
14
14
|
|
15
|
-
import
|
15
|
+
import pkg from '../../../../package.json';
|
16
|
+
import { useContainerStyles } from '../style';
|
16
17
|
import { useStyles } from './style';
|
17
18
|
import { FieldType } from './type';
|
18
19
|
|
@@ -32,12 +33,13 @@ const Preview = memo<FieldType & { title?: string }>(
|
|
32
33
|
|
33
34
|
const { t } = useTranslation('chat');
|
34
35
|
const { styles } = useStyles(withBackground);
|
36
|
+
const { styles: containerStyles } = useContainerStyles();
|
35
37
|
|
36
38
|
const displayTitle = isInbox ? t('inbox.title') : title;
|
37
39
|
const displayDesc = isInbox ? t('inbox.desc') : description;
|
38
40
|
|
39
41
|
return (
|
40
|
-
<div className={
|
42
|
+
<div className={containerStyles.preview}>
|
41
43
|
<div className={withBackground ? styles.background : undefined} id={'preview'}>
|
42
44
|
<Flexbox className={styles.container} gap={16}>
|
43
45
|
<div className={styles.header}>
|
@@ -0,0 +1,103 @@
|
|
1
|
+
import { Form, type FormItemProps } from '@lobehub/ui';
|
2
|
+
import { Button, Segmented, SegmentedProps, Switch } from 'antd';
|
3
|
+
import { memo, useState } from 'react';
|
4
|
+
import { useTranslation } from 'react-i18next';
|
5
|
+
import { Flexbox } from 'react-layout-kit';
|
6
|
+
|
7
|
+
import { FORM_STYLE } from '@/const/layoutTokens';
|
8
|
+
import { useIsMobile } from '@/hooks/useIsMobile';
|
9
|
+
|
10
|
+
import Preview from './Preview';
|
11
|
+
import { FieldType, ImageType } from './type';
|
12
|
+
import { useScreenshot } from './useScreenshot';
|
13
|
+
|
14
|
+
export const imageTypeOptions: SegmentedProps['options'] = [
|
15
|
+
{
|
16
|
+
label: 'JPG',
|
17
|
+
value: ImageType.JPG,
|
18
|
+
},
|
19
|
+
{
|
20
|
+
label: 'PNG',
|
21
|
+
value: ImageType.PNG,
|
22
|
+
},
|
23
|
+
{
|
24
|
+
label: 'SVG',
|
25
|
+
value: ImageType.SVG,
|
26
|
+
},
|
27
|
+
{
|
28
|
+
label: 'WEBP',
|
29
|
+
value: ImageType.WEBP,
|
30
|
+
},
|
31
|
+
];
|
32
|
+
|
33
|
+
const DEFAULT_FIELD_VALUE: FieldType = {
|
34
|
+
imageType: ImageType.JPG,
|
35
|
+
withBackground: true,
|
36
|
+
withFooter: true,
|
37
|
+
withPluginInfo: false,
|
38
|
+
withSystemRole: false,
|
39
|
+
};
|
40
|
+
|
41
|
+
const ShareImage = memo(() => {
|
42
|
+
const [fieldValue, setFieldValue] = useState<FieldType>(DEFAULT_FIELD_VALUE);
|
43
|
+
const { t } = useTranslation('chat');
|
44
|
+
const { loading, onDownload, title } = useScreenshot(fieldValue.imageType);
|
45
|
+
|
46
|
+
const settings: FormItemProps[] = [
|
47
|
+
{
|
48
|
+
children: <Switch />,
|
49
|
+
label: t('shareModal.withSystemRole'),
|
50
|
+
minWidth: undefined,
|
51
|
+
name: 'withSystemRole',
|
52
|
+
valuePropName: 'checked',
|
53
|
+
},
|
54
|
+
{
|
55
|
+
children: <Switch />,
|
56
|
+
label: t('shareModal.withBackground'),
|
57
|
+
minWidth: undefined,
|
58
|
+
name: 'withBackground',
|
59
|
+
valuePropName: 'checked',
|
60
|
+
},
|
61
|
+
{
|
62
|
+
children: <Switch />,
|
63
|
+
label: t('shareModal.withFooter'),
|
64
|
+
minWidth: undefined,
|
65
|
+
name: 'withFooter',
|
66
|
+
valuePropName: 'checked',
|
67
|
+
},
|
68
|
+
{
|
69
|
+
children: <Segmented options={imageTypeOptions} />,
|
70
|
+
label: t('shareModal.imageType'),
|
71
|
+
minWidth: undefined,
|
72
|
+
name: 'imageType',
|
73
|
+
},
|
74
|
+
];
|
75
|
+
|
76
|
+
const isMobile = useIsMobile();
|
77
|
+
return (
|
78
|
+
<Flexbox gap={16} horizontal={!isMobile}>
|
79
|
+
<Preview title={title} {...fieldValue} />
|
80
|
+
<Flexbox gap={16}>
|
81
|
+
<Form
|
82
|
+
initialValues={DEFAULT_FIELD_VALUE}
|
83
|
+
items={settings}
|
84
|
+
itemsType={'flat'}
|
85
|
+
onValuesChange={(_, v) => setFieldValue(v)}
|
86
|
+
{...FORM_STYLE}
|
87
|
+
/>
|
88
|
+
<Button
|
89
|
+
block
|
90
|
+
loading={loading}
|
91
|
+
onClick={onDownload}
|
92
|
+
size={'large'}
|
93
|
+
style={isMobile ? { bottom: 0, position: 'sticky' } : undefined}
|
94
|
+
type={'primary'}
|
95
|
+
>
|
96
|
+
{t('shareModal.download')}
|
97
|
+
</Button>
|
98
|
+
</Flexbox>
|
99
|
+
</Flexbox>
|
100
|
+
);
|
101
|
+
});
|
102
|
+
|
103
|
+
export default ShareImage;
|
@@ -2,7 +2,7 @@ import { createStyles } from 'antd-style';
|
|
2
2
|
|
3
3
|
import { imageUrl } from '@/const/url';
|
4
4
|
|
5
|
-
export const useStyles = createStyles(({ css, token,
|
5
|
+
export const useStyles = createStyles(({ css, token, cx }, withBackground: boolean) => ({
|
6
6
|
background: css`
|
7
7
|
padding: 24px;
|
8
8
|
|
@@ -33,28 +33,6 @@ export const useStyles = createStyles(({ css, token, stylish, cx }, withBackgrou
|
|
33
33
|
background: ${token.colorBgContainer};
|
34
34
|
border-block-end: 1px solid ${token.colorBorder};
|
35
35
|
`,
|
36
|
-
preview: cx(
|
37
|
-
stylish.noScrollbar,
|
38
|
-
css`
|
39
|
-
overflow: hidden scroll;
|
40
|
-
|
41
|
-
width: 100%;
|
42
|
-
max-height: 40dvh;
|
43
|
-
|
44
|
-
background: ${token.colorBgLayout};
|
45
|
-
border: 1px solid ${token.colorBorder};
|
46
|
-
border-radius: ${token.borderRadiusLG}px;
|
47
|
-
|
48
|
-
* {
|
49
|
-
pointer-events: none;
|
50
|
-
|
51
|
-
::-webkit-scrollbar {
|
52
|
-
width: 0 !important;
|
53
|
-
height: 0 !important;
|
54
|
-
}
|
55
|
-
}
|
56
|
-
`,
|
57
|
-
),
|
58
36
|
role: css`
|
59
37
|
margin-block-start: 12px;
|
60
38
|
padding-block-start: 12px;
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import { Highlighter } from '@lobehub/ui';
|
2
|
+
import { memo } from 'react';
|
3
|
+
|
4
|
+
import { useContainerStyles } from '../style';
|
5
|
+
|
6
|
+
const Preview = memo<{ content: string }>(({ content }) => {
|
7
|
+
const { styles } = useContainerStyles();
|
8
|
+
|
9
|
+
return (
|
10
|
+
<div className={styles.preview}>
|
11
|
+
<Highlighter language={'json'} wrap>
|
12
|
+
{content}
|
13
|
+
</Highlighter>
|
14
|
+
</div>
|
15
|
+
);
|
16
|
+
});
|
17
|
+
|
18
|
+
export default Preview;
|