TODO List

This commit is contained in:
Sarah Jamie Lewis 2019-02-11 15:23:17 -08:00
parent 316f9246c0
commit 7b6d6c7ada
1 changed files with 146 additions and 195 deletions

View File

@ -2,26 +2,52 @@ import QtGraphicalEffects 1.0
import QtQuick 2.7 import QtQuick 2.7
import QtQuick.Controls 2.4 import QtQuick.Controls 2.4
import QtQuick.Controls.Material 2.0 import QtQuick.Controls.Material 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3 import QtQuick.Layouts 1.3
import "../widgets" import "../widgets"
import "../widgets/controls" as Awesome import "../widgets/controls" as Awesome
import "../fonts/Twemoji.js" as T import "../fonts/Twemoji.js" as T
import "../utils.js" as Utils
import "../styles"
ColumnLayout { ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
width:parent.width
Text {
Layout.fillWidth: true
text: parent.toolbar.text + " Lists"
}
TextField {
id: filter
placeholderText: "Search.."
style: CwtchTextFieldStyle{}
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: 10
onTextChanged: {
bulletinView.filter = text
if (bulletinView.model.get(bulletinView.currentIndex).title.indexOf(text) == -1) {
bulletinView.currentIndex = -1
}
}
}
Flickable { // THE MESSAGE LIST ITSELF Flickable { // THE MESSAGE LIST ITSELF
id: sv id: sv
clip: true clip: true
Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.alignment: Qt.AlignLeft | Qt.AlignTop
Layout.fillHeight: true Layout.fillHeight: true
Layout.minimumWidth: parent.width
Layout.maximumWidth: parent.width
Layout.fillWidth: true Layout.fillWidth: true
contentWidth: colMessages.width contentWidth: bulletin.width
contentHeight: colMessages.height contentHeight: bulletin.height
boundsBehavior: Flickable.StopAtBounds boundsBehavior: Flickable.StopAtBounds
maximumFlickVelocity: 800 maximumFlickVelocity: 800
@ -30,28 +56,34 @@ ColumnLayout {
target: gcd target: gcd
onClearMessages: function() { onClearMessages: function() {
messagesModel.clear() jsonModel4.clear()
} }
onAppendMessage: function(handle, from, displayName, message, image, mid, fromMe, ts) { onAppendMessage: function(handle, from, displayName, message, image, mid, fromMe, ts) {
var msg var msg
try { try {
msg = JSON.parse(message) msg = JSON.parse(message)
} catch (e) { } catch (e) {
msg = {"o": 1, "d": "(legacy message type) " + message} return
} }
if (msg.o != 2) return if (msg.o != 4) return
messagesModel.append({ if (msg.t != undefined) {
"_handle": handle, jsonModel4.insert(0,{
"_from": from, "title":msg.t,
"_displayName": displayName, "selected":false,
"_message": parse(msg.d, 12), "from": from,
"_image": image, "displayName": displayName,
"_mid": mid, "timestamp": ts,
"_fromMe": fromMe, "complete": false
"_ts": ts, })
}) }
if(msg.c != undefined) {
console.log("Checking off " + msg.c)
console.log(jsonModel4.get(msg.c).title)
jsonModel4.get(msg.c).complete = true
}
if (sv.contentY + sv.height >= sv.contentHeight - colMessages.height && sv.contentHeight > sv.height) { if (sv.contentY + sv.height >= sv.contentHeight - colMessages.height && sv.contentHeight > sv.height) {
sv.contentY = sv.contentHeight - sv.height sv.contentY = sv.contentHeight - sv.height
@ -59,204 +91,123 @@ ColumnLayout {
} }
} }
ScrollBar.vertical: ScrollBar{ ScrollBar.vertical: ScrollBar{
policy: ScrollBar.AlwaysOn policy: ScrollBar.AlwaysOn
} }
ColumnLayout { ListView {
id: colMessages id: bulletinView
width: sv.width anchors.left: parent.left
anchors.leftMargin: 10
anchors.topMargin: 10
width: parent.width - 50
height: parent.height - 20
orientation: Qt.Vertical
spacing: 10
model: jsonModel4
property string filter: ""
delegate:
Item {
width: parent.width
height: title.indexOf(bulletinView.filter) >= 0 ? texttitle.height : 0
visible: title.indexOf(bulletinView.filter) >= 0
Column {
width: parent.width
RowLayout {
CheckBox {
checked: complete
checkedState: complete ? Qt.Checked : Qt.UnChecked
onClicked: {
var msg = JSON.stringify({"o":4, "c":index})
gcd.sendMessage(msg, btnSend.nextMessageID++)
}
}
RowLayout {
Text {
id: texttitle
text: '<b>' + Utils.htmlEscaped(title) + '</b> by ' + from + "<br/>" + timestamp
leftPadding: 10
topPadding: 5
bottomPadding:5
color: windowItem.cwtch_dark_color
}
}
}
ListModel { // MESSAGE OBJECTS ARE STORED HERE ... Rectangle {
id: messagesModel height: 1
} color: windowItem.cwtch_color
anchors {
left: parent.left
right: parent.right
}
}
Item { height: 6 }
Repeater { // ... AND DISPLAYED HERE }
model: messagesModel
delegate: Message { }
handle: _handle
from: _from focus: true
displayName: _displayName ListModel {
message: "be gay, do crimes, and make lists" id: jsonModel4
image: _image
messageID: _mid
fromMe: _fromMe
timestamp: _ts
} }
}
} }
} }
RowLayout { // THE BOTTOM DRAWER GroupBox {
Rectangle { // MESSAGE ENTRY TEXTFIELD title: qsTr("Add a New List Item")
id: rectMessage Layout.fillWidth: true
RowLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.minimumHeight: 40 * gcd.themeScale width: parent.width
Layout.maximumHeight: 40 * gcd.themeScale ColumnLayout {
color: "#EDEDED" Layout.fillWidth: true
border.color: "#AAAAAA"
radius: 10
Flickable { Text {
id: flkMessage text: "Add a new item to the list"
anchors.fill: parent//this does nothing! bug in qt
Layout.minimumWidth: parent.width
Layout.maximumWidth: parent.width
Layout.minimumHeight: rectMessage.height
Layout.maximumHeight: rectMessage.height
contentWidth: txtMessage.width
contentHeight: txtMessage.height
boundsBehavior: Flickable.StopAtBounds
clip:true
maximumFlickVelocity: 300
ScrollBar.vertical: ScrollBar{}
TextEdit {
id: txtMessage
font.pixelSize: 10
text: ""
padding: 6
wrapMode: TextEdit.Wrap
textFormat: Text.RichText
width: rectMessage.width
//height: parent.height
property bool skipOneUpdate: false
Keys.onReturnPressed: { // CTRL+ENTER = LINEBREAK
if (event.modifiers & Qt.ControlModifier) {
txtMessage.insert(txtMessage.cursorPosition, "<br>")
} else if (event.modifiers == Qt.NoModifier) {
btnSend.clicked()
}
}
// welcome to the emoji parser! it is horrifying code that needs to leave in <img src="[emoji]">
// while also stripping any other tag, including other images.
// TODO: this probably breaks if people actually do want to paste html
onTextChanged: {
//console.log("onTextChanged()")
// we're taking advantage of TextEdit.getText()'s parsing capability, which means occasionally
// passing text into it to be filtered. this prevents recursive calls putting us into an
// infinite loop
if (skipOneUpdate) {
console.log("skipping one update")
skipOneUpdate = false
return
}
//console.log("1: " + txtMessage.getText(0, txtMessage.text.length))
// convert <img> tags back to their emoji form
var nt = restoreEmoji(txtMessage.text)
if (nt != txtMessage.text) {
skipOneUpdate = true
txtMessage.text = nt
}
//console.log("2: " + txtMessage.getText(0, txtMessage.text.length))
// strip all HTML tags
var theText = txtMessage.getText(0, txtMessage.text.length)
//console.log("3: " + theText)
// convert emoji back to <img> tags
nt = parse(theText, 10)
//console.log("4: " + nt)
// if there were changes...
if (nt != txtMessage.getText(0, txtMessage.text.length)) {
// first we need to update the cursor position to be the same distance from the end
var oldcursor = txtMessage.cursorPosition
var oldlen = txtMessage.getText(0, txtMessage.text.length).length
// then we actually put the updated text in
skipOneUpdate = true
txtMessage.text = nt
// and then restore the cursor
var newlen = txtMessage.getText(0, txtMessage.text.length).length
txtMessage.cursorPosition = newlen - (oldlen - oldcursor)
}
// autoscroll down only when the scrollbar is already all the way down
if (flkMessage.contentY + flkMessage.height >= flkMessage.contentHeight - txtMessage.height && flkMessage.contentHeight > flkMessage.height) {
flkMessage.contentY = flkMessage.contentHeight - flkMessage.height
}
}
}
}
MouseArea {
anchors.fill: parent
onClicked: txtMessage.focus = true
}
}
ColumnLayout {
id: colRight
spacing: 1
SimpleButton { // SEND MESSAGE BUTTON
id: btnSend
icon: "regular/paper-plane"
text: "send"
Layout.minimumWidth: btnEmoji.width + btnAttach.width + 2
Layout.maximumWidth: btnEmoji.width + btnAttach.width + 2
anchors.right: parent.right
anchors.rightMargin: 2
property int nextMessageID: 1
TextEdit {
id: txtHidden
visible: false
textFormat: Text.RichText
} }
onClicked: { TextField {
if (txtMessage.text != "") { id: newposttitle
txtHidden.text = restoreEmoji(txtMessage.text) placeholderText: "Todo.."
var msg = JSON.stringify({"o":2, "d":txtHidden.getText(0, txtHidden.text.length)}) Layout.fillWidth: true
gcd.sendMessage(msg, nextMessageID++) style: CwtchTextFieldStyle{}
}
txtMessage.text = ""
}
}
RowLayout {
spacing: 1
SimpleButton { // EMOJI DRAWER BUTTON
id: btnEmoji
icon: "regular/smile"
anchors.right: btnAttach.left
anchors.rightMargin: 2
onClicked: gcd.popup("emoji not yet implemented, sorry")
} }
SimpleButton { SimpleButton { // SEND MESSAGE BUTTON
id: btnAttach id: btnSend
icon: "solid/paperclip" icon: "regular/paper-plane"
text: "add"
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: 2 anchors.rightMargin: 2
property int nextMessageID: 1
onClicked: { onClicked: {
gcd.popup("attachments not yet implemented, sorry") if (newposttitle.text != "") {
var msg = JSON.stringify({"o":4, "t":newposttitle.text})
gcd.sendMessage(msg, nextMessageID++)
}
newposttitle.text = ""
} }
} }
} }
} }
} }
}
}