Skip to content

Conversation

@pengfeixx
Copy link
Contributor

@pengfeixx pengfeixx commented Dec 3, 2025

Fix no prompt when input is too long

Log: Fix no prompt when input is too long
pms: BUG-341977

Summary by Sourcery

Validate and constrain authentication name input to prevent missing prompts when the entered text exceeds the allowed length.

Bug Fixes:

  • Ensure an alert is shown when the authentication name exceeds the maximum allowed length instead of silently failing.

Enhancements:

  • Wrap the authentication name TextInput in a background rectangle that visually reflects alert state.
  • Enforce a maximum length on the authentication name field with real-time filtering of disallowed characters.
  • Extend validation to handle empty names and duplicate names with specific alert messages.
  • Update alert tooltip targeting to align with the new input background container.

@sourcery-ai
Copy link

sourcery-ai bot commented Dec 3, 2025

Reviewer's Guide

Refactors the authentication name TextInput into a styled container with real-time validation and alert feedback, adding length and emptiness checks while adjusting focus behavior and tooltip targeting.

Sequence diagram for real-time name validation and alert display

sequenceDiagram
    actor User
    participant AuthenticationUI
    participant textInputBackground
    participant textInputItem
    participant alert
    participant layout

    User->>AuthenticationUI: Click existing name
    AuthenticationUI->>textInputItem: Set focus true, readOnly false

    loop While user types
        User->>textInputItem: Edit text
        textInputItem->>textInputItem: onTextEdited
        textInputItem->>textInputItem: Filter invalid characters
        alt Length > maxLength
            textInputItem->>alert: show(No more than 15 characters)
            textInputItem->>textInputItem: Truncate to maxLength
        end
        textInputItem->>textInputItem: Update text if changed
    end

    User->>textInputItem: Press Enter/Return or lose focus
    textInputItem->>textInputItem: onEditingFinished
    textInputItem->>textInputItem: checkInputInvalid()

    alt Input invalid
        alt Empty
            textInputItem->>alert: show(The name cannot be empty)
        else Invalid chars and over length
            textInputItem->>alert: show(Use letters, numbers and underscores only, and no more than 15 characters)
        else Invalid chars only
            textInputItem->>alert: show(Use letters, numbers and underscores only)
        else Over length only
            textInputItem->>alert: show(No more than 15 characters)
        else Duplicate name
            textInputItem->>alert: show(This name already exists)
        end
        textInputItem->>textInputItem: text = modelData
        textInputItem->>textInputItem: Rebind text to modelData
    else Input valid
        textInputItem->>layout: requestRename(modelData, text)
        textInputItem->>textInputItem: Rebind text to modelData
    end

    textInputItem->>textInputItem: focus = false
    textInputItem->>textInputItem: onFocusChanged -> readOnly true

    note over alert,textInputBackground: alert.target changed from layout to textInputBackground
Loading

File-Level Changes

Change Details Files
Wrap the read-only TextInput in a styled Rectangle to support alert background coloring and better sizing.
  • Introduce a Rectangle as the visual background for the TextInput, including layout margins, width constraints, and corner radius.
  • Bind the Rectangle background color to the alert visibility using a palette-based alert color.
  • Move the TextInput inside the Rectangle and adjust anchors and alignment for left-aligned text within the padded container.
src/plugin-authentication/qml/authenticationMain.qml
Enhance TextInput behavior with max-length, real-time filtering, and improved validation and focus handling.
  • Add a maxLength property to the TextInput and clip content while allowing mouse selection.
  • Implement onTextEdited to filter out disallowed characters, enforce the length limit, and show an alert when the limit is exceeded.
  • Update onEditingFinished to reset bindings when invalid, call layout.requestRename only when there are valid changes, and make the field read-only on blur.
  • Handle both Enter and Return key presses to end editing and clear focus, and add an onFocusChanged handler that sets readOnly when focus is lost.
