Added support for loading more items in conversation buffers

This commit is contained in:
Manuel Cortez 2019-04-09 16:08:14 -05:00
parent cde18c8d35
commit 00eebf9260
3 changed files with 36 additions and 7 deletions

View File

@ -914,7 +914,10 @@ class chatBuffer(baseBuffer):
item_ = getattr(renderers, self.compose_function)(item, self.session) item_ = getattr(renderers, self.compose_function)(item, self.session)
# the self.chat dictionary will have (first_line, last_line) as keys and message ID as a value for looking into it when needed. # the self.chat dictionary will have (first_line, last_line) as keys and message ID as a value for looking into it when needed.
# Here we will get first and last line of a chat message appended to the history. # Here we will get first and last line of a chat message appended to the history.
values = self.tab.add_message(item_[0]) lines = self.tab.history.GetNumberOfLines()
values = self.tab.add_message(item_[0], reverse=reversed)
if reversed:
values = (values[0]-lines, values[1]-lines)
self.chats[values] = item["id"] self.chats[values] = item["id"]
def get_focused_post(self): def get_focused_post(self):
@ -985,10 +988,11 @@ class chatBuffer(baseBuffer):
event.Skip() event.Skip()
def get_items(self, show_nextpage=False): def get_items(self, show_nextpage=False):
""" Update buffer with newest items or get older items in the buffer."""
if self.can_get_items == False: return if self.can_get_items == False: return
retrieved = True # Control variable for handling unauthorised/connection errors. retrieved = True
try: try:
num = getattr(self.session, "get_messages")(name=self.name, *self.args, **self.kwargs) num = getattr(self.session, "get_page")(show_nextpage=show_nextpage, name=self.name, *self.args, **self.kwargs)
except VkApiError as err: except VkApiError as err:
log.error("Error {0}: {1}".format(err.code, err.error)) log.error("Error {0}: {1}".format(err.code, err.error))
retrieved = err.code retrieved = err.code
@ -1001,20 +1005,38 @@ class chatBuffer(baseBuffer):
self.create_tab(self.parent) self.create_tab(self.parent)
# Add name to the new control so we could look for it when needed. # Add name to the new control so we could look for it when needed.
self.tab.name = self.name self.tab.name = self.name
if show_nextpage == False: if show_nextpage == False:
if self.tab.history.GetValue() != "" and num > 0: if self.tab.history.GetValue() != "" and num > 0:
v = [i for i in self.session.db[self.name]["items"][:num]] v = [i for i in self.session.db[self.name]["items"][:num]]
# v.reverse()
[self.insert(i, False) for i in v] [self.insert(i, False) for i in v]
else: else:
[self.insert(i) for i in self.session.db[self.name]["items"][:num]] [self.insert(i) for i in self.session.db[self.name]["items"][:num]]
else: else:
if num > 0: if num > 0:
[self.insert(i, False) for i in self.session.db[self.name]["items"][:num]] # At this point we save more CPU and mathematical work if we just delete everything in the chat history and readd all messages.
# Otherwise we'd have to insert new lines at the top and recalculate positions everywhere else.
# Firstly, we'd have to save the current focused object so we will place the user in the right part of the text after loading everything again.
focused_post = self.get_post()
self.chats = dict()
self.tab.history.SetValue("")
v = [i for i in self.session.db[self.name]["items"]]
[self.insert(i) for i in v]
# Now it's time to set back the focus in the post.
for i in self.chats.keys():
if self.chats[i] == focused_post["id"]:
line = i[0]
self.tab.history.SetInsertionPoint(self.tab.history.XYToPosition(0, line))
output.speak(_("Items loaded"))
break
if self.unread == True and num > 0: if self.unread == True and num > 0:
self.session.db[self.name]["items"][-1].update(read_state=0) self.session.db[self.name]["items"][-1].update(read_state=0)
return retrieved return retrieved
def get_more_items(self):
output.speak(_("Getting more items..."))
call_threaded(self.get_items, show_nextpage=True)
def add_attachment(self, *args, **kwargs): def add_attachment(self, *args, **kwargs):
a = presenters.attachPresenter(session=self.session, view=views.attachDialog(voice_messages=True), interactor=interactors.attachInteractor()) a = presenters.attachPresenter(session=self.session, view=views.attachDialog(voice_messages=True), interactor=interactors.attachInteractor())
if len(a.attachments) != 0: if len(a.attachments) != 0:

