From f1c01a8fb33a086b36d6f9448c499888bd8e2c18 Mon Sep 17 00:00:00 2001 From: swakwork Date: Sun, 13 Jul 2025 16:11:06 +0530 Subject: [PATCH] feat(Twitter): Added `Show post source label` patch --- .../revanced/integrations/twitter/Pref.java | 7 +- .../twitter/patches/tweet/TweetInfoAPI.java | 104 ++++++++++++++++++ .../twitter/settings/ScreenBuilder.java | 9 ++ .../twitter/settings/Settings.java | 1 + .../twitter/settings/SettingsStatus.java | 8 +- .../fragments/SettingsAboutFragment.java | 1 + 6 files changed, 127 insertions(+), 3 deletions(-) create mode 100644 app/src/main/java/app/revanced/integrations/twitter/patches/tweet/TweetInfoAPI.java diff --git a/app/src/main/java/app/revanced/integrations/twitter/Pref.java b/app/src/main/java/app/revanced/integrations/twitter/Pref.java index 098d86615f..6b6b32e7d2 100644 --- a/app/src/main/java/app/revanced/integrations/twitter/Pref.java +++ b/app/src/main/java/app/revanced/integrations/twitter/Pref.java @@ -7,13 +7,14 @@ @SuppressWarnings("unused") public class Pref { - public static boolean ROUND_OFF_NUMBERS,ENABLE_FORCE_HD, HIDE_COMM_BADGE; + public static boolean ROUND_OFF_NUMBERS,ENABLE_FORCE_HD, HIDE_COMM_BADGE,SHOW_SRC_LBL; public static float POST_FONT_SIZE; static{ ROUND_OFF_NUMBERS = isRoundOffNumbersEnabled(); ENABLE_FORCE_HD = enableForceHD(); POST_FONT_SIZE = setPostFontSize(); HIDE_COMM_BADGE = hideCommBadge(); + SHOW_SRC_LBL = showSourceLabel(); } public static float setPostFontSize() { Float fontSize = 0.0f; @@ -30,6 +31,10 @@ public static boolean serverResponseLogging() { public static boolean serverResponseLoggingOverwriteFile() { return Utils.getBooleanPerf(Settings.LOG_RES_OVRD); } + + public static boolean showSourceLabel() { + return Utils.getBooleanPerf(Settings.TIMELINE_SHOW_SOURCE_LABEL); + } public static boolean hideCommBadge() { return Utils.getBooleanPerf(Settings.TIMELINE_HIDE_COMM_BADGE); } diff --git a/app/src/main/java/app/revanced/integrations/twitter/patches/tweet/TweetInfoAPI.java b/app/src/main/java/app/revanced/integrations/twitter/patches/tweet/TweetInfoAPI.java new file mode 100644 index 0000000000..7b8d9b9105 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/twitter/patches/tweet/TweetInfoAPI.java @@ -0,0 +1,104 @@ +package app.revanced.integrations.twitter.patches.tweet; + +import org.json.JSONObject; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import app.revanced.integrations.twitter.Utils; + +public class TweetInfoAPI { + private static JSONObject responseObj = null; + private static JSONObject cache = new JSONObject(); + // Lock is used so that getTweetSource waits till request is fetched. + private static final Object lock = new Object(); + + private static JSONObject fetchStatusById(String id) { + HttpURLConnection connection = null; + BufferedReader reader = null; + if(!app.revanced.integrations.shared.Utils.isNetworkConnected()){ + return null; + } + try { + String apiUrl = "https://api.fxtwitter.com/x/status/" + id; + URL url = new URL(apiUrl); + connection = (HttpURLConnection) url.openConnection(); + + connection.setRequestMethod("GET"); + connection.setConnectTimeout(5000); // 5 seconds + connection.setReadTimeout(5000); // 5 seconds + + int responseCode = connection.getResponseCode(); + if (responseCode != HttpURLConnection.HTTP_OK) { + throw new Exception("HTTP error code: " + responseCode); + } + + reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + StringBuilder responseBuilder = new StringBuilder(); + String line; + + while ((line = reader.readLine()) != null) { + responseBuilder.append(line); + } + return new JSONObject(responseBuilder.toString()); + + } catch (Exception e) { + Utils.logger(e); + return null; + + } finally { + try { + if (reader != null) reader.close(); + if (connection != null) connection.disconnect(); + } catch (Exception ignored) { + } + } + } + + public static void sendRequest(long id) { + String tweetId = String.valueOf(id); + + synchronized (lock) { + if (!cache.has(tweetId)) { + new Thread(() -> { + synchronized (lock) { + responseObj = fetchStatusById(tweetId); + lock.notifyAll(); + } + }).start(); + } + } + } + + public static String getTweetSource(long id) { + String src = null; + String tweetId = String.valueOf(id); + try { + if(app.revanced.integrations.shared.Utils.isNetworkConnected()){ + synchronized (lock) { + if (cache.has(tweetId)) { + src = cache.optString(tweetId); + } else { + while (responseObj == null) { + try { + lock.wait(); + }catch (InterruptedException e){ + Thread.currentThread().interrupt(); + Utils.logger("Interrupted while waiting: " + e.getMessage()); + } + } + + if (responseObj != null && responseObj.has("tweet")) { + src = responseObj.optJSONObject("tweet").optString("source"); + if(src!=null) cache.put(tweetId, src); + } + } + } + } + }catch(Exception e){ + Utils.logger(e); + } + return src; + } +} diff --git a/app/src/main/java/app/revanced/integrations/twitter/settings/ScreenBuilder.java b/app/src/main/java/app/revanced/integrations/twitter/settings/ScreenBuilder.java index 1972cb9400..ee8dd01603 100644 --- a/app/src/main/java/app/revanced/integrations/twitter/settings/ScreenBuilder.java +++ b/app/src/main/java/app/revanced/integrations/twitter/settings/ScreenBuilder.java @@ -658,6 +658,15 @@ public void buildTimelineSection(boolean buildCategory){ ) ); } + if (SettingsStatus.showSourceLabel) { + addPreference(category, + helper.switchPreference( + strRes("piko_pref_show_post_source"), + strRes("piko_pref_show_post_source_desc"), + Settings.TIMELINE_SHOW_SOURCE_LABEL + ) + ); + } if (SettingsStatus.hideLiveThreads) { addPreference(category, helper.switchPreference( diff --git a/app/src/main/java/app/revanced/integrations/twitter/settings/Settings.java b/app/src/main/java/app/revanced/integrations/twitter/settings/Settings.java index f8db083aa0..d0ca0f27b6 100644 --- a/app/src/main/java/app/revanced/integrations/twitter/settings/Settings.java +++ b/app/src/main/java/app/revanced/integrations/twitter/settings/Settings.java @@ -51,6 +51,7 @@ public class Settings extends BaseSettings { public static final StringSetting NATIVE_TRANSLATOR_LANG = new StringSetting("native_translator_language", "en"); public static final BooleanSetting TIMELINE_DISABLE_AUTO_SCROLL = new BooleanSetting("timeline_disable_auto_scroll", true); + public static final BooleanSetting TIMELINE_SHOW_SOURCE_LABEL = new BooleanSetting("timeline_show_source_label", true); public static final BooleanSetting TIMELINE_HIDE_LIVETHREADS = new BooleanSetting("timeline_hide_livethreads", false); public static final BooleanSetting TIMELINE_HIDE_BANNER = new BooleanSetting("timeline_hide_banner", true); public static final BooleanSetting TIMELINE_HIDE_BMK_ICON = new BooleanSetting("timeline_hide_bookmark_icon", false); diff --git a/app/src/main/java/app/revanced/integrations/twitter/settings/SettingsStatus.java b/app/src/main/java/app/revanced/integrations/twitter/settings/SettingsStatus.java index 8b2d7932d2..f73fac4c81 100644 --- a/app/src/main/java/app/revanced/integrations/twitter/settings/SettingsStatus.java +++ b/app/src/main/java/app/revanced/integrations/twitter/settings/SettingsStatus.java @@ -45,7 +45,7 @@ public class SettingsStatus { public static boolean enableUndoPosts = false; public static boolean customAppIcon = false; public static boolean enableForcePip = false; - + public static boolean showSourceLabel = false; public static boolean hideImmersivePlayer = false; public static boolean enableVidAutoAdvance = false; @@ -294,6 +294,10 @@ public static void enableForcePip() { enableForcePip = true; } + public static void showSourceLabel() { + showSourceLabel = true; + } + public static void hideImmersivePlayer() { hideImmersivePlayer = true; } @@ -334,7 +338,7 @@ public static void typeaheadCustomisation() { } public static boolean enableTimelineSection() { - return ( hideCommBadge || showSensitiveMedia || hideNudgeButton || disableAutoTimelineScroll || forceTranslate || hidePromoteButton || hideCommunityNote || hideLiveThreads || hideBanner || hideInlineBmk || showPollResultsEnabled || hideImmersivePlayer || enableVidAutoAdvance || enableForceHD); + return ( showSourceLabel || hideCommBadge || showSensitiveMedia || hideNudgeButton || disableAutoTimelineScroll || forceTranslate || hidePromoteButton || hideCommunityNote || hideLiveThreads || hideBanner || hideInlineBmk || showPollResultsEnabled || hideImmersivePlayer || enableVidAutoAdvance || enableForceHD); } public static boolean enableMiscSection() { diff --git a/app/src/main/java/app/revanced/integrations/twitter/settings/fragments/SettingsAboutFragment.java b/app/src/main/java/app/revanced/integrations/twitter/settings/fragments/SettingsAboutFragment.java index 7b732d92c1..a368d22b87 100644 --- a/app/src/main/java/app/revanced/integrations/twitter/settings/fragments/SettingsAboutFragment.java +++ b/app/src/main/java/app/revanced/integrations/twitter/settings/fragments/SettingsAboutFragment.java @@ -124,6 +124,7 @@ public void onCreate(@org.jetbrains.annotations.Nullable Bundle savedInstanceSta flags.put(strRes("piko_pref_customisation_searchtabs"),SettingsStatus.searchTabCustomisation); flags.put(strRemoveRes("piko_pref_hide_todays_news"),SettingsStatus.hideTodaysNews); flags.put(strRemoveRes("piko_pref_server_response_logging"),SettingsStatus.serverResponseLogging); + flags.put(strRes("piko_pref_show_post_source"),SettingsStatus.showSourceLabel); LegacyTwitterPreferenceCategory patPref = preferenceCategory(strRes("piko_pref_patches"), screen);