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

Merged
merged 9 commits into from
Dec 4, 2024
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 as 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 (data: IFrameData) => {
Data = data;
});
nekok500 marked this conversation as resolved.
Show resolved Hide resolved

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);
});