PageSourceSearch

https://lesefluss.app/app/assets/sort-filter-Ccbwe_Q4.js

js lesefluss.app collected 2026-10-02 01:17:26 UTC 3,543 bytes, 103 lines download raw bytes

1import { ap as parseBookTags, av as BOOK_STATUS_LABELS, cC as bookStatus, aG as readingProgress } from "./index-CPwKESzR.js";
2const SORT_LABELS = {
3  title: "Title",
4  author: "Author",
5  recent: "Recent",
6  progress: "Progress",
7  rating: "Rating"
8};
9const FILTER_LABELS = { all: "All", ...BOOK_STATUS_LABELS };
10const FILTER_OPTIONS = ["all", "want", "reading", "finished", "dropped"];
11const SORT_OPTIONS = ["recent", "title", "author", "progress", "rating"];
12const FINISHED_TAIL_WORDS = 5;
13function isBookFinished(book) {
14  if (book.wordCount <= 0) return false;
15  return book.wordPosition >= book.wordCount - FINISHED_TAIL_WORDS;
16}
17function seriesProgress(activity) {
18  if (!activity || activity.total === 0) return 0;
19  return Math.min(100, Math.round(activity.finished / activity.total * 100));
20}
21function seriesRecency(s, activity) {
22  return activity?.latestRead ?? s.createdAt;
23}
24function seriesStatus(activity) {
25  if (!activity || activity.total === 0) return "want";
26  if (activity.finished >= activity.total) return "finished";
27  return activity.started > 0 ? "reading" : "want";
28}
29function bookSortKey(b) {
30  return {
31    title: b.title,
32    author: b.author ?? "",
33    recency: b.lastRead ?? b.addedAt,
34    progress: readingProgress(b),
35    status: bookStatus(b),
36    rating: b.rating,
37    tags: parseBookTags(b.tags)
38  };
39}
40function seriesSortKey(s, activity) {
41  return {
42    title: s.title,
43    author: s.author ?? "",
44    recency: seriesRecency(s, activity),
45    progress: seriesProgress(activity),
46    status: seriesStatus(activity),
47    rating: null,
48    // Series carry no tags of their own; a tag filter therefore hides them,
49    // which is right: they cannot match it.
50    tags: []
51  };
52}
53function matchesFilter(item, filterBy) {
54  return filterBy === "all" || item.sortKey.status === filterBy;
55}
56function matchesSearch(item, needle) {
57  if (!needle) return true;
58  const { title, author } = item.sortKey;
59  return `${title} ${author}`.toLowerCase().includes(needle);
60}
61function tagsInUse(books) {
62  const seen = /* @__PURE__ */ new Set();
63  for (const book of books) {
64    for (const tag of parseBookTags(book.tags)) seen.add(tag);
65  }
66  return [...seen].sort((a, b) => a.localeCompare(b));
67}
68function compareItems(a, b, sortBy) {
69  switch (sortBy) {
70    case "title":
71      return a.sortKey.title.localeCompare(b.sortKey.title);
72    case "author":
73      return a.sortKey.author.localeCompare(b.sortKey.author);
74    case "recent":
75      return b.sortKey.recency - a.sortKey.recency;
76    case "progress":
77      return b.sortKey.progress - a.sortKey.progress;
78    // Unrated sorts below one star rather than above five.
79    case "rating":
80      return (b.sortKey.rating ?? -1) - (a.sortKey.rating ?? -1);
81  }
82}
83function filterAndSortLibrary(books, series, activity, view) {
84  const { filterBy, sortBy, search = "", tag = null } = view;
85  const needle = search.trim().toLowerCase();
86  const items = [
87    ...books.map((book) => ({ kind: "book", book, sortKey: bookSortKey(book) })),
88    ...series.map((s) => {
89      const a = activity.get(s.id);
90      return { kind: "series", series: s, activity: a, sortKey: seriesSortKey(s, a) };
91    })
92  ];
93  return items.filter((it) => matchesFilter(it, filterBy)).filter((it) => matchesSearch(it, needle)).filter((it) => tag === null || it.sortKey.tags.includes(tag)).sort((a, b) => compareItems(a, b, sortBy));
94}
95export {
96  FILTER_LABELS as F,
97  SORT_LABELS as S,
98  FILTER_OPTIONS as a,
99  SORT_OPTIONS as b,
100  filterAndSortLibrary as f,
101  isBookFinished as i,
102  tagsInUse as t
103};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.