added ping.gg app (#3728)
* added ping.gg app, not sure why its not showing * nit * Fixes * fixed email Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
This commit is contained in:
co-authored by
sean-brydon
parent
1a3aaa134e
commit
1332b76441
@@ -52,6 +52,9 @@ export const locationKeyToString = (location: LocationObject, t: TFunction) => {
|
||||
case LocationType.InPerson:
|
||||
return location.address || "In Person"; // If disabled address won't exist on the object
|
||||
case LocationType.Link:
|
||||
case LocationType.Ping:
|
||||
case LocationType.Riverside:
|
||||
case LocationType.Whereby:
|
||||
return location.link || "Link"; // If disabled link won't exist on the object
|
||||
case LocationType.Phone:
|
||||
return t("your_number");
|
||||
|
||||
@@ -334,6 +334,9 @@ const BookingPage = ({
|
||||
case LocationType.Whereby: {
|
||||
return locationInfo(locationType)?.link || "";
|
||||
}
|
||||
case LocationType.Ping: {
|
||||
return locationInfo(locationType)?.link || "";
|
||||
}
|
||||
// Catches all other location types, such as Google Meet, Zoom etc.
|
||||
default:
|
||||
return selectedLocation || "";
|
||||
|
||||
@@ -85,6 +85,11 @@ export const EditLocationDialog = (props: ISetLocationDialog) => {
|
||||
.string()
|
||||
.regex(/^http(s)?:\/\/(www\.)?around.co\/[a-zA-Z0-9]*/)
|
||||
.optional()
|
||||
: selection?.value === LocationType.Ping
|
||||
? z
|
||||
.string()
|
||||
.regex(/^http(s)?:\/\/(www\.)?ping.gg\/call\/[a-zA-Z0-9]*/)
|
||||
.optional()
|
||||
: selection?.value === LocationType.Riverside
|
||||
? z
|
||||
.string()
|
||||
@@ -324,6 +329,54 @@ export const EditLocationDialog = (props: ISetLocationDialog) => {
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
) : selectedLocation === LocationType.Ping ? (
|
||||
<>
|
||||
<div>
|
||||
<label htmlFor="address" className="block text-sm font-medium text-gray-700">
|
||||
{t("set_ping_link")}
|
||||
</label>
|
||||
<div className="mt-1">
|
||||
<input
|
||||
type="text"
|
||||
{...locationFormMethods.register("locationLink")}
|
||||
id="pinglink"
|
||||
placeholder="https://www.ping.gg/call/theo"
|
||||
required
|
||||
className="block w-full rounded-sm border-gray-300 text-sm"
|
||||
defaultValue={
|
||||
defaultValues
|
||||
? defaultValues.find(
|
||||
(location: { type: LocationType }) => location.type === LocationType.Ping
|
||||
)?.address
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
{!booking && (
|
||||
<div className="mt-3">
|
||||
<Controller
|
||||
name="displayLocationPublicly"
|
||||
control={locationFormMethods.control}
|
||||
render={() => (
|
||||
<CheckboxField
|
||||
defaultChecked={
|
||||
defaultValues
|
||||
? defaultValues.find((location) => location.type === LocationType.Ping)
|
||||
?.displayLocationPublicly
|
||||
: undefined
|
||||
}
|
||||
description={t("display_location_label")}
|
||||
onChange={(e) =>
|
||||
locationFormMethods.setValue("displayLocationPublicly", e.target.checked)
|
||||
}
|
||||
informationIconText={t("display_location_info_badge")}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
) : selectedLocation === LocationType.Riverside ? (
|
||||
<>
|
||||
<div>
|
||||
@@ -416,7 +469,8 @@ export const EditLocationDialog = (props: ISetLocationDialog) => {
|
||||
newLocation === LocationType.Link ||
|
||||
newLocation === LocationType.Whereby ||
|
||||
newLocation === LocationType.Around ||
|
||||
newLocation === LocationType.Riverside
|
||||
newLocation === LocationType.Riverside ||
|
||||
newLocation === LocationType.Ping
|
||||
) {
|
||||
details = { link: values.locationLink, displayLocationPublicly };
|
||||
}
|
||||
|
||||
@@ -474,7 +474,8 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
|
||||
newLocationType === LocationType.UserPhone ||
|
||||
newLocationType === LocationType.Whereby ||
|
||||
newLocationType === LocationType.Around ||
|
||||
newLocationType === LocationType.Riverside
|
||||
newLocationType === LocationType.Riverside ||
|
||||
newLocationType === LocationType.Ping
|
||||
) {
|
||||
openLocationModal(newLocationType);
|
||||
} else {
|
||||
@@ -485,6 +486,8 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* TODO: all of this should be generated from the App Store */}
|
||||
{formMethods.getValues("locations").length > 0 && (
|
||||
<ul>
|
||||
{formMethods.getValues("locations").map((location) => (
|
||||
@@ -522,19 +525,25 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
|
||||
)}
|
||||
{location.type === LocationType.Whereby && (
|
||||
<div className="flex flex-grow items-center">
|
||||
<img src="/api/app-store/whereby/icon.svg" className="h-6 w-6" alt="whereby logo" />
|
||||
<img src="/api/app-store/whereby/icon.svg" className="h-6 w-6" alt="Whereby logo" />
|
||||
<span className="text-sm ltr:ml-2 rtl:mr-2">{location.link}</span>
|
||||
</div>
|
||||
)}
|
||||
{location.type === LocationType.Around && (
|
||||
<div className="flex flex-grow items-center">
|
||||
<img src="/api/app-store/around/icon.svg" className="h-6 w-6" alt="whereby logo" />
|
||||
<img src="/api/app-store/around/icon.svg" className="h-6 w-6" alt="Around logo" />
|
||||
<span className="text-sm ltr:ml-2 rtl:mr-2">{location.link}</span>
|
||||
</div>
|
||||
)}
|
||||
{location.type === LocationType.Riverside && (
|
||||
<div className="flex flex-grow items-center">
|
||||
<img src="/api/app-store/riverside/icon.svg" className="h-6 w-6" alt="whereby logo" />
|
||||
<img src="/api/app-store/riverside/icon.svg" className="h-6 w-6" alt="Riverside logo" />
|
||||
<span className="text-sm ltr:ml-2 rtl:mr-2">{location.link}</span>
|
||||
</div>
|
||||
)}
|
||||
{location.type === LocationType.Ping && (
|
||||
<div className="flex flex-grow items-center">
|
||||
<img src="/api/app-store/ping/icon.svg" className="h-6 w-6" alt="Ping logo" />
|
||||
<span className="text-sm ltr:ml-2 rtl:mr-2">{location.link}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -1026,5 +1026,6 @@
|
||||
"variable_format": "Variable format",
|
||||
"custom_input_as_variable_info": "Ignore all special characters of the additonal input label (use only letters and numbers), use uppercase for all letters and replace whitespaces with underscores.",
|
||||
"using_additional_inputs_as_variables": "How to use additional inputs as variables?",
|
||||
"missing_connected_calendar": "No calendar connected"
|
||||
"missing_connected_calendar": "No calendar connected",
|
||||
"set_ping_link": "Set Ping link"
|
||||
}
|
||||
|
||||
@@ -17,14 +17,15 @@ If we rename all existing apps to their slug names, we can remove type and then
|
||||
|
||||
## TODO
|
||||
|
||||
- Beta Release
|
||||
- Show a warning somewhere that app directory must not be renamed manually, edit command must be used.
|
||||
- edit command should ask for slug and verify if it exists
|
||||
- Improvements
|
||||
- Prefill fields in edit command
|
||||
- Edit command Improvements
|
||||
- Prefill fields in edit command -> It allows only that content to change which user wants to change.
|
||||
- Don't override icon.svg
|
||||
- For Video Apps
|
||||
- Update app-store/locations.ts
|
||||
- _metadata.ts should have locationType and locationLabel props.
|
||||
- Merge app-store:watch and app-store commands, introduce app-store --watch
|
||||
- Allow inputs in non interactive way as well - That would allow easily copy pasting commands.
|
||||
- App already exists check. Ask user to run edit/regenerate command
|
||||
- An app created through CLI should be able to completely skip API validation for testing purposes. Credentials should be created with no API specified specific to the app. It would allow us to test any app end to end not worrying about the corresponding API endpoint.
|
||||
- Require assets path relative to app dir.
|
||||
|
||||
|
||||
@@ -63,6 +63,10 @@ const BaseAppFork = {
|
||||
}
|
||||
updatePackageJson({ slug, appDirPath, appDescription });
|
||||
|
||||
const categoryToVariantMap = {
|
||||
video: "conferencing",
|
||||
};
|
||||
|
||||
let config = {
|
||||
"/*": "Don't modify slug - If required, do it using cli edit command",
|
||||
name: appName,
|
||||
@@ -73,7 +77,7 @@ const BaseAppFork = {
|
||||
imageSrc: `/api/app-store/${slug}/icon.svg`,
|
||||
logo: `/api/app-store/${slug}/icon.svg`,
|
||||
url: `https://cal.com/apps/${slug}`,
|
||||
variant: category,
|
||||
variant: categoryToVariantMap[category] || category,
|
||||
categories: [category],
|
||||
publisher: publisherName,
|
||||
email: publisherEmail,
|
||||
|
||||
@@ -21,6 +21,7 @@ import { metadata as larkcalendar_meta } from "./larkcalendar/_metadata";
|
||||
import { metadata as metamask_meta } from "./metamask/_metadata";
|
||||
import { metadata as office365calendar_meta } from "./office365calendar/_metadata";
|
||||
import { metadata as office365video_meta } from "./office365video/_metadata";
|
||||
import { metadata as ping_meta } from "./ping/_metadata";
|
||||
import { metadata as riverside_meta } from "./riverside/_metadata";
|
||||
import { metadata as slackmessaging_meta } from "./slackmessaging/_metadata";
|
||||
import { metadata as stripepayment_meta } from "./stripepayment/_metadata";
|
||||
@@ -49,6 +50,7 @@ export const appStoreMetadata = {
|
||||
metamask: metamask_meta,
|
||||
office365calendar: office365calendar_meta,
|
||||
office365video: office365video_meta,
|
||||
ping: ping_meta,
|
||||
riverside: riverside_meta,
|
||||
slackmessaging: slackmessaging_meta,
|
||||
stripepayment: stripepayment_meta,
|
||||
|
||||
@@ -18,6 +18,7 @@ export const apiHandlers = {
|
||||
metamask: import("./metamask/api"),
|
||||
office365calendar: import("./office365calendar/api"),
|
||||
office365video: import("./office365video/api"),
|
||||
ping: import("./ping/api"),
|
||||
riverside: import("./riverside/api"),
|
||||
slackmessaging: import("./slackmessaging/api"),
|
||||
stripepayment: import("./stripepayment/api"),
|
||||
|
||||
@@ -19,6 +19,7 @@ export enum AppStoreLocationType {
|
||||
Whereby = "integrations:whereby_video",
|
||||
Around = "integrations:around_video",
|
||||
Riverside = "integrations:riverside_video",
|
||||
Ping = "integrations:ping_video",
|
||||
}
|
||||
|
||||
export type LocationObject = {
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
items:
|
||||
- /api/app-store/ping/1.png
|
||||
- /api/app-store/ping/2.png
|
||||
- /api/app-store/ping/3.png
|
||||
---
|
||||
|
||||
<Slider items={items} />
|
||||
|
||||
Ping.gg makes high quality video collaborations easier than ever. Think "Zoom for streamers and creators". Join a call in 3 clicks, manage audio and video like a pro, and copy-paste your guests straight into OBS
|
||||
@@ -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.Ping,
|
||||
locationLabel: "Ping.gg",
|
||||
...config,
|
||||
} as App;
|
||||
|
||||
export default metadata;
|
||||
@@ -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);
|
||||
@@ -0,0 +1,5 @@
|
||||
import { defaultHandler } from "@calcom/lib/server";
|
||||
|
||||
export default defaultHandler({
|
||||
GET: import("./_getAdd"),
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
export { default as add } from "./add";
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"/*": "Don't modify slug - If required, do it using cli edit command",
|
||||
"name": "Ping.gg",
|
||||
"title": "Ping.gg",
|
||||
"slug": "ping",
|
||||
"type": "ping_video",
|
||||
"imageSrc": "/api/app-store/ping/icon.svg",
|
||||
"logo": "/api/app-store/ping/icon.svg",
|
||||
"url": "https://ping.gg",
|
||||
"variant": "conferencing",
|
||||
"categories": ["video"],
|
||||
"publisher": "Ping.gg",
|
||||
"email": "support@ping.gg",
|
||||
"description": "Ping.gg makes high quality video collaborations easier than ever. Think 'Zoom for streamers and creators'. Join a call in 3 clicks, manage audio and video like a pro, and copy-paste your guests straight into OBS",
|
||||
"__createdUsingCli": true
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export * as api from "./api";
|
||||
export * as components from "./components";
|
||||
export { metadata } from "./_metadata";
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"private": true,
|
||||
"name": "@calcom/ping",
|
||||
"version": "0.0.0",
|
||||
"main": "./index.ts",
|
||||
"description": "Ping.gg makes high quality video collaborations easier than ever. Think 'Zoom for streamers and creators'. Join a call in 3 clicks, manage audio and video like a pro, and copy-paste your guests straight into OBS",
|
||||
"dependencies": {
|
||||
"@calcom/lib": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@calcom/types": "*"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 979 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 118 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 466 KiB |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="a" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 135 134"><defs><style>.b{fill:#e24a8d;}</style></defs><path class="b" d="M109.3,1.03H26.7C12.11,1.03,.24,12.9,.24,27.5V92.5c0,14.59,11.87,26.47,26.47,26.47h10.85c3.91,8.92,12.86,15.2,23.13,15.2s19.27-6.28,23.2-15.2h25.42c14.59,0,26.47-11.87,26.47-26.47V27.5c0-14.59-11.87-26.47-26.47-26.47Zm16.7,91.48c0,9.23-7.48,16.7-16.7,16.7h-33.07c-.15,8.41-7.06,15.2-15.54,15.2s-15.32-6.8-15.47-15.2H26.7c-9.23,0-16.7-7.48-16.7-16.7V27.5c0-9.23,7.48-16.7,16.7-16.7H109.3c9.23,0,16.7,7.48,16.7,16.7V92.5Zm-65.32,25.23c4.89,0,8.87-3.95,8.87-8.8V58.93l19.95,28.82c.04,.06,.08,.11,.12,.16,2.01,2.68,5.05,4.21,8.34,4.21h.92c5.74,0,10.41-4.64,10.41-10.33v-28.5c0-4.89-3.98-8.88-8.87-8.88s-8.8,3.98-8.8,8.88v7.02l-19.8-28.59c-.06-.08-.11-.16-.18-.24-2.19-2.82-5.19-4.37-8.44-4.37h-1c-5.7,0-10.33,4.67-10.33,10.41V108.93c0,4.85,3.95,8.8,8.8,8.8m-25.18-25.61c4.89,0,8.87-3.95,8.87-8.8v-29.65c0-4.89-3.98-8.88-8.87-8.88s-8.8,3.98-8.8,8.88v29.65c0,4.85,3.95,8.8,8.8,8.8"/></svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
@@ -25,5 +25,12 @@
|
||||
"categories": ["video"],
|
||||
"slug": "riverside",
|
||||
"type": "riverside_video"
|
||||
},
|
||||
{
|
||||
"/*": "This file is auto-generated and managed by `yarn app-store`. Don't edit manually but it is to be committed",
|
||||
"dirName": "ping",
|
||||
"categories": ["video"],
|
||||
"slug": "ping",
|
||||
"type": "ping_video"
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user