Skip to content

Commit

Permalink
feat(web): UI扩展支持修改页面标题 (#1389)
Browse files Browse the repository at this point in the history
UI 扩展页面支持修改标题。详情看文档
  • Loading branch information
ddadaal authored Aug 10, 2024
1 parent ddd77bb commit acb1992
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 8 deletions.
6 changes: 6 additions & 0 deletions .changeset/giant-drinks-remain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@scow/lib-web": patch
"@scow/docs": patch
---

UI 扩展页面支持修改标题
25 changes: 21 additions & 4 deletions docs/docs/integration/ui-extension/develop.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,15 @@ SCOW在调用接口时,会将[上下文参数](#上下文参数)作为查询

- 当右上角导航栏链接数量**大于等于5个**,或者屏幕宽度小于**768px**时,所有导航栏链接将会仅显示图标。

## 注意事项
## 扩展消息

### 通过发送消息控制扩展页面的高度
UI扩展可以通过**消息**`postMessage()`, [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage))与SCOW交互。下列为SCOW支持的所有类型的消息以及使用场景介绍。

### `scow.extensionPageHeightChanged`: 控制扩展页面的高度

您的扩展页面将会通过一个`iframe`组件嵌入到SCOW的页面中。由于浏览器的限制,SCOW无法自动根据您网页的高度调整SCOW页面承载您的页面的高度,在默认情况下,您的页面在SCOW中会出现滚动条,影响用户体验。

为了解决这个问题,SCOW需要您在您的页面中,通过给父页面发送消息(`postMessage()`, [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage))的方式,在您的页面高度变化时,将您的页面的高度报告给SCOW。
为了解决这个问题,您需要在您的页面高度变化时,将您的页面的高度报告给SCOW。

具体来说,当SCOW接手到由`iframe`发出的如下格式的消息时,SCOW将会修改`iframe`组件的高度为`payload.height`的值,单位为px。

Expand Down Expand Up @@ -226,7 +228,22 @@ export const RootLayout = () => {

您可以参考此PR[PKUHPC/scow-ui-extension-demo#2](https://github.com/PKUHPC/scow-ui-extension-demo/pull/2)实现。

### 其他注意事项
### `scow.extensionPageTitleChanged`: 修改扩展页面标题

您可以向SCOW发送以下格式的消息以修改扩展页面的标题。最终标题为`${payload.title} - scow`

```json
{
"type": "scow.extensionPageTitleChanged",
"payload": {
"title": "新的标题"
}
}
```

UI扩展实现参考: https://github.com/PKUHPC/scow-ui-extension-demo/commit/cf20685085889422818055513b238d31b815dc79

## 其他注意事项

- UI扩展示例项目:[PKUHPC/scow-ui-extension-demo](https://github.com/PKUHPC/scow-ui-extension-demo)
- 如果您的扩展站和SCOW部署地址非同源,请注意使得您的扩展站的所有路径均支持CORS访问。
Expand Down
25 changes: 21 additions & 4 deletions libs/web/src/extensions/ExtensionPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { joinWithUrl } from "@scow/utils";
import { useRouter } from "next/router";
import React, { useEffect, useRef } from "react";
import { Head } from "src/components/head";
import { extensionEvents } from "src/extensions/events";
import { ExtensionManifestWithUrl, UiExtensionStoreData } from "src/extensions/UiExtensionStore";
import { UserInfo } from "src/layouts/base/types";
import { useDarkMode } from "src/layouts/darkMode";
Expand Down Expand Up @@ -74,6 +75,8 @@ export const ExtensionPage: React.FC<Props> = ({
return <NotFoundPageComponent />;
}

const [title, setTitle] = React.useState(config?.name ?? "Extension");

const darkMode = useDarkMode();

const query = new URLSearchParams(
Expand All @@ -93,12 +96,26 @@ export const ExtensionPage: React.FC<Props> = ({

const ref = useRef<HTMLIFrameElement>(null);

// 监听来自iframe内部网页发送的信息,设置iframe的height
useEffect(() => {
const messageHandler = (e: MessageEvent<any>) => {

if (e.data.type === "scow.extensionPageHeightChanged" && ref.current) {
ref.current.style.height = e.data.payload.height + "px";
if (!ref.current) {
return;
}

const event = extensionEvents.safeParse(e.data);

if (!event.success) {
console.log("SCOW received an invalid event from extension page. event: %s", JSON.stringify(e.data));
return;
}

const data = event.data;

if (data.type === "scow.extensionPageHeightChanged") {
ref.current.style.height = data.payload.height + "px";
} else if (data.type === "scow.extensionPageTitleChanged") {
setTitle(data.payload.title);
}
};
window.addEventListener("message", messageHandler, false);
Expand All @@ -110,7 +127,7 @@ export const ExtensionPage: React.FC<Props> = ({

return (
<>
<Head title={config?.name ?? "Extension"} />
<Head title={title} />
<FrameContainer>
<IFrame
ref={ref}
Expand Down
22 changes: 22 additions & 0 deletions libs/web/src/extensions/events.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* Copyright (c) 2022 Peking University and Peking University Institute for Computing and Digital Economy
* SCOW is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/

import { z } from "zod";

export const extensionEvents = z.discriminatedUnion("type", [
z.object({ type: z.literal("scow.extensionPageHeightChanged"), payload: z.object({ height: z.number() }) }),
z.object({ type: z.literal("scow.extensionPageTitleChanged"), payload: z.object({ title: z.string() }) }),
z.object({ type: z.literal("scow.reloadNavbarLink"), payload: z.object({}) }),
z.object({ type: z.literal("scow.reloadNavigations"), payload: z.object({}) }),
]);


0 comments on commit acb1992

Please sign in to comment.