|
3 | 3 | import android.annotation.SuppressLint; |
4 | 4 | import android.app.Activity; |
5 | 5 | import android.content.Context; |
| 6 | +import android.content.SharedPreferences; |
6 | 7 | import android.text.TextUtils; |
7 | 8 | import android.view.Menu; |
8 | 9 | import android.view.View; |
9 | 10 | import android.view.ViewGroup; |
| 11 | +import android.widget.ListView; |
10 | 12 | import android.widget.Toast; |
11 | 13 |
|
12 | 14 | import androidx.annotation.NonNull; |
13 | 15 |
|
| 16 | +import com.wmods.wppenhacer.adapter.CustomPrivacyAdapter; |
14 | 17 | import com.wmods.wppenhacer.xposed.core.Feature; |
15 | 18 | import com.wmods.wppenhacer.xposed.core.WppCore; |
16 | 19 | import com.wmods.wppenhacer.xposed.core.components.AlertDialogWpp; |
| 20 | +import com.wmods.wppenhacer.xposed.features.others.MenuHome; |
| 21 | +import com.wmods.wppenhacer.xposed.utils.DesignUtils; |
17 | 22 | import com.wmods.wppenhacer.xposed.utils.ReflectionUtils; |
18 | 23 | import com.wmods.wppenhacer.xposed.utils.ResId; |
19 | 24 | import com.wmods.wppenhacer.xposed.utils.Utils; |
20 | 25 |
|
21 | 26 | import org.json.JSONObject; |
22 | 27 |
|
23 | 28 | import java.lang.reflect.Method; |
| 29 | +import java.util.ArrayList; |
24 | 30 | import java.util.Objects; |
25 | 31 |
|
26 | 32 | import de.robv.android.xposed.XC_MethodHook; |
@@ -56,9 +62,7 @@ public void doHook() throws Throwable { |
56 | 62 |
|
57 | 63 | var type = Integer.parseInt(Utils.xprefs.getString("custom_privacy_type", "0")); |
58 | 64 |
|
59 | | - |
60 | 65 | if (type == 1) { |
61 | | - |
62 | 66 | var hooker = new WppCore.ActivityChangeState() { |
63 | 67 | @SuppressLint("ResourceType") |
64 | 68 | @Override |
@@ -101,56 +105,148 @@ protected void afterHookedMethod(MethodHookParam param) throws Throwable { |
101 | 105 | XposedHelpers.findAndHookMethod(ContactInfoActivityClass, "onCreateOptionsMenu", Menu.class, hooker); |
102 | 106 | XposedHelpers.findAndHookMethod(GroupInfoActivityClass, "onCreateOptionsMenu", Menu.class, hooker); |
103 | 107 | } |
| 108 | + |
| 109 | + if (type == 0) return; |
| 110 | + |
| 111 | + var icon = DesignUtils.resizeDrawable(DesignUtils.getDrawable(ResId.drawable.ic_privacy), Utils.dipToPixels(24), Utils.dipToPixels(24)); |
| 112 | + icon.setTint(0xff8696a0); |
| 113 | + MenuHome.menuItems.add((menu, activity) -> menu.add(0, 0, 0, ResId.string.custom_privacy).setIcon(icon).setOnMenuItemClickListener(item -> { |
| 114 | + showCustomPrivacyList(activity, ContactInfoActivityClass, GroupInfoActivityClass); |
| 115 | + return true; |
| 116 | + })); |
104 | 117 | } |
105 | 118 |
|
| 119 | + private void showCustomPrivacyList(Activity activity, Class<?> contactClass, Class<?> groupClass) { |
| 120 | + |
| 121 | + SharedPreferences pprefs = WppCore.getPrivPrefs(); |
| 122 | + var maps = pprefs.getAll(); |
| 123 | + ArrayList<CustomPrivacyAdapter.Item> list = new ArrayList<>(); |
| 124 | + for (var key : maps.keySet()) { |
| 125 | + if (key.endsWith("_privacy")) { |
| 126 | + var number = key.replace("_privacy", ""); |
| 127 | + Object userJid = WppCore.createUserJid(number + (number.length() > 14 ? "@g.us" : "@s.whatsapp.net")); |
| 128 | + |
| 129 | + var contactName = WppCore.getContactName(userJid); |
| 130 | + |
| 131 | + if (TextUtils.isEmpty(contactName)) { |
| 132 | + contactName = number; |
| 133 | + } |
| 134 | + CustomPrivacyAdapter.Item item = new CustomPrivacyAdapter.Item(); |
| 135 | + item.name = contactName; |
| 136 | + item.number = number; |
| 137 | + item.key = key; |
| 138 | + list.add(item); |
| 139 | + } |
| 140 | + } |
| 141 | + |
| 142 | + if (list.isEmpty()) { |
| 143 | + Utils.showToast(activity.getString(ResId.string.no_contact_with_custom_privacy), Toast.LENGTH_SHORT); |
| 144 | + return; |
| 145 | + } |
| 146 | + |
| 147 | + AlertDialogWpp builder = new AlertDialogWpp(activity); |
| 148 | + builder.setTitle(ResId.string.custom_privacy); |
| 149 | + ListView listView = new ListView(activity); |
| 150 | + listView.setAdapter(new CustomPrivacyAdapter(activity, pprefs, list, contactClass, groupClass)); |
| 151 | + builder.setView(listView); |
| 152 | + builder.show(); |
| 153 | + } |
| 154 | + |
| 155 | + |
106 | 156 | private void showPrivacyDialog(Activity activity, boolean isChat) { |
107 | | - Object userJid; |
| 157 | + Object userJid = getUserJid(activity, isChat); |
| 158 | + if (userJid == null) return; |
| 159 | + |
| 160 | + String rawJid = WppCore.getRawString(userJid); |
| 161 | + String number = WppCore.stripJID(rawJid); |
| 162 | + |
| 163 | + AlertDialogWpp builder = createPrivacyDialog(activity, number); |
| 164 | + builder.show(); |
| 165 | + } |
| 166 | + |
| 167 | + private Object getUserJid(Activity activity, boolean isChat) { |
108 | 168 | if (isChat) { |
109 | | - userJid = ReflectionUtils.callMethod(chatUserJidMethod, activity); |
| 169 | + return ReflectionUtils.callMethod(chatUserJidMethod, activity); |
110 | 170 | } else { |
111 | | - userJid = ReflectionUtils.callMethod(groupUserJidMethod, activity); |
| 171 | + return ReflectionUtils.callMethod(groupUserJidMethod, activity); |
112 | 172 | } |
113 | | - if (userJid == null) return; |
114 | | - var rawJid = WppCore.getRawString(userJid); |
115 | | - var number = WppCore.stripJID(rawJid); |
116 | | - var builder = new AlertDialogWpp(activity); |
| 173 | + } |
| 174 | + |
| 175 | + private AlertDialogWpp createPrivacyDialog(Activity activity, String number) { |
| 176 | + AlertDialogWpp builder = new AlertDialogWpp(activity); |
117 | 177 | builder.setTitle(ResId.string.custom_privacy); |
118 | | - String[] items = {activity.getString(ResId.string.hideread), activity.getString(ResId.string.hidestatusview), activity.getString(ResId.string.hidereceipt), activity.getString(ResId.string.ghostmode), activity.getString(ResId.string.ghostmode_r), activity.getString(ResId.string.block_call)}; |
119 | | - String[] itemsKeys = {"HideSeen", "HideViewStatus", "HideReceipt", "HideTyping", "HideRecording", "BlockCall"}; |
120 | | - String[] globalKeys = {"hideread", "hidestatusview", "hidereceipt", "ghostmode_t", "ghostmode_r", "call_privacy"}; |
121 | 178 |
|
| 179 | + String[] items = { |
| 180 | + activity.getString(ResId.string.hideread), |
| 181 | + activity.getString(ResId.string.hidestatusview), |
| 182 | + activity.getString(ResId.string.hidereceipt), |
| 183 | + activity.getString(ResId.string.ghostmode), |
| 184 | + activity.getString(ResId.string.ghostmode_r), |
| 185 | + activity.getString(ResId.string.block_call) |
| 186 | + }; |
| 187 | + |
| 188 | + String[] itemsKeys = { |
| 189 | + "HideSeen", "HideViewStatus", "HideReceipt", "HideTyping", "HideRecording", "BlockCall" |
| 190 | + }; |
| 191 | + |
| 192 | + boolean[] checkedItems = loadPreferences(number, itemsKeys); |
| 193 | + |
| 194 | + builder.setMultiChoiceItems(items, checkedItems, (dialog, which, isChecked) -> checkedItems[which] = isChecked); |
| 195 | + builder.setPositiveButton("OK", (dialog, which) -> savePreferences(number, itemsKeys, checkedItems)); |
| 196 | + builder.setNegativeButton(activity.getString(ResId.string.cancel), null); |
| 197 | + |
| 198 | + return builder; |
| 199 | + } |
| 200 | + |
| 201 | + private boolean[] loadPreferences(String number, String[] itemsKeys) { |
| 202 | + boolean[] checkedItems = new boolean[itemsKeys.length]; |
| 203 | + JSONObject json = CustomPrivacy.getJSON(number); |
122 | 204 |
|
123 | | - // load prefs |
124 | | - boolean[] checkedItems = new boolean[items.length]; |
125 | | - var json = CustomPrivacy.getJSON(number); |
126 | 205 | for (int i = 0; i < itemsKeys.length; i++) { |
127 | | - if (globalKeys[i].equals("call_privacy")) { |
128 | | - checkedItems[i] = json.optBoolean(itemsKeys[i], Objects.equals(prefs.getString(globalKeys[i], "0"), "1")); |
129 | | - } else { |
130 | | - checkedItems[i] = json.optBoolean(itemsKeys[i], prefs.getBoolean(globalKeys[i], false)); |
131 | | - } |
| 206 | + String globalKey = getGlobalKey(itemsKeys[i]); |
| 207 | + checkedItems[i] = json.optBoolean(itemsKeys[i], getDefaultPreference(globalKey)); |
132 | 208 | } |
133 | 209 |
|
134 | | - builder.setMultiChoiceItems(items, checkedItems, (dialog, which, isChecked) -> checkedItems[which] = isChecked); |
135 | | - builder.setPositiveButton("OK", (dialog, which) -> { |
136 | | - try { |
137 | | - JSONObject jsonObject = new JSONObject(); |
138 | | - for (int i = 0; i < itemsKeys.length; i++) { |
139 | | - if (globalKeys[i].equals("call_privacy")) { |
140 | | - if (Objects.equals(prefs.getString(globalKeys[i], "0"), "1") != checkedItems[i]) |
141 | | - jsonObject.put(itemsKeys[i], checkedItems[i]); |
142 | | - } else { |
143 | | - if (prefs.getBoolean(globalKeys[i], false) != checkedItems[i]) |
144 | | - jsonObject.put(itemsKeys[i], checkedItems[i]); |
145 | | - } |
| 210 | + return checkedItems; |
| 211 | + } |
| 212 | + |
| 213 | + private String getGlobalKey(String itemKey) { |
| 214 | + return switch (itemKey) { |
| 215 | + case "HideSeen" -> "hideread"; |
| 216 | + case "HideViewStatus" -> "hidestatusview"; |
| 217 | + case "HideReceipt" -> "hidereceipt"; |
| 218 | + case "HideTyping" -> "ghostmode_t"; |
| 219 | + case "HideRecording" -> "ghostmode_r"; |
| 220 | + case "BlockCall" -> "call_privacy"; |
| 221 | + default -> ""; |
| 222 | + }; |
| 223 | + } |
| 224 | + |
| 225 | + private boolean getDefaultPreference(String globalKey) { |
| 226 | + if (globalKey.equals("call_privacy")) { |
| 227 | + return Objects.equals(prefs.getString(globalKey, "0"), "1"); |
| 228 | + } else { |
| 229 | + return prefs.getBoolean(globalKey, false); |
| 230 | + } |
| 231 | + } |
| 232 | + |
| 233 | + private void savePreferences(String number, String[] itemsKeys, boolean[] checkedItems) { |
| 234 | + try { |
| 235 | + JSONObject jsonObject = new JSONObject(); |
| 236 | + for (int i = 0; i < itemsKeys.length; i++) { |
| 237 | + String globalKey = getGlobalKey(itemsKeys[i]); |
| 238 | + if (globalKey.equals("call_privacy")) { |
| 239 | + if (Objects.equals(prefs.getString(globalKey, "0"), "1") != checkedItems[i]) |
| 240 | + jsonObject.put(itemsKeys[i], checkedItems[i]); |
| 241 | + } else { |
| 242 | + if (prefs.getBoolean(globalKey, false) != checkedItems[i]) |
| 243 | + jsonObject.put(itemsKeys[i], checkedItems[i]); |
146 | 244 | } |
147 | | - WppCore.setPrivJSON(number + "_privacy", jsonObject); |
148 | | - } catch (Exception e) { |
149 | | - Utils.showToast(e.getMessage(), Toast.LENGTH_SHORT); |
150 | 245 | } |
151 | | - }); |
152 | | - builder.setNegativeButton(activity.getString(ResId.string.cancel), null); |
153 | | - builder.show(); |
| 246 | + WppCore.setPrivJSON(number + "_privacy", jsonObject); |
| 247 | + } catch (Exception e) { |
| 248 | + Utils.showToast(e.getMessage(), Toast.LENGTH_SHORT); |
| 249 | + } |
154 | 250 | } |
155 | 251 |
|
156 | 252 | @NonNull |
|
0 commit comments