Use modules.
This commit is contained in:
13
imports/Spectral/Component/AutoMouseArea.qml
Normal file
13
imports/Spectral/Component/AutoMouseArea.qml
Normal file
@@ -0,0 +1,13 @@
|
||||
import QtQuick 2.9
|
||||
|
||||
import Spectral.Setting 0.1
|
||||
|
||||
MouseArea {
|
||||
signal primaryClicked()
|
||||
signal secondaryClicked()
|
||||
|
||||
acceptedButtons: MSettings.pressAndHold ? Qt.LeftButton : (Qt.LeftButton | Qt.RightButton)
|
||||
|
||||
onClicked: mouse.button == Qt.RightButton ? secondaryClicked() : primaryClicked()
|
||||
onPressAndHold: MSettings.pressAndHold ? secondaryClicked() : {}
|
||||
}
|
||||
20
imports/Spectral/Component/Emoji/EmojiButton.qml
Normal file
20
imports/Spectral/Component/Emoji/EmojiButton.qml
Normal file
@@ -0,0 +1,20 @@
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.2
|
||||
|
||||
Text {
|
||||
property string category
|
||||
|
||||
width: 36
|
||||
height: 36
|
||||
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
font.pointSize: 20
|
||||
font.family: "Emoji"
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: emojiCategory = category
|
||||
}
|
||||
}
|
||||
71
imports/Spectral/Component/Emoji/EmojiPicker.qml
Normal file
71
imports/Spectral/Component/Emoji/EmojiPicker.qml
Normal file
@@ -0,0 +1,71 @@
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Controls.Material 2.2
|
||||
|
||||
import Spectral 0.1
|
||||
|
||||
Popup {
|
||||
property var textArea
|
||||
property string emojiCategory: "people"
|
||||
|
||||
EmojiModel {
|
||||
id: emojiModel
|
||||
category: emojiCategory
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
GridView {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
cellWidth: 36
|
||||
cellHeight: 36
|
||||
|
||||
boundsBehavior: Flickable.DragOverBounds
|
||||
|
||||
clip: true
|
||||
|
||||
model: emojiModel.model
|
||||
|
||||
delegate: Text {
|
||||
width: 36
|
||||
height: 36
|
||||
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
font.pointSize: 20
|
||||
font.family: "Emoji"
|
||||
text: modelData
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: textArea.insert(textArea.cursorPosition, modelData)
|
||||
}
|
||||
}
|
||||
|
||||
ScrollBar.vertical: ScrollBar {}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 2
|
||||
|
||||
color: Material.accent
|
||||
}
|
||||
|
||||
Row {
|
||||
EmojiButton { text: "😏"; category: "people" }
|
||||
EmojiButton { text: "🌲"; category: "nature" }
|
||||
EmojiButton { text: "🍛"; category: "food"}
|
||||
EmojiButton { text: "🚁"; category: "activity" }
|
||||
EmojiButton { text: "🚅"; category: "travel" }
|
||||
EmojiButton { text: "💡"; category: "objects" }
|
||||
EmojiButton { text: "🔣"; category: "symbols" }
|
||||
EmojiButton { text: "🏁"; category: "flags" }
|
||||
}
|
||||
}
|
||||
}
|
||||
2
imports/Spectral/Component/Emoji/qmldir
Normal file
2
imports/Spectral/Component/Emoji/qmldir
Normal file
@@ -0,0 +1,2 @@
|
||||
module Spectral.Component.Emoji
|
||||
EmojiPicker 2.0 EmojiPicker.qml
|
||||
18
imports/Spectral/Component/MaterialIcon.qml
Normal file
18
imports/Spectral/Component/MaterialIcon.qml
Normal file
@@ -0,0 +1,18 @@
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
import Spectral.Setting 0.1
|
||||
import Spectral.Font 0.1
|
||||
|
||||
Text {
|
||||
property alias icon: materialLabel.text
|
||||
|
||||
id: materialLabel
|
||||
|
||||
color: MSettings.darkTheme ? "white" : "dark"
|
||||
font.pointSize: 16
|
||||
font.family: MaterialFont.name
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
25
imports/Spectral/Component/SideNavButton.qml
Normal file
25
imports/Spectral/Component/SideNavButton.qml
Normal file
@@ -0,0 +1,25 @@
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Controls.Material 2.2
|
||||
|
||||
import "qrc:/js/util.js" as Util
|
||||
|
||||
ItemDelegate {
|
||||
property var page
|
||||
property bool selected: stackView.currentItem === page
|
||||
property color highlightColor: Material.accent
|
||||
|
||||
Rectangle {
|
||||
width: selected ? 4 : 0
|
||||
height: parent.height
|
||||
|
||||
color: highlightColor
|
||||
|
||||
Behavior on width {
|
||||
PropertyAnimation { easing.type: Easing.InOutCubic; duration: 200 }
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: Util.pushToStack(stackView, page)
|
||||
}
|
||||
34
imports/Spectral/Component/Timeline/AutoImage.qml
Normal file
34
imports/Spectral/Component/Timeline/AutoImage.qml
Normal file
@@ -0,0 +1,34 @@
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.2
|
||||
|
||||
Item {
|
||||
property alias source: baseImage.source
|
||||
property alias sourceSize: baseImage.sourceSize.width
|
||||
|
||||
readonly property bool loading: baseImage.status == Image.Loading
|
||||
|
||||
signal clicked()
|
||||
|
||||
width: loading ? 128 : baseImage.implicitWidth
|
||||
height: loading ? progressBar.height : baseImage.implicitHeight
|
||||
|
||||
id: rekt
|
||||
|
||||
Image { id: baseImage }
|
||||
|
||||
ProgressBar {
|
||||
width: parent.width
|
||||
visible: loading
|
||||
|
||||
id: progressBar
|
||||
|
||||
indeterminate: true
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
propagateComposedEvents: true
|
||||
|
||||
onClicked: rekt.clicked()
|
||||
}
|
||||
}
|
||||
17
imports/Spectral/Component/Timeline/AutoLabel.qml
Normal file
17
imports/Spectral/Component/Timeline/AutoLabel.qml
Normal file
@@ -0,0 +1,17 @@
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Controls.Material 2.2
|
||||
|
||||
import Spectral.Setting 0.1
|
||||
|
||||
Label {
|
||||
property bool coloredBackground
|
||||
|
||||
color: coloredBackground ? "white": Material.foreground
|
||||
|
||||
wrapMode: Label.Wrap
|
||||
linkColor: coloredBackground ? "white" : Material.accent
|
||||
textFormat: MSettings.richText ? Text.RichText : Text.StyledText
|
||||
|
||||
onLinkActivated: Qt.openUrlExternally(link)
|
||||
}
|
||||
38
imports/Spectral/Component/Timeline/DownloadableContent.qml
Normal file
38
imports/Spectral/Component/Timeline/DownloadableContent.qml
Normal file
@@ -0,0 +1,38 @@
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Controls.Material 2.2
|
||||
import Qt.labs.platform 1.0
|
||||
|
||||
Item {
|
||||
property bool openOnFinished: false
|
||||
readonly property bool downloaded: progressInfo && progressInfo.completed
|
||||
|
||||
Rectangle {
|
||||
z: -2
|
||||
height: parent.height
|
||||
width: progressInfo.active && !progressInfo.completed ? progressInfo.progress / progressInfo.total * parent.width : 0
|
||||
|
||||
color: Material.accent
|
||||
opacity: 0.4
|
||||
}
|
||||
|
||||
onDownloadedChanged: if (downloaded && openOnFinished) openSavedFile()
|
||||
|
||||
function saveFileAs() { currentRoom.saveFileAs(eventId) }
|
||||
|
||||
function downloadAndOpen()
|
||||
{
|
||||
if (downloaded) openSavedFile()
|
||||
else
|
||||
{
|
||||
openOnFinished = true
|
||||
currentRoom.downloadFile(eventId, StandardPaths.writableLocation(StandardPaths.CacheLocation) + "/" + eventId.replace(":", "_") + ".tmp")
|
||||
}
|
||||
}
|
||||
|
||||
function openSavedFile()
|
||||
{
|
||||
if (Qt.openUrlExternally(progressInfo.localPath)) return;
|
||||
if (Qt.openUrlExternally(progressInfo.localDir)) return;
|
||||
}
|
||||
}
|
||||
37
imports/Spectral/Component/Timeline/GenericBubble.qml
Normal file
37
imports/Spectral/Component/Timeline/GenericBubble.qml
Normal file
@@ -0,0 +1,37 @@
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Controls.Material 2.2
|
||||
|
||||
import Spectral.Component 2.0
|
||||
import Spectral.Effect 2.0
|
||||
|
||||
import Spectral.Setting 0.1
|
||||
|
||||
Control {
|
||||
property bool highlighted: false
|
||||
property bool colored: false
|
||||
|
||||
readonly property bool darkBackground: highlighted ? true : MSettings.darkTheme
|
||||
|
||||
padding: 12
|
||||
|
||||
AutoMouseArea {
|
||||
anchors.fill: parent
|
||||
|
||||
onSecondaryClicked: {
|
||||
messageContextMenu.row = messageRow
|
||||
messageContextMenu.model = model
|
||||
messageContextMenu.selectedText = contentLabel.selectedText
|
||||
messageContextMenu.popup()
|
||||
}
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
color: colored ? Material.accent : highlighted ? Material.primary : Material.background
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: ElevationEffect {
|
||||
elevation: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
234
imports/Spectral/Component/Timeline/MessageDelegate.qml
Normal file
234
imports/Spectral/Component/Timeline/MessageDelegate.qml
Normal file
@@ -0,0 +1,234 @@
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Controls.Material 2.2
|
||||
|
||||
import Spectral 0.1
|
||||
import Spectral.Setting 0.1
|
||||
|
||||
import "qrc:/js/util.js" as Util
|
||||
|
||||
RowLayout {
|
||||
readonly property bool avatarVisible: !sentByMe && (aboveAuthor !== author || aboveSection !== section || aboveEventType === "state" || aboveEventType === "emote" || aboveEventType === "other")
|
||||
readonly property bool highlighted: !(sentByMe || eventType === "notice" )
|
||||
readonly property bool sentByMe: author === currentRoom.localUser
|
||||
readonly property bool isText: eventType === "notice" || eventType === "message"
|
||||
|
||||
signal saveFileAs()
|
||||
signal openExternally()
|
||||
|
||||
z: -5
|
||||
|
||||
id: messageRow
|
||||
|
||||
Layout.alignment: sentByMe ? Qt.AlignRight : Qt.AlignLeft
|
||||
|
||||
spacing: 6
|
||||
|
||||
ImageItem {
|
||||
Layout.preferredWidth: 40
|
||||
Layout.preferredHeight: 40
|
||||
Layout.alignment: Qt.AlignTop
|
||||
|
||||
round: false
|
||||
visible: avatarVisible
|
||||
hint: author.displayName
|
||||
image: author.avatar
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.preferredWidth: 40
|
||||
Layout.preferredHeight: 40
|
||||
Layout.alignment: Qt.AlignTop
|
||||
|
||||
color: "transparent"
|
||||
visible: !(sentByMe || avatarVisible)
|
||||
}
|
||||
|
||||
GenericBubble {
|
||||
Layout.maximumWidth: messageListView.width - (!sentByMe ? 40 + messageRow.spacing : 0)
|
||||
|
||||
id: genericBubble
|
||||
|
||||
highlighted: messageRow.highlighted
|
||||
colored: highlighted && (eventType === "notice" || highlight)
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
id: messageColumn
|
||||
|
||||
spacing: 0
|
||||
|
||||
AutoLabel {
|
||||
visible: messageRow.avatarVisible
|
||||
text: author.displayName
|
||||
Material.foreground: Material.accent
|
||||
coloredBackground: highlighted
|
||||
font.bold: true
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: inputField.insert(inputField.cursorPosition, author.displayName)
|
||||
}
|
||||
}
|
||||
|
||||
TextEdit {
|
||||
Layout.fillWidth: true
|
||||
|
||||
id: contentLabel
|
||||
|
||||
text: (highlighted ? "<style>a{color: white;} .user-pill{color: white}</style>" : "<style>a{color: " + Material.accent + ";} .user-pill{color: " + Material.accent + "}</style>") + display
|
||||
|
||||
visible: isText
|
||||
color: highlighted ? "white": Material.foreground
|
||||
|
||||
font: Qt.font({pointSize: 10})
|
||||
selectByMouse: true
|
||||
readOnly: true
|
||||
wrapMode: Label.Wrap
|
||||
selectedTextColor: highlighted ? Material.accent : "white"
|
||||
selectionColor: highlighted ? "white" : Material.accent
|
||||
textFormat: Text.RichText
|
||||
|
||||
onLinkActivated: Qt.openUrlExternally(link)
|
||||
}
|
||||
|
||||
Loader {
|
||||
sourceComponent: {
|
||||
switch (eventType) {
|
||||
case "image":
|
||||
return imageComponent
|
||||
case "file":
|
||||
return fileComponent
|
||||
case "audio":
|
||||
return audioComponent
|
||||
}
|
||||
}
|
||||
|
||||
active: eventType === "image" || eventType === "file" || eventType === "audio"
|
||||
}
|
||||
|
||||
Row {
|
||||
Layout.alignment: Qt.AlignRight
|
||||
|
||||
spacing: 4
|
||||
|
||||
AutoLabel {
|
||||
visible: userMarker.length > 5
|
||||
text: userMarker.length - 5 + "+"
|
||||
coloredBackground: highlighted
|
||||
Material.foreground: "grey"
|
||||
font.pointSize: 8
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: userMarker.length > 5 ? userMarker.slice(0, 5) : userMarker
|
||||
|
||||
ImageItem {
|
||||
width: parent.height
|
||||
height: parent.height
|
||||
|
||||
hint: modelData.displayName
|
||||
image: modelData.avatar
|
||||
}
|
||||
}
|
||||
|
||||
AutoLabel {
|
||||
id: timeLabel
|
||||
|
||||
visible: Math.abs(time - aboveTime) > 600000 || index == 0
|
||||
text: Qt.formatTime(time, "hh:mm")
|
||||
coloredBackground: highlighted
|
||||
Material.foreground: "grey"
|
||||
font.pointSize: 8
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: imageComponent
|
||||
|
||||
DownloadableContent {
|
||||
width: messageImage.width
|
||||
height: messageImage.height
|
||||
|
||||
id: downloadable
|
||||
|
||||
AutoImage {
|
||||
z: -4
|
||||
|
||||
id: messageImage
|
||||
|
||||
sourceSize: 128
|
||||
source: "image://mxc/" + (content.thumbnail_url ? content.thumbnail_url : content.url)
|
||||
|
||||
onClicked: downloadAndOpen()
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
messageRow.saveFileAs.connect(saveFileAs)
|
||||
messageRow.openExternally.connect(downloadAndOpen)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: fileComponent
|
||||
|
||||
AutoLabel {
|
||||
Layout.fillWidth: true
|
||||
|
||||
id: downloadDelegate
|
||||
|
||||
text: "<b>File: </b>" + content.body
|
||||
coloredBackground: highlighted
|
||||
|
||||
background: DownloadableContent {
|
||||
id: downloadable
|
||||
|
||||
Component.onCompleted: {
|
||||
messageRow.saveFileAs.connect(saveFileAs)
|
||||
messageRow.openExternally.connect(downloadAndOpen)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: audioComponent
|
||||
|
||||
AutoLabel {
|
||||
id: downloadDelegate
|
||||
|
||||
text: content.info.duration / 1000 + '"'
|
||||
coloredBackground: highlighted
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
|
||||
propagateComposedEvents: true
|
||||
|
||||
onClicked: {
|
||||
if (downloadable.downloaded)
|
||||
spectralController.playAudio(progressInfo.localPath)
|
||||
else
|
||||
{
|
||||
playOnFinished = true
|
||||
currentRoom.downloadFile(eventId, StandardPaths.writableLocation(StandardPaths.CacheLocation) + "/" + eventId.replace(":", "_") + ".tmp")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
background: DownloadableContent {
|
||||
id: downloadable
|
||||
|
||||
onDownloadedChanged: downloaded && playOnFinished ? spectralController.playAudio(progressInfo.localPath) : {}
|
||||
|
||||
Component.onCompleted: {
|
||||
messageRow.saveFileAs.connect(saveFileAs)
|
||||
messageRow.openExternally.connect(downloadAndOpen)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
imports/Spectral/Component/Timeline/StateDelegate.qml
Normal file
24
imports/Spectral/Component/Timeline/StateDelegate.qml
Normal file
@@ -0,0 +1,24 @@
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Controls.Material 2.2
|
||||
|
||||
import Spectral.Setting 0.1
|
||||
|
||||
Label {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
text: "<b>" + author.displayName + "</b> " + display
|
||||
color: "white"
|
||||
|
||||
padding: 8
|
||||
|
||||
wrapMode: Label.Wrap
|
||||
linkColor: "white"
|
||||
textFormat: MSettings.richText ? Text.RichText : Text.StyledText
|
||||
onLinkActivated: Qt.openUrlExternally(link)
|
||||
|
||||
background: Rectangle {
|
||||
color: MSettings.darkTheme ? "#484848" : "grey"
|
||||
}
|
||||
}
|
||||
4
imports/Spectral/Component/Timeline/qmldir
Normal file
4
imports/Spectral/Component/Timeline/qmldir
Normal file
@@ -0,0 +1,4 @@
|
||||
module Spectral.Component.Timeline
|
||||
MessageDelegate 2.0 MessageDelegate.qml
|
||||
StateDelegate 2.0 StateDelegate.qml
|
||||
|
||||
4
imports/Spectral/Component/qmldir
Normal file
4
imports/Spectral/Component/qmldir
Normal file
@@ -0,0 +1,4 @@
|
||||
module Spectral.Component
|
||||
AutoMouseArea 2.0 AutoMouseArea.qml
|
||||
MaterialIcon 2.0 MaterialIcon.qml
|
||||
SideNavButton 2.0 SideNavButton.qml
|
||||
Reference in New Issue
Block a user