From a414e1cb2b5d48dc97a51e9a7373f011632bf5dd Mon Sep 17 00:00:00 2001 From: Vu Hoan Huy <43563783+d4rkk3y@users.noreply.github.com> Date: Wed, 2 Aug 2023 19:09:07 +0700 Subject: [PATCH] feat(Tiktok - Feed filter): Add more filters (#445) Co-authored-by: oSumAtrIX --- .../tiktok/download/DownloadsPatch.java | 4 +- .../revanced/tiktok/feedfilter/AdsFilter.java | 16 ++ .../tiktok/feedfilter/FeedItemsFilter.java | 43 ++-- .../revanced/tiktok/feedfilter/IFilter.java | 9 + .../tiktok/feedfilter/ImageVideoFilter.java | 16 ++ .../tiktok/feedfilter/LikeCountFilter.java | 32 +++ .../tiktok/feedfilter/LiveFilter.java | 16 ++ .../tiktok/feedfilter/StoryFilter.java | 16 ++ .../tiktok/feedfilter/ViewCountFilter.java | 32 +++ .../tiktok/settings/SettingsEnum.java | 68 +++-- .../ReVancedPreferenceFragment.java | 119 +++++++++ .../ReVancedSettingsFragment.java | 242 ------------------ .../tiktok/settingsmenu/SettingsMenu.java | 2 +- .../tiktok/settingsmenu/SettingsStatus.java | 12 +- .../preference/DownloadPathPreference.java | 46 ++-- .../preference/InputTextPreference.java | 17 ++ .../preference/RangeValuePreference.java | 130 ++++++++++ .../preference/TogglePreference.java | 17 ++ .../ConditionalPreferenceCategory.java | 22 ++ .../DownloadsPreferenceCategory.java | 35 +++ .../FeedFilterPreferenceCategory.java | 55 ++++ .../IntegrationsPreferenceCategory.java | 28 ++ .../SimSpoofPreferenceCategory.java | 47 ++++ .../tiktok/spoof/sim/SpoofSimPatch.java | 8 +- .../app/revanced/tiktok/utils/LogHelper.java | 2 +- .../revanced/tiktok/utils/ReVancedUtils.java | 24 +- 26 files changed, 737 insertions(+), 321 deletions(-) create mode 100644 integrations/java/app/revanced/tiktok/feedfilter/AdsFilter.java create mode 100644 integrations/java/app/revanced/tiktok/feedfilter/IFilter.java create mode 100644 integrations/java/app/revanced/tiktok/feedfilter/ImageVideoFilter.java create mode 100644 integrations/java/app/revanced/tiktok/feedfilter/LikeCountFilter.java create mode 100644 integrations/java/app/revanced/tiktok/feedfilter/LiveFilter.java create mode 100644 integrations/java/app/revanced/tiktok/feedfilter/StoryFilter.java create mode 100644 integrations/java/app/revanced/tiktok/feedfilter/ViewCountFilter.java create mode 100644 integrations/java/app/revanced/tiktok/settingsmenu/ReVancedPreferenceFragment.java delete mode 100644 integrations/java/app/revanced/tiktok/settingsmenu/ReVancedSettingsFragment.java create mode 100644 integrations/java/app/revanced/tiktok/settingsmenu/preference/InputTextPreference.java create mode 100644 integrations/java/app/revanced/tiktok/settingsmenu/preference/RangeValuePreference.java create mode 100644 integrations/java/app/revanced/tiktok/settingsmenu/preference/TogglePreference.java create mode 100644 integrations/java/app/revanced/tiktok/settingsmenu/preference/categories/ConditionalPreferenceCategory.java create mode 100644 integrations/java/app/revanced/tiktok/settingsmenu/preference/categories/DownloadsPreferenceCategory.java create mode 100644 integrations/java/app/revanced/tiktok/settingsmenu/preference/categories/FeedFilterPreferenceCategory.java create mode 100644 integrations/java/app/revanced/tiktok/settingsmenu/preference/categories/IntegrationsPreferenceCategory.java create mode 100644 integrations/java/app/revanced/tiktok/settingsmenu/preference/categories/SimSpoofPreferenceCategory.java diff --git a/integrations/java/app/revanced/tiktok/download/DownloadsPatch.java b/integrations/java/app/revanced/tiktok/download/DownloadsPatch.java index e078ab663..fcbd4ffc6 100644 --- a/integrations/java/app/revanced/tiktok/download/DownloadsPatch.java +++ b/integrations/java/app/revanced/tiktok/download/DownloadsPatch.java @@ -4,10 +4,10 @@ import app.revanced.tiktok.settings.SettingsEnum; public class DownloadsPatch { public static String getDownloadPath() { - return SettingsEnum.TIK_DOWN_PATH.getString(); + return SettingsEnum.DOWNLOAD_PATH.getString(); } public static boolean shouldRemoveWatermark() { - return SettingsEnum.TIK_DOWN_WATERMARK.getBoolean(); + return SettingsEnum.DOWNLOAD_WATERMARK.getBoolean(); } } diff --git a/integrations/java/app/revanced/tiktok/feedfilter/AdsFilter.java b/integrations/java/app/revanced/tiktok/feedfilter/AdsFilter.java new file mode 100644 index 000000000..8270cff35 --- /dev/null +++ b/integrations/java/app/revanced/tiktok/feedfilter/AdsFilter.java @@ -0,0 +1,16 @@ +package app.revanced.tiktok.feedfilter; + +import app.revanced.tiktok.settings.SettingsEnum; +import com.ss.android.ugc.aweme.feed.model.Aweme; + +public class AdsFilter implements IFilter { + @Override + public boolean getEnabled() { + return SettingsEnum.REMOVE_ADS.getBoolean(); + } + + @Override + public boolean getFiltered(Aweme item) { + return item.isAd() || item.isWithPromotionalMusic(); + } +} diff --git a/integrations/java/app/revanced/tiktok/feedfilter/FeedItemsFilter.java b/integrations/java/app/revanced/tiktok/feedfilter/FeedItemsFilter.java index d04d3d949..e8ba84327 100644 --- a/integrations/java/app/revanced/tiktok/feedfilter/FeedItemsFilter.java +++ b/integrations/java/app/revanced/tiktok/feedfilter/FeedItemsFilter.java @@ -6,33 +6,28 @@ import com.ss.android.ugc.aweme.feed.model.FeedItemList; import java.util.Iterator; import java.util.List; -import app.revanced.tiktok.settings.SettingsEnum; - -public class FeedItemsFilter { +public final class FeedItemsFilter { + private static final List FILTERS = List.of( + new AdsFilter(), + new LiveFilter(), + new StoryFilter(), + new ImageVideoFilter(), + new ViewCountFilter(), + new LikeCountFilter() + ); public static void filter(FeedItemList feedItemList) { - if (SettingsEnum.TIK_REMOVE_ADS.getBoolean()) removeAds(feedItemList); - if (SettingsEnum.TIK_HIDE_LIVE.getBoolean()) removeLive(feedItemList); - } + Iterator feedItemListIterator = feedItemList.items.iterator(); + while (feedItemListIterator.hasNext()) { + Aweme item = feedItemListIterator.next(); + if (item == null) continue; - private static void removeAds(FeedItemList feedItemList) { - List items = feedItemList.items; - Iterator it = items.iterator(); - while (it.hasNext()) { - Aweme item = it.next(); - if (item != null && (item.isAd() || item.isWithPromotionalMusic())) { - it.remove(); - } - } - } - - private static void removeLive(FeedItemList feedItemList) { - List items = feedItemList.items; - Iterator it = items.iterator(); - while (it.hasNext()) { - Aweme item = it.next(); - if (item != null && (item.isLive() || item.isLiveReplay())) { - it.remove(); + for (IFilter filter : FILTERS) { + boolean enabled = filter.getEnabled(); + if (enabled && filter.getFiltered(item)) { + feedItemListIterator.remove(); + break; + } } } } diff --git a/integrations/java/app/revanced/tiktok/feedfilter/IFilter.java b/integrations/java/app/revanced/tiktok/feedfilter/IFilter.java new file mode 100644 index 000000000..5ddcddf43 --- /dev/null +++ b/integrations/java/app/revanced/tiktok/feedfilter/IFilter.java @@ -0,0 +1,9 @@ +package app.revanced.tiktok.feedfilter; + +import com.ss.android.ugc.aweme.feed.model.Aweme; + +public interface IFilter { + boolean getEnabled(); + + boolean getFiltered(Aweme item); +} diff --git a/integrations/java/app/revanced/tiktok/feedfilter/ImageVideoFilter.java b/integrations/java/app/revanced/tiktok/feedfilter/ImageVideoFilter.java new file mode 100644 index 000000000..b1d23c692 --- /dev/null +++ b/integrations/java/app/revanced/tiktok/feedfilter/ImageVideoFilter.java @@ -0,0 +1,16 @@ +package app.revanced.tiktok.feedfilter; + +import app.revanced.tiktok.settings.SettingsEnum; +import com.ss.android.ugc.aweme.feed.model.Aweme; + +public class ImageVideoFilter implements IFilter { + @Override + public boolean getEnabled() { + return SettingsEnum.HIDE_IMAGE.getBoolean(); + } + + @Override + public boolean getFiltered(Aweme item) { + return item.isImage() || item.isPhotoMode(); + } +} diff --git a/integrations/java/app/revanced/tiktok/feedfilter/LikeCountFilter.java b/integrations/java/app/revanced/tiktok/feedfilter/LikeCountFilter.java new file mode 100644 index 000000000..80657e38a --- /dev/null +++ b/integrations/java/app/revanced/tiktok/feedfilter/LikeCountFilter.java @@ -0,0 +1,32 @@ +package app.revanced.tiktok.feedfilter; + +import app.revanced.tiktok.settings.SettingsEnum; +import com.ss.android.ugc.aweme.feed.model.Aweme; +import com.ss.android.ugc.aweme.feed.model.AwemeStatistics; + +import static app.revanced.tiktok.utils.ReVancedUtils.parseMinMax; + +public final class LikeCountFilter implements IFilter { + final long minLike; + final long maxLike; + + LikeCountFilter() { + long[] minMax = parseMinMax(SettingsEnum.MIN_MAX_LIKES); + minLike = minMax[0]; + maxLike = minMax[1]; + } + + @Override + public boolean getEnabled() { + return true; + } + + @Override + public boolean getFiltered(Aweme item) { + AwemeStatistics statistics = item.getStatistics(); + if (statistics == null) return false; + + long likeCount = statistics.getDiggCount(); + return likeCount < minLike || likeCount > maxLike; + } +} diff --git a/integrations/java/app/revanced/tiktok/feedfilter/LiveFilter.java b/integrations/java/app/revanced/tiktok/feedfilter/LiveFilter.java new file mode 100644 index 000000000..4a97c2d10 --- /dev/null +++ b/integrations/java/app/revanced/tiktok/feedfilter/LiveFilter.java @@ -0,0 +1,16 @@ +package app.revanced.tiktok.feedfilter; + +import app.revanced.tiktok.settings.SettingsEnum; +import com.ss.android.ugc.aweme.feed.model.Aweme; + +public class LiveFilter implements IFilter { + @Override + public boolean getEnabled() { + return SettingsEnum.HIDE_LIVE.getBoolean(); + } + + @Override + public boolean getFiltered(Aweme item) { + return item.isLive() || item.isLiveReplay(); + } +} diff --git a/integrations/java/app/revanced/tiktok/feedfilter/StoryFilter.java b/integrations/java/app/revanced/tiktok/feedfilter/StoryFilter.java new file mode 100644 index 000000000..0260fff0b --- /dev/null +++ b/integrations/java/app/revanced/tiktok/feedfilter/StoryFilter.java @@ -0,0 +1,16 @@ +package app.revanced.tiktok.feedfilter; + +import app.revanced.tiktok.settings.SettingsEnum; +import com.ss.android.ugc.aweme.feed.model.Aweme; + +public class StoryFilter implements IFilter { + @Override + public boolean getEnabled() { + return SettingsEnum.HIDE_STORY.getBoolean(); + } + + @Override + public boolean getFiltered(Aweme item) { + return item.getIsTikTokStory(); + } +} diff --git a/integrations/java/app/revanced/tiktok/feedfilter/ViewCountFilter.java b/integrations/java/app/revanced/tiktok/feedfilter/ViewCountFilter.java new file mode 100644 index 000000000..ef8699580 --- /dev/null +++ b/integrations/java/app/revanced/tiktok/feedfilter/ViewCountFilter.java @@ -0,0 +1,32 @@ +package app.revanced.tiktok.feedfilter; + +import app.revanced.tiktok.settings.SettingsEnum; +import com.ss.android.ugc.aweme.feed.model.Aweme; +import com.ss.android.ugc.aweme.feed.model.AwemeStatistics; + +import static app.revanced.tiktok.utils.ReVancedUtils.parseMinMax; + +public class ViewCountFilter implements IFilter { + final long minView; + final long maxView; + + ViewCountFilter() { + long[] minMax = parseMinMax(SettingsEnum.MIN_MAX_VIEWS); + minView = minMax[0]; + maxView = minMax[1]; + } + + @Override + public boolean getEnabled() { + return true; + } + + @Override + public boolean getFiltered(Aweme item) { + AwemeStatistics statistics = item.getStatistics(); + if (statistics == null) return false; + + long playCount = statistics.getPlayCount(); + return playCount < minView || playCount > maxView; + } +} diff --git a/integrations/java/app/revanced/tiktok/settings/SettingsEnum.java b/integrations/java/app/revanced/tiktok/settings/SettingsEnum.java index 2318c8696..21dd53e9a 100644 --- a/integrations/java/app/revanced/tiktok/settings/SettingsEnum.java +++ b/integrations/java/app/revanced/tiktok/settings/SettingsEnum.java @@ -1,32 +1,42 @@ package app.revanced.tiktok.settings; -import static java.lang.Boolean.FALSE; -import static java.lang.Boolean.TRUE; -import static app.revanced.tiktok.settings.SettingsEnum.ReturnType.BOOLEAN; -import static app.revanced.tiktok.settings.SettingsEnum.ReturnType.STRING; - import android.content.Context; import android.util.Log; - import androidx.annotation.NonNull; - +import androidx.annotation.Nullable; import app.revanced.tiktok.utils.LogHelper; import app.revanced.tiktok.utils.ReVancedUtils; +import java.util.HashMap; +import java.util.Map; + +import static app.revanced.tiktok.settings.SettingsEnum.ReturnType.BOOLEAN; +import static app.revanced.tiktok.settings.SettingsEnum.ReturnType.STRING; +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; + public enum SettingsEnum { - //TikTok Settings - TIK_DEBUG("tik_debug", BOOLEAN, FALSE), // must be first value, otherwise logging during loading will not work - TIK_REMOVE_ADS("tik_remove_ads", BOOLEAN, TRUE, true), - TIK_HIDE_LIVE("tik_hide_live", BOOLEAN, FALSE, true), - TIK_DOWN_PATH("tik_down_path", STRING, "DCIM/TikTok"), - TIK_DOWN_WATERMARK("tik_down_watermark", BOOLEAN, TRUE), - TIK_SIMSPOOF("tik_simspoof", BOOLEAN, TRUE, true), - TIK_SIMSPOOF_ISO("tik_simspoof_iso", STRING, "us"), - TIK_SIMSPOOF_MCCMNC("tik_simspoof_mccmnc", STRING, "310160"), - TIK_SIMSPOOF_OP_NAME("tik_simspoof_op_name", STRING, "T-Mobile"); + DEBUG("debug", BOOLEAN, FALSE), // Must be first value, otherwise logging during loading will not work. + REMOVE_ADS("remove_ads", BOOLEAN, TRUE, true), + HIDE_LIVE("hide_live", BOOLEAN, FALSE, true), + HIDE_STORY("hide_story", BOOLEAN, FALSE, true), + HIDE_IMAGE("hide_image", BOOLEAN, FALSE, true), + MIN_MAX_VIEWS("min_max_views", STRING, "0-" + Long.MAX_VALUE, true), + MIN_MAX_LIKES("min_max_likes", STRING, "0-" + Long.MAX_VALUE, true), + DOWNLOAD_PATH("down_path", STRING, "DCIM/TikTok"), + DOWNLOAD_WATERMARK("down_watermark", BOOLEAN, TRUE), + SIM_SPOOF("simspoof", BOOLEAN, TRUE, true), + SIM_SPOOF_ISO("simspoof_iso", STRING, "us"), + SIMSPOOF_MCCMNC("simspoof_mccmnc", STRING, "310160"), + SIMSPOOF_OP_NAME("simspoof_op_name", STRING, "T-Mobile"); + + private static final Map pathToSetting = new HashMap<>(2 * values().length); static { loadAllSettings(); + for (SettingsEnum setting : values()) { + pathToSetting.put(setting.path, setting); + } } @NonNull @@ -47,11 +57,12 @@ public enum SettingsEnum { SettingsEnum(String path, ReturnType returnType, Object defaultValue) { this(path, returnType, defaultValue, SharedPrefCategory.TIKTOK_PREFS, false); } + SettingsEnum(String path, ReturnType returnType, Object defaultValue, boolean rebootApp) { this(path, returnType, defaultValue, SharedPrefCategory.TIKTOK_PREFS, rebootApp); } - SettingsEnum(@NonNull String path, @NonNull ReturnType returnType, @NonNull Object defaultValue, - @NonNull SharedPrefCategory prefName, boolean rebootApp) { + + SettingsEnum(@NonNull String path, @NonNull ReturnType returnType, @NonNull Object defaultValue, @NonNull SharedPrefCategory prefName, boolean rebootApp) { this.path = path; this.returnType = returnType; this.defaultValue = defaultValue; @@ -59,6 +70,11 @@ public enum SettingsEnum { this.rebootApp = rebootApp; } + @Nullable + public static SettingsEnum getSettingsFromPath(@NonNull String str) { + return pathToSetting.get(str); + } + private static void loadAllSettings() { try { Context context = ReVancedUtils.getAppContext(); @@ -144,11 +160,15 @@ public enum SettingsEnum { return (String) value; } + /** + * @return the value of this setting as as generic object type. + */ + @NonNull + public Object getObjectValue() { + return value; + } + public enum ReturnType { - BOOLEAN, - INTEGER, - LONG, - FLOAT, - STRING, + BOOLEAN, INTEGER, LONG, FLOAT, STRING, } } diff --git a/integrations/java/app/revanced/tiktok/settingsmenu/ReVancedPreferenceFragment.java b/integrations/java/app/revanced/tiktok/settingsmenu/ReVancedPreferenceFragment.java new file mode 100644 index 000000000..0fa735b36 --- /dev/null +++ b/integrations/java/app/revanced/tiktok/settingsmenu/ReVancedPreferenceFragment.java @@ -0,0 +1,119 @@ +package app.revanced.tiktok.settingsmenu; + +import android.app.Activity; +import android.app.AlarmManager; +import android.app.AlertDialog; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.os.Process; +import android.preference.*; +import androidx.annotation.Nullable; +import app.revanced.integrations.utils.LogHelper; +import app.revanced.tiktok.settings.SettingsEnum; +import app.revanced.tiktok.settings.SharedPrefCategory; +import app.revanced.tiktok.settingsmenu.preference.DownloadPathPreference; +import app.revanced.tiktok.settingsmenu.preference.RangeValuePreference; +import app.revanced.tiktok.settingsmenu.preference.categories.DownloadsPreferenceCategory; +import app.revanced.tiktok.settingsmenu.preference.categories.FeedFilterPreferenceCategory; +import app.revanced.tiktok.settingsmenu.preference.categories.IntegrationsPreferenceCategory; +import app.revanced.tiktok.settingsmenu.preference.categories.SimSpoofPreferenceCategory; +import app.revanced.tiktok.utils.ReVancedUtils; +import com.ss.android.ugc.aweme.splash.SplashActivity; + +@SuppressWarnings("deprecation") +public class ReVancedPreferenceFragment extends PreferenceFragment { + private boolean registered = false; + private boolean settingsInitialized = false; + + SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, str) -> { + try { + SettingsEnum setting = SettingsEnum.getSettingsFromPath(str); + if (setting == null) { + return; + } + Preference pref = findPreference(str); + if (pref == null) { + return; + } + if (pref instanceof SwitchPreference) { + SwitchPreference switchPref = (SwitchPreference) pref; + SettingsEnum.setValue(setting, switchPref.isChecked()); + } else if (pref instanceof EditTextPreference) { + EditTextPreference editPreference = (EditTextPreference) pref; + SettingsEnum.setValue(setting, editPreference.getText()); + } else if (pref instanceof ListPreference) { + ListPreference listPref = (ListPreference) pref; + SettingsEnum.setValue(setting, listPref.getValue()); + updateListPreferenceSummary((ListPreference) pref, setting); + } else if (pref instanceof RangeValuePreference) { + RangeValuePreference rangeValuePref = (RangeValuePreference) pref; + SettingsEnum.setValue(setting, rangeValuePref.getValue()); + } else if (pref instanceof DownloadPathPreference) { + DownloadPathPreference downloadPathPref = (DownloadPathPreference) pref; + SettingsEnum.setValue(setting, downloadPathPref.getValue()); + } else { + LogHelper.printException(() -> "Setting cannot be handled: " + pref.getClass() + " " + pref); + return; + } + if (ReVancedUtils.getAppContext() != null && this.settingsInitialized && setting.rebootApp) { + rebootDialog(getActivity()); + } + } catch (Exception ex) { + LogHelper.printException(() -> "OnSharedPreferenceChangeListener failure", ex); + } + }; + + private void updateListPreferenceSummary(ListPreference listPreference, SettingsEnum setting) { + String objectStringValue = setting.getObjectValue().toString(); + final int entryIndex = listPreference.findIndexOfValue(objectStringValue); + if (entryIndex >= 0) { + listPreference.setSummary(listPreference.getEntries()[entryIndex]); + listPreference.setValue(objectStringValue); + } else { + listPreference.setSummary(objectStringValue); + } + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + this.registered = true; + + getPreferenceManager().setSharedPreferencesName(SharedPrefCategory.TIKTOK_PREFS.prefName); + getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this.listener); + + final Activity context = this.getActivity(); + PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(context); + setPreferenceScreen(preferenceScreen); + + new FeedFilterPreferenceCategory(context, preferenceScreen); + new DownloadsPreferenceCategory(context, preferenceScreen); + new SimSpoofPreferenceCategory(context, preferenceScreen); + new IntegrationsPreferenceCategory(context, preferenceScreen); + + this.settingsInitialized = true; + } + + @Override + public void onDestroy() { + if (this.registered) { + getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this.listener); + this.registered = false; + } + + super.onDestroy(); + } + + private void reboot(Activity activity) { + int intent = PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE; + ((AlarmManager) activity.getSystemService(Context.ALARM_SERVICE)).setExact(AlarmManager.ELAPSED_REALTIME, 1500L, PendingIntent.getActivity(activity, 0, new Intent(activity, SplashActivity.class), intent)); + Process.killProcess(Process.myPid()); + } + + private void rebootDialog(final Activity activity) { + new AlertDialog.Builder(activity).setMessage("Refresh and restart").setPositiveButton("Restart", (dialog, i) -> reboot(activity)).setNegativeButton("Cancel", null).show(); + } +} diff --git a/integrations/java/app/revanced/tiktok/settingsmenu/ReVancedSettingsFragment.java b/integrations/java/app/revanced/tiktok/settingsmenu/ReVancedSettingsFragment.java deleted file mode 100644 index 0febb9873..000000000 --- a/integrations/java/app/revanced/tiktok/settingsmenu/ReVancedSettingsFragment.java +++ /dev/null @@ -1,242 +0,0 @@ -package app.revanced.tiktok.settingsmenu; - -import android.app.Activity; -import android.app.AlarmManager; -import android.app.AlertDialog; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.os.Environment; -import android.os.Process; -import android.preference.EditTextPreference; -import android.preference.PreferenceCategory; -import android.preference.PreferenceFragment; -import android.preference.PreferenceScreen; -import android.preference.SwitchPreference; - -import androidx.annotation.Nullable; - -import com.ss.android.ugc.aweme.splash.SplashActivity; - -import app.revanced.tiktok.settings.SettingsEnum; -import app.revanced.tiktok.settings.SharedPrefCategory; -import app.revanced.tiktok.settingsmenu.preference.DownloadPathPreference; -import app.revanced.tiktok.utils.ReVancedUtils; - -public class ReVancedSettingsFragment extends PreferenceFragment { - - private boolean Registered = false; - private boolean settingsInitialized = false; - - SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, str) -> { - for (SettingsEnum setting : SettingsEnum.values()) { - if (!setting.path.equals(str)) continue; - - if (ReVancedUtils.getAppContext() != null && this.settingsInitialized && setting.rebootApp) { - rebootDialog(getActivity()); - } - } - }; - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - getPreferenceManager().setSharedPreferencesName(SharedPrefCategory.TIKTOK_PREFS.prefName); - getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this.listener); - this.Registered = true; - - final Activity context = this.getActivity(); - PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(context); - setPreferenceScreen(preferenceScreen); - - //Feed filter - if (SettingsStatus.feedFilter) { - PreferenceCategory feedFilter = new PreferenceCategory(context); - feedFilter.setTitle("Feed filter"); - preferenceScreen.addPreference(feedFilter); - - //Remove ads toggle - { - SwitchPreference preference = new SwitchPreference(context); - feedFilter.addPreference(preference); - preference.setKey(SettingsEnum.TIK_REMOVE_ADS.path); - preference.setDefaultValue(SettingsEnum.TIK_REMOVE_ADS.defaultValue); - preference.setChecked(SettingsEnum.TIK_REMOVE_ADS.getBoolean()); - preference.setTitle("Remove feed ads"); - preference.setSummary("Remove ads from feed."); - preference.setOnPreferenceChangeListener((pref, newValue) -> { - // FIXME: the value is already saved in the preferences. - // instead of saving again, simple call SettingsEnum#setValue() - final boolean value = (Boolean) newValue; - SettingsEnum.TIK_REMOVE_ADS.saveValue(value); - return true; - }); - } - //Hide LiveStreams toggle - { - SwitchPreference preference = new SwitchPreference(context); - feedFilter.addPreference(preference); - preference.setKey(SettingsEnum.TIK_HIDE_LIVE.path); - preference.setDefaultValue(SettingsEnum.TIK_HIDE_LIVE.defaultValue); - preference.setChecked(SettingsEnum.TIK_HIDE_LIVE.getBoolean()); - preference.setTitle("Hide livestreams"); - preference.setSummary("Hide livestreams from feed."); - preference.setOnPreferenceChangeListener((pref, newValue) -> { - final boolean value = (Boolean) newValue; - SettingsEnum.TIK_HIDE_LIVE.saveValue(value); - return true; - }); - } - } - - //Download - if (SettingsStatus.download) { - PreferenceCategory download = new PreferenceCategory(context); - download.setTitle("Download"); - preferenceScreen.addPreference(download); - //Download path - { - DownloadPathPreference preference = new DownloadPathPreference(context); - download.addPreference(preference); - preference.setKey(SettingsEnum.TIK_DOWN_PATH.path); - preference.setDefaultValue(SettingsEnum.TIK_DOWN_PATH.defaultValue); - preference.setValue(SettingsEnum.TIK_DOWN_PATH.getString()); - preference.setTitle("Download path"); - preference.setSummary(Environment.getExternalStorageDirectory().getPath() + "/" + preference.getValue()); - preference.setOnPreferenceChangeListener((pref, newValue) -> { - final String value = (String) newValue; - SettingsEnum.TIK_DOWN_PATH.saveValue(value); - return true; - }); - } - //Download watermark - { - SwitchPreference preference = new SwitchPreference(context); - download.addPreference(preference); - preference.setKey(SettingsEnum.TIK_DOWN_WATERMARK.path); - preference.setDefaultValue(SettingsEnum.TIK_DOWN_WATERMARK.defaultValue); - preference.setChecked(SettingsEnum.TIK_DOWN_WATERMARK.getBoolean()); - preference.setTitle("Remove watermark"); - preference.setOnPreferenceChangeListener((pref, newValue) -> { - final boolean value = (Boolean) newValue; - SettingsEnum.TIK_DOWN_WATERMARK.saveValue(value); - return true; - }); - } - } - - // SpoofSimPatch - if(SettingsStatus.simSpoof) { - PreferenceCategory simSpoof = new PreferenceCategory(context); - simSpoof.setTitle("Bypass regional restriction"); - preferenceScreen.addPreference(simSpoof); - //Global Switch - { - SwitchPreference preference = new SwitchPreference(context); - simSpoof.addPreference(preference); - preference.setKey(SettingsEnum.TIK_SIMSPOOF.path); - preference.setDefaultValue(SettingsEnum.TIK_SIMSPOOF.defaultValue); - preference.setChecked(SettingsEnum.TIK_SIMSPOOF.getBoolean()); - preference.setTitle("Fake sim card info"); - preference.setSummary("Bypass regional restriction by fake sim card information."); - preference.setOnPreferenceChangeListener((pref, newValue) -> { - final boolean value = (Boolean) newValue; - SettingsEnum.TIK_SIMSPOOF.saveValue(value); - return true; - }); - } - //Country ISO - { - EditTextPreference preference = new EditTextPreference(context); - simSpoof.addPreference(preference); - preference.setKey(SettingsEnum.TIK_SIMSPOOF_ISO.path); - preference.setDefaultValue(SettingsEnum.TIK_SIMSPOOF_ISO.defaultValue); - preference.setText(SettingsEnum.TIK_SIMSPOOF_ISO.getString()); - preference.setTitle("Country ISO"); - preference.setSummary("us, uk, jp, ..."); - preference.setOnPreferenceChangeListener((pref, newValue) -> { - final String value = (String) newValue; - SettingsEnum.TIK_SIMSPOOF_ISO.saveValue(value); - return true; - }); - } - //Operator mcc+mnc - { - EditTextPreference preference = new EditTextPreference(context); - simSpoof.addPreference(preference); - preference.setKey(SettingsEnum.TIK_SIMSPOOF_MCCMNC.path); - preference.setDefaultValue(SettingsEnum.TIK_SIMSPOOF_MCCMNC.defaultValue); - preference.setText(SettingsEnum.TIK_SIMSPOOF_MCCMNC.getString()); - preference.setTitle("Operator mcc+mnc"); - preference.setSummary("mcc+mnc"); - preference.setOnPreferenceChangeListener((pref, newValue) -> { - final String value = (String) newValue; - SettingsEnum.TIK_SIMSPOOF_MCCMNC.saveValue(value); - return true; - }); - } - //Operator name - { - EditTextPreference preference = new EditTextPreference(context); - simSpoof.addPreference(preference); - preference.setKey(SettingsEnum.TIK_SIMSPOOF_OP_NAME.path); - preference.setDefaultValue(SettingsEnum.TIK_SIMSPOOF_OP_NAME.defaultValue); - preference.setText(SettingsEnum.TIK_SIMSPOOF_OP_NAME.getString()); - preference.setTitle("Operator name"); - preference.setSummary("Name of the operator"); - preference.setOnPreferenceChangeListener((pref, newValue) -> { - final String value = (String) newValue; - SettingsEnum.TIK_SIMSPOOF_OP_NAME.saveValue(value); - return true; - }); - } - } - - //Integration - PreferenceCategory integration = new PreferenceCategory(context); - integration.setTitle("Integration"); - preferenceScreen.addPreference(integration); - //Enable DebugLog toggle - { - SwitchPreference preference = new SwitchPreference(context); - integration.addPreference(preference); - preference.setKey(SettingsEnum.TIK_DEBUG.path); - preference.setDefaultValue(SettingsEnum.TIK_DEBUG.defaultValue); - preference.setChecked(SettingsEnum.TIK_DEBUG.getBoolean()); - preference.setTitle("Enable debug log"); - preference.setSummary("Show integration debug log."); - preference.setOnPreferenceChangeListener((pref, newValue) -> { - final boolean value = (Boolean) newValue; - SettingsEnum.TIK_DEBUG.saveValue(value); - return true; - }); - } - this.settingsInitialized = true; - } - - @Override // android.preference.PreferenceFragment, android.app.Fragment - public void onDestroy() { - if (this.Registered) { - getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this.listener); - this.Registered = false; - } - super.onDestroy(); - } - - private void reboot(Activity activity) { - int intent; - intent = PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE; - ((AlarmManager) activity.getSystemService(Context.ALARM_SERVICE)).setExact(AlarmManager.ELAPSED_REALTIME, 1500L, PendingIntent.getActivity(activity, 0, new Intent(activity, SplashActivity.class), intent)); - Process.killProcess(Process.myPid()); - } - - private void rebootDialog(final Activity activity) { - new AlertDialog.Builder(activity). - setMessage("Refresh and restart"). - setPositiveButton("RESTART", (dialog, i) -> reboot(activity)) - .setNegativeButton("CANCEL", null) - .show(); - } -} diff --git a/integrations/java/app/revanced/tiktok/settingsmenu/SettingsMenu.java b/integrations/java/app/revanced/tiktok/settingsmenu/SettingsMenu.java index fc43153b7..fc9bcfabb 100644 --- a/integrations/java/app/revanced/tiktok/settingsmenu/SettingsMenu.java +++ b/integrations/java/app/revanced/tiktok/settingsmenu/SettingsMenu.java @@ -55,7 +55,7 @@ public class SettingsMenu { linearLayout.addView(fragment); base.setContentView(linearLayout); - PreferenceFragment preferenceFragment = new ReVancedSettingsFragment(); + PreferenceFragment preferenceFragment = new ReVancedPreferenceFragment(); base.getFragmentManager().beginTransaction().replace(fragmentId, preferenceFragment).commit(); return true; diff --git a/integrations/java/app/revanced/tiktok/settingsmenu/SettingsStatus.java b/integrations/java/app/revanced/tiktok/settingsmenu/SettingsStatus.java index e770ad450..2b8eb12ca 100644 --- a/integrations/java/app/revanced/tiktok/settingsmenu/SettingsStatus.java +++ b/integrations/java/app/revanced/tiktok/settingsmenu/SettingsStatus.java @@ -1,20 +1,20 @@ package app.revanced.tiktok.settingsmenu; public class SettingsStatus { - public static boolean feedFilter = false; - public static boolean download = false; - public static boolean simSpoof = false; + public static boolean feedFilterEnabled = false; + public static boolean downloadEnabled = false; + public static boolean simSpoofEnabled = false; public static void enableFeedFilter() { - feedFilter = true; + feedFilterEnabled = true; } public static void enableDownload() { - download = true; + downloadEnabled = true; } public static void enableSimSpoof() { - simSpoof = true; + simSpoofEnabled = true; } public static void load() { diff --git a/integrations/java/app/revanced/tiktok/settingsmenu/preference/DownloadPathPreference.java b/integrations/java/app/revanced/tiktok/settingsmenu/preference/DownloadPathPreference.java index acf6e08b2..734a2b591 100644 --- a/integrations/java/app/revanced/tiktok/settingsmenu/preference/DownloadPathPreference.java +++ b/integrations/java/app/revanced/tiktok/settingsmenu/preference/DownloadPathPreference.java @@ -7,6 +7,7 @@ import android.os.Environment; import android.preference.DialogPreference; import android.text.Editable; import android.text.InputType; +import android.text.TextUtils; import android.text.TextWatcher; import android.view.View; import android.widget.EditText; @@ -14,23 +15,48 @@ import android.widget.LinearLayout; import android.widget.RadioButton; import android.widget.RadioGroup; +import app.revanced.tiktok.settings.SettingsEnum; + +@SuppressWarnings("deprecation") public class DownloadPathPreference extends DialogPreference { private final Context context; private final String[] entryValues = {"DCIM", "Movies", "Pictures"}; - private String value; + private String mValue; + + private boolean mValueSet; private int mediaPathIndex; private String childDownloadPath; - public DownloadPathPreference(Context context) { + public DownloadPathPreference(Context context, String title, SettingsEnum setting) { super(context); this.context = context; + this.setTitle(title); + this.setSummary(Environment.getExternalStorageDirectory().getPath() + "/" + setting.getString()); + this.setKey(setting.path); + this.setValue(setting.getString()); + } + + public String getValue() { + return this.mValue; + } + + public void setValue(String value) { + final boolean changed = !TextUtils.equals(mValue, value); + if (changed || !mValueSet) { + mValue = value; + mValueSet = true; + persistString(value); + if (changed) { + notifyDependencyChange(shouldDisableDependents()); + notifyChanged(); + } + } } @Override protected View onCreateDialogView() { String currentMedia = getValue().split("/")[0]; childDownloadPath = getValue().substring(getValue().indexOf("/") + 1); - mediaPathIndex = findIndexOf(currentMedia); LinearLayout dialogView = new LinearLayout(context); @@ -84,10 +110,8 @@ public class DownloadPathPreference extends DialogPreference { protected void onDialogClosed(boolean positiveResult) { if (positiveResult && mediaPathIndex >= 0) { String newValue = entryValues[mediaPathIndex] + "/" + childDownloadPath; - if (callChangeListener(newValue)) { - setValue(newValue); - setSummary(Environment.getExternalStorageDirectory().getPath() + "/" + newValue); - } + setSummary(Environment.getExternalStorageDirectory().getPath() + "/" + newValue); + setValue(newValue); } } @@ -97,12 +121,4 @@ public class DownloadPathPreference extends DialogPreference { } return -1; } - - public String getValue() { - return this.value; - } - - public void setValue(String value) { - this.value = value; - } } diff --git a/integrations/java/app/revanced/tiktok/settingsmenu/preference/InputTextPreference.java b/integrations/java/app/revanced/tiktok/settingsmenu/preference/InputTextPreference.java new file mode 100644 index 000000000..0ee0e7731 --- /dev/null +++ b/integrations/java/app/revanced/tiktok/settingsmenu/preference/InputTextPreference.java @@ -0,0 +1,17 @@ +package app.revanced.tiktok.settingsmenu.preference; + +import android.content.Context; +import android.preference.EditTextPreference; + +import app.revanced.tiktok.settings.SettingsEnum; + +public class InputTextPreference extends EditTextPreference { + + public InputTextPreference(Context context, String title, String summary, SettingsEnum setting) { + super(context); + this.setTitle(title); + this.setSummary(summary); + this.setKey(setting.path); + this.setText(setting.getString()); + } +} diff --git a/integrations/java/app/revanced/tiktok/settingsmenu/preference/RangeValuePreference.java b/integrations/java/app/revanced/tiktok/settingsmenu/preference/RangeValuePreference.java new file mode 100644 index 000000000..793443397 --- /dev/null +++ b/integrations/java/app/revanced/tiktok/settingsmenu/preference/RangeValuePreference.java @@ -0,0 +1,130 @@ +package app.revanced.tiktok.settingsmenu.preference; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.preference.DialogPreference; +import android.text.Editable; +import android.text.InputType; +import android.text.TextUtils; +import android.text.TextWatcher; +import android.view.View; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.TextView; + +import app.revanced.tiktok.settings.SettingsEnum; + +@SuppressWarnings("deprecation") +public class RangeValuePreference extends DialogPreference { + private final Context context; + + private String minValue; + + private String maxValue; + + private String mValue; + + private boolean mValueSet; + + public RangeValuePreference(Context context, String title, String summary, SettingsEnum setting) { + super(context); + this.context = context; + setTitle(title); + setSummary(summary); + setKey(setting.path); + setValue(setting.getString()); + } + + public void setValue(String value) { + final boolean changed = !TextUtils.equals(mValue, value); + if (changed || !mValueSet) { + mValue = value; + mValueSet = true; + persistString(value); + if (changed) { + notifyDependencyChange(shouldDisableDependents()); + notifyChanged(); + } + } + } + + public String getValue() { + return mValue; + } + + @Override + protected View onCreateDialogView() { + minValue = getValue().split("-")[0]; + maxValue = getValue().split("-")[1]; + LinearLayout dialogView = new LinearLayout(context); + dialogView.setOrientation(LinearLayout.VERTICAL); + LinearLayout minView = new LinearLayout(context); + minView.setOrientation(LinearLayout.HORIZONTAL); + TextView min = new TextView(context); + min.setText("Min: "); + minView.addView(min); + EditText minEditText = new EditText(context); + minEditText.setInputType(InputType.TYPE_CLASS_NUMBER); + minEditText.setText(minValue); + minView.addView(minEditText); + dialogView.addView(minView); + LinearLayout maxView = new LinearLayout(context); + maxView.setOrientation(LinearLayout.HORIZONTAL); + TextView max = new TextView(context); + max.setText("Max: "); + maxView.addView(max); + EditText maxEditText = new EditText(context); + maxEditText.setInputType(InputType.TYPE_CLASS_NUMBER); + maxEditText.setText(maxValue); + maxView.addView(maxEditText); + dialogView.addView(maxView); + minEditText.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void afterTextChanged(Editable editable) { + minValue = editable.toString(); + } + }); + maxEditText.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void afterTextChanged(Editable editable) { + maxValue = editable.toString(); + } + }); + return dialogView; + } + + @Override + protected void onPrepareDialogBuilder(AlertDialog.Builder builder) { + builder.setPositiveButton(android.R.string.ok, (dialog, which) -> this.onClick(dialog, DialogInterface.BUTTON_POSITIVE)); + builder.setNegativeButton(android.R.string.cancel, null); + } + + @Override + protected void onDialogClosed(boolean positiveResult) { + if (positiveResult) { + String newValue = minValue + "-" + maxValue; + setValue(newValue); + } + } +} diff --git a/integrations/java/app/revanced/tiktok/settingsmenu/preference/TogglePreference.java b/integrations/java/app/revanced/tiktok/settingsmenu/preference/TogglePreference.java new file mode 100644 index 000000000..f729920e0 --- /dev/null +++ b/integrations/java/app/revanced/tiktok/settingsmenu/preference/TogglePreference.java @@ -0,0 +1,17 @@ +package app.revanced.tiktok.settingsmenu.preference; + +import android.content.Context; +import android.preference.SwitchPreference; + +import app.revanced.tiktok.settings.SettingsEnum; + +@SuppressWarnings("deprecation") +public class TogglePreference extends SwitchPreference { + public TogglePreference(Context context, String title, String summary, SettingsEnum setting) { + super(context); + this.setTitle(title); + this.setSummary(summary); + this.setKey(setting.path); + this.setChecked(setting.getBoolean()); + } +} diff --git a/integrations/java/app/revanced/tiktok/settingsmenu/preference/categories/ConditionalPreferenceCategory.java b/integrations/java/app/revanced/tiktok/settingsmenu/preference/categories/ConditionalPreferenceCategory.java new file mode 100644 index 000000000..5d3bed461 --- /dev/null +++ b/integrations/java/app/revanced/tiktok/settingsmenu/preference/categories/ConditionalPreferenceCategory.java @@ -0,0 +1,22 @@ +package app.revanced.tiktok.settingsmenu.preference.categories; + +import android.content.Context; +import android.preference.PreferenceCategory; +import android.preference.PreferenceScreen; + +@SuppressWarnings("deprecation") +public abstract class ConditionalPreferenceCategory extends PreferenceCategory { + public ConditionalPreferenceCategory(Context context, PreferenceScreen screen) { + super(context); + + if (getSettingsStatus()) { + screen.addPreference(this); + addPreferences(context); + } + } + + public abstract boolean getSettingsStatus(); + + public abstract void addPreferences(Context context); +} + diff --git a/integrations/java/app/revanced/tiktok/settingsmenu/preference/categories/DownloadsPreferenceCategory.java b/integrations/java/app/revanced/tiktok/settingsmenu/preference/categories/DownloadsPreferenceCategory.java new file mode 100644 index 000000000..40f73d64f --- /dev/null +++ b/integrations/java/app/revanced/tiktok/settingsmenu/preference/categories/DownloadsPreferenceCategory.java @@ -0,0 +1,35 @@ +package app.revanced.tiktok.settingsmenu.preference.categories; + +import android.content.Context; +import android.preference.PreferenceScreen; +import app.revanced.tiktok.settings.SettingsEnum; +import app.revanced.tiktok.settingsmenu.SettingsStatus; +import app.revanced.tiktok.settingsmenu.preference.DownloadPathPreference; +import app.revanced.tiktok.settingsmenu.preference.TogglePreference; + +@SuppressWarnings("deprecation") +public class DownloadsPreferenceCategory extends ConditionalPreferenceCategory { + public DownloadsPreferenceCategory(Context context, PreferenceScreen screen) { + super(context, screen); + setTitle("Downloads"); + } + + @Override + public boolean getSettingsStatus() { + return SettingsStatus.downloadEnabled; + } + + @Override + public void addPreferences(Context context) { + addPreference(new DownloadPathPreference( + context, + "Download path", + SettingsEnum.DOWNLOAD_PATH + )); + addPreference(new TogglePreference( + context, + "Remove watermark", "", + SettingsEnum.DOWNLOAD_WATERMARK + )); + } +} diff --git a/integrations/java/app/revanced/tiktok/settingsmenu/preference/categories/FeedFilterPreferenceCategory.java b/integrations/java/app/revanced/tiktok/settingsmenu/preference/categories/FeedFilterPreferenceCategory.java new file mode 100644 index 000000000..b5fbbdeb7 --- /dev/null +++ b/integrations/java/app/revanced/tiktok/settingsmenu/preference/categories/FeedFilterPreferenceCategory.java @@ -0,0 +1,55 @@ +package app.revanced.tiktok.settingsmenu.preference.categories; + +import android.content.Context; +import android.preference.PreferenceScreen; +import app.revanced.tiktok.settings.SettingsEnum; +import app.revanced.tiktok.settingsmenu.SettingsStatus; +import app.revanced.tiktok.settingsmenu.preference.RangeValuePreference; +import app.revanced.tiktok.settingsmenu.preference.TogglePreference; + +@SuppressWarnings("deprecation") +public class FeedFilterPreferenceCategory extends ConditionalPreferenceCategory { + public FeedFilterPreferenceCategory(Context context, PreferenceScreen screen) { + super(context, screen); + setTitle("Feed filter"); + } + + @Override + public boolean getSettingsStatus() { + return SettingsStatus.feedFilterEnabled; + } + + @Override + public void addPreferences(Context context) { + addPreference(new TogglePreference( + context, + "Remove feed ads", "Remove ads from feed.", + SettingsEnum.REMOVE_ADS + )); + addPreference(new TogglePreference( + context, + "Hide livestreams", "Hide livestreams from feed.", + SettingsEnum.HIDE_LIVE + )); + addPreference(new TogglePreference( + context, + "Hide story", "Hide story from feed.", + SettingsEnum.HIDE_STORY + )); + addPreference(new TogglePreference( + context, + "Hide image video", "Hide image video from feed.", + SettingsEnum.HIDE_IMAGE + )); + addPreference(new RangeValuePreference( + context, + "Min/Max views", "The minimum or maximum views of a video to show.", + SettingsEnum.MIN_MAX_VIEWS + )); + addPreference(new RangeValuePreference( + context, + "Min/Max likes", "The minimum or maximum likes of a video to show.", + SettingsEnum.MIN_MAX_LIKES + )); + } +} diff --git a/integrations/java/app/revanced/tiktok/settingsmenu/preference/categories/IntegrationsPreferenceCategory.java b/integrations/java/app/revanced/tiktok/settingsmenu/preference/categories/IntegrationsPreferenceCategory.java new file mode 100644 index 000000000..9fcb450f7 --- /dev/null +++ b/integrations/java/app/revanced/tiktok/settingsmenu/preference/categories/IntegrationsPreferenceCategory.java @@ -0,0 +1,28 @@ +package app.revanced.tiktok.settingsmenu.preference.categories; + +import android.content.Context; +import android.preference.PreferenceScreen; +import app.revanced.tiktok.settings.SettingsEnum; +import app.revanced.tiktok.settingsmenu.preference.TogglePreference; + +@SuppressWarnings("deprecation") +public class IntegrationsPreferenceCategory extends ConditionalPreferenceCategory { + public IntegrationsPreferenceCategory(Context context, PreferenceScreen screen) { + super(context, screen); + setTitle("Integrations"); + } + + @Override + public boolean getSettingsStatus() { + return true; + } + + @Override + public void addPreferences(Context context) { + addPreference(new TogglePreference(context, + "Enable debug log", + "Show integration debug log.", + SettingsEnum.DEBUG + )); + } +} diff --git a/integrations/java/app/revanced/tiktok/settingsmenu/preference/categories/SimSpoofPreferenceCategory.java b/integrations/java/app/revanced/tiktok/settingsmenu/preference/categories/SimSpoofPreferenceCategory.java new file mode 100644 index 000000000..86f82a1d7 --- /dev/null +++ b/integrations/java/app/revanced/tiktok/settingsmenu/preference/categories/SimSpoofPreferenceCategory.java @@ -0,0 +1,47 @@ +package app.revanced.tiktok.settingsmenu.preference.categories; + +import android.content.Context; +import android.preference.PreferenceScreen; +import app.revanced.tiktok.settings.SettingsEnum; +import app.revanced.tiktok.settingsmenu.SettingsStatus; +import app.revanced.tiktok.settingsmenu.preference.InputTextPreference; +import app.revanced.tiktok.settingsmenu.preference.TogglePreference; + +@SuppressWarnings("deprecation") +public class SimSpoofPreferenceCategory extends ConditionalPreferenceCategory { + public SimSpoofPreferenceCategory(Context context, PreferenceScreen screen) { + super(context, screen); + setTitle("Bypass regional restriction"); + } + + + @Override + public boolean getSettingsStatus() { + return SettingsStatus.simSpoofEnabled; + } + + @Override + public void addPreferences(Context context) { + addPreference(new TogglePreference( + context, + "Fake sim card info", + "Bypass regional restriction by fake sim card information.", + SettingsEnum.SIM_SPOOF + )); + addPreference(new InputTextPreference( + context, + "Country ISO", "us, uk, jp, ...", + SettingsEnum.SIM_SPOOF_ISO + )); + addPreference(new InputTextPreference( + context, + "Operator mcc+mnc", "mcc+mnc", + SettingsEnum.SIMSPOOF_MCCMNC + )); + addPreference(new InputTextPreference( + context, + "Operator name", "Name of the operator.", + SettingsEnum.SIMSPOOF_OP_NAME + )); + } +} diff --git a/integrations/java/app/revanced/tiktok/spoof/sim/SpoofSimPatch.java b/integrations/java/app/revanced/tiktok/spoof/sim/SpoofSimPatch.java index 361ac4288..799ec95c4 100644 --- a/integrations/java/app/revanced/tiktok/spoof/sim/SpoofSimPatch.java +++ b/integrations/java/app/revanced/tiktok/spoof/sim/SpoofSimPatch.java @@ -4,11 +4,11 @@ import app.revanced.tiktok.settings.SettingsEnum; public class SpoofSimPatch { public static boolean isEnable() { - return SettingsEnum.TIK_SIMSPOOF.getBoolean(); + return SettingsEnum.SIM_SPOOF.getBoolean(); } public static String getCountryIso(String value) { if (isEnable()) { - return SettingsEnum.TIK_SIMSPOOF_ISO.getString(); + return SettingsEnum.SIM_SPOOF_ISO.getString(); } else { return value; } @@ -16,14 +16,14 @@ public class SpoofSimPatch { } public static String getOperator(String value) { if (isEnable()) { - return SettingsEnum.TIK_SIMSPOOF_MCCMNC.getString(); + return SettingsEnum.SIMSPOOF_MCCMNC.getString(); } else { return value; } } public static String getOperatorName(String value) { if (isEnable()) { - return SettingsEnum.TIK_SIMSPOOF_OP_NAME.getString(); + return SettingsEnum.SIMSPOOF_OP_NAME.getString(); } else { return value; } diff --git a/integrations/java/app/revanced/tiktok/utils/LogHelper.java b/integrations/java/app/revanced/tiktok/utils/LogHelper.java index c0dab4282..d8d9a580c 100644 --- a/integrations/java/app/revanced/tiktok/utils/LogHelper.java +++ b/integrations/java/app/revanced/tiktok/utils/LogHelper.java @@ -10,7 +10,7 @@ import app.revanced.tiktok.settings.SettingsEnum; public class LogHelper { public static void debug(Class clazz, String message) { - if (SettingsEnum.TIK_DEBUG.getBoolean()) { + if (SettingsEnum.DEBUG.getBoolean()) { Log.d("revanced: " + (clazz != null ? clazz.getSimpleName() : ""), message); } } diff --git a/integrations/java/app/revanced/tiktok/utils/ReVancedUtils.java b/integrations/java/app/revanced/tiktok/utils/ReVancedUtils.java index 7ac089ff5..1577fd613 100644 --- a/integrations/java/app/revanced/tiktok/utils/ReVancedUtils.java +++ b/integrations/java/app/revanced/tiktok/utils/ReVancedUtils.java @@ -1,13 +1,14 @@ package app.revanced.tiktok.utils; +import android.annotation.SuppressLint; import android.content.Context; +import app.revanced.tiktok.settings.SettingsEnum; public class ReVancedUtils { - //Used by TiktokIntegrations patch + @SuppressLint("StaticFieldLeak") public static Context context; - //Used by TiktokIntegrations patch public static Context getAppContext() { if (context != null) { return context; @@ -15,4 +16,23 @@ public class ReVancedUtils { LogHelper.printException(ReVancedUtils.class, "Context is null!"); return null; } + + public static long[] parseMinMax(SettingsEnum setting) { + if (setting.returnType == SettingsEnum.ReturnType.STRING) { + final String[] minMax = setting.getString().split("-"); + + if (minMax.length == 2) + try { + final long min = Long.parseLong(minMax[0]); + final long max = Long.parseLong(minMax[1]); + + if (min <= max && min >= 0) return new long[]{min, max}; + + } catch (NumberFormatException ignored) { + } + } + + setting.saveValue("0-" + Long.MAX_VALUE); + return new long[]{0L, Long.MAX_VALUE}; + } } \ No newline at end of file