Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce bundle size for widget room configs #985

Merged
merged 6 commits into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/987.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Reduce bundle size of widget.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
},
"devDependencies": {
"@codemirror/lang-javascript": "^6.0.2",
"@fontsource/inter": "^5.1.0",
"@napi-rs/cli": "^2.13.2",
"@preact/preset-vite": "^2.2.0",
"@rollup/plugin-alias": "^5.1.0",
Expand Down
28 changes: 10 additions & 18 deletions web/components/RoomConfigView.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
import { lazy, Suspense } from "preact/compat"
import { useState } from "preact/hooks"
import { BridgeConfig, EmbedType } from "../BridgeAPI";
import style from "./RoomConfigView.module.scss";
import { ConnectionCard } from "./ConnectionCard";
import { FeedsConfig } from "./roomConfig/FeedsConfig";
import { GenericWebhookConfig } from "./roomConfig/GenericWebhookConfig";
import { OutboundWebhookConfig } from "./roomConfig/OutboundWebhookConfig";
import { GithubRepoConfig } from "./roomConfig/GithubRepoConfig";
import { GitlabRepoConfig } from "./roomConfig/GitlabRepoConfig";
import { JiraProjectConfig } from "./roomConfig/JiraProjectConfig";

import FeedsIcon from "../icons/feeds.png";
import GitHubIcon from "../icons/github.png";
import GitLabIcon from "../icons/gitlab.png";
Expand Down Expand Up @@ -46,40 +40,40 @@ const connections: Record<ConnectionType, IConnectionProps> = {
displayName: "RSS/Atom Feeds",
description: "Subscribe to an RSS/Atom feed",
icon: FeedsIcon,
component: FeedsConfig,
component: lazy(() => import("./roomConfig/FeedsConfig")),
},
[ConnectionType.Github]: {
displayName: 'Github',
description: "Connect the room to a GitHub project",
icon: GitHubIcon,
darkIcon: true,
component: GithubRepoConfig,
component: lazy(() => import("./roomConfig/GithubRepoConfig")),
},
[ConnectionType.Gitlab]: {
displayName: 'Gitlab',
description: "Connect the room to a GitLab project",
icon: GitLabIcon,
component: GitlabRepoConfig,
component: lazy(() => import("./roomConfig/GitlabRepoConfig")),
},
[ConnectionType.Jira]: {
displayName: 'JIRA',
description: "Connect the room to a JIRA project",
icon: JiraIcon,
component: JiraProjectConfig,
component: lazy(() => import("./roomConfig/JiraProjectConfig")),
},
[ConnectionType.Generic]: {
displayName: 'Inbound (Generic) Webhook',
description: "Create a webhook which can be used to connect any service to Matrix",
icon: WebhookIcon,
darkIcon: true,
component: GenericWebhookConfig,
component: lazy(() => import("./roomConfig/GenericWebhookConfig")),
},
[ConnectionType.GenericOutbound]: {
displayName: 'Outbound Webhook',
description: "Create a webhook which can be used to connect any service to Matrix",
icon: WebhookIcon,
darkIcon: true,
component: OutboundWebhookConfig,
component: lazy(() => import("./roomConfig/OutboundWebhookConfig")),
},
};

