Plugin
CustomAppIcons
Add/upload custom (In-)App Icons.
1
/*2
* FiveCord — a Discord client mod3
* Copyright (c) 2025 FiveCord4
* SPDX-License-Identifier: GPL-3.0-or-later5
*/6
7
import { Link } from "@components/Link";8
import { Devs } from "@utils/constants";9
import { localStorage } from "@utils/localStorage";10
import { closeAllModals, openModal } from "@utils/modal";11
import definePlugin from "@utils/types";12
import { findByProps } from "@webpack";13
import { Button, FluxDispatcher, Forms, React, showToast, Toasts } from "@webpack/common";14
15
import AppIconModal from "./AppIconModal";16
17
function removeAppIcon() {18
const current_icon = findByProps("getCurrentDesktopIcon").getCurrentDesktopIcon();19
let icons = JSON.parse(localStorage.getItem("vc_app_icons") || "[]");20
const index = icons.findIndex(icon => current_icon === icon.id);21
if (index !== -1) {22
icons = icons.filter(e => e.id !== current_icon);23
delete findByProps("ICONS", "ICONS_BY_ID").ICONS_BY_ID[current_icon];24
delete findByProps("ICONS", "ICONS_BY_ID").ICONS[findByProps("ICONS", "ICONS_BY_ID").ICONS.findIndex((icon => current_icon === icon?.id))];25
localStorage.setItem("vc_app_icons", JSON.stringify(icons));26
showToast("Icon successfully deleted!", Toasts.Type.SUCCESS);27
FluxDispatcher.dispatch({28
type: "APP_ICON_UPDATED",29
id: "AppIcon"30
});31
} else {32
showToast("Cannot delete native App Icons!", Toasts.Type.FAILURE);33
return;34
}35
36
}37
38
39
export default definePlugin({40
name: "CustomAppIcons",41
description: "Add/upload custom (In-)App Icons.",42
authors: [Devs.FiveCord],43
patches: [44
{45
find: ".PremiumUpsellTypes.APP_ICON_UPSELL",46
replacement: [47
{48
match: /\w+\.jsx\)\(\w+,{markAsDismissed:\w+,isCoachmark:\w+}\)/,49
replace(str) {50
return str + ",$self.addButtons()";51
}52
}53
]54
}55
],56
57
58
start() {59
const appIcons = JSON.parse(localStorage.getItem("vc_app_icons") ?? "[]");60
for (const icon of appIcons) {61
findByProps("ICONS", "ICONS_BY_ID").ICONS.push(icon);62
findByProps("ICONS", "ICONS_BY_ID").ICONS_BY_ID[icon.id] = icon;63
}64
},65
stop() {66
67
},68
addButtons() {69
70
const { editorFooter } = findByProps("editorFooter");71
return (72
<>73
<Button color={Button.Colors.BRAND_NEW} size={Button.Sizes.MEDIUM} className={editorFooter} onClick={() => {74
openModal(props => <AppIconModal {...props} />);75
}}>76
Add Custom App Icon77
</Button>78
<Button color={Button.Colors.RED} size={Button.Sizes.MEDIUM} className={editorFooter} onClick={removeAppIcon}>79
Remove Custom selected App Icon80
</Button>81
</>82
);83
},84
85
settingsAboutComponent: () => {86
return (87
<><Forms.FormTitle>88
<Forms.FormTitle>How to use?</Forms.FormTitle>89
</Forms.FormTitle>90
<Forms.FormText>91
<Forms.FormText>Go to <Link href="/settings/appearance" onClick={e => { e.preventDefault(); closeAllModals(); FluxDispatcher.dispatch({ type: "USER_SETTINGS_MODAL_SET_SECTION", section: "Appearance" }); }}>Appearance Settings</Link> tab.</Forms.FormText>92
<Forms.FormText>Scroll down to "In-app Icons" and click on "Preview App Icon".</Forms.FormText>93
<Forms.FormText>And upload your own custom icon!</Forms.FormText>94
<Forms.FormText>You can only use links when you are uploading your Custom Icon.</Forms.FormText>95
</Forms.FormText></>96
);97
}98
});99