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:
Peer Richelsen
2022-08-08 05:57:09 +00:00
committed by GitHub
co-authored by sean-brydon
parent 1a3aaa134e
commit 1332b76441
23 changed files with 192 additions and 12 deletions
@@ -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 };
}
+13 -4
View File
@@ -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"
}
+6 -5
View File
@@ -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.
+5 -1
View File
@@ -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"),
+1
View File
@@ -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 = {
+10
View File
@@ -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
+19
View File
@@ -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;
+25
View File
@@ -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);
+5
View File
@@ -0,0 +1,5 @@
import { defaultHandler } from "@calcom/lib/server";
export default defaultHandler({
GET: import("./_getAdd"),
});
+1
View File
@@ -0,0 +1 @@
export { default as add } from "./add";
+16
View File
@@ -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
}
+3
View File
@@ -0,0 +1,3 @@
export * as api from "./api";
export * as components from "./components";
export { metadata } from "./_metadata";
+14
View File
@@ -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

+1
View File
@@ -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"
}
]