Skip to content

fix: when drag app to another app from folder,add animation and auto-move with folders.#574

Merged
BLumia merged 1 commit into
linuxdeepin:masterfrom
wjyrich:fix-bug-288847
Jun 10, 2025
Merged

fix: when drag app to another app from folder,add animation and auto-move with folders.#574
BLumia merged 1 commit into
linuxdeepin:masterfrom
wjyrich:fix-bug-288847

Conversation

@wjyrich
Copy link
Copy Markdown
Contributor

@wjyrich wjyrich commented Jun 10, 2025

as title.

PMS-BUG-288847

Summary by Sourcery

Improve folder grid drag-and-drop by adding sorted models, consistent move animations, and timed edge-triggered auto-move previews

New Features:

  • Automatically preview and execute insert moves when dragging an app near the edges of a folder after a short delay

Bug Fixes:

  • Restore smooth reposition animations for items moved between apps within folders

Enhancements:

  • Wrap folder items in a SortProxyModel with filterOnlyMode to maintain consistent ordering
  • Extract and apply a reusable itemMove Transition with eased animation and shorter duration via GridViewContainer

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Jun 10, 2025

Reviewer's Guide

This PR wraps the folder proxy with a SortProxyModel to enforce stable ordering, adds eased item-move transitions in grid views, and implements auto-move-on-drag behavior within folders via drag event handlers and a timed preview slider.

Sequence Diagram: App Auto-Move and Sorting during Drag in Folder

sequenceDiagram
    actor User
    participant DDA as "DelegateDropArea"
    participant FDAT as "FolderDragApplyTimer"
    participant FolderLogic as "Folder Logic (dropOnItem, SortProxyModel)"

    User->>+DDA: Drags item (onEntered)
    DDA->>FDAT: set dragId, restart()

    User->>DDA: Moves item (onPositionChanged)
    DDA->>FDAT: update dragId, currentDropX
    opt dragId is set and timer not running
      DDA->>FDAT: restart()
    end

    loop Timer Ticks (interval: 500ms)
        FDAT->>FDAT: onTriggered()
        alt dragId is set AND item is near edge (op != 0)
            FDAT->>FolderLogic: dropOnItem(dragId, targetItemId, op)  // Preview move
            FolderLogic->>FolderLogic: sortProxyModel.sort(0)
        end
    end

    alt User drops item
        User->>DDA: Drops item (onDropped)
        DDA->>FDAT: stop(), clear dragId
        DDA->>FolderLogic: dropOnItem(dragId, targetItemId, op) // Final move
        FolderLogic->>FolderLogic: sortProxyModel.sort(0)
    else User drags item out
        User->>DDA: Drags item out (onExited)
        DDA->>FDAT: stop(), clear dragId
    end
    DDA-->>-User: Interaction feedback
Loading

Class Diagram: Model Sorting and Drag/Drop Logic in FolderGridViewPopup.qml

classDiagram
    class MultipageSortFilterProxyModel {
        <<QML Component>>
        id: folderProxyModel
        +filterOnlyMode: bool  // Modified
    }

    class SortProxyModel {
        <<QML Component (New)>>
        id: sortProxyModel
        +sourceModel: MultipageSortFilterProxyModel
        +sortRole: int
        +Component.onCompleted() void
        +sort(index: int) void
    }

    class GridViewInFolder {
        <<QML Component>>
        +model: SortProxyModel  // Changed
        +itemMove: Transition  // Updated configuration (e.g., duration: 200, easing: OutQuad)
    }

    class DelegateDropArea {
        <<QML Component>>
        +onEntered(drag: DragEvent) void  // New handler
        +onPositionChanged(drag: DragEvent) void  // New handler
        +onExited() void  // New handler
        +onDropped(drop: DropEvent) void  // Logic modified for timer & sorting
    }

    class FolderDragApplyTimer {
        <<QML Component (New, in DelegateDropArea)>>
        id: folderDragApplyTimer
        +interval: int
        +dragId: string
        +currentDropX: real
        +onTriggered() void
    }

    SortProxyModel --|> MultipageSortFilterProxyModel : uses as sourceModel
    GridViewInFolder --|> SortProxyModel : uses as model
    DelegateDropArea o-- FolderDragApplyTimer : contains
Loading

Class Diagram: Item Move Transition Propagation in GridViewContainer.qml

classDiagram
    class GridViewContainer {
        <<QML Component>>
        +itemMove: Transition  // New property
    }
    class InnerGridView {
        <<QML Component (child of GridViewContainer)>>
        +displaced: Transition  // New binding (uses root.itemMove)
        +move: Transition  // New binding (uses root.itemMove)
        +moveDisplaced: Transition  // New binding (uses root.itemMove)
    }
    GridViewContainer o-- InnerGridView : contains
