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

122 lines
4.3 KiB
QML
Raw Normal View History

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
}
}
}