+
+Discover radically unique video calls designed to help hybrid-remote teams create, collaborate and celebrate together.
\ No newline at end of file
diff --git a/packages/app-store/around/_metadata.ts b/packages/app-store/around/_metadata.ts
new file mode 100644
index 0000000000..3011695ec3
--- /dev/null
+++ b/packages/app-store/around/_metadata.ts
@@ -0,0 +1,19 @@
+import { LocationType } from "@calcom/core/location";
+import type { App } from "@calcom/types/App";
+
+import config from "./config.json";
+
+export const metadata = {
+ category: "other",
+ // FIXME: Currently for an app to be shown as installed, it must have this variable set. Either hardcoded or if it depends on some env variable, that should be checked here
+ installed: true,
+ rating: 0,
+ reviews: 0,
+ trending: true,
+ verified: true,
+ locationType: LocationType.Around,
+ locationLabel: "Around Video",
+ ...config,
+} as App;
+
+export default metadata;
diff --git a/packages/app-store/around/api/_getAdd.ts b/packages/app-store/around/api/_getAdd.ts
new file mode 100644
index 0000000000..4a6e1b4ba8
--- /dev/null
+++ b/packages/app-store/around/api/_getAdd.ts
@@ -0,0 +1,25 @@
+import type { NextApiRequest, NextApiResponse } from "next";
+
+import { defaultResponder } from "@calcom/lib/server";
+
+import checkSession from "../../_utils/auth";
+import { checkInstalled, createDefaultInstallation } from "../../_utils/installation";
+import appConfig from "../config.json";
+
+export async function getHandler(req: NextApiRequest, res: NextApiResponse) {
+ const session = checkSession(req);
+ const slug = appConfig.slug;
+ const appType = appConfig.type;
+
+ await checkInstalled(slug, session.user.id);
+ await createDefaultInstallation({
+ appType,
+ userId: session.user.id,
+ slug,
+ key: {},
+ });
+
+ return { url: "/apps/installed" };
+}
+
+export default defaultResponder(getHandler);
diff --git a/packages/app-store/around/api/add.ts b/packages/app-store/around/api/add.ts
new file mode 100644
index 0000000000..912126e232
--- /dev/null
+++ b/packages/app-store/around/api/add.ts
@@ -0,0 +1,5 @@
+import { defaultHandler } from "@calcom/lib/server";
+
+export default defaultHandler({
+ GET: import("./_getAdd"),
+});
diff --git a/packages/app-store/around/api/index.ts b/packages/app-store/around/api/index.ts
new file mode 100644
index 0000000000..4c0d2ead01
--- /dev/null
+++ b/packages/app-store/around/api/index.ts
@@ -0,0 +1 @@
+export { default as add } from "./add";
diff --git a/packages/app-store/around/components/InstallAppButton.tsx b/packages/app-store/around/components/InstallAppButton.tsx
new file mode 100644
index 0000000000..331b0a9b7a
--- /dev/null
+++ b/packages/app-store/around/components/InstallAppButton.tsx
@@ -0,0 +1,19 @@
+import type { InstallAppButtonProps } from "@calcom/app-store/types";
+
+import useAddAppMutation from "../../_utils/useAddAppMutation";
+import appConfig from "../config.json";
+
+export default function InstallAppButton(props: InstallAppButtonProps) {
+ const mutation = useAddAppMutation("around_video");
+
+ return (
+ <>
+ {props.render({
+ onClick() {
+ mutation.mutate("");
+ },
+ loading: mutation.isLoading,
+ })}
+ >
+ );
+}
diff --git a/packages/app-store/around/components/index.ts b/packages/app-store/around/components/index.ts
new file mode 100644
index 0000000000..0d6008d4ca
--- /dev/null
+++ b/packages/app-store/around/components/index.ts
@@ -0,0 +1 @@
+export { default as InstallAppButton } from "./InstallAppButton";
diff --git a/packages/app-store/around/config.json b/packages/app-store/around/config.json
new file mode 100644
index 0000000000..7da74c6d21
--- /dev/null
+++ b/packages/app-store/around/config.json
@@ -0,0 +1,16 @@
+{
+ "/*": "Don't modify slug - If required, do it using cli edit command",
+ "name": "Around",
+ "title": "Around",
+ "slug": "around",
+ "type": "around_video",
+ "imageSrc": "/api/app-store/around/icon.svg",
+ "logo": "/api/app-store/around/icon.svg",
+ "url": "https://cal.com/apps/around",
+ "variant": "conferencing",
+ "categories": ["video"],
+ "publisher": "Cal.com",
+ "email": "help@cal.com",
+ "description": "Discover radically unique video calls designed to help hybrid-remote teams create, collaborate and celebrate together.",
+ "__createdUsingCli": true
+}
diff --git a/packages/app-store/around/index.ts b/packages/app-store/around/index.ts
new file mode 100644
index 0000000000..a698d1f5c5
--- /dev/null
+++ b/packages/app-store/around/index.ts
@@ -0,0 +1,3 @@
+export * as api from "./api";
+export * as components from "./components";
+export { metadata } from "./_metadata";
diff --git a/packages/app-store/around/package.json b/packages/app-store/around/package.json
new file mode 100644
index 0000000000..b41b8d9723
--- /dev/null
+++ b/packages/app-store/around/package.json
@@ -0,0 +1,14 @@
+{
+ "$schema": "https://json.schemastore.org/package.json",
+ "private": true,
+ "name": "@calcom/around",
+ "version": "0.0.0",
+ "main": "./index.ts",
+ "description": "Discover radically unique video calls designed to help hybrid-remote teams create, collaborate and celebrate together.",
+ "dependencies": {
+ "@calcom/lib": "*"
+ },
+ "devDependencies": {
+ "@calcom/types": "*"
+ }
+}
diff --git a/packages/app-store/around/static/around1.webp b/packages/app-store/around/static/around1.webp
new file mode 100644
index 0000000000..3ead90c9fe
Binary files /dev/null and b/packages/app-store/around/static/around1.webp differ
diff --git a/packages/app-store/around/static/icon.svg b/packages/app-store/around/static/icon.svg
new file mode 100644
index 0000000000..adf1f5fabb
--- /dev/null
+++ b/packages/app-store/around/static/icon.svg
@@ -0,0 +1,15 @@
+
diff --git a/packages/app-store/locations.ts b/packages/app-store/locations.ts
index f7801d67bd..d3b2f75b3c 100644
--- a/packages/app-store/locations.ts
+++ b/packages/app-store/locations.ts
@@ -14,6 +14,9 @@ export enum AppStoreLocationType {
Huddle01 = "integrations:huddle01",
Tandem = "integrations:tandem",
Teams = "integrations:office365_video",
+ Whereby = "integrations:whereby_video",
+ Around = "integrations:around_video",
+ Riverside = "integrations:riverside_video",
}
export type LocationObject = {
diff --git a/packages/app-store/riverside/README.mdx b/packages/app-store/riverside/README.mdx
new file mode 100644
index 0000000000..926e9b3d98
--- /dev/null
+++ b/packages/app-store/riverside/README.mdx
@@ -0,0 +1,7 @@
+---
+items:
+ - /api/app-store/riverside/riverside1.png
+---
+
+
+Your online recording studio.The easiest way to record podcasts and videos in studio quality from anywhere. All from the browser.
\ No newline at end of file
diff --git a/packages/app-store/riverside/_metadata.ts b/packages/app-store/riverside/_metadata.ts
new file mode 100644
index 0000000000..815b96c11f
--- /dev/null
+++ b/packages/app-store/riverside/_metadata.ts
@@ -0,0 +1,19 @@
+import { LocationType } from "@calcom/core/location";
+import type { App } from "@calcom/types/App";
+
+import config from "./config.json";
+
+export const metadata = {
+ category: "other",
+ // FIXME: Currently for an app to be shown as installed, it must have this variable set. Either hardcoded or if it depends on some env variable, that should be checked here
+ installed: true,
+ rating: 0,
+ reviews: 0,
+ trending: true,
+ verified: true,
+ locationType: LocationType.Riverside,
+ locationLabel: "Riverside Video",
+ ...config,
+} as App;
+
+export default metadata;
diff --git a/packages/app-store/riverside/api/_getAdd.ts b/packages/app-store/riverside/api/_getAdd.ts
new file mode 100644
index 0000000000..4a6e1b4ba8
--- /dev/null
+++ b/packages/app-store/riverside/api/_getAdd.ts
@@ -0,0 +1,25 @@
+import type { NextApiRequest, NextApiResponse } from "next";
+
+import { defaultResponder } from "@calcom/lib/server";
+
+import checkSession from "../../_utils/auth";
+import { checkInstalled, createDefaultInstallation } from "../../_utils/installation";
+import appConfig from "../config.json";
+
+export async function getHandler(req: NextApiRequest, res: NextApiResponse) {
+ const session = checkSession(req);
+ const slug = appConfig.slug;
+ const appType = appConfig.type;
+
+ await checkInstalled(slug, session.user.id);
+ await createDefaultInstallation({
+ appType,
+ userId: session.user.id,
+ slug,
+ key: {},
+ });
+
+ return { url: "/apps/installed" };
+}
+
+export default defaultResponder(getHandler);
diff --git a/packages/app-store/riverside/api/add.ts b/packages/app-store/riverside/api/add.ts
new file mode 100644
index 0000000000..912126e232
--- /dev/null
+++ b/packages/app-store/riverside/api/add.ts
@@ -0,0 +1,5 @@
+import { defaultHandler } from "@calcom/lib/server";
+
+export default defaultHandler({
+ GET: import("./_getAdd"),
+});
diff --git a/packages/app-store/riverside/api/index.ts b/packages/app-store/riverside/api/index.ts
new file mode 100644
index 0000000000..4c0d2ead01
--- /dev/null
+++ b/packages/app-store/riverside/api/index.ts
@@ -0,0 +1 @@
+export { default as add } from "./add";
diff --git a/packages/app-store/riverside/components/InstallAppButton.tsx b/packages/app-store/riverside/components/InstallAppButton.tsx
new file mode 100644
index 0000000000..683c5485e8
--- /dev/null
+++ b/packages/app-store/riverside/components/InstallAppButton.tsx
@@ -0,0 +1,19 @@
+import type { InstallAppButtonProps } from "@calcom/app-store/types";
+
+import useAddAppMutation from "../../_utils/useAddAppMutation";
+import appConfig from "../config.json";
+
+export default function InstallAppButton(props: InstallAppButtonProps) {
+ const mutation = useAddAppMutation("riverside_video");
+
+ return (
+ <>
+ {props.render({
+ onClick() {
+ mutation.mutate("");
+ },
+ loading: mutation.isLoading,
+ })}
+ >
+ );
+}
diff --git a/packages/app-store/riverside/components/index.ts b/packages/app-store/riverside/components/index.ts
new file mode 100644
index 0000000000..0d6008d4ca
--- /dev/null
+++ b/packages/app-store/riverside/components/index.ts
@@ -0,0 +1 @@
+export { default as InstallAppButton } from "./InstallAppButton";
diff --git a/packages/app-store/riverside/config.json b/packages/app-store/riverside/config.json
new file mode 100644
index 0000000000..667e564bea
--- /dev/null
+++ b/packages/app-store/riverside/config.json
@@ -0,0 +1,16 @@
+{
+ "/*": "Don't modify slug - If required, do it using cli edit command",
+ "name": "riverside",
+ "title": "Riverside",
+ "slug": "riverside",
+ "type": "riverside_video",
+ "imageSrc": "/api/app-store/riverside/icon.svg",
+ "logo": "/api/app-store/riverside/icon.svg",
+ "url": "https://cal.com/apps/riverside",
+ "variant": "conferencing",
+ "categories": ["video"],
+ "publisher": "Cal.com",
+ "email": "help@cal.com",
+ "description": "Your online recording studio.The easiest way to record podcasts and videos in studio quality from anywhere. All from the browser.",
+ "__createdUsingCli": true
+}
diff --git a/packages/app-store/riverside/index.ts b/packages/app-store/riverside/index.ts
new file mode 100644
index 0000000000..a698d1f5c5
--- /dev/null
+++ b/packages/app-store/riverside/index.ts
@@ -0,0 +1,3 @@
+export * as api from "./api";
+export * as components from "./components";
+export { metadata } from "./_metadata";
diff --git a/packages/app-store/riverside/package.json b/packages/app-store/riverside/package.json
new file mode 100644
index 0000000000..eaf8ec30ba
--- /dev/null
+++ b/packages/app-store/riverside/package.json
@@ -0,0 +1,14 @@
+{
+ "$schema": "https://json.schemastore.org/package.json",
+ "private": true,
+ "name": "@calcom/riverside",
+ "version": "0.0.0",
+ "main": "./index.ts",
+ "description": "Your online recording studio.The easiest way to record podcasts and videos in studio quality from anywhere. All from the browser.",
+ "dependencies": {
+ "@calcom/lib": "*"
+ },
+ "devDependencies": {
+ "@calcom/types": "*"
+ }
+}
diff --git a/packages/app-store/riverside/static/icon.svg b/packages/app-store/riverside/static/icon.svg
new file mode 100644
index 0000000000..9a952fcbd2
--- /dev/null
+++ b/packages/app-store/riverside/static/icon.svg
@@ -0,0 +1,17 @@
+
+
diff --git a/packages/app-store/riverside/static/riverside1.png b/packages/app-store/riverside/static/riverside1.png
new file mode 100644
index 0000000000..7e265f7b8d
Binary files /dev/null and b/packages/app-store/riverside/static/riverside1.png differ
diff --git a/packages/app-store/whereby/README.mdx b/packages/app-store/whereby/README.mdx
new file mode 100644
index 0000000000..863c8105e6
--- /dev/null
+++ b/packages/app-store/whereby/README.mdx
@@ -0,0 +1,9 @@
+---
+items:
+ - /api/app-store/whereby/whereby1.webp
+ - /api/app-store/whereby/whereby2.webp
+---
+
+
+
+Whereby's the easiest way to connect over video – with no app or software download required. Connect with anyone, anywhere with zero hassle.
\ No newline at end of file
diff --git a/packages/app-store/whereby/_metadata.ts b/packages/app-store/whereby/_metadata.ts
new file mode 100644
index 0000000000..e4145cec46
--- /dev/null
+++ b/packages/app-store/whereby/_metadata.ts
@@ -0,0 +1,19 @@
+import { LocationType } from "@calcom/core/location";
+import type { App } from "@calcom/types/App";
+
+import config from "./config.json";
+
+export const metadata = {
+ category: "other",
+ // FIXME: Currently for an app to be shown as installed, it must have this variable set. Either hardcoded or if it depends on some env variable, that should be checked here
+ installed: true,
+ rating: 0,
+ reviews: 0,
+ trending: true,
+ verified: true,
+ locationType: LocationType.Whereby,
+ locationLabel: "Whereby Video",
+ ...config,
+} as App;
+
+export default metadata;
diff --git a/packages/app-store/whereby/api/_getAdd.ts b/packages/app-store/whereby/api/_getAdd.ts
new file mode 100644
index 0000000000..4a6e1b4ba8
--- /dev/null
+++ b/packages/app-store/whereby/api/_getAdd.ts
@@ -0,0 +1,25 @@
+import type { NextApiRequest, NextApiResponse } from "next";
+
+import { defaultResponder } from "@calcom/lib/server";
+
+import checkSession from "../../_utils/auth";
+import { checkInstalled, createDefaultInstallation } from "../../_utils/installation";
+import appConfig from "../config.json";
+
+export async function getHandler(req: NextApiRequest, res: NextApiResponse) {
+ const session = checkSession(req);
+ const slug = appConfig.slug;
+ const appType = appConfig.type;
+
+ await checkInstalled(slug, session.user.id);
+ await createDefaultInstallation({
+ appType,
+ userId: session.user.id,
+ slug,
+ key: {},
+ });
+
+ return { url: "/apps/installed" };
+}
+
+export default defaultResponder(getHandler);
diff --git a/packages/app-store/whereby/api/add.ts b/packages/app-store/whereby/api/add.ts
new file mode 100644
index 0000000000..912126e232
--- /dev/null
+++ b/packages/app-store/whereby/api/add.ts
@@ -0,0 +1,5 @@
+import { defaultHandler } from "@calcom/lib/server";
+
+export default defaultHandler({
+ GET: import("./_getAdd"),
+});
diff --git a/packages/app-store/whereby/api/index.ts b/packages/app-store/whereby/api/index.ts
new file mode 100644
index 0000000000..4c0d2ead01
--- /dev/null
+++ b/packages/app-store/whereby/api/index.ts
@@ -0,0 +1 @@
+export { default as add } from "./add";
diff --git a/packages/app-store/whereby/components/InstallAppButton.tsx b/packages/app-store/whereby/components/InstallAppButton.tsx
new file mode 100644
index 0000000000..7ba763e1a3
--- /dev/null
+++ b/packages/app-store/whereby/components/InstallAppButton.tsx
@@ -0,0 +1,18 @@
+import type { InstallAppButtonProps } from "@calcom/app-store/types";
+
+import useAddAppMutation from "../../_utils/useAddAppMutation";
+
+export default function InstallAppButton(props: InstallAppButtonProps) {
+ const mutation = useAddAppMutation("whereby_video");
+
+ return (
+ <>
+ {props.render({
+ onClick() {
+ mutation.mutate("");
+ },
+ loading: mutation.isLoading,
+ })}
+ >
+ );
+}
diff --git a/packages/app-store/whereby/components/index.ts b/packages/app-store/whereby/components/index.ts
new file mode 100644
index 0000000000..0d6008d4ca
--- /dev/null
+++ b/packages/app-store/whereby/components/index.ts
@@ -0,0 +1 @@
+export { default as InstallAppButton } from "./InstallAppButton";
diff --git a/packages/app-store/whereby/config.json b/packages/app-store/whereby/config.json
new file mode 100644
index 0000000000..cf7f0ceaeb
--- /dev/null
+++ b/packages/app-store/whereby/config.json
@@ -0,0 +1,16 @@
+{
+ "/*": "Don't modify slug - If required, do it using cli edit command",
+ "name": "Whereby",
+ "title": "Whereby",
+ "slug": "whereby",
+ "type": "whereby_video",
+ "imageSrc": "/api/app-store/whereby/icon.svg",
+ "logo": "/api/app-store/whereby/icon.svg",
+ "url": "https://cal.com/apps/whereby",
+ "variant": "conferencing",
+ "categories": ["video"],
+ "publisher": "Cal.com",
+ "email": "help@cal.com",
+ "description": "Whereby makes it super simple for collaborating teams to jump on a video call.",
+ "__createdUsingCli": true
+}
diff --git a/packages/app-store/whereby/index.ts b/packages/app-store/whereby/index.ts
new file mode 100644
index 0000000000..a698d1f5c5
--- /dev/null
+++ b/packages/app-store/whereby/index.ts
@@ -0,0 +1,3 @@
+export * as api from "./api";
+export * as components from "./components";
+export { metadata } from "./_metadata";
diff --git a/packages/app-store/whereby/package.json b/packages/app-store/whereby/package.json
new file mode 100644
index 0000000000..82e738ace2
--- /dev/null
+++ b/packages/app-store/whereby/package.json
@@ -0,0 +1,14 @@
+{
+ "$schema": "https://json.schemastore.org/package.json",
+ "private": true,
+ "name": "@calcom/whereby",
+ "version": "0.0.0",
+ "main": "./index.ts",
+ "description": "Whereby makes it super simple for collaborating teams to jump on a video call.",
+ "dependencies": {
+ "@calcom/lib": "*"
+ },
+ "devDependencies": {
+ "@calcom/types": "*"
+ }
+}
diff --git a/packages/app-store/whereby/static/icon.svg b/packages/app-store/whereby/static/icon.svg
new file mode 100644
index 0000000000..b8c199448e
--- /dev/null
+++ b/packages/app-store/whereby/static/icon.svg
@@ -0,0 +1,5 @@
+
diff --git a/packages/app-store/whereby/static/logo.svg b/packages/app-store/whereby/static/logo.svg
new file mode 100644
index 0000000000..272a15167d
--- /dev/null
+++ b/packages/app-store/whereby/static/logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/app-store/whereby/static/whereby1.webp b/packages/app-store/whereby/static/whereby1.webp
new file mode 100644
index 0000000000..32b2a6aabc
Binary files /dev/null and b/packages/app-store/whereby/static/whereby1.webp differ
diff --git a/packages/app-store/whereby/static/whereby2.webp b/packages/app-store/whereby/static/whereby2.webp
new file mode 100644
index 0000000000..b18c9d27c0
Binary files /dev/null and b/packages/app-store/whereby/static/whereby2.webp differ
diff --git a/packages/lib/server/perfObserver.ts b/packages/lib/server/perfObserver.ts
index 9be8b9fabe..87fa325ce3 100644
--- a/packages/lib/server/perfObserver.ts
+++ b/packages/lib/server/perfObserver.ts
@@ -4,7 +4,6 @@ declare global {
// eslint-disable-next-line no-var
var perfObserver: PerformanceObserver | undefined;
}
-
export const perfObserver =
globalThis.perfObserver ||
new PerformanceObserver((items) => {
diff --git a/packages/prisma/seed-app-store.config.json b/packages/prisma/seed-app-store.config.json
index fe51488c70..94ad9e36cf 100644
--- a/packages/prisma/seed-app-store.config.json
+++ b/packages/prisma/seed-app-store.config.json
@@ -1 +1,24 @@
-[]
+[
+ {
+ "/*": "This file is auto-generated and managed by `yarn app-store`. Don't edit manually but it is to be committed",
+ "dirName": "whereby",
+ "categories": ["video"],
+ "slug": "whereby",
+ "type": "whereby_video"
+ },
+ {
+ "/*": "This file is auto-generated and managed by `yarn app-store`. Don't edit manually but it is to be committed",
+ "dirName": "around",
+ "categories": ["video"],
+ "slug": "around",
+ "type": "around_video"
+ },
+ {
+ "/*": "This file is auto-generated and managed by `yarn app-store`. Don't edit manually but it is to be committed",
+ "dirName": "riverside",
+ "categories": ["video"],
+ "slug": "riverside",
+ "type": "riverside_video"
+ }
+]
+
diff --git a/packages/types/App.d.ts b/packages/types/App.d.ts
index 36b1124548..8a2bbc6a7e 100644
--- a/packages/types/App.d.ts
+++ b/packages/types/App.d.ts
@@ -31,7 +31,7 @@ export interface App {
/** The icon to display in /apps/installed */
imageSrc: string;
/** TODO determine if we should use this instead of category */
- variant: "calendar" | "payment" | "conferencing" | "other" | "other_calendar";
+ variant: "calendar" | "payment" | "conferencing" | "video" | "other" | "other_calendar";
/** The slug for the app store public page inside `/apps/[slug] */
slug: string;
/** The category to which this app belongs, currently we have `calendar`, `payment` or `video` */