-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add sample with some more features using Next JS (React + TS) (#18
) * feat: Add sample with some more features using Next JS (React + TS) * fix: update CPN to published version * fix: respond to review feedback + prettier * test: verify that deployment from this branch still works as expected * fix: add licenses and rm branch-specific deployment * docs: update root README to reference new sample * fix: redeploy with terms, privacy, and support at site root * fix: license and stop publishing
- Loading branch information
Showing
27 changed files
with
689 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
# Build outputs for sample Meet Add-ons | ||
**/dist | ||
**/dist/*/ | ||
**/node_modules | ||
**/.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
NEXT_PUBLIC_DEBUG=1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# next.js | ||
/.next | ||
out | ||
|
||
certificates |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Pretty Colors: Next.js Add-on | ||
|
||
This is a [Meet Add-on](https://developers.google.com/meet/add-ons/guides/overview) built in [Next.js](https://nextjs.org/). This add-on displays an animation that is intended to create a simple "shimmer" effect based on the color that each call participant selects. This add-on only exists to show more features of Google Meet Add-ons than can be found at [googleworkspace/meet/addons-web-sdk/samples/hello-world-next-js](https://github.com/googleworkspace/meet/tree/main/addons-web-sdk/samples/hello-world-next-js). If you find anything about the configuration confusing, please see that more basic example. | ||
|
||
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/animation-next-js/sidepanel), [Main Stage](https://googleworkspace.github.io/meet/animation-next-js/mainstage), and all other routes. The screensharing promotion at the [index.html](https://googleworkspace.github.io/meet/animation-next-js/) will not fully work |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// 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. | ||
|
||
/// <reference types="next" /> | ||
/// <reference types="next/image-types/global" /> | ||
|
||
// NOTE: This file should not be edited | ||
// see https://nextjs.org/docs/basic-features/typescript for more information. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/** @type {import('next').NextConfig} */ | ||
const nextConfig = { | ||
basePath: '/meet/animation-next-js', | ||
distDir: '../dist/animation-next-js', | ||
output: 'export', | ||
}; | ||
|
||
export default nextConfig; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
{ | ||
"name": "animation-next-js", | ||
"version": "0.1.0", | ||
"private": true, | ||
"scripts": { | ||
"dev": "next dev --experimental-https", | ||
"build": "next build", | ||
"start": "next start", | ||
"lint": "next lint" | ||
}, | ||
"dependencies": { | ||
"@googleworkspace/meet-addons": "^0.12.0", | ||
"next": "14.2.7", | ||
"react": "^18", | ||
"react-dom": "^18" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^20", | ||
"@types/react": "^18", | ||
"@types/react-dom": "^18", | ||
"typescript": "^5" | ||
} | ||
} |
59 changes: 59 additions & 0 deletions
59
addons-web-sdk/samples/animation-next-js/src/app/activitysidepanel/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
'use client'; | ||
|
||
import { useEffect, useState } from 'react'; | ||
import { | ||
meet, | ||
MeetSidePanelClient, | ||
} from '@googleworkspace/meet-addons/meet.addons'; | ||
import { CLOUD_PROJECT_NUMBER } from '../../shared/constants'; | ||
|
||
/** | ||
* This page displays in the Side Panel after the activity has started to allow | ||
* each call participant to modify the base color of the main stage animation. | ||
*/ | ||
export default function Page() { | ||
const [sidePanelClient, setSidePanelClient] = useState<MeetSidePanelClient>(); | ||
|
||
/** | ||
* Sends a newly chosen color to the main stage, using frame-to-frame | ||
* messaging. | ||
* @param newColor Hex code of the new color. | ||
*/ | ||
async function updateColor(newColor: string) { | ||
if (!sidePanelClient) { | ||
throw new Error('Side Panel is not yet initialized!'); | ||
} | ||
|
||
await sidePanelClient.notifyMainStage(newColor); | ||
} | ||
|
||
useEffect(() => { | ||
/** | ||
* Initializes the Add-on Side Panel Client. | ||
* https://developers.google.com/meet/add-ons/reference/websdk/addon_sdk.meetsidepanelclient | ||
*/ | ||
async function initializeSidePanelClient() { | ||
const session = await meet.addon.createAddonSession({ | ||
cloudProjectNumber: CLOUD_PROJECT_NUMBER, | ||
}); | ||
const client = await session.createSidePanelClient(); | ||
setSidePanelClient(client); | ||
} | ||
initializeSidePanelClient(); | ||
}, []); | ||
|
||
return ( | ||
<> | ||
<label htmlFor="pretty-color"> | ||
Change the color. Only you will see this: | ||
</label> | ||
<input | ||
type="color" | ||
id="pretty-color" | ||
name="pretty-color" | ||
defaultValue="#00ff00" | ||
onChange={(e) => updateColor(e.target.value)} | ||
/> | ||
</> | ||
); | ||
} |
18 changes: 18 additions & 0 deletions
18
addons-web-sdk/samples/animation-next-js/src/app/layout.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { type Metadata } from 'next'; | ||
|
||
export const metadata: Metadata = { | ||
title: 'Pretty Colors', | ||
description: 'Google Meet Add-on that shows an animation', | ||
}; | ||
|
||
export default function RootLayout({ | ||
children, | ||
}: { | ||
children: React.ReactNode; | ||
}) { | ||
return ( | ||
<html lang="en"> | ||
<body>{children}</body> | ||
</html> | ||
); | ||
} |
71 changes: 71 additions & 0 deletions
71
addons-web-sdk/samples/animation-next-js/src/app/mainstage/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
'use client'; | ||
|
||
import { useEffect, useState } from 'react'; | ||
import { | ||
meet, | ||
FrameToFrameMessage, | ||
MeetMainStageClient, | ||
} from '@googleworkspace/meet-addons/meet.addons'; | ||
import { CLOUD_PROJECT_NUMBER } from '../../shared/constants'; | ||
import PrettyColors from '@/components/prettyColors'; | ||
|
||
/** | ||
* @see {@link https://developers.google.com/meet/add-ons/guides/overview#main-stage} | ||
*/ | ||
export default function Page() { | ||
const [color, setColor] = useState('#00ff00'); | ||
|
||
/** | ||
* Creates a MeetMainStageClient to control the main stage of the add-on. | ||
* https://developers.google.com/meet/add-ons/reference/websdk/addon_sdk.meetmainstageclient | ||
*/ | ||
async function initializeMainStageClient(): Promise<MeetMainStageClient> { | ||
const session = await meet.addon.createAddonSession({ | ||
cloudProjectNumber: CLOUD_PROJECT_NUMBER, | ||
}); | ||
return await session.createMainStageClient(); | ||
} | ||
|
||
/** | ||
* Parses the collaboration starting state from the side panel, and updates | ||
* the color used for the main animation. | ||
*/ | ||
async function setStartingState(mainStageClient: MeetMainStageClient) { | ||
const startingState = await mainStageClient.getActivityStartingState(); | ||
const additionalData = JSON.parse(startingState.additionalData ?? '{}'); | ||
setColor(additionalData.startingColor); | ||
} | ||
|
||
/** | ||
* Listens for new frame-to-frame messages from the side panel that update | ||
* the color used for the main animation. | ||
*/ | ||
function awaitNewColor(mainStageClient: MeetMainStageClient) { | ||
mainStageClient.on( | ||
'frameToFrameMessage', | ||
(message: FrameToFrameMessage) => { | ||
setColor(message.payload); | ||
} | ||
); | ||
} | ||
|
||
useEffect(() => { | ||
/** | ||
* Initialize the main stage by initializing the client, then using that | ||
* client to get the starting state (color), and observe any new colors | ||
* passed from the Side Panel. | ||
*/ | ||
async function initializeMainStage() { | ||
const client = await initializeMainStageClient(); | ||
setStartingState(client); | ||
awaitNewColor(client); | ||
} | ||
initializeMainStage(); | ||
}, []); | ||
|
||
return ( | ||
<> | ||
<PrettyColors baseColor={color}></PrettyColors> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
'use client'; | ||
|
||
import { useEffect } from 'react'; | ||
import { meet } from '@googleworkspace/meet-addons/meet.addons.screenshare'; | ||
import { CLOUD_PROJECT_NUMBER, SIDE_PANEL_URL } from '../shared/constants'; | ||
|
||
export default function App() { | ||
/** | ||
* Screensharing this page will prompt you to install/open this add-on. | ||
* When it is opened, it will prompt you to set up the add-on in the side | ||
* panel before starting the activity for everyone. | ||
* @see {@link https://developers.google.com/meet/add-ons/guides/screen-sharing} | ||
*/ | ||
useEffect(() => { | ||
meet.addon.screensharing.exposeToMeetWhenScreensharing({ | ||
cloudProjectNumber: CLOUD_PROJECT_NUMBER, | ||
// Will open the Side Panel for the activity initiator to set the | ||
// activity starting state. Activity won't start for other participants. | ||
sidePanelUrl: SIDE_PANEL_URL, | ||
startActivityOnOpen: false, | ||
}); | ||
}, []); | ||
|
||
return ( | ||
<> | ||
<div>Screenshare this page to promote an add-on.</div> | ||
</> | ||
); | ||
} |
75 changes: 75 additions & 0 deletions
75
addons-web-sdk/samples/animation-next-js/src/app/sidepanel/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
'use client'; | ||
|
||
import { useEffect, useState } from 'react'; | ||
import { | ||
meet, | ||
MeetSidePanelClient, | ||
} from '@googleworkspace/meet-addons/meet.addons'; | ||
import { | ||
ACTIVITY_SIDE_PANEL_URL, | ||
CLOUD_PROJECT_NUMBER, | ||
MAIN_STAGE_URL, | ||
} from '../../shared/constants'; | ||
|
||
/** | ||
* @see {@link https://developers.google.com/meet/add-ons/guides/overview#side-panel} | ||
*/ | ||
export default function Page() { | ||
const [sidePanelClient, setSidePanelClient] = useState<MeetSidePanelClient>(); | ||
|
||
/** | ||
* Starts the add-on activity and passes the selected color to the Main Stage, | ||
* as part of the activity starting state. | ||
*/ | ||
async function startCollaboration(e: unknown) { | ||
if (!sidePanelClient) { | ||
throw new Error('Side Panel is not yet initialized!'); | ||
} | ||
|
||
const startingColor = ( | ||
document.getElementById('starting-color')! as HTMLInputElement | ||
).value; | ||
await sidePanelClient.startActivity({ | ||
mainStageUrl: MAIN_STAGE_URL, | ||
sidePanelUrl: ACTIVITY_SIDE_PANEL_URL, | ||
// Pass the selected color to customize the initial display. | ||
additionalData: `{\"startingColor\": \"${startingColor}\"}`, | ||
}); | ||
window.location.replace(ACTIVITY_SIDE_PANEL_URL + window.location.search); | ||
} | ||
|
||
useEffect(() => { | ||
/** | ||
* Initializes the Add-on Side Panel Client. | ||
* https://developers.google.com/meet/add-ons/reference/websdk/addon_sdk.meetsidepanelclient | ||
*/ | ||
async function initializeSidePanelClient() { | ||
const session = await meet.addon.createAddonSession({ | ||
cloudProjectNumber: CLOUD_PROJECT_NUMBER, | ||
}); | ||
const client = await session.createSidePanelClient(); | ||
setSidePanelClient(client); | ||
} | ||
initializeSidePanelClient(); | ||
}, []); | ||
|
||
return ( | ||
<> | ||
<div> | ||
Welcome to Pretty Colors! This is a contrived demo add-on that lets you | ||
look at an animation involving your favorite color. | ||
</div> | ||
<label htmlFor="starting-color"> | ||
Pick a color you like. Everyone will see this: | ||
</label> | ||
<input | ||
type="color" | ||
id="starting-color" | ||
name="starting-color" | ||
defaultValue="#00ff00" | ||
/> | ||
<br /> | ||
<button onClick={startCollaboration}>Start the animation!</button> | ||
</> | ||
); | ||
} |
Oops, something went wrong.