Added support to comment threads. Shows comment replies in a separate viewer. Show total replies for a comment in a column in the list

This commit is contained in:
Manuel Cortez 2019-01-09 16:47:58 -06:00
parent 9465cf03ac
commit 02f1ab0e4a
3 changed files with 115 additions and 12 deletions

View File

@ -46,7 +46,11 @@ class displayPostInteractor(base.baseInteractor):
widgetUtils.connect_event(self.view.like, widgetUtils.BUTTON_PRESSED, self.on_like) widgetUtils.connect_event(self.view.like, widgetUtils.BUTTON_PRESSED, self.on_like)
widgetUtils.connect_event(self.view.comment, widgetUtils.BUTTON_PRESSED, self.on_add_comment) widgetUtils.connect_event(self.view.comment, widgetUtils.BUTTON_PRESSED, self.on_add_comment)
widgetUtils.connect_event(self.view.tools, widgetUtils.BUTTON_PRESSED, self.on_show_tools_menu) widgetUtils.connect_event(self.view.tools, widgetUtils.BUTTON_PRESSED, self.on_show_tools_menu)
if hasattr(self.view, "repost"):
widgetUtils.connect_event(self.view.repost, widgetUtils.BUTTON_PRESSED, self.on_repost) widgetUtils.connect_event(self.view.repost, widgetUtils.BUTTON_PRESSED, self.on_repost)
self.view.comments.list.Bind(wx.EVT_LIST_ITEM_FOCUSED, self.on_focus)
if hasattr(self.view, "reply"):
widgetUtils.connect_event(self.view.reply, widgetUtils.BUTTON_PRESSED, self.on_reply)
# self.view.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.on_show_menu, self.view.comments.list) # self.view.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.on_show_menu, self.view.comments.list)
# self.view.Bind(wx.EVT_LIST_KEY_DOWN, self.on_show_menu_by_key, self.view.comments.list) # self.view.Bind(wx.EVT_LIST_KEY_DOWN, self.on_show_menu_by_key, self.view.comments.list)
pub.subscribe(self.set, self.modulename+"_set") pub.subscribe(self.set, self.modulename+"_set")
@ -63,12 +67,26 @@ class displayPostInteractor(base.baseInteractor):
pub.unsubscribe(self.enable_attachments, self.modulename+"_enable_attachments") pub.unsubscribe(self.enable_attachments, self.modulename+"_enable_attachments")
pub.unsubscribe(self.enable_photo_controls, self.modulename+"_enable_photo_controls") pub.unsubscribe(self.enable_photo_controls, self.modulename+"_enable_photo_controls")
def on_focus(self, *args, **kwargs):
item = self.view.comments.get_selected()
if item == -1:
self.view.reply.Enable(False)
else:
self.view.reply.Enable(True)
def on_like(self, *args, **kwargs): def on_like(self, *args, **kwargs):
self.presenter.post_like() self.presenter.post_like()
def on_repost(self, *args, **kwargs): def on_repost(self, *args, **kwargs):
self.presenter.post_repost() self.presenter.post_repost()
def on_reply(self, *args, **kwargs):
if hasattr(self.view, "repost"):
comment = self.view.comments.get_selected()
self.presenter.reply(comment)
else:
self.presenter.reply()
def on_add_comment(self, *args, **kwargs): def on_add_comment(self, *args, **kwargs):
self.presenter.add_comment() self.presenter.add_comment()

View File

