feat: add undo/redo

N-setting -> Chat -> Text Style -> Undo/Redo
This commit is contained in:
NextAlone 2022-03-18 17:33:11 +08:00
parent e78cfce4cb
commit 6212558ee3
No known key found for this signature in database
GPG Key ID: DBA7B0AEF8C1CD2C
7 changed files with 85 additions and 2 deletions

View File

@ -399,6 +399,10 @@ dependencies {
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.5"
}
dependencies {
// add for undo and redo
implementation 'org.lsposed.hiddenapibypass:hiddenapibypass:4.3'
}
apply plugin: "com.google.gms.google-services"
apply plugin: "com.google.firebase.crashlytics"

View File

@ -41,9 +41,9 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.EditText;
import android.widget.TextView;
import org.lsposed.hiddenapibypass.HiddenApiBypass;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.FileLog;
@ -58,6 +58,8 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import xyz.nextalone.nagram.NaConfig;
public class EditTextBoldCursor extends EditTextEffects {
private static Field mEditor;
@ -143,6 +145,60 @@ public class EditTextBoldCursor extends EditTextEffects {
private List<TextWatcher> registeredTextWatchers = new ArrayList<>();
private boolean isTextWatchersSuppressed = false;
private static Method canUndoMethod;
private static Method canRedoMethod;
static {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
canUndoMethod = HiddenApiBypass.getDeclaredMethod(TextView.class, "canUndo");
canRedoMethod = HiddenApiBypass.getDeclaredMethod(TextView.class, "canRedo");
} else {
canUndoMethod = TextView.class.getDeclaredMethod("canUndo");
canRedoMethod = TextView.class.getDeclaredMethod("canRedo");
}
canUndoMethod.setAccessible(true);
canRedoMethod.setAccessible(true);
} catch (Exception e) {
e.printStackTrace();
FileLog.e(e);
canUndoMethod = null;
canRedoMethod = null;
}
}
public final boolean canUndo() {
if (canUndoMethod == null) {
return false;
}
try {
return (boolean) canUndoMethod.invoke(this);
} catch (Exception e) {
FileLog.e(e);
}
return false;
}
public final boolean canRedo() {
if (canRedoMethod == null) {
return false;
}
try {
return (boolean) canRedoMethod.invoke(this);
} catch (Exception e) {
FileLog.e(e);
}
return false;
}
private void addUndoRedo(Menu menu) {
if (canUndo()) {
menu.add(R.id.menu_undoredo, android.R.id.undo, 2, LocaleController.getString("TextUndo", R.string.TextUndo));
}
if (canRedo()) {
menu.add(R.id.menu_undoredo, android.R.id.redo, 3, LocaleController.getString("TextRedo", R.string.TextRedo));
}
}
@TargetApi(23)
private class ActionModeCallback2Wrapper extends ActionMode.Callback2 {
@ -976,6 +1032,9 @@ public class EditTextBoldCursor extends EditTextEffects {
};
callback.onCreateActionMode(floatingActionMode, floatingActionMode.getMenu());
extendActionMode(floatingActionMode, floatingActionMode.getMenu());
if (NaConfig.INSTANCE.getShowTextUndoRedo().Bool()) {
addUndoRedo(floatingActionMode.getMenu());
}
floatingActionMode.invalidate();
getViewTreeObserver().addOnPreDrawListener(floatingToolbarPreDrawListener);
invalidate();

View File

@ -470,7 +470,7 @@ public class NekoChatSettingsActivity extends BaseFragment implements Notificati
LinearLayout linearLayoutInviteContainer = new LinearLayout(context);
linearLayoutInviteContainer.setOrientation(LinearLayout.VERTICAL);
linearLayout.addView(linearLayoutInviteContainer, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
for (int a = 0; a < 9; a++) {
for (int a = 0; a < 10; a++) {
TextCheckCell textCell = new TextCheckCell(getParentActivity());
textCell.setTag(a);
switch (a) {
@ -510,6 +510,9 @@ public class NekoChatSettingsActivity extends BaseFragment implements Notificati
textCell.setTextAndCheck(LocaleController.getString("Regular", R.string.Regular), NaConfig.INSTANCE.getShowTextRegular().Bool(), false);
break;
}
case 9: {
textCell.setTextAndCheck(LocaleController.getString("TextUndoRedo", R.string.TextUndoRedo), NaConfig.INSTANCE.getShowTextUndoRedo().Bool(), false);
}
}
textCell.setTag(a);
textCell.setBackground(Theme.getSelectorDrawable(false));
@ -553,6 +556,10 @@ public class NekoChatSettingsActivity extends BaseFragment implements Notificati
textCell.setChecked(NaConfig.INSTANCE.getShowTextRegular().toggleConfigBool());
break;
}
case 9: {
textCell.setChecked(NaConfig.INSTANCE.getShowTextUndoRedo().toggleConfigBool());
break;
}
}
});

View File

@ -103,6 +103,12 @@ object NaConfig {
ConfigItem.configTypeInt,
0
)
val showTextUndoRedo =
addConfig(
"TextUndoRedo",
ConfigItem.configTypeBool,
false
)
fun addConfig(
k: String,

View File

@ -10,4 +10,7 @@
<string name="CombineMessageEnabledWithReply">合并并回复首条消息</string>
<string name="CombineMessageEnabled">仅合并消息</string>
<string name="CombineMessageDisabled">关闭</string>
<string name="TextUndoRedo">撤销/重做</string>
<string name="TextUndo">撤销</string>
<string name="TextRedo">重做</string>
</resources>

View File

@ -9,6 +9,7 @@
<item name="menu_strike" type="id"/>
<item name="menu_underline" type="id"/>
<item name="menu_groupbolditalic" type="id"/>
<item name="menu_undoredo" type="id"/>
<item name="parent_tag" type="id"/>
<item name="object_tag" type="id"/>
<item name="index_tag" type="id"/>

View File

@ -10,4 +10,7 @@
<string name="CombineMessageEnabledWithReply">Combine Message Enabled With Reply</string>
<string name="CombineMessageEnabled">Combine Message Enabled</string>
<string name="CombineMessageDisabled">Combine Message Disabled</string>
<string name="TextUndoRedo">Undo/Redo</string>
<string name="TextUndo">Undo</string>
<string name="TextRedo">Redo</string>
</resources>