From d9f530cd3f4594b5270509d3eaa3b16b9cce51e8 Mon Sep 17 00:00:00 2001 From: nekok500 Date: Tue, 26 Nov 2024 17:13:39 +0900 Subject: [PATCH 1/7] feat(Zaiko): add presence --- websites/Z/Zaiko/iframe.ts | 26 ++++++ websites/Z/Zaiko/metadata.json | 36 +++++++++ websites/Z/Zaiko/presence.ts | 143 +++++++++++++++++++++++++++++++++ 3 files changed, 205 insertions(+) create mode 100644 websites/Z/Zaiko/iframe.ts create mode 100644 websites/Z/Zaiko/metadata.json create mode 100644 websites/Z/Zaiko/presence.ts diff --git a/websites/Z/Zaiko/iframe.ts b/websites/Z/Zaiko/iframe.ts new file mode 100644 index 000000000000..af38f002be8f --- /dev/null +++ b/websites/Z/Zaiko/iframe.ts @@ -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( + "#vjs_video_3_html5_api" + ); + if (video) { + const data: iFrameData = { + currentTime: video.currentTime, + duration: video.duration, + paused: video.paused, + thumbnail: document.querySelector( + "#vjs_video_3 > div.vjs-poster > picture > img" + )?.src, + }; + + iframe.send(data); + } +}); diff --git a/websites/Z/Zaiko/metadata.json b/websites/Z/Zaiko/metadata.json new file mode 100644 index 000000000000..d5294e08c8ea --- /dev/null +++ b/websites/Z/Zaiko/metadata.json @@ -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 + } + ] +} \ No newline at end of file diff --git a/websites/Z/Zaiko/presence.ts b/websites/Z/Zaiko/presence.ts new file mode 100644 index 000000000000..13bb0f276704 --- /dev/null +++ b/websites/Z/Zaiko/presence.ts @@ -0,0 +1,143 @@ +import { iFrameData } from "./iframe"; + +const presence = new Presence({ + clientId: "1310622511419101235", + }), + strings = await 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; +}); + +presence.on("UpdateData", async () => { + const privacy = await presence.getSetting("privacy"), + presenceData: PresenceData = { + type: ActivityType.Watching, + largeImageKey: "https://i.imgur.com/jEBa0Ti.png", + startTimestamp: browsingTimestamp, + }, + ownerId = /(.+).zaiko.io/.exec(document.location.hostname)?.[1], + eventId = /\/event\/(\d+)\/stream.*/.exec(document.location.pathname)?.[1]; + + if (eventId) { + if (!Data) return; + + presenceData.details = strings.watchingLive; + + if (privacy) { + presenceData.smallImageKey = Data.paused ? Assets.Pause : Assets.Play; + presenceData.smallImageText = Data.paused + ? strings.paused + : strings.playing; + } else { + const eventTitle = document + .querySelector("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.smallImageKey = Data.paused ? Assets.Pause : Assets.Play; + presenceData.smallImageText = Data.paused + ? strings.paused + : strings.playing; + + presenceData.buttons = [ + { + label: strings.buttonWatchStream, + url: `https://zaiko.io/event/${eventId}`, + }, + ]; + } + } else if (ownerId) { + 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( + ".item-page > div > div.container-fluid > div > figure > img" + )?.src); + ownerAvatar = + document.querySelector(".img-profile-logo")?.src; + } else { + // transparent background pattern e.g. 365603 + eventTitle = document.querySelector("h1.title-h1").textContent?.trim(); + eventCover = document.querySelector( + "div.event-media > img" + )?.src; + ownerAvatar = document.querySelector( + "#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("meta[property='og:site_name']") + ?.content.trim(); + + presenceData.buttons = [ + { + label: strings.buttonWatchStream, + url: `https://${ownerId}.zaiko.io/item/${eventId}`, + }, + ]; + } + } 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); +}); From 05b9a2c8d8a32d3c9bc42d79fd0da0bca8d52d75 Mon Sep 17 00:00:00 2001 From: nekok500 Date: Tue, 26 Nov 2024 18:24:53 +0900 Subject: [PATCH 2/7] fix(Zaiko): undefined in eventpage activity button --- websites/Z/Zaiko/presence.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/websites/Z/Zaiko/presence.ts b/websites/Z/Zaiko/presence.ts index 13bb0f276704..ddecfe35b223 100644 --- a/websites/Z/Zaiko/presence.ts +++ b/websites/Z/Zaiko/presence.ts @@ -26,7 +26,6 @@ presence.on("UpdateData", async () => { largeImageKey: "https://i.imgur.com/jEBa0Ti.png", startTimestamp: browsingTimestamp, }, - ownerId = /(.+).zaiko.io/.exec(document.location.hostname)?.[1], eventId = /\/event\/(\d+)\/stream.*/.exec(document.location.pathname)?.[1]; if (eventId) { @@ -68,7 +67,7 @@ presence.on("UpdateData", async () => { }, ]; } - } else if (ownerId) { + } else if (/(.+).zaiko.io/.test(document.location.hostname)) { let eventTitle, eventCover, ownerAvatar; if (document.querySelector(".item-page")) { // white background pattern e.g. 365423 @@ -108,8 +107,8 @@ presence.on("UpdateData", async () => { presenceData.buttons = [ { - label: strings.buttonWatchStream, - url: `https://${ownerId}.zaiko.io/item/${eventId}`, + label: strings.buttonViewPage, + url: document.location.href, }, ]; } From 4827580016dfe9008b9d046c1886229758acca2e Mon Sep 17 00:00:00 2001 From: nekok500 Date: Tue, 26 Nov 2024 18:43:36 +0900 Subject: [PATCH 3/7] fix(Zaiko): top-level await --- websites/Z/Zaiko/presence.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/websites/Z/Zaiko/presence.ts b/websites/Z/Zaiko/presence.ts index ddecfe35b223..5bc74f650006 100644 --- a/websites/Z/Zaiko/presence.ts +++ b/websites/Z/Zaiko/presence.ts @@ -3,7 +3,7 @@ import { iFrameData } from "./iframe"; const presence = new Presence({ clientId: "1310622511419101235", }), - strings = await presence.getStrings({ + getStrings = presence.getStrings({ playing: "general.playing", paused: "general.paused", watching: "general.watching", @@ -20,7 +20,8 @@ presence.on("iFrameData", async (data: iFrameData) => { }); presence.on("UpdateData", async () => { - const privacy = await presence.getSetting("privacy"), + const strings = await getStrings, + privacy = await presence.getSetting("privacy"), presenceData: PresenceData = { type: ActivityType.Watching, largeImageKey: "https://i.imgur.com/jEBa0Ti.png", From 11b5ecbc9f1078a5570b53b6be71fbc4b53cd029 Mon Sep 17 00:00:00 2001 From: nekok500 Date: Tue, 26 Nov 2024 18:49:37 +0900 Subject: [PATCH 4/7] refactor(Zaiko): remove unnecessary if --- websites/Z/Zaiko/presence.ts | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/websites/Z/Zaiko/presence.ts b/websites/Z/Zaiko/presence.ts index 5bc74f650006..8c710b9f7abd 100644 --- a/websites/Z/Zaiko/presence.ts +++ b/websites/Z/Zaiko/presence.ts @@ -34,12 +34,12 @@ presence.on("UpdateData", async () => { presenceData.details = strings.watchingLive; - if (privacy) { - presenceData.smallImageKey = Data.paused ? Assets.Pause : Assets.Play; - presenceData.smallImageText = Data.paused - ? strings.paused - : strings.playing; - } else { + presenceData.smallImageKey = Data.paused ? Assets.Pause : Assets.Play; + presenceData.smallImageText = Data.paused + ? strings.paused + : strings.playing; + + if (!privacy) { const eventTitle = document .querySelector("h5.stream-sidebar-header-title") ?.textContent.trim(); @@ -56,11 +56,6 @@ presence.on("UpdateData", async () => { ); } - presenceData.smallImageKey = Data.paused ? Assets.Pause : Assets.Play; - presenceData.smallImageText = Data.paused - ? strings.paused - : strings.playing; - presenceData.buttons = [ { label: strings.buttonWatchStream, From b9a157a59bef0915ff31e695acc1161b69143273 Mon Sep 17 00:00:00 2001 From: nekok500 Date: Wed, 27 Nov 2024 23:35:00 +0900 Subject: [PATCH 5/7] refactor(Zaiko): format some lines --- websites/Z/Zaiko/presence.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/websites/Z/Zaiko/presence.ts b/websites/Z/Zaiko/presence.ts index 8c710b9f7abd..8c2dccb8ef74 100644 --- a/websites/Z/Zaiko/presence.ts +++ b/websites/Z/Zaiko/presence.ts @@ -1,4 +1,4 @@ -import { iFrameData } from "./iframe"; +import { iFrameData as IFrameData } from "./iframe"; const presence = new Presence({ clientId: "1310622511419101235", @@ -13,9 +13,9 @@ const presence = new Presence({ }), browsingTimestamp = Math.floor(Date.now() / 1000); -let Data: iFrameData; +let Data: IFrameData; -presence.on("iFrameData", async (data: iFrameData) => { +presence.on("iFrameData", async (data: IFrameData) => { Data = data; }); @@ -67,14 +67,14 @@ presence.on("UpdateData", async () => { let eventTitle, eventCover, ownerAvatar; if (document.querySelector(".item-page")) { // white background pattern e.g. 365423 - (eventTitle = document + 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( - ".item-page > div > div.container-fluid > div > figure > img" - )?.src); + ?.textContent.trim(); + eventCover = document.querySelector( + ".item-page > div > div.container-fluid > div > figure > img" + )?.src; ownerAvatar = document.querySelector(".img-profile-logo")?.src; } else { From 80e7a974d3dcca7cf626c7a1b83fe384369f3818 Mon Sep 17 00:00:00 2001 From: nekok500 Date: Sat, 30 Nov 2024 00:55:25 +0900 Subject: [PATCH 6/7] refactor(Zaiko): rename variable `Data` to `data` --- websites/Z/Zaiko/presence.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/websites/Z/Zaiko/presence.ts b/websites/Z/Zaiko/presence.ts index 8c2dccb8ef74..9b02225fc4f1 100644 --- a/websites/Z/Zaiko/presence.ts +++ b/websites/Z/Zaiko/presence.ts @@ -13,10 +13,10 @@ const presence = new Presence({ }), browsingTimestamp = Math.floor(Date.now() / 1000); -let Data: IFrameData; +let data: IFrameData; -presence.on("iFrameData", async (data: IFrameData) => { - Data = data; +presence.on("iFrameData", async (receivedData: IFrameData) => { + data = receivedData; }); presence.on("UpdateData", async () => { @@ -30,12 +30,12 @@ presence.on("UpdateData", async () => { eventId = /\/event\/(\d+)\/stream.*/.exec(document.location.pathname)?.[1]; if (eventId) { - if (!Data) return; + if (!data) return; presenceData.details = strings.watchingLive; - presenceData.smallImageKey = Data.paused ? Assets.Pause : Assets.Play; - presenceData.smallImageText = Data.paused + presenceData.smallImageKey = data.paused ? Assets.Pause : Assets.Play; + presenceData.smallImageText = data.paused ? strings.paused : strings.playing; @@ -47,12 +47,12 @@ presence.on("UpdateData", async () => { presenceData.state = eventTitle; presenceData.largeImageText = eventTitle; - if (Data.thumbnail) presenceData.largeImageKey = Data.thumbnail; - if (!Data.paused && !isNaN(Data.duration)) { + 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) + Math.floor(data.currentTime), + Math.floor(data.duration) ); } From a7cbb5a4cc819b574b3637cda3095445bf409630 Mon Sep 17 00:00:00 2001 From: nekok500 Date: Sat, 30 Nov 2024 00:56:09 +0900 Subject: [PATCH 7/7] refactor(Zaiko): format class name --- websites/Z/Zaiko/iframe.ts | 4 ++-- websites/Z/Zaiko/presence.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/websites/Z/Zaiko/iframe.ts b/websites/Z/Zaiko/iframe.ts index af38f002be8f..0a173fdf259f 100644 --- a/websites/Z/Zaiko/iframe.ts +++ b/websites/Z/Zaiko/iframe.ts @@ -1,4 +1,4 @@ -export interface iFrameData { +export interface IFrameData { currentTime: number; duration: number; paused: boolean; @@ -12,7 +12,7 @@ iframe.on("UpdateData", async () => { "#vjs_video_3_html5_api" ); if (video) { - const data: iFrameData = { + const data: IFrameData = { currentTime: video.currentTime, duration: video.duration, paused: video.paused, diff --git a/websites/Z/Zaiko/presence.ts b/websites/Z/Zaiko/presence.ts index 9b02225fc4f1..59d0a6f60966 100644 --- a/websites/Z/Zaiko/presence.ts +++ b/websites/Z/Zaiko/presence.ts @@ -1,4 +1,4 @@ -import { iFrameData as IFrameData } from "./iframe"; +import { IFrameData } from "./iframe"; const presence = new Presence({ clientId: "1310622511419101235",