Skip to content

Commit d6906b2

Browse files
committed
Release MoreProfile plugin
1 parent 4eb6062 commit d6906b2

File tree

1 file changed

+285
-0
lines changed

1 file changed

+285
-0
lines changed
Lines changed: 285 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
1+
package com.github.halkiion.plugins;
2+
3+
import android.content.Context;
4+
import android.graphics.drawable.Drawable;
5+
import android.text.Editable;
6+
import android.text.InputFilter;
7+
import android.text.TextWatcher;
8+
import android.util.TypedValue;
9+
import android.view.View;
10+
import android.view.ViewGroup;
11+
import android.widget.EditText;
12+
import android.widget.LinearLayout;
13+
import android.widget.TextView;
14+
import androidx.core.content.ContextCompat;
15+
16+
import com.aliucord.Utils;
17+
import com.discord.models.user.MeUser;
18+
import com.discord.widgets.settings.account.WidgetSettingsAccount;
19+
import com.discord.widgets.settings.account.WidgetSettingsAccountUsernameEdit;
20+
import com.google.android.material.floatingactionbutton.FloatingActionButton;
21+
import com.google.android.material.textfield.TextInputLayout;
22+
import com.lytefast.flexinput.R;
23+
24+
import java.lang.reflect.Field;
25+
import java.util.ArrayList;
26+
27+
import de.robv.android.xposed.XC_MethodHook;
28+
29+
30+
public class DisplayNameSetting {
31+
public static boolean isDisplayNameMode = false;
32+
public static String lastDisplayName = null;
33+
34+
private static final String SETTING_TAG = "display_name_setting";
35+
private static LinearLayout usernameRowRef = null;
36+
37+
private static String currentEditValue = null;
38+
private static boolean isProgrammaticEdit = false;
39+
private static String originalUsername = null;
40+
41+
public static void onAccountConfigureUI(XC_MethodHook.MethodHookParam param, Context context) {
42+
isDisplayNameMode = false;
43+
44+
var binding = WidgetSettingsAccount.access$getBinding$p((WidgetSettingsAccount) param.thisObject);
45+
LinearLayout mainColumn = (LinearLayout) binding.x.getChildAt(0);
46+
47+
usernameRowRef = binding.p;
48+
if (usernameRowRef == null)
49+
return;
50+
51+
String headerText = context.getString(R.h.form_label_account_information);
52+
int insertIndex = findInsertIndex(mainColumn, headerText);
53+
54+
LinearLayout settingRow = (mainColumn != null) ? (LinearLayout) mainColumn.findViewWithTag(SETTING_TAG) : null;
55+
56+
String displayName = lastDisplayName;
57+
if (displayName == null) {
58+
try {
59+
Object model = param.args[0];
60+
Field userField = model.getClass().getDeclaredField("meUser");
61+
userField.setAccessible(true);
62+
Object user = userField.get(model);
63+
if (user != null)
64+
displayName = UserValues.getDisplayName(user);
65+
} catch (Throwable ignored) {
66+
}
67+
}
68+
if (displayName == null)
69+
displayName = "";
70+
lastDisplayName = displayName;
71+
72+
addDisplayNameHeader(mainColumn, headerText);
73+
74+
if (settingRow == null) {
75+
mainColumn.setLayoutTransition(null);
76+
settingRow = createSettingRow(mainColumn.getContext(), Strings.getString("display_name"), displayName,
77+
SETTING_TAG);
78+
mainColumn.addView(settingRow, insertIndex);
79+
settingRow.setOnClickListener(v -> {
80+
isDisplayNameMode = true;
81+
WidgetSettingsAccountUsernameEdit.Companion.launch(v.getContext());
82+
});
83+
} else {
84+
TextView value = (TextView) settingRow.getChildAt(1);
85+
value.setText(displayName);
86+
}
87+
currentEditValue = null;
88+
originalUsername = null;
89+
}
90+
91+
public static void onEditScreenConfigureUI(XC_MethodHook.MethodHookParam param) {
92+
if (!isDisplayNameMode)
93+
return;
94+
95+
WidgetSettingsAccountUsernameEdit frag = (WidgetSettingsAccountUsernameEdit) param.thisObject;
96+
View view = frag.getView();
97+
if (view == null)
98+
return;
99+
setupDisplayNameEditScreen(frag, view);
100+
}
101+
102+
private static LinearLayout createSettingRow(Context context, String labelText, String valueText, String tag) {
103+
if (usernameRowRef == null)
104+
return null;
105+
TextView usernameLabel = (TextView) usernameRowRef.getChildAt(0);
106+
TextView usernameValue = (TextView) usernameRowRef.getChildAt(1);
107+
108+
LinearLayout rowClone = new LinearLayout(context);
109+
rowClone.setOrientation(LinearLayout.HORIZONTAL);
110+
rowClone.setTag(tag);
111+
rowClone.setBackground(usernameRowRef.getBackground());
112+
ViewGroup.LayoutParams origParams = usernameRowRef.getLayoutParams();
113+
if (origParams != null)
114+
rowClone.setLayoutParams(origParams);
115+
116+
TextView label = new TextView(context, null, 0, R.i.UiKit_Settings_Item_Icon);
117+
label.setLayoutParams(usernameLabel.getLayoutParams());
118+
label.setText(labelText);
119+
copyTextViewStyle(label, usernameLabel);
120+
121+
TextView value = new TextView(context, null, 0, R.i.UiKit_Settings_Item_Icon);
122+
value.setLayoutParams(usernameValue.getLayoutParams());
123+
value.setText(valueText);
124+
value.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
125+
copyTextViewStyle(value, usernameValue);
126+
127+
TypedValue typedValue = new TypedValue();
128+
if (context.getTheme().resolveAttribute(Utils.getResId("ic_navigate_next", "attr"), typedValue, true)) {
129+
Drawable chevron = ContextCompat.getDrawable(context, typedValue.resourceId);
130+
if (chevron != null)
131+
chevron.mutate();
132+
value.setCompoundDrawablesWithIntrinsicBounds(null, null, chevron, null);
133+
value.setCompoundDrawablePadding(usernameValue.getCompoundDrawablePadding());
134+
}
135+
136+
rowClone.addView(label);
137+
rowClone.addView(value);
138+
139+
return rowClone;
140+
}
141+
142+
private static int findInsertIndex(LinearLayout mainColumn, String headerText) {
143+
for (int i = 0; i < mainColumn.getChildCount(); i++) {
144+
View child = mainColumn.getChildAt(i);
145+
if (child instanceof TextView) {
146+
CharSequence text = ((TextView) child).getText();
147+
if (text != null && text.toString().equals(headerText))
148+
return i + 1;
149+
}
150+
}
151+
return 1;
152+
}
153+
154+
private static void clearTextWatchers(EditText editText) {
155+
try {
156+
Field f = TextView.class.getDeclaredField("mListeners");
157+
f.setAccessible(true);
158+
ArrayList<?> listeners = (ArrayList<?>) f.get(editText);
159+
if (listeners != null)
160+
listeners.clear();
161+
} catch (Throwable e) {
162+
}
163+
}
164+
165+
private static void setupDisplayNameEditScreen(WidgetSettingsAccountUsernameEdit frag, View view) {
166+
frag.setActionBarTitle(Strings.getString("edit_display_name"));
167+
168+
TextInputLayout usernameWrap = view.findViewById(Utils.getResId("edit_account_username_wrap", "id"));
169+
if (usernameWrap == null)
170+
return;
171+
172+
usernameWrap.setHint("Display Name");
173+
EditText usernameEdit = usernameWrap.getEditText();
174+
if (usernameEdit == null)
175+
return;
176+
177+
usernameEdit.setFilters(new InputFilter[] { new InputFilter.LengthFilter(32) });
178+
179+
clearTextWatchers(usernameEdit);
180+
181+
if (originalUsername == null) {
182+
originalUsername = usernameEdit.getText().toString();
183+
}
184+
185+
isProgrammaticEdit = true;
186+
if (currentEditValue != null) {
187+
usernameEdit.setText(currentEditValue);
188+
usernameEdit.setSelection(currentEditValue.length());
189+
} else {
190+
usernameEdit.setText(lastDisplayName);
191+
usernameEdit.setSelection(lastDisplayName.length());
192+
}
193+
isProgrammaticEdit = false;
194+
195+
View saveBtnView = view.findViewById(Utils.getResId("settings_account_save", "id"));
196+
if (!(saveBtnView instanceof FloatingActionButton))
197+
return;
198+
199+
FloatingActionButton saveFab = (FloatingActionButton) saveBtnView;
200+
if (usernameEdit.getText() != null && !usernameEdit.getText().toString().equals(lastDisplayName))
201+
saveFab.show();
202+
else
203+
saveFab.hide();
204+
205+
usernameEdit.addTextChangedListener(new TextWatcher() {
206+
@Override
207+
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
208+
}
209+
210+
@Override
211+
public void onTextChanged(CharSequence s, int start, int before, int count) {
212+
}
213+
214+
@Override
215+
public void afterTextChanged(Editable s) {
216+
if (isProgrammaticEdit)
217+
return;
218+
219+
String newText = s.toString();
220+
if (!newText.equals(originalUsername)) {
221+
currentEditValue = newText;
222+
}
223+
if (!newText.equals(lastDisplayName))
224+
saveFab.show();
225+
else
226+
saveFab.hide();
227+
}
228+
});
229+
230+
saveFab.setOnClickListener(v -> {
231+
String newDisplayName = usernameEdit.getText().toString();
232+
String oldDisplayName = lastDisplayName;
233+
lastDisplayName = newDisplayName;
234+
currentEditValue = null;
235+
originalUsername = null;
236+
237+
APIRequest.setDisplayName(newDisplayName, view.getContext(), success -> {
238+
if (!success)
239+
lastDisplayName = oldDisplayName;
240+
});
241+
242+
saveFab.hide(new FloatingActionButton.OnVisibilityChangedListener() {
243+
@Override
244+
public void onHidden(FloatingActionButton fab) {
245+
Utility.hideKeyboard(view);
246+
if (frag.isAdded())
247+
frag.requireActivity().onBackPressed();
248+
}
249+
});
250+
});
251+
}
252+
253+
private static void copyTextViewStyle(TextView target, TextView source) {
254+
target.setTextColor(source.getTextColors());
255+
target.setTextSize(source.getTextSize()
256+
/ source.getContext().getResources().getDisplayMetrics().scaledDensity);
257+
target.setTypeface(source.getTypeface());
258+
target.setGravity(source.getGravity());
259+
target.setPadding(
260+
source.getPaddingLeft(),
261+
source.getPaddingTop(),
262+
source.getPaddingRight(),
263+
source.getPaddingBottom());
264+
target.setBackground(source.getBackground());
265+
}
266+
267+
private static void addDisplayNameHeader(LinearLayout mainColumn, String headerText) {
268+
boolean headerExists = false;
269+
for (int i = 0; i < mainColumn.getChildCount(); i++) {
270+
View child = mainColumn.getChildAt(i);
271+
if (child instanceof TextView) {
272+
CharSequence text = ((TextView) child).getText();
273+
if (text != null && text.toString().equals(headerText)) {
274+
headerExists = true;
275+
break;
276+
}
277+
}
278+
}
279+
if (!headerExists) {
280+
TextView header = new TextView(mainColumn.getContext(), null, 0, R.i.UiKit_Settings_Item_Header);
281+
header.setText(headerText);
282+
mainColumn.addView(header, 0);
283+
}
284+
}
285+
}

0 commit comments

Comments
 (0)