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+ } ;
0 commit comments