example 'meshtastic': add deletion of messages; revisions

This commit is contained in:
pls.153 2023-08-09 18:32:58 +02:00
parent 8f42003e36
commit e6b25c8d60
8 changed files with 128 additions and 85 deletions

View file

@ -31,3 +31,7 @@
(let ((val (first (query "select max(mid) from messages"))))
(if (numberp val) val 0)))
(defun delete-message (mid)
(query "delete from messages where mid = ?"
mid))

View file

@ -11,7 +11,6 @@
(msg:show-messages)
(q> |currentIndex| ui:*main-view* 0)) ; 'Group'
(q> |playing| ui:*loading* nil)
(q> |interactive| ui:*main-view* t)
#+android
(progn
(ensure-permissions :access-fine-location) ; for sharing location
@ -30,6 +29,7 @@
(q> |currentIndex| ui:*main-view* 0))
(q> |visible| ui:*location* (= 0 index))
(q> |visible| ui:*find* (= 1 index))
(q> |interactive| ui:*main-view* (/= 1 index)) ; swipe single message, not view
(values))
(defun icon-press-and-hold (name) ; see QML

View file

@ -61,6 +61,7 @@
(defpackage :db
(:use :cl)
(:export
#:delete-message
#:ini
#:load-message
#:load-messages

View file

@ -12,9 +12,124 @@ Rectangle {
anchors.fill: parent
anchors.bottomMargin: rectEdit.height + 3
anchors.margins: 5
delegate: messageDelegate
model: messages
clip: true
delegate: SwipeDelegate {
id: swipeDelegate
width: view.width
height: delegate.height
clip: true
onPressAndHold: Lisp.call("msg:message-press-and-hold", model.text)
background: Item {
id: delegate
width: Math.max(text.paintedWidth, rowSender.width + 4 * text.padding) + 2 * text.padding + 4
height: model.hidden ? 0 : (text.contentHeight + 2 * text.padding + sender.contentHeight + 8)
Rectangle {
anchors.centerIn: parent
width: parent.width
height: parent.height - 4
color: model.me ? "#f2f2f2" : "#ffffcc"
radius: 12
Row {
id: rowSender
padding: text.padding
spacing: padding - 2
AnimatedImage {
id: semaphore
playing: false
y: 4
width: 8
height: width
source: "../img/semaphore.gif"
currentFrame: model.ackState
visible: model.me
}
Text {
id: sender
font.pixelSize: 12
font.family: fontText.name
color: "#8B0000"
text: model.senderName ? model.senderName : model.sender
}
}
Text {
id: timestamp
x: delegate.width - contentWidth - text.padding
y: text.padding
font.pixelSize: 12
font.family: fontText.name
color: "#505050"
text: model.hour
MouseArea {
anchors.fill: parent
onClicked: Lisp.call("msg:show-date", model.timestamp)
}
}
Text {
id: text
y: sender.contentHeight
width: main.width - 10
padding: 5
wrapMode: Text.Wrap
font.pixelSize: 18
font.family: fontText.name
color: "#303030"
textFormat: Text.StyledText // for 'paintedWidth' to always work
text: model.text
}
}
}
ListView.onRemove: SequentialAnimation {
PropertyAction {
target: swipeDelegate
property: "ListView.delayRemove"
value: true
}
NumberAnimation {
target: swipeDelegate
property: "height"
to: 0
easing.type: Easing.InOutQuad
}
PropertyAction {
target: swipeDelegate
property: "ListView.delayRemove"
value: false
}
}
swipe.left: Rectangle {
y: 2
width: 35
height: parent.height - 2 * y
color: "#ff4141"
radius: 12
Image {
anchors.centerIn: parent
width: 12
height: width
source: "../img/delete.png"
}
SwipeDelegate.onClicked: {
var mid = model.mid
view.model.remove(index)
Lisp.call("db:delete-message", mid)
}
}
}
}
ListModel {
@ -67,83 +182,6 @@ Rectangle {
Component.onCompleted: remove(0) // see hack above
}
Component {
id: messageDelegate
Item {
id: delegate
width: Math.max(text.paintedWidth, rowSender.width + 4 * text.padding) + 2 * text.padding + 4
height: model.hidden ? 0 : (text.contentHeight + 2 * text.padding + sender.contentHeight + 8)
clip: true
Rectangle {
anchors.centerIn: parent
width: parent.width
height: parent.height - 4
color: model.me ? "#f2f2f2" : "#ffffcc"
radius: 12
MouseArea {
anchors.fill: parent
onPressAndHold: Lisp.call("msg:message-press-and-hold", model.text)
}
Row {
id: rowSender
padding: text.padding
spacing: padding - 2
AnimatedImage {
id: semaphore
playing: false
y: 4
width: 8
height: width
source: "../img/semaphore.gif"
currentFrame: model.ackState
visible: model.me
}
Text {
id: sender
font.pixelSize: 12
font.family: fontText.name
color: "#8B0000"
text: model.senderName ? model.senderName : model.sender
}
}
Text {
id: timestamp
x: delegate.width - contentWidth - text.padding
y: text.padding
font.pixelSize: 12
font.family: fontText.name
color: "#505050"
text: model.hour
MouseArea {
anchors.fill: parent
onClicked: Lisp.call("msg:show-date", model.timestamp)
}
}
Text {
id: text
y: sender.contentHeight
width: main.width - 10
padding: 5
wrapMode: Text.Wrap
font.pixelSize: 18
font.family: fontText.name
color: "#303030"
textFormat: Text.StyledText // for 'paintedWidth' to always work
text: model.text
}
}
}
}
// find text
TextField {

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View file

@ -40,7 +40,6 @@ Item {
width: headerHeight
height: width
anchors.right: parent.right
visible: false
MouseArea {
anchors.fill: parent

View file

@ -37,12 +37,14 @@ Messages
--------
The initial view shows the messages between you and a chosen person. You choose
the desired person in the **Group** view (swipe to the left).
the desired person in the **Group** view (tap on group icon).
To copy a message to the clipboard, press-and-hold it.
To see the exact date of a message, tap on its hour.
To delete a message, swipe it to the right and tap on the delete button.
The search function (icon on the right) should be intuitive. The search term
(case insensitive) is highlighted in red. Tap again on the search icon to leave
search mode.
@ -51,7 +53,7 @@ search mode.
Group
-----
Swiping to the left (from **Messages**), you see the list of all persons. Every
Tapping on group (in **Messages**), you'll see the list of all persons. Every
person is associated to a specific radio. This view is populated automatically.
You can set a name to every person associated to a radio, which defaults to
@ -66,7 +68,7 @@ without internet connection.
Radios
------
Swiping to the right (from **Messages**), you see the list of all radios
Tapping on radio (in **Messages**), you'll see the list of all radios
visible to your phone's bluetooth. You generally just choose 1 device, which
will be remembered.

View file

@ -57,8 +57,7 @@ The macOS version must be compiled first and started from Finder (not the
console), otherwise BLE permissions will not work (if run from console, the app
will show a BLE exception and consume 100% CPU).
It should also work on Windows 10 and later, but the bluetooth part is not
tested yet.
Windows 10+ will follow soon.