Compare commits
8 Commits
117bfb4790
...
dfdad76d97
Author | SHA1 | Date |
---|---|---|
expectocode | dfdad76d97 | |
Black Hat | 6bf7e7e0c9 | |
Black Hat | 603cb33042 | |
Black Hat | ae5154fd35 | |
Black Hat | 5fd5d0d9ea | |
Black Hat | b4281896ba | |
Black Hat | 75c5c71855 | |
Black Hat | b7d8f70a5f |
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/spectral.iml" filepath="$PROJECT_DIR$/.idea/spectral.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="CPP_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
<mapping directory="$PROJECT_DIR$/include/SortFilterProxyModel" vcs="Git" />
|
||||||
|
<mapping directory="$PROJECT_DIR$/include/libqmatrixclient" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1,153 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CMakeRunConfigurationManager" shouldGenerate="true" shouldDeleteObsolete="true">
|
||||||
|
<generated />
|
||||||
|
</component>
|
||||||
|
<component name="CMakeSettings">
|
||||||
|
<configurations>
|
||||||
|
<configuration PROFILE_NAME="Debug" CONFIG_NAME="Debug" />
|
||||||
|
</configurations>
|
||||||
|
</component>
|
||||||
|
<component name="ChangeListManager">
|
||||||
|
<list default="true" id="1dc08437-54b4-4b19-9a54-6472ca11c95f" name="Default Changelist" comment="">
|
||||||
|
<change beforePath="$PROJECT_DIR$/include/libqmatrixclient" beforeDir="false" afterPath="$PROJECT_DIR$/include/libqmatrixclient" afterDir="false" />
|
||||||
|
</list>
|
||||||
|
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
|
||||||
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||||
|
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||||
|
</component>
|
||||||
|
<component name="ClangdSettings">
|
||||||
|
<option name="formatViaClangd" value="false" />
|
||||||
|
</component>
|
||||||
|
<component name="FileEditorManager">
|
||||||
|
<leaf>
|
||||||
|
<file pinned="false" current-in-tab="true">
|
||||||
|
<entry file="file://$PROJECT_DIR$/src/spectraluser.cpp">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="75">
|
||||||
|
<caret line="5" lean-forward="true" selection-start-line="5" selection-end-line="5" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
</leaf>
|
||||||
|
</component>
|
||||||
|
<component name="Git.Settings">
|
||||||
|
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||||
|
</component>
|
||||||
|
<component name="IdeDocumentHistory">
|
||||||
|
<option name="CHANGED_PATHS">
|
||||||
|
<list>
|
||||||
|
<option value="$PROJECT_DIR$/src/spectraluser.cpp" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="MacroExpansionManager">
|
||||||
|
<option name="directoryName" value="KjZzvpQi" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectConfigurationFiles">
|
||||||
|
<option name="files">
|
||||||
|
<list>
|
||||||
|
<option value="$PROJECT_DIR$/.idea/spectral.iml" />
|
||||||
|
<option value="$PROJECT_DIR$/.idea/vcs.xml" />
|
||||||
|
<option value="$PROJECT_DIR$/.idea/modules.xml" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectFrameBounds">
|
||||||
|
<option name="x" value="1928" />
|
||||||
|
<option name="y" value="8" />
|
||||||
|
<option name="width" value="539" />
|
||||||
|
<option name="height" value="687" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
|
||||||
|
<component name="ProjectView">
|
||||||
|
<navigator proportions="" version="1">
|
||||||
|
<foldersAlwaysOnTop value="true" />
|
||||||
|
</navigator>
|
||||||
|
<panes>
|
||||||
|
<pane id="ProjectPane">
|
||||||
|
<subPane>
|
||||||
|
<expand>
|
||||||
|
<path>
|
||||||
|
<item name="spectral" type="b2602c69:ProjectViewProjectNode" />
|
||||||
|
<item name="spectral" type="462c0819:PsiDirectoryNode" />
|
||||||
|
</path>
|
||||||
|
<path>
|
||||||
|
<item name="spectral" type="b2602c69:ProjectViewProjectNode" />
|
||||||
|
<item name="spectral" type="462c0819:PsiDirectoryNode" />
|
||||||
|
<item name="src" type="462c0819:PsiDirectoryNode" />
|
||||||
|
</path>
|
||||||
|
</expand>
|
||||||
|
<select />
|
||||||
|
</subPane>
|
||||||
|
</pane>
|
||||||
|
<pane id="Scope" />
|
||||||
|
</panes>
|
||||||
|
</component>
|
||||||
|
<component name="PropertiesComponent">
|
||||||
|
<property name="WebServerToolWindowFactoryState" value="false" />
|
||||||
|
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
|
||||||
|
</component>
|
||||||
|
<component name="RunDashboard">
|
||||||
|
<option name="ruleStates">
|
||||||
|
<list>
|
||||||
|
<RuleState>
|
||||||
|
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
|
||||||
|
</RuleState>
|
||||||
|
<RuleState>
|
||||||
|
<option name="name" value="StatusDashboardGroupingRule" />
|
||||||
|
</RuleState>
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="TaskManager">
|
||||||
|
<task active="true" id="Default" summary="Default task">
|
||||||
|
<changelist id="1dc08437-54b4-4b19-9a54-6472ca11c95f" name="Default Changelist" comment="" />
|
||||||
|
<created>1558287890866</created>
|
||||||
|
<option name="number" value="Default" />
|
||||||
|
<option name="presentableId" value="Default" />
|
||||||
|
<updated>1558287890866</updated>
|
||||||
|
<workItem from="1558287893419" duration="176000" />
|
||||||
|
</task>
|
||||||
|
<servers />
|
||||||
|
</component>
|
||||||
|
<component name="TimeTrackingManager">
|
||||||
|
<option name="totallyTimeSpent" value="176000" />
|
||||||
|
</component>
|
||||||
|
<component name="ToolWindowManager">
|
||||||
|
<frame x="1928" y="8" width="539" height="687" extended-state="0" />
|
||||||
|
<layout>
|
||||||
|
<window_info id="Favorites" side_tool="true" />
|
||||||
|
<window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.6136821" />
|
||||||
|
<window_info id="Structure" order="1" side_tool="true" weight="0.25" />
|
||||||
|
<window_info anchor="bottom" id="Database Changes" />
|
||||||
|
<window_info anchor="bottom" id="Version Control" />
|
||||||
|
<window_info anchor="bottom" id="Terminal" />
|
||||||
|
<window_info anchor="bottom" id="Event Log" side_tool="true" />
|
||||||
|
<window_info anchor="bottom" id="Message" order="0" />
|
||||||
|
<window_info anchor="bottom" id="Find" order="1" />
|
||||||
|
<window_info anchor="bottom" id="Run" order="2" />
|
||||||
|
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
|
||||||
|
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
|
||||||
|
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
||||||
|
<window_info anchor="bottom" id="TODO" order="6" />
|
||||||
|
<window_info anchor="right" id="Cargo" />
|
||||||
|
<window_info anchor="right" id="Database" />
|
||||||
|
<window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" />
|
||||||
|
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
|
||||||
|
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
|
||||||
|
</layout>
|
||||||
|
</component>
|
||||||
|
<component name="editorHistoryManager">
|
||||||
|
<entry file="file://$PROJECT_DIR$/src/spectraluser.cpp">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="75">
|
||||||
|
<caret line="5" lean-forward="true" selection-start-line="5" selection-end-line="5" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1,71 @@
|
||||||
|
import QtQuick 2.12
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
property alias topLeftRadius: topLeftRect.radius
|
||||||
|
property alias topRightRadius: topRightRect.radius
|
||||||
|
property alias bottomLeftRadius: bottomLeftRect.radius
|
||||||
|
property alias bottomRightRadius: bottomRightRect.radius
|
||||||
|
|
||||||
|
property alias topLeftVisible: topLeftRect.visible
|
||||||
|
property alias topRightVisible: topRightRect.visible
|
||||||
|
property alias bottomLeftVisible: bottomLeftRect.visible
|
||||||
|
property alias bottomRightVisible: bottomRightRect.visible
|
||||||
|
|
||||||
|
antialiasing: true
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
|
||||||
|
width: parent.width / 2
|
||||||
|
height: parent.height / 2
|
||||||
|
|
||||||
|
id: topLeftRect
|
||||||
|
|
||||||
|
antialiasing: true
|
||||||
|
|
||||||
|
color: parent.color
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
width: parent.width / 2
|
||||||
|
height: parent.height / 2
|
||||||
|
|
||||||
|
id: topRightRect
|
||||||
|
|
||||||
|
antialiasing: true
|
||||||
|
|
||||||
|
color: parent.color
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
|
||||||
|
width: parent.width / 2
|
||||||
|
height: parent.height / 2
|
||||||
|
|
||||||
|
id: bottomLeftRect
|
||||||
|
|
||||||
|
antialiasing: true
|
||||||
|
|
||||||
|
color: parent.color
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
width: parent.width / 2
|
||||||
|
height: parent.height / 2
|
||||||
|
|
||||||
|
id: bottomRightRect
|
||||||
|
|
||||||
|
antialiasing: true
|
||||||
|
|
||||||
|
color: parent.color
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,8 @@ import QtQuick 2.12
|
||||||
import QtQuick.Controls 2.12
|
import QtQuick.Controls 2.12
|
||||||
import QtGraphicalEffects 1.0
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
|
import Spectral.Setting 0.1
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
property string hint: "H"
|
property string hint: "H"
|
||||||
property string source: ""
|
property string source: ""
|
||||||
|
@ -35,7 +37,7 @@ Item {
|
||||||
visible: !realSource || image.status != Image.Ready
|
visible: !realSource || image.status != Image.Ready
|
||||||
|
|
||||||
radius: height / 2
|
radius: height / 2
|
||||||
color: stringToColor(hint)
|
color: MPalette.accent
|
||||||
antialiasing: true
|
antialiasing: true
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
|
@ -50,16 +52,16 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function stringToColor(str) {
|
// function stringToColor(str) {
|
||||||
var hash = 0;
|
// var hash = 0;
|
||||||
for (var i = 0; i < str.length; i++) {
|
// for (var i = 0; i < str.length; i++) {
|
||||||
hash = str.charCodeAt(i) + ((hash << 5) - hash);
|
// hash = str.charCodeAt(i) + ((hash << 5) - hash);
|
||||||
}
|
// }
|
||||||
var colour = '#';
|
// var colour = '#';
|
||||||
for (var j = 0; j < 3; j++) {
|
// for (var j = 0; j < 3; j++) {
|
||||||
var value = (hash >> (j * 8)) & 0xFF;
|
// var value = (hash >> (j * 8)) & 0xFF;
|
||||||
colour += ('00' + value.toString(16)).substr(-2);
|
// colour += ('00' + value.toString(16)).substr(-2);
|
||||||
}
|
// }
|
||||||
return colour;
|
// return colour;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,65 +67,25 @@ ColumnLayout {
|
||||||
Control {
|
Control {
|
||||||
Layout.maximumWidth: messageListView.width - (!sentByMe ? 36 + messageRow.spacing : 0) - 48
|
Layout.maximumWidth: messageListView.width - (!sentByMe ? 36 + messageRow.spacing : 0) - 48
|
||||||
|
|
||||||
verticalPadding: 8
|
padding: 0
|
||||||
horizontalPadding: 16
|
|
||||||
|
background: AutoRectangle {
|
||||||
|
readonly property int minorRadius: 2
|
||||||
|
|
||||||
|
id: bubbleBackground
|
||||||
|
|
||||||
background: Rectangle {
|
|
||||||
color: sentByMe ? MPalette.background : eventType === "notice" ? MPalette.primary : MPalette.accent
|
color: sentByMe ? MPalette.background : eventType === "notice" ? MPalette.primary : MPalette.accent
|
||||||
radius: 18
|
radius: 18
|
||||||
antialiasing: true
|
|
||||||
|
|
||||||
Rectangle {
|
topLeftVisible: true
|
||||||
anchors.top: parent.top
|
topRightVisible: true
|
||||||
anchors.left: parent.left
|
bottomLeftVisible: true
|
||||||
|
bottomRightVisible: true
|
||||||
|
|
||||||
width: parent.width / 2
|
topLeftRadius: minorRadius
|
||||||
height: parent.height / 2
|
topRightRadius: minorRadius
|
||||||
|
bottomLeftRadius: minorRadius
|
||||||
visible: true
|
bottomRightRadius: minorRadius
|
||||||
|
|
||||||
color: sentByMe ? MPalette.background : eventType === "notice" ? MPalette.primary : MPalette.accent
|
|
||||||
radius: 5
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.right: parent.right
|
|
||||||
|
|
||||||
width: parent.width / 2
|
|
||||||
height: parent.height / 2
|
|
||||||
|
|
||||||
visible: true
|
|
||||||
|
|
||||||
color: sentByMe ? MPalette.background : eventType === "notice" ? MPalette.primary : MPalette.accent
|
|
||||||
radius: 5
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.left: parent.left
|
|
||||||
|
|
||||||
width: parent.width / 2
|
|
||||||
height: parent.height / 2
|
|
||||||
|
|
||||||
visible: true
|
|
||||||
|
|
||||||
color: sentByMe ? MPalette.background : eventType === "notice" ? MPalette.primary : MPalette.accent
|
|
||||||
radius: 5
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.right: parent.right
|
|
||||||
|
|
||||||
width: parent.width / 2
|
|
||||||
height: parent.height / 2
|
|
||||||
|
|
||||||
visible: true
|
|
||||||
|
|
||||||
color: sentByMe ? MPalette.background : eventType === "notice" ? MPalette.primary : MPalette.accent
|
|
||||||
radius: 5
|
|
||||||
}
|
|
||||||
|
|
||||||
AutoMouseArea {
|
AutoMouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
@ -166,63 +126,72 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
contentItem: ColumnLayout {
|
contentItem: ColumnLayout {
|
||||||
RowLayout {
|
spacing: 0
|
||||||
|
|
||||||
|
Control {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
Layout.topMargin: 8
|
||||||
|
Layout.leftMargin: 8
|
||||||
|
Layout.rightMargin: 8
|
||||||
|
|
||||||
|
padding: 4
|
||||||
|
rightPadding: 12
|
||||||
|
|
||||||
visible: replyVisible
|
visible: replyVisible
|
||||||
|
|
||||||
Avatar {
|
contentItem: RowLayout {
|
||||||
Layout.preferredWidth: 28
|
Avatar {
|
||||||
Layout.preferredHeight: 28
|
Layout.preferredWidth: 28
|
||||||
Layout.alignment: Qt.AlignTop
|
Layout.preferredHeight: 28
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
|
||||||
source: replyVisible ? replyAuthor.avatarMediaId : ""
|
source: replyVisible ? replyAuthor.avatarMediaId : ""
|
||||||
hint: replyVisible ? replyAuthor.displayName : "H"
|
hint: replyVisible ? replyAuthor.displayName : "H"
|
||||||
|
|
||||||
RippleEffect {
|
RippleEffect {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
circular: true
|
circular: true
|
||||||
|
|
||||||
onClicked: userDetailDialog.createObject(ApplicationWindow.overlay, {"room": currentRoom, "user": replyAuthor}).open()
|
onClicked: userDetailDialog.createObject(ApplicationWindow.overlay, {"room": currentRoom, "user": replyAuthor}).open()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Control {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
visible: replyVisible
|
|
||||||
|
|
||||||
padding: 0
|
|
||||||
|
|
||||||
background: RippleEffect {
|
|
||||||
onClicked: goToEvent(replyEventId)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
contentItem: Label {
|
Label {
|
||||||
color: darkBackground ? "white" : MPalette.lighter
|
Layout.fillWidth: true
|
||||||
text: "<style>a{color: " + (darkBackground ? "white" : MPalette.foreground) + ";} .user-pill{}</style>" + (replyDisplay || "")
|
|
||||||
|
color: !sentByMe ? MPalette.foreground : "white"
|
||||||
|
text: "<style>a{color: " + color + ";} .user-pill{}</style>" + (replyDisplay || "")
|
||||||
|
|
||||||
wrapMode: Label.Wrap
|
wrapMode: Label.Wrap
|
||||||
textFormat: Label.RichText
|
textFormat: Label.RichText
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
background: Rectangle {
|
||||||
Layout.fillWidth: true
|
color: sentByMe ? MPalette.accent : MPalette.background
|
||||||
Layout.preferredHeight: 1
|
radius: 18
|
||||||
|
|
||||||
visible: replyVisible
|
AutoMouseArea {
|
||||||
color: darkBackground ? "white" : MPalette.lighter
|
anchors.fill: parent
|
||||||
|
|
||||||
|
onClicked: goToEvent(replyEventId)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TextEdit {
|
TextEdit {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
Layout.leftMargin: 16
|
||||||
|
Layout.rightMargin: 16
|
||||||
|
Layout.topMargin: 8
|
||||||
|
Layout.bottomMargin: 8
|
||||||
|
|
||||||
id: contentLabel
|
id: contentLabel
|
||||||
|
|
||||||
text: "<style>a{color: " + (darkBackground ? "white" : MPalette.foreground) + ";} .user-pill{}</style>" + display
|
text: "<style>a{color: " + color + ";} .user-pill{}</style>" + display
|
||||||
|
|
||||||
color: darkBackground ? "white" : MPalette.foreground
|
color: darkBackground ? "white" : MPalette.foreground
|
||||||
|
|
||||||
|
|
|
@ -7,3 +7,4 @@ AutoListView 2.0 AutoListView.qml
|
||||||
AutoTextField 2.0 AutoTextField.qml
|
AutoTextField 2.0 AutoTextField.qml
|
||||||
Avatar 2.0 Avatar.qml
|
Avatar 2.0 Avatar.qml
|
||||||
FullScreenImage 2.0 FullScreenImage.qml
|
FullScreenImage 2.0 FullScreenImage.qml
|
||||||
|
AutoRectangle 2.0 AutoRectangle.qml
|
||||||
|
|
|
@ -27,8 +27,8 @@ Dialog {
|
||||||
Layout.preferredWidth: 72
|
Layout.preferredWidth: 72
|
||||||
Layout.preferredHeight: 72
|
Layout.preferredHeight: 72
|
||||||
|
|
||||||
hint: user ? user.displayName : "No name"
|
hint: user.displayName
|
||||||
source: user ? user.avatarMediaId : null
|
source: user.avatarMediaId
|
||||||
|
|
||||||
RippleEffect {
|
RippleEffect {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
@ -50,10 +50,19 @@ Dialog {
|
||||||
|
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
wrapMode: Text.NoWrap
|
wrapMode: Text.NoWrap
|
||||||
text: user ? user.displayName : "No Name"
|
text: user.displayName
|
||||||
color: MPalette.foreground
|
color: MPalette.foreground
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
visible: user.bridgeName
|
||||||
|
|
||||||
|
text: user.bridgeName
|
||||||
|
color: MPalette.lighter
|
||||||
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
@ -89,7 +98,7 @@ Dialog {
|
||||||
|
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
wrapMode: Text.NoWrap
|
wrapMode: Text.NoWrap
|
||||||
text: user ? user.id : "No ID"
|
text: user.id
|
||||||
color: MPalette.accent
|
color: MPalette.accent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,3 +11,4 @@ FontFamilyDialog 2.0 FontFamilyDialog.qml
|
||||||
AccountDetailDialog 2.0 AccountDetailDialog.qml
|
AccountDetailDialog 2.0 AccountDetailDialog.qml
|
||||||
OpenFileDialog 2.0 OpenFileDialog.qml
|
OpenFileDialog 2.0 OpenFileDialog.qml
|
||||||
OpenFolderDialog 2.0 OpenFolderDialog.qml
|
OpenFolderDialog 2.0 OpenFolderDialog.qml
|
||||||
|
ImageClipboardDialog 2.0 ImageClipboardDialog.qml
|
||||||
|
|
|
@ -31,7 +31,7 @@ Item {
|
||||||
|
|
||||||
connection: root.connection
|
connection: root.connection
|
||||||
|
|
||||||
onNewMessage: if (!window.active && MSettings.showNotification) spectralController.postNotification(roomId, eventId, roomName, senderName, text, icon)
|
onNewMessage: if (!window.active && MSettings.showNotification) notificationsManager.postNotification(roomId, eventId, roomName, senderName, text, icon)
|
||||||
}
|
}
|
||||||
|
|
||||||
SortFilterProxyModel {
|
SortFilterProxyModel {
|
||||||
|
@ -54,6 +54,16 @@ Item {
|
||||||
|
|
||||||
sorters: [
|
sorters: [
|
||||||
RoleSorter { roleName: "category" },
|
RoleSorter { roleName: "category" },
|
||||||
|
ExpressionSorter {
|
||||||
|
expression: {
|
||||||
|
return modelLeft.highlightCount > 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ExpressionSorter {
|
||||||
|
expression: {
|
||||||
|
return modelLeft.notificationCount > 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
RoleSorter {
|
RoleSorter {
|
||||||
roleName: "lastActiveTime"
|
roleName: "lastActiveTime"
|
||||||
sortOrder: Qt.DescendingOrder
|
sortOrder: Qt.DescendingOrder
|
||||||
|
|
|
@ -3,10 +3,12 @@ import QtQuick.Controls 2.12
|
||||||
import QtQuick.Layouts 1.12
|
import QtQuick.Layouts 1.12
|
||||||
import QtQuick.Controls.Material 2.12
|
import QtQuick.Controls.Material 2.12
|
||||||
import Qt.labs.qmlmodels 1.0
|
import Qt.labs.qmlmodels 1.0
|
||||||
|
import Qt.labs.platform 1.0
|
||||||
|
|
||||||
import Spectral.Component 2.0
|
import Spectral.Component 2.0
|
||||||
import Spectral.Component.Emoji 2.0
|
import Spectral.Component.Emoji 2.0
|
||||||
import Spectral.Component.Timeline 2.0
|
import Spectral.Component.Timeline 2.0
|
||||||
|
import Spectral.Dialog 2.0
|
||||||
import Spectral.Effect 2.0
|
import Spectral.Effect 2.0
|
||||||
|
|
||||||
import Spectral 0.1
|
import Spectral 0.1
|
||||||
|
@ -23,6 +25,121 @@ Item {
|
||||||
room: currentRoom
|
room: currentRoom
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DropArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
enabled: currentRoom
|
||||||
|
|
||||||
|
onDropped: {
|
||||||
|
if (!drop.hasUrls) return
|
||||||
|
|
||||||
|
roomPanelInput.attach(drop.urls[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageClipboard {
|
||||||
|
id: imageClipboard
|
||||||
|
}
|
||||||
|
|
||||||
|
Popup {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
id: attachDialog
|
||||||
|
|
||||||
|
padding: 16
|
||||||
|
|
||||||
|
contentItem: RowLayout {
|
||||||
|
Control {
|
||||||
|
Layout.preferredWidth: 160
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
padding: 16
|
||||||
|
|
||||||
|
contentItem: ColumnLayout {
|
||||||
|
spacing: 16
|
||||||
|
|
||||||
|
MaterialIcon {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
||||||
|
icon: "\ue2c8"
|
||||||
|
font.pixelSize: 64
|
||||||
|
color: MPalette.lighter
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
||||||
|
text: "Choose local file"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
background: RippleEffect {
|
||||||
|
onClicked: {
|
||||||
|
attachDialog.close()
|
||||||
|
|
||||||
|
var fileDialog = openFileDialog.createObject(ApplicationWindow.overlay)
|
||||||
|
|
||||||
|
fileDialog.chosen.connect(function(path) {
|
||||||
|
if (!path) return
|
||||||
|
|
||||||
|
roomPanelInput.attach(path)
|
||||||
|
})
|
||||||
|
|
||||||
|
fileDialog.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.preferredWidth: 1
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
color: MPalette.banner
|
||||||
|
}
|
||||||
|
|
||||||
|
Control {
|
||||||
|
Layout.preferredWidth: 160
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
padding: 16
|
||||||
|
|
||||||
|
contentItem: ColumnLayout {
|
||||||
|
spacing: 16
|
||||||
|
|
||||||
|
MaterialIcon {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
||||||
|
icon: "\ue410"
|
||||||
|
font.pixelSize: 64
|
||||||
|
color: MPalette.lighter
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
||||||
|
text: "Clipboard image"
|
||||||
|
color: MPalette.foreground
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
background: RippleEffect {
|
||||||
|
onClicked: {
|
||||||
|
var localPath = StandardPaths.writableLocation(StandardPaths.CacheLocation) + "/screenshots/" + (new Date()).getTime() + ".png"
|
||||||
|
if (!imageClipboard.saveImage(localPath)) return
|
||||||
|
roomPanelInput.attach(localPath)
|
||||||
|
attachDialog.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: openFileDialog
|
||||||
|
|
||||||
|
OpenFileDialog {}
|
||||||
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import QtQuick.Controls.Material 2.12
|
||||||
|
|
||||||
import Spectral.Component 2.0
|
import Spectral.Component 2.0
|
||||||
import Spectral.Component.Emoji 2.0
|
import Spectral.Component.Emoji 2.0
|
||||||
|
import Spectral.Dialog 2.0
|
||||||
import Spectral.Effect 2.0
|
import Spectral.Effect 2.0
|
||||||
import Spectral.Setting 0.1
|
import Spectral.Setting 0.1
|
||||||
|
|
||||||
|
@ -21,6 +22,9 @@ Control {
|
||||||
property int autoCompleteBeginPosition
|
property int autoCompleteBeginPosition
|
||||||
property int autoCompleteEndPosition
|
property int autoCompleteEndPosition
|
||||||
|
|
||||||
|
property bool hasAttachment: false
|
||||||
|
property url attachmentPath
|
||||||
|
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
padding: 0
|
padding: 0
|
||||||
|
@ -171,13 +175,13 @@ Control {
|
||||||
Layout.alignment: Qt.AlignBottom
|
Layout.alignment: Qt.AlignBottom
|
||||||
|
|
||||||
id: uploadButton
|
id: uploadButton
|
||||||
visible: !isReply
|
visible: !isReply && !hasAttachment
|
||||||
|
|
||||||
contentItem: MaterialIcon {
|
contentItem: MaterialIcon {
|
||||||
icon: "\ue226"
|
icon: "\ue226"
|
||||||
}
|
}
|
||||||
|
|
||||||
onClicked: currentRoom.chooseAndUploadFile()
|
onClicked: attachDialog.open()
|
||||||
|
|
||||||
BusyIndicator {
|
BusyIndicator {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
@ -202,6 +206,51 @@ Control {
|
||||||
onClicked: clearReply()
|
onClicked: clearReply()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Control {
|
||||||
|
Layout.margins: 6
|
||||||
|
Layout.preferredHeight: 36
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
|
||||||
|
visible: hasAttachment
|
||||||
|
|
||||||
|
rightPadding: 8
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: MPalette.accent
|
||||||
|
radius: height / 2
|
||||||
|
antialiasing: true
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: RowLayout {
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
ToolButton {
|
||||||
|
Layout.preferredWidth: height
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
id: cancelAttachmentButton
|
||||||
|
|
||||||
|
contentItem: MaterialIcon {
|
||||||
|
icon: "\ue5cd"
|
||||||
|
color: "white"
|
||||||
|
font.pixelSize: 18
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
hasAttachment = false
|
||||||
|
attachmentPath = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
|
||||||
|
text: attachmentPath != "" ? attachmentPath.toString().substring(attachmentPath.toString().lastIndexOf('/') + 1, attachmentPath.length) : ""
|
||||||
|
color: "white"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TextArea {
|
TextArea {
|
||||||
property real progress: 0
|
property real progress: 0
|
||||||
|
|
||||||
|
@ -252,7 +301,7 @@ Control {
|
||||||
Keys.onReturnPressed: {
|
Keys.onReturnPressed: {
|
||||||
if (event.modifiers & Qt.ShiftModifier) {
|
if (event.modifiers & Qt.ShiftModifier) {
|
||||||
insert(cursorPosition, "\n")
|
insert(cursorPosition, "\n")
|
||||||
} else if (text) {
|
} else {
|
||||||
postMessage(text)
|
postMessage(text)
|
||||||
text = ""
|
text = ""
|
||||||
closeAll()
|
closeAll()
|
||||||
|
@ -304,9 +353,16 @@ Control {
|
||||||
}
|
}
|
||||||
|
|
||||||
function postMessage(text) {
|
function postMessage(text) {
|
||||||
if (text.trim().length === 0) { return }
|
|
||||||
if(!currentRoom) { return }
|
if(!currentRoom) { return }
|
||||||
|
|
||||||
|
if (hasAttachment) {
|
||||||
|
currentRoom.uploadFile(attachmentPath, text)
|
||||||
|
clearAttachment()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text.trim().length === 0) { return }
|
||||||
|
|
||||||
var PREFIX_ME = '/me '
|
var PREFIX_ME = '/me '
|
||||||
var PREFIX_NOTICE = '/notice '
|
var PREFIX_NOTICE = '/notice '
|
||||||
var PREFIX_RAINBOW = '/rainbow '
|
var PREFIX_RAINBOW = '/rainbow '
|
||||||
|
@ -372,6 +428,10 @@ Control {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImageClipboard {
|
||||||
|
id: imageClipboard
|
||||||
|
}
|
||||||
|
|
||||||
function insert(str) {
|
function insert(str) {
|
||||||
inputField.insert(inputField.cursorPosition, str)
|
inputField.insert(inputField.cursorPosition, str)
|
||||||
}
|
}
|
||||||
|
@ -396,4 +456,14 @@ Control {
|
||||||
autoCompleteListView.visible = false
|
autoCompleteListView.visible = false
|
||||||
emojiPicker.visible = false
|
emojiPicker.visible = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function attach(localPath) {
|
||||||
|
hasAttachment = true
|
||||||
|
attachmentPath = localPath
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearAttachment() {
|
||||||
|
hasAttachment = false
|
||||||
|
attachmentPath = ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 52a81dfa8a5415be369d819837f445479b833cde
|
Subproject commit d6f39dcb0de69322479f287514a8c36afcb3fe7b
|
|
@ -56,12 +56,17 @@ ApplicationWindow {
|
||||||
|
|
||||||
quitOnLastWindowClosed: !MSettings.showTray
|
quitOnLastWindowClosed: !MSettings.showTray
|
||||||
|
|
||||||
|
onErrorOccured: errorControl.show(error + ": " + detail, 3000)
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationsManager {
|
||||||
|
id: notificationsManager
|
||||||
|
|
||||||
onNotificationClicked: {
|
onNotificationClicked: {
|
||||||
roomListForm.enteredRoom = spectralController.connection.room(roomId)
|
roomListForm.enteredRoom = spectralController.connection.room(roomId)
|
||||||
roomForm.goToEvent(eventId)
|
roomForm.goToEvent(eventId)
|
||||||
showWindow()
|
showWindow()
|
||||||
}
|
}
|
||||||
onErrorOccured: errorControl.show(error + ": " + detail, 3000)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Shortcut {
|
Shortcut {
|
||||||
|
|
1
res.qrc
1
res.qrc
|
@ -58,5 +58,6 @@
|
||||||
<file>imports/Spectral/Dialog/OpenFileDialog.qml</file>
|
<file>imports/Spectral/Dialog/OpenFileDialog.qml</file>
|
||||||
<file>imports/Spectral/Dialog/OpenFolderDialog.qml</file>
|
<file>imports/Spectral/Dialog/OpenFolderDialog.qml</file>
|
||||||
<file>imports/Spectral/Component/Timeline/VideoDelegate.qml</file>
|
<file>imports/Spectral/Component/Timeline/VideoDelegate.qml</file>
|
||||||
|
<file>imports/Spectral/Component/AutoRectangle.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
10
spectral.pro
10
spectral.pro
|
@ -117,7 +117,6 @@ mac {
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
src/controller.h \
|
src/controller.h \
|
||||||
src/roomlistmodel.h \
|
src/roomlistmodel.h \
|
||||||
src/imageprovider.h \
|
|
||||||
src/messageeventmodel.h \
|
src/messageeventmodel.h \
|
||||||
src/emojimodel.h \
|
src/emojimodel.h \
|
||||||
src/spectralroom.h \
|
src/spectralroom.h \
|
||||||
|
@ -125,19 +124,22 @@ HEADERS += \
|
||||||
src/accountlistmodel.h \
|
src/accountlistmodel.h \
|
||||||
src/spectraluser.h \
|
src/spectraluser.h \
|
||||||
src/notifications/manager.h \
|
src/notifications/manager.h \
|
||||||
src/utils.h
|
src/utils.h \
|
||||||
|
src/imageclipboard.h \
|
||||||
|
src/matriximageprovider.h
|
||||||
|
|
||||||
SOURCES += src/main.cpp \
|
SOURCES += src/main.cpp \
|
||||||
src/controller.cpp \
|
src/controller.cpp \
|
||||||
src/roomlistmodel.cpp \
|
src/roomlistmodel.cpp \
|
||||||
src/imageprovider.cpp \
|
|
||||||
src/messageeventmodel.cpp \
|
src/messageeventmodel.cpp \
|
||||||
src/emojimodel.cpp \
|
src/emojimodel.cpp \
|
||||||
src/spectralroom.cpp \
|
src/spectralroom.cpp \
|
||||||
src/userlistmodel.cpp \
|
src/userlistmodel.cpp \
|
||||||
src/accountlistmodel.cpp \
|
src/accountlistmodel.cpp \
|
||||||
src/spectraluser.cpp \
|
src/spectraluser.cpp \
|
||||||
src/utils.cpp
|
src/utils.cpp \
|
||||||
|
src/imageclipboard.cpp \
|
||||||
|
src/matriximageprovider.cpp
|
||||||
|
|
||||||
unix:!mac {
|
unix:!mac {
|
||||||
SOURCES += src/notifications/managerlinux.cpp
|
SOURCES += src/notifications/managerlinux.cpp
|
||||||
|
|
|
@ -0,0 +1,223 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE QtCreatorProject>
|
||||||
|
<!-- Written by QtCreator 4.9.0, 2019-05-19T18:51:54. -->
|
||||||
|
<qtcreator>
|
||||||
|
<data>
|
||||||
|
<variable>EnvironmentId</variable>
|
||||||
|
<value type="QByteArray">{7614c50b-52db-49bf-a585-31417a3c0f62}</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
||||||
|
<value type="int">0</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.EditorSettings</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
|
||||||
|
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
|
||||||
|
<value type="QString" key="language">Cpp</value>
|
||||||
|
<valuemap type="QVariantMap" key="value">
|
||||||
|
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
|
||||||
|
</valuemap>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
|
||||||
|
<value type="QString" key="language">QmlJS</value>
|
||||||
|
<valuemap type="QVariantMap" key="value">
|
||||||
|
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
|
||||||
|
</valuemap>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
|
||||||
|
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.IndentSize">4</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
|
||||||
|
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
|
||||||
|
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
|
||||||
|
<value type="int" key="EditorConfiguration.TabSize">8</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
|
||||||
|
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.PluginSettings</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey"/>
|
||||||
|
<value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.Target.0</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Qt 5.12.1 (System)</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Qt 5.12.1 (System)</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{97a6fc6e-df2b-4272-9664-99a23fd81def}</value>
|
||||||
|
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
||||||
|
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||||
|
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/tanuj/code/spectral/build</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
||||||
|
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
|
||||||
|
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
|
||||||
|
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
||||||
|
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
|
||||||
|
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
|
||||||
|
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
||||||
|
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
|
||||||
|
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
||||||
|
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||||
|
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
|
||||||
|
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy Configuration</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||||
|
<value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
|
||||||
|
<valuelist type="QVariantList" key="Analyzer.Perf.Events">
|
||||||
|
<value type="QString">cpu-cycles</value>
|
||||||
|
</valuelist>
|
||||||
|
<valuelist type="QVariantList" key="Analyzer.Perf.ExtraArguments"/>
|
||||||
|
<value type="int" key="Analyzer.Perf.Frequency">250</value>
|
||||||
|
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value>
|
||||||
|
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="int" key="Analyzer.Perf.StackSize">4096</value>
|
||||||
|
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
|
||||||
|
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
|
||||||
|
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
|
||||||
|
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
|
||||||
|
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||||
|
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
|
||||||
|
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
|
||||||
|
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
|
||||||
|
<value type="QString" key="Analyzer.Valgrind.KCachegrindExecutable">kcachegrind</value>
|
||||||
|
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
|
||||||
|
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
|
||||||
|
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
|
||||||
|
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
|
||||||
|
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
|
||||||
|
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
|
||||||
|
<value type="int">0</value>
|
||||||
|
<value type="int">1</value>
|
||||||
|
<value type="int">2</value>
|
||||||
|
<value type="int">3</value>
|
||||||
|
<value type="int">4</value>
|
||||||
|
<value type="int">5</value>
|
||||||
|
<value type="int">6</value>
|
||||||
|
<value type="int">7</value>
|
||||||
|
<value type="int">8</value>
|
||||||
|
<value type="int">9</value>
|
||||||
|
<value type="int">10</value>
|
||||||
|
<value type="int">11</value>
|
||||||
|
<value type="int">12</value>
|
||||||
|
<value type="int">13</value>
|
||||||
|
<value type="int">14</value>
|
||||||
|
</valuelist>
|
||||||
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
|
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">spectral</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/tanuj/code/spectral/spectral.pro</value>
|
||||||
|
<value type="QString" key="RunConfiguration.Arguments"></value>
|
||||||
|
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||||
|
<value type="QString" key="RunConfiguration.WorkingDirectory"></value>
|
||||||
|
<value type="QString" key="RunConfiguration.WorkingDirectory.default">/home/tanuj/code/spectral/build</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.TargetCount</variable>
|
||||||
|
<value type="int">1</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
|
||||||
|
<value type="int">21</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>Version</variable>
|
||||||
|
<value type="int">21</value>
|
||||||
|
</data>
|
||||||
|
</qtcreator>
|
|
@ -31,13 +31,9 @@
|
||||||
#include <QtNetwork/QAuthenticator>
|
#include <QtNetwork/QAuthenticator>
|
||||||
#include <QtNetwork/QNetworkReply>
|
#include <QtNetwork/QNetworkReply>
|
||||||
|
|
||||||
Controller::Controller(QObject* parent)
|
Controller::Controller(QObject* parent) : QObject(parent) {
|
||||||
: QObject(parent), notificationsManager(this) {
|
|
||||||
QApplication::setQuitOnLastWindowClosed(false);
|
QApplication::setQuitOnLastWindowClosed(false);
|
||||||
|
|
||||||
connect(¬ificationsManager, &NotificationsManager::notificationClicked,
|
|
||||||
this, &Controller::notificationClicked);
|
|
||||||
|
|
||||||
Connection::setRoomType<SpectralRoom>();
|
Connection::setRoomType<SpectralRoom>();
|
||||||
Connection::setUserType<SpectralUser>();
|
Connection::setUserType<SpectralUser>();
|
||||||
|
|
||||||
|
@ -232,10 +228,6 @@ void Controller::createDirectChat(Connection* c, const QString& userID) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::copyToClipboard(const QString& text) {
|
|
||||||
m_clipboard->setText(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::playAudio(QUrl localFile) {
|
void Controller::playAudio(QUrl localFile) {
|
||||||
QMediaPlayer* player = new QMediaPlayer;
|
QMediaPlayer* player = new QMediaPlayer;
|
||||||
player->setMedia(localFile);
|
player->setMedia(localFile);
|
||||||
|
@ -243,16 +235,6 @@ void Controller::playAudio(QUrl localFile) {
|
||||||
connect(player, &QMediaPlayer::stateChanged, [=] { player->deleteLater(); });
|
connect(player, &QMediaPlayer::stateChanged, [=] { player->deleteLater(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::postNotification(const QString& roomId,
|
|
||||||
const QString& eventId,
|
|
||||||
const QString& roomName,
|
|
||||||
const QString& senderName,
|
|
||||||
const QString& text,
|
|
||||||
const QImage& icon) {
|
|
||||||
notificationsManager.postNotification(roomId, eventId, roomName, senderName,
|
|
||||||
text, icon);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Controller::dpi() {
|
int Controller::dpi() {
|
||||||
return SettingsGroup("Interface").value("dpi", 100).toInt();
|
return SettingsGroup("Interface").value("dpi", 100).toInt();
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,8 +67,6 @@ class Controller : public QObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QClipboard* m_clipboard = QApplication::clipboard();
|
|
||||||
NotificationsManager notificationsManager;
|
|
||||||
QVector<Connection*> m_connections;
|
QVector<Connection*> m_connections;
|
||||||
QPointer<Connection> m_connection;
|
QPointer<Connection> m_connection;
|
||||||
|
|
||||||
|
@ -99,14 +97,7 @@ class Controller : public QObject {
|
||||||
void joinRoom(Connection* c, const QString& alias);
|
void joinRoom(Connection* c, const QString& alias);
|
||||||
void createRoom(Connection* c, const QString& name, const QString& topic);
|
void createRoom(Connection* c, const QString& name, const QString& topic);
|
||||||
void createDirectChat(Connection* c, const QString& userID);
|
void createDirectChat(Connection* c, const QString& userID);
|
||||||
void copyToClipboard(const QString& text);
|
|
||||||
void playAudio(QUrl localFile);
|
void playAudio(QUrl localFile);
|
||||||
void postNotification(const QString& roomId,
|
|
||||||
const QString& eventId,
|
|
||||||
const QString& roomName,
|
|
||||||
const QString& senderName,
|
|
||||||
const QString& text,
|
|
||||||
const QImage& icon);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CONTROLLER_H
|
#endif // CONTROLLER_H
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
#include "imageclipboard.h"
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QGuiApplication>
|
||||||
|
#include <QUrl>
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
|
ImageClipboard::ImageClipboard(QObject* parent)
|
||||||
|
: QObject(parent), m_clipboard(QGuiApplication::clipboard()) {
|
||||||
|
connect(m_clipboard, &QClipboard::changed, this,
|
||||||
|
&ImageClipboard::imageChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImageClipboard::hasImage() {
|
||||||
|
return !image().isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage ImageClipboard::image() {
|
||||||
|
return m_clipboard->image();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImageClipboard::saveImage(const QUrl& localPath) {
|
||||||
|
if (!localPath.isLocalFile())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto i = image();
|
||||||
|
|
||||||
|
if (i.isNull())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QString path = QFileInfo(localPath.toString()).absolutePath();
|
||||||
|
QDir dir;
|
||||||
|
if (!dir.exists(path))
|
||||||
|
dir.mkpath(path);
|
||||||
|
|
||||||
|
i.save(localPath.toLocalFile());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef IMAGECLIPBOARD_H
|
||||||
|
#define IMAGECLIPBOARD_H
|
||||||
|
|
||||||
|
#include <QClipboard>
|
||||||
|
#include <QImage>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class ImageClipboard : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(bool hasImage READ hasImage NOTIFY imageChanged)
|
||||||
|
Q_PROPERTY(QImage image READ image NOTIFY imageChanged)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ImageClipboard(QObject* parent = nullptr);
|
||||||
|
|
||||||
|
bool hasImage();
|
||||||
|
QImage image();
|
||||||
|
|
||||||
|
Q_INVOKABLE bool saveImage(const QUrl& localPath);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QClipboard* m_clipboard;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void imageChanged();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // IMAGECLIPBOARD_H
|
14
src/main.cpp
14
src/main.cpp
|
@ -8,8 +8,10 @@
|
||||||
#include "accountlistmodel.h"
|
#include "accountlistmodel.h"
|
||||||
#include "controller.h"
|
#include "controller.h"
|
||||||
#include "emojimodel.h"
|
#include "emojimodel.h"
|
||||||
#include "imageprovider.h"
|
#include "imageclipboard.h"
|
||||||
|
#include "matriximageprovider.h"
|
||||||
#include "messageeventmodel.h"
|
#include "messageeventmodel.h"
|
||||||
|
#include "notifications/manager.h"
|
||||||
#include "room.h"
|
#include "room.h"
|
||||||
#include "roomlistmodel.h"
|
#include "roomlistmodel.h"
|
||||||
#include "spectralroom.h"
|
#include "spectralroom.h"
|
||||||
|
@ -55,6 +57,9 @@ int main(int argc, char* argv[]) {
|
||||||
qmlRegisterType<UserListModel>("Spectral", 0, 1, "UserListModel");
|
qmlRegisterType<UserListModel>("Spectral", 0, 1, "UserListModel");
|
||||||
qmlRegisterType<MessageEventModel>("Spectral", 0, 1, "MessageEventModel");
|
qmlRegisterType<MessageEventModel>("Spectral", 0, 1, "MessageEventModel");
|
||||||
qmlRegisterType<EmojiModel>("Spectral", 0, 1, "EmojiModel");
|
qmlRegisterType<EmojiModel>("Spectral", 0, 1, "EmojiModel");
|
||||||
|
qmlRegisterType<NotificationsManager>("Spectral", 0, 1,
|
||||||
|
"NotificationsManager");
|
||||||
|
qmlRegisterType<ImageClipboard>("Spectral", 0, 1, "ImageClipboard");
|
||||||
qmlRegisterUncreatableType<RoomMessageEvent>("Spectral", 0, 1,
|
qmlRegisterUncreatableType<RoomMessageEvent>("Spectral", 0, 1,
|
||||||
"RoomMessageEvent", "ENUM");
|
"RoomMessageEvent", "ENUM");
|
||||||
qmlRegisterUncreatableType<RoomType>("Spectral", 0, 1, "RoomType", "ENUM");
|
qmlRegisterUncreatableType<RoomType>("Spectral", 0, 1, "RoomType", "ENUM");
|
||||||
|
@ -72,9 +77,10 @@ int main(int argc, char* argv[]) {
|
||||||
QQmlApplicationEngine engine;
|
QQmlApplicationEngine engine;
|
||||||
|
|
||||||
engine.addImportPath("qrc:/imports");
|
engine.addImportPath("qrc:/imports");
|
||||||
ImageProvider* m_provider = new ImageProvider();
|
MatrixImageProvider* matrixImageProvider = new MatrixImageProvider();
|
||||||
engine.rootContext()->setContextProperty("imageProvider", m_provider);
|
engine.rootContext()->setContextProperty("imageProvider",
|
||||||
engine.addImageProvider(QLatin1String("mxc"), m_provider);
|
matrixImageProvider);
|
||||||
|
engine.addImageProvider(QLatin1String("mxc"), matrixImageProvider);
|
||||||
|
|
||||||
engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
|
engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
|
||||||
if (engine.rootObjects().isEmpty())
|
if (engine.rootObjects().isEmpty())
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "imageprovider.h"
|
#include "matriximageprovider.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
@ -108,7 +108,7 @@ void ThumbnailResponse::cancel() {
|
||||||
Qt::QueuedConnection);
|
Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
QQuickImageResponse* ImageProvider::requestImageResponse(
|
QQuickImageResponse* MatrixImageProvider::requestImageResponse(
|
||||||
const QString& id,
|
const QString& id,
|
||||||
const QSize& requestedSize) {
|
const QSize& requestedSize) {
|
||||||
return new ThumbnailResponse(m_connection.load(), id, requestedSize);
|
return new ThumbnailResponse(m_connection.load(), id, requestedSize);
|
|
@ -1,5 +1,5 @@
|
||||||
#ifndef IMAGEPROVIDER_H
|
#ifndef MatrixImageProvider_H
|
||||||
#define IMAGEPROVIDER_H
|
#define MatrixImageProvider_H
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QtQuick/QQuickAsyncImageProvider>
|
#include <QtQuick/QQuickAsyncImageProvider>
|
||||||
|
@ -43,12 +43,12 @@ class ThumbnailResponse : public QQuickImageResponse {
|
||||||
void cancel() override;
|
void cancel() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ImageProvider : public QObject, public QQuickAsyncImageProvider {
|
class MatrixImageProvider : public QObject, public QQuickAsyncImageProvider {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(QMatrixClient::Connection* connection READ connection WRITE
|
Q_PROPERTY(QMatrixClient::Connection* connection READ connection WRITE
|
||||||
setConnection NOTIFY connectionChanged)
|
setConnection NOTIFY connectionChanged)
|
||||||
public:
|
public:
|
||||||
explicit ImageProvider() = default;
|
explicit MatrixImageProvider() = default;
|
||||||
|
|
||||||
QQuickImageResponse* requestImageResponse(
|
QQuickImageResponse* requestImageResponse(
|
||||||
const QString& id,
|
const QString& id,
|
||||||
|
@ -67,4 +67,4 @@ class ImageProvider : public QObject, public QQuickAsyncImageProvider {
|
||||||
QAtomicPointer<QMatrixClient::Connection> m_connection;
|
QAtomicPointer<QMatrixClient::Connection> m_connection;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // IMAGEPROVIDER_H
|
#endif // MatrixImageProvider_H
|
|
@ -19,11 +19,7 @@ struct roomEventId {
|
||||||
class NotificationsManager : public QObject {
|
class NotificationsManager : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
NotificationsManager(QObject *parent = nullptr);
|
NotificationsManager(QObject* parent = nullptr);
|
||||||
|
|
||||||
void postNotification(const QString &roomId, const QString &eventId,
|
|
||||||
const QString &roomName, const QString &senderName,
|
|
||||||
const QString &text, const QImage &icon);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void notificationClicked(const QString roomId, const QString eventId);
|
void notificationClicked(const QString roomId, const QString eventId);
|
||||||
|
@ -31,7 +27,8 @@ class NotificationsManager : public QObject {
|
||||||
private:
|
private:
|
||||||
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
|
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
|
||||||
QDBusInterface dbus;
|
QDBusInterface dbus;
|
||||||
uint showNotification(const QString summary, const QString text,
|
uint showNotification(const QString summary,
|
||||||
|
const QString text,
|
||||||
const QImage image);
|
const QImage image);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -43,9 +40,16 @@ class NotificationsManager : public QObject {
|
||||||
public slots:
|
public slots:
|
||||||
void actionInvoked(uint id, QString action);
|
void actionInvoked(uint id, QString action);
|
||||||
void notificationClosed(uint id, uint reason);
|
void notificationClosed(uint id, uint reason);
|
||||||
|
|
||||||
|
void postNotification(const QString& roomId,
|
||||||
|
const QString& eventId,
|
||||||
|
const QString& roomName,
|
||||||
|
const QString& senderName,
|
||||||
|
const QString& text,
|
||||||
|
const QImage& icon);
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
|
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
|
||||||
QDBusArgument &operator<<(QDBusArgument &arg, const QImage &image);
|
QDBusArgument& operator<<(QDBusArgument& arg, const QImage& image);
|
||||||
const QDBusArgument &operator>>(const QDBusArgument &arg, QImage &);
|
const QDBusArgument& operator>>(const QDBusArgument& arg, QImage&);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -44,33 +44,33 @@ inline QSize getImageSize(const QUrl& imageUrl) {
|
||||||
return reader.size();
|
return reader.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpectralRoom::chooseAndUploadFile() {
|
void SpectralRoom::uploadFile(const QUrl& url, const QString& body) {
|
||||||
auto localFile = QFileDialog::getOpenFileUrl(Q_NULLPTR, tr("Save File as"));
|
if (url.isEmpty())
|
||||||
if (!localFile.isEmpty()) {
|
return;
|
||||||
QString txnID = postFile(localFile.fileName(), localFile, false);
|
|
||||||
setHasFileUploading(true);
|
QString txnID = postFile(body.isEmpty() ? url.fileName() : body, url, false);
|
||||||
connect(this, &Room::fileTransferCompleted,
|
setHasFileUploading(true);
|
||||||
[=](QString id, QUrl localFile, QUrl mxcUrl) {
|
connect(this, &Room::fileTransferCompleted,
|
||||||
if (id == txnID) {
|
[=](QString id, QUrl localFile, QUrl mxcUrl) {
|
||||||
setFileUploadingProgress(0);
|
if (id == txnID) {
|
||||||
setHasFileUploading(false);
|
setFileUploadingProgress(0);
|
||||||
}
|
setHasFileUploading(false);
|
||||||
});
|
}
|
||||||
connect(this, &Room::fileTransferFailed, [=](QString id, QString error) {
|
});
|
||||||
if (id == txnID) {
|
connect(this, &Room::fileTransferFailed, [=](QString id, QString error) {
|
||||||
setFileUploadingProgress(0);
|
if (id == txnID) {
|
||||||
setHasFileUploading(false);
|
setFileUploadingProgress(0);
|
||||||
}
|
setHasFileUploading(false);
|
||||||
});
|
}
|
||||||
connect(
|
});
|
||||||
this, &Room::fileTransferProgress,
|
connect(
|
||||||
[=](QString id, qint64 progress, qint64 total) {
|
this, &Room::fileTransferProgress,
|
||||||
if (id == txnID) {
|
[=](QString id, qint64 progress, qint64 total) {
|
||||||
qDebug() << "Progress:" << progress << total;
|
if (id == txnID) {
|
||||||
setFileUploadingProgress(int(float(progress) / float(total) * 100));
|
qDebug() << "Progress:" << progress << total;
|
||||||
}
|
setFileUploadingProgress(int(float(progress) / float(total) * 100));
|
||||||
});
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpectralRoom::acceptInvitation() {
|
void SpectralRoom::acceptInvitation() {
|
||||||
|
|
|
@ -254,7 +254,7 @@ class SpectralRoom : public Room {
|
||||||
void fileUploadingProgressChanged();
|
void fileUploadingProgressChanged();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void chooseAndUploadFile();
|
void uploadFile(const QUrl& url, const QString& body = "");
|
||||||
void acceptInvitation();
|
void acceptInvitation();
|
||||||
void forget();
|
void forget();
|
||||||
void sendTypingNotification(bool isTyping);
|
void sendTypingNotification(bool isTyping);
|
||||||
|
|
|
@ -1 +1,5 @@
|
||||||
#include "spectraluser.h"
|
#include "spectraluser.h"
|
||||||
|
|
||||||
|
QColor SpectralUser::color() {
|
||||||
|
return QColor::fromHslF(hueF(), 0.7, 0.5, 1);
|
||||||
|
}
|
||||||
|
|
|
@ -10,9 +10,12 @@ using namespace QMatrixClient;
|
||||||
|
|
||||||
class SpectralUser : public User {
|
class SpectralUser : public User {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QColor color READ color CONSTANT)
|
||||||
public:
|
public:
|
||||||
SpectralUser(QString userId, Connection* connection)
|
SpectralUser(QString userId, Connection* connection)
|
||||||
: User(userId, connection) {}
|
: User(userId, connection) {}
|
||||||
|
|
||||||
|
QColor color();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SpectralUser_H
|
#endif // SpectralUser_H
|
||||||
|
|
Loading…
Reference in New Issue