Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 7 additions & 7 deletions .github/workflows/test_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ jobs:
uses: actions/checkout@v4

- name: Clone Vencord
run: git clone --depth=1 https://github.com/Vendicated/Vencord.git vencord
run: git clone --depth=1 https://github.com/Equicord/Equicord.git Equicord

- name: Move current repo into Vencord plugins
- name: Move current repo into Equicord plugins
run: |
PLUGIN_NAME=$(basename $GITHUB_REPOSITORY)
mkdir -p vencord/src/plugins/$PLUGIN_NAME
mkdir -p Equicord/src/plugins/$PLUGIN_NAME
shopt -s extglob
cp -r !(vencord|.git|.github) vencord/src/plugins/$PLUGIN_NAME/
cp -r !(Equicord|.git|.github) Equicord/src/plugins/$PLUGIN_NAME/

- name: Setup Node.js
uses: actions/setup-node@v4
Expand All @@ -37,13 +37,13 @@ jobs:
run: npm install -g pnpm

- name: Install dependencies
working-directory: vencord
working-directory: Equicord
run: pnpm install

- name: Run pnpm build
working-directory: vencord
working-directory: Equicord
run: pnpm build

- name: Run pnpm buildWeb
working-directory: vencord
working-directory: Equicord
run: pnpm buildWeb
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,5 +94,5 @@ If you feel loved or interested in this project, you can leave us a **star** and
<br>
<div align="center">
<img src="https://i.imgur.com/iDlsg7L.png" alt="Lumi Logo" width="100">
<h6>@2023-2025 <strong>Lumi Comunity</strong></h6>
<h6>@2023-2025 <strong>Lumi Community</strong></h6>
</div>
11 changes: 5 additions & 6 deletions docs/ru/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
<h1><img src="https://i.imgur.com/iDlsg7L.png" alt="Lumi Logo" width="25"><strong>・fakeProfile</strong></h1>
Плагин <strong>всё в одном</strong> для кастомизации вашего Discord-профиля
<br>
<a href="https://github.com/TheLumiDevs/fakeProfile"><img src="https://flagicons.lipis.dev/flags/4x3/us.svg" alt="en_US" width="25"></a>
<a href="https://github.com/gujarathisampath/fakeProfile"><img src="https://flagicons.lipis.dev/flags/4x3/us.svg" alt="en_US" width="25"></a>
<br>
<h6>Хотите перевести? Пожалуйста, сделайте форк и сделайте запрос вашего перевода.</h6>
<h6>Этот репозиторий является форком <a href="https://github.com/gujarathisampath/fakeProfile">основного fakeProfile</a>, пожалуйста оставьте звезду в нём.</h6>
</div>

<!-- MARKDOWN BADGED -->
Expand All @@ -16,7 +15,7 @@
<img src="https://img.shields.io/badge/CSS-239120?&style=for-the-badge&logo=css3&logoColor=white" alt="CSS"></a>
<a href="https://discord.gg/ffmkewQ4R7"><img src="https://img.shields.io/badge/Discord-%235865F2.svg?style=for-the-badge&logo=discord&logoColor=white" alt="Discord Server"></a>
<br>
<a href="https://github.com/TheLumiDevs/fakeProfile/commits/main/"><img src="https://img.shields.io/github/last-commit/TheLumiDevs/fakeProfile?&style=for-the-badge&color=FFFFFF&logoColor=D9E0EE&labelColor=42A5F5%22width=%22200"></a>
<a href="https://github.com/gujarathisampath/fakeProfile/commits/main/"><img src="https://img.shields.io/github/last-commit/gujarathisampath/fakeProfile?&style=for-the-badge&color=FFFFFF&logoColor=D9E0EE&labelColor=42A5F5%22width=%22200"></a>
<br>
<h6><strong>Поддержка трёх клиентов</strong></h6>
<a href="https://github.com/pyoncord/Bunny"><img src="https://i.imgur.com/YjtQqBQ.png" alt="Pyoncord" width="50"></a>
Expand Down Expand Up @@ -68,8 +67,8 @@
Если вам понравился или заинтересованы в этом проекте, - вы можете оставить **звезду** и поделиться этим проектом с людьми, которые хотят что и вы. Это будет отличной мотивацией для нас, чтобы продолжить разработку этого проекта, чтобы сделать даже лучше. Спасибо вам огромное.