View File

@ -392,7 +392,7 @@ class Controller(object):
elif user_id > 2000000000: elif user_id > 2000000000:
chat = self.session.vk.client.messages.getChat(chat_id=user_id-2000000000) chat = self.session.vk.client.messages.getChat(chat_id=user_id-2000000000)
name = chat["title"] name = chat["title"]
wx.CallAfter(pub.sendMessage, "create_buffer", buffer_type="chatBuffer", buffer_title=name, parent_tab="chats", get_items=True, kwargs=dict(parent=self.window.tb, name="{0}_messages".format(user_id,), composefunc="render_message", session=self.session, unread=unread, count=200, peer_id=user_id, rev=0, extended=True, fields="id, user_id, date, read_state, out, body, attachments, deleted")) wx.CallAfter(pub.sendMessage, "create_buffer", buffer_type="chatBuffer", buffer_title=name, parent_tab="chats", get_items=True, kwargs=dict(parent=self.window.tb, name="{0}_messages".format(user_id,), composefunc="render_message", parent_endpoint="messages", endpoint="getHistory", session=self.session, unread=unread, count=200, peer_id=user_id, rev=0, extended=True, fields="id, user_id, date, read_state, out, body, attachments, deleted"))
# if setfocus: # if setfocus:
# pos = self.window.search(buffer.name) # pos = self.window.search(buffer.name)
# self.window.change_buffer(pos) # self.window.change_buffer(pos)
@ -538,7 +538,7 @@ class Controller(object):
data = [message] data = [message]
# Let's add this to the buffer. # Let's add this to the buffer.
# ToDo: Clean this code and test how is the database working with this set to True. # ToDo: Clean this code and test how is the database working with this set to True.
num = self.session.order_buffer(buffer.name, data, True) buffer.session.db[buffer.name]["items"].append(message)
buffer.insert(self.session.db[buffer.name]["items"][-1], False) buffer.insert(self.session.db[buffer.name]["items"][-1], False)
self.session.soundplayer.play("message_received.ogg") self.session.soundplayer.play("message_received.ogg")
wx.CallAfter(self.reorder_buffer, buffer) wx.CallAfter(self.reorder_buffer, buffer)

View File

@ -66,6 +66,9 @@ class vkSession(object):
self.db[name] = {} self.db[name] = {}
self.db[name]["items"] = [] self.db[name]["items"] = []
first_addition = True first_addition = True
# Handles chat messages case, as the buffer is inverted
if name.endswith("_messages") and show_nextpage == True:
show_nextpage = False
for i in data: for i in data:
if "type" in i and not isinstance(i["type"], int) and (i["type"] == "wall_photo" or i["type"] == "photo_tag" or i["type"] == "photo"): if "type" in i and not isinstance(i["type"], int) and (i["type"] == "wall_photo" or i["type"] == "photo_tag" or i["type"] == "photo"):
log.debug("Skipping unsupported item... %r" % (i,)) log.debug("Skipping unsupported item... %r" % (i,))
@ -192,6 +195,10 @@ class vkSession(object):
if data != None: if data != None:
if "count" not in kwargs: if "count" not in kwargs:
kwargs["count"] = 100 kwargs["count"] = 100
# Let's handle a little exception when dealing with conversation buffers.
# the first results of the query should be reversed before being sent to order_buffer.
if type(data) == dict and "items" in data and endpoint == "getHistory" and kwargs["offset"] == 0:
data["items"].reverse()
if type(data) == dict: if type(data) == dict:
num = self.order_buffer(name, data["items"], show_nextpage) num = self.order_buffer(name, data["items"], show_nextpage)
self.db[name]["offset"] = kwargs["offset"]+kwargs["count"] self.db[name]["offset"] = kwargs["offset"]+kwargs["count"]