Skip to content

Commit 97445a2

Browse files
committed
added Ring Indicator and small fix for antied
1 parent cc37bbd commit 97445a2

File tree

11 files changed

+444
-5
lines changed

11 files changed

+444
-5
lines changed

.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,6 @@ module.exports = {
3232
"react/display-name": "off",
3333
"react/react-in-jsx-scope": "off",
3434
"no-unused-vars": "off",
35+
"no-mixed-spaces-and-tabs": "off"
3536
}
3637
}

angel/antied/Settings.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ export default function SettingPage() {
147147
createChild("text", "Text Variables", "Customize Texts", null, TextComponent, styles),
148148
createChild("timestamp", "Timestamp", "Timestamp Styles", null, TimestampComponent, styles),
149149
createChild("colorpick", "Colors", "Customize Colors", null, ColorPickComponent, styles),
150-
createChild("ingorelist", "Ignore List", "Show IngoreList", null, IgnoreListComponent, null),
150+
createChild("ingorelist", "Ignore List", "Show Ignore List", null, IgnoreListComponent, null),
151151
createChild("nerd", "Nerd Stuff", "Open Sesami", null, NerdComponent, null, styles),
152152
]
153153

angel/antied/manifest.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"name":"Must Hug Cute Moodle v1.4.3b",
3-
"originalName": "Must Hug Cute Moodle v1.4.3b",
2+
"name":"Cute Moodle v1.4.4",
3+
"originalName": "Cute Moodle v1.4.4",
44
"description":"Keeps a temporary record of deleted messages and any edits until you reload the app.",
55
"main": "index.jsx",
66
"authors": [

angel/antied/patches/flux_dispatch.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export default deletedMessageArray => before("dispatch", FluxDispatcher, args =>
4343
if (!orig?.author?.id || !orig.author.username) return;
4444

4545
// ephemeral message dismiss (from bots)
46-
if(orig?.author?.bot && orig?.type == 64) return;
46+
if(orig?.author?.bot && orig?.flags == 64) return;
4747

4848
// empty message check
4949
if (!orig.content && !orig.attachments?.length && !orig.embeds?.length) return;

angel/ringindicator/index.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Import Lib
2+
import { storage, id } from "@vendetta/plugin";
3+
import { makeDefaults } from "../../lib/utility";
4+
5+
// Imports
6+
import { stopPlugin } from "@vendetta/plugins";
7+
import { showToast } from "@vendetta/ui/toasts";
8+
import { logger } from "@vendetta";
9+
10+
import ViewComponent from "./patches/ViewComponent";
11+
import setting from "./pages/setting";
12+
13+
makeDefaults(storage, {
14+
colors: {
15+
online: "#3BA55C",
16+
idle: "#FAA81A",
17+
dnd: "#ED4245",
18+
},
19+
mult: 1.3,
20+
size: 28
21+
})
22+
23+
24+
// Export for other file to use as references
25+
export let isEnabled = false;
26+
export const pluginNameToast = "[Ring Indicator]";
27+
export const getExt = url => new URL(url).pathname.split('.').pop();
28+
29+
// Definitions
30+
let unpatch = null;
31+
const patches = [
32+
[ViewComponent, []]
33+
];
34+
35+
36+
37+
// Helper Definitions
38+
const patcher = () => patches.forEach(([fn, args]) => fn(...args));
39+
40+
41+
// export MAIN
42+
export default {
43+
onLoad: () => {
44+
isEnabled = true;
45+
try {
46+
unpatch = patcher();
47+
}
48+
catch(err) {
49+
logger.info(`${pluginNameToast} Crash On Load.\n\n`, err)
50+
showToast(`${pluginNameToast} Crashing On Load. Please check debug log for more info.`)
51+
stopPlugin(id)
52+
}
53+
},
54+
onUnload: () => {
55+
isEnabled = false;
56+
unpatch?.()
57+
// stopPlugin(id)
58+
},
59+
settings: setting
60+
}

angel/ringindicator/manifest.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name":"Ring Indicator v1.0.0",
3+
"description":"Modify members presence indicator to be ring around their profile picture.",
4+
"main": "index.js",
5+
"authors": [
6+
{
7+
"name": "AngelW0lf",
8+
"id": "692632336961110087"
9+
}
10+
],
11+
"vendetta": {
12+
"icon":"ic_progress_wrench_24px"
13+
}
14+
}
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
import { findByProps } from "@vendetta/metro";
2+
import { React, ReactNative } from "@vendetta/metro/common";
3+
import { storage } from "@vendetta/plugin"
4+
import { useProxy } from "@vendetta/storage"
5+
import { Forms } from "@vendetta/ui/components";
6+
7+
const { ScrollView, View, Text, TextInput, Animated, Easing, Pressable } = ReactNative;
8+
const { useState, useEffect, useRef } = React;
9+
const { FormSection, FormDivider, FormRow } = Forms;
10+
11+
const { openAlert } = findByProps("openAlert", "dismissAlert");
12+
const { AlertModal, AlertActions, AlertActionButton } = findByProps("AlertModal", "AlertActions", "AlertActionButton");
13+
14+
export default () => {
15+
useProxy(storage);
16+
const [colors, setColors] = useState(storage.colors || {
17+
online: "#3BA55C",
18+
idle: "#FAA81A",
19+
dnd: "#ED4245",
20+
});
21+
22+
const [mult, setMult] = useState(storage.mult || 1.2);
23+
const [size, setSize] = useState(storage.size || 30);
24+
25+
26+
const hue = useRef(new Animated.Value(0)).current;
27+
useEffect(() => {
28+
Animated.loop(
29+
Animated.timing(hue, {
30+
toValue: 1,
31+
duration: 1000,
32+
easing: Easing.linear,
33+
useNativeDriver: false,
34+
})
35+
).start();
36+
}, []);
37+
38+
const headerColor = hue.interpolate({
39+
inputRange: [0, 1],
40+
outputRange: ["#ff0000", "#ff0000"], // will be rotated by hue
41+
});
42+
43+
const updateColor = (key, val) => {
44+
const next = { ...colors, [key]: val };
45+
setColors(next);
46+
storage.colors = next;
47+
};
48+
49+
const Ring = ({ status, color }) => (
50+
<View style={{
51+
width: 48, height: 48, borderRadius: 24,
52+
backgroundColor: "#1E1E1E", margin: 8,
53+
justifyContent: "center", alignItems: "center",
54+
}}>
55+
<View style={{
56+
width: 44, height: 44, borderRadius: 22,
57+
borderWidth: 4, borderColor: color,
58+
}} />
59+
<Text style={{ color: "#fff", fontSize: 10, marginTop: 4 }}>{status}</Text>
60+
</View>
61+
);
62+
63+
const thing = "I'm toooooo lazy to finish this plugin, so deal with it.";
64+
65+
const keyDict = {
66+
"online": "Online",
67+
"idle": "Idle",
68+
"dnd": "Do Not Disturb",
69+
}
70+
71+
const randomHex = () => "#" + Math.floor(Math.random() * 0xffffff).toString(16).padStart(6, "0");
72+
73+
return (
74+
<ScrollView style={{ backgroundColor: "#111" }}>
75+
<Animated.View style={{
76+
paddingVertical: 40, alignItems: "center",
77+
backgroundColor: headerColor,
78+
}}>
79+
<Text style={{ fontSize: 32, fontWeight: "bold", color: "#fff" }}>Presence Ring</Text>
80+
<Text style={{ fontSize: 14, color: "#eee", marginTop: 4 }}>Customise indicator colors</Text>
81+
</Animated.View>
82+
83+
<FormSection title="Live preview">
84+
<View style={{ flexDirection: "row", justifyContent: "space-evenly", paddingVertical: 16 }}>
85+
<Ring status="Online" color={colors.online} />
86+
<Ring status="Idle" color={colors.idle} />
87+
<Ring status="DND" color={colors.dnd} />
88+
</View>
89+
</FormSection>
90+
91+
<FormSection title="Colour palette">
92+
<View style={{ marginHorizontal: 16, marginVertical: 8 }}>
93+
{
94+
Object.entries(colors).map(([key, value]) => (
95+
<>
96+
<Text style={{ color: "#fff", fontSize: 16, marginBottom: 4 }}>
97+
{keyDict[key]}
98+
</Text>
99+
<View style={{ flexDirection: "row", alignItems: "center" }}>
100+
<TextInput
101+
style={{
102+
flex: 1, backgroundColor: "#222", color: "#fff",
103+
borderRadius: 8, paddingHorizontal: 12, paddingVertical: 10,
104+
fontFamily: "monospace", fontSize: 14,
105+
borderWidth: 2, borderColor: value,
106+
}}
107+
value={value}
108+
onChangeText={v => updateColor(key, v)}
109+
placeholder="#RRGGBB"
110+
/>
111+
<View style={{
112+
width: 32, height: 32, borderRadius: 16,
113+
backgroundColor: value, marginLeft: 12,
114+
borderWidth: 3, borderColor: "#444",
115+
}} />
116+
</View>
117+
</>
118+
))}
119+
{/*
120+
<View style={{ flexDirection: "row", alignItems: "center" }}>
121+
<TextInput
122+
style={{
123+
flex: 1, backgroundColor: "#222", color: "#fff",
124+
borderRadius: 8, paddingHorizontal: 12, paddingVertical: 10,
125+
fontFamily: "monospace", fontSize: 14,
126+
borderWidth: 2, borderColor: randomHex(),
127+
}}
128+
value={mult}
129+
onChangeText={v => {
130+
setMult(v)
131+
storage.mult = v;
132+
}}
133+
placeholder="1.2"
134+
/>
135+
</View>
136+
137+
<View style={{ flexDirection: "row", alignItems: "center" }}>
138+
<TextInput
139+
style={{
140+
flex: 1, backgroundColor: "#222", color: "#fff",
141+
borderRadius: 8, paddingHorizontal: 12, paddingVertical: 10,
142+
fontFamily: "monospace", fontSize: 14,
143+
borderWidth: 2, borderColor: randomHex(),
144+
}}
145+
value={size}
146+
onChangeText={v => {
147+
setSize(v)
148+
storage.size = v;
149+
}}
150+
placeholder="30"
151+
/>
152+
</View>
153+
*/}
154+
</View>
155+
</FormSection>
156+
157+
<FormSection title="Wild extras">
158+
<View style={{
159+
margin: 16, padding: 20,
160+
backgroundColor: "#252525", borderRadius: 12,
161+
borderWidth: 2, borderColor: "#5865F2",
162+
}}>
163+
<FormRow
164+
label="Click to Randomize the color palette"
165+
style={{ color: "#aaa", fontSize: 12, textAlign: "center", marginTop: 8 }}
166+
onPress={() => {
167+
168+
openAlert("rainbomizer",
169+
(<>
170+
<AlertModal
171+
title="Note"
172+
content={<Text variant="text-md/semibold" color="TEXT_NORMAL">{thing}</Text>}
173+
actions={
174+
<AlertActions>
175+
<AlertActionButton text="OK" variant="primary"/>
176+
</AlertActions>
177+
}
178+
/>
179+
</>)
180+
);
181+
}}
182+
/>
183+
</View>
184+
</FormSection>
185+
<View style={{ paddingBottom: "50vh" }}/>
186+
</ScrollView>
187+
);
188+
};
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { before } from "@vendetta/patcher";
2+
import { storage } from "@vendetta/plugin";
3+
import { General } from "@vendetta/ui/components";
4+
import { isEnabled } from "..";
5+
6+
7+
export default () => before("render", General.View, (args) => {
8+
if(!isEnabled) return;
9+
10+
const [wrapper] = args;
11+
if (!wrapper || !Array.isArray(wrapper.style)) return;
12+
13+
14+
const statusColours = storage.colors || {
15+
online: "#3BA55C", // green
16+
idle: "#FAA81A", // yellow
17+
dnd: "#ED4245", // red
18+
};
19+
20+
const circleIdx = wrapper.style.findIndex(
21+
s => s &&
22+
s.width === 32 &&
23+
s.height === 32 &&
24+
s.borderRadius === 16
25+
);
26+
27+
const transformIdx = wrapper.style.findIndex(
28+
s => s &&
29+
s.width === 92 &&
30+
s.height === 92 &&
31+
s.borderRadius === 92 &&
32+
s.padding === 6 &&
33+
s.zIndex === 0
34+
);
35+
36+
37+
if (circleIdx !== -1) {
38+
// we check if this wrapper is memberlist
39+
const userProps = wrapper.children?.[1]?.props;
40+
const presenceProps = wrapper.children?.[3]?.props;
41+
42+
// missing / wrong type → bail out
43+
if (!userProps?.hasOwnProperty("user") || typeof userProps.user?.id !== "string") return;
44+
if (!presenceProps?.hasOwnProperty("status") || typeof presenceProps.status !== "string") return;
45+
46+
// console.log(userProps.user?.id, presenceProps)
47+
48+
const userPresence = presenceProps.status;
49+
50+
const colour = statusColours[userPresence] ?? null; // not match -> null -> no ring, means offline
51+
if (colour) {
52+
presenceProps.size = 0;
53+
presenceProps.isMobileOnline = false;
54+
presenceProps.style.display = "none";
55+
userProps.cutout.nativeCutouts[0].size = 0;
56+
57+
const mult = storage.mult || 1.2;
58+
const size = storage.size || 30;
59+
60+
wrapper.style[0] = { width: size * mult, height: size * mult, borderRadius: 16 * mult, overflow: "hidden" };
61+
62+
// Object.assign(wrapper.style[0], {
63+
wrapper.style.push({
64+
borderWidth: 2.5 * mult,
65+
borderColor: colour,
66+
borderStyle: "solid",
67+
});
68+
}
69+
}
70+
// else if(transformIdx !== -1) {
71+
// // check if this profile pfp circle, if so poke at it, currently useless
72+
// // console.log(wrapper)
73+
74+
// const mult = 1.4;
75+
76+
// wrapper.style.push({
77+
// borderWidth: 4 * mult,
78+
// borderColor: "#FAA81A",
79+
// borderStyle: "solid",
80+
// });
81+
// }
82+
83+
});

build.mjs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ async function buildPlugin(isDebug = false, NOTE, path, distro, plugins, usesKey
6161
const files = await readdir(`./${path}`);
6262
for (let plug of files) {
6363
const manifest = JSON.parse(await readFile(`./${path}/${plug}/manifest.json`));
64+
65+
if(!manifest || !manifest.main) {
66+
console.log(`Skipped => ${plug} => invalid manifest entry.`)
67+
continue;
68+
}
69+
6470
const outPath = `${distro}/${plug}/index.js`;
6571

6672
// await readdir("./debug").catch(() => mkdir("./debug"))

0 commit comments

Comments
 (0)