<p align="center">
<a href="https://github.com/TheLumiDevs/fakeProfile" style="pointer-events: none; cursor: default;">
<img src="https://m3-markdown-badges.vercel.app/stars/2/2//TheLumiDevs/fakeProfile" alt="Leave us a star" width="200">
<a href="https://github.com/gujarathisampath/fakeProfile" style="pointer-events: none; cursor: default;">
<img src="https://m3-markdown-badges.vercel.app/stars/2/2//gujarathisampath/fakeProfile" alt="Leave us a star" width="200">
</a>
</p>

Expand All @@ -80,5 +79,5 @@
<br>
<div align="center">
<img src="https://i.imgur.com/iDlsg7L.png" alt="Lumi Logo" width="100">
<h6>@2023-2025 <strong>Lumi Comunity</strong></h6>
<h6>@2023-2025 <strong>Lumi Community</strong></h6>
</div>
2 changes: 1 addition & 1 deletion index.css
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@

.custom-nameplate ~ div {
z-index: 1;
}
}
26 changes: 19 additions & 7 deletions index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default definePlugin({
name: "Sampath",
id: 984015688807100419n,
}],
dependencies: ["MessageDecorationsAPI", "BadgeAPI"],
dependencies: ["MessageDecorationsAPI", "BadgeAPI", "MemberListDecoratorsAPI"],
start: async () => {
enableStyle(style);
useUsersProfileStore.getState().fetchBadges();
Expand Down Expand Up @@ -158,7 +158,7 @@ export default definePlugin({
{
match: /(?<=\),nameplate:)(\i)/,
replace: "$self.nameplate($1)"
}
},
]
},
{
Expand All @@ -167,6 +167,15 @@ export default definePlugin({
match: /children:\[(?=.{0,100}\.MEMBER_LIST)/,
replace: "$&arguments[0].banner,"
}
},
{
find: ".WIDGETS_RTC_UPSELL_COACHMARK),",
replacement: [
{
match: /(?<=\i\)\({avatarDecoration:)\i(?=,)(?<=currentUser:(\i).+?)/,
replace: "$self.useUserAvatarDecoration($1)??$&"
}
]
}
],
profileDecodeHook(user: UserProfile) {
Expand Down Expand Up @@ -244,12 +253,15 @@ export default definePlugin({
nameplate(nameplate: Nameplate | undefined) {
return nameplate;
},
customnameplate(user: User, nameplate: Nameplate | undefined) {
const userId = user?.id;
const userData = useUsersProfileStore.getState().get(userId);
customnameplate(user: User | undefined, nameplate: Nameplate | undefined) {
if (!user) return null;
const userData = useUsersProfileStore.getState().get(user.id);
if (userData && userData?.nameplate && settings.store.enableNameplate) {
const url = userData.nameplate;
const urlStr = typeof url === "object" ? JSON.stringify(url) : url;
const raw = userData.nameplate;
const urlStr = typeof raw === "object" && raw !== null
? (raw as Nameplate).src
: raw as string;
if (!urlStr) return null;
return (<img id={`custom-nameplate-${user.id}`} src={urlStr} className="custom-nameplate" />);
}
return null;
Expand Down
4 changes: 2 additions & 2 deletions lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ export interface Decors {
}

export const getEffects = async (): Promise<ProfileEffects[]> => fetch(BASE_URL + "/profile-effects").then(c => c.json());
export const getBadges = async (): Promise<Badge[]> => fetch(BASE_URL + "/badges").then(c => c.json());
export const getBadges = async (): Promise<Record<string, Badge[]>> => fetch(BASE_URL + "/badges").then(c => c.json());

export const getPresets = async (): Promise<Decors[]> => fetch(BASE_URL + "/decorations").then(c => c.json());

export const getUsers = async (ids?: string[]): Promise<Record<string, string | null>> => {
export const getUsers = async (ids?: string[]): Promise<Record<string, Partial<UserProfile> | null>> => {
if (ids?.length === 0) return {};

const url = new URL(BASE_URL + "/users");
Expand Down
90 changes: 48 additions & 42 deletions lib/stores/UsersProfileStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,54 +51,59 @@ export const useUsersProfileStore = proxyLazy(() => zustandCreate((set: any, get
fetchBadges: debounce(async () => {
if (!settings.store.enableCustomBadges) return;

const { addedBadges } = get();

addedBadges.forEach(badge => removeProfileBadge(badge));

const fetchedBadges = await getBadges();
const newBadges = new Map(
Object.entries(fetchedBadges).map(([key, value]) => [key, value])
);

const newAddedBadges: any[] = [];

newBadges.forEach((userBadges, userId) => {
if (Array.isArray(userBadges)) {
userBadges.forEach(badge => {
const newBadge = {
id: "new_badges_profile_badge",
iconSrc: badge.badge,
description: badge.tooltip,
position: BadgePosition.START,
shouldShow: ({ userId: badgeUserId }) => badgeUserId === userId,
...(badge.badge_id && { id: badge.badge_id })
} satisfies ProfileBadge;

addProfileBadge(newBadge);
newAddedBadges.push(newBadge);
});
}
});

set({
badges: newBadges,
addedBadges: newAddedBadges,
});
try {
const { addedBadges } = get();

addedBadges.forEach(badge => removeProfileBadge(badge));

const fetchedBadges = await getBadges();

if (!fetchedBadges || typeof fetchedBadges !== "object" || Array.isArray(fetchedBadges)) return;

const newBadges = new Map(
Object.entries(fetchedBadges).map(([key, value]) => [key, value])
);

const newAddedBadges: any[] = [];

newBadges.forEach((userBadges, userId) => {
if (Array.isArray(userBadges)) {
userBadges.forEach(badge => {
if (!badge?.badge) return;
const newBadge: ProfileBadge = {
id: badge.badge_id ?? badge.badge,
iconSrc: badge.badge,
description: badge.tooltip,
position: BadgePosition.START,
shouldShow: ({ userId: badgeUserId }) => badgeUserId === userId,
};
addProfileBadge(newBadge);
newAddedBadges.push(newBadge);
});
}
});

set({
badges: newBadges,
addedBadges: newAddedBadges,
});
} catch (e) {
console.error("[fakeProfile] fetchBadges failed:", e);
}
}),
fetchProfileEffects: debounce(async () => {
const { profileEffects } = get();
const fetchedProfileEffects = await getEffects();
const newProfileEffects = new Map(
Object.entries(fetchedProfileEffects).map(([key, value]) => [key, value])
if (!Array.isArray(fetchedProfileEffects)) return;
const newProfileEffects = new Map<string, ProfileEffects>(
fetchedProfileEffects.map(effect => [effect.skuId, effect])
);
set({
profileEffects: newProfileEffects,
});

}),
fetchDecorations: debounce(async () => {
const { decorations } = get();
const fetchedDecorations = await getPresets();
if (!Array.isArray(fetchedDecorations)) return;
const newDecorations = new Map(
fetchedDecorations.map(decoration => [decoration.asset, decoration])
);
Expand Down Expand Up @@ -199,12 +204,13 @@ export function useUserAvatarDecoration(user?: User): Decoration | null | undefi
return destructor;
}, []);
if (AvatarDecoration) {
const decoration = useUsersProfileStore.getState().decorations.get(AvatarDecoration);
let decoration = useUsersProfileStore.getState().decorations.get(AvatarDecoration);
if (!decoration) {
useUsersProfileStore.getState().fetchDecorations();
const decoration = useUsersProfileStore.getState().decorations.get(AvatarDecoration);
return { asset: AvatarDecoration, skuId: decoration.skuId, animated: decoration.animated };
// fire-and-forget: hook can't be async; next render will pick up the result via subscription
void useUsersProfileStore.getState().fetchDecorations();
decoration = useUsersProfileStore.getState().decorations.get(AvatarDecoration);
}
if (!decoration) return null;
return { asset: AvatarDecoration, skuId: decoration.skuId, animated: decoration.animated };
}
return null;
Expand Down
1 change: 1 addition & 0 deletions lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import { User } from "@vencord/discord-types";

export interface UserProfile extends User {
bio: string;
profileEffect: {};
userId: string;
themeColors?: Array<number>;
Expand Down
Loading