Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Settings): implement array types #3121

Open
wants to merge 69 commits into
base: dev
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
63eb635
bleh
EepyElvyra Jan 3, 2025
8261629
make textreplace work
EepyElvyra Jan 3, 2025
4f2a87a
add lists to plugin modals (super shitty)
EepyElvyra Jan 3, 2025
83c0290
stuff
EepyElvyra Jan 3, 2025
740780f
renames
EepyElvyra Jan 3, 2025
1c9ed9b
lint
EepyElvyra Jan 3, 2025
8197966
lint
EepyElvyra Jan 3, 2025
abdfea1
rename
EepyElvyra Jan 3, 2025
ab2c9c5
idek fixes or sum
EepyElvyra Jan 3, 2025
2a5d84d
guhhh
EepyElvyra Jan 3, 2025
716b759
update plugins
EepyElvyra Jan 3, 2025
c302b3c
fixes
EepyElvyra Jan 3, 2025
3c10755
remove stuff
EepyElvyra Jan 3, 2025
a314230
Guhh nobody saw this
EepyElvyra Jan 3, 2025
5ae2d03
Don't clear input on error
EepyElvyra Jan 3, 2025
2407cbe
Merge remote-tracking branch 'head/dev' into feat/api/SettingsLists
EepyElvyra Jan 4, 2025
76ff7ed
Merge remote-tracking branch 'refs/remotes/origin/feat/api/SettingsLi…
EepyElvyra Jan 4, 2025
b5c0412
change to javadoc
EepyElvyra Jan 4, 2025
8495294
rework UI
EepyElvyra Jan 4, 2025
202cda9
remove comment
EepyElvyra Jan 4, 2025
148e057
remove unused var
EepyElvyra Jan 4, 2025
1553751
ensure value gets updated correctly
EepyElvyra Jan 4, 2025
f36e5a3
do it nicer
EepyElvyra Jan 4, 2025
60219b3
add usermention component for dms
EepyElvyra Jan 4, 2025
334678d
improve buttons
EepyElvyra Jan 4, 2025
f82cb51
fix
EepyElvyra Jan 4, 2025
7c729de
make searching from modal work
EepyElvyra Jan 5, 2025
5e616fc
fix up some stuff
EepyElvyra Jan 5, 2025
ff95a51
update pindms
EepyElvyra Jan 5, 2025
e08cfc5
fix names & give arrays a default value
EepyElvyra Jan 5, 2025
c3a51cc
fix names & give arrays a default value
EepyElvyra Jan 5, 2025
cfd2969
Merge remote-tracking branch 'origin/feat/api/SettingsLists' into fea…
EepyElvyra Jan 5, 2025
3d444c9
fix name
EepyElvyra Jan 5, 2025
01b9be6
thimgs
EepyElvyra Jan 6, 2025
3db9a00
change a bit more
EepyElvyra Jan 6, 2025
8af0bd5
flip buttons around
EepyElvyra Jan 6, 2025
b04d43d
port console janitor and other stuff
EepyElvyra Jan 9, 2025
9ccdaf4
Merge branch 'refs/heads/dev' into feat/api/SettingsLists
EepyElvyra Jan 9, 2025
b166668
blep
EepyElvyra Jan 10, 2025
1185cb4
Merge branch 'refs/heads/dev' into feat/api/SettingsLists
EepyElvyra Jan 10, 2025
900cd46
it works omg
EepyElvyra Jan 10, 2025
ebd6a2b
remove comments and fix scrolling
EepyElvyra Jan 10, 2025
231d315
add types
EepyElvyra Jan 11, 2025
191b637
add guilds
EepyElvyra Jan 11, 2025
2d09dda
fix no results display
EepyElvyra Jan 11, 2025
567127f
remove comments guh
EepyElvyra Jan 11, 2025
c141b8e
fixes
EepyElvyra Jan 11, 2025
14fe735
Ensure settings get written for message tags
EepyElvyra Jan 11, 2025
6166a8e
fix me being silly with messagetags
EepyElvyra Jan 13, 2025
f5e455e
implement a better way to convert string to array
EepyElvyra Jan 13, 2025
cdeff6a
Merge remote-tracking branch 'origin/feat/api/SettingsLists' into fea…
EepyElvyra Jan 13, 2025
56ed1e7
Merge remote-tracking branch 'head/dev' into feat/api/SettingsLists
EepyElvyra Jan 13, 2025
8d9e9c4
dispatch onchange when checkbox is clicked
EepyElvyra Jan 13, 2025
e6188b7
fix textreplace migration
EepyElvyra Jan 14, 2025
9205b5d
improve styles
EepyElvyra Jan 14, 2025
a62788c
im so tupid sometimes
EepyElvyra Jan 16, 2025
fcdfd07
convert noreplymention setting
EepyElvyra Jan 16, 2025
25dd64d
more slight improvements
EepyElvyra Jan 16, 2025
0a96e1a
remove useless code
EepyElvyra Jan 16, 2025
6ddf203
revert the changes that migrate datastore to array settings
EepyElvyra Jan 19, 2025
bc843c3
revert the changes that migrate datastore to array settings v2
EepyElvyra Jan 19, 2025
de2f1d5
Merge branch 'dev' into feat/api/SettingsLists
EepyElvyra Jan 23, 2025
9cee56e
minor fixes
EepyElvyra Jan 23, 2025
e19937d
ImageZoom: Fix incorrectly adding context menu in some places (#3150)
sadan4 Jan 25, 2025
b44e27d
Merge branch 'dev' into feat/api/SettingsLists
EepyElvyra Jan 25, 2025
5508d89
Merge branch 'dev' into feat/api/SettingsLists
EepyElvyra Jan 25, 2025
e8be962
Merge branch 'dev' into feat/api/SettingsLists
EepyElvyra Jan 26, 2025
d66a69e
Merge branch 'dev' into feat/api/SettingsLists
EepyElvyra Jan 27, 2025
ccd42a9
Idk tbh
EepyElvyra Jan 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
stuff
EepyElvyra committed Jan 3, 2025

Verified

This commit was signed with the committer’s verified signature.
caixw caixw
commit 83c0290549e43b9ef140f3aea5fa46348675930b
2 changes: 1 addition & 1 deletion src/components/PluginSettings/PluginModal.tsx
Original file line number Diff line number Diff line change
@@ -83,7 +83,7 @@ const Components: Record<OptionType, React.ComponentType<ISettingElementProps<an
[OptionType.SELECT]: SettingSelectComponent,
[OptionType.SLIDER]: SettingSliderComponent,
[OptionType.COMPONENT]: SettingCustomComponent,
[OptionType.LIST]: SettingListComponent,
[OptionType.ARRAY]: SettingListComponent,
[OptionType.USERS]: SettingListComponent,
[OptionType.CHANNELS]: SettingListComponent,
[OptionType.GUILDS]: SettingListComponent
134 changes: 85 additions & 49 deletions src/components/PluginSettings/components/SettingListComponent.tsx
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ import { Margins } from "@utils/margins";
import { wordsFromCamel, wordsToTitle } from "@utils/text";
import { OptionType, PluginOptionList } from "@utils/types";
import { findComponentByCodeLazy } from "@webpack";
import { Button,ChannelStore, Forms, GuildStore, React, useState } from "@webpack/common";
import { Button, ChannelStore, Forms, GuildStore, React, TextInput, useState } from "@webpack/common";

import { ISettingElementProps } from ".";
import { Channel } from "discord-types/general";
@@ -35,6 +35,13 @@ const CloseIcon = () => {
</svg>;
};

const CheckMarkIcon = () => {
return <svg width="24" height="24" viewBox="0 0 24 24">
<path fill="currentColor" d="M21.7 5.3a1 1 0 0 1 0 1.4l-12 12a1 1 0 0 1-1.4 0l-6-6a1 1 0 1 1 1.4-1.4L9 16.58l11.3-11.3a1 1 0 0 1 1.4 0Z"></path>
</svg>;
};


interface UserMentionComponentProps {
id: string;
channelId: string;
@@ -52,30 +59,21 @@ export function SettingListComponent({
const [error, setError] = useState<string | null>(null);

const [items, setItems] = useState<string[]>([]);
const [newItem, setNewItem] = useState<string>("");

const addItem = () => {
if (newItem.trim() !== "") {
setItems([...items, newItem]);
setNewItem("");
}
pluginSettings[id] = items;
};

if (items.length === 0 && pluginSettings[id].length !== 0) {
setItems(pluginSettings[id]);
}

const removeItem = (index: number) => {
if (items.length === 1) {
setItems([]);
pluginSettings[id] = [];
return;
}
setItems(items.filter((_, i) => i !== index));
pluginSettings[id] = items;
};


function handleChange(newValue) {
onChange(newValue);
}

function wrapChannel(id: string) {
const channel = ChannelStore.getChannel(id) as Channel;
if (!channel) {
@@ -84,48 +82,86 @@ export function SettingListComponent({
return (GuildStore.getGuild(channel.guild_id)?.name ?? "Unknown Guild") + " - " + channel.name;
}

/* Pseudocode for handling submit */
function handleSubmit() {
// Handle the submit action for the specific item
// This could involve updating the state, making an API call, etc.
// Clear the input field after submission
const inputElement = document.getElementById(`vc-plugin-modal-input-${option.type === OptionType.CHANNELS ? "channel" : option.type === OptionType.GUILDS ? "guild" : option.type === OptionType.USERS ? "user" : "string"}`);
if (!inputElement || inputElement.value === "") {
return;
}
// TODO add searching for users, channels, and guilds lol
setItems([...items, inputElement.value]);
pluginSettings[id] = items;
inputElement.value = "";
}


// FIXME make channels and guilds nicer!
// TODO make string type work
return (
<Forms.FormSection>
<Forms.FormTitle>{wordsToTitle(wordsFromCamel(id))}</Forms.FormTitle>
<Forms.FormText className={Margins.bottom16} type="description">{option.description}</Forms.FormText>
<ErrorBoundary noop>
{items.map((item, index) => (
<React.Fragment key={`${item}-${index}`}>
<Flex
flexDirection="row"
style={{
gap: "1px",
}}
>
{option.type === OptionType.USERS ? (
<UserMentionComponent
userId={item}
className="mention"
/>
) : option.type === OptionType.CHANNELS ? (
<span style={{ color: "white" }}>{wrapChannel(item)}</span>
) : option.type === OptionType.GUILDS ? (
<span style={{ color: "white" }}>
{GuildStore.getGuild(item)?.name || "Unknown Guild"}
</span>
// TODO add logo to guild and channel?
) : (
<span>{item}</span>
)}
<Button
size={Button.Sizes.MIN}
onClick={() => removeItem(index)}
style={
{ background: "none", }
}
<React.Fragment>
{items.map((item, index) => (
<Flex
flexDirection="row"
style={{
gap: "1px",
}}
>
<CloseIcon />
</Button>
{option.type === OptionType.USERS ? (
<UserMentionComponent
userId={item}
className="mention"
/>
) : option.type === OptionType.CHANNELS ? (
<span style={{ color: "white" }}>{wrapChannel(item)}</span>
) : option.type === OptionType.GUILDS ? (
<span style={{ color: "white" }}>
{GuildStore.getGuild(item)?.name || "Unknown Guild"}
</span>
// TODO add logo to guild and channel?
) : (
<span style={{ color: "white" }}>{item}</span>
)}
<Button
size={Button.Sizes.MIN}
onClick={() => removeItem(index)}
style={
{ background: "none", }
}
>
<CloseIcon/>
</Button>
</Flex>
</React.Fragment>
))}

))}
<Flex
flexDirection="row"
style={{
gap: "5px",
marginTop: "10px",
}}
>
{/* Add a single input field */}
<TextInput
type="text"
placeholder="Add Item"
id={`vc-plugin-modal-input-${option.type === OptionType.CHANNELS ? "channel" : option.type === OptionType.GUILDS ? "guild" : option.type === OptionType.USERS ? "user" : "string"}`}
/>
{/* Add a submit button */}
<Button
size={Button.Sizes.MIN}
onClick={handleSubmit}
style={{ background: "none" }}
>
<CheckMarkIcon/>
</Button>
</Flex>
</React.Fragment>
</ErrorBoundary>


19 changes: 7 additions & 12 deletions src/plugins/loadingQuotes/index.ts
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

import { definePluginSettings } from "@api/Settings";
import { definePluginSettings, migrateSettingsToArrays } from "@api/Settings";
import { Devs } from "@utils/constants";
import { Logger } from "@utils/Logger";
import definePlugin, { OptionType } from "@utils/types";
@@ -25,6 +25,8 @@ import presetQuotesText from "file://quotes.txt";
const presetQuotes = presetQuotesText.split("\n").map(quote => /^\s*[^#\s]/.test(quote) && quote.trim()).filter(Boolean) as string[];
const noQuotesQuote = "Did you really disable all loading quotes? What a buffoon you are...";

migrateSettingsToArrays("LoadingQuotes", ["additionalQuotes"], "|");

const settings = definePluginSettings({
replaceEvents: {
description: "Should this plugin also apply during events with special event themed quotes? (e.g. Halloween)",
@@ -42,14 +44,8 @@ const settings = definePluginSettings({
default: false
},
additionalQuotes: {
description: "Additional custom quotes to possibly appear, separated by the below delimiter",
type: OptionType.STRING,
default: "",
},
additionalQuotesDelimiter: {
description: "Delimiter for additional quotes",
type: OptionType.STRING,
default: "|",
description: "Additional custom quotes to possibly appear",
type: OptionType.ARRAY,
},
});

@@ -79,16 +75,15 @@ export default definePlugin({

mutateQuotes(quotes: string[]) {
try {
const { enableDiscordPresetQuotes, additionalQuotes, additionalQuotesDelimiter, enablePluginPresetQuotes } = settings.store;
const { enableDiscordPresetQuotes, additionalQuotes, enablePluginPresetQuotes } = settings.store;

if (!enableDiscordPresetQuotes)
quotes.length = 0;


if (enablePluginPresetQuotes)
quotes.push(...presetQuotes);

quotes.push(...additionalQuotes.split(additionalQuotesDelimiter).filter(Boolean));
quotes.push(...additionalQuotes);

if (!quotes.length)
quotes.push(noQuotesQuote);
4 changes: 2 additions & 2 deletions src/plugins/textReplace/index.tsx
Original file line number Diff line number Diff line change
@@ -72,12 +72,12 @@ const settings = definePluginSettings({
}
},
stringRules: {
type: OptionType.LIST,
type: OptionType.ARRAY,
hidden: true,
description: ""
},
regexRules: {
type: OptionType.LIST,
type: OptionType.ARRAY,
hidden: true,
description: ""
},
6 changes: 3 additions & 3 deletions src/utils/types.ts
Original file line number Diff line number Diff line change
@@ -167,7 +167,7 @@ export const enum OptionType {
SELECT,
SLIDER,
COMPONENT,
LIST,
ARRAY,
USERS, // List of users
CHANNELS, // List of channels
GUILDS, // List of guilds
@@ -265,7 +265,7 @@ export interface PluginSettingSliderDef {
}

export interface PluginSettingListDef{
type: OptionType.LIST | OptionType.CHANNELS | OptionType.GUILDS | OptionType.USERS;
type: OptionType.ARRAY | OptionType.CHANNELS | OptionType.GUILDS | OptionType.USERS;
popoutText?: string;
hidePopout?: boolean;
}
@@ -305,7 +305,7 @@ type PluginSettingType<O extends PluginSettingDef> = O extends PluginSettingStri
O extends PluginSettingComponentDef ? any :
O extends PluginSettingListDef ? any[] :
never;
type PluginSettingDefaultType<O extends PluginSettingDef> = O extends PluginSettingSelectDef ? (
type PluginSettingDefaultType<O extends PluginSettingDef> = O extends PluginSettingListDef ? any[] : O extends PluginSettingSelectDef ? (
O["options"] extends { default?: boolean; }[] ? O["options"][number]["value"] : undefined
) : O extends { default: infer T; } ? T : undefined;