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

feat(Zaiko): Add presence #8915

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
26 changes: 26 additions & 0 deletions websites/Z/Zaiko/iframe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export interface IFrameData {
currentTime: number;
duration: number;
paused: boolean;
thumbnail: string;
}

const iframe = new iFrame();

iframe.on("UpdateData", async () => {
const video = document.querySelector<HTMLVideoElement>(
"#vjs_video_3_html5_api"
);
if (video) {
const data: IFrameData = {
currentTime: video.currentTime,
duration: video.duration,
paused: video.paused,
thumbnail: document.querySelector<HTMLImageElement>(
"#vjs_video_3 > div.vjs-poster > picture > img"
)?.src,
};

iframe.send(data);
}
});
36 changes: 36 additions & 0 deletions websites/Z/Zaiko/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"$schema": "https://schemas.premid.app/metadata/1.11",
"apiVersion": 1,
"author": {
"id": "586157827400400907",
"name": "nekok500"
},
"service": "Zaiko",
"altnames": [
"ZAIKO"
],
"description": {
"en": "Zaiko is a e-Tickets & Live streaming platform."
},
"url": "zaiko.io",
"regExp": "(.+\\.)?zaiko\\.io",
"version": "1.0.0",
"logo": "https://i.imgur.com/jEBa0Ti.png",
"thumbnail": "https://i.imgur.com/WBViwOI.jpeg",
"color": "#f4017a",
"category": "videos",
"tags": [
"live",
"video"
],
"iframe": true,
"iFrameRegExp": "live.zaiko.services.*",
"settings": [
{
"id": "privacy",
"title": "Privacy mode",
"icon": "fas fa-user-secret",
"value": false
}
]
}
138 changes: 138 additions & 0 deletions websites/Z/Zaiko/presence.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import { IFrameData } from "./iframe";

const presence = new Presence({
clientId: "1310622511419101235",
}),
getStrings = presence.getStrings({
playing: "general.playing",
paused: "general.paused",
watching: "general.watching",
watchingLive: "general.watchingLive",
buttonWatchStream: "general.buttonWatchStream",
buttonViewPage: "general.buttonViewPage",
}),
browsingTimestamp = Math.floor(Date.now() / 1000);

let data: IFrameData;

presence.on("iFrameData", async (receivedData: IFrameData) => {
data = receivedData;
});

presence.on("UpdateData", async () => {
const strings = await getStrings,
privacy = await presence.getSetting("privacy"),
presenceData: PresenceData = {
type: ActivityType.Watching,
largeImageKey: "https://i.imgur.com/jEBa0Ti.png",
startTimestamp: browsingTimestamp,
},
eventId = /\/event\/(\d+)\/stream.*/.exec(document.location.pathname)?.[1];

if (eventId) {
if (!data) return;

presenceData.details = strings.watchingLive;

presenceData.smallImageKey = data.paused ? Assets.Pause : Assets.Play;
presenceData.smallImageText = data.paused
? strings.paused
: strings.playing;

if (!privacy) {
const eventTitle = document
.querySelector<HTMLHeadingElement>("h5.stream-sidebar-header-title")
?.textContent.trim();

presenceData.state = eventTitle;
presenceData.largeImageText = eventTitle;

if (data.thumbnail) presenceData.largeImageKey = data.thumbnail;
if (!data.paused && !isNaN(data.duration)) {
[presenceData.startTimestamp, presenceData.endTimestamp] =
presence.getTimestamps(
Math.floor(data.currentTime),
Math.floor(data.duration)
);
}

presenceData.buttons = [
{
label: strings.buttonWatchStream,
url: `https://zaiko.io/event/${eventId}`,
},
];
}
} else if (/(.+).zaiko.io/.test(document.location.hostname)) {
let eventTitle, eventCover, ownerAvatar;
if (document.querySelector(".item-page")) {
// white background pattern e.g. 365423
eventTitle = document
.querySelector(
".item-page > div > div.container > div > div.my-4.col-lg-7 > div > div > div.mb-2 > h1"
)
?.textContent.trim();
eventCover = document.querySelector<HTMLImageElement>(
".item-page > div > div.container-fluid > div > figure > img"
)?.src;
ownerAvatar =
document.querySelector<HTMLImageElement>(".img-profile-logo")?.src;
} else {
// transparent background pattern e.g. 365603
eventTitle = document.querySelector("h1.title-h1").textContent?.trim();
eventCover = document.querySelector<HTMLImageElement>(
"div.event-media > img"
)?.src;
ownerAvatar = document.querySelector<HTMLImageElement>(
"#content-wrapper > header > div.base-header-nav.d-flex.align-items-center > div > a > img"
)?.src;
}

if (document.location.pathname.startsWith("/item/")) {
presenceData.details = "Browsing event page";

if (!privacy && eventTitle) {
presenceData.state = eventTitle;
presenceData.largeImageKey = eventCover;
presenceData.largeImageText = eventTitle;

if (ownerAvatar) presenceData.smallImageKey = ownerAvatar;
presenceData.smallImageText = document
.querySelector<HTMLMetaElement>("meta[property='og:site_name']")
?.content.trim();

presenceData.buttons = [
{
label: strings.buttonViewPage,
url: document.location.href,
},
];
}
} else {
const ownerName = document.querySelector("title")?.textContent.trim();

switch (document.location.pathname) {
case "/":
presenceData.details = "Browsing home page";
break;
case "/events":
case "/news":
presenceData.details = `Browsing ${document.location.pathname.slice(
1
)} page`;
break;
}

if (!privacy) {
presenceData.state = ownerName;
presenceData.largeImageText = ownerName;
if (ownerAvatar) presenceData.largeImageKey = ownerAvatar;
}
}
} else if (document.location.pathname === "/")
presenceData.details = "Browsing home page";
else if (document.location.pathname.startsWith("/account"))
presenceData.details = "Browsing account page";

presence.setActivity(presenceData);
});