Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

library: Add Language and Category filters #967

Merged
merged 9 commits into from
Sep 23, 2024
12 changes: 12 additions & 0 deletions src/Library/Library.blp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@ Adw.Window window {
}
}

Box {
DropDown dropdown_language {
BharatAtbrat marked this conversation as resolved.
Show resolved Hide resolved
halign: end;
margin-end: 12;
hexpand: true;
}

DropDown dropdown_category {
halign: end;
}
}

ListBox library_uncategorized {
BharatAtbrat marked this conversation as resolved.
Show resolved Hide resolved
selection-mode: none;

Expand Down
85 changes: 76 additions & 9 deletions src/Library/Library.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import Gio from "gi://Gio";
import Gtk from "gi://Gtk";

import {
decode,
demos_dir,
getLanguage,
makeDropdownFlat,
settings as global_settings,
quitOnLastWindowClose,
} from "../util.js";
Expand All @@ -19,22 +21,51 @@ import { build } from "../../troll/src/builder.js";

export default function Library({ application }) {
const objects = build(resource);
const { window, picture_illustration, search_entry } = objects;
const {
window,
picture_illustration,
search_entry,
dropdown_category,
dropdown_language,
} = objects;
window.application = application;
picture_illustration.set_resource(illustration);
makeDropdownFlat(dropdown_category);
makeDropdownFlat(dropdown_language);

if (__DEV__) {
window.add_css_class("devel");
}

let last_triggered;
let current_category = 0;
let current_language = 0;

window.connect("close-request", quitOnLastWindowClose);

const demos = getDemos();
const widgets_map = new Map();
const category_map = new Map();
const language_model = new Gtk.StringList();
const category_model = new Gtk.StringList();
language_model.append("All Languages");
category_model.append("All Categories");
const language_check = ["All Languages"];
const category_check = ["All Categories"];
BharatAtbrat marked this conversation as resolved.
Show resolved Hide resolved
BharatAtbrat marked this conversation as resolved.
Show resolved Hide resolved

demos.forEach((demo) => {
demo.languages.forEach((lang) => {
if (!language_check.includes(lang)) {
language_check.push(lang);
language_model.append(lang);
}
});

if (!category_check.includes(demo.category)) {
category_check.push(demo.category);
category_model.append(demo.category);
}

const entry_row = new EntryRow({ demo: demo });
if (demo.name === "Welcome") last_triggered = entry_row;

Expand All @@ -51,25 +82,61 @@ export default function Library({ application }) {
category_map.set(demo.category, objects[`library_${demo.category}`]);
}
objects[`library_${demo.category}`].append(entry_row);
widgets_map.set(demo.name, { entry_row, category: demo.category });
widgets_map.set(demo.name, {
entry_row,
category_index: category_check.indexOf(demo.category),
languages_index: demo.languages.map((lang) =>
language_check.indexOf(lang),
),
});
});

search_entry.connect("search-changed", () => {
dropdown_language.set_model(language_model);
dropdown_category.set_model(category_model);

function updateList() {
const search_term = search_entry.get_text().toLowerCase();
const visible_categories = new Set();

widgets_map.forEach(({ entry_row, category }, demo_name) => {
const is_match = demo_name.toLowerCase().includes(search_term);
entry_row.visible = is_match;
if (is_match) visible_categories.add(category);
});
widgets_map.forEach(
({ entry_row, category_index, languages_index }, demo_name) => {
const category_match =
current_category === 0 || category_index === current_category;
const language_match =
current_language === 0 || languages_index.includes(current_language);
const search_match = demo_name.toLowerCase().includes(search_term);
const is_match =
category_match &&
language_match &&
(search_term === "" || search_match);
entry_row.visible = is_match;
if (is_match) visible_categories.add(category_check[category_index]);
},
);

category_map.forEach((category_widget, category_name) => {
const label = objects[`label_${category_name}`];
if (label) label.visible = search_term === "";
if (label)
label.visible =
current_category === 0 &&
current_language === 0 &&
search_term === "";
category_widget.visible = visible_categories.has(category_name);
});
}

search_entry.connect("search-changed", updateList);

dropdown_category.connect("notify::selected", () => {
current_category = dropdown_category.get_selected();
updateList();
});

dropdown_language.connect("notify::selected", () => {
current_language = dropdown_language.get_selected();
updateList();
});

const action_library = new Gio.SimpleAction({
name: "library",
parameter_type: null,
Expand Down
Loading