From a776898268fe991cb7015e452f36456b2312935b Mon Sep 17 00:00:00 2001 From: instant992 Date: Wed, 10 Jun 2026 02:00:10 +0400 Subject: [PATCH] Pin account-info row, add phone-number privacy option, update icon - Account balance/subscription row now sits right after the archive folder so it stays visible even when the archive is auto-scrolled out of view - New 'My phone number' setting (Show / Blur / Hide) under General > Privacy that masks the user's own number in Settings header and profile - NekoConfig.formatOwnPhone() applies the chosen mode consistently - Regenerate launcher icon from foxigram4.png --- .../telegram/ui/Adapters/DialogsAdapter.java | 16 +++++-- .../java/org/telegram/ui/ProfileActivity.java | 10 +++-- .../org/telegram/ui/SettingsActivity.java | 2 +- .../java/tw/nekomimi/nekogram/NekoConfig.java | 45 +++++++++++++++++++ .../settings/NekoGeneralSettingsActivity.java | 27 +++++++++++ .../src/main/res/values/strings_neko.xml | 5 +++ 6 files changed, 97 insertions(+), 8 deletions(-) diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsAdapter.java index e3a36353..a7f99a45 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsAdapter.java @@ -1500,10 +1500,6 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements return; } - if (shouldShowFoxAccountInfo()) { - itemInternals.add(new ItemInternal(VIEW_TYPE_FOX_ACCOUNT_INFO)); - } - if (!hasHints && dialogsType == 0 && folderId == 0 && messagesController.isDialogsEndReached(folderId) && !forceUpdatingContacts) { if (messagesController.getAllFoldersDialogsCount() <= 10 && ContactsController.getInstance(currentAccount).doneLoadingContacts && !ContactsController.getInstance(currentAccount).contacts.isEmpty()) { onlineContacts = new ArrayList<>(ContactsController.getInstance(currentAccount).contacts); @@ -1643,12 +1639,24 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements } if (!stopUpdate) { + boolean foxInfoInserted = false; for (int k = 0; k < array.size(); k++) { if (dialogsType == DialogsActivity.DIALOGS_TYPE_ADD_USERS_TO && array.get(k) instanceof DialogsActivity.DialogsHeader) { itemInternals.add(new ItemInternal(VIEW_TYPE_HEADER_2, array.get(k))); } else { itemInternals.add(new ItemInternal(VIEW_TYPE_DIALOG, array.get(k))); } + // Insert the account-info row right after the archive folder so + // it stays pinned visible even when the archive is auto-scrolled + // out of view (the list auto-scrolls to position 1 in that case). + if (!foxInfoInserted && shouldShowFoxAccountInfo() && array.get(k) instanceof TLRPC.TL_dialogFolder) { + itemInternals.add(new ItemInternal(VIEW_TYPE_FOX_ACCOUNT_INFO)); + foxInfoInserted = true; + } + } + // No archive folder present: just pin it to the very top. + if (!foxInfoInserted && shouldShowFoxAccountInfo()) { + itemInternals.add(0, new ItemInternal(VIEW_TYPE_FOX_ACCOUNT_INFO)); } if (!forceShowEmptyCell && dialogsType != 7 && dialogsType != 8 && !MessagesController.getInstance(currentAccount).isDialogsEndReached(folderId)) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java index e4e66868..096f6b03 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java @@ -13613,7 +13613,11 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. phoneNumber = null; } isFragmentPhoneNumber = phoneNumber != null && phoneNumber.matches("888\\d{8}"); - detailCell.setTextAndValue(text, LocaleController.getString(isFragmentPhoneNumber ? R.string.AnonymousNumber : R.string.PhoneMobile), false); + CharSequence phoneText = text; + if (user != null && user.id == getUserConfig().getClientUserId()) { + phoneText = tw.nekomimi.nekogram.NekoConfig.formatOwnPhone(text); + } + detailCell.setTextAndValue(phoneText, LocaleController.getString(isFragmentPhoneNumber ? R.string.AnonymousNumber : R.string.PhoneMobile), false); } else if (position == noteRow) { final TLRPC.UserFull userInfo = getMessagesController().getUserFull(userId); if (userInfo == null) return; @@ -13719,9 +13723,9 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } } else if (position == numberRow) { TLRPC.User user = UserConfig.getInstance(currentAccount).getCurrentUser(); - String value; + CharSequence value; if (user != null && user.phone != null && user.phone.length() != 0) { - value = PhoneFormat.getInstance().format("+" + user.phone); + value = tw.nekomimi.nekogram.NekoConfig.formatOwnPhone(PhoneFormat.getInstance().format("+" + user.phone)); } else { value = LocaleController.getString(R.string.NumberUnknown); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java index c13ccff1..903e0a94 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java @@ -531,7 +531,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter titleView.setText(UserObject.getUserName(user)); final StringBuilder sb = new StringBuilder(); if (user != null) { - sb.append(PhoneFormat.getInstance().format("+" + user.phone)); + sb.append(tw.nekomimi.nekogram.NekoConfig.formatOwnPhone(PhoneFormat.getInstance().format("+" + user.phone))); } final String username = UserObject.getPublicUsername(user); if (username != null) { diff --git a/TMessagesProj/src/main/java/tw/nekomimi/nekogram/NekoConfig.java b/TMessagesProj/src/main/java/tw/nekomimi/nekogram/NekoConfig.java index bb01669d..a23f8290 100644 --- a/TMessagesProj/src/main/java/tw/nekomimi/nekogram/NekoConfig.java +++ b/TMessagesProj/src/main/java/tw/nekomimi/nekogram/NekoConfig.java @@ -150,6 +150,12 @@ public class NekoConfig { public static boolean shouldNOTTrustMe = false; + // How the user's OWN phone number is presented across the app. + public static final int PHONE_SHOW = 0; + public static final int PHONE_BLUR = 1; + public static final int PHONE_HIDE = 2; + public static int hidePhoneNumber = PHONE_SHOW; + public static int userMcc = 0; private static final SharedPreferences.OnSharedPreferenceChangeListener listener = (preferences, key) -> { @@ -199,6 +205,7 @@ public class NekoConfig { askBeforeCall = preferences.getBoolean("askBeforeCall", true); shouldNOTTrustMe = preferences.getBoolean("shouldNOTTrustMe", false); disableNumberRounding = preferences.getBoolean("disableNumberRounding", false); + hidePhoneNumber = preferences.getInt("hidePhoneNumber", PHONE_SHOW); disableAppBarShadow = preferences.getBoolean("disableAppBarShadow", false); mediaPreview = preferences.getBoolean("mediaPreview", true); idType = preferences.getInt("idType", ID_TYPE_API); @@ -668,6 +675,44 @@ public class NekoConfig { editor.apply(); } + public static void setHidePhoneNumber(int mode) { + hidePhoneNumber = mode; + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + editor.putInt("hidePhoneNumber", hidePhoneNumber); + editor.apply(); + } + + /** + * Transform the user's OWN already-formatted phone number according to the + * {@link #hidePhoneNumber} setting: + * + */ + public static CharSequence formatOwnPhone(CharSequence formatted) { + if (formatted == null || hidePhoneNumber == PHONE_SHOW) { + return formatted; + } + if (hidePhoneNumber == PHONE_HIDE) { + return org.telegram.messenger.LocaleController.getString(org.telegram.messenger.R.string.MobileHidden); + } + StringBuilder sb = new StringBuilder(formatted.length()); + for (int i = 0; i < formatted.length(); i++) { + char c = formatted.charAt(i); + if (Character.isDigit(c)) { + sb.append('•'); + } else { + sb.append(c); + } + } + return sb.toString(); + } + public static void setNameOrder(int order) { nameOrder = order; SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE); diff --git a/TMessagesProj/src/main/java/tw/nekomimi/nekogram/settings/NekoGeneralSettingsActivity.java b/TMessagesProj/src/main/java/tw/nekomimi/nekogram/settings/NekoGeneralSettingsActivity.java index 5c632e2f..36a85b6f 100644 --- a/TMessagesProj/src/main/java/tw/nekomimi/nekogram/settings/NekoGeneralSettingsActivity.java +++ b/TMessagesProj/src/main/java/tw/nekomimi/nekogram/settings/NekoGeneralSettingsActivity.java @@ -38,6 +38,7 @@ public class NekoGeneralSettingsActivity extends BaseNekoSettingsActivity { private final int nameOrderRow = rowId++; private final int idTypeRow = rowId++; + private final int hidePhoneNumberRow = rowId++; private final int disabledInstantCameraRow = rowId++; private final int askBeforeCallRow = rowId++; @@ -104,6 +105,14 @@ public class NekoGeneralSettingsActivity extends BaseNekoSettingsActivity { return app == null ? "" : app.title; } + private CharSequence getHidePhoneNumberValue() { + return switch (NekoConfig.hidePhoneNumber) { + case NekoConfig.PHONE_BLUR -> LocaleController.getString(R.string.HidePhoneNumberBlur); + case NekoConfig.PHONE_HIDE -> LocaleController.getString(R.string.HidePhoneNumberHide); + default -> LocaleController.getString(R.string.HidePhoneNumberShow); + }; + } + @Override protected void fillItems(ArrayList items, UniversalAdapter adapter) { items.add(UItem.asHeader(LocaleController.getString(R.string.Connection))); @@ -142,6 +151,10 @@ public class NekoGeneralSettingsActivity extends BaseNekoSettingsActivity { }).slug("idType")); items.add(UItem.asShadow(LocaleController.getString(R.string.IdTypeAbout))); + items.add(UItem.asHeader(LocaleController.getString(R.string.PrivacyTitle))); + items.add(TextSettingsCellFactory.of(hidePhoneNumberRow, LocaleController.getString(R.string.HidePhoneNumber), getHidePhoneNumberValue()).slug("hidePhoneNumber")); + items.add(UItem.asShadow(LocaleController.getString(R.string.HidePhoneNumberAbout))); + items.add(UItem.asHeader(LocaleController.getString(R.string.General))); items.add(UItem.asCheck(disabledInstantCameraRow, LocaleController.getString(R.string.DisableInstantCamera)).slug("disabledInstantCamera").setChecked(NekoConfig.disableInstantCamera)); items.add(UItem.asCheck(askBeforeCallRow, LocaleController.getString(R.string.AskBeforeCalling)).slug("askBeforeCall").setChecked(NekoConfig.askBeforeCall)); @@ -223,6 +236,20 @@ public class NekoGeneralSettingsActivity extends BaseNekoSettingsActivity { listView.adapter.notifyItemChanged(position, PARTIAL); parentLayout.rebuildAllFragmentViews(false, false); }, resourcesProvider); + } else if (id == hidePhoneNumberRow) { + ArrayList arrayList = new ArrayList<>(); + ArrayList types = new ArrayList<>(); + arrayList.add(LocaleController.getString(R.string.HidePhoneNumberShow)); + types.add(NekoConfig.PHONE_SHOW); + arrayList.add(LocaleController.getString(R.string.HidePhoneNumberBlur)); + types.add(NekoConfig.PHONE_BLUR); + arrayList.add(LocaleController.getString(R.string.HidePhoneNumberHide)); + types.add(NekoConfig.PHONE_HIDE); + PopupHelper.show(arrayList, LocaleController.getString(R.string.HidePhoneNumber), types.indexOf(NekoConfig.hidePhoneNumber), getParentActivity(), view, i -> { + NekoConfig.setHidePhoneNumber(types.get(i)); + item.textValue = getHidePhoneNumberValue(); + listView.adapter.notifyItemChanged(position, PARTIAL); + }, resourcesProvider); } else if (id == accentAsNotificationColorRow) { NekoConfig.toggleAccentAsNotificationColor(); if (view instanceof TextCheckCell) { diff --git a/TMessagesProj/src/main/res/values/strings_neko.xml b/TMessagesProj/src/main/res/values/strings_neko.xml index df91974e..61b25d41 100644 --- a/TMessagesProj/src/main/res/values/strings_neko.xml +++ b/TMessagesProj/src/main/res/values/strings_neko.xml @@ -81,6 +81,11 @@ Hide Telegram API Bot API + My phone number + Choose how your own phone number is shown across the app (drawer, settings and your profile). This only changes how it looks on this device. + Show + Blur + Hide Auto pause video When lock screen/switch to background. Disable proximity events