import { h, Component } from 'preact'; export class ReadingList extends Component { state = { readingListItems: [], query: '', index: '', page: 0, totalReadingList: 0, availableTags: [], selectedTags: [], itemsLoaded: false, archiving: false, statusView: document.getElementById('reading-list').dataset.view, showLoadMoreButton: false, }; componentDidMount() { const algoliaId = document.querySelector("meta[name='algolia-public-id']") .content; const algoliaKey = document.getElementById('reading-list').dataset.algolia; const env = document.querySelector("meta[name='environment']").content; const client = algoliasearch(algoliaId, algoliaKey); const index = client.initIndex(`SecuredReactions_${env}`); const t = this; index .search('', { page: t.state.page, hitsPerPage: 64, filters: `status:${t.state.statusView}`, }) .then(content => { t.setState({ totalReadingList: content.nbHits, readingListItems: content.hits, index, itemsLoaded: true, }); this.shouldShowLoadMoreButton(); }); const waitingOnUser = setInterval(() => { if (window.currentUser) { t.setState({ availableTags: window.currentUser.followed_tag_names }); clearInterval(waitingOnUser); } }, 1); } handleTyping = e => { const query = e.target.value; const { selectedTags, statusView } = this.state; this.listSearch(query, selectedTags, statusView); }; toggleTag = (e, tag) => { e.preventDefault(); const { query, selectedTags, statusView } = this.state; const newTags = selectedTags; if (newTags.indexOf(tag) === -1) { newTags.push(tag); } else { newTags.splice(newTags.indexOf(tag), 1); } this.setState({ selectedTags: newTags }); this.listSearch(query, newTags, statusView); }; toggleStatusView = e => { e.preventDefault(); const { statusView, query, selectedTags } = this.state; if (statusView === 'valid') { this.setState({ statusView: 'archived' }); this.listSearch(query, selectedTags, 'archived'); window.history.replaceState(null, null, '/readinglist/archive'); } else { this.setState({ statusView: 'valid' }); this.listSearch(query, selectedTags, 'valid'); window.history.replaceState(null, null, '/readinglist'); } }; archive = (e, item) => { e.preventDefault(); const { statusView, readingListItems, totalReadingList } = this.state; const t = this; window.fetch(`/reading_list_items/${item.id}`, { method: 'PUT', headers: { 'X-CSRF-Token': window.csrfToken, 'Content-Type': 'application/json', }, body: JSON.stringify({ current_status: statusView }), credentials: 'same-origin', }); const newItems = readingListItems; newItems.splice(newItems.indexOf(item), 1); t.setState({ archiving: true, readingListItems: newItems, totalReadingList: totalReadingList - 1, }); setTimeout(() => { t.setState({ archiving: false }); }, 1800); }; shouldShowLoadMoreButton = () => { const { totalReadingList, readingListItems } = this.state; const totalReadingListLoaded = readingListItems.length; this.setState({ showLoadMoreButton: true }); if (totalReadingListLoaded >= totalReadingList) { this.setState({ showLoadMoreButton: false }); } }; loadNextReadingList = () => { const { statusView, query, selectedTags, page } = this.state; const isLoadMore = true; this.setState({ page: page + 1 }); this.listSearch(query, selectedTags, statusView, isLoadMore); }; listSearch(query, tags, statusView, isLoadMore = false) { const t = this; if (!isLoadMore) { this.setState({ page: 0 }); } const { index, page, readingListItems } = this.state; const filters = { page, hitsPerPage: 64, filters: `status:${statusView}` }; if (tags.length > 0) { filters.tagFilters = tags; } index.search(query, filters).then(content => { if (!isLoadMore) { t.setState({ readingListItems: content.hits, totalReadingList: content.nbHits, query, }); } else { t.setState({ readingListItems: [...readingListItems, ...content.hits], totalReadingList: content.nbHits, query, }); } this.shouldShowLoadMoreButton(); t.setState({ readingListItems: content.hits, totalReadingList: content.nbHits, query, }); }); } render() { const { archiving, availableTags, itemsLoaded, query, readingListItems, selectedTags, statusView, showLoadMoreButton, totalReadingList, } = this.state; let allItems = readingListItems.map(item => (