From ca2a2f161e849e1dde2b8beea6e5f8c368806275 Mon Sep 17 00:00:00 2001 From: yijie4188 Date: Tue, 15 Aug 2023 21:22:44 +0800 Subject: [PATCH] feat(core): abstract messenger to support message display function --- core/src/index.ts | 1 + core/src/messenger-provider.ts | 36 ++++++++++++++++++++++++++++++++++ core/src/plugins/urlCache.tsx | 5 ++++- src/App.tsx | 20 ++++++------------- src/main.tsx | 15 ++++++++++++++ 5 files changed, 62 insertions(+), 15 deletions(-) create mode 100644 core/src/messenger-provider.ts diff --git a/core/src/index.ts b/core/src/index.ts index 44a022e1..6c91c63f 100644 --- a/core/src/index.ts +++ b/core/src/index.ts @@ -3,5 +3,6 @@ export { } from './components/EditorZone' export * from './components/QuickAccess' export * from './eval-logs/bridge' +export * from './messenger-provider.ts' export * from './plugins' export * from './utils' diff --git a/core/src/messenger-provider.ts b/core/src/messenger-provider.ts new file mode 100644 index 00000000..db2b2d82 --- /dev/null +++ b/core/src/messenger-provider.ts @@ -0,0 +1,36 @@ +export interface Messenger { + display( + type: + | 'success' + | 'info' + | 'warning' + | 'error', + message: React.ReactNode, + options?: { + duration?: number + closable?: boolean + position?: + | 'top-center' + | 'top-right' + | 'bottom-center' + | 'bottom-right' + } + ): void +} + +let instance: Messenger | null = null + +let messengerPromiseResolve: (messenger: Messenger) => void + +export const messenger: Promise = new Promise((resolve) => { + if (instance) { + resolve(instance) + } else { + messengerPromiseResolve = resolve + } +}) + +export function provideMessenger(messenger: Messenger) { + instance = messenger + messengerPromiseResolve(messenger) +} diff --git a/core/src/plugins/urlCache.tsx b/core/src/plugins/urlCache.tsx index 06c8846b..0a3edb3b 100644 --- a/core/src/plugins/urlCache.tsx +++ b/core/src/plugins/urlCache.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react' -import { copyToClipboard, definePlugin } from '@power-playground/core' +import { copyToClipboard, definePlugin, messenger } from '@power-playground/core' import { setCodeHistory } from '../components/bottom-status/historyStore' @@ -29,6 +29,9 @@ export default definePlugin({ const code = editor.getValue() history.pushState(null, '', '#' + btoa(encodeURIComponent(code))) copyToClipboard(location.href) + messenger.then(m => m.display( + 'success', 'Saved to clipboard, you can share it to your friends!' + )) editor.focus() setCodeHistory(old => old.concat({ code, time: Date.now() })) }) diff --git a/src/App.tsx b/src/App.tsx index e903156a..c86b6abc 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,16 +1,13 @@ // noinspection ES6ConvertVarToLetConst import './App.scss' -// eslint-disable-next-line @typescript-eslint/no-restricted-imports -import 'react-toastify/dist/ReactToastify.css' import { useEffect, useMemo, useState } from 'react' -import { toast, ToastContainer } from 'react-toastify' import type { Plugin } from '@power-playground/core' import { createQuickAccessInstance, EditorZone, - elBridgeP, + elBridgeP, messenger, QuickAccess, QuickAccessContext, registerPluginConfigures } from '@power-playground/core' @@ -75,7 +72,6 @@ export function App() { const [displayHeader, setDisplayHeader] = useState(true) return ( <> -

{ setDisplayHeader(false) - toast(<>Press Esc to show the header again, { - type: 'info', - position: 'bottom-right', - autoClose: 3000, - hideProgressBar: true, - closeOnClick: true, - pauseOnHover: true, - draggable: true - }) + messenger.then(m => m.display( + 'info', <>Press Esc to show the header again, { + position: 'top-center' + } + )) document.addEventListener('keydown', function onEsc(e: KeyboardEvent) { if (e.key === 'Escape') { setDisplayHeader(true) diff --git a/src/main.tsx b/src/main.tsx index 94be93dc..7f77a380 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,9 +1,13 @@ // noinspection JSNonASCIINames import './main.scss' +// eslint-disable-next-line @typescript-eslint/no-restricted-imports +import 'react-toastify/dist/ReactToastify.css' import React from 'react' import ReactDOM from 'react-dom/client' +import { toast, ToastContainer } from 'react-toastify' +import { provideMessenger } from '@power-playground/core' import { App } from './App.tsx' @@ -34,8 +38,19 @@ Object.defineProperty(window, '小黑子', { } }) +provideMessenger({ + display(type, message, opts) { + toast[type](message, { + position: opts?.position ?? 'bottom-right', + autoClose: opts?.duration ?? 3000, + closeButton: opts?.closable ?? true + }) + } +}) + ReactDOM.createRoot(document.getElementById('root')!).render( + )