add database table and api to track read state of conversations
This commit is contained in:
14
database.py
14
database.py
@@ -59,3 +59,17 @@ class LxmfMessage(BaseModel):
|
||||
# define table name
|
||||
class Meta:
|
||||
table_name = "lxmf_messages"
|
||||
|
||||
|
||||
class LxmfConversationReadState(BaseModel):
|
||||
|
||||
id = BigAutoField()
|
||||
destination_hash = CharField(unique=True) # unique destination hash
|
||||
last_read_at = DateTimeField()
|
||||
|
||||
created_at = DateTimeField(default=lambda: datetime.now(timezone.utc))
|
||||
updated_at = DateTimeField(default=lambda: datetime.now(timezone.utc))
|
||||
|
||||
# define table name
|
||||
class Meta:
|
||||
table_name = "lxmf_conversation_read_state"
|
||||
|
||||
@@ -2043,8 +2043,13 @@
|
||||
this.loadNodePage(node.destination_hash, "/page/index.mu");
|
||||
},
|
||||
onConversationClick: function(conversation) {
|
||||
|
||||
// object must stay compatible with format of peers
|
||||
this.onPeerClick(conversation);
|
||||
|
||||
// mark conversation as read
|
||||
this.markConversationAsRead(conversation.destination_hash);
|
||||
|
||||
},
|
||||
parseSeconds: function(secondsToFormat) {
|
||||
secondsToFormat = Number(secondsToFormat);
|
||||
@@ -2192,6 +2197,20 @@
|
||||
// reload conversation
|
||||
await this.loadLxmfMessages(this.selectedPeer.destination_hash);
|
||||
|
||||
},
|
||||
async markConversationAsRead(destinationHash) {
|
||||
|
||||
// mark conversation as read
|
||||
try {
|
||||
await window.axios.get(`/api/v1/lxmf/conversations/${this.selectedPeer.destination_hash}/mark-as-read`);
|
||||
} catch(e) {
|
||||
// do nothing if failed to mark as read
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
// reload conversations
|
||||
await this.getConversations();
|
||||
|
||||
},
|
||||
async enableInterface(interfaceName) {
|
||||
|
||||
|
||||
30
web.py
30
web.py
@@ -65,6 +65,7 @@ class ReticulumWebChat:
|
||||
database.Config,
|
||||
database.Announce,
|
||||
database.LxmfMessage,
|
||||
database.LxmfConversationReadState,
|
||||
])
|
||||
|
||||
# vacuum database on start to shrink its file size
|
||||
@@ -852,6 +853,20 @@ class ReticulumWebChat:
|
||||
"conversations": conversations,
|
||||
})
|
||||
|
||||
# mark lxmf conversation as read
|
||||
@routes.get("/api/v1/lxmf/conversations/{destination_hash}/mark-as-read")
|
||||
async def index(request):
|
||||
|
||||
# get path params
|
||||
destination_hash = request.match_info.get("destination_hash", "")
|
||||
|
||||
# mark lxmf conversation as read
|
||||
self.db_mark_lxmf_conversation_as_read(destination_hash)
|
||||
|
||||
return web.json_response({
|
||||
"message": "ok",
|
||||
})
|
||||
|
||||
# called when web app has started
|
||||
async def on_startup(app):
|
||||
|
||||
@@ -1299,6 +1314,21 @@ class ReticulumWebChat:
|
||||
query = query.on_conflict(conflict_target=[database.Announce.destination_hash], update=data)
|
||||
query.execute()
|
||||
|
||||
# upserts lxmf conversation read state to the database
|
||||
def db_mark_lxmf_conversation_as_read(self, destination_hash: str):
|
||||
|
||||
# prepare data to insert or update
|
||||
data = {
|
||||
"destination_hash": destination_hash,
|
||||
"last_read_at": datetime.now(timezone.utc),
|
||||
"updated_at": datetime.now(timezone.utc),
|
||||
}
|
||||
|
||||
# upsert to database
|
||||
query = database.LxmfConversationReadState.insert(data)
|
||||
query = query.on_conflict(conflict_target=[database.LxmfConversationReadState.destination_hash], update=data)
|
||||
query.execute()
|
||||
|
||||
# handle sending an lxmf message to reticulum
|
||||
async def send_message(self, destination_hash, content: str,
|
||||
image_field: LxmfImageField = None,
|
||||
|
||||
Reference in New Issue
Block a user