Skip to content

Commit

Permalink
[feat] add sample add-on with Vite 6
Browse files Browse the repository at this point in the history
  • Loading branch information
teddyward committed Dec 9, 2024
1 parent e54c94c commit 6045d77
Show file tree
Hide file tree
Showing 11 changed files with 1,666 additions and 56 deletions.
5 changes: 5 additions & 0 deletions addons-web-sdk/samples/hello-world-react-ts-vite/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# React TypeScript example

This "hello, world!" add-on is built using React, TypeScript, and [Vite](https://vite.dev/) in order to show how a React app can be deployed as a static site to be used as an add-on. It is very similar to the sample at <https://github.com/googleworkspace/meet/tree/main/addons-web-sdk/samples/hello-world>, but the basic structure is a multi-page React app. Please see our other [samples](https://github.com/googleworkspace/meet/tree/main/addons-web-sdk/samples) to learn more advanced functionality!

This add-on is deployed with GitHub pages, so that you can view the live versions of its [Side Panel](https://googleworkspace.github.io/meet/hello-world-react-ts-vite/sidepanel) and [Main Stage](https://googleworkspace.github.io/meet/hello-world-react-ts-vite/mainstage).
26 changes: 26 additions & 0 deletions addons-web-sdk/samples/hello-world-react-ts-vite/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "hello-world-react-ts-vite",
"description": "This add-on is built using React and TypeScript in order to show how a React app can be modified to work as an add-on.",
"keywords": [
"Google Meet"
],
"author": "teddyward",
"license": "Apache-2.0",
"scripts": {
"start": "vite",
"build": "npm install && vite build",
"preview": "vite preview"
},
"dependencies": {
"@googleworkspace/meet-addons": "^1.1.1",
"react": "^18",
"react-dom": "^18"
},
"devDependencies": {
"@types/react": "^18",
"@types/react-dom": "^18",
"@vitejs/plugin-react": "^4.3.4",
"typescript": "^5",
"vite": "^6"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<!-- See: https://developers.google.com/meet/add-ons/guides/overview#main-stage -->
<head>
<title>Meet Add-on Main Stage in Vite-React-TS</title>
</head>

<body>
<div id="root"></div>
<script type="module" src="/mainStage.tsx"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<!-- See: https://developers.google.com/meet/add-ons/guides/overview#side-panel -->
<head>
<title>Meet Add-on Side Panel in Vite-React-TS</title>
</head>

<body>
<div id="root"></div>
<script type="module" src="/sidePanel.tsx"></script>
</body>
</html>
17 changes: 17 additions & 0 deletions addons-web-sdk/samples/hello-world-react-ts-vite/src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

export const CLOUD_PROJECT_NUMBER: string = '989911054302';
export const MAIN_STAGE_URL: string =
'https://googleworkspace.github.io/meet/hello-world-react-ts-vite/mainstage';
39 changes: 39 additions & 0 deletions addons-web-sdk/samples/hello-world-react-ts-vite/src/mainStage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { useEffect } from 'react';
import { meet } from '@googleworkspace/meet-addons/meet.addons';
import { CLOUD_PROJECT_NUMBER } from './constants';

/**
* See: https://developers.google.com/meet/add-ons/guides/overview#main-stage
*/
function MainStage() {
/**
* Prepares the Add-on Main Stage Client, which signals that the add-on has
* successfully launched in the main stage.
*/
useEffect(() => {
(async () => {
const session = await meet.addon.createAddonSession({
cloudProjectNumber: CLOUD_PROJECT_NUMBER,
});
await session.createMainStageClient();
})();
}, []);

return (
<>
<div>
This is the Add-on Main Stage. Everyone in the call can see this.
</div>
<div>Hello, world!</div>
</>
);
}

// Renders the MainStage as a React component.
createRoot(document.getElementById('root')!).render(
<StrictMode>
<MainStage />
</StrictMode>
);
49 changes: 49 additions & 0 deletions addons-web-sdk/samples/hello-world-react-ts-vite/src/sidePanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { StrictMode } from 'react';
import { useEffect, useState } from 'react';
import {
meet,
MeetSidePanelClient,
} from '@googleworkspace/meet-addons/meet.addons';
import { CLOUD_PROJECT_NUMBER, MAIN_STAGE_URL } from './constants';
import { createRoot } from 'react-dom/client';

/**
* See: https://developers.google.com/meet/add-ons/guides/overview#side-panel
*/
function SidePanel() {
const [sidePanelClient, setSidePanelClient] = useState<MeetSidePanelClient>();

// Launches the main stage when the main button is clicked.
async function startActivity(e) {
if (!sidePanelClient) {
throw new Error('Side Panel is not yet initialized!');
}
await sidePanelClient.startActivity({ mainStageUrl: MAIN_STAGE_URL });
}

/**
* Prepares the Add-on Side Panel Client.
*/
useEffect(() => {
(async () => {
const session = await meet.addon.createAddonSession({
cloudProjectNumber: CLOUD_PROJECT_NUMBER,
});
setSidePanelClient(await session.createSidePanelClient());
})();
}, []);

return (
<>
<div>This is the Add-on Side Panel. Only you can see this.</div>
<button onClick={startActivity}>Launch Activity in Main Stage.</button>
</>
);
}

// Renders the SidePanel as a React component.
createRoot(document.getElementById('root')!).render(
<StrictMode>
<SidePanel />
</StrictMode>
);
14 changes: 14 additions & 0 deletions addons-web-sdk/samples/hello-world-react-ts-vite/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"compilerOptions": {
"allowImportingTsExtensions": true,
"isolatedModules": true,
"jsx": "react-jsx",
"lib": ["ES2023", "DOM"],
"module": "ESNext",
"moduleResolution": "bundler",
"moduleDetection": "force",
"noEmit": true,
"target": "ES2023"
},
"include": ["src"]
}
43 changes: 43 additions & 0 deletions addons-web-sdk/samples/hello-world-react-ts-vite/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import { resolve } from 'path';
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

import { fileURLToPath } from 'node:url';
const externalId = fileURLToPath(
new URL(
'node_modules/@googleworkspace/meet-addons/meet.addons.js',
import.meta.url
)
);
console.log(externalId);

// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
base: '/meet/hello-world-react-ts-vite',
root: 'src',
build: {
outDir: '../../dist/hello-world-react-ts-vite',
emptyOutDir: true,
rollupOptions: {
input: {
main: resolve(__dirname, 'src/SidePanel.html'),
mainStage: resolve(__dirname, 'src/MainStage.html'),
},
},
},
});
Loading

0 comments on commit 6045d77

Please sign in to comment.