Verified Commit e1c5b567 authored by Jakob Moser's avatar Jakob Moser
Browse files

Mostly move pagination logic around

parent 3ca34638
Loading
Loading
Loading
Loading
+14 −2
Original line number Diff line number Diff line
import PaginationControls from "./PaginationControls.js"

const ELEMENTS_PER_PAGE = 25

export default {
    view(vnode) {
        // TODO Implement actually pages, not just a single page with only the first 100 elements.
        return vnode.attrs.elements.take(100).toArray()
        const elements = vnode.attrs.elements.toArray()
        const totalPages = Math.ceil(elements.length / ELEMENTS_PER_PAGE)
        const currentPageIndex = 0

        const startIndex = currentPageIndex * ELEMENTS_PER_PAGE
        return [
            elements.slice(startIndex, startIndex + ELEMENTS_PER_PAGE),
            // TODO Actually change the contents on page change
            m(PaginationControls, { currentPage: currentPageIndex + 1, totalPages, onPageChange: console.log })
        ]
    }
}

static/model/SongListModel.js

deleted100644 → 0
+0 −145
Original line number Diff line number Diff line
import Song from "./Song.js"

const SongListModel = {
    currentPage: 1,
    itemsPerPage: 60, // Wie vom Benutzer angegeben
    totalPagesComputed: 1,

    onbeforeupdate: function (vnode, old) {
        if (
            vnode.attrs.currentView !== old.attrs.currentView ||
            (vnode.attrs.query || "") !== (old.attrs.query || "")
        ) {
            this.currentPage = 1
        }
        return true
    },

    onPageChange: function (newPage) {
        if (newPage >= 1 && newPage <= this.totalPagesComputed) {
            this.currentPage = newPage
        }
    },

    getProcessedSongsForView: function (viewFilter, query) {
        let initialSongsForView = []
        let messageFromTabFilter = null // Nachricht rein basierend auf Tab-Auswahl

        // 1. Songs basierend auf dem aktuellen Tab (View) filtern
        switch (viewFilter) {
            case "favorites":
                initialSongsForView = (Song.all || []).filter(
                    song => song.favorite,
                )
                if (initialSongsForView.length === 0) {
                    // Überhaupt keine Favoriten
                    messageFromTabFilter =
                        "Du hast noch keine Favoriten markiert."
                }
                break
            case "popular":
                // initialSongsForView bleibt leer
                messageFromTabFilter =
                    "Die Liste der beliebten Songs ist bald verfügbar!"
                break
            case "all":
            default:
                initialSongsForView = Song.all || []
                if (initialSongsForView.length === 0) {
                    messageFromTabFilter = "Keine Songs in der Bibliothek."
                }
                break
        }

        let songsAfterSearch = initialSongsForView.slice()
        let composedMessage = null // Endgültige Nachricht für den Benutzer

        // 2. Suchbegriff anwenden und Nachrichten erstellen
        const trimmedQuery = query ? query.trim() : ""
        if (trimmedQuery !== "") {
            const lowerQuery = trimmedQuery.toLowerCase()
            songsAfterSearch = initialSongsForView.filter(
                song =>
                    (song.title &&
                        song.title.toLowerCase().includes(lowerQuery)) ||
                    (song.artist &&
                        song.artist.toLowerCase().includes(lowerQuery)),
            )

            if (viewFilter === "favorites") {
                const totalFavoritesOverall = initialSongsForView.length // Anzahl Favoriten vor der Suche
                const favoritesFoundBySearch = songsAfterSearch.length

                if (totalFavoritesOverall > 0) {
                    if (favoritesFoundBySearch > 0) {
                        composedMessage = {
                            type: "filtered_favorites_some_hidden",
                            showing: favoritesFoundBySearch,
                            total: totalFavoritesOverall,
                        }
                    } else {
                        composedMessage = {
                            type: "filtered_favorites_none_found_by_search",
                            total: totalFavoritesOverall,
                        }
                    }
                }
            }
        } else {
            // Kein Suchbegriff aktiv
            composedMessage = messageFromTabFilter
        }

        const totalFilteredItems = songsAfterSearch.length // Gesamtanzahl der Items nach Filterung/Suche (über alle Seiten)

        // 3. Paginierungslogik
        const totalPages =
            Math.ceil(totalFilteredItems / this.itemsPerPage) || 1
        this.totalPagesComputed = totalPages

        // Sicherstellen, dass currentPage innerhalb gültiger Grenzen liegt
        if (this.currentPage > totalPages) this.currentPage = totalPages
        if (this.currentPage < 1) this.currentPage = 1

        const startIndex = (this.currentPage - 1) * this.itemsPerPage
        const paginatedSongs = songsAfterSearch.slice(
            startIndex,
            startIndex + this.itemsPerPage,
        )

        // 4. Songs für die aktuelle Seite nach Künstler gruppieren
        const groups = {}
        if (paginatedSongs.length > 0) {
            paginatedSongs.forEach(song => {
                groups[song.artist] = groups[song.artist] || []
                groups[song.artist].push(song)
            })
        }
        const sortedArtistNames = Object.keys(groups).sort((a, b) =>
            a.localeCompare(b),
        )
        const finalGroupedSongsOnPage = {}
        sortedArtistNames.forEach(artist => {
            finalGroupedSongsOnPage[artist] = groups[artist].sort((a, b) =>
                a.title.localeCompare(b.title),
            )
        })

        // 5. Endgültige Nachricht, falls nach Filterung/Suche gar keine Items da sind (über alle Seiten)
        //    und noch keine spezifischere Nachricht (z.B. Favoriten-Logik) gesetzt wurde.
        if (totalFilteredItems === 0 && !composedMessage) {
            composedMessage = "Keine Songs entsprechen den aktuellen Kriterien."
        }

        return {
            groupedSongs: finalGroupedSongsOnPage,
            message: composedMessage,
            hasContentOnPage: paginatedSongs.length > 0,
            currentPage: this.currentPage,
            totalPages: totalPages,
            totalFilteredItems: totalFilteredItems,
        }
    },
}

export default SongListModel