Added common media filter
This commit is contained in:
parent
46c7eb35b3
commit
7846a0a895
@ -1,36 +1,36 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { MediaListCollection, ProgressRow, RowId } from "./lib/types";
|
import type { MediaListCollection, ProgressRow } from "./lib/types";
|
||||||
import { term, items, filtered } from "./stores/table";
|
import { tableFilters, table, filtered, tableIndex } from "./stores/table";
|
||||||
import RowHeader from "./lib/components/table/RowHeader.svelte";
|
import RowHeader from "./lib/components/table/RowHeader.svelte";
|
||||||
import { AniList } from "./lib/services/anilist";
|
import { AniList } from "./lib/services/anilist";
|
||||||
import { formatProgress } from "./lib/utils/formatting";
|
import { formatProgress } from "./lib/utils/formatting";
|
||||||
|
|
||||||
|
let searchTerm = "";
|
||||||
|
let onlyShowCommon = true;
|
||||||
|
|
||||||
let inputUser = "";
|
let inputUser = "";
|
||||||
let progressIndex = [];
|
|
||||||
|
|
||||||
function hotEncode(index, data) {
|
function hotEncode(index, data) {
|
||||||
return index.map((idx) => data[idx] ?? null);
|
return index.map((idx) => data[idx] ?? null);
|
||||||
}
|
}
|
||||||
|
|
||||||
function processUser(userName: string, mediaList: MediaListCollection) {
|
function processUser(userName: string, mediaList: MediaListCollection) {
|
||||||
progressIndex.push(userName);
|
tableIndex.update((old) => [...old, userName]);
|
||||||
|
|
||||||
for (const list of mediaList.lists) {
|
for (const list of mediaList.lists) {
|
||||||
for (const listEntry of list.entries) {
|
for (const listEntry of list.entries) {
|
||||||
let rowId = listEntry.media.id;
|
let rowId = listEntry.media.id;
|
||||||
|
|
||||||
let row: ProgressRow = $items.get(rowId) ?? {
|
let row: ProgressRow = $table.get(rowId) ?? {
|
||||||
media: listEntry.media,
|
media: listEntry.media,
|
||||||
progress: {},
|
progress: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
row.progress[userName] = listEntry.progress;
|
row.progress[userName] = listEntry.progress;
|
||||||
|
|
||||||
items.update((map) => map.set(rowId, row));
|
table.update((map) => map.set(rowId, row));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
progressIndex = progressIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleAddUser() {
|
async function handleAddUser() {
|
||||||
@ -43,8 +43,10 @@
|
|||||||
inputUser = "";
|
inputUser = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
let searchTerm = "";
|
$: tableFilters.update((old) => ({
|
||||||
$: term.set(searchTerm.toLowerCase());
|
term: searchTerm.toLowerCase(),
|
||||||
|
onlyCommon: onlyShowCommon,
|
||||||
|
}));
|
||||||
|
|
||||||
const styleClasses = {
|
const styleClasses = {
|
||||||
tableHeader: "text-sm font-medium text-gray-900 px-6 py-4 text-left",
|
tableHeader: "text-sm font-medium text-gray-900 px-6 py-4 text-left",
|
||||||
@ -56,14 +58,24 @@
|
|||||||
<table class="min-w-full">
|
<table class="min-w-full">
|
||||||
<thead>
|
<thead>
|
||||||
<th scope="col" class="{styleClasses.tableHeader} w-1/3">
|
<th scope="col" class="{styleClasses.tableHeader} w-1/3">
|
||||||
<input
|
<div class="flex items-center space-x-2">
|
||||||
class="border rounded-sm px-3 py-2"
|
<input
|
||||||
type="text"
|
class="border rounded-sm px-3 py-2"
|
||||||
placeholder="Filter media"
|
type="text"
|
||||||
bind:value="{searchTerm}"
|
placeholder="Filter media"
|
||||||
/>
|
bind:value="{searchTerm}"
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
<label for="onlyCommon">Only show common media</label>
|
||||||
|
<input
|
||||||
|
id="onlyCommon"
|
||||||
|
type="checkbox"
|
||||||
|
bind:checked="{onlyShowCommon}"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</th>
|
</th>
|
||||||
{#each progressIndex as userName}
|
{#each $tableIndex as userName}
|
||||||
<th scope="col" class="{styleClasses.tableHeader}">
|
<th scope="col" class="{styleClasses.tableHeader}">
|
||||||
{userName}
|
{userName}
|
||||||
</th>
|
</th>
|
||||||
@ -86,7 +98,7 @@
|
|||||||
<td class="px-6 py-3 text-sm font-medium text-gray-900">
|
<td class="px-6 py-3 text-sm font-medium text-gray-900">
|
||||||
<RowHeader media="{media}" />
|
<RowHeader media="{media}" />
|
||||||
</td>
|
</td>
|
||||||
{#each hotEncode(progressIndex, progress) as entry}
|
{#each hotEncode($tableIndex, progress) as entry}
|
||||||
<td class="text-sm text-gray-900 font-light px-6 py-4">
|
<td class="text-sm text-gray-900 font-light px-6 py-4">
|
||||||
{formatProgress(entry, media.episodes)}
|
{formatProgress(entry, media.episodes)}
|
||||||
</td>
|
</td>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { type Media } from "../../types";
|
import type { Media } from "../../types";
|
||||||
import { formatTimestamp } from "../../utils/formatting";
|
import { formatTimestamp } from "../../utils/formatting";
|
||||||
|
|
||||||
export let media: Media;
|
export let media: Media;
|
||||||
|
@ -6,3 +6,5 @@ export type RowId = number;
|
|||||||
export type ProgressEntry = Record<string, number>;
|
export type ProgressEntry = Record<string, number>;
|
||||||
export type ProgressRow = { media: Media; progress: ProgressEntry };
|
export type ProgressRow = { media: Media; progress: ProgressEntry };
|
||||||
export type ProgressTable = Map<RowId, ProgressRow>;
|
export type ProgressTable = Map<RowId, ProgressRow>;
|
||||||
|
|
||||||
|
export type TableFilters = { term: string; onlyCommon: boolean };
|
||||||
|
@ -1,20 +1,39 @@
|
|||||||
import { writable, derived } from "svelte/store";
|
import { writable, derived } from "svelte/store";
|
||||||
import type { ProgressRow, ProgressTable, RowId } from "../lib/types";
|
import type {
|
||||||
|
ProgressRow,
|
||||||
|
ProgressTable,
|
||||||
|
RowId,
|
||||||
|
TableFilters,
|
||||||
|
} from "../lib/types";
|
||||||
|
|
||||||
export const term = writable("");
|
export const tableFilters = writable<TableFilters>({
|
||||||
|
term: "",
|
||||||
|
onlyCommon: false,
|
||||||
|
});
|
||||||
|
|
||||||
export const items = writable<ProgressTable>(new Map());
|
export const table = writable<ProgressTable>(new Map());
|
||||||
|
|
||||||
function search([term, items]): ProgressTable {
|
export const tableIndex = writable<string[]>([]);
|
||||||
|
|
||||||
|
type SearchParams = [TableFilters, ProgressTable, string[]];
|
||||||
|
|
||||||
|
function search([filters, items, index]: SearchParams): ProgressTable {
|
||||||
return new Map(
|
return new Map(
|
||||||
[...items].filter(([_, value]: [RowId, ProgressRow]) => {
|
[...items].filter(([_, value]: [RowId, ProgressRow]) => {
|
||||||
let title = value.media.title;
|
let title = value.media.title;
|
||||||
|
|
||||||
|
if (filters.onlyCommon) {
|
||||||
|
if (Object.keys(value.progress).length !== index.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
title.english?.toLowerCase().includes(term) ||
|
title.english?.toLowerCase().includes(filters.term) ||
|
||||||
title.romaji?.toLowerCase().includes(term)
|
title.romaji?.toLowerCase().includes(filters.term)
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const filtered = derived([term, items], search);
|
export const filtered = derived([tableFilters, table, tableIndex], search);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user