@ -69,7 +69,7 @@ class displayPostPresenter(base.basePresenter):
""" Get comments and insert them in a list.""" """ Get comments and insert them in a list."""
user = self.post[self.user_identifier] user = self.post[self.user_identifier]
id = self.post[self.post_identifier] id = self.post[self.post_identifier]
self.comments = self.session.vk.client.wall.getComments(owner_id=user, post_id=id, need_likes=1, count=100, extended=1, preview_length=0) self.comments = self.session.vk.client.wall.getComments(owner_id=user, post_id=id, need_likes=1, count=100, extended=1, preview_length=0, thread_items_count=10)
comments_ = [] comments_ = []
for i in self.comments["items"]: for i in self.comments["items"]:
# If comment has a "deleted" key it should not be displayed, obviously. # If comment has a "deleted" key it should not be displayed, obviously.
@ -88,7 +88,8 @@ class displayPostPresenter(base.basePresenter):
original_date = arrow.get(i["date"]) original_date = arrow.get(i["date"])
created_at = original_date.humanize(locale=languageHandler.curLang[:2]) created_at = original_date.humanize(locale=languageHandler.curLang[:2])
likes = str(i["likes"]["count"]) likes = str(i["likes"]["count"])
comments_.append((from_, text, created_at, likes)) replies = str(i["thread"]["count"])
comments_.append((from_, text, created_at, likes, replies))
self.send_message("add_items", control="comments", items=comments_) self.send_message("add_items", control="comments", items=comments_)
def get_post_information(self): def get_post_information(self):
@ -226,7 +227,7 @@ class displayPostPresenter(base.basePresenter):
def post_repost(self): def post_repost(self):
object_id = "wall{0}_{1}".format(self.post[self.user_identifier], self.post[self.post_identifier]) object_id = "wall{0}_{1}".format(self.post[self.user_identifier], self.post[self.post_identifier])
p = createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.post(title=_("Repost"), message=_("Add your comment here"), text="", mode="comment")) p = createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createPostDialog(title=_("Repost"), message=_("Add your comment here"), text="", mode="comment"))
if hasattr(p, "text") or hasattr(p, "privacy"): if hasattr(p, "text") or hasattr(p, "privacy"):
msg = p.text msg = p.text
self.session.vk.client.wall.repost(object=object_id, message=msg) self.session.vk.client.wall.repost(object=object_id, message=msg)
@ -238,7 +239,7 @@ class displayPostPresenter(base.basePresenter):
self.send_message("set_label", control="shares", label=_("Shared {0} times").format(self.post["reposts"]["count"],)) self.send_message("set_label", control="shares", label=_("Shared {0} times").format(self.post["reposts"]["count"],))
def add_comment(self): def add_comment(self):
comment = createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.post(title=_("Add a comment"), message="", text="", mode="comment")) comment = createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createPostDialog(title=_("Add a comment"), message="", text="", mode="comment"))
if hasattr(comment, "text") or hasattr(comment, "privacy"): if hasattr(comment, "text") or hasattr(comment, "privacy"):
msg = comment.text msg = comment.text
try: try:
@ -252,12 +253,27 @@ class displayPostPresenter(base.basePresenter):
except Exception as msg: except Exception as msg:
log.error(msg) log.error(msg)
def reply(self, comment):
c = self.comments["items"][comment]
comment = createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createPostDialog(title=_("Reply to {username}").format(username=self.session.get_user_name(c["from_id"]),), message="", text="", mode="comment"))
if hasattr(comment, "text") or hasattr(comment, "privacy"):
msg = comment.text
try:
user = c["owner_id"]
reply_to_comment = c["id"]
post_id = c["post_id"]
r = self.session.vk.client.wall.createComment(owner_id=user, reply_to_user=user, post_id=post_id, message=msg, reply_to_comment=reply_to_comment, v=5.51)
output.speak(_("You've posted a comment"))
except IndexError as msg:
log.error(msg)
def clear_comments_list(self): def clear_comments_list(self):
self.send_message("clear_list", list="comments") self.send_message("clear_list", list="comments")
def show_comment(self, comment_index): def show_comment(self, comment_index):
c = self.comments["items"][comment_index] c = self.comments["items"][comment_index]
a = displayCommentPresenter(session=self.session, postObject=c, interactor=interactors.displayPostInteractor(), view=views.displayPost()) c["post_id"] = self.post[self.post_identifier]
a = displayCommentPresenter(session=self.session, postObject=c, interactor=interactors.displayPostInteractor(), view=views.displayComment())
def translate(self, text, language): def translate(self, text, language):
msg = translator.translator.translate(text, language) msg = translator.translator.translate(text, language)
@ -337,19 +353,18 @@ class displayCommentPresenter(displayPostPresenter):
def load_all_components(self): def load_all_components(self):
self.get_post_information() self.get_post_information()
self.get_likes() self.get_likes()
self.send_message("disable_control", control="shares")
self.send_message("disable_control", control="comment") self.send_message("disable_control", control="comment")
self.get_comments()
if self.post["likes"]["can_like"] == 0 and self.post["likes"]["user_likes"] == 0: if self.post["likes"]["can_like"] == 0 and self.post["likes"]["user_likes"] == 0:
self.send_message("disable_control", "like") self.send_message("disable_control", "like")
elif self.post["likes"]["user_likes"] == 1: elif self.post["likes"]["user_likes"] == 1:
self.send_message("set_label", control="like", label=_("&Dislike")) self.send_message("set_label", control="like", label=_("&Dislike"))
self.send_message("disable_control", control="repost")
def get_post_information(self): def get_post_information(self):
from_ = self.session.get_user_name(self.post[self.user_identifier]) from_ = self.session.get_user_name(self.post[self.user_identifier])
if ("from_id" in self.post and "owner_id" in self.post): if ("from_id" in self.post and "owner_id" in self.post):
# Translators: {0} will be replaced with the user who is posting, and {1} with the wall owner. # Translators: {0} will be replaced with the user who is posting, and {1} with the wall owner.
title = _("Post from {0} in the {1}'s post").format(self.session.get_user_name(self.post["from_id"]), self.session.get_user_name(self.post["owner_id"])) title = _("Comment from {0} in the {1}'s post").format(self.session.get_user_name(self.post["from_id"]), self.session.get_user_name(self.post["owner_id"]))
self.send_message("set_title", value=title) self.send_message("set_title", value=title)
message = "" message = ""
message = get_message(self.post) message = get_message(self.post)
@ -357,6 +372,48 @@ class displayCommentPresenter(displayPostPresenter):
self.get_attachments(self.post, message) self.get_attachments(self.post, message)
self.check_image_load() self.check_image_load()
def reply(self):
comment = createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createPostDialog(title=_("Reply to {username}").format(username=self.session.get_user_name(self.post["from_id"]),), message="", text="", mode="comment"))
if hasattr(comment, "text") or hasattr(comment, "privacy"):
msg = comment.text
try:
user = self.post["owner_id"]
reply_to_comment = self.post["id"]
post_id = self.post["post_id"]
r = self.session.vk.client.wall.createComment(owner_id=self.post["owner_id"], post_id=post_id, message=msg, reply_to_comment=reply_to_comment)
output.speak(_("You've posted a comment"))
except IndexError as msg:
log.error(msg)
def get_comments(self):
""" Get comments and insert them in a list."""
comments_ = []
for i in self.post["thread"]["items"]:
# If comment has a "deleted" key it should not be displayed, obviously.
if "deleted" in i:
continue
from_ = self.session.get_user_name(i["from_id"])
if "reply_to_user" in i:
extra_info = self.session.get_user_name(i["reply_to_user"])
from_ = _("{0} > {1}").format(from_, extra_info)
# As we set the comment reply properly in the from_ field, let's remove the first username from here if it exists.
fixed_text = re.sub("^\[id\d+\|\D+\], ", "", i["text"])
if len(fixed_text) > 140:
text = fixed_text[:141]
else:
text = fixed_text
original_date = arrow.get(i["date"])
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
likes = str(i["likes"]["count"])
replies = ""
comments_.append((from_, text, created_at, likes, replies))
self.send_message("add_items", control="comments", items=comments_)
def show_comment(self, comment_index):
c = self.post["thread"]["items"][comment_index]
c["post_id"] = self.post["post_id"]
a = displayCommentPresenter(session=self.session, postObject=c, interactor=interactors.displayPostInteractor(), view=views.displayComment())
class displayAudioPresenter(base.basePresenter): class displayAudioPresenter(base.basePresenter):
def __init__(self, session, postObject, view, interactor): def __init__(self, session, postObject, view, interactor):
super(displayAudioPresenter, self).__init__(view=view, interactor=interactor, modulename="display_audio") super(displayAudioPresenter, self).__init__(view=view, interactor=interactor, modulename="display_audio")

