adds edits
This commit is contained in:
@@ -35,7 +35,9 @@ TextEdit {
|
||||
focus: false
|
||||
selectByMouse: true
|
||||
|
||||
onLinkActivated: if (enableLinkActivation && link !== '#state-text')
|
||||
onLinkActivated: if (enableLinkActivation
|
||||
&& link !== '#state-text'
|
||||
&& link !== '#replaced-text')
|
||||
Qt.openUrlExternally(link)
|
||||
|
||||
MouseArea {
|
||||
|
@@ -51,6 +51,16 @@ HRowLayout {
|
||||
|
||||
readonly property var reactions: model.reactions
|
||||
|
||||
readonly property var contentHistory: model.content_history
|
||||
readonly property string replacedText:
|
||||
`<a href="#replaced-text" style="text-decoration: none">` +
|
||||
`<font size=${theme.fontSize.small}px><font ` + (
|
||||
model.replaced ?
|
||||
`color="${theme.chat.message.readCounter}"> 🖉` : // U+1F589
|
||||
|
||||
">"
|
||||
) + "</font></font></a>"
|
||||
|
||||
readonly property bool pureMedia: ! contentText && linksRepeater.count
|
||||
|
||||
readonly property bool hoveredSelectable: contentHover.hovered
|
||||
@@ -125,6 +135,13 @@ HRowLayout {
|
||||
id: contentLabel
|
||||
visible: ! pureMedia
|
||||
enableLinkActivation: ! eventList.selectedCount
|
||||
onLinkActivated:
|
||||
if(link === "#replaced-text") window.makePopup(
|
||||
"Popups/MessageReplaceHistoryPopup.qml",
|
||||
{
|
||||
contentHistory: contentHistory
|
||||
},
|
||||
)
|
||||
|
||||
selectByMouse:
|
||||
eventList.selectedCount <= 1 &&
|
||||
@@ -165,6 +182,7 @@ HRowLayout {
|
||||
timeText +
|
||||
"</font>" +
|
||||
|
||||
replacedText +
|
||||
stateText
|
||||
|
||||
transform: Translate { x: xOffset }
|
||||
|
@@ -284,6 +284,8 @@ Rectangle {
|
||||
function focusNextVisibleMessage() {
|
||||
decrementCurrentIndex()
|
||||
while ( currentIndex > -1 && model.get(currentIndex).hidden ) {
|
||||
if ( currentIndex === 0 )
|
||||
currentIndex = -1;
|
||||
decrementCurrentIndex()
|
||||
}
|
||||
}
|
||||
|
275
src/gui/Pages/Chat/Timeline/HistoryContent.qml
Normal file
275
src/gui/Pages/Chat/Timeline/HistoryContent.qml
Normal file
@@ -0,0 +1,275 @@
|
||||
// Copyright Mirage authors & contributors <https://github.com/mirukana/mirage>
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import "../../../Base"
|
||||
import "../../.."
|
||||
|
||||
HRowLayout {
|
||||
id: historyContent
|
||||
|
||||
readonly property var mentions: []
|
||||
|
||||
readonly property string mentionsCSS: {
|
||||
const lines = []
|
||||
|
||||
for (const [name, link] of mentions) {
|
||||
if (! link.match(/^https?:\/\/matrix.to\/#\/@.+/)) continue
|
||||
|
||||
lines.push(
|
||||
`.mention[data-mention='${utils.escapeHtml(name)}'] ` +
|
||||
`{ color: ${utils.nameColor(name)} }`
|
||||
)
|
||||
}
|
||||
|
||||
return "<style type='text/css'>" + lines.join("\n") + "</style>"
|
||||
}
|
||||
readonly property string diffCSS: {
|
||||
const lines = [
|
||||
"del { background-color: #f8d7da; color: #721c24; text-decoration: line-through; }",
|
||||
"ins { background-color: #d4edda; color: #155724; text-decoration: underline; }",
|
||||
]
|
||||
return "<style type='text/css'>" + lines.join("\n") + "</style>"
|
||||
}
|
||||
|
||||
|
||||
readonly property string senderText: ""
|
||||
property string contentText: model.content_diff
|
||||
readonly property string timeText: utils.formatTime(model.date, false)
|
||||
|
||||
readonly property bool pureMedia: false
|
||||
|
||||
readonly property bool hoveredSelectable: contentHover.hovered
|
||||
readonly property string hoveredLink:
|
||||
linksRepeater.lastHovered && linksRepeater.lastHovered.hovered ?
|
||||
linksRepeater.lastHovered.mediaUrl :
|
||||
contentLabel.hoveredLink
|
||||
|
||||
readonly property alias contentLabel: contentLabel
|
||||
|
||||
readonly property int xOffset:
|
||||
onRight ?
|
||||
Math.min(
|
||||
contentColumn.width - contentLabel.paintedWidth -
|
||||
contentLabel.leftPadding - contentLabel.rightPadding,
|
||||
|
||||
contentColumn.width - linksRepeater.widestChild -
|
||||
(
|
||||
pureMedia ?
|
||||
0 : contentLabel.leftPadding + contentLabel.rightPadding
|
||||
),
|
||||
) :
|
||||
0
|
||||
|
||||
readonly property int maxMessageWidth:
|
||||
contentText.includes("<pre>") || contentText.includes("<table>") ?
|
||||
-1 :
|
||||
window.settings.Chat.max_messages_line_length < 0 ?
|
||||
-1 :
|
||||
Math.ceil(
|
||||
mainUI.fontMetrics.averageCharacterWidth *
|
||||
window.settings.Chat.max_messages_line_length
|
||||
)
|
||||
|
||||
readonly property alias selectedText: contentLabel.selectedPlainText
|
||||
|
||||
spacing: theme.chat.message.horizontalSpacing
|
||||
layoutDirection: onRight ? Qt.RightToLeft: Qt.LeftToRight
|
||||
|
||||
HColumnLayout {
|
||||
id: contentColumn
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
HSelectableLabel {
|
||||
id: contentLabel
|
||||
visible: ! pureMedia
|
||||
enableLinkActivation: ! historyList.selectedCount
|
||||
|
||||
selectByMouse:
|
||||
historyList.selectedCount <= 1 &&
|
||||
historyDelegate.checked &&
|
||||
textSelectionBlocker.point.scenePosition === Qt.point(0, 0)
|
||||
|
||||
topPadding: theme.chat.message.verticalSpacing
|
||||
bottomPadding: topPadding
|
||||
leftPadding: historyContent.spacing
|
||||
rightPadding: leftPadding
|
||||
|
||||
color: theme.chat.message.body
|
||||
|
||||
font.italic: false
|
||||
wrapMode: TextEdit.Wrap
|
||||
textFormat: Text.RichText
|
||||
text:
|
||||
// CSS
|
||||
theme.chat.message.styleInclude + mentionsCSS + diffCSS +
|
||||
|
||||
// Sender name & message body
|
||||
(
|
||||
compact && contentText.match(/^\s*<(p|h[1-6])>/) ?
|
||||
contentText.replace(
|
||||
/(^\s*<(p|h[1-6])>)/, "$1" + senderText,
|
||||
) :
|
||||
senderText + contentText
|
||||
) +
|
||||
|
||||
// Time
|
||||
// For some reason, if there's only one space,
|
||||
// times will be on their own lines most of the time.
|
||||
" " +
|
||||
`<font size=${theme.fontSize.small}px ` +
|
||||
`color=${theme.chat.message.date}>` +
|
||||
timeText +
|
||||
"</font>"
|
||||
|
||||
transform: Translate { x: xOffset }
|
||||
|
||||
Layout.maximumWidth: historyContent.maxMessageWidth
|
||||
Layout.fillWidth: true
|
||||
|
||||
onSelectedTextChanged: if (selectedPlainText) {
|
||||
historyList.delegateWithSelectedText = model.id
|
||||
historyList.selectedText = selectedPlainText
|
||||
} else if (historyList.delegateWithSelectedText === model.id) {
|
||||
historyList.delegateWithSelectedText = ""
|
||||
historyList.selectedText = ""
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: historyList
|
||||
onCheckedChanged: contentLabel.deselect()
|
||||
onDelegateWithSelectedTextChanged: {
|
||||
if (historyList.delegateWithSelectedText !== model.id)
|
||||
contentLabel.deselect()
|
||||
}
|
||||
}
|
||||
|
||||
HoverHandler { id: contentHover }
|
||||
|
||||
PointHandler {
|
||||
id: mousePointHandler
|
||||
|
||||
property bool checkedNow: false
|
||||
|
||||
acceptedButtons: Qt.LeftButton
|
||||
acceptedModifiers: Qt.NoModifier
|
||||
acceptedPointerTypes:
|
||||
PointerDevice.GenericPointer | PointerDevice.Eraser
|
||||
|
||||
onActiveChanged: {
|
||||
if (active &&
|
||||
! historyDelegate.checked &&
|
||||
(! parent.hoveredLink ||
|
||||
! parent.enableLinkActivation)) {
|
||||
|
||||
historyList.check(model.index)
|
||||
checkedNow = true
|
||||
}
|
||||
|
||||
if (! active && historyDelegate.checked) {
|
||||
checkedNow ?
|
||||
checkedNow = false :
|
||||
historyList.uncheck(model.index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PointHandler {
|
||||
id: mouseShiftPointHandler
|
||||
acceptedButtons: Qt.LeftButton
|
||||
acceptedModifiers: Qt.ShiftModifier
|
||||
acceptedPointerTypes:
|
||||
PointerDevice.GenericPointer | PointerDevice.Eraser
|
||||
|
||||
onActiveChanged: {
|
||||
if (active &&
|
||||
! historyDelegate.checked &&
|
||||
(! parent.hoveredLink ||
|
||||
! parent.enableLinkActivation)) {
|
||||
|
||||
historyList.checkFromLastToHere(model.index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
id: touchTapHandler
|
||||
acceptedButtons: Qt.LeftButton
|
||||
acceptedPointerTypes: PointerDevice.Finger | PointerDevice.Pen
|
||||
onTapped:
|
||||
if (! parent.hoveredLink || ! parent.enableLinkActivation)
|
||||
historyDelegate.toggleChecked()
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
id: textSelectionBlocker
|
||||
acceptedPointerTypes: PointerDevice.Finger | PointerDevice.Pen
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: contentBackground
|
||||
width: Math.max(
|
||||
parent.paintedWidth +
|
||||
parent.leftPadding + parent.rightPadding,
|
||||
|
||||
linksRepeater.summedWidth +
|
||||
(pureMedia ? 0 : parent.leftPadding + parent.rightPadding),
|
||||
)
|
||||
height: contentColumn.height
|
||||
radius: theme.chat.message.radius
|
||||
z: -100
|
||||
color: historyDelegate.checked &&
|
||||
! contentLabel.selectedPlainText &&
|
||||
! mousePointHandler.active &&
|
||||
! mouseShiftPointHandler.active ?
|
||||
theme.chat.message.checkedBackground :
|
||||
|
||||
isOwn?
|
||||
theme.chat.message.ownBackground :
|
||||
|
||||
theme.chat.message.background
|
||||
}
|
||||
}
|
||||
|
||||
HRepeater {
|
||||
id: linksRepeater
|
||||
|
||||
property EventMediaLoader lastHovered: null
|
||||
|
||||
model: {
|
||||
const links = historyDelegate.currentModel.links
|
||||
|
||||
if (historyDelegate.currentModel.media_url)
|
||||
links.push(historyDelegate.currentModel.media_url)
|
||||
|
||||
return links
|
||||
}
|
||||
|
||||
EventMediaLoader {
|
||||
singleMediaInfo: historyDelegate.currentModel
|
||||
mediaUrl: modelData
|
||||
showSender: pureMedia ? senderText : ""
|
||||
showDate: pureMedia ? timeText : ""
|
||||
showLocalEcho: pureMedia && (
|
||||
singleMediaInfo.is_local_echo ||
|
||||
singleMediaInfo.read_by_count
|
||||
) ? stateText : ""
|
||||
|
||||
transform: Translate { x: xOffset }
|
||||
|
||||
onHoveredChanged: if (hovered) linksRepeater.lastHovered = this
|
||||
|
||||
Layout.bottomMargin: pureMedia ? 0 : contentLabel.bottomPadding
|
||||
Layout.leftMargin: pureMedia ? 0 : historyContent.spacing
|
||||
Layout.rightMargin: pureMedia ? 0 : historyContent.spacing
|
||||
Layout.preferredWidth: item ? item.width : -1
|
||||
Layout.preferredHeight: item ? item.height : -1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HSpacer {}
|
||||
}
|
93
src/gui/Pages/Chat/Timeline/HistoryDelegate.qml
Normal file
93
src/gui/Pages/Chat/Timeline/HistoryDelegate.qml
Normal file
@@ -0,0 +1,93 @@
|
||||
// Copyright Mirage authors & contributors <https://github.com/mirukana/mirage>
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import Clipboard 0.1
|
||||
import "../../.."
|
||||
import "../../../Base"
|
||||
|
||||
HColumnLayout {
|
||||
id: historyDelegate
|
||||
|
||||
// Remember timeline goes from newest message at index 0 to oldest
|
||||
readonly property var previousModel: historyList.model.get(model.index + 1)
|
||||
readonly property var nextModel: historyList.model.get(model.index - 1)
|
||||
readonly property QtObject currentModel: model
|
||||
|
||||
readonly property bool isFocused: model.index === historyList.currentIndex
|
||||
|
||||
readonly property bool compact: window.settings.General.compact
|
||||
readonly property bool checked: model.id in historyList.checked
|
||||
readonly property bool isOwn: true
|
||||
readonly property bool isRedacted: false
|
||||
readonly property bool onRight: ! historyList.ownEventsOnLeft && isOwn
|
||||
readonly property bool combine: false
|
||||
readonly property bool talkBreak: false
|
||||
readonly property bool dayBreak:
|
||||
model.index === 0 ? true : historyList.canDayBreak(previousModel, model)
|
||||
|
||||
readonly property bool hideNameLine: true
|
||||
|
||||
readonly property int cursorShape:
|
||||
historyContent.hoveredLink ? Qt.PointingHandCursor :
|
||||
historyContent.hoveredSelectable ? Qt.IBeamCursor :
|
||||
Qt.ArrowCursor
|
||||
|
||||
readonly property int separationSpacing: theme.spacing * (
|
||||
dayBreak ? 4 :
|
||||
talkBreak ? 6 :
|
||||
combine && compact ? 0.25 :
|
||||
combine ? 0.5 :
|
||||
compact ? 1 :
|
||||
2
|
||||
)
|
||||
|
||||
readonly property alias historyContent: historyContent
|
||||
|
||||
function toggleChecked() {
|
||||
historyList.toggleCheck(model.index)
|
||||
}
|
||||
|
||||
width: historyList.width - historyList.leftMargin - historyList.rightMargin
|
||||
|
||||
// Needed because of historyList's MouseArea which steals the
|
||||
// HSelectableLabel's MouseArea hover events
|
||||
onCursorShapeChanged: historyList.cursorShape = cursorShape
|
||||
|
||||
ListView.onRemove: historyList.uncheck(model.id)
|
||||
|
||||
DelegateTransitionFixer {}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
visible: model.index !== 0
|
||||
Layout.preferredHeight: separationSpacing
|
||||
}
|
||||
|
||||
DayBreak {
|
||||
visible: dayBreak
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumWidth: parent.width
|
||||
Layout.bottomMargin: separationSpacing
|
||||
}
|
||||
|
||||
HistoryContent {
|
||||
id: historyContent
|
||||
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.LeftButton
|
||||
acceptedModifiers: Qt.NoModifier
|
||||
onTapped: toggleChecked()
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.LeftButton
|
||||
acceptedModifiers: Qt.ShiftModifier
|
||||
onTapped: historyList.checkFromLastToHere(model.index)
|
||||
}
|
||||
}
|
206
src/gui/Pages/Chat/Timeline/HistoryList.qml
Normal file
206
src/gui/Pages/Chat/Timeline/HistoryList.qml
Normal file
@@ -0,0 +1,206 @@
|
||||
// Copyright Mirage authors & contributors <https://github.com/mirukana/mirage>
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import QtQuick.Window 2.12
|
||||
import Clipboard 0.1
|
||||
import "../../.."
|
||||
import "../../../Base"
|
||||
import "../../../PythonBridge"
|
||||
import "../../../ShortcutBundles"
|
||||
|
||||
Rectangle {
|
||||
|
||||
readonly property alias historyList: historyList
|
||||
|
||||
color: theme.chat.eventList.background
|
||||
|
||||
HShortcut {
|
||||
sequences: window.settings.Keys.Messages.unfocus_or_deselect
|
||||
onActivated: {
|
||||
historyList.selectedCount ?
|
||||
historyList.checked = {} :
|
||||
historyList.currentIndex = -1
|
||||
}
|
||||
}
|
||||
|
||||
HShortcut {
|
||||
sequences: window.settings.Keys.Messages.previous
|
||||
onActivated: historyList.focusPreviousMessage()
|
||||
}
|
||||
|
||||
HShortcut {
|
||||
sequences: window.settings.Keys.Messages.next
|
||||
onActivated: historyList.focusNextMessage()
|
||||
}
|
||||
|
||||
HShortcut {
|
||||
active: historyList.currentItem
|
||||
sequences: window.settings.Keys.Messages.select
|
||||
onActivated: historyList.toggleCheck(historyList.currentIndex)
|
||||
}
|
||||
|
||||
HShortcut {
|
||||
active: historyList.currentItem
|
||||
sequences: window.settings.Keys.Messages.select_until_here
|
||||
onActivated:
|
||||
historyList.checkFromLastToHere(historyList.currentIndex)
|
||||
}
|
||||
|
||||
HShortcut {
|
||||
sequences: window.settings.Keys.Messages.open_links_files
|
||||
onActivated: {
|
||||
const indice =
|
||||
historyList.getFocusedOrSelectedOrLastMediaEvents(true)
|
||||
|
||||
for (const i of Array.from(indice).sort().reverse()) {
|
||||
const event = historyList.model.get(i)
|
||||
|
||||
for (const url of JSON.parse(event.links)) {
|
||||
utils.getLinkType(url) === Utils.Media.Image ?
|
||||
historyList.openImageViewer(event, url) :
|
||||
Qt.openUrlExternally(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HShortcut {
|
||||
sequences: window.settings.Keys.Messages.open_links_files_externally
|
||||
onActivated: {
|
||||
const indice =
|
||||
historyList.getFocusedOrSelectedOrLastMediaEvents(true)
|
||||
|
||||
for (const i of Array.from(indice).sort().reverse()) {
|
||||
const event = historyList.model.get(i)
|
||||
|
||||
for (const url of JSON.parse(event.links))
|
||||
Qt.openUrlExternally(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HListView {
|
||||
id: historyList
|
||||
|
||||
property bool ownEventsOnLeft: false
|
||||
|
||||
property string delegateWithSelectedText: ""
|
||||
property string selectedText: ""
|
||||
|
||||
property bool showFocusedSeenTooltips: false
|
||||
|
||||
property alias cursorShape: cursorShapeArea.cursorShape
|
||||
|
||||
function focusCenterMessage() {
|
||||
const previous = highlightRangeMode
|
||||
highlightRangeMode = HListView.NoHighlightRange
|
||||
currentIndex = indexAt(0, contentY + height / 2)
|
||||
highlightRangeMode = previous
|
||||
}
|
||||
|
||||
function focusPreviousMessage() {
|
||||
currentIndex === -1 && visibleEnd.y < contentHeight - height / 4 ?
|
||||
focusCenterMessage() :
|
||||
incrementCurrentIndex()
|
||||
}
|
||||
|
||||
function focusNextMessage() {
|
||||
currentIndex === -1 && visibleEnd.y < contentHeight - height / 4 ?
|
||||
focusCenterMessage() :
|
||||
|
||||
historyList.currentIndex === 0 ?
|
||||
historyList.currentIndex = -1 :
|
||||
|
||||
decrementCurrentIndex()
|
||||
}
|
||||
|
||||
function copySelectedDelegates() {
|
||||
if (historyList.selectedText) {
|
||||
Clipboard.text = historyList.selectedText
|
||||
return
|
||||
}
|
||||
|
||||
if (! historyList.selectedCount && historyList.currentIndex !== -1) {
|
||||
const model = historyList.model.get(historyList.currentIndex)
|
||||
const source = JSON.parse(model.source)
|
||||
|
||||
Clipboard.text =
|
||||
model.media_http_url &&
|
||||
utils.isEmptyObject(JSON.parse(model.media_crypt_dict)) ?
|
||||
model.media_http_url :
|
||||
|
||||
"body" in source ?
|
||||
source.body :
|
||||
|
||||
utils.stripHtmlTags(utils.processedEventText(model))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
const contents = []
|
||||
|
||||
for (const model of historyList.getSortedChecked()) {
|
||||
const source = JSON.parse(model.source)
|
||||
|
||||
contents.push(
|
||||
model.media_http_url &&
|
||||
utils.isEmptyObject(JSON.parse(model.media_crypt_dict)) ?
|
||||
model.media_http_url :
|
||||
|
||||
"body" in source ?
|
||||
source.body :
|
||||
|
||||
utils.stripHtmlTags(utils.processedEventText(model))
|
||||
)
|
||||
}
|
||||
|
||||
Clipboard.text = contents.join("\n\n")
|
||||
}
|
||||
|
||||
function canDayBreak(item, itemAfter) {
|
||||
if (! item || ! itemAfter || ! item.date || ! itemAfter.date)
|
||||
return false
|
||||
|
||||
return item.date.getDate() !== itemAfter.date.getDate()
|
||||
}
|
||||
|
||||
function getFocusedOrSelectedOrLastMediaEvents(acceptLinks=false) {
|
||||
if (historyList.selectedCount) return historyList.checkedIndice
|
||||
if (historyList.currentIndex !== -1) return [historyList.currentIndex]
|
||||
|
||||
// Find most recent event that's a media or contains links
|
||||
for (let i = 0; i < historyList.model.count && i <= 1000; i++) {
|
||||
const ev = historyList.model.get(i)
|
||||
const links = JSON.parse(ev.links)
|
||||
|
||||
if (ev.media_url || (acceptLinks && links.length)) return [i]
|
||||
}
|
||||
}
|
||||
|
||||
anchors.fill: parent
|
||||
clip: true
|
||||
keyNavigationWraps: false
|
||||
leftMargin: theme.spacing
|
||||
rightMargin: theme.spacing
|
||||
topMargin: theme.spacing
|
||||
bottomMargin: theme.spacing
|
||||
|
||||
// model: ModelStore.get(chat.userRoomId[0], chat.userRoomId[1], "events")
|
||||
model: []
|
||||
delegate: HistoryDelegate {}
|
||||
|
||||
highlight: Rectangle {
|
||||
color: theme.chat.message.focusedHighlight
|
||||
opacity: theme.chat.message.focusedHighlightOpacity
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: cursorShapeArea
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton
|
||||
}
|
||||
|
||||
}
|
||||
}
|
44
src/gui/Popups/MessageReplaceHistoryPopup.qml
Normal file
44
src/gui/Popups/MessageReplaceHistoryPopup.qml
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright Mirage authors & contributors <https://github.com/mirukana/mirage>
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import "../Base"
|
||||
import "../Base/Buttons"
|
||||
import "../Pages/Chat/Timeline"
|
||||
|
||||
HColumnPopup {
|
||||
id: popup
|
||||
|
||||
contentWidthLimit:
|
||||
window.settings.Chat.max_messages_line_length < 0 ?
|
||||
theme.controls.popup.defaultWidth * 2 :
|
||||
Math.ceil(
|
||||
mainUI.fontMetrics.averageCharacterWidth *
|
||||
window.settings.Chat.max_messages_line_length
|
||||
)
|
||||
property var contentHistory
|
||||
|
||||
page.footer: AutoDirectionLayout {
|
||||
CancelButton {
|
||||
id: cancelButton
|
||||
onClicked: popup.close()
|
||||
}
|
||||
}
|
||||
|
||||
onOpened: cancelButton.forceActiveFocus()
|
||||
|
||||
SummaryLabel {
|
||||
text: qsTr("Message History")
|
||||
textFormat: Text.StyledText
|
||||
}
|
||||
|
||||
HistoryList {
|
||||
id: historyList
|
||||
historyList.model: contentHistory
|
||||
height: 400
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user