mirror of
https://github.com/Equicord/Equicord.git
synced 2025-03-14 06:00:27 -04:00
210 lines
7.4 KiB
TypeScript
210 lines
7.4 KiB
TypeScript
/*
|
|
* Vencord, a Discord client mod
|
|
* Copyright (c) 2024 Vendicated and contributors
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
*/
|
|
|
|
import { DataStore } from "@api/index";
|
|
import { definePluginSettings } from "@api/Settings";
|
|
import { Devs } from "@utils/constants";
|
|
import definePlugin, { OptionType, PluginNative } from "@utils/types";
|
|
import { ApplicationAssetUtils, FluxDispatcher, UserStore } from "@webpack/common";
|
|
import { Message } from "discord-types/general";
|
|
|
|
export async function getApplicationAsset(key: string): Promise<string> {
|
|
if (/https?:\/\/(cdn|media)\.discordapp\.(com|net)\/attachments\//.test(key)) return "mp:" + key.replace(/https?:\/\/(cdn|media)\.discordapp\.(com|net)\//, "");
|
|
return (await ApplicationAssetUtils.fetchAssetIds("0", [key]))[0];
|
|
}
|
|
|
|
|
|
enum StatsDisplay {
|
|
messagesSentToday,
|
|
messagesSentAllTime,
|
|
mostListenedAlbum
|
|
}
|
|
|
|
const settings = definePluginSettings(
|
|
{
|
|
assetURL: {
|
|
type: OptionType.STRING,
|
|
description: "The image to use for your rpc. Your profile picture is used if left blank",
|
|
default: "",
|
|
restartNeeded: false,
|
|
onChange: () => { updateData(); }
|
|
},
|
|
RPCTitle: {
|
|
type: OptionType.STRING,
|
|
description: "The title for the rpc",
|
|
default: "RPCStats",
|
|
restartNeeded: false,
|
|
onChange: () => { updateData(); }
|
|
},
|
|
statDisplay: {
|
|
type: OptionType.SELECT,
|
|
description: "What should the rpc display? (you can only have one line i'm pretty sure)",
|
|
options: [
|
|
{ value: StatsDisplay.messagesSentToday, label: "The amount of messages sent today", default: true },
|
|
{ value: StatsDisplay.messagesSentAllTime, label: "The amount of messages sent all time" },
|
|
{ value: StatsDisplay.mostListenedAlbum, label: "Your most listened album for the week" }
|
|
],
|
|
restartNeeded: false,
|
|
onChange: () => { updateData(); }
|
|
},
|
|
lastFMApiKey: {
|
|
type: OptionType.STRING,
|
|
description: "Your last.fm API key",
|
|
default: "",
|
|
restartNeeded: false,
|
|
onChange: () => { updateData(); }
|
|
},
|
|
lastFMUsername: {
|
|
type: OptionType.STRING,
|
|
description: "Your last.fm username",
|
|
default: "",
|
|
restartNeeded: false,
|
|
onChange: () => { updateData(); }
|
|
},
|
|
albumCoverImage: {
|
|
type: OptionType.BOOLEAN,
|
|
description: "Should the album cover image be used as the rpc image? (if you have the last fm display chosen)",
|
|
default: true,
|
|
restartNeeded: false,
|
|
onChange: () => { updateData(); }
|
|
},
|
|
lastFMStatFormat: {
|
|
type: OptionType.STRING,
|
|
description: "How should the last fm stat be formatted? $album is replaced with the album name, and $artist is replaced with the artist name",
|
|
default: "Top album this week: \"$album - $artist\"",
|
|
restartNeeded: false,
|
|
onChange: () => { updateData(); }
|
|
}
|
|
});
|
|
|
|
async function setRpc(disable?: boolean, details?: string, imageURL?: string) {
|
|
if (!disable) {
|
|
if (!settings.store.lastFMApiKey.length && settings.store.statDisplay === StatsDisplay.mostListenedAlbum) {
|
|
FluxDispatcher.dispatch({
|
|
type: "LOCAL_ACTIVITY_UPDATE",
|
|
activity: null,
|
|
socketId: "RPCStats",
|
|
});
|
|
}
|
|
}
|
|
const activity = {
|
|
"application_id": "0",
|
|
"name": settings.store.RPCTitle,
|
|
"details": details || "No info right now :(",
|
|
"type": 0,
|
|
"flags": 1,
|
|
"assets": {
|
|
// i love insanely long statements
|
|
"large_image":
|
|
(imageURL == null || !settings.store.albumCoverImage) ?
|
|
await getApplicationAsset(settings.store.assetURL.length ? settings.store.assetURL : UserStore.getCurrentUser().getAvatarURL()) :
|
|
await getApplicationAsset(imageURL)
|
|
}
|
|
};
|
|
FluxDispatcher.dispatch({
|
|
type: "LOCAL_ACTIVITY_UPDATE",
|
|
activity: !disable ? activity : null,
|
|
socketId: "RPCStats",
|
|
});
|
|
}
|
|
|
|
function getCurrentDate(): string {
|
|
const today = new Date();
|
|
const year = today.getFullYear();
|
|
const month = String(today.getMonth() + 1).padStart(2, "0");
|
|
const day = String(today.getDate()).padStart(2, "0");
|
|
return `${year}-${month}-${day}`;
|
|
}
|
|
|
|
interface IMessageCreate {
|
|
type: "MESSAGE_CREATE";
|
|
optimistic: boolean;
|
|
isPushNotification: boolean;
|
|
channelId: string;
|
|
message: Message;
|
|
}
|
|
|
|
const Native = VencordNative.pluginHelpers.RPCStats as PluginNative<typeof import("./native")>;
|
|
|
|
async function updateData() {
|
|
switch (settings.store.statDisplay) {
|
|
case StatsDisplay.messagesSentToday:
|
|
let messagesSent;
|
|
if (await DataStore.get("RPCStatsDate") === getCurrentDate()) {
|
|
messagesSent = await DataStore.get("RPCStatsMessages");
|
|
}
|
|
else {
|
|
await DataStore.set("RPCStatsDate", getCurrentDate());
|
|
await DataStore.set("RPCStatsMessages", 0);
|
|
messagesSent = 0;
|
|
}
|
|
setRpc(false, `Messages sent today: ${messagesSent}\n`);
|
|
break;
|
|
case StatsDisplay.messagesSentAllTime:
|
|
let messagesAllTime = await DataStore.get("RPCStatsAllTimeMessages");
|
|
if (!messagesAllTime) {
|
|
DataStore.set("RPCStatsAllTimeMessages", 0);
|
|
messagesAllTime = 0;
|
|
}
|
|
setRpc(false, `Messages sent all time: ${messagesAllTime}\n`);
|
|
break;
|
|
// slightly cursed
|
|
case StatsDisplay.mostListenedAlbum:
|
|
|
|
const lastFMDataJson = await Native.fetchTopAlbum(
|
|
{
|
|
apiKey: settings.store.lastFMApiKey,
|
|
user: settings.store.lastFMUsername,
|
|
period: "7day"
|
|
});
|
|
|
|
if (lastFMDataJson == null) return;
|
|
|
|
const lastFMData = JSON.parse(lastFMDataJson);
|
|
console.log(lastFMData);
|
|
setRpc(false, settings.store.lastFMStatFormat.replace("$album", lastFMData.albumName).replace("$artist", lastFMData.artistName), lastFMData?.albumCoverUrl);
|
|
break;
|
|
}
|
|
}
|
|
|
|
export default definePlugin({
|
|
name: "RPCStats",
|
|
description: "Displays stats about your activity as an rpc",
|
|
authors: [Devs.Samwich],
|
|
async start() {
|
|
updateData();
|
|
|
|
setInterval(() => {
|
|
checkForNewDay();
|
|
updateData();
|
|
}, 1000);
|
|
|
|
},
|
|
settings,
|
|
stop() {
|
|
setRpc(true);
|
|
},
|
|
flux:
|
|
{
|
|
async MESSAGE_CREATE({ optimistic, type, message }: IMessageCreate) {
|
|
if (optimistic || type !== "MESSAGE_CREATE") return;
|
|
if (message.state === "SENDING") return;
|
|
if (message.author.id !== UserStore.getCurrentUser().id) return;
|
|
await DataStore.set("RPCStatsMessages", await DataStore.get("RPCStatsMessages") + 1);
|
|
await DataStore.set("RPCStatsAllTimeMessages", await DataStore.get("RPCStatsAllTimeMessages") + 1);
|
|
updateData();
|
|
},
|
|
}
|
|
});
|
|
|
|
let lastCheckedDate: string = getCurrentDate();
|
|
|
|
function checkForNewDay(): void {
|
|
const currentDate = getCurrentDate();
|
|
if (currentDate !== lastCheckedDate) {
|
|
lastCheckedDate = currentDate;
|
|
}
|
|
}
|