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/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
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/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/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/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
+ }))
+ }
+ ]
+ });
+ }
+ }
+ ]
+});
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;
-}