diff --git a/client/desktop/src/main/inject/index.ts b/client/desktop/src/main/inject/index.ts
index c5719313..7a8f8328 100644
--- a/client/desktop/src/main/inject/index.ts
+++ b/client/desktop/src/main/inject/index.ts
@@ -31,6 +31,18 @@ export function generateInjectedScript(): string {
return [generateDeviceInfo()].join(';');
}
+function getPlatform() {
+ if (process.platform === 'darwin') {
+ return 'mac';
+ } else if (process.platform === 'win32') {
+ return 'windows';
+ } else if (process.platform === 'linux') {
+ return 'linux';
+ } else {
+ return process.platform;
+ }
+}
+
function generateDeviceInfo() {
- return `window.__electronDeviceInfo = { version: "${app.getVersion()}", name: "${app.getName()}" }`;
+ return `window.__electronDeviceInfo = { version: "${app.getVersion()}", name: "${app.getName()}", platform: "${getPlatform}" }`;
}
diff --git a/client/shared/index.tsx b/client/shared/index.tsx
index 1a3a1b5a..3eedbc5f 100644
--- a/client/shared/index.tsx
+++ b/client/shared/index.tsx
@@ -39,6 +39,7 @@ export {
// event
export { sharedEvent, useSharedEventHandler } from './event/index';
+export type { SharedEventType } from './event/index';
// helper
export { getDMConverseName } from './helper/converse-helper';
diff --git a/client/web/plugins/.eslintrc.js b/client/web/plugins/.eslintrc.js
index 4976eb83..d8425b51 100644
--- a/client/web/plugins/.eslintrc.js
+++ b/client/web/plugins/.eslintrc.js
@@ -11,6 +11,10 @@ module.exports = {
name: 'tailchat-shared',
message: 'Only allow use `@capital/*`',
},
+ {
+ name: 'antd',
+ message: 'Only allow use `@capital/component`',
+ },
{
name: 'translate',
message: 'Maybe you should use `./translate`',
diff --git a/client/web/plugins/com.msgbyte.env.electron/package.json b/client/web/plugins/com.msgbyte.env.electron/package.json
index 7a3f6171..e66fa3a8 100644
--- a/client/web/plugins/com.msgbyte.env.electron/package.json
+++ b/client/web/plugins/com.msgbyte.env.electron/package.json
@@ -7,8 +7,11 @@
"scripts": {
"sync:declaration": "tailchat declaration github"
},
- "dependencies": {},
+ "dependencies": {
+ "semver": "^7.5.4"
+ },
"devDependencies": {
+ "@types/semver": "^7.5.0",
"@types/styled-components": "^5.1.26",
"react": "18.2.0",
"styled-components": "^5.3.6"
diff --git a/client/web/plugins/com.msgbyte.env.electron/src/DeviceInfoPanel.tsx b/client/web/plugins/com.msgbyte.env.electron/src/DeviceInfoPanel.tsx
index 0adcc0eb..3d29f0ee 100644
--- a/client/web/plugins/com.msgbyte.env.electron/src/DeviceInfoPanel.tsx
+++ b/client/web/plugins/com.msgbyte.env.electron/src/DeviceInfoPanel.tsx
@@ -1,14 +1,13 @@
+import { showSuccessToasts } from '@capital/common';
+import { Button } from '@capital/component';
import React from 'react';
+import { checkUpdate } from './checkUpdate';
import { Translate } from './translate';
-
-interface WindowElectronDeviceInfo {
- name: string;
- version: string;
-}
+import { getDeviceInfo } from './utils';
export const DeviceInfoPanel: React.FC = React.memo(() => {
- const deviceInfo: WindowElectronDeviceInfo =
- (window as any).__electronDeviceInfo ?? {};
+ const deviceInfo = getDeviceInfo();
+
return (
@@ -17,6 +16,19 @@ export const DeviceInfoPanel: React.FC = React.memo(() => {
{Translate.clientVersion}: {deviceInfo.version}
+
+ {Translate.platform}: {deviceInfo.platform}
+
+
);
});
diff --git a/client/web/plugins/com.msgbyte.env.electron/src/checkUpdate.tsx b/client/web/plugins/com.msgbyte.env.electron/src/checkUpdate.tsx
new file mode 100644
index 00000000..18456535
--- /dev/null
+++ b/client/web/plugins/com.msgbyte.env.electron/src/checkUpdate.tsx
@@ -0,0 +1,60 @@
+import { Button, notification } from '@capital/component';
+import React from 'react';
+import { Translate } from './translate';
+import { getDeviceInfo } from './utils';
+
+const url = 'https://tailchat.msgbyte.com/downloads/client.json';
+
+export async function checkUpdate(): Promise
{
+ const deviceInfo = getDeviceInfo();
+ const [semver, config] = await Promise.all([
+ import('semver'),
+ fetch(url).then((res) => res.json()),
+ ]);
+
+ const version = deviceInfo.version;
+ const platform = deviceInfo.platform;
+ const latestConfig = config?.[platform];
+ const latestVersion = latestConfig?.version;
+ const latestUrl = latestConfig?.url;
+
+ if (!latestVersion) {
+ console.warn('Not found latest version');
+ return true;
+ }
+ if (!latestUrl) {
+ console.warn('Not found latest url');
+ return true;
+ }
+
+ if (semver.gt(latestVersion, version)) {
+ // 有新版本
+ notification.info({
+ message: Translate.newVersionTip,
+ description: (
+
+
{Translate.newVersionDesc}
+
+ {version} -> {latestVersion}
+
+
+ ),
+ btn: (
+
+ ),
+ placement: 'topRight',
+ duration: 0,
+ });
+
+ return true;
+ }
+
+ return false;
+}
diff --git a/client/web/plugins/com.msgbyte.env.electron/src/index.tsx b/client/web/plugins/com.msgbyte.env.electron/src/index.tsx
index ce3005aa..202e5e4a 100644
--- a/client/web/plugins/com.msgbyte.env.electron/src/index.tsx
+++ b/client/web/plugins/com.msgbyte.env.electron/src/index.tsx
@@ -8,6 +8,7 @@ import React from 'react';
import { DeviceInfoPanel } from './DeviceInfoPanel';
import { Translate } from './translate';
import { forwardSharedEvent } from './utils';
+import { checkUpdate } from './checkUpdate';
const PLUGIN_NAME = 'Electron Support';
@@ -37,3 +38,7 @@ regChatInputButton({
});
forwardSharedEvent('receiveUnmutedMessage');
+
+setTimeout(() => {
+ checkUpdate();
+}, 1000);
diff --git a/client/web/plugins/com.msgbyte.env.electron/src/translate.ts b/client/web/plugins/com.msgbyte.env.electron/src/translate.ts
index 1f19e5e0..9325004e 100644
--- a/client/web/plugins/com.msgbyte.env.electron/src/translate.ts
+++ b/client/web/plugins/com.msgbyte.env.electron/src/translate.ts
@@ -13,4 +13,28 @@ export const Translate = {
'zh-CN': '客户端版本号',
'en-US': 'Client Version',
}),
+ platform: localTrans({
+ 'zh-CN': '平台',
+ 'en-US': 'Platform',
+ }),
+ newVersionTip: localTrans({
+ 'zh-CN': '新版本提示',
+ 'en-US': 'New Version Upgrade Tip',
+ }),
+ newVersionDesc: localTrans({
+ 'zh-CN': '发现有新的版本可以安装',
+ 'en-US': 'A new version was found to be installed',
+ }),
+ upgradeNow: localTrans({
+ 'zh-CN': '立即更新',
+ 'en-US': 'Upgrade Now',
+ }),
+ checkVersion: localTrans({
+ 'zh-CN': '检查更新',
+ 'en-US': 'Check for updates',
+ }),
+ isLatest: localTrans({
+ 'zh-CN': '已经是最新版',
+ 'en-US': 'Already the latest version',
+ }),
};
diff --git a/client/web/plugins/com.msgbyte.env.electron/src/utils.ts b/client/web/plugins/com.msgbyte.env.electron/src/utils.ts
index 579eb0dd..ad5dd4d1 100644
--- a/client/web/plugins/com.msgbyte.env.electron/src/utils.ts
+++ b/client/web/plugins/com.msgbyte.env.electron/src/utils.ts
@@ -7,7 +7,7 @@ export function forwardSharedEvent(
eventName: string,
processPayload?: (payload: any) => Promise<{ type: string; payload: any }>
) {
- sharedEvent.on(eventName, async (payload: any) => {
+ sharedEvent.on(eventName as any, async (payload: any) => {
let type = eventName;
if (processPayload) {
const res = await processPayload(payload);
@@ -23,3 +23,19 @@ export function forwardSharedEvent(
postMessageEvent(type, payload);
});
}
+
+interface ElectronDeviceInfo {
+ name: string;
+ version: string;
+ platform: string;
+}
+export function getDeviceInfo() {
+ const deviceInfo: ElectronDeviceInfo = {
+ name: '',
+ version: '0.0.0',
+ platform: 'windows',
+ ...((window as any).__electronDeviceInfo ?? {}),
+ };
+
+ return deviceInfo;
+}
diff --git a/client/web/plugins/com.msgbyte.env.electron/tsconfig.json b/client/web/plugins/com.msgbyte.env.electron/tsconfig.json
index d9b47ed0..efb75ed0 100644
--- a/client/web/plugins/com.msgbyte.env.electron/tsconfig.json
+++ b/client/web/plugins/com.msgbyte.env.electron/tsconfig.json
@@ -2,6 +2,9 @@
"compilerOptions": {
"esModuleInterop": true,
"jsx": "react",
- "importsNotUsedAsValues": "error"
+ "importsNotUsedAsValues": "error",
+ "paths": {
+ "@capital/*": ["../../src/plugin/*"],
+ }
}
}
diff --git a/client/web/plugins/com.msgbyte.env.electron/types/tailchat.d.ts b/client/web/plugins/com.msgbyte.env.electron/types/tailchat.d.ts
deleted file mode 100644
index 49f524ae..00000000
--- a/client/web/plugins/com.msgbyte.env.electron/types/tailchat.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-declare module '@capital/common';
-declare module '@capital/component';
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 71b36206..c6612b18 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1056,7 +1056,14 @@ importers:
version: 18.2.0
client/web/plugins/com.msgbyte.env.electron:
+ dependencies:
+ semver:
+ specifier: ^7.5.4
+ version: 7.5.4
devDependencies:
+ '@types/semver':
+ specifier: ^7.5.0
+ version: 7.5.0
'@types/styled-components':
specifier: ^5.1.26
version: 5.1.26
@@ -5439,7 +5446,7 @@ packages:
react-router-config: 5.1.1(react-router@5.3.4)(react@17.0.2)
react-router-dom: 5.3.4(react@17.0.2)
rtl-detect: 1.0.4
- semver: 7.3.8
+ semver: 7.5.4
serve-handler: 6.1.5
shelljs: 0.8.5
terser-webpack-plugin: 5.3.6(esbuild@0.15.18)(webpack@5.75.0)
@@ -7380,7 +7387,7 @@ packages:
resolution: {integrity: sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==}
dependencies:
'@gar/promisify': 1.1.3
- semver: 7.3.8
+ semver: 7.5.4
dev: true
/@npmcli/move-file@1.1.2:
@@ -11528,7 +11535,7 @@ packages:
loglevel: 1.8.0
mongoose: 6.1.1
reflect-metadata: 0.1.13
- semver: 7.3.8
+ semver: 7.5.4
tslib: 2.5.0
dev: false
@@ -12402,8 +12409,8 @@ packages:
/@types/scheduler@0.16.2:
resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==}
- /@types/semver@7.3.13:
- resolution: {integrity: sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==}
+ /@types/semver@7.5.0:
+ resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==}
dev: true
/@types/send@0.17.1:
@@ -12666,7 +12673,7 @@ packages:
ignore: 5.2.4
natural-compare-lite: 1.4.0
regexpp: 3.2.0
- semver: 7.3.8
+ semver: 7.5.4
tsutils: 3.21.0(typescript@4.9.4)
typescript: 4.9.4
transitivePeerDependencies:
@@ -12740,7 +12747,7 @@ packages:
debug: 4.3.4(supports-color@9.2.2)
globby: 11.1.0
is-glob: 4.0.3
- semver: 7.3.8
+ semver: 7.5.4
tsutils: 3.21.0(typescript@4.9.4)
typescript: 4.9.4
transitivePeerDependencies:
@@ -12754,14 +12761,14 @@ packages:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
dependencies:
'@types/json-schema': 7.0.11
- '@types/semver': 7.3.13
+ '@types/semver': 7.5.0
'@typescript-eslint/scope-manager': 5.53.0
'@typescript-eslint/types': 5.53.0
'@typescript-eslint/typescript-estree': 5.53.0(typescript@4.9.4)
eslint: 8.34.0
eslint-scope: 5.1.1
eslint-utils: 3.0.0(eslint@8.34.0)
- semver: 7.3.8
+ semver: 7.5.4
transitivePeerDependencies:
- supports-color
- typescript
@@ -16307,7 +16314,7 @@ packages:
postcss-modules-values: 4.0.0(postcss@8.4.21)
postcss-value-parser: 4.2.0
schema-utils: 3.1.1
- semver: 7.3.8
+ semver: 7.5.4
webpack: 5.75.0(esbuild@0.12.29)(webpack-cli@4.10.0)
dev: true
@@ -16324,7 +16331,7 @@ packages:
postcss-modules-scope: 3.0.0(postcss@8.4.21)
postcss-modules-values: 4.0.0(postcss@8.4.21)
postcss-value-parser: 4.2.0
- semver: 7.3.8
+ semver: 7.5.4
webpack: 5.75.0(esbuild@0.12.29)(webpack-cli@4.10.0)
dev: false
@@ -19193,7 +19200,7 @@ packages:
memfs: 3.4.13
minimatch: 3.1.2
schema-utils: 2.7.0
- semver: 7.3.8
+ semver: 7.5.4
tapable: 1.1.3
typescript: 4.9.4
webpack: 5.75.0(esbuild@0.12.29)(webpack-cli@4.10.0)
@@ -22215,7 +22222,7 @@ packages:
jest-util: 27.5.1
natural-compare: 1.4.0
pretty-format: 27.5.1
- semver: 7.3.8
+ semver: 7.5.4
transitivePeerDependencies:
- supports-color
dev: true
@@ -24946,7 +24953,7 @@ packages:
dependencies:
hosted-git-info: 4.1.0
is-core-module: 2.11.0
- semver: 7.3.8
+ semver: 7.5.4
validate-npm-package-license: 3.0.4
dev: true
@@ -25625,7 +25632,7 @@ packages:
got: 11.8.3
registry-auth-token: 5.0.1
registry-url: 6.0.1
- semver: 7.3.8
+ semver: 7.5.4
dev: true
/param-case@2.1.1:
@@ -26284,7 +26291,7 @@ packages:
loader-utils: 2.0.4
postcss: 7.0.39
schema-utils: 3.1.1
- semver: 7.3.8
+ semver: 7.5.4
webpack: 5.75.0(esbuild@0.12.29)(webpack-cli@4.10.0)
dev: true
@@ -26298,7 +26305,7 @@ packages:
cosmiconfig: 7.1.0
klona: 2.0.6
postcss: 8.4.21
- semver: 7.3.8
+ semver: 7.5.4
webpack: 5.75.0(esbuild@0.12.29)(webpack-cli@4.10.0)
dev: true
@@ -26312,7 +26319,7 @@ packages:
cosmiconfig: 7.1.0
klona: 2.0.6
postcss: 8.4.21
- semver: 7.3.8
+ semver: 7.5.4
webpack: 5.75.0(esbuild@0.12.29)(webpack-cli@4.10.0)
dev: false
@@ -27026,7 +27033,7 @@ packages:
pino-http: 5.8.0
pkg-conf: 3.1.0
resolve: 1.22.1
- semver: 7.3.8
+ semver: 7.5.4
update-dotenv: 1.1.1(dotenv@8.6.0)
uuid: 8.3.2
transitivePeerDependencies:
@@ -30087,7 +30094,7 @@ packages:
resolution: {integrity: sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==}
engines: {node: '>=12'}
dependencies:
- semver: 7.3.8
+ semver: 7.5.4
dev: true
/semver@5.7.1:
@@ -30103,16 +30110,16 @@ packages:
hasBin: true
dev: true
- /semver@7.3.7:
- resolution: {integrity: sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==}
+ /semver@7.3.8:
+ resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==}
engines: {node: '>=10'}
hasBin: true
dependencies:
lru-cache: 6.0.0
dev: true
- /semver@7.3.8:
- resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==}
+ /semver@7.5.4:
+ resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==}
engines: {node: '>=10'}
hasBin: true
dependencies:
@@ -31364,7 +31371,7 @@ packages:
mime: 2.6.0
qs: 6.11.1
readable-stream: 3.6.1
- semver: 7.3.8
+ semver: 7.5.4
transitivePeerDependencies:
- supports-color
dev: true
@@ -32219,7 +32226,7 @@ packages:
json5: 2.2.1
lodash.memoize: 4.1.2
make-error: 1.3.6
- semver: 7.3.7
+ semver: 7.5.4
typescript: 4.9.4
yargs-parser: 20.2.9
dev: true
@@ -32255,7 +32262,7 @@ packages:
json5: 2.2.1
lodash.memoize: 4.1.2
make-error: 1.3.6
- semver: 7.3.7
+ semver: 7.5.4
typescript: 4.9.4
yargs-parser: 20.2.9
dev: true
@@ -32291,7 +32298,7 @@ packages:
json5: 2.2.1
lodash.memoize: 4.1.2
make-error: 1.3.6
- semver: 7.3.7
+ semver: 7.5.4
typescript: 4.9.4
yargs-parser: 20.2.9
dev: true
@@ -32327,7 +32334,7 @@ packages:
json5: 2.2.1
lodash.memoize: 4.1.2
make-error: 1.3.6
- semver: 7.3.7
+ semver: 7.5.4
typescript: 4.9.4
yargs-parser: 20.2.9
dev: true
@@ -32958,7 +32965,7 @@ packages:
is-yarn-global: 0.3.0
latest-version: 5.1.0
pupa: 2.1.1
- semver: 7.3.8
+ semver: 7.5.4
semver-diff: 3.1.1
xdg-basedir: 4.0.0
dev: false
@@ -32978,7 +32985,7 @@ packages:
is-yarn-global: 0.4.1
latest-version: 7.0.0
pupa: 3.1.0
- semver: 7.3.8
+ semver: 7.5.4
semver-diff: 4.0.0
xdg-basedir: 5.1.0
dev: true