Loading

File-Level Changes

Change Details Files
Enforce stable ordering in folder grid
  • Enabled filterOnlyMode on the existing folder proxy model
  • Introduced a SortProxyModel with sortRole and initial sort on completion
  • Replaced direct folderProxyModel references in both grid views with sortProxyModel
  • Invoked sortProxyModel.sort after each drop to refresh order
qml/FolderGridViewPopup.qml
Add eased move animations to grid items
  • Defined an itemMove Transition with NumberAnimation (duration 200ms, Easing.OutQuad)
  • Applied itemMove to itemMove in FolderGridViewPopup grid views
  • Exposed itemMove as a Transition property in GridViewContainer and wired it to displaced, move, and moveDisplaced
qml/FolderGridViewPopup.qml
qml/windowed/GridViewContainer.qml
Implement auto-move-on-drag in folder cells
  • Added onEntered, onPositionChanged, onExited handlers in DelegateDropArea to manage dragId and currentDropX
  • Created folderDragApplyTimer to preview dropOnItem operations every 500ms based on pointer position
  • Stopped timer and cleared dragId on drop, then triggered dropOnItem and resort
qml/FolderGridViewPopup.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
Copy Markdown

@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 @wjyrich - I've reviewed your changes - here's some feedback:

  • Consider extracting the itemMove Transition into a shared property or style instead of duplicating the same animation block in both grid views for easier maintenance.
  • You’re instantiating a Timer in every DelegateDropArea to handle drag previews—centralize that logic at the popup level to avoid creating multiple timers and simplify state management.
  • The single SortProxyModel is used by both grid views and may cause cross-view reordering issues—consider giving each view its own proxy instance to isolate their sorting behavior.
Here's what I looked at during the review
  • 🟡 General issues: 3 issues found
  • 🟢 Security: all looks good
  • 🟢 Testing: all looks good
  • 🟢 Complexity: all looks good
  • 🟢 Documentation: all looks good

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.

Comment thread qml/FolderGridViewPopup.qml
Comment thread qml/FolderGridViewPopup.qml Outdated
Comment thread qml/FolderGridViewPopup.qml
@deepin-ci-robot
Copy link
Copy Markdown

deepin pr auto review

代码审查意见:

  1. FolderGridViewPopup.qml文件中,MultipageSortFilterProxyModelfilterOnlyMode属性被设置为true,但未提供相应的注释说明为什么需要这个设置。建议添加注释说明其用途。

  2. SortProxyModelComponent.onCompleted信号中,调用了sort(0)方法。如果sort(0)是默认排序,建议在代码中明确注释说明这一点,以便其他开发者理解。

  3. GridViewContainer.qml文件中,widthheight的计算逻辑被修改,但未提供修改后的计算逻辑的注释说明。建议添加注释说明修改的原因和目的。

  4. GridViewContainer.qml文件中,height的计算逻辑中,当root.rows == 0时,直接返回parent.height,这可能不是预期的行为。建议确认这个逻辑是否符合设计要求。

  5. windowed/GridViewContainer.qml文件中,新增了itemMove属性,但未在代码中看到相应的使用。建议确认是否需要这个属性,并在使用前进行相应的注释说明。

  6. DelegateDropArea组件中,onEnteredonPositionChangedonExited信号处理函数中,folderDragApplyTimerdragIdcurrentDropX属性被频繁设置,建议将这些设置操作封装成一个函数,以提高代码的可读性和可维护性。

  7. DelegateDropArea组件的onTriggered函数中,当op不为0时,调用了dropOnItemsortProxyModel.sort(0)方法。建议在这些操作前添加注释说明其目的和逻辑。

  8. DelegateDropArea组件的Timer中,onTriggered函数中使用了if (dragId === "") return的判断,但未对dragId的初始值进行设置。建议在Timer组件初始化时设置dragId的初始值。

  9. DelegateDropArea组件的Timer中,onTriggered函数中使用了parent.width / 4parent.width - sideOpPadding来计算侧边操作区域,但未对parent.width为0的情况进行处理。建议添加相应的判断逻辑,以避免除以0的错误。

  10. DelegateDropArea组件的Timer中,onTriggered函数中使用了dropOnItem方法,但未提供dropOnItem方法的实现。建议确认dropOnItem方法的实现,并确保其正确性。

以上是针对代码审查意见的总结,希望能够对您有所帮助。

@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: BLumia, wjyrich

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

Details 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

@BLumia BLumia merged commit b2f5046 into linuxdeepin:master Jun 10, 2025
9 of 10 checks passed
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