Skip to content
Open
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
159 changes: 159 additions & 0 deletions src/renderer/apis/notification.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import { DISCORD_BLURPLE } from "src/constants";
import type { ButtonItemProps } from "../modules/components/ButtonItem";

export interface NotificationProps {
id?: string;
timeout: number;
origin?: string;
name?: string;
color?: string;
gradient?: [string, string];
iconColor?: string;
imageClassName?: string | undefined;
header: React.ReactNode;
content: React.ReactNode;
image: string;
icon?: React.FunctionComponent<React.SVGProps<SVGSVGElement>> | false;
buttons?: ButtonItemProps[];
className?: string;
style?: React.CSSProperties;
hideProgressBar?: boolean;
type?: string;
}
export interface NotificationPropsWithId extends NotificationProps {
id: string;
origin: string;
name: string;
color: string;
}

class RPNotificationHandler extends EventTarget {
private notifications = new Map<string, NotificationPropsWithId>();

public sendNotification(notification: NotificationPropsWithId): () => void {
this.notifications.set(notification.id, notification);
this.dispatchEvent(new CustomEvent("rpNotificationUpdate"));
return () => {
this.notifications.delete(notification.id);
this.dispatchEvent(new CustomEvent("rpNotificationUpdate"));
};
}

public getNotifications(): NotificationPropsWithId[] {
return Array.from(this.notifications.values());
}

public closeNotification(id: string): void {
this.notifications.delete(id);
this.dispatchEvent(new CustomEvent("rpNotificationUpdate"));
}
}

/**
* @internal
* @hidden
*/
export const NotificationHandler = new RPNotificationHandler();

