From 4b5d09a3cf8faac99905392d657660e1469f87c9 Mon Sep 17 00:00:00 2001 From: sealday Date: Fri, 27 Sep 2024 05:12:12 +0800 Subject: [PATCH] feat: web notification (#1573) Co-authored-by: sealday Reviewed-on: https://git.daoyoucloud.com/daoyoucloud/tachybase/pulls/1573 --- .../PluginWebNotification.tsx | 17 ----------- .../src/client/components/index.ts | 1 - .../online-users}/OnlineUserProvider.tsx | 30 +++++++------------ .../src/client/features/online-users/index.ts | 9 ++++++ .../@hera/plugin-core/src/client/index.tsx | 2 ++ .../plugin-messages/src/client/index.tsx | 8 ++--- .../PluginWebNotification.tsx | 30 +++++++++++++++++++ .../plugin-messages/src/server/plugin.ts | 15 +++++++++- .../@tachybase/plugin-online-user/.npmignore | 2 ++ .../@tachybase/plugin-online-user/README.md | 1 + .../@tachybase/plugin-online-user/client.d.ts | 2 ++ .../@tachybase/plugin-online-user/client.js | 1 + .../plugin-online-user/package.json | 11 +++++++ .../@tachybase/plugin-online-user/server.d.ts | 2 ++ .../@tachybase/plugin-online-user/server.js | 1 + .../plugin-online-user/src/client/index.tsx | 21 +++++++++++++ .../plugin-online-user/src/index.ts | 2 ++ .../src/server/collections/.gitkeep | 0 .../plugin-online-user/src/server/index.ts | 1 + .../plugin-online-user/src/server/plugin.ts | 19 ++++++++++++ packages/presets/base/package.json | 1 + packages/presets/base/src/server/index.ts | 1 + pnpm-lock.yaml | 15 ++++++++++ 23 files changed, 147 insertions(+), 45 deletions(-) delete mode 100644 packages/core/client/src/built-in/web-notification/PluginWebNotification.tsx rename packages/plugins/@hera/plugin-core/src/client/{components/system => features/online-users}/OnlineUserProvider.tsx (65%) create mode 100644 packages/plugins/@hera/plugin-core/src/client/features/online-users/index.ts create mode 100644 packages/plugins/@tachybase/plugin-messages/src/client/web-notification/PluginWebNotification.tsx create mode 100644 packages/plugins/@tachybase/plugin-online-user/.npmignore create mode 100644 packages/plugins/@tachybase/plugin-online-user/README.md create mode 100644 packages/plugins/@tachybase/plugin-online-user/client.d.ts create mode 100644 packages/plugins/@tachybase/plugin-online-user/client.js create mode 100644 packages/plugins/@tachybase/plugin-online-user/package.json create mode 100644 packages/plugins/@tachybase/plugin-online-user/server.d.ts create mode 100644 packages/plugins/@tachybase/plugin-online-user/server.js create mode 100644 packages/plugins/@tachybase/plugin-online-user/src/client/index.tsx create mode 100644 packages/plugins/@tachybase/plugin-online-user/src/index.ts create mode 100644 packages/plugins/@tachybase/plugin-online-user/src/server/collections/.gitkeep create mode 100644 packages/plugins/@tachybase/plugin-online-user/src/server/index.ts create mode 100644 packages/plugins/@tachybase/plugin-online-user/src/server/plugin.ts diff --git a/packages/core/client/src/built-in/web-notification/PluginWebNotification.tsx b/packages/core/client/src/built-in/web-notification/PluginWebNotification.tsx deleted file mode 100644 index 08fa15e7b..000000000 --- a/packages/core/client/src/built-in/web-notification/PluginWebNotification.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { Plugin } from '../../application/Plugin'; - -export class PluginWebNotification extends Plugin { - async afterLoad() { - // ‌请求用户授予权限 - if (Notification.permission !== 'denied') { - await Notification.requestPermission(); - } - - setTimeout(() => { - const notification = new Notification('通知标题:', { - body: '通知内容', - icon: 'https://www.example.com/icon.png', // 通知的图标 URL - }); - }, 2000); - } -} diff --git a/packages/plugins/@hera/plugin-core/src/client/components/index.ts b/packages/plugins/@hera/plugin-core/src/client/components/index.ts index fae14942b..7f7c1b604 100644 --- a/packages/plugins/@hera/plugin-core/src/client/components/index.ts +++ b/packages/plugins/@hera/plugin-core/src/client/components/index.ts @@ -8,5 +8,4 @@ export * from './custom-components/CustomField'; export * from './fields/AssociatedField'; export * from './fields/CalcResult'; export * from './fields/Expression'; -export * from './system/OnlineUserProvider'; export * from './excel-table/ExcelFile'; diff --git a/packages/plugins/@hera/plugin-core/src/client/components/system/OnlineUserProvider.tsx b/packages/plugins/@hera/plugin-core/src/client/features/online-users/OnlineUserProvider.tsx similarity index 65% rename from packages/plugins/@hera/plugin-core/src/client/components/system/OnlineUserProvider.tsx rename to packages/plugins/@hera/plugin-core/src/client/features/online-users/OnlineUserProvider.tsx index 7093857ba..9bd0c2d3a 100644 --- a/packages/plugins/@hera/plugin-core/src/client/components/system/OnlineUserProvider.tsx +++ b/packages/plugins/@hera/plugin-core/src/client/features/online-users/OnlineUserProvider.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from 'react'; -import { css, useAPIClient, useApp } from '@tachybase/client'; +import { PinnedPluginListProvider, SchemaComponentOptions, useAPIClient, useApp, useToken } from '@tachybase/client'; import { uid } from '@tachybase/schema'; import { Button, Dropdown } from 'antd'; @@ -9,6 +9,7 @@ const OnlineUserManger = () => { const app = useApp(); const [onlineUserItems, setOnlineUserItems] = useState([]); const api = useAPIClient(); + const { token } = useToken(); useEffect(() => { app.ws.on('message', (event: MessageEvent) => { const data = JSON.parse(event.data); @@ -38,32 +39,21 @@ const OnlineUserManger = () => { return ( - ); }; -export const OnlineUserDropdown = () => { +export const OnlineUserProvider = (props) => { return ( -
- -
+ {props.children} + ); }; diff --git a/packages/plugins/@hera/plugin-core/src/client/features/online-users/index.ts b/packages/plugins/@hera/plugin-core/src/client/features/online-users/index.ts new file mode 100644 index 000000000..1a1f87b3b --- /dev/null +++ b/packages/plugins/@hera/plugin-core/src/client/features/online-users/index.ts @@ -0,0 +1,9 @@ +import { Plugin } from '@tachybase/client'; + +import { OnlineUserProvider } from './OnlineUserProvider'; + +export class PluginOnlineUsers extends Plugin { + async load() { + this.app.use(OnlineUserProvider); + } +} diff --git a/packages/plugins/@hera/plugin-core/src/client/index.tsx b/packages/plugins/@hera/plugin-core/src/client/index.tsx index 98ce3b4c2..11773f610 100644 --- a/packages/plugins/@hera/plugin-core/src/client/index.tsx +++ b/packages/plugins/@hera/plugin-core/src/client/index.tsx @@ -20,6 +20,7 @@ import { DepartmentsPlugin } from './features/departments'; import { EmbedPlugin } from './features/embed'; import { PluginFieldAppends } from './features/field-appends'; import { PluginHeraVersion } from './features/hera-version'; +import { PluginOnlineUsers } from './features/online-users'; import { PluginOutbound } from './features/outbound'; import { PluginPDF } from './features/pdf'; import { PluginSheet } from './features/sheet'; @@ -62,6 +63,7 @@ export class PluginCoreClient extends Plugin { await this.app.pm.add(PluginPDF); await this.app.pm.add(PluginOutbound); // await this.app.pm.add(PluginModeHighlight); + await this.app.pm.add(PluginOnlineUsers); await this.app.pm.add(PluginFieldAppends); await this.app.pm.add(PluginCustomComponents); await this.app.pm.add(PluginSheet); diff --git a/packages/plugins/@tachybase/plugin-messages/src/client/index.tsx b/packages/plugins/@tachybase/plugin-messages/src/client/index.tsx index 48b3831a6..63245e0a9 100644 --- a/packages/plugins/@tachybase/plugin-messages/src/client/index.tsx +++ b/packages/plugins/@tachybase/plugin-messages/src/client/index.tsx @@ -10,6 +10,7 @@ import { MessageNotificationProvider } from './MessageNotificationProvider'; import { MessagePage } from './MessagePage'; import { MessageProvider } from './MessageProvider'; import { SubscriptionManager } from './SubscriptionManager'; +import { PluginWebNotification } from './web-notification/PluginWebNotification'; interface MessageType { title: string; @@ -20,7 +21,7 @@ export class PluginMessagesClient extends Plugin { private _messageTypes: MessageType[] = []; async afterAdd() { - // await this.app.pm.add() + await this.app.pm.add(PluginWebNotification, { name: 'message-web' }); } async beforeLoad() {} @@ -71,11 +72,6 @@ export class PluginMessagesClient extends Plugin { Component: SubscriptionManager, }); - this.registe({ - name: 'browser', - title: lang('Browser notification'), - }); - this.registe({ name: 'sms', title: lang('SMS notification'), diff --git a/packages/plugins/@tachybase/plugin-messages/src/client/web-notification/PluginWebNotification.tsx b/packages/plugins/@tachybase/plugin-messages/src/client/web-notification/PluginWebNotification.tsx new file mode 100644 index 000000000..8c8b00e72 --- /dev/null +++ b/packages/plugins/@tachybase/plugin-messages/src/client/web-notification/PluginWebNotification.tsx @@ -0,0 +1,30 @@ +import { Plugin } from '@tachybase/client'; + +import PluginMessagesClient from '..'; +import { lang } from '../locale'; + +export class PluginWebNotification extends Plugin { + async afterLoad() { + // ‌请求用户授予权限 + if (Notification.permission !== 'denied') { + await Notification.requestPermission(); + } + } + + async load() { + this.pm.get(PluginMessagesClient).registe({ + name: 'browser', + title: lang('Browser notification'), + }); + + this.app.ws.on('message', (event: MessageEvent) => { + const data = JSON.parse(event.data); + if (data?.type === 'messages') { + const message = data.payload.message; + const notification = new Notification(message.title, { + body: message.content, + }); + } + }); + } +} diff --git a/packages/plugins/@tachybase/plugin-messages/src/server/plugin.ts b/packages/plugins/@tachybase/plugin-messages/src/server/plugin.ts index dbf845e9b..db37d18d9 100644 --- a/packages/plugins/@tachybase/plugin-messages/src/server/plugin.ts +++ b/packages/plugins/@tachybase/plugin-messages/src/server/plugin.ts @@ -1,5 +1,6 @@ +import { Model } from '@tachybase/database'; import { PluginWorkflow } from '@tachybase/plugin-workflow'; -import { Plugin } from '@tachybase/server'; +import { Gateway, Plugin } from '@tachybase/server'; import { MessageInstruction } from './instructions/message-instruction'; @@ -9,8 +10,20 @@ export class PluginMessagesServer extends Plugin { async beforeLoad() {} async load() { + const appName = this.app.name; const workflowPlugin = this.app.getPlugin(PluginWorkflow); workflowPlugin.registerInstruction('message-instruction', MessageInstruction); + this.db.on('messages.afterCreate', async (message: Model, options) => { + const gateway = Gateway.getInstance(); + const ws = gateway['wsServer']; + + ws.sendToConnectionsByTag('app', appName, { + type: 'messages', + payload: { + message: message.toJSON(), + }, + }); + }); } async install() {} diff --git a/packages/plugins/@tachybase/plugin-online-user/.npmignore b/packages/plugins/@tachybase/plugin-online-user/.npmignore new file mode 100644 index 000000000..65f5e8779 --- /dev/null +++ b/packages/plugins/@tachybase/plugin-online-user/.npmignore @@ -0,0 +1,2 @@ +/node_modules +/src diff --git a/packages/plugins/@tachybase/plugin-online-user/README.md b/packages/plugins/@tachybase/plugin-online-user/README.md new file mode 100644 index 000000000..54128e99c --- /dev/null +++ b/packages/plugins/@tachybase/plugin-online-user/README.md @@ -0,0 +1 @@ +# @tachybase/plugin-online-user diff --git a/packages/plugins/@tachybase/plugin-online-user/client.d.ts b/packages/plugins/@tachybase/plugin-online-user/client.d.ts new file mode 100644 index 000000000..6c459cbac --- /dev/null +++ b/packages/plugins/@tachybase/plugin-online-user/client.d.ts @@ -0,0 +1,2 @@ +export * from './dist/client'; +export { default } from './dist/client'; diff --git a/packages/plugins/@tachybase/plugin-online-user/client.js b/packages/plugins/@tachybase/plugin-online-user/client.js new file mode 100644 index 000000000..b6e3be70e --- /dev/null +++ b/packages/plugins/@tachybase/plugin-online-user/client.js @@ -0,0 +1 @@ +module.exports = require('./dist/client/index.js'); diff --git a/packages/plugins/@tachybase/plugin-online-user/package.json b/packages/plugins/@tachybase/plugin-online-user/package.json new file mode 100644 index 000000000..8e18cea2e --- /dev/null +++ b/packages/plugins/@tachybase/plugin-online-user/package.json @@ -0,0 +1,11 @@ +{ + "name": "@tachybase/plugin-online-user", + "version": "0.22.4", + "main": "dist/server/index.js", + "dependencies": {}, + "peerDependencies": { + "@tachybase/client": "workspace:*", + "@tachybase/server": "workspace:*", + "@tachybase/test": "workspace:*" + } +} diff --git a/packages/plugins/@tachybase/plugin-online-user/server.d.ts b/packages/plugins/@tachybase/plugin-online-user/server.d.ts new file mode 100644 index 000000000..c41081ddc --- /dev/null +++ b/packages/plugins/@tachybase/plugin-online-user/server.d.ts @@ -0,0 +1,2 @@ +export * from './dist/server'; +export { default } from './dist/server'; diff --git a/packages/plugins/@tachybase/plugin-online-user/server.js b/packages/plugins/@tachybase/plugin-online-user/server.js new file mode 100644 index 000000000..972842039 --- /dev/null +++ b/packages/plugins/@tachybase/plugin-online-user/server.js @@ -0,0 +1 @@ +module.exports = require('./dist/server/index.js'); diff --git a/packages/plugins/@tachybase/plugin-online-user/src/client/index.tsx b/packages/plugins/@tachybase/plugin-online-user/src/client/index.tsx new file mode 100644 index 000000000..950080a2f --- /dev/null +++ b/packages/plugins/@tachybase/plugin-online-user/src/client/index.tsx @@ -0,0 +1,21 @@ +import { Plugin } from '@tachybase/client'; + +export class PluginOnlineUserClient extends Plugin { + async afterAdd() { + // await this.app.pm.add() + } + + async beforeLoad() {} + + // You can get and modify the app instance here + async load() { + console.log(this.app); + // this.app.addComponents({}) + // this.app.addScopes({}) + // this.app.addProvider() + // this.app.addProviders() + // this.app.router.add() + } +} + +export default PluginOnlineUserClient; diff --git a/packages/plugins/@tachybase/plugin-online-user/src/index.ts b/packages/plugins/@tachybase/plugin-online-user/src/index.ts new file mode 100644 index 000000000..7e74612df --- /dev/null +++ b/packages/plugins/@tachybase/plugin-online-user/src/index.ts @@ -0,0 +1,2 @@ +export * from './server'; +export { default } from './server'; diff --git a/packages/plugins/@tachybase/plugin-online-user/src/server/collections/.gitkeep b/packages/plugins/@tachybase/plugin-online-user/src/server/collections/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/packages/plugins/@tachybase/plugin-online-user/src/server/index.ts b/packages/plugins/@tachybase/plugin-online-user/src/server/index.ts new file mode 100644 index 000000000..b68aea57f --- /dev/null +++ b/packages/plugins/@tachybase/plugin-online-user/src/server/index.ts @@ -0,0 +1 @@ +export { default } from './plugin'; diff --git a/packages/plugins/@tachybase/plugin-online-user/src/server/plugin.ts b/packages/plugins/@tachybase/plugin-online-user/src/server/plugin.ts new file mode 100644 index 000000000..8ff892dc7 --- /dev/null +++ b/packages/plugins/@tachybase/plugin-online-user/src/server/plugin.ts @@ -0,0 +1,19 @@ +import { Plugin } from '@tachybase/server'; + +export class PluginOnlineUserServer extends Plugin { + async afterAdd() {} + + async beforeLoad() {} + + async load() {} + + async install() {} + + async afterEnable() {} + + async afterDisable() {} + + async remove() {} +} + +export default PluginOnlineUserServer; diff --git a/packages/presets/base/package.json b/packages/presets/base/package.json index 14e3ee297..634764297 100644 --- a/packages/presets/base/package.json +++ b/packages/presets/base/package.json @@ -43,6 +43,7 @@ "@tachybase/plugin-multi-app-manager": "workspace:*", "@tachybase/plugin-multi-app-share-collection": "workspace:*", "@tachybase/plugin-oidc": "workspace:*", + "@tachybase/plugin-online-user": "workspace:*", "@tachybase/plugin-saml": "workspace:*", "@tachybase/plugin-sequence-field": "workspace:*", "@tachybase/plugin-sms-auth": "workspace:*", diff --git a/packages/presets/base/src/server/index.ts b/packages/presets/base/src/server/index.ts index c054adcf4..30c2988ed 100644 --- a/packages/presets/base/src/server/index.ts +++ b/packages/presets/base/src/server/index.ts @@ -18,6 +18,7 @@ export class PresetTachyBase extends Plugin { 'acl', 'messages', // optional plugins, default enabled + 'online-user', 'action-bulk-edit', 'action-bulk-update', 'action-duplicate', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d85465f98..f88fb37f7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3656,6 +3656,18 @@ importers: specifier: ^6.25.1 version: 6.25.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + packages/plugins/@tachybase/plugin-online-user: + dependencies: + '@tachybase/client': + specifier: workspace:* + version: link:../../../core/client + '@tachybase/server': + specifier: workspace:* + version: link:../../../core/server + '@tachybase/test': + specifier: workspace:* + version: link:../../../core/test + packages/plugins/@tachybase/plugin-print-template: dependencies: '@bull-board/api': @@ -4512,6 +4524,9 @@ importers: '@tachybase/plugin-oidc': specifier: workspace:* version: link:../../plugins/@tachybase/plugin-oidc + '@tachybase/plugin-online-user': + specifier: workspace:* + version: link:../../plugins/@tachybase/plugin-online-user '@tachybase/plugin-saml': specifier: workspace:* version: link:../../plugins/@tachybase/plugin-saml