Add JSON editor for custom URL inline bot rules#62
Merged
omg-xtao merged 12 commits intoMay 5, 2026
Conversation
Reviewer's GuideImplements a local, JSON-based configuration and UI editor for URL inline bot rules, replaces the previous remote-fetch and serialized storage mechanism, and simplifies inline bot result sending behavior for media results. Sequence diagram for applying URL inline bot rules when checking a URLsequenceDiagram
actor User
participant ChatActivity
participant InlineBotRulesHelper
participant NaConfig
User->>ChatActivity: Type_or_paste_message_text
ChatActivity->>InlineBotRulesHelper: doRegex(textToCheck)
InlineBotRulesHelper->>NaConfig: getFixUrlAutoInlineBot().Bool()
NaConfig-->>InlineBotRulesHelper: fixUrlAutoInlineBot_enabled
InlineBotRulesHelper->>NaConfig: getFixUrlAutoInlineBotRules().String()
NaConfig-->>InlineBotRulesHelper: jsonRulesString
InlineBotRulesHelper->>InlineBotRulesHelper: loadInlineBotRules()
InlineBotRulesHelper->>InlineBotRulesHelper: parseInlineBotRules(jsonRulesString,true)
InlineBotRulesHelper->>InlineBotRulesHelper: Compile_case_insensitive_regex_patterns
InlineBotRulesHelper->>InlineBotRulesHelper: Iterate_rules_and_match_text
InlineBotRulesHelper-->>ChatActivity: matchingBotUsername_or_null
ChatActivity-->>User: Use_inline_bot_username_if_not_null
Updated class diagram for InlineBotRulesHelper and related configuration and UIclassDiagram
class InlineBotRulesHelper {
-static InlineBotRulesHelper Instance
-ArrayList~InlineBotRule~ inlineBotRules
-String loadedRules
+static InlineBotRulesHelper getInstance()
-void loadInlineBotRules()
+String doRegex(String textToCheck)
+static ArrayList~InlineBotRule~ parseInlineBotRules(String list, boolean compilePattern)
-static void addInlineBotRule(ArrayList~InlineBotRule~ rules, String username, String rule, boolean compilePattern)
+static String serializeInlineBotRules(ArrayList~InlineBotRule~ rules)
}
class InlineBotRule {
+String username
+String rule
+Pattern regexPattern
+InlineBotRule()
+InlineBotRule(String username, String rule)
+InlineBotRule(String username, String rule, boolean compilePattern)
+void buildRegexPattern()
}
class NaConfig {
<<object>>
+ConfigItem fixUrlAutoInlineBot
+ConfigItem fixUrlAutoInlineBotRules
+NaConfig INSTANCE
}
class ConfigItem {
+String key
+int type
+String String()
+boolean Bool()
+void setConfigString(String value)
+String getKey()
}
class NekoExperimentalSettingsActivity {
-AbstractConfigCell fixUrlAutoInlineBotRow
-AbstractConfigCell fixUrlAutoInlineBotRulesRow
+void showFixUrlAutoInlineBotRulesDialog()
-void addFixUrlAutoInlineBotRuleRow(Context context, LinearLayout rowsContainer, ArrayList~EditTextBoldCursor[]~ ruleRows, String rule, String username)
}
class ConfigCellTextCheck {
}
class ConfigCellTextInput {
}
class NaConfig_usage_in_UI {
}
InlineBotRulesHelper "1" *-- "*" InlineBotRule : contains
NaConfig "1" o-- "1" ConfigItem : defines
NekoExperimentalSettingsActivity ..> InlineBotRulesHelper : uses_parse_and_serialize_rules
NekoExperimentalSettingsActivity ..> NaConfig : reads_and_writes_FixUrlAutoInlineBotRules
NekoExperimentalSettingsActivity ..> ConfigCellTextCheck : uses
NekoExperimentalSettingsActivity ..> ConfigCellTextInput : uses
NaConfig_usage_in_UI ..> NaConfig : singleton_ACCESS_via_INSTANCE
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- In
showFixUrlAutoInlineBotRulesDialog, you manually strip a leading@from usernames whileInlineBotRulesHelper.addInlineBotRulealso normalizes usernames; consider centralizing this normalization in a single helper to avoid subtle divergence in behavior over time. - The
+button is created for every rule row inaddFixUrlAutoInlineBotRuleRow, which allows adding new rows from any position; if that’s not intentional, you could restrict the add button to the last row to keep the layout simpler and avoid accidental insertions in the middle.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `showFixUrlAutoInlineBotRulesDialog`, you manually strip a leading `@` from usernames while `InlineBotRulesHelper.addInlineBotRule` also normalizes usernames; consider centralizing this normalization in a single helper to avoid subtle divergence in behavior over time.
- The `+` button is created for every rule row in `addFixUrlAutoInlineBotRuleRow`, which allows adding new rows from any position; if that’s not intentional, you could restrict the add button to the last row to keep the layout simpler and avoid accidental insertions in the middle.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
b0517b2 to
6cc1189
Compare
Contributor
Author
|
Addressed Sourcery's feedback in the latest push:
|
BraveSail
added a commit
to BraveSail/Nagram
that referenced
this pull request
Apr 29, 2026
Port the small follow-up changes from upstream PR NextAlone#62 onto the current branch after merging latest upstream/dev. Normalize bot usernames in one helper and only show the add button on the last rule row.
Replace the cramped two-column inline bot rules editor with stacked card rows inside the experimental settings dialog. Add a clear hint, a full-width add control, per-row delete buttons, and shared EditText styling for URL regex and inline bot username fields. Validation: git diff --check passed. Full Gradle configuration remains blocked locally by missing Android NDK 26.1.10909125.
Populate FixUrlAutoInlineBotRules with the five default rules shown in the settings screenshot: x.com and twitter.com use twpicbot, threads.com and threads.net use lizardman_bot, and pixiv.net uses pixiv_bot. The branch was already merged with the latest upstream/dev before this change. Verified the embedded JSON parses successfully.
Restore the original PhotoViewer media preview path for regular photo/gif/video inline bot results so manual inline bot usage no longer sends media immediately. Add FixUrlAutoInlineBotSkipMediaPreview as an opt-in setting. When enabled, the instant send behavior only applies to automatic URL inline bot searches detected by MentionsAdapter; other inline bot results keep the preview/selection flow. Validation: git diff --check; XML parsing for updated string resources; JSON parsing for the default URL inline bot rules. Full Gradle validation is blocked in this container because Android SDK/local.properties is not configured.
Reject invalid regex patterns in the custom URL inline bot rules dialog before saving. The dialog now keeps focus on the invalid row and shows which rule failed, instead of accepting a value that later gets ignored at runtime. Tighten the built-in default rules so dots are escaped and matches are bounded to URL-like hosts. This avoids broad matches such as twitter-com, notwitter.com, and query-only mentions on unrelated URLs. Also log runtime parse failures in InlineBotRulesHelper instead of silently swallowing them. Validation: git diff --check, XML parsing for updated string resources, JSON parsing for default rules, and Java Pattern compilation for all default regexes.
The PR workflow's Debug Build step was assembling the release variant after removing the release signing config, producing unsigned release APK artifacts. Those artifacts are not suitable for direct smoke testing and can behave differently from the intended debug package. Switch the PR workflow to assembleDebug and replace the release signing config with the default debug signing config, so uploaded PR artifacts are debuggable debug APKs intended for installation/testing. Validation: git diff --check.
This reverts commit 2af335e.
Sync only the inline bot rule editor follow-up changes into the PR branch. Keep simple mode host-only, serialize simple hosts as backend regex rules, persist advanced mode, validate regex/host inputs, and block unsafe advanced-to-simple conversion. Also includes the editor layout/string follow-ups needed by these settings UI changes. Excludes release keystore and native integrity changes from the PR branch. Validation: git diff --check.
72df582 to
3deec65
Compare
omg-xtao
approved these changes
May 5, 2026
omg-xtao
added a commit
that referenced
this pull request
May 5, 2026
- 新增 InlineBotRulesRepository 作为统一规则仓库,管理远程(只读)和本地(可编辑)规则 - 新增 InlineBotRulesSettingActivity 规则设置页面,支持远程规则开关和本地规则 CRUD - 新增 InlineBotRulesEditActivity 规则编辑页面 - 在 NekoExperimentalSettingsActivity 中整合相关设置项,形成独立的功能模块 Co-authored-by: BraveSail <49320262+BraveSail@users.noreply.github.com> Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR makes URL auto inline bot rules local and user-configurable from Experimental Settings.
Users can manage multiple URL matching rules in a row-based editor. Each rule maps a matched URL/host to the inline bot username that should be used.
The editor now has two explicit modes:
x.com. The saved backend rule still uses a regex, but the UI only accepts valid host input. A simple host rule matches the host itself and all deeper subdomains, for examplex.com,a.x.com, andb.a.x.com.Rules are evaluated in the displayed list order. If both
x.comanda.x.comexist, whichever row matches first wins.Functional changes
FixUrlAutoInlineBotRulesas a string config value storing a JSON array of rules.FixUrlAutoInlineBotRulesAdvancedModeso the selected Simple/Advanced editor mode is persisted instead of being inferred only from saved patterns.NekoExperimentalSettingsActivitywith editable pattern/host and bot username fields.Pattern.compile(..., CASE_INSENSITIVE)before saving@before saving/parsing.x.com→twpicbottwitter.com→twpicbotthreads.com→lizardman_botthreads.net→lizardman_botpixiv.net→pixiv_bottwitter-com,notwitter.com, or query-only matches inside unrelated URLs.FixUrlAutoInlineBotSkipMediaPreviewas an opt-in switch for direct media inline result sending. It is off by default, so normal photo/gif/video inline bot results still openPhotoViewerfor preview/selection. When enabled, direct sending only applies to automatic URL inline bot searches.devbranch state used by this PR branch.Review follow-up covered
Config format
Rules are saved as JSON. Backend matching remains regex-based for compatibility:
[ {"pattern":"(^|[\\s(\\[{<])(?:https?://)?([\\w-]+\\.)*x\\.com(?=[:/?#\\s)\\]}>]|$)","bot":"twpicbot"}, {"pattern":"(^|[\\s(\\[{<])(?:https?://)?([\\w-]+\\.)*twitter\\.com(?=[:/?#\\s)\\]}>]|$)","bot":"twpicbot"} ]Empty rows are skipped when saving. Existing invalid patterns that somehow reach runtime are logged and skipped.
Notes
rule => bot_usernamefree-form format is intentionally not kept for long-term compatibility, because it was only introduced on this feature branch before the JSON editor change.Testing
git diff --checkpasses.Patternsuccessfully.x.commatchesx.com,a.x.com, andb.a.x.coma.x.comdoes not match plainx.comThe PR branch now contains only the inline bot rules/settings follow-up changes on top of the prior PR branch state.