Use modules.

This commit is contained in:
Black Hat
2018-10-01 16:07:48 +08:00
parent 0654a8b2b6
commit 385135a658
41 changed files with 158 additions and 89 deletions

View 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() : {}
}

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

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

View File

@@ -0,0 +1,2 @@
module Spectral.Component.Emoji
EmojiPicker 2.0 EmojiPicker.qml

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

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

View 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()
}
}

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

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

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

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

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

View File

@@ -0,0 +1,4 @@
module Spectral.Component.Timeline
MessageDelegate 2.0 MessageDelegate.qml
StateDelegate 2.0 StateDelegate.qml

View File

@@ -0,0 +1,4 @@
module Spectral.Component
AutoMouseArea 2.0 AutoMouseArea.qml
MaterialIcon 2.0 MaterialIcon.qml
SideNavButton 2.0 SideNavButton.qml