Skip to content

Commit 7aa97b6

Browse files
authored
library: Add Language and Category filters (#967)
1 parent d02b1d1 commit 7aa97b6

3 files changed

Lines changed: 161 additions & 36 deletions

File tree

build-aux/wip/run.js

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -66,28 +66,30 @@ if (!exists(`${path}/.flatpak/repo`)) {
6666
}
6767

6868
if (!exists(`${path}/.flatpak/flatpak-builder`)) {
69-
const module_name = app_module.name;
70-
71-
const manifest_relative_path =
72-
Gio.File.new_for_path(path).get_relative_path(manifest_file);
73-
74-
const prefix = [
75-
"flatpak-builder",
76-
"--ccache",
77-
"--force-clean",
78-
"--disable-updates",
79-
];
80-
81-
const suffix = [
82-
`--state-dir=${path}/.flatpak/flatpak-builder`,
83-
`--stop-at=${module_name}`,
84-
`${path}/.flatpak/repo`,
85-
manifest_relative_path,
86-
];
69+
await downloadSources();
70+
await buildModules();
71+
}
8772

88-
// downloads sources (de-initializes)
73+
const prefix = [
74+
"flatpak-builder",
75+
"--ccache",
76+
"--force-clean",
77+
"--disable-updates",
78+
];
79+
const suffix = [
80+
`--state-dir=${path}/.flatpak/flatpak-builder`,
81+
`--stop-at=${app_module.name}`,
82+
`${path}/.flatpak/repo`,
83+
Gio.File.new_for_path(path).get_relative_path(manifest_file),
84+
];
85+
86+
// de-initializes
87+
async function downloadSources() {
8988
await run([...prefix, "--download-only", ...suffix]);
90-
// builds modules (de-initializes)
89+
}
90+
91+
// de-initializes
92+
async function buildModules() {
9193
await run([
9294
...prefix,
9395
"--disable-download",

src/Library/Library.blp

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,24 @@ Adw.Window window {
5050
]
5151
}
5252

53-
SearchEntry search_entry {
54-
search-delay: 100;
55-
placeholder-text: _("Search demos");
56-
activates-default: true;
57-
width-request: 400;
58-
margin-top: 32;
53+
Box {
54+
spacing: 6;
55+
56+
SearchEntry search_entry {
57+
search-delay: 100;
58+
placeholder-text: _("Search demos");
59+
activates-default: true;
60+
hexpand: true;
61+
margin-top: 32;
62+
}
63+
64+
DropDown dropdown_language {
65+
valign: end;
66+
}
67+
68+
DropDown dropdown_category {
69+
valign: end;
70+
}
5971
}
6072
}
6173

@@ -215,6 +227,28 @@ Adw.Window window {
215227
halign: center;
216228
margin-bottom: 24;
217229
margin-top: 12;
230+
orientation: vertical;
231+
232+
Box results_empty {
233+
orientation: vertical;
234+
visible: false;
235+
margin-top: 46;
236+
margin-bottom: 70;
237+
spacing: 6;
238+
239+
Label {
240+
label: _("No results");
241+
242+
styles [
243+
"title-4"
244+
]
245+
}
246+
247+
Button button_reset {
248+
label: _("Reset filters");
249+
halign: center;
250+
}
251+
}
218252

219253
Label {
220254
label: _("All examples are dedicated to the public domain\nand <b>can be used freely</b> under the terms of <a href=\"https://creativecommons.org/publicdomain/zero/1.0/\">CC0 1.0</a>");

src/Library/Library.js

Lines changed: 99 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Gio from "gi://Gio";
2+
import Gtk from "gi://Gtk";
23

34
import {
45
decode,
@@ -14,12 +15,21 @@ import { createSessionFromDemo } from "../sessions.js";
1415
import EntryRow from "./EntryRow.js";
1516

1617
import illustration from "./library.svg";
18+
import { gettext as _ } from "gettext";
1719

1820
import { build } from "../../troll/src/builder.js";
1921

2022
export default function Library({ application }) {
2123
const objects = build(resource);
22-
const { window, picture_illustration, search_entry } = objects;
24+
const {
25+
window,
26+
picture_illustration,
27+
search_entry,
28+
dropdown_category,
29+
dropdown_language,
30+
results_empty,
31+
button_reset,
32+
} = objects;
2333
window.application = application;
2434
picture_illustration.set_resource(illustration);
2535

@@ -34,7 +44,48 @@ export default function Library({ application }) {
3444
const demos = getDemos();
3545
const widgets_map = new Map();
3646
const category_map = new Map();
47+
48+
const language_model = new Gtk.StringList();
49+
language_model.append(_("Any Language"));
50+
dropdown_language.set_model(language_model);
51+
const language_check = [_("Any Language")];
52+
const language_labels = {
53+
javascript: _("JavaScript"),
54+
python: _("Python"),
55+
rust: _("Rust"),
56+
vala: _("Vala"),
57+
typescript: _("TypeScript"),
58+
};
59+
Object.values(language_labels).forEach((str) => language_model.push(str));
60+
61+
const category_model = new Gtk.StringList();
62+
category_model.append(_("Any Category"));
63+
dropdown_category.set_model(category_model);
64+
const category_check = [_("Any Category")];
65+
const category_labels = {
66+
uncategorized: _("Uncategorized"),
67+
tools: _("Tools"),
68+
network: _("Network"),
69+
controls: _("Controls"),
70+
layout: _("Layout"),
71+
feedback: _("Feedback"),
72+
navigation: _("Navigation"),
73+
user_interface: _("User Interface"),
74+
platform: _("Platform APIs"),
75+
};
76+
Object.values(category_labels).forEach((str) => category_model.push(str));
77+
3778
demos.forEach((demo) => {
79+
demo.languages.forEach((lang) => {
80+
if (!language_check.includes(lang)) {
81+
language_check.push(lang);
82+
}
83+
});
84+
85+
if (!category_check.includes(demo.category)) {
86+
category_check.push(demo.category);
87+
}
88+
3889
const entry_row = new EntryRow({ demo: demo });
3990
if (demo.name === "Welcome") last_triggered = entry_row;
4091

@@ -51,25 +102,63 @@ export default function Library({ application }) {
51102
category_map.set(demo.category, objects[`library_${demo.category}`]);
52103
}
53104
objects[`library_${demo.category}`].append(entry_row);
54-
widgets_map.set(demo.name, { entry_row, category: demo.category });
105+
widgets_map.set(demo.name, {
106+
entry_row,
107+
category_index: category_check.indexOf(demo.category),
108+
languages_index: demo.languages.map((lang) =>
109+
language_check.indexOf(lang),
110+
),
111+
});
55112
});
56113

57-
search_entry.connect("search-changed", () => {
114+
function updateList() {
115+
const current_category = dropdown_category.get_selected();
116+
const current_language = dropdown_language.get_selected();
117+
58118
const search_term = search_entry.get_text().toLowerCase();
59119
const visible_categories = new Set();
60-
61-
widgets_map.forEach(({ entry_row, category }, demo_name) => {
62-
const is_match = demo_name.toLowerCase().includes(search_term);
63-
entry_row.visible = is_match;
64-
if (is_match) visible_categories.add(category);
65-
});
120+
let results_found = false;
121+
widgets_map.forEach(
122+
({ entry_row, category_index, languages_index }, demo_name) => {
123+
const category_match =
124+
current_category === 0 || category_index === current_category;
125+
const language_match =
126+
current_language === 0 || languages_index.includes(current_language);
127+
const search_match = demo_name.toLowerCase().includes(search_term);
128+
const is_match =
129+
category_match &&
130+
language_match &&
131+
(search_term === "" || search_match);
132+
entry_row.visible = is_match;
133+
if (is_match) {
134+
results_found = true;
135+
visible_categories.add(category_check[category_index]);
136+
}
137+
},
138+
);
66139

67140
category_map.forEach((category_widget, category_name) => {
68141
const label = objects[`label_${category_name}`];
69-
if (label) label.visible = search_term === "";
142+
if (label)
143+
label.visible =
144+
current_category === 0 &&
145+
current_language === 0 &&
146+
search_term === "";
70147
category_widget.visible = visible_categories.has(category_name);
71148
});
149+
results_empty.set_visible(!results_found);
150+
}
151+
152+
search_entry.connect("search-changed", updateList);
153+
dropdown_category.connect("notify::selected", updateList);
154+
dropdown_language.connect("notify::selected", updateList);
155+
156+
button_reset.connect("clicked", () => {
157+
search_entry.text = "";
158+
dropdown_category.selected = 0;
159+
dropdown_language.selected = 0;
72160
});
161+
73162
const action_library = new Gio.SimpleAction({
74163
name: "library",
75164
parameter_type: null,

0 commit comments

Comments
 (0)