Expand All @@ -91,10 +85,9 @@ export default function RoomConfigView(props: IProps) {

if (activeConnectionType) {
const ConfigComponent = connections[activeConnectionType].component;
content = <ConfigComponent
roomId={props.roomId}
showHeader={props.embedType !== EmbedType.IntegrationManager}
/>;
content = <Suspense fallback="loading">
<ConfigComponent roomId={props.roomId} showHeader={props.embedType !== EmbedType.IntegrationManager} />
</Suspense>;
} else {
content = <>
<section>
Expand All @@ -115,7 +108,6 @@ export default function RoomConfigView(props: IProps) {
}

return <div className={style.root}>

{!serviceScope && activeConnectionType &&
<header>
<span className={style.backButton} onClick={() => setActiveConnectionType(null)}>
Expand Down
5 changes: 3 additions & 2 deletions web/components/roomConfig/FeedsConfig.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,7 @@ const roomConfigText: IRoomConfigText = {

const RoomConfigListItemFunc = (c: FeedResponseItem) => c.config.label || c.config.url;

export const FeedsConfig: BridgeConfig = ({ roomId, showHeader }) => {

const FeedsConfig: BridgeConfig = ({ roomId, showHeader }) => {
return <RoomConfig<ServiceConfig, FeedResponseItem, FeedConnectionState>
headerImg={FeedsIcon}
showHeader={showHeader}
Expand All @@ -105,3 +104,5 @@ export const FeedsConfig: BridgeConfig = ({ roomId, showHeader }) => {
connectionConfigComponent={ConnectionConfiguration}
/>;
};

export default FeedsConfig;
73 changes: 46 additions & 27 deletions web/components/roomConfig/GenericWebhookConfig.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { FunctionComponent, createRef } from "preact";
import { useCallback, useEffect, useState } from "preact/hooks"
import CodeMirror from '@uiw/react-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { add, format } from "date-fns";
import { BridgeConfig } from "../../BridgeAPI";
import type { GenericHookConnectionState, GenericHookResponseItem, GenericHookServiceConfig } from "../../../src/Connections/GenericHook";
Expand All @@ -10,6 +8,12 @@ import { InputField, ButtonSet, Button } from "../elements";
import WebhookIcon from "../../icons/webhook.png";
import { Alert, ToggleInput } from "@vector-im/compound-web";
import { InfoIcon, WarningIcon } from "@vector-im/compound-design-tokens/assets/web/icons"
import { lazy, Suspense } from "preact/compat";
import { LoadingSpinner } from "../elements/LoadingSpinner";
import { Extension } from "@uiw/react-codemirror";


const CodeMirror = lazy(() => import("@uiw/react-codemirror"));

const EXAMPLE_SCRIPT = `if (data.counter === undefined) {
result = {
Expand All @@ -29,10 +33,46 @@ const EXAMPLE_SCRIPT = `if (data.counter === undefined) {
}`;

const DOCUMENTATION_LINK = "https://matrix-org.github.io/matrix-hookshot/latest/setup/webhooks.html#script-api";
const CODE_MIRROR_EXTENSIONS = [javascript({})];

const EXPIRY_WARN_AT_MS = 3 * 24 * 60 * 60 * 1000;

const CodeEditor: FunctionComponent<{value: string, onChange: (value: string) => void}> = ({value, onChange}) => {
const [codeMirrorTheme, setCodeMirrorTheme] = useState<"light"|"dark">("light");
const [extensions, setExtensions] = useState<Extension[]>();
useEffect(() => {
const mm = window.matchMedia('(prefers-color-scheme: dark)');
const fn = (event: MediaQueryListEvent) => {
setCodeMirrorTheme(event.matches ? "dark" : "light");
};
mm.addEventListener('change', fn);
setCodeMirrorTheme(mm.matches ? "dark" : "light");
return () => mm.removeEventListener('change', fn);
}, []);

useEffect(() => {
async function loader() {
const { javascript } = await import("@codemirror/lang-javascript");
setExtensions([javascript({ jsx: false, typescript: false})]);
console.log('Extensions loaded');
}
void loader();
}, []);

if (!extensions) {
return <LoadingSpinner />;
}

return <Suspense fallback={<LoadingSpinner />}>
<CodeMirror
value={value}
theme={codeMirrorTheme}
extensions={extensions}
onChange={onChange}
/>
<p> See the <a target="_blank" rel="noopener noreferrer" href={DOCUMENTATION_LINK}>documentation</a> for help writing transformation functions </p>
</Suspense>;
};

const ConnectionConfiguration: FunctionComponent<ConnectionConfigurationProps<GenericHookServiceConfig, GenericHookResponseItem, GenericHookConnectionState>> = ({serviceConfig, existingConnection, onSave, onRemove, isUpdating}) => {
const [transFn, setTransFn] = useState<string>(existingConnection?.config.transformationFunction as string || EXAMPLE_SCRIPT);
const [transFnEnabled, setTransFnEnabled] = useState(serviceConfig.allowJsTransformationFunctions && !!existingConnection?.config.transformationFunction);
Expand All @@ -58,21 +98,6 @@ const ConnectionConfiguration: FunctionComponent<ConnectionConfigurationProps<Ge
});
}, [expiryRef, canEdit, onSave, nameRef, transFn, existingConnection, transFnEnabled, waitForComplete]);

const [codeMirrorTheme, setCodeMirrorTheme] = useState<"light"|"dark">("light");
useEffect(() => {
if (!transFnEnabled) {
return;
}
const mm = window.matchMedia('(prefers-color-scheme: dark)');
const fn = (event: MediaQueryListEvent) => {
setCodeMirrorTheme(event.matches ? "dark" : "light");
};
mm.addEventListener('change', fn);
setCodeMirrorTheme(mm.matches ? "dark" : "light");
return () => mm.removeEventListener('change', fn);
}, [transFnEnabled]);


const hasExpired = existingConnection?.secrets?.timeRemainingMs ? existingConnection?.secrets?.timeRemainingMs <= 0 : false;
const willExpireSoon = !hasExpired && existingConnection?.secrets?.timeRemainingMs ? existingConnection?.secrets?.timeRemainingMs <= EXPIRY_WARN_AT_MS : false;

Expand Down Expand Up @@ -123,15 +148,7 @@ const ConnectionConfiguration: FunctionComponent<ConnectionConfigurationProps<Ge
<InputField visible={serviceConfig.allowJsTransformationFunctions && transFnEnabled} label="Respond after function completes" noPadding={true}>
<ToggleInput disabled={!canEdit || serviceConfig.waitForComplete} type="checkbox" checked={waitForComplete || serviceConfig.waitForComplete} onChange={useCallback(() => setWaitForComplete(v => !v), [])} />
</InputField>

{transFnEnabled && <><CodeMirror
value={transFn}
theme={codeMirrorTheme}
extensions={CODE_MIRROR_EXTENSIONS}
onChange={setTransFn}
/>
<p> See the <a target="_blank" rel="noopener noreferrer" href={DOCUMENTATION_LINK}>documentation</a> for help writing transformation functions </p>
</>}
{transFnEnabled && <CodeEditor value={transFn} onChange={setTransFn} />}
<ButtonSet>
{ canEdit && <Button disabled={isUpdating} type="submit">{ existingConnection ? "Save" : "Add Webhook" }</Button>}
{ canEdit && existingConnection && <Button disabled={isUpdating} intent="remove" onClick={onRemove}>Remove Webhook</Button>}
Expand Down Expand Up @@ -173,3 +190,5 @@ export const GenericWebhookConfig: BridgeConfig = ({ roomId, showHeader }) => {
connectionConfigComponent={ConnectionConfiguration}
/>;
};

export default GenericWebhookConfig;
4 changes: 3 additions & 1 deletion web/components/roomConfig/GithubRepoConfig.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ const roomConfigText: IRoomConfigText = {

const RoomConfigListItemFunc = (c: GitHubRepoResponseItem) => getRepoFullName(c.config);

export const GithubRepoConfig: BridgeConfig = ({ roomId, showHeader }) => {
const GithubRepoConfig: BridgeConfig = ({ roomId, showHeader }) => {
return <RoomConfig<never, GitHubRepoResponseItem, GitHubRepoConnectionState>
headerImg={GitHubIcon}
darkHeaderImg={true}
Expand All @@ -191,3 +191,5 @@ export const GithubRepoConfig: BridgeConfig = ({ roomId, showHeader }) => {
connectionConfigComponent={ConnectionConfiguration}
/>;
};

export default GithubRepoConfig;
4 changes: 3 additions & 1 deletion web/components/roomConfig/GitlabRepoConfig.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ const RoomConfigText = {

const RoomConfigListItemFunc = (c: GitLabRepoResponseItem) => c.config.path;

export const GitlabRepoConfig: BridgeConfig = ({ roomId, showHeader }) => {
const GitlabRepoConfig: BridgeConfig = ({ roomId, showHeader }) => {
return <RoomConfig<never, GitLabRepoResponseItem, GitLabRepoConnectionState>
headerImg={GitLabIcon}
showHeader={showHeader}
Expand All @@ -138,3 +138,5 @@ export const GitlabRepoConfig: BridgeConfig = ({ roomId, showHeader }) => {
connectionConfigComponent={ConnectionConfiguration}
/>;
};

export default GitlabRepoConfig;
4 changes: 3 additions & 1 deletion web/components/roomConfig/JiraProjectConfig.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ const RoomConfigText = {

const RoomConfigListItemFunc = (c: JiraProjectResponseItem) => c.config.url;

export const JiraProjectConfig: BridgeConfig = ({ roomId, showHeader }) => {
const JiraProjectConfig: BridgeConfig = ({ roomId, showHeader }) => {
return <RoomConfig<never, JiraProjectResponseItem, JiraProjectConnectionState>
headerImg={JiraIcon}
showHeader={showHeader}
Expand All @@ -122,3 +122,5 @@ export const JiraProjectConfig: BridgeConfig = ({ roomId, showHeader }) => {
connectionConfigComponent={ConnectionConfiguration}
/>;
};

export default JiraProjectConfig;
4 changes: 3 additions & 1 deletion web/components/roomConfig/OutboundWebhookConfig.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ const RoomConfigText = {

const RoomConfigListItemFunc = (c: OutboundHookResponseItem) => c.config.name;

export const OutboundWebhookConfig: BridgeConfig = ({ roomId, showHeader }) => {
const OutboundWebhookConfig: BridgeConfig = ({ roomId, showHeader }) => {
return <RoomConfig<ServiceConfig, OutboundHookResponseItem, OutboundHookConnectionState>
headerImg={WebhookIcon}
darkHeaderImg={true}
Expand All @@ -83,3 +83,5 @@ export const OutboundWebhookConfig: BridgeConfig = ({ roomId, showHeader }) => {
connectionConfigComponent={ConnectionConfiguration}
/>;
};

export default OutboundWebhookConfig;
Binary file removed web/fonts/Inter/Inter-Bold.woff
Binary file not shown.
Binary file removed web/fonts/Inter/Inter-Bold.woff2
Binary file not shown.
Binary file removed web/fonts/Inter/Inter-BoldItalic.woff
Binary file not shown.
Binary file removed web/fonts/Inter/Inter-BoldItalic.woff2
Binary file not shown.
Binary file removed web/fonts/Inter/Inter-Italic.woff
Binary file not shown.
Binary file removed web/fonts/Inter/Inter-Italic.woff2
Binary file not shown.
Binary file removed web/fonts/Inter/Inter-Medium.woff
Binary file not shown.
Binary file removed web/fonts/Inter/Inter-Medium.woff2
Binary file not shown.
Binary file removed web/fonts/Inter/Inter-MediumItalic.woff
Binary file not shown.
Binary file removed web/fonts/Inter/Inter-MediumItalic.woff2
Binary file not shown.
Binary file removed web/fonts/Inter/Inter-Regular.woff
Binary file not shown.
Binary file removed web/fonts/Inter/Inter-Regular.woff2
Binary file not shown.
Binary file removed web/fonts/Inter/Inter-SemiBold.woff
Binary file not shown.
Binary file removed web/fonts/Inter/Inter-SemiBold.woff2
Binary file not shown.
Binary file removed web/fonts/Inter/Inter-SemiBoldItalic.woff
Binary file not shown.
Binary file removed web/fonts/Inter/Inter-SemiBoldItalic.woff2
Binary file not shown.
93 changes: 0 additions & 93 deletions web/fonts/OFL.txt

This file was deleted.

Loading
Loading