Merge branch 'dev'

This commit is contained in:
thororen1234 2025-08-11 22:47:58 -04:00
commit abec6fdba6
No known key found for this signature in database
25 changed files with 76 additions and 214 deletions

View file

@ -4,13 +4,15 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { migratePluginSettings } from "@api/Settings";
import { EquicordDevs } from "@utils/constants";
import { openUserProfile } from "@utils/discord";
import definePlugin from "@utils/types";
import { User } from "@vencord/discord-types";
migratePluginSettings("AlwaysExpandProfiles", "AlwaysExpandProfile");
export default definePlugin({
name: "AlwaysExpandProfile",
name: "AlwaysExpandProfiles",
description: "Always display a user's full popout",
authors: [EquicordDevs.thororen],
patches: [

View file

@ -7,7 +7,7 @@
import "./styles.css";
import { migratePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import { Devs, EquicordDevs } from "@utils/constants";
import definePlugin from "@utils/types";
import { patchActivityList } from "./patch-helpers/activityList";
@ -22,7 +22,8 @@ export default definePlugin({
authors: [
Devs.D3SOX,
Devs.Arjix,
Devs.AutumnVN
Devs.AutumnVN,
EquicordDevs.thororen
],
tags: ["activity"],
@ -59,6 +60,7 @@ export default definePlugin({
},
predicate: () => settings.store.userPopout
},
// DM Sidebar
{
find: ".SIDEBAR}),nicknameIcons",
replacement: {
@ -67,6 +69,7 @@ export default definePlugin({
},
predicate: () => settings.store.userPopout
},
// User Panel
{
find: "#{intl::STATUS_MENU_LABEL}",
replacement: {

View file

@ -6,7 +6,7 @@
import ErrorBoundary from "@components/ErrorBoundary";
import { findComponentByCodeLazy } from "@webpack";
import { Tooltip } from "@webpack/common";
import { React, Tooltip } from "@webpack/common";
import { JSX } from "react";
import { ActivityTooltip } from "../components/ActivityTooltip";
@ -21,7 +21,7 @@ const DefaultActivityIcon = findComponentByCodeLazy("M5 2a3 3 0 0 0-3 3v14a3 3 0
export function patchActivityList({ activities, user, hideTooltip }: ActivityListProps): JSX.Element | null {
const icons: ActivityListIcon[] = [];
if (user.bot || hideTooltip) return null;
if (user.bot || settings.store.hideTooltip && hideTooltip) return null;
const applicationIcons = getApplicationIcons(activities);
if (applicationIcons.length) {

View file

@ -47,7 +47,7 @@ export const settings = definePluginSettings({
<div style={{
width: "100%",
height: 1,
borderTop: "thin solid var(--background-modifier-accent)",
borderTop: "thin solid var(--input-border)",
paddingTop: 5,
paddingBottom: 5
}} />
@ -59,6 +59,11 @@ export const settings = definePluginSettings({
default: true,
restartNeeded: true,
},
hideTooltip: {
type: OptionType.BOOLEAN,
description: "Hides activities in various places",
default: true,
},
allActivitiesStyle: {
type: OptionType.SELECT,
description: "Style for showing all activities",

View file

@ -62,7 +62,7 @@
}
.vc-bactivities-controls [class^="vc-activities-caret-"]:hover:not(.disabled) {
background: var(--background-modifier-accent);
background: var(--input-border);
}
.vc-bactivities-controls .carousel {

View file

@ -68,7 +68,7 @@
.vc-channeltabs-separator {
width: 98%;
height: 1px;
background: var(--background-modifier-accent);
background: var(--input-border);
margin: 4px auto;
}
@ -283,7 +283,7 @@
padding: 0.125rem 0;
min-width: 0;
border-radius: 0.25rem;
border: 1px solid var(--background-modifier-accent);
border: 1px solid var(--input-border);
}
.vc-channeltabs-preview-tab-compact {
@ -312,4 +312,4 @@
/* stylelint-disable-next-line no-descending-specificity */
.vc-channeltabs-tab-container svg {
-webkit-app-region: no-drag;
}
}

View file

@ -14,7 +14,7 @@
.collections-sort-divider {
margin: 10px 0;
border-top: 1px solid var(--background-modifier-accent);
border-top: 1px solid var(--input-border);
}
.collections-sort-description,

View file

@ -23,19 +23,19 @@
justify-content: center;
margin-top: 2px;
padding-top: 12px;
border-top: 1px solid var(--profile-body-divider-color, var(--background-modifier-accent));
border-top: 1px solid var(--profile-body-divider-color, var(--input-border));
}
.vc-github-repos-button,
.vc-github-repos-show-more {
width: 100%;
border: 1px solid var(--profile-body-divider-color, var(--background-modifier-accent)) !important;
border: 1px solid var(--profile-body-divider-color, var(--input-border)) !important;
}
.vc-github-repo-card {
padding: 8px;
border-radius: var(--radius-xs);
border: 1px solid var(--profile-body-divider-color, var(--background-modifier-accent));
border: 1px solid var(--profile-body-divider-color, var(--input-border));
}
.vc-github-repo-header {
@ -103,7 +103,7 @@
}
.vc-github-repos-table thead {
border-bottom: 2px solid var(--background-modifier-accent);
border-bottom: 2px solid var(--input-border);
}
.vc-github-repos-table th {
@ -111,7 +111,7 @@
padding: 10px 16px;
font-weight: 600;
color: var(--header-primary);
border-bottom: 2px solid var(--background-modifier-accent);
border-bottom: 2px solid var(--input-border);
}
.vc-github-repos-table th:last-child {
@ -119,7 +119,7 @@
}
.vc-github-repos-table tbody tr {
border-bottom: 1px solid var(--background-modifier-accent);
border-bottom: 1px solid var(--input-border);
cursor: pointer;
transition: background-color 0.2s ease;
}
@ -131,7 +131,7 @@
.vc-github-repos-table td {
padding: 12px 16px;
vertical-align: middle;
border-bottom: 1px solid var(--background-modifier-accent);
border-bottom: 1px solid var(--input-border);
overflow: hidden;
text-overflow: ellipsis;
}
@ -181,4 +181,4 @@
.vc-github-repos-table-star-icon {
color: var(--text-warning);
}
}

View file

@ -23,7 +23,7 @@
flex-direction: row;
margin-left: 20px;
margin-right: 20px;
border-top: 1px solid var(--background-modifier-accent);
border-top: 1px solid var(--input-border);
border-bottom: 1px solid transparent;
justify-content: space-between;
}

View file

@ -90,7 +90,7 @@ export default definePlugin({
{
find: "#{intl::QUICKSWITCHER_PROTIP}",
replacement: {
match: /(?<=renderResults\(\){)let{query/,
match: /(?<=renderResults\(\){.{0,100})let{query/,
replace: "this.props.results = $self.filteredGuildResults(this.props.results);$&",
},
},

View file

@ -2,7 +2,7 @@
/* stylelint-disable length-zero-no-unit */
/*
$modifier: var(--background-modifier-accent);
$modifier: var(--input-border);
*/
.vc-notebook-search {
@ -65,7 +65,7 @@ $modifier: var(--background-modifier-accent);
border: 0;
height: 2px;
margin: 12px 0px 16px 0px;
background-color: var(--background-modifier-accent);
background-color: var(--input-border);
}
.vc-holy-note [class*="buttonContainer"] {

View file

@ -8,7 +8,7 @@
border-radius: 1rem;
background-color: var(--background-secondary);
border-style: dashed;
border-color: var(--background-modifier-accent);
border-color: var(--input-border);
border-width: 4px;
display: flex;
flex-direction: column;

View file

@ -33,7 +33,7 @@ import { TidalPlayer } from "./tidal/TidalPlayer";
export default definePlugin({
name: "MusicControls",
description: "Music Controls and Lyrics for multiple services ",
authors: [EquicordDevs.thororen, EquicordDevs.vmohammad, Devs.Joona],
authors: [Devs.Ven, Devs.afn, Devs.KraXen72, Devs.Av32000, Devs.nin0dev, EquicordDevs.thororen, EquicordDevs.vmohammad, Devs.Joona],
settings,
patches: [
{

View file

@ -11,6 +11,7 @@ import { ErrorBoundary, openPluginModal } from "@components/index";
import { EquicordDevs } from "@utils/constants";
import { getIntlMessage } from "@utils/index";
import definePlugin, { StartAt } from "@utils/types";
import { onceReady } from "@webpack";
import { ContextMenuApi, Menu, NavigationRouter } from "@webpack/common";
import { JSX } from "react";
@ -1122,6 +1123,17 @@ export default definePlugin({
rerenderQuests();
}
},
LOGOUT(data) {
settings.store.unclaimedUnignoredQuests = 0;
settings.store.onQuestsPage = false;
},
LOGIN_SUCCESS(data) {
onceReady.then(() => {
fetchAndDispatchQuests("Questify", QuestifyLogger);
});
}
},
renderQuestifyButton: ErrorBoundary.wrap(QuestButton, { noop: true }),

View file

@ -149,7 +149,7 @@ export function questIsIgnored(questID: string): boolean {
export function validateIgnoredQuests(ignoredQuests?: string[], questsData?: Quest[]): [string[], number] {
const quests = questsData ?? Array.from(QuestsStore.quests.values()) as Quest[];
const excludedQuests = Array.from(QuestsStore.excludedQuests.values()) as ExcludedQuest[];
const currentlyIgnored = ignoredQuests ? new Set(ignoredQuests) : new Set(getIgnoredQuestIDs());
const currentlyIgnored = ignoredQuests ? new Set(ignoredQuests) : new Set(getIgnoredQuestIDs(questsData?.[0]?.userStatus?.userId));
const validIgnored = new Set<string>();
let numUnclaimedUnignoredQuests = 0;
@ -175,7 +175,7 @@ export function validateIgnoredQuests(ignoredQuests?: string[], questsData?: Que
export function validateAndOverwriteIgnoredQuests(ignoredQuests?: string[], questsData?: Quest[]): string[] {
const [validIgnored, numUnclaimedUnignoredQuests] = validateIgnoredQuests(ignoredQuests, questsData);
settings.store.unclaimedUnignoredQuests = numUnclaimedUnignoredQuests;
setIgnoredQuestIDs(validIgnored);
setIgnoredQuestIDs(validIgnored, questsData?.[0]?.userStatus?.userId);
return validIgnored;
}

View file

@ -106,6 +106,7 @@ export interface Quest {
};
},
userStatus: null | {
userId: string;
claimedAt: string | null;
completedAt: string | null;
enrolledAt: string | null;

View file

@ -25,15 +25,17 @@ export const leftClick = 0;
export const middleClick = 1;
export const rightClick = 2;
export function setIgnoredQuestIDs(questIDs: string[]): void {
const currentUserID = UserStore.getCurrentUser().id;
export function setIgnoredQuestIDs(questIDs: string[], userId?: string): void {
const currentUserID = userId ?? UserStore.getCurrentUser()?.id;
if (!currentUserID) return;
const { ignoredQuestProfile } = settings.store;
const key = ignoredQuestProfile === "shared" ? "shared" : currentUserID;
settings.store.ignoredQuestIDs[key] = questIDs;
}
export function getIgnoredQuestIDs(): string[] {
const currentUserID = UserStore.getCurrentUser().id;
export function getIgnoredQuestIDs(userId?: string): string[] {
const currentUserID = userId ?? UserStore.getCurrentUser()?.id;
if (!currentUserID) return [];
const { ignoredQuestIDs, ignoredQuestProfile } = settings.store;
const key = ignoredQuestProfile === "shared" ? "shared" : currentUserID;
ignoredQuestIDs[key] ??= [];

View file

@ -43,7 +43,7 @@ export default definePlugin({
authors: [EquicordDevs.Jaxx],
patches: [
{
find: '"SearchStore");',
find: '"SearchQueryStore");',
replacement: {
match: /\i\.searchResultsQuery=(\i)/,
replace: "$&,$self.main($1)"

View file

@ -85,14 +85,14 @@
}
.vce-overwrite-modal {
border: 1px solid var(--background-modifier-accent);
border: 1px solid var(--input-border);
border-radius: 8px;
padding: 0.5em;
}
.vce-image-paste {
border-radius: 8px;
border: 3px dashed var(--background-modifier-accent);
border: 3px dashed var(--input-border);
background-color: var(--background-secondary);
padding: 20px;
text-align: center;
@ -115,7 +115,7 @@
.vce-styled-list li {
padding: 10px 0;
border-bottom: thin solid var(--background-modifier-accent);
border-bottom: thin solid var(--input-border);
}
.vce-styled-list li:last-child {
@ -123,7 +123,7 @@
}
.vce-divider-border {
border-bottom: thin solid var(--background-modifier-accent);
border-bottom: thin solid var(--input-border);
padding: 10px 0;
width: 100%;
}

View file

@ -35,10 +35,10 @@ export default definePlugin({
}
},
{
find: ".handleSendMessage,onResize",
find: ".handleSendMessage,onResize:",
replacement: {
// https://regex101.com/r/hBlXpl/1
match: /let (\i)=\i\.\i\.parse\((\i),.+?let (\i)=\i\.\i\.getSendMessageOptions\(\{.+?\}\);(?<=\)\(({.+?})\)\.then.+?)/,
// https://regex101.com/r/7iswuk/1
match: /let (\i)=\i\.\i\.parse\((\i),.+?\.getSendMessageOptions\(\{.+?\}\);(?=.+?(\i)\.flags=)(?<=\)\(({.+?})\)\.then.+?)/,
replace: (m, parsedMessage, channel, replyOptions, extra) => m +
`if(await Vencord.Api.MessageEvents._handlePreSend(${channel}.id,${parsedMessage},${extra},${replyOptions}))` +
"return{shouldClear:false,shouldRefocus:true};"

View file

@ -11,7 +11,7 @@ import { getCurrentChannel } from "@utils/discord";
import definePlugin, { OptionType } from "@utils/types";
import { User } from "@vencord/discord-types";
import { findComponentByCodeLazy } from "@webpack";
import { ContextMenuApi, Menu, useEffect, useRef } from "@webpack/common";
import { ContextMenuApi, Menu } from "@webpack/common";
interface UserProfileProps {
popoutProps: Record<string, any>;
@ -22,7 +22,7 @@ interface UserProfileProps {
const UserProfile = findComponentByCodeLazy(".POPOUT,user");
let openAlternatePopout = false;
let accountPanelRef: React.RefObject<Record<PropertyKey, any> | null> = { current: null };
let accountPanelRef: React.RefObject<HTMLDivElement | null> = { current: null };
const AccountPanelContextMenu = ErrorBoundary.wrap(() => {
const { prioritizeServerProfile } = settings.use(["prioritizeServerProfile"]);
@ -38,8 +38,7 @@ const AccountPanelContextMenu = ErrorBoundary.wrap(() => {
disabled={getCurrentChannel()?.getGuildId() == null}
action={e => {
openAlternatePopout = true;
accountPanelRef.current?.props.onMouseDown();
accountPanelRef.current?.props.onClick(e);
accountPanelRef.current?.click();
}}
/>
<Menu.MenuCheckboxItem
@ -71,10 +70,6 @@ export default definePlugin({
find: "#{intl::ACCOUNT_SPEAKING_WHILE_MUTED}",
group: true,
replacement: [
{
match: /let{ref:\i,speaking:\i/,
replace: "$self.useAccountPanelRef();$&"
},
{
match: /(\.AVATAR,children:.+?renderPopout:\((\i),\i\)=>){(.+?)}(?=,position)(?<=currentUser:(\i).+?)/,
replace: (_, rest, popoutProps, originalPopout, currentUser) => `${rest}$self.UserProfile({popoutProps:${popoutProps},currentUser:${currentUser},originalRenderPopout:()=>{${originalPopout}}})`
@ -84,8 +79,8 @@ export default definePlugin({
replace: "$&$self.onPopoutClose();"
},
{
match: /(?<=#{intl::SET_STATUS}\),)/,
replace: "ref:$self.accountPanelRef,onContextMenu:$self.openAccountPanelContextMenu,"
match: /#{intl::SET_STATUS}\)(?<=innerRef:(\i),style:.+?)/,
replace: "$&,onContextMenu:($self.grabRef($1),$self.openAccountPanelContextMenu)"
}
]
}
@ -95,12 +90,9 @@ export default definePlugin({
return accountPanelRef;
},
useAccountPanelRef() {
useEffect(() => () => {
accountPanelRef.current = null;
}, []);
return (accountPanelRef = useRef(null));
grabRef(ref: React.RefObject<HTMLDivElement>) {
accountPanelRef = ref;
return ref;
},
openAccountPanelContextMenu(event: React.UIEvent) {

View file

@ -1,104 +0,0 @@
/*
* Vencord, a modification for Discord's desktop app
* Copyright (c) 2022 Vendicated and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import "./styles.css";
import { get, set } from "@api/DataStore";
import { updateMessage } from "@api/MessageUpdater";
import { migratePluginSettings } from "@api/Settings";
import { ImageInvisible, ImageVisible } from "@components/Icons";
import { Devs } from "@utils/constants";
import { classes } from "@utils/misc";
import definePlugin from "@utils/types";
import { Message } from "@vencord/discord-types";
import { ChannelStore } from "@webpack/common";
const KEY = "HideAttachments_HiddenIds";
let hiddenMessages = new Set<string>();
async function getHiddenMessages() {
hiddenMessages = await get(KEY) ?? new Set();
return hiddenMessages;
}
const saveHiddenMessages = (ids: Set<string>) => set(KEY, ids);
migratePluginSettings("HideMedia", "HideAttachments");
const hasMedia = (msg: Message) => msg.attachments.length > 0 || msg.embeds.length > 0 || msg.stickerItems.length > 0;
export default definePlugin({
name: "HideMedia",
description: "Hide attachments and embeds for individual messages via hover button",
authors: [Devs.Ven],
dependencies: ["MessageUpdaterAPI"],
patches: [{
find: "this.renderAttachments(",
replacement: {
match: /(?<=\i=)this\.render(?:Attachments|Embeds|StickersAccessories)\((\i)\)/g,
replace: "$self.shouldHide($1?.id)?null:$&"
}
}],
renderMessagePopoverButton(msg) {
if (!hasMedia(msg) && !msg.messageSnapshots.some(s => hasMedia(s.message))) return null;
const isHidden = hiddenMessages.has(msg.id);
return {
label: isHidden ? "Show Media" : "Hide Media",
icon: isHidden ? ImageVisible : ImageInvisible,
message: msg,
channel: ChannelStore.getChannel(msg.channel_id),
onClick: () => this.toggleHide(msg.channel_id, msg.id)
};
},
renderMessageAccessory({ message }) {
if (!this.shouldHide(message.id)) return null;
return (
<span className={classes("vc-hideAttachments-accessory", !message.content && "vc-hideAttachments-no-content")}>
Media Hidden
</span>
);
},
async start() {
await getHiddenMessages();
},
stop() {
hiddenMessages.clear();
},
shouldHide(messageId: string) {
return hiddenMessages.has(messageId);
},
async toggleHide(channelId: string, messageId: string) {
const ids = await getHiddenMessages();
if (!ids.delete(messageId))
ids.add(messageId);
await saveHiddenMessages(ids);
updateMessage(channelId, messageId);
}
});

View file

@ -1,10 +0,0 @@
.vc-hideAttachments-accessory {
color: var(--text-muted);
margin-top: 0.5em;
font-style: italic;
font-weight: 400;
}
.vc-hideAttachments-no-content {
margin-top: 0;
}

View file

@ -29,8 +29,8 @@ import ReviewComponent from "./ReviewComponent";
const Transforms = findByPropsLazy("insertNodes", "textToText");
const Editor = findByPropsLazy("start", "end", "toSlateRange");
const ChatInputTypes = findByPropsLazy("FORM");
const InputComponent = findComponentByCodeLazy("disableThemedBackground", "CHANNEL_TEXT_AREA");
const ChatInputTypes = findByPropsLazy("FORM", "USER_PROFILE");
const InputComponent = findComponentByCodeLazy("editorClassName", "CHANNEL_TEXT_AREA");
const createChannelRecordFromServer = findByCodeLazy(".GUILD_TEXT])", "fromServer)");
interface UserProps {
@ -127,7 +127,7 @@ export function ReviewsInputComponent(
) {
const { token } = Auth;
const editorRef = useRef<any>(null);
const inputType = ChatInputTypes.FORM;
const inputType = ChatInputTypes.USER_PROFILE_REPLY;
inputType.disableAutoFocus = true;
const channel = createChannelRecordFromServer({ id: "0", type: 1 });

View file

@ -9,6 +9,7 @@
}
.vc-rdb-input {
padding-left: 12px;
margin-top: 6px;
margin-bottom: 12px;
resize: none;
@ -134,45 +135,3 @@
.vc-rdb-block-modal-unblock {
cursor: pointer;
}
.vc-rdb-avatar {
z-index: 1 !important;
}
.vc-rdb-white-line {
position: absolute;
left: calc(var(--vc-rdb-avatar-size) / 2);
top: calc(var(--vc-rdb-avatar-size) + 2 * var(--vc-rdb-spacing-size));
width: 2px;
height: calc(100% - var(--vc-rdb-avatar-size) - 4 * var(--vc-rdb-spacing-size) - 2px);
;
border-left: 3px solid gray;
}
.vc-rdb-reply-line {
position: relative;
border: 3px solid gray;
border-top: none;
border-right: none;
border-bottom-left-radius: 20px;
height: calc(8px);
width: calc(24px);
top: calc(var(--vc-rdb-avatar-size) / 2 + 4px);
left: calc(var(--vc-rdb-avatar-size) * -2 - 4px);
}
.vc-rdb-profile-photo-container {
position: relative;
}
.vc-rdb-buttons {
opacity: 0;
}
.vc-rdb-reply:hover>.vc-rdb-buttons {
opacity: 1;
}
.vc-rdb-review:hover>.vc-rdb-buttons {
opacity: 1;
}