src/plugin-authentication/qml/authenticationMain.qml
Extend validation logic to handle empty values and adjust user-facing error messages and alert targeting.
  • Modify checkInputInvalid to allow empty text for regex validity checks but treat emptiness as an explicit error condition.
  • Add an explicit alert when the name is empty, and keep existing messages for invalid characters, over-length, and duplicate names while referencing maxLength.
  • Retarget D.AlertToolTip from the layout to the new textInputBackground container for visually-localized error prompts.
src/plugin-authentication/qml/authenticationMain.qml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes - here's some feedback:

  • In checkInputInvalid(), the isValid calculation mixes text and textInputItem.text and treats empty text as valid while separately handling isEmpty; consider normalizing to a single source (text) and simplifying the logic so validity and emptiness are not checked in overlapping conditions.
  • The alertBackgroundColor property on textInputBackground is defined but not used, while color is set from D.ColorSelector.alertBackgroundColor; either wire the property into color or remove the unused property to avoid confusion.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `checkInputInvalid()`, the `isValid` calculation mixes `text` and `textInputItem.text` and treats empty text as valid while separately handling `isEmpty`; consider normalizing to a single source (`text`) and simplifying the logic so validity and emptiness are not checked in overlapping conditions.
- The `alertBackgroundColor` property on `textInputBackground` is defined but not used, while `color` is set from `D.ColorSelector.alertBackgroundColor`; either wire the property into `color` or remove the unused property to avoid confusion.

## Individual Comments

