mirror of
https://github.com/status-im/status-desktop.git
synced 2025-01-10 06:16:32 +00:00
fcd9567677
This commit adds the link preview settings card in the chat input area and connects the settings to the controller. Not included in this commit: Backend for the preserving the settings, syncing the settings and enforcing the settings on the backend side. Whenever an url is detected in the chat input area, the link preview settings card is presented. This card enables the user to choose one of the following options: 1. `Show for this message` - All the link previews in the current message will be loaded without asking again. The current message can be defined as the message currently typed/pasted in the chat input. Deleting or sending the current content is resetting this setting and the link preview settings card will be presented again when a new url is detected. 2. `Always show previews` - All the link previews will be loaded automatically. The link preview settings card will not be presented again (in the current state, this settings is enabled for the lifetime of the controller. This will change once the settings are preserved and synced) 3. `Never show previews` - No link preview will be loaded. Same as the `Always show previews` option, this will be preserved for the lifetime of the controller for now. 4. Dismiss (x button) - The link preview settings card will be dismissed. It will be loaded again when a new link preview is detected The same options can be loaded as a context menu on the link preview card. Changes: 1. Adding `LinkPreviewSettingsCard` 2. Adding the settings context menu to `LinkPreviewSettingsCard` and `LinkPreviewMiniCard` 3. Connect settings events to the nim controller 4. Adding the controller logic for settings change 5. Adding the link preview dismiss settings flag to the preserverd properties and use it as a condition to load the settings. 6. Adding/Updating corresponding storybook pages
157 lines
4.6 KiB
QML
157 lines
4.6 KiB
QML
import QtQuick 2.15
|
|
|
|
/*
|
|
Custom stack-based undo/redo implementation for TextEdit that works with formatted text.
|
|
|
|
Usage:
|
|
TextEdit {
|
|
id: textEdit
|
|
text: "Hello world"
|
|
onCustomEvent: undoStack.clear()
|
|
}
|
|
|
|
UndoRedoStack {
|
|
id: undoStack
|
|
textEdit: textEdit
|
|
enabled: true
|
|
maxStackSize: 100
|
|
}
|
|
*/
|
|
|
|
Item {
|
|
id: root
|
|
|
|
/*
|
|
The TextEdit to apply undo/redo to. The stack manager will be installed automatically on this textEdit
|
|
*/
|
|
required property TextEdit textEdit
|
|
/*
|
|
The maximum stack size
|
|
Once the maximum stack size is reached, the stack will be reduced to half its size by removing every second item
|
|
As a result the undo/redo will be less precise, jumping back/forward by 2 steps instead of 1
|
|
The first item in the stack will always be kept
|
|
*/
|
|
property int maxStackSize: 100
|
|
/*
|
|
Function used to clear the stack
|
|
This function will be called automatically when the TextEdit component changes or when the enabled property changes
|
|
*/
|
|
function clear() {
|
|
d.undoStack = []
|
|
d.redoStack = []
|
|
d.previousFormattedText = ""
|
|
d.previousText = ""
|
|
}
|
|
|
|
/*
|
|
Undo the last action
|
|
count: The number of actions to redo
|
|
*/
|
|
function undo(count = 1) {
|
|
if(d.undoStack.length == 0 || count <= 0) {
|
|
return
|
|
}
|
|
|
|
for (var i = 0; i < count; i++) {
|
|
if(d.undoStack.length == 0) {
|
|
return
|
|
}
|
|
|
|
const lastAction = d.undoStack.pop()
|
|
d.redoStack.push(lastAction)
|
|
lastAction.undo()
|
|
}
|
|
}
|
|
|
|
/*
|
|
Redo the last action
|
|
count: The number of actions to redo
|
|
*/
|
|
function redo(count = 1) {
|
|
if(d.redoStack.length == 0 || count <= 0) {
|
|
return
|
|
}
|
|
|
|
for (var i = 0; i < count; i++) {
|
|
if(d.redoStack.length == 0) {
|
|
return
|
|
}
|
|
const lastAction = d.redoStack.pop()
|
|
d.undoStack.push(lastAction)
|
|
lastAction.redo()
|
|
}
|
|
}
|
|
|
|
onTextEditChanged: {
|
|
clear()
|
|
textEdit.Keys.forwardTo.push(root)
|
|
}
|
|
onEnabledChanged: clear()
|
|
|
|
Keys.enabled: root.enabled
|
|
Keys.onPressed: {
|
|
if(event.matches(StandardKey.Undo)) {
|
|
undo(event.isAutoRepeat ? 2 : 1)
|
|
event.accepted = true
|
|
return
|
|
}
|
|
|
|
if(event.matches(StandardKey.Redo)) {
|
|
redo(event.isAutoRepeat ? 2 : 1)
|
|
event.accepted = true
|
|
return
|
|
}
|
|
}
|
|
|
|
readonly property QtObject d: QtObject {
|
|
property var undoStack: []
|
|
property var redoStack: []
|
|
property string previousFormattedText: ""
|
|
property string previousText: ""
|
|
|
|
property bool aboutToChangeText: false
|
|
|
|
function reduceUndoStack() {
|
|
if(d.undoStack.length <= root.maxStackSize) {
|
|
return
|
|
}
|
|
|
|
const newStackSize = Math.ceil(root.maxStackSize / 2)
|
|
for(var i = 1; i <= newStackSize; i++) {
|
|
d.undoStack.splice(i, Math.ceil(root.maxStackSize / newStackSize))
|
|
}
|
|
}
|
|
|
|
readonly property Connections textChangedConnection: Connections {
|
|
target: root.textEdit
|
|
enabled: root.enabled && !d.aboutToChangeText
|
|
function onTextChanged() {
|
|
const unformattedText = root.textEdit.getText(0, root.textEdit.length)
|
|
if(d.previousText !== unformattedText) {
|
|
const newFormattedText = root.textEdit.text
|
|
const previousFormattedTextCopy = d.previousFormattedText
|
|
d.undoStack.push({
|
|
undo: function() {
|
|
d.aboutToChangeText = true
|
|
root.textEdit.text = previousFormattedTextCopy
|
|
root.textEdit.cursorPosition = root.textEdit.length
|
|
d.aboutToChangeText = false
|
|
},
|
|
redo: function() {
|
|
d.aboutToChangeText = true
|
|
root.textEdit.text = newFormattedText
|
|
root.textEdit.cursorPosition = root.textEdit.length
|
|
d.aboutToChangeText = false
|
|
}
|
|
})
|
|
|
|
d.reduceUndoStack()
|
|
|
|
d.previousText = unformattedText
|
|
d.previousFormattedText = newFormattedText
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|