/**
* Send an in-app notification on discord.
*
* @example
* ```
* import { NotificationAPI } from "replugged";
*
* const notification = NotificationAPI.coremod("Notification");
*
* export async function start() {
* notification.notify({
* header: "Example",
timeout: 10000,
content: "This is an example notification!"
})
* }
*
* export function stop() {
* notification.dismissAll();
* }
* ```
*/
export class NotificationAPI {
public origin: string;
public name: string;
public color: string;
private notifications: Array<() => void> = [];

/**
*
* @param origin Origin of the context (e.g. API, Plugin, Coremod...)
* @param name Name of the context (e.g. Notices, SilentTyping, Badges...)
* @param color Color of the prefix as hex or a CSS color
*/
public constructor(origin: string, name: string, color?: string) {
this.origin = origin;
this.name = name;
this.color = color ?? DISCORD_BLURPLE;
}

/**
* A function to send in app notification.
* @param notification The notification details to show
* @returns A callback to dismiss the notification
*/
public notify(notification: NotificationProps): () => void {
notification.name = this.name;
notification.origin = this.origin;
notification.type ??= "info";
notification.color ??= this.color;
notification.id = `${this.origin}-${this.name}-${notification.type} -${Date.now()}`;
const dismiss = NotificationHandler.sendNotification(notification as NotificationPropsWithId);
this.notifications.push(dismiss);
return () => {
dismiss();
this.notifications = this.notifications.filter((f) => f !== dismiss);
};
}

/**
* Dismiss all notifications made by from this origin
*/
public dismissAll(): void {
for (const dismiss of this.notifications) {
dismiss();
}
this.notifications = [];
}

/**
* Convenience method to create a new {@link NotificationAPI} for an API.
* @internal
* @param name Name of the API
* @param color Color of the prefix as hex or a CSS color (default: blurple)
* @returns {@link NotificationAPI} with origin "API"
*/
public static api(name: string, color?: string): NotificationAPI {
return new NotificationAPI("API", name, color);
}

/**
* Convenience method to create a new {@link NotificationAPI} for an coremod.
* @internal
* @param name Name of the Coremod
* @param color Color of the prefix as hex or a CSS color (default: blurple)
* @returns {@link NotificationAPI} with origin "Coremod"
*/
public static coremod(name: string, color?: string): NotificationAPI {
return new NotificationAPI("Coremod", name, color);
}

/**
* Convenience method to create a new {@link NotificationAPI} for an Plugin.
* @internal
* @param name Name of the Plugin
* @param color Color of the prefix as hex or a CSS color (default: blurple)
* @returns {@link NotificationAPI} with origin "Plugin"
*/
public static plugin(name: string, color?: string): NotificationAPI {
return new NotificationAPI("Plugin", name, color);
}
}
9 changes: 9 additions & 0 deletions src/renderer/coremods/notification/icons/Close.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { React } from "@common";
export default React.memo((props: React.SVGProps<SVGSVGElement>) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" {...props}>
<path
fill="currentColor"
d="M18.4 4L12 10.4L5.6 4L4 5.6L10.4 12L4 18.4L5.6 20L12 13.6L18.4 20L20 18.4L13.6 12L20 5.6L18.4 4Z"
/>
</svg>
));
9 changes: 9 additions & 0 deletions src/renderer/coremods/notification/icons/Danger.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { React } from "@common";
export default React.memo((props: React.SVGProps<SVGSVGElement>) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15 15" {...props}>
<path
d="M7.02799 0.333252C3.346 0.333252 0.361328 3.31792 0.361328 6.99992C0.361328 10.6819 3.346 13.6666 7.02799 13.6666C10.71 13.6666 13.6947 10.6819 13.6947 6.99992C13.6947 3.31792 10.7093 0.333252 7.02799 0.333252ZM10.166 9.19525L9.22333 10.1379L7.02799 7.94325L4.83266 10.1379L3.89 9.19525L6.08466 6.99992L3.88933 4.80459L4.832 3.86259L7.02733 6.05792L9.22266 3.86259L10.1653 4.80459L7.97066 6.99992L10.166 9.19525Z"
fill="currentColor"
/>
</svg>
));
9 changes: 9 additions & 0 deletions src/renderer/coremods/notification/icons/Info.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { React } from "@common";
export default React.memo((props: React.SVGProps<SVGSVGElement>) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 11 11" {...props}>
<path
fill="currentColor"
d="M6 1C3.243 1 1 3.244 1 6c0 2.758 2.243 5 5 5s5-2.242 5-5c0-2.756-2.243-5-5-5zm0 2.376a.625.625 0 110 1.25.625.625 0 010-1.25zM7.5 8.5h-3v-1h1V6H5V5h1a.5.5 0 01.5.5v2h1v1z"
/>
</svg>
));
9 changes: 9 additions & 0 deletions src/renderer/coremods/notification/icons/Success.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { React } from "@common";
export default React.memo((props: React.SVGProps<SVGSVGElement>) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" {...props}>
<path
fill="currentColor"
d="M8.99991 16.17L4.82991 12L3.40991 13.41L8.99991 19L20.9999 7.00003L19.5899 5.59003L8.99991 16.17Z"
/>
</svg>
));
9 changes: 9 additions & 0 deletions src/renderer/coremods/notification/icons/Warning.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { React } from "@common";
export default React.memo((props: React.SVGProps<SVGSVGElement>) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21 21" {...props}>
<path
d="M10 0C4.486 0 0 4.486 0 10C0 15.515 4.486 20 10 20C15.514 20 20 15.515 20 10C20 4.486 15.514 0 10 0ZM9 4H11V11H9V4ZM10 15.25C9.31 15.25 8.75 14.691 8.75 14C8.75 13.31 9.31 12.75 10 12.75C10.69 12.75 11.25 13.31 11.25 14C11.25 14.691 10.69 15.25 10 15.25Z"
fill="currentColor"
/>
</svg>
));
13 changes: 13 additions & 0 deletions src/renderer/coremods/notification/icons/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Close from "./Close";
import Danger from "./Danger";
import Info from "./Info";
import Success from "./Success";
import Warning from "./Warning";

export default {
Close,
Danger,
Info,
Success,
Warning,
};
9 changes: 9 additions & 0 deletions src/renderer/coremods/notification/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import NotificationContainer from "./notification";

/**
* @internal
* @hidden
*/
export function _renderNotification(): React.ReactElement {
return <NotificationContainer />;
}
Loading