diff --git a/src/equicordplugins/equicordHelper/index.tsx b/src/equicordplugins/equicordHelper/index.tsx index f571b043e..a736a719e 100644 --- a/src/equicordplugins/equicordHelper/index.tsx +++ b/src/equicordplugins/equicordHelper/index.tsx @@ -41,13 +41,19 @@ const settings = definePluginSettings({ description: "Discord hides your own activity buttons for some reason", restartNeeded: true, default: false, + }, + noDefaultHangStatus: { + type: OptionType.BOOLEAN, + description: "Disable the default hang status when joining voice channels", + restartNeeded: true, + default: false, } }); export default definePlugin({ name: "EquicordHelper", description: "Used to provide support, fix discord caused crashes, and other misc features.", - authors: [Devs.thororen, EquicordDevs.nyx, EquicordDevs.Naibuu], + authors: [Devs.thororen, EquicordDevs.nyx, EquicordDevs.Naibuu, EquicordDevs.keyages], required: true, settings, patches: [ @@ -120,6 +126,15 @@ export default definePlugin({ replace: "$& && false" } }, + // No Default Hang Status + { + find: ".CHILLING)", + predicate: () => settings.store.noDefaultHangStatus, + replacement: { + match: /{enableHangStatus:(\i),/, + replace: "{_enableHangStatus:$1=false," + } + }, // Always show open legacy settings ...[ ".DEVELOPER_SECTION,", diff --git a/src/equicordplugins/messageLoggerEnhanced/LoggedMessageManager.ts b/src/equicordplugins/messageLoggerEnhanced/LoggedMessageManager.ts index e83a30e61..5408349e9 100644 --- a/src/equicordplugins/messageLoggerEnhanced/LoggedMessageManager.ts +++ b/src/equicordplugins/messageLoggerEnhanced/LoggedMessageManager.ts @@ -17,18 +17,35 @@ */ import { Flogger, settings } from "."; -import { addMessageIDB, db, DBMessageStatus, deleteMessagesBulkIDB, getOldestMessagesIDB } from "./db"; +import { addMessageIDB, db, DBMessageStatus, deleteMessagesBulkIDB, getOlderThanTimestampForGuildsIDB, getOldestMessagesIDB } from "./db"; import { LoggedMessage, LoggedMessageJSON } from "./types"; import { cleanupMessage } from "./utils"; import { cacheMessageImages } from "./utils/saveImage"; -export const addMessage = async (message: LoggedMessage | LoggedMessageJSON, status: DBMessageStatus) => { +let lastCleanupTime = 0; +const CLEANUP_COOLDOWN = 60 * 1000; + +export const addMessage = async (message: LoggedMessage | LoggedMessageJSON, status: DBMessageStatus, currentChannelId?: string) => { if (settings.store.saveImages && status === DBMessageStatus.DELETED) await cacheMessageImages(message); const finalMessage = cleanupMessage(message); await addMessageIDB(finalMessage, status); + if (settings.store.timeBasedCleanupMinutes > 0) { + const now = Date.now(); + if (now - lastCleanupTime > CLEANUP_COOLDOWN) { + lastCleanupTime = now; + const cutoffTime = new Date(now - settings.store.timeBasedCleanupMinutes * 60 * 1000).toISOString(); + const oldGuildMessages = await getOlderThanTimestampForGuildsIDB(cutoffTime, currentChannelId, settings.store.preserveCurrentChannel); + + if (oldGuildMessages.length > 0) { + Flogger.info(`Deleting ${oldGuildMessages.length} old server messages older than ${settings.store.timeBasedCleanupMinutes} minutes`); + await deleteMessagesBulkIDB(oldGuildMessages.map(m => m.message_id)); + } + } + } + if (settings.store.messageLimit > 0) { const currentMessageCount = await db.count("messages"); if (currentMessageCount > settings.store.messageLimit) { diff --git a/src/equicordplugins/messageLoggerEnhanced/db.ts b/src/equicordplugins/messageLoggerEnhanced/db.ts index db22a62e5..21dcaa3a8 100644 --- a/src/equicordplugins/messageLoggerEnhanced/db.ts +++ b/src/equicordplugins/messageLoggerEnhanced/db.ts @@ -4,6 +4,7 @@ * SPDX-License-Identifier: GPL-3.0-or-later */ +import { ChannelStore } from "@webpack/common"; import { DBSchema, IDBPDatabase, openDB } from "idb"; import { LoggedMessageJSON } from "./types"; @@ -109,6 +110,36 @@ export async function getOldestMessagesIDB(limit: number) { return cacheRecords(await db.getAllFromIndex("messages", "by_timestamp", undefined, limit)); } +export async function getOlderThanTimestampIDB(timestamp: string) { + const tx = db.transaction("messages", "readonly"); + const { store } = tx; + const index = store.index("by_timestamp"); + + const cursor = await index.openCursor(IDBKeyRange.upperBound(timestamp)); + + if (!cursor) { + return []; + } + + const messages: DBMessageRecord[] = []; + for await (const c of cursor) { + messages.push(c.value); + } + + return cacheRecords(messages); +} + +export async function getOlderThanTimestampForGuildsIDB(timestamp: string, currentChannelId?: string, preserveCurrentChannel?: boolean) { + const allOldMessages = await getOlderThanTimestampIDB(timestamp); + return allOldMessages.filter(record => { + const { message } = record; + const channel = ChannelStore.getChannel(message.channel_id); + const isGuildMessage = channel?.guild_id != null; + const isCurrentChannel = preserveCurrentChannel && currentChannelId && message.channel_id === currentChannelId; + return isGuildMessage && !isCurrentChannel; + }); +} + export async function getDateStortedMessagesByStatusIDB(newest: boolean, limit: number, status: DBMessageStatus) { const tx = db.transaction("messages", "readonly"); const { store } = tx; diff --git a/src/equicordplugins/messageLoggerEnhanced/index.tsx b/src/equicordplugins/messageLoggerEnhanced/index.tsx index 5b4f8a536..db9a4238b 100644 --- a/src/equicordplugins/messageLoggerEnhanced/index.tsx +++ b/src/equicordplugins/messageLoggerEnhanced/index.tsx @@ -8,11 +8,11 @@ export const Native = getNative(); import "./styles.css"; -import { Devs } from "@utils/constants"; +import { Devs, EquicordDevs } from "@utils/constants"; import { Logger } from "@utils/Logger"; import definePlugin from "@utils/types"; import { findByPropsLazy } from "@webpack"; -import { FluxDispatcher, MessageStore, UserStore } from "@webpack/common"; +import { FluxDispatcher, MessageStore, SelectedChannelStore, UserStore } from "@webpack/common"; import { LogsIcon, OpenLogsButton } from "./components/LogsButton"; import { openLogModal } from "./components/LogsModal"; @@ -89,7 +89,8 @@ async function messageDeleteHandler(payload: MessageDeletePayload & { isBulk: bo if (payload.isBulk) return message; - await addMessage(message, ghostPinged ? idb.DBMessageStatus.GHOST_PINGED : idb.DBMessageStatus.DELETED); + const currentChannelId = SelectedChannelStore.getChannelId(); + await addMessage(message, ghostPinged ? idb.DBMessageStatus.GHOST_PINGED : idb.DBMessageStatus.DELETED, currentChannelId); } finally { handledMessageIds.delete(payload.id); @@ -105,6 +106,17 @@ async function messageDeleteBulkHandler({ channelId, guildId, ids }: MessageDele } await idb.addMessagesBulkIDB(messages); + + if (messages.length > 0 && settings.store.timeBasedCleanupMinutes > 0) { + const currentChannelId = SelectedChannelStore.getChannelId(); + const cutoffTime = new Date(Date.now() - settings.store.timeBasedCleanupMinutes * 60 * 1000).toISOString(); + const oldGuildMessages = await idb.getOlderThanTimestampForGuildsIDB(cutoffTime, currentChannelId, settings.store.preserveCurrentChannel); + + if (oldGuildMessages.length > 0) { + Flogger.info(`Deleting ${oldGuildMessages.length} old server messages older than ${settings.store.timeBasedCleanupMinutes} minutes (bulk cleanup)`); + await idb.deleteMessagesBulkIDB(oldGuildMessages.map(m => m.message_id)); + } + } } async function messageUpdateHandler(payload: MessageUpdatePayload) { @@ -154,7 +166,8 @@ async function messageUpdateHandler(payload: MessageUpdatePayload) { if (message == null || message.channel_id == null || message.editHistory == null || message.editHistory.length === 0) return; // Flogger.log("ADDING MESSAGE (EDITED)", message, payload); - await addMessage(message, idb.DBMessageStatus.EDITED); + const currentChannelId = SelectedChannelStore.getChannelId(); + await addMessage(message, idb.DBMessageStatus.EDITED, currentChannelId); } function messageCreateHandler(payload: MessageCreatePayload) { @@ -228,7 +241,7 @@ async function processMessageFetch(response: FetchMessagesResponse) { export default definePlugin({ name: "MessageLoggerEnhanced", - authors: [Devs.Aria], + authors: [Devs.Aria, EquicordDevs.keyages], description: "G'day", dependencies: ["MessageLogger"], @@ -261,7 +274,6 @@ export default definePlugin({ replace: "$1childrenAccessories:arguments[0].childrenAccessories || null,childrenHeader:" } }, - // https://regex101.com/r/S3IVGm/1 // fix vidoes failing because there are no thumbnails { diff --git a/src/equicordplugins/messageLoggerEnhanced/settings.tsx b/src/equicordplugins/messageLoggerEnhanced/settings.tsx index 695a999da..fd54ebe2c 100644 --- a/src/equicordplugins/messageLoggerEnhanced/settings.tsx +++ b/src/equicordplugins/messageLoggerEnhanced/settings.tsx @@ -165,6 +165,18 @@ export const settings = definePluginSettings({ description: "Maximum number of messages to store in the cache. Older messages are deleted when the limit is reached. This helps reduce memory usage and improve performance. 0 means there is no limit", }, + timeBasedCleanupMinutes: { + default: 0, + type: OptionType.NUMBER, + description: "Automatically remove messages from servers that are older than this many minutes. Set to 0 to disable time-based cleanup.", + }, + + preserveCurrentChannel: { + default: true, + type: OptionType.BOOLEAN, + description: "When enabled, messages in your currently selected channel are not affected by time-based cleanup.", + }, + whitelistedIds: { default: "", type: OptionType.STRING,