wire basic post functions
This commit is contained in:
parent
df9e836886
commit
1d2a7de3a5
3 changed files with 122 additions and 6 deletions
|
@ -14,7 +14,7 @@ A nut obsessed saber-toothed client for pnut.io
|
||||||
- [x] Menu (about, refresh, logout)
|
- [x] Menu (about, refresh, logout)
|
||||||
- [x] Keyboard shortcuts
|
- [x] Keyboard shortcuts
|
||||||
- [x] Avatars
|
- [x] Avatars
|
||||||
- [ ] Post actions (reply, bookmark, repost, quote, copy, delete)
|
- [x] Post actions (reply, bookmark, repost, quote, copy, delete)
|
||||||
- [ ] Loading indicator
|
- [ ] Loading indicator
|
||||||
- [ ] Load newer posts
|
- [ ] Load newer posts
|
||||||
- [ ] Load older posts
|
- [ ] Load older posts
|
||||||
|
|
10
src/main.py
10
src/main.py
|
@ -149,15 +149,19 @@ class Application(Gtk.Application):
|
||||||
|
|
||||||
# TODO: find better icons
|
# TODO: find better icons
|
||||||
unified = Timeline('unified')
|
unified = Timeline('unified')
|
||||||
|
unified.connect('reply', self.on_reply_post)
|
||||||
self.stack.add_titled(unified, "unified", "Timeline")
|
self.stack.add_titled(unified, "unified", "Timeline")
|
||||||
self.stack.child_set_property(unified, "icon-name", "user-home-symbolic")
|
self.stack.child_set_property(unified, "icon-name", "user-home-symbolic")
|
||||||
mentions = Timeline('mentions')
|
mentions = Timeline('mentions')
|
||||||
|
mentions.connect('reply', self.on_reply_post)
|
||||||
self.stack.add_titled(mentions, "mentions", "Mentions")
|
self.stack.add_titled(mentions, "mentions", "Mentions")
|
||||||
self.stack.child_set_property(mentions, "icon-name", "goa-panel-symbolic")
|
self.stack.child_set_property(mentions, "icon-name", "goa-panel-symbolic")
|
||||||
bookmarks = Timeline('bookmarks')
|
bookmarks = Timeline('bookmarks')
|
||||||
|
bookmarks.connect('reply', self.on_reply_post)
|
||||||
self.stack.add_titled(bookmarks, "bookmarks", "Bookmarks")
|
self.stack.add_titled(bookmarks, "bookmarks", "Bookmarks")
|
||||||
self.stack.child_set_property(bookmarks, "icon-name", "user-bookmarks-symbolic")
|
self.stack.child_set_property(bookmarks, "icon-name", "user-bookmarks-symbolic")
|
||||||
global_tl = Timeline('global')
|
global_tl = Timeline('global')
|
||||||
|
global_tl.connect('reply', self.on_reply_post)
|
||||||
self.stack.add_titled(global_tl, "global", "Global")
|
self.stack.add_titled(global_tl, "global", "Global")
|
||||||
self.stack.child_set_property(global_tl, "icon-name", "network-workgroup-symbolic")
|
self.stack.child_set_property(global_tl, "icon-name", "network-workgroup-symbolic")
|
||||||
|
|
||||||
|
@ -179,6 +183,12 @@ class Application(Gtk.Application):
|
||||||
compose = ComposeWindow()
|
compose = ComposeWindow()
|
||||||
compose.set_transient_for(self.win)
|
compose.set_transient_for(self.win)
|
||||||
|
|
||||||
|
def on_reply_post(self, widget, post_id, text):
|
||||||
|
compose = ComposeWindow()
|
||||||
|
compose.set_post(text)
|
||||||
|
compose.set_reply_to(post_id)
|
||||||
|
compose.set_transient_for(self.win)
|
||||||
|
|
||||||
def on_main_popover(self, button):
|
def on_main_popover(self, button):
|
||||||
self.main_popover.popup()
|
self.main_popover.popup()
|
||||||
|
|
||||||
|
|
116
src/widgets.py
116
src/widgets.py
|
@ -27,7 +27,7 @@ from dateutil.tz import tzlocal
|
||||||
gi.require_version('GdkPixbuf', '2.0')
|
gi.require_version('GdkPixbuf', '2.0')
|
||||||
gi.require_version('Gdk', '3.0')
|
gi.require_version('Gdk', '3.0')
|
||||||
gi.require_version('Gtk', '3.0')
|
gi.require_version('Gtk', '3.0')
|
||||||
from gi.repository import GObject, GdkPixbuf, Gdk, Gtk
|
from gi.repository import GObject, GdkPixbuf, Gdk, Gtk, Gio
|
||||||
|
|
||||||
gi.require_version('Handy', '1')
|
gi.require_version('Handy', '1')
|
||||||
from gi.repository import Handy
|
from gi.repository import Handy
|
||||||
|
@ -39,6 +39,8 @@ class ComposeWindow(Handy.Window):
|
||||||
self.set_default_size(500, 300)
|
self.set_default_size(500, 300)
|
||||||
self.set_type_hint(Gdk.WindowTypeHint.DIALOG)
|
self.set_type_hint(Gdk.WindowTypeHint.DIALOG)
|
||||||
|
|
||||||
|
self.reply_to = None
|
||||||
|
|
||||||
box = Gtk.Box(orientation='vertical')
|
box = Gtk.Box(orientation='vertical')
|
||||||
header = Handy.HeaderBar(show_close_button=False)
|
header = Handy.HeaderBar(show_close_button=False)
|
||||||
|
|
||||||
|
@ -94,11 +96,20 @@ class ComposeWindow(Handy.Window):
|
||||||
self.counter = self.max_length - self.buffer.get_char_count()
|
self.counter = self.max_length - self.buffer.get_char_count()
|
||||||
self.counter_label.set_text(str(self.counter))
|
self.counter_label.set_text(str(self.counter))
|
||||||
|
|
||||||
|
def set_post(self, text):
|
||||||
|
self.buffer.set_text(text, -1)
|
||||||
|
|
||||||
|
def set_reply_to(self, reply_to):
|
||||||
|
self.reply_to = reply_to
|
||||||
|
|
||||||
def send_post(self, button):
|
def send_post(self, button):
|
||||||
start = self.buffer.get_start_iter()
|
start = self.buffer.get_start_iter()
|
||||||
end = self.buffer.get_end_iter()
|
end = self.buffer.get_end_iter()
|
||||||
text = self.buffer.get_text(start, end, False)
|
text = self.buffer.get_text(start, end, False)
|
||||||
pnutpy.api.create_post(data={'text': text})
|
data = {'text': text}
|
||||||
|
if self.reply_to is not None:
|
||||||
|
data['reply_to'] = self.reply_to
|
||||||
|
pnutpy.api.create_post(data=data)
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
def cancel_post(self, button):
|
def cancel_post(self, button):
|
||||||
|
@ -175,12 +186,15 @@ class LoginPage(Gtk.Box):
|
||||||
class Timeline(Gtk.Box):
|
class Timeline(Gtk.Box):
|
||||||
|
|
||||||
__gsignals__ = {
|
__gsignals__ = {
|
||||||
'refresh': (GObject.SIGNAL_RUN_FIRST, None, ())
|
'refresh': (GObject.SIGNAL_RUN_FIRST, None, ()),
|
||||||
|
'reply': (GObject.SIGNAL_RUN_FIRST, None, (int,str,))
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, stream):
|
def __init__(self, stream):
|
||||||
super().__init__(orientation='vertical')
|
super().__init__(orientation='vertical')
|
||||||
|
|
||||||
|
self.clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
|
||||||
|
|
||||||
scroller = Gtk.ScrolledWindow(
|
scroller = Gtk.ScrolledWindow(
|
||||||
halign='fill',
|
halign='fill',
|
||||||
kinetic_scrolling=True
|
kinetic_scrolling=True
|
||||||
|
@ -194,6 +208,39 @@ class Timeline(Gtk.Box):
|
||||||
self.stream = stream
|
self.stream = stream
|
||||||
self.load_timeline()
|
self.load_timeline()
|
||||||
|
|
||||||
|
self.view.connect('button-press-event', self.on_button_pressed)
|
||||||
|
|
||||||
|
action_group = Gio.SimpleActionGroup()
|
||||||
|
|
||||||
|
action = Gio.SimpleAction.new('reply', None)
|
||||||
|
action.connect('activate', self.on_reply)
|
||||||
|
action_group.add_action(action)
|
||||||
|
|
||||||
|
action = Gio.SimpleAction.new('replyall', None)
|
||||||
|
action.connect('activate', self.on_reply_all)
|
||||||
|
action_group.add_action(action)
|
||||||
|
|
||||||
|
action = Gio.SimpleAction.new('bookmark', None)
|
||||||
|
action.connect('activate', self.on_bookmark)
|
||||||
|
action_group.add_action(action)
|
||||||
|
|
||||||
|
action = Gio.SimpleAction.new('repost', None)
|
||||||
|
action.connect('activate', self.on_repost)
|
||||||
|
action_group.add_action(action)
|
||||||
|
|
||||||
|
action = Gio.SimpleAction.new('quote', None)
|
||||||
|
action.connect('activate', self.on_quote)
|
||||||
|
action_group.add_action(action)
|
||||||
|
|
||||||
|
action = Gio.SimpleAction.new('copy', None)
|
||||||
|
action.connect('activate', self.on_copy)
|
||||||
|
action_group.add_action(action)
|
||||||
|
|
||||||
|
self.insert_action_group('win', action_group)
|
||||||
|
|
||||||
|
builder = Gtk.Builder.new_from_resource("/dev/thrrgilag/squeak/menu.ui")
|
||||||
|
self.menu = builder.get_object("post-menu")
|
||||||
|
|
||||||
def load_timeline(self):
|
def load_timeline(self):
|
||||||
if self.stream == 'unified':
|
if self.stream == 'unified':
|
||||||
posts, meta = pnutpy.api.users_post_streams_unified(include_raw=1)
|
posts, meta = pnutpy.api.users_post_streams_unified(include_raw=1)
|
||||||
|
@ -207,7 +254,9 @@ class Timeline(Gtk.Box):
|
||||||
for item in posts:
|
for item in posts:
|
||||||
if 'is_deleted' in item:
|
if 'is_deleted' in item:
|
||||||
continue
|
continue
|
||||||
self.view.add(PostItem(item))
|
postitem = PostItem(item)
|
||||||
|
postitem.connect('menu-pressed', self.show_menu)
|
||||||
|
self.view.add(postitem)
|
||||||
|
|
||||||
def do_refresh(self):
|
def do_refresh(self):
|
||||||
rows = self.view.get_children()
|
rows = self.view.get_children()
|
||||||
|
@ -216,8 +265,55 @@ class Timeline(Gtk.Box):
|
||||||
self.load_timeline()
|
self.load_timeline()
|
||||||
self.show_all()
|
self.show_all()
|
||||||
|
|
||||||
|
def on_button_pressed(self, widget, event):
|
||||||
|
logging.debug("-blarp-")
|
||||||
|
if event.type == Gdk.EventType.BUTTON_PRESS and event.button == 3:
|
||||||
|
logging.debug("-blarp- right button")
|
||||||
|
|
||||||
|
def show_menu(self, widget, index):
|
||||||
|
self.post_index = index
|
||||||
|
self.post_data = widget.post
|
||||||
|
popover = Gtk.Popover()
|
||||||
|
popover.set_position(Gtk.PositionType.BOTTOM)
|
||||||
|
popover.set_relative_to(widget.menu_button)
|
||||||
|
popover.bind_model(self.menu, None)
|
||||||
|
popover.popup()
|
||||||
|
|
||||||
|
def on_reply(self, action, param):
|
||||||
|
replyuser = "@" + self.post_data.user.username + " "
|
||||||
|
self.emit('reply', self.post_data.id, replyuser)
|
||||||
|
|
||||||
|
def on_reply_all(self, action, param):
|
||||||
|
replyuser = "@" + self.post_data.user.username + " "
|
||||||
|
self.emit('reply', self.post_data.id, replyuser)
|
||||||
|
|
||||||
|
def on_bookmark(self, action, param):
|
||||||
|
if self.post_data.you_bookmarked:
|
||||||
|
pnutpy.api.unbookmark_post(self.post_data.id)
|
||||||
|
else:
|
||||||
|
pnutpy.api.bookmark_post(self.post_data.id)
|
||||||
|
|
||||||
|
def on_repost(self, action, param):
|
||||||
|
if self.post_data.you_bookmarked:
|
||||||
|
pnutpy.api.unrepost_post(self.post_data.id)
|
||||||
|
else:
|
||||||
|
pnutpy.api.repost_post(self.post_data.id)
|
||||||
|
|
||||||
|
def on_quote(self, action, param):
|
||||||
|
quote = " >> @" + self.post_data.user.username + ": "
|
||||||
|
quote += self.post_data.content.text
|
||||||
|
logging.debug(quote)
|
||||||
|
self.emit('reply', self.post_data.id, quote)
|
||||||
|
|
||||||
|
def on_copy(self, action, param):
|
||||||
|
self.clipboard.set_text(self.post_data.content.text, -1)
|
||||||
|
|
||||||
class PostItem(Gtk.ListBoxRow):
|
class PostItem(Gtk.ListBoxRow):
|
||||||
|
|
||||||
|
__gsignals__ = {
|
||||||
|
'menu-pressed': (GObject.SIGNAL_RUN_FIRST, None, (int,))
|
||||||
|
}
|
||||||
|
|
||||||
def __init__(self, post):
|
def __init__(self, post):
|
||||||
super(Gtk.ListBoxRow, self).__init__()
|
super(Gtk.ListBoxRow, self).__init__()
|
||||||
self.post = post
|
self.post = post
|
||||||
|
@ -225,6 +321,10 @@ class PostItem(Gtk.ListBoxRow):
|
||||||
self.box = Gtk.Box(orientation='vertical')
|
self.box = Gtk.Box(orientation='vertical')
|
||||||
self.add(self.box)
|
self.add(self.box)
|
||||||
|
|
||||||
|
# post menu
|
||||||
|
self.menu_button = Gtk.Button.new_from_icon_name('view-more-symbolic', 1)
|
||||||
|
self.menu_button.connect('clicked', self.show_menu)
|
||||||
|
|
||||||
# name container
|
# name container
|
||||||
self.name_box = Gtk.Box(orientation='vertical')
|
self.name_box = Gtk.Box(orientation='vertical')
|
||||||
self.username = Gtk.Label(label="@" + post.user.username, xalign=0)
|
self.username = Gtk.Label(label="@" + post.user.username, xalign=0)
|
||||||
|
@ -265,11 +365,14 @@ class PostItem(Gtk.ListBoxRow):
|
||||||
|
|
||||||
# footer container
|
# footer container
|
||||||
self.f_box = Gtk.Box(orientation='horizontal')
|
self.f_box = Gtk.Box(orientation='horizontal')
|
||||||
|
self.f_box.pack_end(self.menu_button, False, False, 10)
|
||||||
|
|
||||||
|
# datetime
|
||||||
post_date_local = post.created_at.astimezone(tzlocal())
|
post_date_local = post.created_at.astimezone(tzlocal())
|
||||||
datetime_label = Gtk.Label(label=post_date_local.strftime("%Y-%m-%d %H:%M"), xalign=1)
|
datetime_label = Gtk.Label(label=post_date_local.strftime("%Y-%m-%d %H:%M"), xalign=1)
|
||||||
self.f_box.pack_end(datetime_label, False, False, 10)
|
self.f_box.pack_end(datetime_label, False, False, 10)
|
||||||
pad = Gtk.Label(label="")
|
pad = Gtk.Label(label="")
|
||||||
self.f_box.pack_start(pad, False, False, 10)
|
self.f_box.pack_start(pad, False, False, 5)
|
||||||
|
|
||||||
if post.id != int(post.thread_id):
|
if post.id != int(post.thread_id):
|
||||||
thread_icon = Gtk.Image.new_from_icon_name("user-available-symbolic", Gtk.IconSize.SMALL_TOOLBAR)
|
thread_icon = Gtk.Image.new_from_icon_name("user-available-symbolic", Gtk.IconSize.SMALL_TOOLBAR)
|
||||||
|
@ -315,3 +418,6 @@ class PostItem(Gtk.ListBoxRow):
|
||||||
pixbuf = loader.get_pixbuf()
|
pixbuf = loader.get_pixbuf()
|
||||||
return pixbuf.scale_simple(256,new_height,GdkPixbuf.InterpType.BILINEAR)
|
return pixbuf.scale_simple(256,new_height,GdkPixbuf.InterpType.BILINEAR)
|
||||||
|
|
||||||
|
def show_menu(self, widget):
|
||||||
|
self.emit('menu-pressed', self.get_index())
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue