Vencord icon indicating copy to clipboard operation
Vencord copied to clipboard

feat(Settings)!: implement array types

Open EepyElvyra opened this issue 11 months ago โ€ข 8 comments

This PR implements: #615 #2210

New option types:

  • OptionType.ARRAY
  • OptionType.USERS
  • OptionType.CHANNELS
  • OptionType.GUILDS

these replace the previously used strings with separators. Additionally, context menu entries are generated for all user, channel and guild options.

Since IDs are not user-friendly, this PR additionally implements a Modal replicating Discord's forwarding Modal to search for users/channels/guilds by text.

Warning: make a backup of your settings before trying this for testing as the changes made are incompatible with the current codebase and things will break if you rollback.

EepyElvyra avatar Jan 03 '25 20:01 EepyElvyra

I think this is ready now

EepyElvyra avatar Jan 11 '25 01:01 EepyElvyra

@CodiumAI-Agent /review

EepyElvyra avatar Jan 11 '25 19:01 EepyElvyra

PR Reviewer Guide ๐Ÿ”

(Review updated until commit https://github.com/Vendicated/Vencord/commit/86747641741f9edcf892c6b04650384c3b9c88bd)

Here are some key observations to aid the review process:

๐ŸŽซ Ticket compliance analysis ๐Ÿ”ถ

615 - Fully compliant

Fully compliant requirements:

  • Implement an array option type for settings.
  • Replace the current string-separated input method with a more user-friendly UI.
  • Provide a modal for searching and selecting users, channels, or guilds.

Not compliant requirements:

  • None

2210 - Partially compliant

Fully compliant requirements:

  • Create an API for allow/deny lists for users, guilds, and channels.
  • Provide a UI helper for managing these lists.

Not compliant requirements:

  • Support filtering by ID, name substring, and guild role for users.
โฑ๏ธย Estimated effort to review: 5 ๐Ÿ”ต๐Ÿ”ต๐Ÿ”ต๐Ÿ”ต๐Ÿ”ต
๐Ÿงชย No relevant tests
๐Ÿ”’ย No security concerns identified
โšกย Recommended focus areas for review

Possible Issue

The handleSubmit function does not validate whether the text input matches the expected format for the specific OptionType. This could lead to invalid entries being added to the array.

function handleSubmit() {
    if (items.includes(text)) {
        setError("This item is already added");
        setText("");
        return;
    }

    setItems([...items, text]);

    setText("");
    setError(null);
Performance Concern

The filterResults function appears to perform multiple iterations over the results array, which might impact performance for large datasets. Consider optimizing this logic.


function filterResults(props: {
    results: Result[];
    hasQuery: boolean;
    frequentChannels: Channel[];
    channelHistory: string[];
    guilds: GuildResult[]
}): Result[] {
    const removeDuplicates = (arr: Result[]): Result[] => {
        const clean: any[] = [];
        const seenIds = new Set();
        arr.forEach(item => {
            if (item == null || item.record == null) return;
            if (!seenIds.has(item.record.id)) {
                seenIds.add(item.record.id);
                clean.push(item);
            }
        });
        return clean;
    };

    const { results, hasQuery, frequentChannels, channelHistory, guilds } = props;
    if (hasQuery) return filterItems(results);

    const recentDestinations = filterItems([
        ...(channelHistory.length > 0 ? channelHistory.map(e => convertItem(e)) : []),
        ...(frequentChannels.length > 0 ? frequentChannels.map(e => convertItem(e.id)) : []),
        ...guilds
    ]);

    return removeDuplicates(
        [...(selected.length > 0 ? selected.map(e => getItem(e)) : []),
            ...recentDestinations
        ]);
}
Context Menu Logic

The MakeContextCallback function does not handle cases where value.id is undefined or invalid, which could lead to runtime errors.

return (children, props) => {
    if (!registeredPlugins[OptionType.CHANNELS] && !registeredPlugins[OptionType.USERS] && !registeredPlugins[OptionType.GUILDS])
        return;
    const value = props[name.toLowerCase()];
    if (!value) return;
    if (props.label === getIntlMessage("CHANNEL_ACTIONS_MENU_LABEL")) return; // random shit like notification settings

    const lastChild = children.at(-1);
    if (lastChild?.key === "developer-actions") {
        const p = lastChild.props;
        if (!Array.isArray(p.children))
            p.children = [p.children];

        children = p.children;
    }
    children.splice(-1, 0,
        createContextMenu(name, value)
    );
};

QodoAI-Agent avatar Jan 11 '25 19:01 QodoAI-Agent

@CodiumAI-Agent /review

EepyElvyra avatar Jan 11 '25 19:01 EepyElvyra

Persistent review updated to latest commit https://github.com/Vendicated/Vencord/commit/14fe735fc43b7f090953979101741a76a4627f30

QodoAI-Agent avatar Jan 11 '25 19:01 QodoAI-Agent

i tried to fix conflicts but borked smth :P

Vendicated avatar Jan 23 '25 02:01 Vendicated

Persistent review updated to latest commit https://github.com/Vendicated/Vencord/commit/86747641741f9edcf892c6b04650384c3b9c88bd

QodoAI-Agent avatar Jan 23 '25 02:01 QodoAI-Agent

bump

EepyElvyra avatar Feb 23 '25 22:02 EepyElvyra

lowkey i cba to maintain this or fix it again and i dont think itll ever get merged sooo

EepyElvyra avatar Apr 09 '25 11:04 EepyElvyra