From 2d1bebeeb59b3e7e400ef47fce7496d10c42fe9e Mon Sep 17 00:00:00 2001 From: XuqmGroup Date: Tue, 28 Apr 2026 10:31:50 +0800 Subject: [PATCH] =?UTF-8?q?feat(im):=20=E6=B7=BB=E5=8A=A0=E5=8D=B3?= =?UTF-8?q?=E6=97=B6=E9=80=9A=E8=AE=AF=E6=95=B0=E6=8D=AE=E5=BA=93=E5=92=8C?= =?UTF-8?q?=E7=BC=A9=E6=94=BE=E5=9B=BE=E7=89=87=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现了基于 WatermelonDB 的 IM 数据库功能 - 添加了 ScaledImage 组件用于图片尺寸自适应 - 集成了消息存储、会话管理、搜索等功能 - 配置了项目基础结构和依赖管理 - 定义了数据库表结构和类型声明 --- package.json | 1 + .../common/src/components/ScaledImage.tsx | 2 +- packages/im/src/db/ImDatabase.ts | 16 ++--- src/types/watermelondb.d.ts | 61 +++++++++++++++++++ tsconfig.json | 7 +++ 5 files changed, 78 insertions(+), 9 deletions(-) create mode 100644 src/types/watermelondb.d.ts diff --git a/package.json b/package.json index 9ad31db..5849a2a 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "@xuqm/rn-sdk", "version": "0.2.0", "description": "XuqmGroup React Native SDK — meta-package (IM, Push, Update, Common)", + "license": "UNLICENSED", "main": "src/index.ts", "react-native": "src/index.ts", "types": "src/index.ts", diff --git a/packages/common/src/components/ScaledImage.tsx b/packages/common/src/components/ScaledImage.tsx index 887a223..371359b 100644 --- a/packages/common/src/components/ScaledImage.tsx +++ b/packages/common/src/components/ScaledImage.tsx @@ -54,7 +54,7 @@ function computeDimensions( return { width: Math.round(width), height: Math.round(height) } } -export function ScaledImage(props: Props): JSX.Element { +export function ScaledImage(props: Props): React.ReactElement { const { uri, originalWidth, diff --git a/packages/im/src/db/ImDatabase.ts b/packages/im/src/db/ImDatabase.ts index 5f8365a..0eb9347 100644 --- a/packages/im/src/db/ImDatabase.ts +++ b/packages/im/src/db/ImDatabase.ts @@ -36,7 +36,7 @@ export const ImDatabase = { schema: imDbSchema, dbName, jsi: true, - onSetUpError: (err) => console.error('[ImDatabase] setup error', err), + onSetUpError: (err: unknown) => console.error('[ImDatabase] setup error', err), }) _db = new Database({ adapter, @@ -57,7 +57,7 @@ export const ImDatabase = { .fetch() if (existing.length === 0) { - await db.get('im_messages').create(m => { + await db.get('im_messages').create((m: MessageModel) => { m.serverId = msg.id m.appId = msg.appId m.conversationId = convId @@ -72,7 +72,7 @@ export const ImDatabase = { m.syncedAt = now }) } else { - await existing[0].update(m => { + await existing[0].update((m: MessageModel) => { m.status = msg.status m.content = msg.content m.syncedAt = now @@ -87,7 +87,7 @@ export const ImDatabase = { const msgTime = new Date(msg.createdAt).getTime() if (convs.length === 0) { - await db.get('im_conversations').create(c => { + await db.get('im_conversations').create((c: ConversationModel) => { c.appId = msg.appId c.targetId = msg.toId c.chatType = msg.chatType @@ -101,7 +101,7 @@ export const ImDatabase = { c.updatedAt = new Date() }) } else { - await convs[0].update(c => { + await convs[0].update((c: ConversationModel) => { if (msgTime >= c.lastMsgTime) { c.lastMsgId = msg.id c.lastMsgContent = msg.content @@ -150,7 +150,7 @@ export const ImDatabase = { .fetch() if (convs.length > 0) { await db.write(async () => { - await convs[0].update(c => { c.unreadCount = 0 }) + await convs[0].update((c: ConversationModel) => { c.unreadCount = 0 }) }) } }, @@ -225,7 +225,7 @@ export const ImDatabase = { .fetch() if (convs.length > 0) { await db.write(async () => { - await convs[0].update(c => { c.isMuted = muted }) + await convs[0].update((c: ConversationModel) => { c.isMuted = muted }) }) } }, @@ -238,7 +238,7 @@ export const ImDatabase = { .fetch() if (convs.length > 0) { await db.write(async () => { - await convs[0].update(c => { c.isPinned = pinned }) + await convs[0].update((c: ConversationModel) => { c.isPinned = pinned }) }) } }, diff --git a/src/types/watermelondb.d.ts b/src/types/watermelondb.d.ts new file mode 100644 index 0000000..79b6e78 --- /dev/null +++ b/src/types/watermelondb.d.ts @@ -0,0 +1,61 @@ +declare module '@nozbe/watermelondb' { + export class Model { + static table: string + update(mutator: (record: this) => void | Promise): Promise + destroyPermanently(): Promise + } + + export class Database { + constructor(options: unknown) + write(work: () => Promise | T): Promise + get(table: string): Collection + } + + export interface Collection { + query(...conditions: unknown[]): Query + create(builder: (record: T) => void | Promise): Promise + } + + export interface Query { + fetch(): Promise + extend(...conditions: unknown[]): Query + observe(): Observable + } + + export interface Observable { + subscribe(callback: (value: T) => void): Subscription + } + + export interface Subscription { + unsubscribe(): void + } + + export const Q: { + and(...conditions: unknown[]): unknown + or(...conditions: unknown[]): unknown + where(column: string, value: unknown): unknown + sortBy(column: string, order?: unknown): unknown + take(count: number): unknown + skip(count: number): unknown + oneOf(values: unknown[]): unknown + like(pattern: string): unknown + gte(value: unknown): unknown + lte(value: unknown): unknown + sanitizeLikeString(value: string): string + desc: unknown + } + + export function appSchema(schema: unknown): unknown + export function tableSchema(schema: unknown): unknown +} + +declare module '@nozbe/watermelondb/adapters/sqlite' { + export default class SQLiteAdapter { + constructor(options: unknown) + } +} + +declare module '@nozbe/watermelondb/decorators' { + export function field(columnName: string): any + export function date(columnName: string): any +} diff --git a/tsconfig.json b/tsconfig.json index 4a81949..460ff75 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,6 +3,13 @@ "target": "ES2020", "module": "ESNext", "moduleResolution": "bundler", + "baseUrl": ".", + "paths": { + "@xuqm/rn-common": ["packages/common/src"], + "@xuqm/rn-im": ["packages/im/src"], + "@xuqm/rn-push": ["packages/push/src"], + "@xuqm/rn-update": ["packages/update/src"] + }, "strict": true, "jsx": "react-native", "lib": ["ES2020"],