diff options
context:
space:
mode:
Diffstat (limited to 'source/ui-refs.c')
-rw-r--r--source/ui-refs.c128
1 file changed, 114 insertions, 14 deletions
diff --git a/source/ui-refs.c b/source/ui-refs.c
index 500adfd..a38bfc4 100644
--- a/source/ui-refs.c
+++ b/source/ui-refs.c
@@ -145,23 +145,60 @@ static void print_refs_link(const char *path)
html("</td></tr>");
}
-void cgit_print_branches(int maxcount)
+/* Prev/next links for the dedicated branch and tag pages, so each
+ * category pages independently instead of sharing one endless page. */
+static void print_ref_pager(int ofs, int pagesize, int count, const char *path)
{
- struct reflist list;
- int i;
+ char *url;
+
+ html("<tr class='nohover'><td colspan='5' class='refs-pager'>");
+ if (ofs > 0) {
+ url = cgit_pageurl(ctx.qry.repo, fmt("refs/%s", path),
+ fmt("ofs=%d", ofs > pagesize ? ofs - pagesize : 0));
+ html("<a href='");
+ html_attr(url);
+ html("'>[prev]</a> ");
+ free(url);
+ }
+ htmlf("%d - %d of %d", ofs + 1,
+ ofs + pagesize < count ? ofs + pagesize : count, count);
+ if (ofs + pagesize < count) {
+ url = cgit_pageurl(ctx.qry.repo, fmt("refs/%s", path),
+ fmt("ofs=%d", ofs + pagesize));
+ html(" <a href='");
+ html_attr(url);
+ html("'>[next]</a>");
+ free(url);
+ }
+ html("</td></tr>");
+}
+static void collect_branches(struct reflist *list)
+{
+ list->refs = NULL;
+ list->alloc = list->count = 0;
+ refs_for_each_branch_ref(get_main_ref_store(the_repository),
+ cgit_refs_cb, list);
+ if (ctx.repo->enable_remote_branches)
+ refs_for_each_remote_ref(get_main_ref_store(the_repository),
+ cgit_refs_cb, list);
+}
+
+static void print_branch_header(void)
+{
html("<tr class='nohover'><th class='left'>Branch</th>"
"<th class='left'>Commit message</th>"
"<th class='left'>Author</th>"
"<th class='left' colspan='2'>Age</th></tr>\n");
+}
- list.refs = NULL;
- list.alloc = list.count = 0;
- refs_for_each_branch_ref(get_main_ref_store(the_repository),
- cgit_refs_cb, &list);
- if (ctx.repo->enable_remote_branches)
- refs_for_each_remote_ref(get_main_ref_store(the_repository),
- cgit_refs_cb, &list);
+void cgit_print_branches(int maxcount)
+{
+ struct reflist list;
+ int i;
+
+ print_branch_header();
+ collect_branches(&list);
if (maxcount == 0 || maxcount > list.count)
maxcount = list.count;
@@ -205,19 +242,82 @@ void cgit_print_tags(int maxcount)
cgit_free_reflist_inner(&list);
}
+/* The dedicated branch page lists everything, a page at a time. The
+ * whole list is name-sorted (or age-sorted per branch-sort) so the
+ * order is stable across pages. */
+static void print_branches_page(int pagesize)
+{
+ struct reflist list;
+ int i, ofs, end;
+
+ print_branch_header();
+ collect_branches(&list);
+
+ qsort(list.refs, list.count, sizeof(*list.refs), cmp_branch_age);
+ if (ctx.repo->branch_sort == 0)
+ qsort(list.refs, list.count, sizeof(*list.refs), cmp_ref_name);
+
+ if (pagesize <= 0 || pagesize > list.count)
+ pagesize = list.count;
+ ofs = ctx.qry.ofs > 0 ? ctx.qry.ofs : 0;
+ if (ofs > list.count)
+ ofs = list.count;
+ end = ofs + pagesize < list.count ? ofs + pagesize : list.count;
+
+ for (i = ofs; i < end; i++)
+ print_branch(list.refs[i]);
+
+ if (pagesize < list.count)
+ print_ref_pager(ofs, pagesize, list.count, "heads");
+
+ cgit_free_reflist_inner(&list);
+}
+
+static void print_tags_page(int pagesize)
+{
+ struct reflist list;
+ int i, ofs, end;
+
+ list.refs = NULL;
+ list.alloc = list.count = 0;
+ refs_for_each_tag_ref(get_main_ref_store(the_repository),
+ cgit_refs_cb, &list);
+ if (list.count == 0)
+ return;
+ qsort(list.refs, list.count, sizeof(*list.refs), cmp_tag_age);
+
+ if (pagesize <= 0 || pagesize > list.count)
+ pagesize = list.count;
+ ofs = ctx.qry.ofs > 0 ? ctx.qry.ofs : 0;
+ if (ofs > list.count)
+ ofs = list.count;
+ end = ofs + pagesize < list.count ? ofs + pagesize : list.count;
+
+ print_tag_header();
+ for (i = ofs; i < end; i++)
+ print_tag(list.refs[i]);
+
+ if (pagesize < list.count)
+ print_ref_pager(ofs, pagesize, list.count, "tags");
+
+ cgit_free_reflist_inner(&list);
+}
+
void cgit_print_refs(void)
{
cgit_print_layout_start();
html("<table class='list nowrap'>");
if (ctx.qry.path && starts_with(ctx.qry.path, "heads"))
- cgit_print_branches(0);
+ print_branches_page(ctx.cfg.max_ref_count);
else if (ctx.qry.path && starts_with(ctx.qry.path, "tags"))
- cgit_print_tags(0);
+ print_tags_page(ctx.cfg.max_ref_count);
else {
- cgit_print_branches(0);
+ /* The combined page caps each section, with the [...] rows
+ * leading to the dedicated pages above. */
+ cgit_print_branches(ctx.cfg.max_ref_count);
html("<tr class='nohover'><td colspan='5'>&nbsp;</td></tr>");
- cgit_print_tags(0);
+ cgit_print_tags(ctx.cfg.max_ref_count);
}
html("</table>");
cgit_print_layout_end();