status-desktop/ui/app/AppLayouts/Profile/helpers/VisibilityAndPositionDirtyS...

122 lines
4.3 KiB
QML
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import QtQml 2.15
import StatusQ 0.1
import StatusQ.Core.Utils 0.1
/**
* Basic building block for storing temporary state in the "Profile Showcase"
* functionality. Allows to store on the UI side the temporary position and
* visibility level. Can store temporary state for Communities, Accounts,
* Collectibles and Assets.
*/
WritableProxyModel {
id: root
/**
* "Hidden" is a special type of visibility that requires special
* treatment. When the visibility is changed from hidden to other type
* of visibility, in addition to changing the visibility, the appropriate
* position is also set.
*/
property int visibilityHidden: 0
/* Provides the list of objects representing the current state in the
* in the following format:
* [ {
* showcaseKey: <string or integer>
* showcasePosition: <integer>
* showcaseVisibility: <integer>
* }
* ]
*
* The entries with visibility 0 (hidden) are not included in the list.
*/
function currentState(roleNames) {
const visible = d.getVisibleEntries(roleNames)
const minPos = Math.min(...visible.map(e => e.showcasePosition))
return visible.map(e => { e.showcasePosition -= minPos; return e })
}
/* Sets the visibility of the given item. If the element was hidden, it is
* positioned last.
*/
function setVisibility(key, visibility) {
const sourceIdx = d.indexByKey(key)
const oldVisibility = d.getVisibility(sourceIdx)
if (oldVisibility === visibility)
return
// hiding, changing visibility level
if (visibility === visibilityHidden) {
set(sourceIdx, { showcaseVisibility: undefined, showcasePosition: undefined})
return
}
if (oldVisibility === visibilityHidden || oldVisibility === undefined) {
// unhiding
const positions = d.getVisibleEntries().map(e => e.showcasePosition)
const position = Math.max(-1, ...positions) + 1
set(sourceIdx, { showcaseVisibility: visibility, showcasePosition: position })
return
}
// changing visibility level
set(sourceIdx, { showcaseVisibility: visibility })
}
/* Sets the showcasePosition of the item. The "toShowcasePosition" is the
* new position of the item. All items in between the previous and the
* new position are moved accordingly.
*/
function changePosition(index, toShowcasePosition) {
// changing the position of the items in between
const fromShowcasePosition = get(index).showcasePosition
const minPosition = Math.min(fromShowcasePosition, toShowcasePosition)
const maxPosition = Math.max(fromShowcasePosition, toShowcasePosition)
const visible = d.getVisibleEntries()
visible.sort((a, b) => a.showcasePosition - b.showcasePosition)
.filter(e => e.showcasePosition >= minPosition && e.showcasePosition <= maxPosition && e.index !== index)
.forEach(e => {
e.showcasePosition += (fromShowcasePosition > toShowcasePosition ? 1 : -1)
set(e.index, { showcasePosition: e.showcasePosition })
})
//changing the position of the item
set(index, { showcasePosition: toShowcasePosition })
}
syncedRemovals: true
readonly property QtObject d_: QtObject {
id: d
function indexByKey(key) {
return ModelUtils.indexOf(root, "showcaseKey", key)
}
function getVisibleEntries(roleNames = ["showcaseKey", "showcasePosition", "showcaseVisibility"]) {
if (roleNames.length === 0)
roleNames = ["showcaseKey", "showcasePosition", "showcaseVisibility"]
if (!roleNames.includes("showcaseVisibility"))
roleNames.push("showcaseVisibility")
const keysAndPos = ModelUtils.modelToArray(root, roleNames)
keysAndPos.forEach((e, i) => e.index = i)
return keysAndPos.filter(p => p.showcaseVisibility
&& p.showcaseVisibility !== root.visibilityHidden)
}
function getVisibility(idx) {
return ModelUtils.get(root, idx, "showcaseVisibility")
|| root.visibilityHidden
}
}
}