on fdeccfb help sign in
webring/scripts/portal.js
91 lines 3.8 kB history raw
1'use strict'
3function Portal (sites) {
4 this.el = document.createElement('div')
5 this.el.id = 'portal'
6 this.sites = sites
8 // Templates
10 function _readme () {
11 return '<p class="readme">This webring is an attempt to inspire artists & developers to build their own website and share traffic among each other. The ring welcomes personalized websites such as <b>diaries, wikis & portfolios</b>.</p><p>To add yourself to the ring, submit a <a href="https://github.com/XXIIVV/webring/edit/master/scripts/sites.js" target="_blank">Pull Request</a>.<br />If you found a broken link, please <a href="https://github.com/XXIIVV/webring/issues/new" target="_blank">report it</a>.</p>'
12 }
14 function _buttons () {
15 return '<p class="buttons"><a href="#random" onClick="portal.reload()">Random</a> | <a href="https://github.com/XXIIVV/webring">Information</a> <a id="icon" href="#random" onClick="portal.reload()"></a> | <a href="hallway.html">The Hallway</a> | <a href="wiki.html">The Wiki</a> | <a id="opml">OPML</a></p>'
16 }
18 function _directory (sites) {
19 const siteTypesArray = [...new Set(sites.map(site => site.type).filter(Boolean))]
20 const siteTypes = siteTypesArray.reduce((output, siteType) =>
21 `${output}<a data-type="${siteType}" href="#" onclick="toggleType(event)">&lt;${siteType}&gt;</a>`,
22 '<a class="current" href="#" onclick="toggleType(event)">&lt;all&gt;</a>')
23 const listItems = sites.reduce((acc, site, id) =>
24 `${acc}<li ${_type(site)} id='${id}'><a href='${site.url}'>${_name(site)}</a></li>`, '')
25 return `<nav>${siteTypes}</nav><main><ul>${listItems}</ul></main><footer>${_readme()}${_buttons()}</footer>`
26 }
28 function _name (site) {
29 return site.title || `${site.url.split('//')[1]}`
30 }
32 function _type (site) {
33 return site.type ? `data-type="${site.type}"` : ''
34 }
36 function _redirect (site) {
37 return `<main><p>Redirecting to <a href="${site.url}">${site.url}</a></p></main>
38 <footer><p class='buttons'><a href='#' onClick="portal.reload('')">Directory</a> | <a href='#${site.url}' onClick="portal.reload()">Skip</a> | <a href='#random' onClick="portal.reload()">Random</a> | <a href='https://github.com/XXIIVV/webring'>Information</a> <a id='icon' href='#random' onClick="portal.reload()"></a></p>`
39 }
41 //
43 this.install = function (host) {
44 host.appendChild(this.el)
45 }
47 this.start = function () {
48 if (window.location.hash && window.location.hash.length > 4) {
49 const site = this.next()
50 this.el.innerHTML = _redirect(site)
51 setTimeout(() => { window.location = site.url }, 3000)
52 } else {
53 this.el.innerHTML = _directory(this.sites)
54 }
55 }
57 this.reload = function () {
58 setTimeout(() => { window.location.reload() }, 500)
59 }
61 this.navigate = function (target) {
62 setTimeout(() => { window.location.href = target }, 3000)
63 }
65 this.locate = function () {
66 const hash = window.location.hash.replace('#', '').trim()
68 if (hash === 'random') {
69 return Math.floor(Math.random() * this.sites.length)
70 } else {
71 const id = sites.findIndex(site => site.url.indexOf(hash) > -1)
72 return id > -1 ? parseInt(id) : -1
73 }
74 }
76 this.next = function (loc = this.locate()) {
77 return loc === this.sites.length - 1 ? this.sites[0] : this.sites[loc + 1]
78 }
81function toggleType (e) {
82 e.preventDefault()
83 const navLink = e.target
84 const selectedType = navLink.dataset.type
85 document.querySelector('nav a.current').classList.remove('current')
86 navLink.classList.add('current')
87 document.querySelectorAll('main li').forEach(el => { el.style.display = 'block' })
88 if (selectedType) {
89 document.querySelectorAll(`main li:not([data-type='${selectedType}'])`).forEach(el => { el.style.display = 'none' })
90 }