From 8e978ff2122ebe6ec6e912bfb3f39a23fc147703 Mon Sep 17 00:00:00 2001 From: areteruhiro Date: Sun, 3 Nov 2024 16:00:22 +0900 Subject: [PATCH] =?UTF-8?q?KeepUnread=E3=83=9C=E3=82=BF=E3=83=B3=E3=82=92L?= =?UTF-8?q?sPatch=E7=94=A8=E3=81=AB=E4=BD=9C=E6=88=90=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=81=93=E3=81=A8=E3=81=AB=E3=82=88=E3=82=8A=E3=80=81root?= =?UTF-8?q?=E3=81=97=E3=81=A6=E3=81=84=E3=82=8B=E7=AB=AF=E6=9C=AB=E3=81=AF?= =?UTF-8?q?=E3=80=81=E4=BF=9D=E5=AD=98=E3=81=99=E3=82=8B=E3=82=88=E3=81=86?= =?UTF-8?q?=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chipppppppppp/lime/LimeOptions.java | 2 + .../io/github/chipppppppppp/lime/Main.java | 4 +- .../chipppppppppp/lime/hooks/KeepUnread.java | 102 +++++++++++++----- .../lime/hooks/KeepUnreadLSpatch.java | 91 ++++++++++++++++ app/src/main/res/values-ja/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 6 files changed, 172 insertions(+), 29 deletions(-) create mode 100644 app/src/main/java/io/github/chipppppppppp/lime/hooks/KeepUnreadLSpatch.java diff --git a/app/src/main/java/io/github/chipppppppppp/lime/LimeOptions.java b/app/src/main/java/io/github/chipppppppppp/lime/LimeOptions.java index ce61fa79..42480a68 100644 --- a/app/src/main/java/io/github/chipppppppppp/lime/LimeOptions.java +++ b/app/src/main/java/io/github/chipppppppppp/lime/LimeOptions.java @@ -31,6 +31,7 @@ public Option(String name, int id, boolean checked) { public Option preventUnsendMessage = new Option("prevent_unsend_message", R.string.switch_prevent_unsend_message, false); public Option sendMuteMessage = new Option("mute_message", R.string.switch_send_mute_message, false); public Option removeKeepUnread = new Option("remove_keep_unread", R.string.switch_remove_keep_unread, false); + public Option KeepUnreadLSpatch = new Option("Keep_UnreadLSpatch", R.string.switch_KeepUnreadLSpatch, false); public Option blockTracking = new Option("block_tracking", R.string.switch_block_tracking, false); public Option stopVersionCheck = new Option("stop_version_check", R.string.switch_stop_version_check, false); public Option outputCommunication = new Option("output_communication", R.string.switch_output_communication, false); @@ -57,6 +58,7 @@ public Option(String name, int id, boolean checked) { archived, sendMuteMessage, removeKeepUnread, + KeepUnreadLSpatch, blockTracking, stopVersionCheck, outputCommunication, diff --git a/app/src/main/java/io/github/chipppppppppp/lime/Main.java b/app/src/main/java/io/github/chipppppppppp/lime/Main.java index 86113d5a..efdc3d68 100644 --- a/app/src/main/java/io/github/chipppppppppp/lime/Main.java +++ b/app/src/main/java/io/github/chipppppppppp/lime/Main.java @@ -18,6 +18,7 @@ import io.github.chipppppppppp.lime.hooks.EmbedOptions; import io.github.chipppppppppp.lime.hooks.IHook; import io.github.chipppppppppp.lime.hooks.KeepUnread; +import io.github.chipppppppppp.lime.hooks.KeepUnreadLSpatch; import io.github.chipppppppppp.lime.hooks.ModifyRequest; import io.github.chipppppppppp.lime.hooks.ModifyResponse; import io.github.chipppppppppp.lime.hooks.OutputRequest; @@ -67,7 +68,8 @@ public class Main implements IXposedHookLoadPackage, IXposedHookInitPackageResou new OutputRequest(), new Archived(), new Ringtone(), - new UnsentCap() + new UnsentCap(), + new KeepUnreadLSpatch() }; public void handleLoadPackage(@NonNull XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable { diff --git a/app/src/main/java/io/github/chipppppppppp/lime/hooks/KeepUnread.java b/app/src/main/java/io/github/chipppppppppp/lime/hooks/KeepUnread.java index b54363ef..5e7c2d42 100644 --- a/app/src/main/java/io/github/chipppppppppp/lime/hooks/KeepUnread.java +++ b/app/src/main/java/io/github/chipppppppppp/lime/hooks/KeepUnread.java @@ -23,52 +23,98 @@ import io.github.chipppppppppp.lime.R; public class KeepUnread implements IHook { + static boolean keepUnread = false; @Override public void hook(LimeOptions limeOptions, XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable { if (limeOptions.removeKeepUnread.checked) return; - Class hookTarget; - hookTarget = loadPackageParam.classLoader.loadClass("jp.naver.line.android.common.view.listview.PopupListView"); - XposedBridge.hookAllConstructors(hookTarget, new XC_MethodHook() { - @Override - protected void afterHookedMethod(MethodHookParam param) throws Throwable { + XposedBridge.hookAllConstructors( + loadPackageParam.classLoader.loadClass("jp.naver.line.android.common.view.listview.PopupListView"), + new XC_MethodHook() { + @Override + protected void afterHookedMethod(MethodHookParam param) throws Throwable { + ViewGroup viewGroup = (ViewGroup) param.thisObject; + Context context = viewGroup.getContext(); + context.getApplicationContext().createPackageContext(Constants.MODULE_NAME, Context.CONTEXT_IGNORE_SECURITY); - ViewGroup viewGroup = (ViewGroup) param.thisObject; - Context context = viewGroup.getContext(); - Context moduleContext = context.getApplicationContext().createPackageContext(Constants.MODULE_NAME, Context.CONTEXT_IGNORE_SECURITY); - String textKeepUnread = moduleContext.getResources().getString(R.string.switch_keep_unread); - RelativeLayout layout = new RelativeLayout(context); - RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams( - RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT); - layout.setLayoutParams(layoutParams); + Context moduleContext = context.getApplicationContext().createPackageContext(Constants.MODULE_NAME, Context.CONTEXT_IGNORE_SECURITY); + String textKeepUnread = moduleContext.getResources().getString(R.string.switch_keep_unread); - Switch switchView = new Switch(context); - switchView.setText(textKeepUnread); - RelativeLayout.LayoutParams switchParams = new RelativeLayout.LayoutParams( - RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); - switchParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE); + keepUnread = readStateFromFile(context); - switchView.setChecked(false); - switchView.setOnCheckedChangeListener((buttonView, isChecked) -> { - }); + RelativeLayout container = new RelativeLayout(context); + RelativeLayout.LayoutParams containerParams = new RelativeLayout.LayoutParams( + RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT); + container.setLayoutParams(containerParams); - layout.addView(switchView, switchParams); + GradientDrawable background = new GradientDrawable(); + background.setShape(GradientDrawable.RECTANGLE); + background.setColor(Color.parseColor("#06C755")); + background.setCornerRadii(new float[]{100, 100, 80, 30, 100, 100, 80, 30}); + container.setBackground(background); - ((ListView) viewGroup.getChildAt(0)).addFooterView(layout); - } - }); - + TextView label = new TextView(context); + label.setText(textKeepUnread); + label.setTextSize(18); + label.setTextColor(Color.WHITE); + label.setId(View.generateViewId()); + RelativeLayout.LayoutParams labelParams = new RelativeLayout.LayoutParams( + RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); + labelParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT); + labelParams.setMargins(40, 0, 0, 0); + container.addView(label, labelParams); + + Switch switchView = new Switch(context); + RelativeLayout.LayoutParams switchParams = new RelativeLayout.LayoutParams( + RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); + switchParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); + switchParams.setMargins(0, 0, 40, 0); + switchView.setChecked(keepUnread); + switchView.setOnCheckedChangeListener((buttonView, isChecked) -> { + keepUnread = isChecked; + saveStateToFile(context, isChecked); + }); + + container.addView(switchView, switchParams); + + ((ListView) viewGroup.getChildAt(0)).addFooterView(container); + } + } + ); XposedHelpers.findAndHookMethod( loadPackageParam.classLoader.loadClass(Constants.MARK_AS_READ_HOOK.className), Constants.MARK_AS_READ_HOOK.methodName, new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { + if (keepUnread) { param.setResult(null); + } } } ); } - -} + private void saveStateToFile(Context context, boolean state) { + String filename = "keep_unread_state.txt"; + try (FileOutputStream fos = context.openFileOutput(filename, Context.MODE_PRIVATE)) { + fos.write((state ? "1" : "0").getBytes()); + } catch (IOException e) { + e.printStackTrace(); + } + } + private boolean readStateFromFile(Context context) { + String filename = "keep_unread_state.txt"; + try (FileInputStream fis = context.openFileInput(filename)) { + int c; + StringBuilder sb = new StringBuilder(); + while ((c = fis.read()) != -1) { + sb.append((char) c); + } + return "1".equals(sb.toString()); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/io/github/chipppppppppp/lime/hooks/KeepUnreadLSpatch.java b/app/src/main/java/io/github/chipppppppppp/lime/hooks/KeepUnreadLSpatch.java new file mode 100644 index 00000000..3c208dad --- /dev/null +++ b/app/src/main/java/io/github/chipppppppppp/lime/hooks/KeepUnreadLSpatch.java @@ -0,0 +1,91 @@ +package io.github.chipppppppppp.lime.hooks; + +import android.content.Context; +import android.graphics.Color; +import android.graphics.drawable.GradientDrawable; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ListView; +import android.widget.RelativeLayout; +import android.widget.Switch; +import android.widget.TextView; + +import de.robv.android.xposed.XC_MethodHook; +import de.robv.android.xposed.XposedBridge; +import de.robv.android.xposed.XposedHelpers; +import de.robv.android.xposed.callbacks.XC_LoadPackage; +import io.github.chipppppppppp.lime.LimeOptions; +import io.github.chipppppppppp.lime.R; + +public class KeepUnreadLSpatch implements IHook { + static boolean keepUnread = false; + + @Override + public void hook(LimeOptions limeOptions, XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable { + if (!limeOptions.KeepUnreadLSpatch.checked) return; + + XposedBridge.hookAllConstructors( + loadPackageParam.classLoader.loadClass("jp.naver.line.android.common.view.listview.PopupListView"), + new XC_MethodHook() { + @Override + protected void afterHookedMethod(MethodHookParam param) throws Throwable { + ViewGroup viewGroup = (ViewGroup) param.thisObject; + Context context = viewGroup.getContext(); + + Context moduleContext = context.getApplicationContext().createPackageContext(Constants.MODULE_NAME, Context.CONTEXT_IGNORE_SECURITY); + String textKeepUnread = moduleContext.getResources().getString(R.string.switch_keep_unread); + + RelativeLayout container = new RelativeLayout(context); + RelativeLayout.LayoutParams containerParams = new RelativeLayout.LayoutParams( + RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT); + container.setLayoutParams(containerParams); + + GradientDrawable background = new GradientDrawable(); + background.setShape(GradientDrawable.RECTANGLE); + background.setColor(Color.parseColor("#06C755")); + background.setCornerRadii(new float[]{100, 100, 80, 30, 100, 100, 80, 30}); + + container.setBackground(background); + + TextView label = new TextView(context); + label.setText(textKeepUnread); + label.setTextSize(18); + label.setTextColor(Color.WHITE); + label.setId(View.generateViewId()); + RelativeLayout.LayoutParams labelParams = new RelativeLayout.LayoutParams( + RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); + labelParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT); + labelParams.setMargins(40, 0, 0, 0); + container.addView(label, labelParams); + + Switch switchView = new Switch(context); + RelativeLayout.LayoutParams switchParams = new RelativeLayout.LayoutParams( + RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); + switchParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); + switchParams.setMargins(0, 0, 40, 0); + switchView.setChecked(false); + switchView.setOnCheckedChangeListener((buttonView, isChecked) -> { + keepUnread = isChecked; + }); + + container.addView(switchView, switchParams); + + ((ListView) viewGroup.getChildAt(0)).addFooterView(container); + } + } + ); + + XposedHelpers.findAndHookMethod( + loadPackageParam.classLoader.loadClass(Constants.MARK_AS_READ_HOOK.className), + Constants.MARK_AS_READ_HOOK.methodName, + new XC_MethodHook() { + @Override + protected void beforeHookedMethod(MethodHookParam param) throws Throwable { + if (keepUnread) { + param.setResult(null); + } + } + } + ); + } +} \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index d42bff78..5a6d0866 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -56,6 +56,7 @@ 未読のまま閲覧 + LsPatch用「未読のまま閲覧」スイッチを表示 バックアップ diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 53f5deec..c67c2f7f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -76,5 +76,6 @@ Really want to delete it? Nothing backed up Could not get properly.\nPlease restart the app + Show \"Read as unread\" switch for LsPatch