const m = require('mithril') const api = require('./api') const Tree = [] const Articles = [] exports.Tree = Tree exports.Articles = Articles exports.loading = false exports.error = '' exports.year = null exports.month = null const matcher = /\/(\d+)(\/\d+)?/ function calculateActiveBranches() { let path = matcher.exec(m.route.get()) if (path && path[1] !== exports.year?.title) { for (let year of Tree) { if (year.title === path[1]) { exports.year = year break } } } else if (!path && m.route.get() === '/') { exports.year = Tree[Tree.length - 1] } else if (!path) { exports.year = null } if (path && exports.year && path[2]) { exports.month = exports.year.branches[Number(path[2].slice(1)) - 1] || null } else if (!path?.[2]) { exports.month = null } } function rebuildTree() { Tree.splice(0, Tree.length) if (!Articles.length) return let startYear = Articles[0].publish_at let target = new Date() let articleIndex = 0 for (let year = startYear.getFullYear(); year <= target.getFullYear(); year++) { let branchYear = { title: year.toString(), type: 'year', branches: [], videos: [] } Tree.push(branchYear) let lastMonth = year === target.getFullYear() ? target.getMonth() + 1 : 12 for (let month = 1; month <= lastMonth; month++) { let branchMonth = { title: month.toString(), type: 'month', branches: [], videos: [] } branchYear.branches.push(branchMonth) let start = new Date(year, month - 1) let end = new Date(year, month) for (; Articles[articleIndex] && Articles[articleIndex].publish_at >= start && Articles[articleIndex].publish_at < end; articleIndex++) { branchYear.videos.push(Articles[articleIndex]) branchMonth.videos.push(Articles[articleIndex]) } } } } function removeArticle(id) { let index = Articles.findIndex(article => article.id === id) if (index >= 0) { Articles.splice(index, 1) rebuildTree() } } function refreshTree() { exports.error = '' if (exports.loading) return Promise.resolve() exports.loading = true m.redraw() return api.sendRequest({ method: 'GET', url: '/api/articles', }) .then(result => { result.videos.forEach(video => { video.publish_at = new Date(video.publish_at) video.path_short = video.path.split('-')[2] }) Articles.splice(0, Articles.length) Articles.push.apply(Articles, result.videos) rebuildTree() }, err => { exports.error = 'Error fetching videos: ' + err.message }) .then(() => { exports.loading = false m.redraw() }) } exports.removeArticle = removeArticle exports.rebuildTree = rebuildTree exports.refreshTree = refreshTree exports.calculateActiveBranches = calculateActiveBranches