### Comment 1
<location> `src/plugin-authentication/qml/authenticationMain.qml:146` </location>
<code_context>
-                            text: modelData
+                        Rectangle {
+                            id: textInputBackground
+                            property D.Palette alertBackgroundColor: DS.Style.edit.alertBackground
                             Layout.leftMargin: 10
                             Layout.preferredHeight: DS.Style.itemDelegate.height
</code_context>

<issue_to_address>
**suggestion:** The `alertBackgroundColor` property is defined but never used, which adds unnecessary noise.

`alertBackgroundColor` is declared on the `Rectangle`, but the `color` binding uses `D.ColorSelector.alertBackgroundColor` instead. Either bind `color` to this property (for configurability), e.g. `color: alert.visible ? alertBackgroundColor : "transparent"`, or remove the unused property to avoid confusion.

Suggested implementation:

```
                        Rectangle {
                            id: textInputBackground
                            property D.Palette alertBackgroundColor: DS.Style.edit.alertBackground
                            Layout.leftMargin: 10
                            Layout.preferredHeight: DS.Style.itemDelegate.height
                            color: alert.visible ? alertBackgroundColor : "transparent"

```

If there is already an existing `color` binding inside this `Rectangle` (for example `color: alert.visible ? D.ColorSelector.alertBackgroundColor : "transparent"`), you should **replace** that line instead of adding a new `color` binding. In that case, the edit should be:

- `color: alert.visible ? D.ColorSelector.alertBackgroundColor : "transparent"``color: alert.visible ? alertBackgroundColor : "transparent"`.

Ensure there is only one `color:` binding in this `Rectangle` block.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: caixr23, pengfeixx

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Fix no prompt when input is too long

Log: Fix no prompt when input is too long
pms: BUG-341977
@pengfeixx
Copy link
Contributor Author

/forcemerge

@deepin-ci-robot
Copy link

deepin pr auto review

我来对这段代码进行详细审查:

  1. 代码结构和逻辑改进:
  • 将TextInput包装在Rectangle中是好的改进,增加了背景色和边框效果,提升了UI体验
  • 增加了maxLength属性来统一管理最大长度限制,避免硬编码
  • 添加了实时输入过滤功能,可以即时阻止非法字符输入,比只在最后验证更好
  1. 性能优化建议:
  • 在onTextEdited中的正则表达式替换可以考虑使用更高效的方式,比如维护一个允许的字符集合
  • Layout.minimumWidth的绑定可能会导致频繁重排,建议设置一个合理的最小宽度固定值
  • nameList的获取在每次验证时都会执行,可以考虑缓存这些列表
  1. 安全性改进:
  • 输入验证逻辑更完善了,增加了空值检查
  • 实时过滤非法字符可以防止注入攻击
  • 建议增加对特殊Unicode字符的过滤,比如控制字符等
  1. 代码质量建议:
  • checkInputInvalid函数中的验证逻辑可以拆分成更小的函数,提高可读性
  • 正则表达式可以定义为常量,避免重复创建
  • 错误提示信息可以考虑统一管理,便于国际化维护
  1. 具体修改建议:
Rectangle {
    id: textInputBackground
    property D.Palette alertBackgroundColor: DS.Style.edit.alertBackground
    Layout.leftMargin: 10
    Layout.preferredHeight: DS.Style.itemDelegate.height
    Layout.maximumWidth: 200
    Layout.minimumWidth: 100  // 设置固定最小值
    radius: 4
    color: alert.visible ? D.ColorSelector.alertBackgroundColor : "transparent"

    // 定义正则表达式常量
    readonly property var validNameRegex: /^[A-Za-z0-9\u4e00-\u9fa5_]+$/
    
    // 缓存名称列表
    property var nameList: []
    
    Component.onCompleted: {
        updateNameList()
    }
    
    function updateNameList() {
        switch (itemRep.authType) {
        case CharaMangerModel.Type_Face:
            nameList = dccData.model.facesList;
            break;
        case CharaMangerModel.Type_Finger:
            nameList = dccData.model.thumbsList;
            break;
        case CharaMangerModel.Type_Iris:
            nameList = dccData.model.irisList;
            break;
        }
    }

    TextInput {
        id: textInputItem
        property int maxLength: 15
        anchors.fill: parent
        anchors.leftMargin: 8
        anchors.rightMargin: 8
        text: modelData
        verticalAlignment: Text.AlignVCenter
        horizontalAlignment: Text.AlignLeft
        focus: false
        wrapMode: Text.NoWrap
        readOnly: true
        focusPolicy: Qt.NoFocus
        color: palette.text
        clip: true
        selectByMouse: true

        onTextEdited: {
            var filteredText = filterInvalidChars(text);
            if (filteredText.length > maxLength) {
                alert.show(qsTr("No more than 15 characters"));
                filteredText = filteredText.slice(0, maxLength);
            }
            
            if (text !== filteredText) {
                text = filteredText;
            }
        }
        
        function filterInvalidChars(input) {
            // 使用字符白名单进行过滤
            var result = "";
            for (var i = 0; i < input.length; i++) {
                var char = input[i];
                if (validNameRegex.test(char)) {
                    result += char;
                }
            }
            return result;
        }

        onEditingFinished: {
            if (!validateInput()) {
                text = modelData;
                textInputItem.text = Qt.binding(function() { 
                    return modelData
                })
                return;
            }
            focus = false;
            if (modelData !== textInputItem.text) {
                layout.requestRename(modelData, text);
            }
            textInputItem.text = Qt.binding(function() { 
                return modelData
            })
        }

        function validateInput() {
            if (text.length === 0) {
                alert.show(qsTr("The name cannot be empty"));
                return false;
            }
            
            if (!validNameRegex.test(text)) {
                alert.show(qsTr("Use letters, numbers and underscores only"));
                return false;
            }
            
            if (text.length > maxLength) {
                alert.show(qsTr("No more than 15 characters"));
                return false;
            }
            
            if (nameList.includes(text) && text !== modelData) {
                alert.show(qsTr("This name already exists"));
                return false;
            }
            
            return true;
        }
    }
}

这些改进主要关注了:

  1. 性能优化:缓存名称列表,优化字符过滤逻辑
  2. 代码质量:提取常量,拆分函数,提高可维护性
  3. 安全性:改进输入验证逻辑
  4. 用户体验:更好的错误提示和输入限制

@deepin-bot
Copy link

deepin-bot bot commented Dec 4, 2025

This pr force merged! (status: blocked)

@deepin-bot deepin-bot bot merged commit 9efedbb into linuxdeepin:master Dec 4, 2025
15 of 17 checks passed
@pengfeixx pengfeixx deleted the fix-341977 branch December 4, 2025 02:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants