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

Added an example app to demonstrate the new Video Selection API, upgraded @canva/design to 1.9.0, and added the ability to filter by fontRefs in findFonts API #30

Merged
merged 1 commit into from
Jun 4, 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
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
# Changelog

## 2024-06-04

### 🧰 Added
- `examples`
- Added an example to demonstrate the new [Video Selection API](https://www.canva.dev/docs/apps/api/design-selection-register-on-change/) in `examples/video_replacement`.
- `@canva/preview/asset`
- Added the ability to filter by fontRefs in `findFonts` API.

### 🐞 Fixed
- `examples`
- Continue removing `dataUrl` usages in `examples/native_image_elements`.
- Fixed a number of instances of stale info in our `README.md` files.

### 🔧 Changed
- Update Hot Module Replacement warnings to a avoid using the HMR acronym.
- Pinned `nodemon` version to `3.0.1`.
- `@canva/design`
- Upgraded to version `1.9.0` which has the following changes:
- Added the ability to read/write video via the selection API.

## 2024-05-09

### 🧰 Added
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ Some examples have a backend. This backend is defined in the example's `backend/
To run examples that have a backend:

1. Navigate to the [Your apps](https://www.canva.com/developers/apps) page.
2. Copy the ID of an app from the **App ID** column.
2. Copy the ID of an app from the **App ID** column in the apps table.
3. In the starter kit's `.env` file, set `CANVA_APP_ID` to the ID of the app.

For example:
Expand Down
2 changes: 0 additions & 2 deletions examples/app_image_elements/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,6 @@ export const App = () => {
mimeType: "image/jpeg",
url: imageSrc,
thumbnailUrl: imageSrc,
width: 400,
height: 400,
});
images[state.imageId].imageRef = ref;
}
Expand Down
10 changes: 6 additions & 4 deletions examples/authentication/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
1. Get the ID of an app.
1. Log in to the [Developer Portal](https://www.canva.com/developers/).
2. Navigate to the [Your apps](https://www.canva.com/developers/apps) page.
3. Copy the ID of an app from the **App ID** column.
3. Copy the ID of an app from the **App ID** column in the Apps table.
2. Open the starter kit's `.env` file.
3. Set the `APP_ID` environment variable to the ID of the app.

Expand All @@ -17,16 +17,18 @@ You server needs to be exposed via a publicly available URL, so that Canva can s

To use ngrok, you'll need to do the following:

1. Sign up for a ngrok account at https://ngrok.com/.
2. Locate your ngrok [authtoken](https://dashboard.ngrok.com/get-started/your-authtoken).
1. Sign up for a ngrok account at <https://ngrok.com/>.
2. Locate your ngrok [authtoken](https://dashboard.ngrok.com/get-started/your-authtoken).
3. Set an environment variable for your authtoken, using the command line. Replace `<YOUR_AUTH_TOKEN>` with your actual ngrok authtoken:

For macOS and Linux:

```bash
export NGROK_AUTHTOKEN=<YOUR_AUTH_TOKEN>
```

For Windows PowerShell:

```shell
$Env:NGROK_AUTHTOKEN = "<YOUR_AUTH_TOKEN>"
```
Expand Down
50 changes: 26 additions & 24 deletions examples/digital_asset_management/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@
1. Get the ID of your app.
1. Log in to the [Developer Portal](https://www.canva.com/developers/).
2. Navigate to the [Your apps](https://www.canva.com/developers/apps) page.
3. Copy the ID from the **App ID** column.
3. Copy the ID from the **App ID** column in the apps table.
2. Open the starter kit's [.env file](../../.env).
3. Set the `APP_ID` environment variable to the ID of the app.

## Step 2: Run the development servers

1. Navigate into the starter kit:

```
```bash
cd canva-apps-sdk-starter-kit
```

1. Run the following command:

```
```bash
npm start digital_asset_management
```

Expand All @@ -28,28 +28,30 @@
2. Navigate to your app at `https://www.canva.com/developers/apps`, and click **Preview** to preview the app.

3. If your app requires authentication with a third party service, continue to Step 3.
Otherwise, you can make requests to your service via [./backend/server.ts](./backend/server.ts) inside `"/resources/find"`.
Otherwise, you can make requests to your service via [./backend/server.ts](./backend/server.ts) inside `"/resources/find"`.

## Step 3: (optional) Configure ngrok
## Step 3: (optional) Configure ngrok

If your app requires authentication with a third party service,
If your app requires authentication with a third party service,
your server needs to be exposed via a publicly available URL, so that Canva can send requests to it. This step explains how to do this with [ngrok](https://ngrok.com/).

**Note:** ngrok is a useful tool, but it has inherent security risks, such as someone figuring out the URL of your server and accessing proprietary information. Be mindful of the risks, and if you're working as part of an organization, talk to your IT department.
You must replace ngrok urls with hosted API endpoints for production apps.

To use ngrok, you'll need to do the following:

1. Sign up for a ngrok account at https://ngrok.com/.
2. Locate your ngrok [authtoken](https://dashboard.ngrok.com/get-started/your-authtoken).
1. Sign up for a ngrok account at <https://ngrok.com/>.
2. Locate your ngrok [authtoken](https://dashboard.ngrok.com/get-started/your-authtoken).
3. Set an environment variable for your authtoken, using the command line. Replace `<YOUR_AUTH_TOKEN>` with your actual ngrok authtoken:

For macOS and Linux:

```bash
export NGROK_AUTHTOKEN=<YOUR_AUTH_TOKEN>
```

For Windows PowerShell:

```shell
$Env:NGROK_AUTHTOKEN = "<YOUR_AUTH_TOKEN>"
```
Expand All @@ -64,27 +66,27 @@ From the `canva-apps-sdk-starter-kit` directory

1. Stop any running scripts, and run the following command to launch the backend and frontend development servers. The `--ngrok` parameter exposes the backend server via a publicly accessible URL.

```
```bash
npm start digital_asset_management --ngrok
```

2. After ngrok is running, copy your ngrok url
(e.g. https://0000-0000.ngrok-free.app) to the clipboard.
2. After ngrok is running, copy your ngrok url
(e.g. <https://0000-0000.ngrok-free.app>) to the clipboard.
1. Go to your app in the [Developer Portal](https://www.canva.com/developers/apps).
2. Navigate to the "Add authentication" section of your app.
3. Check "This app requires authentication"
4. In the "Redirect URL" text box, enter your ngrok url followed by `/redirect-url` e.g.
https://0000-0000.ngrok-free.app/redirect-url
5. In the "Redirect URL" text box, enter your ngrok url followed by `/` e.g.
https://0000-0000.ngrok-free.app/
4. In the "Redirect URL" text box, enter your ngrok url followed by `/redirect-url` e.g.
<https://0000-0000.ngrok-free.app/redirect-url>
5. In the "Authentication base URL" text box, enter your ngrok url followed by `/` e.g.
<https://0000-0000.ngrok-free.app/>
Note: Your ngrok URL changes each time you restart ngrok. Keep these fields up to
date to ensure your example authentication step will run.

3. Make sure the app is authenticating users by making the following changes:
1. Replace

`router.post("/resources/find", async (req, res) => {`
`router.post("/resources/find", async (req, res) => {`

with

`router.post("/api/resources/find", async (req, res) => {`
Expand All @@ -101,23 +103,23 @@ From the `canva-apps-sdk-starter-kit` directory
```const url = new URL(`${BACKEND_HOST}/api/resources/find`);```

in [./adapter.ts](./adapter.ts)

3. Comment out these lines in [./app.tsx](./app.tsx)

```
3. Comment out these lines in [./app.tsx](./app.tsx)

```typescript
// Comment this next line out for production apps
setAuthState("authenticated");
```

4. Navigate to your app at `https://www.canva.com/developers/apps`, and click **Preview** to preview the app.
1. A new screen will appear asking if you want to authenticate.
4. Navigate to your app at `https://www.canva.com/developers/apps`, and click **Preview** to preview the app.
1. A new screen will appear asking if you want to authenticate.
Press **Connect** to start the authentication flow.
2. A ngrok screen may appear. If it does, select **Visit Site**
3. An authentication popup will appear. For the username, enter `username`, and
for the password enter `password`.
4. If successful, you will be redirected back to your app.

5. You can now modify the `/redirect-url` function in `server.ts` to authenticate with your third-party
asset manager, and `/api/resources/find` to pull assets from your third-party asset manager.

See `https://www.canva.dev/docs/apps/authenticating-users/` for more details.
See `https://www.canva.dev/docs/apps/authenticating-users/` for more details.
32 changes: 21 additions & 11 deletions examples/native_image_elements/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import dog from "assets/images/dog.jpg";
import rabbit from "assets/images/rabbit.jpg";
import React from "react";
import baseStyles from "styles/components.css";
import { upload } from "@canva/asset";

const images = {
dog: {
Expand Down Expand Up @@ -47,6 +48,25 @@ export const App = () => {
};
});

const addImage = React.useCallback(async () => {
setIsLoading(true);
try {
const { ref } = await upload({
type: "IMAGE",
mimeType: "image/jpeg",
url: dataUrl,
thumbnailUrl: dataUrl,
});

await addNativeElement({
type: "IMAGE",
ref,
});
} finally {
setIsLoading(false);
}
}, [dataUrl]);

return (
<div className={baseStyles.scrollContainer}>
<Rows spacing="2u">
Expand Down Expand Up @@ -78,17 +98,7 @@ export const App = () => {
variant="primary"
disabled={disabled}
loading={isLoading}
onClick={async () => {
try {
setIsLoading(true);
await addNativeElement({
type: "IMAGE",
dataUrl,
});
} finally {
setIsLoading(false);
}
}}
onClick={addImage}
stretch
>
Add element
Expand Down
48 changes: 48 additions & 0 deletions examples/video_replacement/app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from "react";
import { Button, Rows, Text } from "@canva/app-ui-kit";
import styles from "styles/components.css";
import { upload } from "@canva/asset";
import { useSelection } from "utils/use_selection_hook";

export const App = () => {
const [loading, setLoading] = React.useState(false);
const selection = useSelection("video");

const updateVideo = async () => {
setLoading(true);
const queuedVideo = await upload({
type: "VIDEO",
mimeType: "video/mp4",
thumbnailImageUrl:
"https://www.canva.dev/example-assets/video-import/beach-thumbnail-image.jpg",
thumbnailVideoUrl:
"https://www.canva.dev/example-assets/video-import/beach-thumbnail-video.mp4",
url: "https://www.canva.dev/example-assets/video-import/beach-video.mp4",
width: 320,
height: 180,
});
const draft = await selection.read();
draft.contents.forEach((s) => (s.ref = queuedVideo.ref));

await draft.save();
setLoading(false);
};
return (
<div className={styles.scrollContainer}>
<Rows spacing="2u">
<Text>
This example demonstrates how apps can replace the selected video.
Select a video in the editor to begin.
</Text>
<Button
variant="primary"
onClick={updateVideo}
disabled={selection.count === 0}
loading={loading}
>
Replace with sample video
</Button>
</Rows>
</div>
);
};
20 changes: 20 additions & 0 deletions examples/video_replacement/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as React from "react";
import { createRoot } from "react-dom/client";
import { App } from "./app";
import "@canva/app-ui-kit/styles.css";
import { AppUiProvider } from "@canva/app-ui-kit";

const root = createRoot(document.getElementById("root")!);
function render() {
root.render(
<AppUiProvider>
<App />
</AppUiProvider>
);
}

render();

if (module.hot) {
module.hot.accept("./app", render);
}
Loading
Loading