From a09d7bb63c1dfcaf1305d4a2420c7e012e62393c Mon Sep 17 00:00:00 2001 From: Next Alone <12210746+NextAlone@users.noreply.github.com> Date: Sun, 3 Nov 2024 05:54:33 +0800 Subject: [PATCH] feat: [WIP] add HyperOS AI in editor Signed-off-by: Next Alone <12210746+NextAlone@users.noreply.github.com> --- .../ui/Cells/TextSelectionHelper.java | 3 +- .../ui/Components/EditTextBoldCursor.java | 104 +++++++++++++++++- .../activity/ExperimentSettingActivity.java | 13 +++ .../xyz/nextalone/nnngram/utils/Defines.kt | 1 + .../main/res/values-zh/strings_nullgram.xml | 1 + TMessagesProj/src/main/res/values/ids.xml | 1 + .../src/main/res/values/strings_nullgram.xml | 1 + 7 files changed, 121 insertions(+), 3 deletions(-) diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextSelectionHelper.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextSelectionHelper.java index c5a015c80a..0c9d7a10bf 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextSelectionHelper.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextSelectionHelper.java @@ -1424,11 +1424,12 @@ private ActionMode.Callback createActionCallback() { final ActionMode.Callback callback = new ActionMode.Callback() { @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { + menu.removeItem(R.id.hyperos_ai); menu.add(Menu.NONE, android.R.id.copy, 0, android.R.string.copy); menu.add(Menu.NONE, R.id.menu_quote, 1, LocaleController.getString(R.string.Quote)); menu.add(Menu.NONE, android.R.id.selectAll, 2, android.R.string.selectAll); menu.add(Menu.NONE, TRANSLATE, 3, LocaleController.getString(R.string.TranslateMessage)); - menu.add(menu.NONE, BLOCK, 4, LocaleController.getString(R.string.block)); + menu.add(Menu.NONE, BLOCK, 4, LocaleController.getString(R.string.block)); return true; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/EditTextBoldCursor.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/EditTextBoldCursor.java index 9c8d180d27..a85b9d7306 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/EditTextBoldCursor.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/EditTextBoldCursor.java @@ -20,12 +20,18 @@ package org.telegram.ui.Components; import static org.telegram.messenger.AndroidUtilities.dp; +import static org.telegram.messenger.AndroidUtilities.getSystemProperty; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.annotation.SuppressLint; import android.annotation.TargetApi; +import android.app.Activity; +import android.content.ComponentName; import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.LinearGradient; @@ -81,6 +87,7 @@ import java.util.List; import xyz.nextalone.gen.Config; +import xyz.nextalone.nnngram.utils.Log; public class EditTextBoldCursor extends EditTextEffects { @@ -183,6 +190,9 @@ public void run() { public static boolean disableMarkdown = Config.markdownDisabled; private boolean showDisableMarkdown = false; + public static boolean IS_HYPEROS = getSystemProperty("ro.mi.os.version.name") != null; + private static final String HYPEROS_NOTES_PKG = "com.miui.notes"; + private static final String HYPEROS_AI_SERVICE = "com.miui.notes.ai.AiTextWidgetService"; static { try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { @@ -230,7 +240,7 @@ public void setShowDisableMarkdown(boolean show) { showDisableMarkdown = show; } - + public void setHintText2(CharSequence text, boolean animated) { if (hintAnimatedDrawable2 != null) { hintAnimatedDrawable2.setText(text, !LocaleController.isRTL && animated); @@ -1220,6 +1230,7 @@ public ActionMode startActionMode(ActionMode.Callback callback) { callback.onCreateActionMode(floatingActionMode, floatingActionMode.getMenu()); extendActionMode(floatingActionMode, floatingActionMode.getMenu()); addUndoRedo(floatingActionMode.getMenu()); + addHyperOsAi(floatingActionMode.getMenu()); floatingActionMode.invalidate(); getViewTreeObserver().addOnPreDrawListener(floatingToolbarPreDrawListener); invalidate(); @@ -1243,16 +1254,105 @@ private void addUndoRedo(Menu menu) { } } + private void addHyperOsAi(Menu menu) { + // Check if is HyperOS + if (!IS_HYPEROS || !Config.enableXiaomiHyperAi) { + return; + } + + PackageManager packageManager = getContext().getPackageManager(); + if (packageManager == null) { + return; + } + + try { + // Retrieve package information for HyperOS Notes + PackageInfo packageInfo = packageManager.getPackageInfo(HYPEROS_NOTES_PKG, 0); + + if (packageInfo.versionCode < 1100) { + return; + } + } catch (PackageManager.NameNotFoundException e) { + // Package not found, exit gracefully + return; + } + + // Add AI menu item if it doesn't already exist + if (menu.findItem(R.id.hyperos_ai) == null) { + menu.add(Menu.NONE, R.id.hyperos_ai, 0, "AI") + .setAlphabeticShortcut('s') + .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); + } + } + @Override public boolean onTextContextMenuItem(int id) { if (id == R.id.menu_markdown) { disableMarkdown = !disableMarkdown; floatingActionMode.finish(); return true; + } else if (id == R.id.hyperos_ai) { + startHyperOsAiService(); + return true; } return super.onTextContextMenuItem(id); } - + + private void startHyperOsAiService() { + try { + String currentPackage = getContext().getPackageName(); + Intent serviceIntent = new Intent(); + + // Pass the package name + serviceIntent.putExtra("packageName", currentPackage); + + // Handle selection logic + String selectedText = ""; + if (hasSelection()) { + int selectionStart = getSelectionStart(); + int selectionEnd = getSelectionEnd(); + if (selectionStart != selectionEnd) { + selectedText = getText().subSequence(selectionStart, selectionEnd).toString(); + } + } + serviceIntent.putExtra("selectedText", selectedText); + + // Store original view bounds + serviceIntent.putExtra("originalViewLeft", getLeft()); + serviceIntent.putExtra("originalViewTop", getTop()); + serviceIntent.putExtra("originalViewRight", getRight()); + serviceIntent.putExtra("originalViewBottom", getBottom()); + serviceIntent.putExtra("originalViewName", getClass().getName()); + serviceIntent.putExtra("isEditor", true); + + // Get the active screen location + int[] screenCoordinates = new int[2]; + Rect focusedRect = new Rect(); + getLocationOnScreen(screenCoordinates); + getFocusedRect(focusedRect); + focusedRect.offset(screenCoordinates[0], screenCoordinates[1]); + + Activity currentActivity = (Activity) getContext(); + if (currentActivity != null) { + Rect windowFrame = new Rect(); + currentActivity.getWindow().getDecorView().getWindowVisibleDisplayFrame(windowFrame); + + // Putting the visible window bounds into the Intent + serviceIntent.putExtra("left", windowFrame.left); + serviceIntent.putExtra("top", windowFrame.top); + serviceIntent.putExtra("right", windowFrame.right); + serviceIntent.putExtra("bottom", windowFrame.bottom); + serviceIntent.putExtra("taskId", currentActivity.getTaskId()); + } + + // Prepare and start the service + serviceIntent.setComponent(new ComponentName(HYPEROS_NOTES_PKG, HYPEROS_AI_SERVICE)); + getContext().startForegroundService(serviceIntent); + } catch (Exception e) { + Log.e("Failed to start HyperOS AI service", e); + } + } + private boolean shouldShowQuoteButton() { if (!hasSelection() || getSelectionStart() < 0 || getSelectionEnd() < 0 || getSelectionStart() == getSelectionEnd()) { return false; diff --git a/TMessagesProj/src/main/java/xyz/nextalone/nnngram/activity/ExperimentSettingActivity.java b/TMessagesProj/src/main/java/xyz/nextalone/nnngram/activity/ExperimentSettingActivity.java index bee60679b9..8b89fb9c40 100644 --- a/TMessagesProj/src/main/java/xyz/nextalone/nnngram/activity/ExperimentSettingActivity.java +++ b/TMessagesProj/src/main/java/xyz/nextalone/nnngram/activity/ExperimentSettingActivity.java @@ -19,6 +19,8 @@ package xyz.nextalone.nnngram.activity; +import static org.telegram.messenger.AndroidUtilities.getSystemProperty; + import android.annotation.SuppressLint; import android.content.Context; import android.view.View; @@ -64,6 +66,7 @@ public class ExperimentSettingActivity extends BaseActivity { private int linkedUserRow; private int overrideChannelAliasRow; private int showRPCErrorRow; + private int enableXiaomiHyperAiRow; private int specialRow; private int special2Row; @@ -219,6 +222,11 @@ protected void onItemClick(View view, int position, float x, float y) { if (view instanceof TextCheckCell) { ((TextCheckCell) view).setChecked(Config.ignoreChatStrict); } + } else if (position == enableXiaomiHyperAiRow) { + Config.toggleEnableXiaomiHyperAi(); + if (view instanceof TextCheckCell) { + ((TextCheckCell) view).setChecked(Config.enableXiaomiHyperAi); + } } } @@ -252,6 +260,9 @@ protected void updateRows() { } var user = UserConfig.getInstance(currentAccount).getCurrentUser(); showRPCErrorRow = user != null && user.developer() ? addRow("showRPCError") : -1; + if (getSystemProperty("ro.mi.os.version.name") != null) { + enableXiaomiHyperAiRow = addRow("enableXiaomiHyperAi"); + } experiment2Row = addRow(); if (Config.showHiddenSettings) { @@ -391,6 +402,8 @@ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position, boole textCell.setTextAndCheck(LocaleController.getString("enablePanguOnReceiving", R.string.enablePanguOnReceiving), Config.enablePanguOnReceiving, true); } else if (position == ignoreChatStrictRow) { textCell.setTextAndCheck("", Config.ignoreChatStrict, true); + } else if (position == enableXiaomiHyperAiRow) { + textCell.setTextAndCheck(LocaleController.getString(R.string.enableXiaomiHyperAi), Config.enableXiaomiHyperAi, true); } break; } diff --git a/TMessagesProj/src/main/java/xyz/nextalone/nnngram/utils/Defines.kt b/TMessagesProj/src/main/java/xyz/nextalone/nnngram/utils/Defines.kt index ee5e1f1cac..72e2352bb1 100644 --- a/TMessagesProj/src/main/java/xyz/nextalone/nnngram/utils/Defines.kt +++ b/TMessagesProj/src/main/java/xyz/nextalone/nnngram/utils/Defines.kt @@ -246,6 +246,7 @@ object Defines { @BooleanConfig(true) const val showTextRegular = "showTextRegular" @BooleanConfig(true) const val showTextQuote = "showTextQuote" @BooleanConfig(true) const val showTextMonoCode = "showTextMonoCode" + @BooleanConfig(false) const val enableXiaomiHyperAi = "enableXiaomiHyperAi" /** * 数组中元素未找到的下标,值为-1 diff --git a/TMessagesProj/src/main/res/values-zh/strings_nullgram.xml b/TMessagesProj/src/main/res/values-zh/strings_nullgram.xml index fede99fa7a..c25bcd0f3b 100644 --- a/TMessagesProj/src/main/res/values-zh/strings_nullgram.xml +++ b/TMessagesProj/src/main/res/values-zh/strings_nullgram.xml @@ -378,4 +378,5 @@ 禁用视频重力检测 隐藏标题代理入口 加入频道后自动静音 + 在输入框中显示小米澎湃AI diff --git a/TMessagesProj/src/main/res/values/ids.xml b/TMessagesProj/src/main/res/values/ids.xml index a14bae4357..d76b134795 100644 --- a/TMessagesProj/src/main/res/values/ids.xml +++ b/TMessagesProj/src/main/res/values/ids.xml @@ -79,4 +79,5 @@ + diff --git a/TMessagesProj/src/main/res/values/strings_nullgram.xml b/TMessagesProj/src/main/res/values/strings_nullgram.xml index b94cf90d58..afa45742a2 100644 --- a/TMessagesProj/src/main/res/values/strings_nullgram.xml +++ b/TMessagesProj/src/main/res/values/strings_nullgram.xml @@ -391,4 +391,5 @@ Disable gravity detection in video Hide proxy entry in title Auto mute after joining channel + Enable Xiaomi HyperAI in editor