From 01086482e45268f3df21cbeeff6a0b724910741c Mon Sep 17 00:00:00 2001 From: Zv_yz Date: Thu, 21 Mar 2024 23:24:07 -0300 Subject: [PATCH 1/3] [+] README.md --- README.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 18e2d74..85df350 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,11 @@ -# Show Sessions -Port of Strencher's plugin (https://github.com/Strencher/BetterDiscordStuff/tree/master/ShowSessions) to Powercord \ No newline at end of file +# Install +Clone the repository inside your Vencord `src/userplugins` folder +```bash +cd Vencord/src/userplugins +git clone https://github.com/Zv-yz/ShowSessions +pnpm build +``` + +# Credits +- [Oocrop](https://github.com/Oocrop/show-sessions) porting plugin on Powercord/Replugged +- [Strencher](https://github.com/Strencher) creator of plugin \ No newline at end of file From 1909ec4783107b2e1b8863c41ff741a5a15eb8c3 Mon Sep 17 00:00:00 2001 From: Zv_yz Date: Thu, 21 Mar 2024 23:25:38 -0300 Subject: [PATCH 2/3] [-] removed old files --- LICENSE | 21 ---- components/SessionList.jsx | 146 ---------------------------- constants.js | 27 ------ i18n/en-US.json | 17 ---- i18n/index.js | 7 -- i18n/ru.json | 17 ---- index.js | 192 ------------------------------------- manifest.json | 7 -- style.css | 35 ------- 9 files changed, 469 deletions(-) delete mode 100644 LICENSE delete mode 100644 components/SessionList.jsx delete mode 100644 constants.js delete mode 100644 i18n/en-US.json delete mode 100644 i18n/index.js delete mode 100644 i18n/ru.json delete mode 100644 index.js delete mode 100644 manifest.json delete mode 100644 style.css diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 1b11cba..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021 Oocrop - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/components/SessionList.jsx b/components/SessionList.jsx deleted file mode 100644 index 49257ab..0000000 --- a/components/SessionList.jsx +++ /dev/null @@ -1,146 +0,0 @@ -const { - React, - getModule, - getModuleByDisplayName, - Flux: { connectStores }, - i18n: { Messages }, - constants: { - Colors: { STATUS_GREEN_600 } - } -} = require("powercord/webpack"); -const { AsyncComponent } = require("powercord/components"); -const { DEVICE, OS } = require("../constants"); - -module.exports = AsyncComponent.from( - (async () => { - const { getCurrentUser } = await getModule(["getCurrentUser"]); - const sessionStore = await getModule(["getActiveSession"]); - const { FormSection, FormDivider } = await getModule(["FormSection"]); - const { default: Avatar } = await getModule(["AnimatedAvatar"]); - const UserActivityContainer = await getModuleByDisplayName( - "UserActivityContainer" - ); - const CustomStatus = await getModuleByDisplayName("CustomStatus"); - const { TextBadge } = await getModule(["TextBadge"]); - const { parse } = await getModule(["parse", "parseTopic"]); - const { marginTop40 } = await getModule(["marginTop40"]); - const { card, title } = await getModule(["card", "loaded"]); - const { colorStandard } = await getModule(["colorStandard"]); - const { - customStatus, - customStatusEmoji, - customStatusSoloEmoji, - customStatusText - } = await getModule(["customStatus", "customStatusEmoji"]); - - class SessionList extends React.Component { - render() { - const sessions = sessionStore.getSessions(); - const currentSession = sessionStore.getSession(); - return ( - <> - -
- {Object.values(sessions) - .filter(s => s.sessionId !== "all") - .map((session, index) => - this.renderItem( - session, - index, - session.sessionId === - currentSession.sessionId - ) - )} -
-
- - - ); - } - - renderItem(session, index, current) { - const currentUser = getCurrentUser(); - return ( -
-
-

- {Messages.SHOW_SESSIONS_SESSION_NUMERATED.format( - { num: index + 1 } - )} - {current ? ( - - ) : null} -

- -
- {session.activities.length > 0 ? ( - <> - - {session.activities.map(activity => ( -
- {activity.type === 4 ? ( - - ) : ( - - )} -
- ))} -
- - - ) : null} -
- {[ - `**ID**: \`${session.sessionId}\``, - `**${Messages.SHOW_SESSIONS_DEVICE}**: ${DEVICE[ - session.clientInfo.client - ]()}`, - `**${Messages.SHOW_SESSIONS_OS}**: ${ - OS[session.clientInfo.os] - }` - ].map(s => ( - <> - {parse(s)} -
- - ))} -
-
- ); - } - } - - return connectStores([sessionStore], () => ({}))(SessionList); - })() -); diff --git a/constants.js b/constants.js deleted file mode 100644 index 9520de2..0000000 --- a/constants.js +++ /dev/null @@ -1,27 +0,0 @@ -const { - i18n: { Messages } -} = require("powercord/webpack"); - -const STATUS = { - online: () => "🟢 " + Messages.STATUS_ONLINE, - idle: () => "🌙 " + Messages.STATUS_IDLE, - dnd: () => "⛔ " + Messages.STATUS_DND, - streaming: () => "🟣 " + Messages.STATUS_STREAMING, - invisible: () => "⚫ " + Messages.STATUS_INVISIBLE -}; - -const DEVICE = { - desktop: () => "🖥 " + Messages.SHOW_SESSIONS_DEVICE_DESKTOP, - mobile: () => "📱 " + Messages.SHOW_SESSIONS_DEVICE_MOBILE, - web: () => "🌐 " + Messages.SHOW_SESSIONS_DEVICE_WEB -}; - -const OS = { - windows: "🪟 Windows", - linux: "🐧 Linux", - macos: "🍎 MacOS", - android: "🤖 Android", - ios: "🍎 iOS" -}; - -module.exports = { STATUS, DEVICE, OS }; diff --git a/i18n/en-US.json b/i18n/en-US.json deleted file mode 100644 index 6d65e24..0000000 --- a/i18n/en-US.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "SHOW_SESSIONS_UNKNOWN": "Unknown", - "SHOW_SESSIONS_SESSIONS": "Sessions", - "SHOW_SESSIONS_NO_SESSIONS": "No Sessions", - "SHOW_SESSIONS_NO_SESSIONS_DESC": "Have you gone offline?", - "SHOW_SESSIONS_SESSION_NUMERATED": "Session #{num}", - "SHOW_SESSIONS_STATUS": "Status", - "SHOW_SESSIONS_DEVICE": "Device", - "SHOW_SESSIONS_DEVICE_DESKTOP": "Desktop", - "SHOW_SESSIONS_DEVICE_MOBILE": "Mobile", - "SHOW_SESSIONS_DEVICE_WEB": "Web Browser", - "SHOW_SESSIONS_OS": "OS", - "SHOW_SESSIONS_ACTIVITIES": "Activities", - "SHOW_SESSIONS_SINCE": "since", - "SHOW_SESSIONS_ENDS": "ends", - "SHOW_SESSIONS_CURRENT_SESSION": "Current Session" -} diff --git a/i18n/index.js b/i18n/index.js deleted file mode 100644 index 6a04e6e..0000000 --- a/i18n/index.js +++ /dev/null @@ -1,7 +0,0 @@ -require("fs") - .readdirSync(__dirname) - .filter(file => file !== "index.js") - .forEach(filename => { - const moduleName = filename.split(".")[0]; - exports[moduleName] = require(`${__dirname}/${filename}`); - }); diff --git a/i18n/ru.json b/i18n/ru.json deleted file mode 100644 index cf22053..0000000 --- a/i18n/ru.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "SHOW_SESSIONS_UNKNOWN": "Неизвестно", - "SHOW_SESSIONS_SESSIONS": "Сессии", - "SHOW_SESSIONS_NO_SESSIONS": "Нет Сессий", - "SHOW_SESSIONS_NO_SESSIONS_DESC": "Может, Вы оффлайн?", - "SHOW_SESSIONS_SESSION_NUMERATED": "Сессия №{num}", - "SHOW_SESSIONS_STATUS": "Статус", - "SHOW_SESSIONS_DEVICE": "Устройство", - "SHOW_SESSIONS_DEVICE_DESKTOP": "Компьютер", - "SHOW_SESSIONS_DEVICE_MOBILE": "Телефон", - "SHOW_SESSIONS_DEVICE_WEB": "Браузер", - "SHOW_SESSIONS_OS": "ОС", - "SHOW_SESSIONS_ACTIVITIES": "Активности", - "SHOW_SESSIONS_SINCE": "начато", - "SHOW_SESSIONS_ENDS": "закончится", - "SHOW_SESSIONS_CURRENT_SESSION": "Текущая сессия" -} diff --git a/index.js b/index.js deleted file mode 100644 index f0aff49..0000000 --- a/index.js +++ /dev/null @@ -1,192 +0,0 @@ -const { Plugin } = require("powercord/entities"); -const { - getModuleByDisplayName, - getModule, - i18n: { Messages }, - React, - FluxDispatcher -} = require("powercord/webpack"); -const { inject, uninject } = require("powercord/injector"); -const { wrapInHooks } = require("powercord/util"); -const SessionList = require("./components/SessionList"); -const { STATUS, DEVICE, OS } = require("./constants"); - -powercord.api.i18n.loadAllStrings(require("./i18n")); - -function formatWithoutReact(i18nString, values) { - return i18nString.message.replaceAll(/!!\{(.+?)\}!!/g, (_, name) => { - if (values[name] === undefined) - throw new Error("A value must be provided for " + name); - return values[name]; - }); -} - -module.exports = class ShowSessions extends Plugin { - async startPlugin() { - this.loadStylesheet("style.css"); - this.sessionStore = await getModule(["getActiveSession"]); - - powercord.api.commands.registerCommand({ - command: "sessions", - description: "Shows active sessions on your account", - executor: this.command.bind(this) - }); - - let ConnectedUserAccountSettings; - while (typeof ConnectedUserAccountSettings !== "function") { - ConnectedUserAccountSettings = await getModuleByDisplayName( - "ConnectedUserAccountSettings" - ); - await new Promise(resolve => setTimeout(resolve, 1e4)); - } - - const UserSettingsAccount = wrapInHooks( - () => ConnectedUserAccountSettings().type - )(); - - inject( - "show-sessions_account-settings", - UserSettingsAccount.prototype, - "render", - (_, res) => { - res.props.children[2].props.children.splice( - 1, - 0, - React.createElement(SessionList, {}) - ); - return res; - } - ); - } - pluginWillUnload() { - uninject("show-sessions_account-settings"); - powercord.api.commands.unregisterCommand("sessions"); - } - - command() { - const sessions = this.sessionStore.getSessions(); - const currentSession = this.sessionStore.getSession(); - return { - send: false, - result: { - type: "rich", - title: - Object.keys(sessions).length > 0 - ? Messages.SHOW_SESSIONS_SESSIONS - : Messages.SHOW_SESSIONS_NO_SESSIONS, - description: - Object.keys(sessions).length > 0 - ? "" - : Messages.SHOW_SESSIONS_NO_SESSIONS_DESC, - fields: Object.values(sessions) - .filter(s => s.sessionId !== "all") - .map((session, index) => ({ - name: Messages.SHOW_SESSIONS_SESSION_NUMERATED.format({ - num: index + 1 - }), - value: [ - `**ID:** \`${session.sessionId}\``, - `**${Messages.SHOW_SESSIONS_STATUS}:** ${STATUS[ - session.status - ]()}`, - `**${Messages.SHOW_SESSIONS_DEVICE}:** ${ - DEVICE[session.clientInfo.client]() || - "❓ " + Messages.SHOW_SESSIONS_UNKNOWN - }`, - `**${Messages.SHOW_SESSIONS_OS}:** ${ - OS[session.clientInfo.os] || - "❓ " + Messages.SHOW_SESSIONS_UNKNOWN - }`, - session.activities.length > 0 - ? `**${ - Messages.SHOW_SESSIONS_ACTIVITIES - }:** ${session.activities - .map(activity => { - switch (activity.type) { - case 0: - return `${activity.name}${ - activity.timestamps - ?.start - ? `, ${ - Messages.SHOW_SESSIONS_SINCE - } ` - : "" - }${ - activity.timestamps?.end - ? `, ${ - Messages.SHOW_SESSIONS_ENDS - } ` - : "" - }`; - case 1: - return `[${formatWithoutReact( - Messages.STREAMING, - { name: activity.state } - )}](${activity.url})`; - case 2: - return `${formatWithoutReact( - Messages.LISTENING_TO, - { name: activity.state } - )}`; - case 3: - return `${formatWithoutReact( - Messages.WATCHING, - { name: activity.state } - )}`; - case 4: - return `${ - Messages.CUSTOM_STATUS - }: ${ - activity.emoji?.id - ? `<${ - activity - .emoji - .animated - ? "a" - : "" - }:${ - activity - .emoji - .name - }:${ - activity - .emoji - .id - }>` - : `${activity.emoji?.name ?? ""} ` || "" - }${activity.state || ""}`; - case 5: - return `${formatWithoutReact( - Messages.COMPETING, - { name: activity.state } - )}`; - } - }) - .join("\n ")}` - : false, - session.sessionId === currentSession.sessionId - ? Messages.SHOW_SESSIONS_CURRENT_SESSION + " ✅" - : false - ] - .filter(r => r) - .join("\n"), - inline: true - })) - } - }; - } -}; diff --git a/manifest.json b/manifest.json deleted file mode 100644 index 5eb92a1..0000000 --- a/manifest.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "Show Sessions", - "author": "Oocrop", - "license": "MIT", - "version": "1.0.0", - "description": "Shows you active sessions on your account. Original plugin by Strencher" -} diff --git a/style.css b/style.css deleted file mode 100644 index 749384c..0000000 --- a/style.css +++ /dev/null @@ -1,35 +0,0 @@ -.sessionsGrid { - display: grid; - grid-template-columns: 1fr 1fr; - grid-auto-flow: row; - gap: 20px; -} - -.sessionCard { - padding: 16px; - gap: 10px; - cursor: unset; - height: auto; -} -.sessionCard:hover { - background-color: var(--background-secondary-alt) !important; - box-shadow: none; - transform: none; -} - -.sessionCard-header { - display: flex; - gap: 15px; -} -.sessionCard-title { - word-break: break-all; - gap: 10px; -} - -.sessionCard-activity { - background-color: var(--background-primary); - padding: 10px; - margin-bottom: 5px; - border-radius: 5px; - width: 288px; -} From 8c652e43b9438f06e61c43813ac7e9c7fe247611 Mon Sep 17 00:00:00 2001 From: Zv_yz Date: Thu, 21 Mar 2024 23:26:00 -0300 Subject: [PATCH 3/3] [+] new files --- constants.ts | 27 +++++++++ index.ts | 165 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 192 insertions(+) create mode 100644 constants.ts create mode 100644 index.ts diff --git a/constants.ts b/constants.ts new file mode 100644 index 0000000..52a1c92 --- /dev/null +++ b/constants.ts @@ -0,0 +1,27 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +module.exports = { + STATUS: { + online: () => "🟢 Online", + idle: () => "🌙 Idle", + dnd: () => "⛔ Do Not Disturb", + streaming: () => "🟣 Streaming", + invisible: () => "⚫ Invisible" + }, + DEVICE: { + desktop: () => "🖥 Desktop", + mobile: () => "📱 Mobile", + web: () => "🌐 Web Browser" + }, + OS: { + windows: "🪟 Windows", + linux: "🐧 Linux", + macos: "🍎 MacOS", + android: "🤖 Android", + ios: "🍎 iOS" + } +}; diff --git a/index.ts b/index.ts new file mode 100644 index 0000000..001c43d --- /dev/null +++ b/index.ts @@ -0,0 +1,165 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { ApplicationCommandInputType, sendBotMessage } from "@api/Commands"; +import definePlugin from "@utils/types"; +import { findStoreLazy } from "@webpack"; +import { i18n } from "@webpack/common"; + +import { DEVICE, OS, STATUS } from "./constants"; + +const SessionsStore = findStoreLazy("SessionsStore"); + +interface Emoji { + animated: boolean, + id: string, + name: string; +} + +interface Activity { + type: number; + timestamps: { + start: number; + end: number; + }; + state: string; + session_id: string; + name: string; + id: string; + emoji: Emoji; + details: string; + created_at: number; + buttons: string[]; + url: string, + assets: { + small_text: string; + small_image: string; + large_text: string; + large_image: string; + }; + application_id: string; +} + +interface ClientInfo { + version: number; + os: string; + client: string; +} + +interface Session { + sessionId: string; + status: string; + activities: Activity[]; + active: boolean; + clientInfo: ClientInfo; +} + +interface SessionData { + [sessionId: string]: Session; +} + +function formatWithoutReact(i18nString, values) { + return i18nString.message.replaceAll(/!!\{(.+?)\}!!/g, (_, name) => { + if (values[name] === undefined) throw new Error("A value must be provided for " + name); + return values[name]; + }); +} + +export default definePlugin({ + name: "ShowSessions", + description: "Shows active sessions on your account", + authors: [ + { + id: 566409342161780747n, + name: "zv_yz", + } + ], + dependencies: ["CommandsAPI"], + commands: [ + { + name: "sessions", + description: "Shows active sessions on your account", + inputType: ApplicationCommandInputType.BUILT_IN, + options: [], + execute: (_, ctx) => { + const Sessions: SessionData = SessionsStore?.getSessions(); + const currentSession: Session = SessionsStore?.getSession(); + + // @ts-ignore + sendBotMessage(ctx.channel.id, { + author: { + username: "Vencord" + }, + embeds: [ + { + type: "rich", + title: Object.keys(Sessions).length > 0 + ? "Sessions" + : "No Sessions", + description: + Object.keys(Sessions).length > 0 + ? "" + : "Have you gone offline?", + // @ts-ignore + fields: Object.values(Sessions) + .filter(s => s.sessionId !== "all") + .map((session, index) => ({ + name: `Session #${index + 1}`, + value: [ + `**ID:** \`${session.sessionId}\``, + `**Status:** ${STATUS[session.status]()}`, + `**Device:** ${DEVICE[session.clientInfo.client]() || "❓ Unknown"}`, + `**OS:** ${OS[session.clientInfo.os] || "❓ Unknown"}`, + session.activities.length > 0 ? `**Activities:** ${session.activities + .map(activity => { + switch (activity.type) { + case 0: + return ` + ${activity.name}${activity.timestamps?.start ? `, since ` : ""} + ${activity.timestamps?.end ? `, ends ` : ""} + `; + case 1: + return `[${formatWithoutReact( + i18n.Messages.STREAMING, + { name: activity.state } + )}](${activity.url})`; + case 2: + return `${formatWithoutReact( + i18n.Messages.LISTENING_TO, + { name: activity.state } + )}`; + case 3: + return `${formatWithoutReact( + i18n.Messages.WATCHING, + { name: activity.state } + )}`; + case 4: + return `Custom Status: ${activity.emoji?.id + ? `<${activity.emoji.animated ? "a" : ""}:${activity.emoji.name}:${activity.emoji.id}>` + : `${activity.emoji?.name ?? ""} ` || ""} + ${activity.state || ""}`; + case 5: + return `${formatWithoutReact( + i18n.Messages.COMPETING, + { name: activity.state } + )}`; + } + }) + .join("\n ")}` + : false, + session.sessionId === currentSession.sessionId ? "Current Session ✅" : false + ] + .filter(r => r) + .join("\n"), + inline: true + })) + } + ] + }); + } + } + ] +});