M melon/home/history.py => melon/home/history.py +50 -6
@@ 30,29 30,73 @@ class History(ViewStackPage):
status.set_child(box)
self.inner.set_child(status)
else:
- self.results = Adw.PreferencesPage()
+ self.wrapper = Gtk.Viewport()
+ self.results = Gtk.Box(orientation = Gtk.Orientation.VERTICAL)
title = Adw.PreferencesGroup()
title.set_title(_("History"))
title.set_description(_("These are the videos you opened in the past"))
- self.results.add(title)
- self.inner.set_child(self.results)
+ self.results.append(title)
+ self.wrapper.set_child(self.results)
+ self.inner.set_child(self.wrapper)
+ # unset load more button
+ # because it is no longer connected to this preferences page
+ self.next_ctr = None
self.load_page(0)
+ # keep track of the load more button
+ next_ctr = None
+ focus_node = None
def load_page(self, page=0):
+ self.focus_node = None
+ padding = 12
+ # add history entries
app_settings = get_app_settings()
for date, content in self.data[page*self.page_size:(page+1)*self.page_size]:
group = Adw.PreferencesGroup()
group.set_title(date)
- self.results.add(group)
+ self.results.append(group)
for resource in content:
group.add(AdaptiveFeedItem(resource, app_settings["show_images_in_feed"]))
- # TODO somehow add "load more" button
+ # because we aren't using a preferencepage
+ # we have to take care of padding ourselfs
+ group.set_margin_end(padding)
+ group.set_margin_start(padding)
+ group.set_margin_top(padding)
+ group.set_margin_bottom(padding)
+ # store first group
+ if self.focus_node is None:
+ self.focus_node = group
+ # remove old load more button
+ if not self.next_ctr is None:
+ self.results.remove(self.next_ctr)
+ # show Load more button if there are more entries
+ if len(self.data) > (page+1)*self.page_size:
+ self.next_ctr = Adw.PreferencesGroup()
+ btn = Adw.ActionRow()
+ btn.set_title(_("Show more"))
+ btn.set_subtitle(_("Load older videos"))
+ btn.add_suffix(Gtk.Image.new_from_icon_name("go-down-symbolic"))
+ btn.set_activatable(True)
+ btn.connect("activated", lambda _: self.load_page(page+1))
+ self.next_ctr.add(btn)
+ # because we aren't using a preferencepage
+ # we have to take care of padding ourselfs
+ self.next_ctr.set_margin_end(padding)
+ self.next_ctr.set_margin_start(padding)
+ self.next_ctr.set_margin_top(padding)
+ self.next_ctr.set_margin_bottom(padding)
+ self.results.append(self.next_ctr)
+ # if we added a new group
+ # auto scroll to it
+ # NOTE: we have to delay this, because everything has to be layout first
+ # and apparently GTK doesn't have an event for this
+ if not self.focus_node is None:
+ GLib.timeout_add(500, lambda: self.wrapper.scroll_to(self.focus_node))
def schedule(self):
app_settings = get_app_settings()
# make sure only videos from available servers are shown
hist = filter_resources(get_history(), app_settings, access=lambda x:x[0])
- hist.reverse()
GLib.idle_add(self.update, list(group_by_date(hist).items()))
thread = None
M melon/models/__init__.py => melon/models/__init__.py +1 -0
@@ 632,6 632,7 @@ def get_history():
SELECT timestamp, server, id, url, title, description, thumbnail, channel_id, channel_name
FROM history,videos
WHERE history.video_id = id AND history.video_server = server
+ ORDER BY timestamp DESC
""").fetchall()
return [ (Video(d[1], d[3], d[2], d[4], (d[8], d[7]), d[5], d[6]), d[0]) for d in results ]