|
1 | 1 | extends layout
|
2 | 2 |
|
3 | 3 | block title
|
4 |
| - - import dubregistry.viewutils; |
5 |
| - - import dubregistry.web; |
6 |
| - - import vibe.data.json; |
7 |
| - - import std.algorithm.comparison : min; |
8 |
| - - import std.algorithm.iteration : map; |
9 |
| - - import std.string : replace, split; |
10 |
| - - title = "Find, Use and Share DUB Packages"; |
11 |
| - script(type="application/javascript", src="scripts/home.js") |
12 |
| - script(type="application/javascript"). |
13 |
| - window.categories = #{serializeToJson(info.categories).toString()}; |
| 4 | + - import dubregistry.viewutils; |
| 5 | + - import dubregistry.web; |
| 6 | + - import vibe.data.json; |
| 7 | + - import std.algorithm.comparison : min; |
| 8 | + - import std.algorithm.iteration : map; |
| 9 | + - import std.string : replace, split; |
| 10 | + - title = "Find, Use and Share DUB Packages"; |
| 11 | + script(type="application/javascript", src="scripts/home.js") |
| 12 | + script(type="application/javascript"). |
| 13 | + window.categories = #{serializeToJson(info.categories).toString()}; |
14 | 14 |
|
15 | 15 | block body
|
16 |
| - - auto category = req.query.get("category", null); |
17 |
| - - auto sort_mode = req.query.get("sort", "updated"); |
| 16 | + - auto category = req.query.get("category", null); |
| 17 | + - auto sort_mode = req.query.get("sort", "updated"); |
18 | 18 |
|
19 |
| - - string makeHomeURL(string sort, string category, ulong skip, ulong limit) { |
20 |
| - - import std.conv : to; |
21 |
| - - return "?sort=" ~ sort ~ "&category=" ~ category ~ "&skip=" ~ skip.to!string ~ "&limit=" ~ limit.to!string; |
22 |
| - - } |
| 19 | + - string makeHomeURL(string sort, string category, ulong skip, ulong limit) { |
| 20 | + - import std.conv : to; |
| 21 | + - return "?sort=" ~ sort ~ "&category=" ~ category ~ "&skip=" ~ skip.to!string ~ "&limit=" ~ limit.to!string; |
| 22 | + - } |
23 | 23 |
|
24 |
| - - auto mirror = req.params.get("mirror", ""); |
25 |
| - - if (mirror.length) |
26 |
| - p This is a mirror of #[a(href=mirror)= mirror]. |
27 |
| - - else |
28 |
| - p Welcome to DUB, the D package registry. The following list shows all available packages: |
29 |
| - //New Section |
| 24 | + - auto mirror = req.params.get("mirror", ""); |
| 25 | + - if (mirror.length) |
| 26 | + p This is a mirror of #[a(href=mirror)= mirror]. |
| 27 | + - else |
| 28 | + p Welcome to DUB, the D package registry. The following list shows all available packages: |
30 | 29 |
|
31 |
| - h2 📚 Commonly Used Libraries |
32 |
| - ul |
33 |
| - li |
34 |
| - a(href="https://vibed.org/") 🌐 vibe.d - A high-performance asynchronous I/O web framework |
35 |
| - li |
36 |
| - a(href="http://gtkd.org/") 🖥️ gtkd - GTK bindings for building GUI applications in D |
37 |
| - li |
38 |
| - a(href="https://github.com/BindBC") 🔗 bindbc - A collection of bindings for C libraries |
39 |
| - li |
40 |
| - a(href="https://github.com/dlang-community/gettext") 🌎 gettext - A library for handling internationalization |
| 30 | + //New Section |
| 31 | + h2 📚 Commonly Used Libraries |
| 32 | + ul |
| 33 | + li |
| 34 | + a(href="https://vibed.org/") 🌐 vibe.d - A high-performance asynchronous I/O web framework |
| 35 | + li |
| 36 | + a(href="http://gtkd.org/") 🖥️ gtkd - GTK bindings for building GUI applications in D |
| 37 | + li |
| 38 | + a(href="https://github.com/BindBC") 🔗 bindbc - A collection of bindings for C libraries |
| 39 | + li |
| 40 | + a(href="https://github.com/dlang-community/gettext") 🌎 gettext - A library for handling internationalization |
| 41 | + |
| 42 | + form#category-form(method="GET", action="") |
| 43 | + input(type="hidden", name="sort", value=sort_mode) |
| 44 | + input(type="hidden", name="limit", value=info.limit) |
| 45 | + p Select category: |
| 46 | + select#category(name="category", size="1", onChange='document.getElementById("category-form").submit()') |
| 47 | + - void outputCat(Category cat) |
| 48 | + - if (!cat) |
| 49 | + option(value="") All packages |
| 50 | + - else |
| 51 | + option(value=cat.name, selected=cat.name==category)= cat.indentedDescription |
| 52 | + - if (!cat || cat.subCategories.length) |
| 53 | + - foreach (c; cat ? cat.subCategories : info.categories) |
| 54 | + - outputCat(c); |
| 55 | + - outputCat(null); |
| 56 | + button#category-submit(type="submit") Update |
| 57 | + #category-dynamic-form(style="display: none") |
| 58 | + p Select category: |
| 59 | + - foreach (i; 0 .. 6) |
| 60 | + select(id="categories_#{i}", name="categories_#{i}", onChange='setCategoryFromSelector(#{i})') |
| 61 | + :javascript |
| 62 | + setupCategoryForm(); |
41 | 63 |
|
| 64 | + table |
42 | 65 |
|
43 |
| - form#category-form(method="GET", action="") |
44 |
| - input(type="hidden", name="sort", value=sort_mode) |
45 |
| - input(type="hidden", name="limit", value=info.limit) |
46 |
| - p Select category: |
47 |
| - select#category(name="category", size="1", onChange='document.getElementById("category-form").submit()') |
48 |
| - - void outputCat(Category cat) |
49 |
| - - if (!cat) |
50 |
| - option(value="") All packages |
51 |
| - - else |
52 |
| - option(value=cat.name, selected=cat.name==category)= cat.indentedDescription |
53 |
| - - if (!cat || cat.subCategories.length) |
54 |
| - - foreach (c; cat ? cat.subCategories : info.categories) |
55 |
| - - outputCat(c); |
56 |
| - - outputCat(null); |
57 |
| - button#category-submit(type="submit") Update |
58 |
| - #category-dynamic-form(style="display: none") |
59 |
| - p Select category: |
60 |
| - - foreach (i; 0 .. 6) |
61 |
| - select(id="categories_#{i}", name="categories_#{i}", onChange='setCategoryFromSelector(#{i})') |
62 |
| - :javascript |
63 |
| - setupCategoryForm(); |
| 66 | + - static immutable browse_kinds = ["name;Name", "updated;Last update", "score;Score", "added;Registered", ";Description"]; |
| 67 | + tr |
| 68 | + - foreach (i, c; browse_kinds) |
| 69 | + - auto cp = c.split(";"); |
| 70 | + - if (cp[0].length == 0) |
| 71 | + th= cp[1] |
| 72 | + - else if (sort_mode == cp[0]) |
| 73 | + th.selected= cp[1] |
| 74 | + - else |
| 75 | + th |
| 76 | + a(href=makeHomeURL(cp[0], category, info.skip, info.limit))= cp[1] |
64 | 77 |
|
65 |
| - table |
| 78 | + - foreach (pl; info.packages) |
| 79 | + - if( pl["versions"].length ) |
| 80 | + - auto vidx = getBestVersionIndex(pl["versions"].get!(Json[]).map!(v => v["version"].opt!string)); |
| 81 | + - auto p = pl["versions"][vidx]; |
| 82 | + - auto desc = p["description"].opt!string; |
| 83 | + - auto ver = p["version"].opt!string(); |
| 84 | + tr |
| 85 | + td |
| 86 | + - import std.string : startsWith; |
| 87 | + - string image, imageDescription; |
| 88 | + - bool isApplication; |
| 89 | + - if (pl["categories"].length) |
| 90 | + - foreach (category; pl["categories"]) |
| 91 | + - if (category.get!string.startsWith("application")) |
| 92 | + - isApplication = true; |
| 93 | + - break; |
| 94 | + - if (auto pc = pl["categories"][0].get!string in info.categoryMap) |
| 95 | + - image = pc.imageName; |
| 96 | + - imageDescription = pc.imageDescription; |
| 97 | + - if (!image.length) image = "unknown"; |
| 98 | + - if (!imageDescription.length) imageDescription = "unknown"; |
| 99 | + span(class="category-icon icon-category-#{image} #{isApplication ? `application` : ``}", title=imageDescription) |
| 100 | + a(href='packages/#{pl["name"].get!string}')= pl["name"].get!string |
| 101 | + td.nobreak |
| 102 | + - if (ver.length <= 20) |
| 103 | + |= ver |
| 104 | + - else |
| 105 | + | #{ver[0 .. 18]}… |
| 106 | + span.dull.nobreak(title=formatDateTime(p["date"]))<> , #{formatFuzzyDate(p["date"])} |
| 107 | + td.nobreak(title="#{formatPackageStats(pl.stats)}", style="color: #B03931;")!= formatScore(pl.stats.score) |
| 108 | + td.nobreak(title=formatDateTime(pl["dateAdded"]))= formatDate(pl["dateAdded"]) |
| 109 | + - if (desc.length <= 100) |
| 110 | + td= desc |
| 111 | + - else |
| 112 | + td #{desc[0 .. 98]}… |
66 | 113 |
|
67 |
| - - static immutable browse_kinds = ["name;Name", "updated;Last update", "score;Score", "added;Registered", ";Description"]; |
68 |
| - tr |
69 |
| - - foreach (i, c; browse_kinds) |
70 |
| - - auto cp = c.split(";"); |
71 |
| - - if (cp[0].length == 0) |
72 |
| - th= cp[1] |
73 |
| - - else if (sort_mode == cp[0]) |
74 |
| - th.selected= cp[1] |
75 |
| - - else |
76 |
| - th |
77 |
| - a(href=makeHomeURL(cp[0], category, info.skip, info.limit))= cp[1] |
| 114 | + ul.pageNav |
| 115 | + - foreach (i; 0 .. (info.packageCount + info.limit - 1) / info.limit) |
| 116 | + - if (i * info.limit == info.skip) |
| 117 | + li.selected= i+1 |
| 118 | + - else |
| 119 | + li: a(href=makeHomeURL(sort_mode, category, i*info.limit, info.limit))= i+1 |
| 120 | + ul.pageNav.perPage |
| 121 | + - static immutable limit_enum = [10, 20, 50, 100]; |
| 122 | + - foreach (limit; limit_enum) |
| 123 | + - if (info.limit == limit) |
| 124 | + li.selected= limit |
| 125 | + - else |
| 126 | + li: a(href=makeHomeURL(sort_mode, category, info.skip, limit))= limit |
78 | 127 |
|
79 |
| - - foreach (pl; info.packages) |
80 |
| - - if( pl["versions"].length ) |
81 |
| - - auto vidx = getBestVersionIndex(pl["versions"].get!(Json[]).map!(v => v["version"].opt!string)); |
82 |
| - - auto p = pl["versions"][vidx]; |
83 |
| - - auto desc = p["description"].opt!string; |
84 |
| - - auto ver = p["version"].opt!string(); |
85 |
| - tr |
86 |
| - td |
87 |
| - - import std.string : startsWith; |
88 |
| - - string image, imageDescription; |
89 |
| - - bool isApplication; |
90 |
| - - if (pl["categories"].length) |
91 |
| - - foreach (category; pl["categories"]) |
92 |
| - - if (category.get!string.startsWith("application")) |
93 |
| - - isApplication = true; |
94 |
| - - break; |
95 |
| - - if (auto pc = pl["categories"][0].get!string in info.categoryMap) |
96 |
| - - image = pc.imageName; |
97 |
| - - imageDescription = pc.imageDescription; |
98 |
| - - if (!image.length) image = "unknown"; |
99 |
| - - if (!imageDescription.length) imageDescription = "unknown"; |
100 |
| - span(class="category-icon icon-category-#{image} #{isApplication ? `application` : ``}", title=imageDescription) |
101 |
| - a(href='packages/#{pl["name"].get!string}')= pl["name"].get!string |
102 |
| - td.nobreak |
103 |
| - - if (ver.length <= 20) |
104 |
| - |= ver |
105 |
| - - else |
106 |
| - | #{ver[0 .. 18]}… |
107 |
| - span.dull.nobreak(title=formatDateTime(p["date"]))<> , #{formatFuzzyDate(p["date"])} |
108 |
| - td.nobreak(title="#{formatPackageStats(pl.stats)}", style="color: #B03931;")!= formatScore(pl.stats.score) |
109 |
| - td.nobreak(title=formatDateTime(pl["dateAdded"]))= formatDate(pl["dateAdded"]) |
110 |
| - - if (desc.length <= 100) |
111 |
| - td= desc |
112 |
| - - else |
113 |
| - td #{desc[0 .. 98]}… |
| 128 | + p Displaying results #{info.skip+1} to #{min(info.skip+info.limit, info.packageCount)} of #{info.packageCount} packages found. |
114 | 129 |
|
115 |
| - ul.pageNav |
116 |
| - - foreach (i; 0 .. (info.packageCount + info.limit - 1) / info.limit) |
117 |
| - - if (i * info.limit == info.skip) |
118 |
| - li.selected= i+1 |
119 |
| - - else |
120 |
| - li: a(href=makeHomeURL(sort_mode, category, i*info.limit, info.limit))= i+1 |
121 |
| - ul.pageNav.perPage |
122 |
| - - static immutable limit_enum = [10, 20, 50, 100]; |
123 |
| - - foreach (limit; limit_enum) |
124 |
| - - if (info.limit == limit) |
125 |
| - li.selected= limit |
126 |
| - - else |
127 |
| - li: a(href=makeHomeURL(sort_mode, category, info.skip, limit))= limit |
128 |
| - |
129 |
| - p Displaying results #{info.skip+1} to #{min(info.skip+info.limit, info.packageCount)} of #{info.packageCount} packages found. |
130 |
| - |
131 |
| - - if (!mirror.length) |
132 |
| - - if (req.session) |
133 |
| - p: a(href="my_packages") Manage my packages |
134 |
| - - else |
135 |
| - p Please #[a(href="login?redirect=/my_packages") log in] to manage your own packages. |
| 130 | + - if (!mirror.length) |
| 131 | + - if (req.session) |
| 132 | + p: a(href="my_packages") Manage my packages |
| 133 | + - else |
| 134 | + p Please #[a(href="login?redirect=/my_packages") log in] to manage your own packages. |
0 commit comments