View File

@ -23,10 +23,13 @@ class displayBasicPost(widgetUtils.BaseDialog):
def create_comments_list(self): def create_comments_list(self):
lbl = wx.StaticText(self.panel, -1, _("Comments")) lbl = wx.StaticText(self.panel, -1, _("Comments"))
self.comments = widgetUtils.list(self.panel, _("User"), _("Comment"), _("Date"), _("Likes"), style=wx.LC_REPORT) self.comments = widgetUtils.list(self.panel, _("User"), _("Comment"), _("Date"), _("Likes"), _("replies"), style=wx.LC_REPORT)
self.reply = wx.Button(self.panel, -1, _("Reply to comment"))
self.reply.Enable(False)
box = wx.BoxSizer(wx.HORIZONTAL) box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(lbl, 0, wx.ALL, 5) box.Add(lbl, 0, wx.ALL, 5)
box.Add(self.comments.list, 0, wx.ALL, 5) box.Add(self.comments.list, 0, wx.ALL, 5)
box.Add(self.reply, 0, wx.ALL, 5)
return box return box
def create_attachments(self): def create_attachments(self):
@ -58,7 +61,6 @@ class displayBasicPost(widgetUtils.BaseDialog):
self.previous_photo.Enable(True) self.previous_photo.Enable(True)
self.next_photo.Enable(True) self.next_photo.Enable(True)
def create_likes_box(self): def create_likes_box(self):
self.likes = wx.Button(self.panel, -1, _("Loading data...")) self.likes = wx.Button(self.panel, -1, _("Loading data..."))
return self.likes return self.likes
@ -73,6 +75,7 @@ class displayBasicPost(widgetUtils.BaseDialog):
if comment: self.comment = wx.Button(self.panel, -1, _("Add comment")) if comment: self.comment = wx.Button(self.panel, -1, _("Add comment"))
box = wx.BoxSizer(wx.HORIZONTAL) box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(self.like, 0, wx.ALL, 5) box.Add(self.like, 0, wx.ALL, 5)
box.Add(self.repost, 0, wx.ALL, 5)
if comment: box.Add(self.comment, 0, wx.ALL, 5) if comment: box.Add(self.comment, 0, wx.ALL, 5)
return box return box
@ -137,15 +140,40 @@ class displayComment(displayBasicPost):
super(displayComment, self).__init__(*args, **kwargs) super(displayComment, self).__init__(*args, **kwargs)
post_view_box = self.create_post_view() post_view_box = self.create_post_view()
self.sizer.Add(post_view_box, 0, wx.ALL, 5) self.sizer.Add(post_view_box, 0, wx.ALL, 5)
attachments_box = self.create_attachments()
self.sizer.Add(attachments_box, 0, wx.ALL, 5)
self.attachments.list.Enable(False)
self.create_photo_viewer()
self.image.Enable(False)
self.create_tools_button() self.create_tools_button()
self.sizer.Add(self.tools, 0, wx.ALL, 5) self.sizer.Add(self.tools, 0, wx.ALL, 5)
likes_box = self.create_likes_box() likes_box = self.create_likes_box()
self.sizer.Add(likes_box, 0, wx.ALL, 5) self.sizer.Add(likes_box, 0, wx.ALL, 5)
actions_box = self.create_action_buttons(comment=False) actions_box = self.create_action_buttons()
self.sizer.Add(actions_box, 0, wx.ALL, 5) self.sizer.Add(actions_box, 0, wx.ALL, 5)
comments_box = self.create_comments_list()
self.sizer.Add(comments_box, 0, wx.ALL, 5)
self.sizer.Add(self.create_dialog_buttons()) self.sizer.Add(self.create_dialog_buttons())
self.done() self.done()
def create_comments_list(self):
lbl = wx.StaticText(self.panel, -1, _("Replies"))
self.comments = widgetUtils.list(self.panel, _("User"), _("Comment"), _("Date"), _("Likes"), _("Replies"), style=wx.LC_REPORT)
box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(lbl, 0, wx.ALL, 5)
box.Add(self.comments.list, 0, wx.ALL, 5)
return box
def create_action_buttons(self, comment=True):
self.like = wx.Button(self.panel, -1, _("&Like"))
self.reply = wx.Button(self.panel, -1, _("Reply to thread"))
if comment: self.comment = wx.Button(self.panel, -1, _("Add comment"))
box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(self.like, 0, wx.ALL, 5)
box.Add(self.reply, 0, wx.ALL, 5)
if comment: box.Add(self.comment, 0, wx.ALL, 5)
return box
class displayAudio(widgetUtils.BaseDialog): class displayAudio(widgetUtils.BaseDialog):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(displayAudio, self).__init__(parent=None, *args, **kwargs) super(displayAudio, self).__init__(parent=None, *args, **kwargs)